feat: Enhance Excel upload functionality with automatic numbering column detection
- Implemented automatic detection of numbering columns in the Excel upload modal, improving user experience by streamlining the upload process. - Updated the master-detail Excel upload configuration to reflect changes in how numbering rules are applied, ensuring consistency across uploads. - Refactored related components to remove deprecated properties and improve clarity in the configuration settings. - Enhanced error handling and logging for better debugging during the upload process.
This commit is contained in:
@@ -3777,7 +3777,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||
|
||||
/**
|
||||
* 마스터-디테일 엑셀 업로드 설정 컴포넌트
|
||||
* 분할 패널 + column_labels에서 관계를 자동 감지하고, 사용자는 채번 규칙만 선택
|
||||
* 분할 패널 + column_labels에서 관계를 자동 감지 (채번은 테이블 타입 관리에서 자동 감지)
|
||||
*/
|
||||
const MasterDetailExcelUploadConfig: React.FC<{
|
||||
config: any;
|
||||
@@ -4005,7 +4005,7 @@ const MasterDetailExcelUploadConfig: React.FC<{
|
||||
{/* 마스터 키 자동 생성 안내 */}
|
||||
{relationInfo && (
|
||||
<p className="text-muted-foreground border-t pt-2 text-xs">
|
||||
마스터 테이블의 <strong>{relationInfo.masterKeyColumn}</strong> 값은 위에서 설정한 채번 규칙으로 자동
|
||||
마스터 테이블의 <strong>{relationInfo.masterKeyColumn}</strong> 값은 테이블 타입 관리에서 설정된 채번 규칙으로 자동
|
||||
생성됩니다.
|
||||
</p>
|
||||
)}
|
||||
@@ -4114,165 +4114,15 @@ const MasterDetailExcelUploadConfig: React.FC<{
|
||||
};
|
||||
|
||||
/**
|
||||
* 엑셀 업로드 채번 규칙 설정 (단일 테이블/마스터-디테일 모두 사용 가능)
|
||||
* 엑셀 업로드 채번 규칙 안내 (테이블 타입 관리에서 자동 감지)
|
||||
*/
|
||||
const ExcelNumberingRuleConfig: React.FC<{
|
||||
config: { numberingRuleId?: string; numberingTargetColumn?: string };
|
||||
updateConfig: (updates: { numberingRuleId?: string; numberingTargetColumn?: string }) => void;
|
||||
tableName?: string; // 단일 테이블인 경우 테이블명
|
||||
hasSplitPanel?: boolean; // 분할 패널 여부 (마스터-디테일)
|
||||
}> = ({ config, updateConfig, tableName, hasSplitPanel }) => {
|
||||
const [numberingRules, setNumberingRules] = useState<any[]>([]);
|
||||
const [ruleSelectOpen, setRuleSelectOpen] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [tableColumns, setTableColumns] = useState<Array<{ columnName: string; columnLabel: string }>>([]);
|
||||
const [columnsLoading, setColumnsLoading] = useState(false);
|
||||
|
||||
// 채번 규칙 목록 로드
|
||||
useEffect(() => {
|
||||
const loadNumberingRules = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { apiClient } = await import("@/lib/api/client");
|
||||
const response = await apiClient.get("/numbering-rules");
|
||||
if (response.data?.success && response.data?.data) {
|
||||
setNumberingRules(response.data.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("채번 규칙 목록 로드 실패:", error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadNumberingRules();
|
||||
}, []);
|
||||
|
||||
// 단일 테이블인 경우 컬럼 목록 로드
|
||||
useEffect(() => {
|
||||
if (!tableName || hasSplitPanel) {
|
||||
setTableColumns([]);
|
||||
return;
|
||||
}
|
||||
|
||||
const loadColumns = async () => {
|
||||
setColumnsLoading(true);
|
||||
try {
|
||||
const { apiClient } = await import("@/lib/api/client");
|
||||
const response = await apiClient.get(`/table-management/tables/${tableName}/columns`);
|
||||
if (response.data?.success && response.data?.data?.columns) {
|
||||
const cols = response.data.data.columns.map((col: any) => ({
|
||||
columnName: col.columnName || col.column_name,
|
||||
columnLabel: col.displayName || col.columnLabel || col.column_label || col.columnName || col.column_name,
|
||||
}));
|
||||
setTableColumns(cols);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("컬럼 목록 로드 실패:", error);
|
||||
} finally {
|
||||
setColumnsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadColumns();
|
||||
}, [tableName, hasSplitPanel]);
|
||||
|
||||
const selectedRule = numberingRules.find((r) => String(r.rule_id || r.ruleId) === String(config.numberingRuleId));
|
||||
|
||||
const ExcelNumberingRuleInfo: React.FC = () => {
|
||||
return (
|
||||
<div className="border-t pt-3">
|
||||
<Label className="text-xs">채번 규칙</Label>
|
||||
<p className="text-muted-foreground mb-2 text-xs">
|
||||
업로드 시 자동으로 생성할 코드/번호의 채번 규칙을 선택하세요.
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
테이블 타입 관리에서 "채번" 타입으로 설정된 컬럼의 채번 규칙이 업로드 시 자동으로 적용됩니다.
|
||||
</p>
|
||||
|
||||
<Popover open={ruleSelectOpen} onOpenChange={setRuleSelectOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
role="combobox"
|
||||
aria-expanded={ruleSelectOpen}
|
||||
className="h-8 w-full justify-between text-xs"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "로딩 중..." : selectedRule?.rule_name || selectedRule?.ruleName || "채번 없음"}
|
||||
<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-2 text-center text-xs">검색 결과 없음</CommandEmpty>
|
||||
<CommandGroup>
|
||||
<CommandItem
|
||||
value="__none__"
|
||||
onSelect={() => {
|
||||
updateConfig({ numberingRuleId: undefined, numberingTargetColumn: undefined });
|
||||
setRuleSelectOpen(false);
|
||||
}}
|
||||
className="text-xs"
|
||||
>
|
||||
<Check className={cn("mr-2 h-4 w-4", !config.numberingRuleId ? "opacity-100" : "opacity-0")} />
|
||||
채번 없음
|
||||
</CommandItem>
|
||||
{numberingRules.map((rule, idx) => {
|
||||
const ruleId = String(rule.rule_id || rule.ruleId || `rule-${idx}`);
|
||||
const ruleName = rule.rule_name || rule.ruleName || "(이름 없음)";
|
||||
return (
|
||||
<CommandItem
|
||||
key={ruleId}
|
||||
value={ruleName}
|
||||
onSelect={() => {
|
||||
updateConfig({ numberingRuleId: ruleId });
|
||||
setRuleSelectOpen(false);
|
||||
}}
|
||||
className="text-xs"
|
||||
>
|
||||
<Check
|
||||
className={cn(
|
||||
"mr-2 h-4 w-4",
|
||||
String(config.numberingRuleId) === ruleId ? "opacity-100" : "opacity-0",
|
||||
)}
|
||||
/>
|
||||
{ruleName}
|
||||
</CommandItem>
|
||||
);
|
||||
})}
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
{/* 단일 테이블이고 채번 규칙이 선택된 경우, 적용할 컬럼 선택 */}
|
||||
{config.numberingRuleId && !hasSplitPanel && tableName && (
|
||||
<div className="mt-2">
|
||||
<Label className="text-xs">채번 적용 컬럼</Label>
|
||||
<Select
|
||||
value={config.numberingTargetColumn || ""}
|
||||
onValueChange={(value) => updateConfig({ numberingTargetColumn: value || undefined })}
|
||||
disabled={columnsLoading}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs">
|
||||
<SelectValue placeholder={columnsLoading ? "로딩 중..." : "컬럼 선택"} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{tableColumns.map((col) => (
|
||||
<SelectItem key={col.columnName} value={col.columnName}>
|
||||
{col.columnLabel} ({col.columnName})
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-muted-foreground mt-1 text-xs">채번 값이 입력될 컬럼을 선택하세요.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 분할 패널인 경우 안내 메시지 */}
|
||||
{config.numberingRuleId && hasSplitPanel && (
|
||||
<p className="text-muted-foreground mt-1 text-xs">마스터-디테일 구조에서는 마스터 키 컬럼에 자동 적용됩니다.</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -4440,14 +4290,10 @@ const ExcelUploadConfigSection: React.FC<{
|
||||
allComponents: ComponentData[];
|
||||
currentTableName?: string; // 현재 화면의 테이블명 (ButtonConfigPanel에서 전달)
|
||||
}> = ({ config, onUpdateProperty, allComponents, currentTableName: propTableName }) => {
|
||||
// 엑셀 업로드 설정 상태 관리
|
||||
// 엑셀 업로드 설정 상태 관리 (채번은 테이블 타입 관리에서 자동 감지)
|
||||
const [excelUploadConfig, setExcelUploadConfig] = useState<{
|
||||
numberingRuleId?: string;
|
||||
numberingTargetColumn?: string;
|
||||
afterUploadFlows?: Array<{ flowId: string; order: number }>;
|
||||
}>({
|
||||
numberingRuleId: config.action?.excelNumberingRuleId,
|
||||
numberingTargetColumn: config.action?.excelNumberingTargetColumn,
|
||||
afterUploadFlows: config.action?.excelAfterUploadFlows || [],
|
||||
});
|
||||
|
||||
@@ -4529,17 +4375,11 @@ const ExcelUploadConfigSection: React.FC<{
|
||||
);
|
||||
}, [hasSplitPanel, singleTableName, propTableName]);
|
||||
|
||||
// 설정 업데이트 함수
|
||||
// 설정 업데이트 함수 (채번은 테이블 타입 관리에서 자동 감지되므로 제어 실행만 관리)
|
||||
const updateExcelUploadConfig = (updates: Partial<typeof excelUploadConfig>) => {
|
||||
const newConfig = { ...excelUploadConfig, ...updates };
|
||||
setExcelUploadConfig(newConfig);
|
||||
|
||||
if (updates.numberingRuleId !== undefined) {
|
||||
onUpdateProperty("componentConfig.action.excelNumberingRuleId", updates.numberingRuleId);
|
||||
}
|
||||
if (updates.numberingTargetColumn !== undefined) {
|
||||
onUpdateProperty("componentConfig.action.excelNumberingTargetColumn", updates.numberingTargetColumn);
|
||||
}
|
||||
if (updates.afterUploadFlows !== undefined) {
|
||||
onUpdateProperty("componentConfig.action.excelAfterUploadFlows", updates.afterUploadFlows);
|
||||
}
|
||||
@@ -4548,15 +4388,9 @@ const ExcelUploadConfigSection: React.FC<{
|
||||
// config 변경 시 로컬 상태 동기화
|
||||
useEffect(() => {
|
||||
setExcelUploadConfig({
|
||||
numberingRuleId: config.action?.excelNumberingRuleId,
|
||||
numberingTargetColumn: config.action?.excelNumberingTargetColumn,
|
||||
afterUploadFlows: config.action?.excelAfterUploadFlows || [],
|
||||
});
|
||||
}, [
|
||||
config.action?.excelNumberingRuleId,
|
||||
config.action?.excelNumberingTargetColumn,
|
||||
config.action?.excelAfterUploadFlows,
|
||||
]);
|
||||
}, [config.action?.excelAfterUploadFlows]);
|
||||
|
||||
return (
|
||||
<div className="bg-muted/50 mt-4 space-y-4 rounded-lg border p-4">
|
||||
@@ -4595,13 +4429,8 @@ const ExcelUploadConfigSection: React.FC<{
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 채번 규칙 설정 (항상 표시) */}
|
||||
<ExcelNumberingRuleConfig
|
||||
config={excelUploadConfig}
|
||||
updateConfig={updateExcelUploadConfig}
|
||||
tableName={singleTableName}
|
||||
hasSplitPanel={hasSplitPanel}
|
||||
/>
|
||||
{/* 채번 규칙 안내 (테이블 타입 관리에서 자동 감지) */}
|
||||
<ExcelNumberingRuleInfo />
|
||||
|
||||
{/* 업로드 후 제어 실행 (항상 표시) */}
|
||||
<ExcelAfterUploadControlConfig config={excelUploadConfig} updateConfig={updateExcelUploadConfig} />
|
||||
|
||||
Reference in New Issue
Block a user