카드 디스플레이 설정 패널에 테이블 선택 기능을 추가하고, 커스텀 테이블 사용 여부에 따라 컬럼 목록을 동적으로 로드하도록 개선했습니다. 또한, 다국어 지원 및 테이블 설정 현황 문서의 내용을 업데이트하여 적용 상태를 명확히 하였습니다.
This commit is contained in:
parent
57d86c8ef1
commit
7181822832
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
## 요약
|
||||
|
||||
| 기능 | 적용 완료 | 미적용 | 해당없음 |
|
||||
|------|----------|--------|---------|
|
||||
| **다국어 지원** | 3개 | 10개 | 3개 |
|
||||
| **컴포넌트별 테이블 설정** | 4개 | 6개 | 6개 |
|
||||
| 기능 | 적용 완료 | 미적용 | 해당없음 |
|
||||
| -------------------------- | --------- | ------ | -------- |
|
||||
| **다국어 지원** | 3개 | 10개 | 3개 |
|
||||
| **컴포넌트별 테이블 설정** | 5개 | 5개 | 6개 |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -18,52 +18,52 @@
|
|||
|
||||
### 데이터 표시 (Display) - 4개
|
||||
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
|---------|:----------:|:----------:|------|
|
||||
| **테이블 리스트** | ✅ 적용 | ✅ 적용 | `customTableName`, `useCustomTable` 지원 |
|
||||
| **카드 디스플레이** | ❌ 미적용 | ⚠️ 부분 | `screenTableName`만 사용, 컴포넌트별 테이블 선택 UI 없음 |
|
||||
| **텍스트 표시** | ❌ 미적용 | ➖ 해당없음 | 정적 텍스트 표시용 |
|
||||
| **피벗 그리드** | ❌ 미적용 | ⚠️ 부분 | `tableName` 설정 가능하나 Combobox UI 없음 |
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
| ------------------- | :---------: | :---------: | ------------------------------------------------------------------- |
|
||||
| **테이블 리스트** | ✅ 적용 | ✅ 적용 | `customTableName`, `useCustomTable` 지원 |
|
||||
| **카드 디스플레이** | ❌ 미적용 | ✅ 적용 | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable` 지원 |
|
||||
| **텍스트 표시** | ❌ 미적용 | ➖ 해당없음 | 정적 텍스트 표시용 |
|
||||
| **피벗 그리드** | ❌ 미적용 | ⚠️ 부분 | `tableName` 설정 가능하나 Combobox UI 없음 |
|
||||
|
||||
---
|
||||
|
||||
### 데이터 입력 (Data) - 2개
|
||||
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
|---------|:----------:|:----------:|------|
|
||||
| **통합 반복 데이터** | ❌ 미적용 | ✅ 적용 | `mainTableName`, `foreignKeyColumn` 지원, Combobox UI 적용 |
|
||||
| **반복 화면 모달** | ❌ 미적용 | ⚠️ 부분 | `tableName` 설정 가능하나 Combobox UI 없음 |
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
| -------------------- | :---------: | :---------: | ---------------------------------------------------------- |
|
||||
| **통합 반복 데이터** | ❌ 미적용 | ✅ 적용 | `mainTableName`, `foreignKeyColumn` 지원, Combobox UI 적용 |
|
||||
| **반복 화면 모달** | ❌ 미적용 | ⚠️ 부분 | `tableName` 설정 가능하나 Combobox UI 없음 |
|
||||
|
||||
---
|
||||
|
||||
### 액션 (Action) - 1개
|
||||
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
|---------|:----------:|:----------:|------|
|
||||
| **기본 버튼** | ✅ 적용 | ➖ 해당없음 | `langKeyId`, `langKey` 지원 |
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
| ------------- | :---------: | :---------: | --------------------------- |
|
||||
| **기본 버튼** | ✅ 적용 | ➖ 해당없음 | `langKeyId`, `langKey` 지원 |
|
||||
|
||||
---
|
||||
|
||||
### 레이아웃 (Layout) - 5개
|
||||
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
|---------|:----------:|:----------:|------|
|
||||
| **분할 패널** | ✅ 적용 | ⚠️ 부분 | 다국어 지원, 테이블 설정은 하위 패널에서 처리 |
|
||||
| **탭 컴포넌트** | ❌ 미적용 | ➖ 해당없음 | 화면 전환용 컨테이너 |
|
||||
| **Section Card** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 |
|
||||
| **Section Paper** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 |
|
||||
| **구분선** | ❌ 미적용 | ➖ 해당없음 | 시각적 구분용 |
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
| ----------------- | :---------: | :---------: | --------------------------------------------- |
|
||||
| **분할 패널** | ✅ 적용 | ⚠️ 부분 | 다국어 지원, 테이블 설정은 하위 패널에서 처리 |
|
||||
| **탭 컴포넌트** | ❌ 미적용 | ➖ 해당없음 | 화면 전환용 컨테이너 |
|
||||
| **Section Card** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 |
|
||||
| **Section Paper** | ❌ 미적용 | ➖ 해당없음 | 그룹화 컨테이너 |
|
||||
| **구분선** | ❌ 미적용 | ➖ 해당없음 | 시각적 구분용 |
|
||||
|
||||
---
|
||||
|
||||
### 유틸리티 (Utility) - 4개
|
||||
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
|---------|:----------:|:----------:|------|
|
||||
| **코드 채번 규칙** | ❌ 미적용 | ➖ 해당없음 | 채번 규칙 관리 전용 |
|
||||
| **렉 구조 설정** | ❌ 미적용 | ➖ 해당없음 | 창고 렉 설정 전용 |
|
||||
| **출발지/도착지 선택** | ❌ 미적용 | ⚠️ 부분 | `customTableName` 지원하나 Combobox UI 없음 |
|
||||
| **검색 필터** | ❌ 미적용 | ⚠️ 부분 | `screenTableName` 자동 감지 |
|
||||
| 컴포넌트 | 다국어 지원 | 테이블 설정 | 비고 |
|
||||
| ---------------------- | :---------: | :---------: | ------------------------------------------- |
|
||||
| **코드 채번 규칙** | ❌ 미적용 | ➖ 해당없음 | 채번 규칙 관리 전용 |
|
||||
| **렉 구조 설정** | ❌ 미적용 | ➖ 해당없음 | 창고 렉 설정 전용 |
|
||||
| **출발지/도착지 선택** | ❌ 미적용 | ⚠️ 부분 | `customTableName` 지원하나 Combobox UI 없음 |
|
||||
| **검색 필터** | ❌ 미적용 | ⚠️ 부분 | `screenTableName` 자동 감지 |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -74,11 +74,13 @@
|
|||
다국어 지원이란 컴포넌트의 라벨, 플레이스홀더 등 텍스트 속성에 다국어 키를 연결하여 언어별로 다른 텍스트를 표시하는 기능입니다.
|
||||
|
||||
**적용 완료 (3개)**
|
||||
|
||||
- `table-list`: 컬럼 라벨 다국어 지원
|
||||
- `button-primary`: 버튼 텍스트 다국어 지원
|
||||
- `split-panel-layout`: 패널 제목 다국어 지원
|
||||
|
||||
**미적용 (10개)**
|
||||
|
||||
- `card-display`, `text-display`, `pivot-grid`
|
||||
- `unified-repeater`, `repeat-screen-modal`
|
||||
- `tabs`, `section-card`, `section-paper`, `divider-line`
|
||||
|
|
@ -90,26 +92,27 @@
|
|||
|
||||
컴포넌트별 테이블 설정이란 화면의 메인 테이블과 별개로 컴포넌트가 자체적으로 사용할 테이블을 지정할 수 있는 기능입니다.
|
||||
|
||||
**완전 적용 (4개)**
|
||||
**완전 적용 (5개)**
|
||||
|
||||
| 컴포넌트 | 적용 방식 |
|
||||
|---------|----------|
|
||||
| `table-list` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable`, `isReadOnly` 지원 |
|
||||
| 컴포넌트 | 적용 방식 |
|
||||
| ------------------ | --------------------------------------------------------------------------------- |
|
||||
| `table-list` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable`, `isReadOnly` 지원 |
|
||||
| `unified-repeater` | Combobox UI로 테이블 선택, `mainTableName`, `foreignKeyColumn` 지원, FK 자동 연결 |
|
||||
| `unified-list` | `TableListConfigPanel` 래핑하여 동일 기능 제공 |
|
||||
| `unified-list` | `TableListConfigPanel` 래핑하여 동일 기능 제공 |
|
||||
| `card-display` | Combobox UI로 테이블 선택, `customTableName`, `useCustomTable` 지원 |
|
||||
|
||||
**부분 적용 (6개)**
|
||||
**부분 적용 (5개)**
|
||||
|
||||
| 컴포넌트 | 현재 상태 | 필요 작업 |
|
||||
|---------|----------|----------|
|
||||
| `card-display` | `screenTableName` 사용 | Combobox UI 추가 필요 |
|
||||
| `pivot-grid` | `tableName` 설정 가능 | Combobox UI 추가 필요 |
|
||||
| `repeat-screen-modal` | `tableName` 설정 가능 | Combobox UI 추가 필요 |
|
||||
| `split-panel-layout` | 하위 패널에서 처리 | 하위 컴포넌트에 위임 |
|
||||
| `location-swap-selector` | `customTableName` 지원 | Combobox UI 추가 필요 |
|
||||
| `table-search-widget` | `screenTableName` 자동 감지 | 현재 방식 유지 가능 |
|
||||
| 컴포넌트 | 현재 상태 | 필요 작업 |
|
||||
| ------------------------ | --------------------------- | --------------------- |
|
||||
| `pivot-grid` | `tableName` 설정 가능 | Combobox UI 추가 필요 |
|
||||
| `repeat-screen-modal` | `tableName` 설정 가능 | Combobox UI 추가 필요 |
|
||||
| `split-panel-layout` | 하위 패널에서 처리 | 하위 컴포넌트에 위임 |
|
||||
| `location-swap-selector` | `customTableName` 지원 | Combobox UI 추가 필요 |
|
||||
| `table-search-widget` | `screenTableName` 자동 감지 | 현재 방식 유지 가능 |
|
||||
|
||||
**해당없음 (6개)**
|
||||
|
||||
- `text-display`, `divider-line`: 정적 컴포넌트
|
||||
- `tabs`, `section-card`, `section-paper`: 레이아웃 컨테이너
|
||||
- `numbering-rule`, `rack-structure`: 특수 목적 컴포넌트
|
||||
|
|
@ -120,29 +123,28 @@
|
|||
|
||||
### 1순위: 데이터 컴포넌트 테이블 설정 UI 통일
|
||||
|
||||
| 컴포넌트 | 작업 내용 |
|
||||
|---------|----------|
|
||||
| `card-display` | Combobox UI 추가, `customTableName` 지원 |
|
||||
| `pivot-grid` | Combobox UI 추가 |
|
||||
| `repeat-screen-modal` | Combobox UI 추가 |
|
||||
| 컴포넌트 | 작업 내용 | 상태 |
|
||||
| --------------------- | ---------------------------------------- | ------- |
|
||||
| `card-display` | Combobox UI 추가, `customTableName` 지원 | ✅ 완료 |
|
||||
| `pivot-grid` | Combobox UI 추가 | 대기 |
|
||||
| `repeat-screen-modal` | Combobox UI 추가 | 대기 |
|
||||
|
||||
### 2순위: 다국어 지원 확대
|
||||
|
||||
| 컴포넌트 | 작업 내용 |
|
||||
|---------|----------|
|
||||
| 컴포넌트 | 작업 내용 |
|
||||
| ------------------ | -------------------------- |
|
||||
| `unified-repeater` | 컬럼 라벨 `langKeyId` 지원 |
|
||||
| `card-display` | 필드 라벨 `langKeyId` 지원 |
|
||||
| `tabs` | 탭 이름 `langKeyId` 지원 |
|
||||
| `section-card` | 제목 `langKeyId` 지원 |
|
||||
| `card-display` | 필드 라벨 `langKeyId` 지원 |
|
||||
| `tabs` | 탭 이름 `langKeyId` 지원 |
|
||||
| `section-card` | 제목 `langKeyId` 지원 |
|
||||
|
||||
---
|
||||
|
||||
## 범례
|
||||
|
||||
| 기호 | 의미 |
|
||||
|-----|------|
|
||||
| ✅ | 완전 적용 |
|
||||
| ⚠️ | 부분 적용 (기능은 있으나 UI 미비) |
|
||||
| ❌ | 미적용 |
|
||||
| ➖ | 해당없음 (기능 불필요) |
|
||||
|
||||
| 기호 | 의미 |
|
||||
| ---- | --------------------------------- |
|
||||
| ✅ | 완전 적용 |
|
||||
| ⚠️ | 부분 적용 (기능은 있으나 UI 미비) |
|
||||
| ❌ | 미적용 |
|
||||
| ➖ | 해당없음 (기능 불필요) |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
"use client";
|
||||
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useMemo } from "react";
|
||||
import { entityJoinApi } from "@/lib/api/entityJoin";
|
||||
import { tableManagementApi } from "@/lib/api/tableManagement";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
|
@ -11,11 +12,14 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { Trash2, Database, ChevronsUpDown, Check } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface CardDisplayConfigPanelProps {
|
||||
config: any;
|
||||
|
|
@ -57,6 +61,13 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
screenTableName,
|
||||
tableColumns = [],
|
||||
}) => {
|
||||
// 테이블 선택 상태
|
||||
const [tableComboboxOpen, setTableComboboxOpen] = useState(false);
|
||||
const [allTables, setAllTables] = useState<Array<{ tableName: string; displayName: string }>>([]);
|
||||
const [loadingTables, setLoadingTables] = useState(false);
|
||||
const [availableColumns, setAvailableColumns] = useState<any[]>([]);
|
||||
const [loadingColumns, setLoadingColumns] = useState(false);
|
||||
|
||||
// 엔티티 조인 컬럼 상태
|
||||
const [entityJoinColumns, setEntityJoinColumns] = useState<{
|
||||
availableColumns: EntityJoinColumn[];
|
||||
|
|
@ -64,18 +75,80 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
}>({ availableColumns: [], joinTables: [] });
|
||||
const [loadingEntityJoins, setLoadingEntityJoins] = useState(false);
|
||||
|
||||
// 현재 사용할 테이블명
|
||||
const targetTableName = useMemo(() => {
|
||||
if (config.useCustomTable && config.customTableName) {
|
||||
return config.customTableName;
|
||||
}
|
||||
return config.tableName || screenTableName;
|
||||
}, [config.useCustomTable, config.customTableName, config.tableName, screenTableName]);
|
||||
|
||||
// 전체 테이블 목록 로드
|
||||
useEffect(() => {
|
||||
const loadAllTables = async () => {
|
||||
setLoadingTables(true);
|
||||
try {
|
||||
const response = await tableManagementApi.getTableList();
|
||||
if (response.success && response.data) {
|
||||
setAllTables(response.data.map((t: any) => ({
|
||||
tableName: t.tableName || t.table_name,
|
||||
displayName: t.tableLabel || t.displayName || t.tableName || t.table_name,
|
||||
})));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("테이블 목록 로드 실패:", error);
|
||||
} finally {
|
||||
setLoadingTables(false);
|
||||
}
|
||||
};
|
||||
loadAllTables();
|
||||
}, []);
|
||||
|
||||
// 선택된 테이블의 컬럼 로드
|
||||
useEffect(() => {
|
||||
const loadColumns = async () => {
|
||||
if (!targetTableName) {
|
||||
setAvailableColumns([]);
|
||||
return;
|
||||
}
|
||||
|
||||
// 커스텀 테이블이 아니면 props로 받은 tableColumns 사용
|
||||
if (!config.useCustomTable && tableColumns && tableColumns.length > 0) {
|
||||
setAvailableColumns(tableColumns);
|
||||
return;
|
||||
}
|
||||
|
||||
setLoadingColumns(true);
|
||||
try {
|
||||
const result = await tableManagementApi.getColumnList(targetTableName);
|
||||
if (result.success && result.data?.columns) {
|
||||
setAvailableColumns(result.data.columns.map((col: any) => ({
|
||||
columnName: col.columnName,
|
||||
columnLabel: col.displayName || col.columnLabel || col.columnName,
|
||||
dataType: col.dataType,
|
||||
})));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("컬럼 목록 로드 실패:", error);
|
||||
setAvailableColumns([]);
|
||||
} finally {
|
||||
setLoadingColumns(false);
|
||||
}
|
||||
};
|
||||
loadColumns();
|
||||
}, [targetTableName, config.useCustomTable, tableColumns]);
|
||||
|
||||
// 엔티티 조인 컬럼 정보 가져오기
|
||||
useEffect(() => {
|
||||
const fetchEntityJoinColumns = async () => {
|
||||
const tableName = config.tableName || screenTableName;
|
||||
if (!tableName) {
|
||||
if (!targetTableName) {
|
||||
setEntityJoinColumns({ availableColumns: [], joinTables: [] });
|
||||
return;
|
||||
}
|
||||
|
||||
setLoadingEntityJoins(true);
|
||||
try {
|
||||
const result = await entityJoinApi.getEntityJoinColumns(tableName);
|
||||
const result = await entityJoinApi.getEntityJoinColumns(targetTableName);
|
||||
setEntityJoinColumns({
|
||||
availableColumns: result.availableColumns || [],
|
||||
joinTables: result.joinTables || [],
|
||||
|
|
@ -89,7 +162,38 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
};
|
||||
|
||||
fetchEntityJoinColumns();
|
||||
}, [config.tableName, screenTableName]);
|
||||
}, [targetTableName]);
|
||||
|
||||
// 테이블 선택 핸들러
|
||||
const handleTableSelect = (tableName: string, isScreenTable: boolean) => {
|
||||
if (isScreenTable) {
|
||||
// 화면 기본 테이블 선택
|
||||
onChange({
|
||||
...config,
|
||||
useCustomTable: false,
|
||||
customTableName: undefined,
|
||||
tableName: tableName,
|
||||
columnMapping: { displayColumns: [] }, // 컬럼 매핑 초기화
|
||||
});
|
||||
} else {
|
||||
// 다른 테이블 선택
|
||||
onChange({
|
||||
...config,
|
||||
useCustomTable: true,
|
||||
customTableName: tableName,
|
||||
tableName: tableName,
|
||||
columnMapping: { displayColumns: [] }, // 컬럼 매핑 초기화
|
||||
});
|
||||
}
|
||||
setTableComboboxOpen(false);
|
||||
};
|
||||
|
||||
// 현재 선택된 테이블 표시명 가져오기
|
||||
const getSelectedTableDisplay = () => {
|
||||
if (!targetTableName) return "테이블을 선택하세요";
|
||||
const found = allTables.find(t => t.tableName === targetTableName);
|
||||
return found?.displayName || targetTableName;
|
||||
};
|
||||
|
||||
const handleChange = (key: string, value: any) => {
|
||||
onChange({ ...config, [key]: value });
|
||||
|
|
@ -219,6 +323,9 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
joinColumnsByTable[col.tableName].push(col);
|
||||
});
|
||||
|
||||
// 현재 사용할 컬럼 목록 (커스텀 테이블이면 로드한 컬럼, 아니면 props)
|
||||
const currentTableColumns = config.useCustomTable ? availableColumns : (tableColumns.length > 0 ? tableColumns : availableColumns);
|
||||
|
||||
// 컬럼 선택 셀렉트 박스 렌더링 (Shadcn UI)
|
||||
const renderColumnSelect = (
|
||||
value: string,
|
||||
|
|
@ -240,12 +347,12 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
</SelectItem>
|
||||
|
||||
{/* 기본 테이블 컬럼 */}
|
||||
{tableColumns.length > 0 && (
|
||||
{currentTableColumns.length > 0 && (
|
||||
<SelectGroup>
|
||||
<SelectLabel className="text-xs font-semibold text-muted-foreground">
|
||||
기본 컬럼
|
||||
</SelectLabel>
|
||||
{tableColumns.map((column) => (
|
||||
{currentTableColumns.map((column: any) => (
|
||||
<SelectItem
|
||||
key={column.columnName}
|
||||
value={column.columnName}
|
||||
|
|
@ -283,13 +390,99 @@ export const CardDisplayConfigPanel: React.FC<CardDisplayConfigPanelProps> = ({
|
|||
<div className="space-y-4">
|
||||
<div className="text-sm font-medium">카드 디스플레이 설정</div>
|
||||
|
||||
{/* 테이블 선택 */}
|
||||
<div className="space-y-2">
|
||||
<Label className="text-xs font-medium">표시 테이블</Label>
|
||||
<Popover open={tableComboboxOpen} onOpenChange={setTableComboboxOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={tableComboboxOpen}
|
||||
className="h-9 w-full justify-between text-xs"
|
||||
disabled={loadingTables}
|
||||
>
|
||||
<div className="flex items-center gap-2 truncate">
|
||||
<Database className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||
<span className="truncate">{getSelectedTableDisplay()}</span>
|
||||
</div>
|
||||
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-[300px] p-0" align="start">
|
||||
<Command>
|
||||
<CommandInput placeholder="테이블 검색..." className="text-xs" />
|
||||
<CommandList>
|
||||
<CommandEmpty className="py-3 text-center text-xs text-muted-foreground">
|
||||
테이블을 찾을 수 없습니다.
|
||||
</CommandEmpty>
|
||||
|
||||
{/* 화면 기본 테이블 */}
|
||||
{screenTableName && (
|
||||
<CommandGroup heading="기본 (화면 테이블)">
|
||||
<CommandItem
|
||||
value={screenTableName}
|
||||
onSelect={() => handleTableSelect(screenTableName, true)}
|
||||
className="text-xs"
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
targetTableName === screenTableName && !config.useCustomTable
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
<Database className="mr-2 h-3.5 w-3.5 text-blue-500" />
|
||||
{allTables.find(t => t.tableName === screenTableName)?.displayName || screenTableName}
|
||||
</CommandItem>
|
||||
</CommandGroup>
|
||||
)}
|
||||
|
||||
{/* 전체 테이블 */}
|
||||
<CommandGroup heading="전체 테이블">
|
||||
{allTables
|
||||
.filter(t => t.tableName !== screenTableName)
|
||||
.map((table) => (
|
||||
<CommandItem
|
||||
key={table.tableName}
|
||||
value={table.tableName}
|
||||
onSelect={() => handleTableSelect(table.tableName, false)}
|
||||
className="text-xs"
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
config.useCustomTable && targetTableName === table.tableName
|
||||
? "opacity-100"
|
||||
: "opacity-0"
|
||||
)}
|
||||
/>
|
||||
<Database className="mr-2 h-3.5 w-3.5 text-muted-foreground" />
|
||||
<span className="truncate">{table.displayName}</span>
|
||||
</CommandItem>
|
||||
))}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
{config.useCustomTable && (
|
||||
<p className="text-[10px] text-muted-foreground">
|
||||
화면 기본 테이블이 아닌 다른 테이블의 데이터를 표시합니다.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 테이블이 선택된 경우 컬럼 매핑 설정 */}
|
||||
{tableColumns && tableColumns.length > 0 && (
|
||||
{(currentTableColumns.length > 0 || loadingColumns) && (
|
||||
<div className="space-y-3">
|
||||
<h5 className="text-xs font-medium text-muted-foreground">컬럼 매핑</h5>
|
||||
|
||||
{loadingEntityJoins && (
|
||||
<div className="text-xs text-muted-foreground">조인 컬럼 로딩 중...</div>
|
||||
{(loadingEntityJoins || loadingColumns) && (
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{loadingColumns ? "컬럼 로딩 중..." : "조인 컬럼 로딩 중..."}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-1">
|
||||
|
|
|
|||
|
|
@ -45,6 +45,12 @@ export interface CardDisplayConfig extends ComponentConfig {
|
|||
// 컬럼 매핑 설정
|
||||
columnMapping?: ColumnMappingConfig;
|
||||
|
||||
// 컴포넌트별 테이블 설정
|
||||
useCustomTable?: boolean;
|
||||
customTableName?: string;
|
||||
tableName?: string;
|
||||
isReadOnly?: boolean;
|
||||
|
||||
// 테이블 데이터 설정
|
||||
dataSource?: "static" | "table" | "api";
|
||||
tableId?: string;
|
||||
|
|
|
|||
Loading…
Reference in New Issue