Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into lhj
; Please enter a commit message to explain why this merge is necessary, ; especially if it merges an updated upstream into a topic branch. ; ; Lines starting with ';' will be ignored, and an empty message aborts ; the commit.
This commit is contained in:
@@ -1369,58 +1369,25 @@ export const InteractiveScreenViewer: React.FC<InteractiveScreenViewerProps> = (
|
||||
}
|
||||
|
||||
case "entity": {
|
||||
// DynamicWebTypeRenderer로 위임하여 EntitySearchInputWrapper 사용
|
||||
const widget = comp as WidgetComponent;
|
||||
const config = widget.webTypeConfig as EntityTypeConfig | undefined;
|
||||
|
||||
console.log("🏢 InteractiveScreenViewer - Entity 위젯:", {
|
||||
componentId: widget.id,
|
||||
widgetType: widget.widgetType,
|
||||
config,
|
||||
appliedSettings: {
|
||||
entityName: config?.entityName,
|
||||
displayField: config?.displayField,
|
||||
valueField: config?.valueField,
|
||||
multiple: config?.multiple,
|
||||
defaultValue: config?.defaultValue,
|
||||
},
|
||||
});
|
||||
|
||||
const finalPlaceholder = config?.placeholder || "엔티티를 선택하세요...";
|
||||
const defaultOptions = [
|
||||
{ label: "사용자", value: "user" },
|
||||
{ label: "제품", value: "product" },
|
||||
{ label: "주문", value: "order" },
|
||||
{ label: "카테고리", value: "category" },
|
||||
];
|
||||
|
||||
return (
|
||||
<Select
|
||||
value={currentValue || config?.defaultValue || ""}
|
||||
onValueChange={(value) => updateFormData(fieldName, value)}
|
||||
disabled={readonly}
|
||||
required={required}
|
||||
>
|
||||
<SelectTrigger
|
||||
className="w-full"
|
||||
style={{ height: "100%" }}
|
||||
style={{
|
||||
...comp.style,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
<SelectValue placeholder={finalPlaceholder} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{defaultOptions.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{config?.displayFormat
|
||||
? config.displayFormat.replace("{label}", option.label).replace("{value}", option.value)
|
||||
: option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>,
|
||||
return applyStyles(
|
||||
<DynamicWebTypeRenderer
|
||||
webType="entity"
|
||||
config={widget.webTypeConfig}
|
||||
props={{
|
||||
component: widget,
|
||||
value: currentValue,
|
||||
onChange: (value: any) => updateFormData(fieldName, value),
|
||||
onFormDataChange: updateFormData,
|
||||
formData: formData,
|
||||
readonly: readonly,
|
||||
required: required,
|
||||
placeholder: widget.placeholder || "엔티티를 선택하세요",
|
||||
isInteractive: true,
|
||||
className: "w-full h-full",
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Search, Database, Link, X, Plus } from "lucide-react";
|
||||
import { EntityTypeConfig } from "@/types/screen";
|
||||
@@ -26,6 +27,8 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||
placeholder: "",
|
||||
displayFormat: "simple",
|
||||
separator: " - ",
|
||||
multiple: false, // 다중 선택
|
||||
uiMode: "select", // UI 모드: select, combo, modal, autocomplete
|
||||
...config,
|
||||
};
|
||||
|
||||
@@ -38,6 +41,8 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||
placeholder: safeConfig.placeholder,
|
||||
displayFormat: safeConfig.displayFormat,
|
||||
separator: safeConfig.separator,
|
||||
multiple: safeConfig.multiple,
|
||||
uiMode: safeConfig.uiMode,
|
||||
});
|
||||
|
||||
const [newFilter, setNewFilter] = useState({ field: "", operator: "=", value: "" });
|
||||
@@ -74,6 +79,8 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||
placeholder: safeConfig.placeholder,
|
||||
displayFormat: safeConfig.displayFormat,
|
||||
separator: safeConfig.separator,
|
||||
multiple: safeConfig.multiple,
|
||||
uiMode: safeConfig.uiMode,
|
||||
});
|
||||
}, [
|
||||
safeConfig.referenceTable,
|
||||
@@ -83,8 +90,18 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||
safeConfig.placeholder,
|
||||
safeConfig.displayFormat,
|
||||
safeConfig.separator,
|
||||
safeConfig.multiple,
|
||||
safeConfig.uiMode,
|
||||
]);
|
||||
|
||||
// UI 모드 옵션
|
||||
const uiModes = [
|
||||
{ value: "select", label: "드롭다운 선택" },
|
||||
{ value: "combo", label: "입력 + 모달 버튼" },
|
||||
{ value: "modal", label: "모달 팝업" },
|
||||
{ value: "autocomplete", label: "자동완성" },
|
||||
];
|
||||
|
||||
const updateConfig = (key: keyof EntityTypeConfig, value: any) => {
|
||||
// 로컬 상태 즉시 업데이트
|
||||
setLocalValues((prev) => ({ ...prev, [key]: value }));
|
||||
@@ -260,6 +277,46 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* UI 모드 */}
|
||||
<div>
|
||||
<Label htmlFor="uiMode" className="text-sm font-medium">
|
||||
UI 모드
|
||||
</Label>
|
||||
<Select value={localValues.uiMode || "select"} onValueChange={(value) => updateConfig("uiMode", value)}>
|
||||
<SelectTrigger className="mt-1 h-8 w-full text-xs">
|
||||
<SelectValue placeholder="모드 선택" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{uiModes.map((mode) => (
|
||||
<SelectItem key={mode.value} value={mode.value}>
|
||||
{mode.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<p className="text-muted-foreground mt-1 text-xs">
|
||||
{localValues.uiMode === "select" && "검색 가능한 드롭다운 형태로 표시됩니다."}
|
||||
{localValues.uiMode === "combo" && "입력 필드와 검색 버튼이 함께 표시됩니다."}
|
||||
{localValues.uiMode === "modal" && "모달 팝업에서 데이터를 검색하고 선택합니다."}
|
||||
{localValues.uiMode === "autocomplete" && "입력하면서 자동완성 목록이 표시됩니다."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* 다중 선택 */}
|
||||
<div className="flex items-center justify-between rounded-md border p-3">
|
||||
<div className="space-y-1">
|
||||
<Label htmlFor="multiple" className="text-sm font-medium">
|
||||
다중 선택
|
||||
</Label>
|
||||
<p className="text-muted-foreground text-xs">여러 항목을 선택할 수 있습니다.</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="multiple"
|
||||
checked={localValues.multiple || false}
|
||||
onCheckedChange={(checked) => updateConfig("multiple", checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 필터 관리 */}
|
||||
<div className="space-y-3">
|
||||
<Label className="text-sm font-medium">데이터 필터</Label>
|
||||
|
||||
Reference in New Issue
Block a user