데이터 테이블 첨부파일 연계
This commit is contained in:
@@ -7,16 +7,23 @@ import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { FileComponent } from "@/types/screen";
|
||||
import { FileComponent, TableInfo } from "@/types/screen";
|
||||
import { Plus, X } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface FileComponentConfigPanelProps {
|
||||
component: FileComponent;
|
||||
onUpdateProperty: (componentId: string, path: string, value: any) => void;
|
||||
currentTable?: TableInfo; // 현재 화면의 테이블 정보
|
||||
currentTableName?: string; // 현재 화면의 테이블명
|
||||
}
|
||||
|
||||
export const FileComponentConfigPanel: React.FC<FileComponentConfigPanelProps> = ({ component, onUpdateProperty }) => {
|
||||
export const FileComponentConfigPanel: React.FC<FileComponentConfigPanelProps> = ({
|
||||
component,
|
||||
onUpdateProperty,
|
||||
currentTable,
|
||||
currentTableName,
|
||||
}) => {
|
||||
// 로컬 상태
|
||||
const [localInputs, setLocalInputs] = useState({
|
||||
docType: component.fileConfig.docType || "DOCUMENT",
|
||||
@@ -25,12 +32,15 @@ export const FileComponentConfigPanel: React.FC<FileComponentConfigPanelProps> =
|
||||
maxSize: component.fileConfig.maxSize || 10,
|
||||
maxFiles: component.fileConfig.maxFiles || 5,
|
||||
newAcceptType: "", // 새 파일 타입 추가용
|
||||
linkedTable: component.fileConfig.linkedTable || "", // 연결 테이블
|
||||
linkedField: component.fileConfig.linkedField || "", // 연결 필드
|
||||
});
|
||||
|
||||
const [localValues, setLocalValues] = useState({
|
||||
multiple: component.fileConfig.multiple ?? true,
|
||||
showPreview: component.fileConfig.showPreview ?? true,
|
||||
showProgress: component.fileConfig.showProgress ?? true,
|
||||
autoLink: component.fileConfig.autoLink ?? false, // 자동 연결
|
||||
});
|
||||
|
||||
const [acceptTypes, setAcceptTypes] = useState<string[]>(component.fileConfig.accept || []);
|
||||
@@ -44,12 +54,15 @@ export const FileComponentConfigPanel: React.FC<FileComponentConfigPanelProps> =
|
||||
maxSize: component.fileConfig.maxSize || 10,
|
||||
maxFiles: component.fileConfig.maxFiles || 5,
|
||||
newAcceptType: "",
|
||||
linkedTable: component.fileConfig.linkedTable || "",
|
||||
linkedField: component.fileConfig.linkedField || "",
|
||||
});
|
||||
|
||||
setLocalValues({
|
||||
multiple: component.fileConfig.multiple ?? true,
|
||||
showPreview: component.fileConfig.showPreview ?? true,
|
||||
showProgress: component.fileConfig.showProgress ?? true,
|
||||
autoLink: component.fileConfig.autoLink ?? false,
|
||||
});
|
||||
|
||||
setAcceptTypes(component.fileConfig.accept || []);
|
||||
@@ -332,6 +345,114 @@ export const FileComponentConfigPanel: React.FC<FileComponentConfigPanelProps> =
|
||||
<Label htmlFor="showProgress">업로드 진행률 표시</Label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 테이블 연결 설정 섹션 */}
|
||||
<div className="mt-6 rounded-lg border bg-blue-50 p-4">
|
||||
<h4 className="mb-3 text-sm font-semibold text-blue-900">📎 테이블 연결 설정</h4>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-2">
|
||||
<Checkbox
|
||||
id="autoLink"
|
||||
checked={localValues.autoLink}
|
||||
onCheckedChange={(checked) => {
|
||||
setLocalValues((prev) => ({ ...prev, autoLink: checked as boolean }));
|
||||
onUpdateProperty(component.id, "fileConfig.autoLink", checked);
|
||||
|
||||
// 자동 연결이 활성화되면 현재 화면의 테이블 정보를 자동 설정
|
||||
if (checked && currentTableName && currentTable) {
|
||||
// 기본키 추정 로직 (일반적인 패턴들)
|
||||
const primaryKeyGuesses = [
|
||||
`${currentTableName}_id`, // table_name + "_id"
|
||||
`${currentTableName.replace(/_/g, "")}_id`, // undercore 제거 + "_id"
|
||||
currentTableName.endsWith("_info") || currentTableName.endsWith("_mng")
|
||||
? currentTableName.replace(/_(info|mng)$/, "_code") // _info, _mng -> _code
|
||||
: `${currentTableName}_code`, // table_name + "_code"
|
||||
"id", // 단순 "id"
|
||||
"objid", // "objid"
|
||||
];
|
||||
|
||||
// 실제 테이블 컬럼에서 기본키로 추정되는 컬럼 찾기
|
||||
let detectedPrimaryKey = "";
|
||||
for (const guess of primaryKeyGuesses) {
|
||||
const foundColumn = currentTable.columns.find(
|
||||
(col) => col.columnName.toLowerCase() === guess.toLowerCase(),
|
||||
);
|
||||
if (foundColumn) {
|
||||
detectedPrimaryKey = foundColumn.columnName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 찾지 못한 경우 첫 번째 컬럼을 기본키로 사용
|
||||
if (!detectedPrimaryKey && currentTable.columns.length > 0) {
|
||||
detectedPrimaryKey = currentTable.columns[0].columnName;
|
||||
}
|
||||
|
||||
console.log("🔗 자동 테이블 연결 설정:", {
|
||||
tableName: currentTableName,
|
||||
detectedPrimaryKey,
|
||||
availableColumns: currentTable.columns.map((c) => c.columnName),
|
||||
});
|
||||
|
||||
// 자동으로 테이블명과 기본키 설정
|
||||
setLocalInputs((prev) => ({
|
||||
...prev,
|
||||
linkedTable: currentTableName,
|
||||
linkedField: detectedPrimaryKey,
|
||||
}));
|
||||
|
||||
onUpdateProperty(component.id, "fileConfig.linkedTable", currentTableName);
|
||||
onUpdateProperty(component.id, "fileConfig.linkedField", detectedPrimaryKey);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Label htmlFor="autoLink">다른 테이블과 자동 연결</Label>
|
||||
</div>
|
||||
|
||||
{localValues.autoLink && (
|
||||
<>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="linkedTable">연결할 테이블명</Label>
|
||||
<Input
|
||||
id="linkedTable"
|
||||
value={localInputs.linkedTable}
|
||||
readOnly
|
||||
className="bg-gray-50 text-gray-700"
|
||||
placeholder="자동으로 설정됩니다"
|
||||
/>
|
||||
<div className="text-xs text-green-600">✅ 현재 화면의 테이블이 자동으로 설정됩니다</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="linkedField">연결할 필드명 (기본키)</Label>
|
||||
<Input
|
||||
id="linkedField"
|
||||
value={localInputs.linkedField}
|
||||
readOnly
|
||||
className="bg-gray-50 text-gray-700"
|
||||
placeholder="자동으로 감지됩니다"
|
||||
/>
|
||||
<div className="text-xs text-green-600">✅ 테이블의 기본키가 자동으로 감지됩니다</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded bg-blue-100 p-2 text-xs text-blue-600">
|
||||
💡 이 설정을 활성화하면 파일이 현재 레코드와 자동으로 연결됩니다.
|
||||
<br />
|
||||
{currentTableName && localInputs.linkedField ? (
|
||||
<>
|
||||
예: {currentTableName} 테이블의 {localInputs.linkedField}가 "값123"인 레코드에 파일을 업로드하면
|
||||
<br />
|
||||
target_objid가 "{currentTableName}:값123"로 설정됩니다.
|
||||
</>
|
||||
) : (
|
||||
<>테이블과 기본키 정보가 자동으로 설정되면 연결 예시가 표시됩니다.</>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user