feature/v2-unified-renewal #379
|
|
@ -67,7 +67,90 @@ interface UnifiedRepeaterConfig {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 저장 테이블 설정 UI 표준
|
### 조회 테이블 설정 UI 표준 (테이블 리스트)
|
||||||
|
|
||||||
|
테이블 리스트 등 조회용 컴포넌트의 ConfigPanel에서:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// 현재 선택된 테이블 카드 형태로 표시
|
||||||
|
<div className="flex items-center gap-2 rounded-md border bg-slate-50 p-2">
|
||||||
|
<Database className="h-4 w-4 text-blue-500" />
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="text-xs font-medium">
|
||||||
|
{config.customTableName || screenTableName || "테이블 미선택"}
|
||||||
|
</div>
|
||||||
|
<div className="text-[10px] text-muted-foreground">
|
||||||
|
{config.useCustomTable ? "커스텀 테이블" : "화면 기본 테이블"}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
// 테이블 선택 Combobox (기본/전체 그룹)
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button variant="outline" className="w-full justify-between">
|
||||||
|
테이블 변경...
|
||||||
|
<ChevronsUpDown className="ml-2 h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="p-0">
|
||||||
|
<Command>
|
||||||
|
<CommandInput placeholder="테이블 검색..." />
|
||||||
|
<CommandList>
|
||||||
|
{/* 그룹 1: 화면 기본 테이블 */}
|
||||||
|
{screenTableName && (
|
||||||
|
<CommandGroup heading="기본 (화면 테이블)">
|
||||||
|
<CommandItem
|
||||||
|
value={screenTableName}
|
||||||
|
onSelect={() => {
|
||||||
|
handleChange("useCustomTable", false);
|
||||||
|
handleChange("customTableName", undefined);
|
||||||
|
handleChange("selectedTable", screenTableName);
|
||||||
|
handleChange("columns", []); // 테이블 변경 시 컬럼 초기화
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Database className="mr-2 h-3 w-3 text-blue-500" />
|
||||||
|
{screenTableName}
|
||||||
|
</CommandItem>
|
||||||
|
</CommandGroup>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 그룹 2: 전체 테이블 */}
|
||||||
|
<CommandGroup heading="전체 테이블">
|
||||||
|
{availableTables
|
||||||
|
.filter((table) => table.tableName !== screenTableName)
|
||||||
|
.map((table) => (
|
||||||
|
<CommandItem
|
||||||
|
key={table.tableName}
|
||||||
|
value={table.tableName}
|
||||||
|
onSelect={() => {
|
||||||
|
handleChange("useCustomTable", true);
|
||||||
|
handleChange("customTableName", table.tableName);
|
||||||
|
handleChange("selectedTable", table.tableName);
|
||||||
|
handleChange("columns", []); // 테이블 변경 시 컬럼 초기화
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Table2 className="mr-2 h-3 w-3 text-slate-400" />
|
||||||
|
{table.displayName || table.tableName}
|
||||||
|
</CommandItem>
|
||||||
|
))}
|
||||||
|
</CommandGroup>
|
||||||
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
// 읽기전용 설정
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Checkbox
|
||||||
|
checked={config.isReadOnly || false}
|
||||||
|
onCheckedChange={(checked) => handleChange("isReadOnly", checked)}
|
||||||
|
/>
|
||||||
|
<Label className="text-xs">읽기전용 (조회만 가능)</Label>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 저장 테이블 설정 UI 표준 (리피터)
|
||||||
|
|
||||||
리피터 등 저장 기능이 있는 컴포넌트의 ConfigPanel에서:
|
리피터 등 저장 기능이 있는 컴포넌트의 ConfigPanel에서:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4076,12 +4076,17 @@ export class TableManagementService {
|
||||||
|
|
||||||
// table_type_columns에서 입력타입 정보 조회
|
// table_type_columns에서 입력타입 정보 조회
|
||||||
// 회사별 설정 우선, 없으면 기본 설정(*) fallback
|
// 회사별 설정 우선, 없으면 기본 설정(*) fallback
|
||||||
|
// detail_settings 컬럼에 유효하지 않은 JSON이 있을 수 있으므로 안전하게 처리
|
||||||
const rawInputTypes = await query<any>(
|
const rawInputTypes = await query<any>(
|
||||||
`SELECT DISTINCT ON (ttc.column_name)
|
`SELECT DISTINCT ON (ttc.column_name)
|
||||||
ttc.column_name as "columnName",
|
ttc.column_name as "columnName",
|
||||||
COALESCE(cl.column_label, ttc.column_name) as "displayName",
|
COALESCE(cl.column_label, ttc.column_name) as "displayName",
|
||||||
ttc.input_type as "inputType",
|
ttc.input_type as "inputType",
|
||||||
COALESCE(ttc.detail_settings::jsonb, '{}'::jsonb) as "detailSettings",
|
CASE
|
||||||
|
WHEN ttc.detail_settings IS NULL OR ttc.detail_settings = '' THEN '{}'::jsonb
|
||||||
|
WHEN ttc.detail_settings ~ '^\\s*\\{.*\\}\\s*$' THEN ttc.detail_settings::jsonb
|
||||||
|
ELSE '{}'::jsonb
|
||||||
|
END as "detailSettings",
|
||||||
ttc.is_nullable as "isNullable",
|
ttc.is_nullable as "isNullable",
|
||||||
ic.data_type as "dataType",
|
ic.data_type as "dataType",
|
||||||
ttc.company_code as "companyCode"
|
ttc.company_code as "companyCode"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue