편집기 인풋 오류 수정 및 탭 컴포넌트 완성
This commit is contained in:
parent
5e2392c417
commit
a0180d66a2
|
|
@ -981,7 +981,18 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||||
// 스페이스바 키 이벤트 처리 (Pan 모드) + 전역 마우스 이벤트
|
// 스페이스바 키 이벤트 처리 (Pan 모드) + 전역 마우스 이벤트
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleKeyDown = (e: KeyboardEvent) => {
|
const handleKeyDown = (e: KeyboardEvent) => {
|
||||||
// 입력 필드에서는 스페이스바 무시
|
// 입력 필드에서는 스페이스바 무시 (activeElement로 정확하게 체크)
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
if (
|
||||||
|
activeElement instanceof HTMLInputElement ||
|
||||||
|
activeElement instanceof HTMLTextAreaElement ||
|
||||||
|
activeElement?.getAttribute('contenteditable') === 'true' ||
|
||||||
|
activeElement?.getAttribute('role') === 'textbox'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// e.target도 함께 체크 (이중 방어)
|
||||||
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -997,6 +1008,17 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyUp = (e: KeyboardEvent) => {
|
const handleKeyUp = (e: KeyboardEvent) => {
|
||||||
|
// 입력 필드에서는 스페이스바 무시
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
if (
|
||||||
|
activeElement instanceof HTMLInputElement ||
|
||||||
|
activeElement instanceof HTMLTextAreaElement ||
|
||||||
|
activeElement?.getAttribute('contenteditable') === 'true' ||
|
||||||
|
activeElement?.getAttribute('role') === 'textbox'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.code === "Space") {
|
if (e.code === "Space") {
|
||||||
e.preventDefault(); // 스페이스바 기본 스크롤 동작 차단
|
e.preventDefault(); // 스페이스바 기본 스크롤 동작 차단
|
||||||
setIsPanMode(false);
|
setIsPanMode(false);
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.borderWidth || ""}
|
value={localStyle.borderWidth || ""}
|
||||||
onChange={(e) => handleStyleChange("borderWidth", e.target.value)}
|
onChange={(e) => handleStyleChange("borderWidth", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -60,20 +59,20 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.borderStyle || "solid"}
|
value={localStyle.borderStyle || "solid"}
|
||||||
onValueChange={(value) => handleStyleChange("borderStyle", value)}
|
onValueChange={(value) => handleStyleChange("borderStyle", value)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
|
<SelectTrigger className=" text-xsh-6 w-full px-2 py-0">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="solid" style={{ fontSize: "12px" }}>
|
<SelectItem value="solid" className="text-xs">
|
||||||
실선
|
실선
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="dashed" style={{ fontSize: "12px" }}>
|
<SelectItem value="dashed" className="text-xs">
|
||||||
파선
|
파선
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="dotted" style={{ fontSize: "12px" }}>
|
<SelectItem value="dotted" className="text-xs">
|
||||||
점선
|
점선
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="none" style={{ fontSize: "12px" }}>
|
<SelectItem value="none" className="text-xs">
|
||||||
없음
|
없음
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|
@ -93,7 +92,7 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.borderColor || "#000000"}
|
value={localStyle.borderColor || "#000000"}
|
||||||
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
|
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
|
||||||
className="h-6 w-12 p-1"
|
className="h-6 w-12 p-1"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -101,7 +100,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
|
onChange={(e) => handleStyleChange("borderColor", e.target.value)}
|
||||||
placeholder="#000000"
|
placeholder="#000000"
|
||||||
className="h-6 flex-1 text-xs"
|
className="h-6 flex-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -116,7 +114,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.borderRadius || ""}
|
value={localStyle.borderRadius || ""}
|
||||||
onChange={(e) => handleStyleChange("borderRadius", e.target.value)}
|
onChange={(e) => handleStyleChange("borderRadius", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -142,7 +139,7 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.backgroundColor || "#ffffff"}
|
value={localStyle.backgroundColor || "#ffffff"}
|
||||||
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
|
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
|
||||||
className="h-6 w-12 p-1"
|
className="h-6 w-12 p-1"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -150,7 +147,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
|
onChange={(e) => handleStyleChange("backgroundColor", e.target.value)}
|
||||||
placeholder="#ffffff"
|
placeholder="#ffffff"
|
||||||
className="h-6 flex-1 text-xs"
|
className="h-6 flex-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -166,7 +162,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.backgroundImage || ""}
|
value={localStyle.backgroundImage || ""}
|
||||||
onChange={(e) => handleStyleChange("backgroundImage", e.target.value)}
|
onChange={(e) => handleStyleChange("backgroundImage", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
<p className="text-[10px] text-muted-foreground">
|
<p className="text-[10px] text-muted-foreground">
|
||||||
위젯 배경 꾸미기용 (고급 사용자 전용)
|
위젯 배경 꾸미기용 (고급 사용자 전용)
|
||||||
|
|
@ -195,7 +190,7 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.color || "#000000"}
|
value={localStyle.color || "#000000"}
|
||||||
onChange={(e) => handleStyleChange("color", e.target.value)}
|
onChange={(e) => handleStyleChange("color", e.target.value)}
|
||||||
className="h-6 w-12 p-1"
|
className="h-6 w-12 p-1"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
@ -203,7 +198,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
onChange={(e) => handleStyleChange("color", e.target.value)}
|
onChange={(e) => handleStyleChange("color", e.target.value)}
|
||||||
placeholder="#000000"
|
placeholder="#000000"
|
||||||
className="h-6 flex-1 text-xs"
|
className="h-6 flex-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -218,7 +212,6 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.fontSize || ""}
|
value={localStyle.fontSize || ""}
|
||||||
onChange={(e) => handleStyleChange("fontSize", e.target.value)}
|
onChange={(e) => handleStyleChange("fontSize", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -232,29 +225,29 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.fontWeight || "normal"}
|
value={localStyle.fontWeight || "normal"}
|
||||||
onValueChange={(value) => handleStyleChange("fontWeight", value)}
|
onValueChange={(value) => handleStyleChange("fontWeight", value)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
|
<SelectTrigger className=" text-xsh-6 w-full px-2 py-0">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="normal" style={{ fontSize: "12px" }}>
|
<SelectItem value="normal" className="text-xs">
|
||||||
보통
|
보통
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="bold" style={{ fontSize: "12px" }}>
|
<SelectItem value="bold" className="text-xs">
|
||||||
굵게
|
굵게
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="100" style={{ fontSize: "12px" }}>
|
<SelectItem value="100" className="text-xs">
|
||||||
100
|
100
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="400" style={{ fontSize: "12px" }}>
|
<SelectItem value="400" className="text-xs">
|
||||||
400
|
400
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="500" style={{ fontSize: "12px" }}>
|
<SelectItem value="500" className="text-xs">
|
||||||
500
|
500
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="600" style={{ fontSize: "12px" }}>
|
<SelectItem value="600" className="text-xs">
|
||||||
600
|
600
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="700" style={{ fontSize: "12px" }}>
|
<SelectItem value="700" className="text-xs">
|
||||||
700
|
700
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|
@ -268,20 +261,20 @@ export default function StyleEditor({ style, onStyleChange, className }: StyleEd
|
||||||
value={localStyle.textAlign || "left"}
|
value={localStyle.textAlign || "left"}
|
||||||
onValueChange={(value) => handleStyleChange("textAlign", value)}
|
onValueChange={(value) => handleStyleChange("textAlign", value)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
|
<SelectTrigger className=" text-xsh-6 w-full px-2 py-0">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="left" style={{ fontSize: "12px" }}>
|
<SelectItem value="left" className="text-xs">
|
||||||
왼쪽
|
왼쪽
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="center" style={{ fontSize: "12px" }}>
|
<SelectItem value="center" className="text-xs">
|
||||||
가운데
|
가운데
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="right" style={{ fontSize: "12px" }}>
|
<SelectItem value="right" className="text-xs">
|
||||||
오른쪽
|
오른쪽
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="justify" style={{ fontSize: "12px" }}>
|
<SelectItem value="justify" className="text-xs">
|
||||||
양쪽
|
양쪽
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={modalScreenOpen}
|
aria-expanded={modalScreenOpen}
|
||||||
className="h-6 w-full justify-between px-2 py-0"
|
className="h-6 w-full justify-between px-2 py-0"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
disabled={screensLoading}
|
disabled={screensLoading}
|
||||||
>
|
>
|
||||||
{config.action?.targetScreenId
|
{config.action?.targetScreenId
|
||||||
|
|
@ -900,7 +900,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={modalScreenOpen}
|
aria-expanded={modalScreenOpen}
|
||||||
className="h-6 w-full justify-between px-2 py-0"
|
className="h-6 w-full justify-between px-2 py-0"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
disabled={screensLoading}
|
disabled={screensLoading}
|
||||||
>
|
>
|
||||||
{config.action?.targetScreenId
|
{config.action?.targetScreenId
|
||||||
|
|
@ -978,7 +978,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={modalScreenOpen}
|
aria-expanded={modalScreenOpen}
|
||||||
className="h-6 w-full justify-between px-2 py-0"
|
className="h-6 w-full justify-between px-2 py-0"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
disabled={screensLoading}
|
disabled={screensLoading}
|
||||||
>
|
>
|
||||||
{config.action?.targetScreenId
|
{config.action?.targetScreenId
|
||||||
|
|
@ -1132,7 +1132,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={modalScreenOpen}
|
aria-expanded={modalScreenOpen}
|
||||||
className="h-6 w-full justify-between px-2 py-0"
|
className="h-6 w-full justify-between px-2 py-0"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
disabled={screensLoading}
|
disabled={screensLoading}
|
||||||
>
|
>
|
||||||
{config.action?.targetScreenId
|
{config.action?.targetScreenId
|
||||||
|
|
@ -1286,7 +1286,6 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={displayColumnOpen}
|
aria-expanded={displayColumnOpen}
|
||||||
className="mt-2 h-8 w-full justify-between text-xs"
|
className="mt-2 h-8 w-full justify-between text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
disabled={columnsLoading || tableColumns.length === 0}
|
disabled={columnsLoading || tableColumns.length === 0}
|
||||||
>
|
>
|
||||||
{columnsLoading
|
{columnsLoading
|
||||||
|
|
@ -1301,9 +1300,9 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
|
<PopoverContent className="p-0" style={{ width: "var(--radix-popover-trigger-width)" }} align="start">
|
||||||
<Command>
|
<Command>
|
||||||
<CommandInput placeholder="컬럼 검색..." className="text-xs" style={{ fontSize: "12px" }} />
|
<CommandInput placeholder="컬럼 검색..." className="text-xs" />
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty className="text-xs" style={{ fontSize: "12px" }}>
|
<CommandEmpty className="text-xs">
|
||||||
컬럼을 찾을 수 없습니다.
|
컬럼을 찾을 수 없습니다.
|
||||||
</CommandEmpty>
|
</CommandEmpty>
|
||||||
<CommandGroup>
|
<CommandGroup>
|
||||||
|
|
@ -1316,7 +1315,6 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
setDisplayColumnOpen(false);
|
setDisplayColumnOpen(false);
|
||||||
}}
|
}}
|
||||||
className="text-xs"
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<Check
|
<Check
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
@ -1350,7 +1348,7 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
role="combobox"
|
role="combobox"
|
||||||
aria-expanded={navScreenOpen}
|
aria-expanded={navScreenOpen}
|
||||||
className="h-6 w-full justify-between px-2 py-0"
|
className="h-6 w-full justify-between px-2 py-0"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
disabled={screensLoading}
|
disabled={screensLoading}
|
||||||
>
|
>
|
||||||
{config.action?.targetScreenId
|
{config.action?.targetScreenId
|
||||||
|
|
@ -1424,7 +1422,6 @@ export const ButtonConfigPanel: React.FC<ButtonConfigPanelProps> = ({
|
||||||
onUpdateProperty("componentConfig.action.targetUrl", newValue);
|
onUpdateProperty("componentConfig.action.targetUrl", newValue);
|
||||||
}}
|
}}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
<p className="mt-1 text-xs text-muted-foreground">URL을 입력하면 화면 선택보다 우선 적용됩니다</p>
|
<p className="mt-1 text-xs text-muted-foreground">URL을 입력하면 화면 선택보다 우선 적용됩니다</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<CheckSquare className="h-4 w-4" />
|
<CheckSquare className="h-4 w-4" />
|
||||||
체크박스 설정
|
체크박스 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -173,7 +173,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.label || ""}
|
value={localConfig.label || ""}
|
||||||
onChange={(e) => updateConfig("label", e.target.value)}
|
onChange={(e) => updateConfig("label", e.target.value)}
|
||||||
placeholder="체크박스 라벨"
|
placeholder="체크박스 라벨"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -187,7 +187,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.checkedValue || ""}
|
value={localConfig.checkedValue || ""}
|
||||||
onChange={(e) => updateConfig("checkedValue", e.target.value)}
|
onChange={(e) => updateConfig("checkedValue", e.target.value)}
|
||||||
placeholder="Y"
|
placeholder="Y"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -199,7 +199,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.uncheckedValue || ""}
|
value={localConfig.uncheckedValue || ""}
|
||||||
onChange={(e) => updateConfig("uncheckedValue", e.target.value)}
|
onChange={(e) => updateConfig("uncheckedValue", e.target.value)}
|
||||||
placeholder="N"
|
placeholder="N"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -232,7 +232,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.groupLabel || ""}
|
value={localConfig.groupLabel || ""}
|
||||||
onChange={(e) => updateConfig("groupLabel", e.target.value)}
|
onChange={(e) => updateConfig("groupLabel", e.target.value)}
|
||||||
placeholder="체크박스 그룹 제목"
|
placeholder="체크박스 그룹 제목"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -244,19 +244,19 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={newOptionLabel}
|
value={newOptionLabel}
|
||||||
onChange={(e) => setNewOptionLabel(e.target.value)}
|
onChange={(e) => setNewOptionLabel(e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={newOptionValue}
|
value={newOptionValue}
|
||||||
onChange={(e) => setNewOptionValue(e.target.value)}
|
onChange={(e) => setNewOptionValue(e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={addOption}
|
onClick={addOption}
|
||||||
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
<Plus className="h-3 w-3" />
|
<Plus className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -277,13 +277,13 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={option.label}
|
value={option.label}
|
||||||
onChange={(e) => updateOption(index, "label", e.target.value)}
|
onChange={(e) => updateOption(index, "label", e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={option.value}
|
value={option.value}
|
||||||
onChange={(e) => updateOption(index, "value", e.target.value)}
|
onChange={(e) => updateOption(index, "value", e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Switch
|
<Switch
|
||||||
checked={!option.disabled}
|
checked={!option.disabled}
|
||||||
|
|
@ -361,7 +361,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
disabled={localConfig.readonly}
|
disabled={localConfig.readonly}
|
||||||
required={localConfig.required}
|
required={localConfig.required}
|
||||||
defaultChecked={localConfig.defaultChecked}
|
defaultChecked={localConfig.defaultChecked}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="preview-single" className="text-xs">
|
<Label htmlFor="preview-single" className="text-xs">
|
||||||
{localConfig.label || "체크박스 라벨"}
|
{localConfig.label || "체크박스 라벨"}
|
||||||
|
|
@ -380,7 +380,7 @@ export const CheckboxConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
disabled={localConfig.readonly || option.disabled}
|
disabled={localConfig.readonly || option.disabled}
|
||||||
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
|
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
|
||||||
defaultChecked={option.checked}
|
defaultChecked={option.checked}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor={`preview-group-${index}`} className="text-xs">
|
<Label htmlFor={`preview-group-${index}`} className="text-xs">
|
||||||
{option.label}
|
{option.label}
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<Code className="h-4 w-4" />
|
<Code className="h-4 w-4" />
|
||||||
코드 에디터 설정
|
코드 에디터 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -174,7 +174,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
step={50}
|
step={50}
|
||||||
value={localConfig.height || 300}
|
value={localConfig.height || 300}
|
||||||
onChange={(e) => updateConfig("height", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("height", parseInt(e.target.value))}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<div className="text-muted-foreground flex justify-between text-xs">
|
<div className="text-muted-foreground flex justify-between text-xs">
|
||||||
<span>150px</span>
|
<span>150px</span>
|
||||||
|
|
@ -199,7 +199,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("fontSize", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("fontSize", parseInt(e.target.value))}
|
||||||
min={10}
|
min={10}
|
||||||
max={24}
|
max={24}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("tabSize", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("tabSize", parseInt(e.target.value))}
|
||||||
min={1}
|
min={1}
|
||||||
max={8}
|
max={8}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -308,7 +308,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="코드를 입력하세요..."
|
placeholder="코드를 입력하세요..."
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -330,7 +330,7 @@ export const CodeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.defaultValue || ""}
|
value={localConfig.defaultValue || ""}
|
||||||
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
||||||
placeholder="기본 코드 내용"
|
placeholder="기본 코드 내용"
|
||||||
className="font-mono text-xs" style={{ fontSize: "12px" }}
|
className="font-mono text-xs"
|
||||||
rows={4}
|
rows={4}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<Calendar className="h-4 w-4" />
|
<Calendar className="h-4 w-4" />
|
||||||
날짜 설정
|
날짜 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -95,7 +95,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="날짜를 선택하세요"
|
placeholder="날짜를 선택하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -149,7 +149,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
type={localConfig.showTime ? "datetime-local" : "date"}
|
type={localConfig.showTime ? "datetime-local" : "date"}
|
||||||
value={localConfig.minDate || ""}
|
value={localConfig.minDate || ""}
|
||||||
onChange={(e) => updateConfig("minDate", e.target.value)}
|
onChange={(e) => updateConfig("minDate", e.target.value)}
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" variant="outline" onClick={() => setCurrentDate("minDate")} className="text-xs">
|
<Button size="sm" variant="outline" onClick={() => setCurrentDate("minDate")} className="text-xs">
|
||||||
오늘
|
오늘
|
||||||
|
|
@ -167,7 +167,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
type={localConfig.showTime ? "datetime-local" : "date"}
|
type={localConfig.showTime ? "datetime-local" : "date"}
|
||||||
value={localConfig.maxDate || ""}
|
value={localConfig.maxDate || ""}
|
||||||
onChange={(e) => updateConfig("maxDate", e.target.value)}
|
onChange={(e) => updateConfig("maxDate", e.target.value)}
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" variant="outline" onClick={() => setCurrentDate("maxDate")} className="text-xs">
|
<Button size="sm" variant="outline" onClick={() => setCurrentDate("maxDate")} className="text-xs">
|
||||||
오늘
|
오늘
|
||||||
|
|
@ -190,7 +190,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
type={localConfig.showTime ? "datetime-local" : "date"}
|
type={localConfig.showTime ? "datetime-local" : "date"}
|
||||||
value={localConfig.defaultValue || ""}
|
value={localConfig.defaultValue || ""}
|
||||||
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" variant="outline" onClick={() => setCurrentDate("defaultValue")} className="text-xs">
|
<Button size="sm" variant="outline" onClick={() => setCurrentDate("defaultValue")} className="text-xs">
|
||||||
현재
|
현재
|
||||||
|
|
@ -245,7 +245,7 @@ export const DateConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
min={localConfig.minDate}
|
min={localConfig.minDate}
|
||||||
max={localConfig.maxDate}
|
max={localConfig.maxDate}
|
||||||
defaultValue={localConfig.defaultValue}
|
defaultValue={localConfig.defaultValue}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<div className="text-muted-foreground mt-2 text-xs">
|
<div className="text-muted-foreground mt-2 text-xs">
|
||||||
형식: {localConfig.format}
|
형식: {localConfig.format}
|
||||||
|
|
|
||||||
|
|
@ -51,37 +51,52 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
const [newFieldName, setNewFieldName] = useState("");
|
const [newFieldName, setNewFieldName] = useState("");
|
||||||
const [newFieldLabel, setNewFieldLabel] = useState("");
|
const [newFieldLabel, setNewFieldLabel] = useState("");
|
||||||
const [newFieldType, setNewFieldType] = useState("string");
|
const [newFieldType, setNewFieldType] = useState("string");
|
||||||
|
const [isUserEditing, setIsUserEditing] = useState(false);
|
||||||
|
|
||||||
// 컴포넌트 변경 시 로컬 상태 동기화
|
// 컴포넌트 변경 시 로컬 상태 동기화 (사용자가 입력 중이 아닐 때만)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const currentConfig = (widget.webTypeConfig as EntityTypeConfig) || {};
|
if (!isUserEditing) {
|
||||||
setLocalConfig({
|
const currentConfig = (widget.webTypeConfig as EntityTypeConfig) || {};
|
||||||
entityType: currentConfig.entityType || "",
|
setLocalConfig({
|
||||||
displayFields: currentConfig.displayFields || [],
|
entityType: currentConfig.entityType || "",
|
||||||
searchFields: currentConfig.searchFields || [],
|
displayFields: currentConfig.displayFields || [],
|
||||||
valueField: currentConfig.valueField || "id",
|
searchFields: currentConfig.searchFields || [],
|
||||||
labelField: currentConfig.labelField || "name",
|
valueField: currentConfig.valueField || "id",
|
||||||
multiple: currentConfig.multiple || false,
|
labelField: currentConfig.labelField || "name",
|
||||||
searchable: currentConfig.searchable !== false,
|
multiple: currentConfig.multiple || false,
|
||||||
placeholder: currentConfig.placeholder || "엔티티를 선택하세요",
|
searchable: currentConfig.searchable !== false,
|
||||||
emptyMessage: currentConfig.emptyMessage || "검색 결과가 없습니다",
|
placeholder: currentConfig.placeholder || "엔티티를 선택하세요",
|
||||||
pageSize: currentConfig.pageSize || 20,
|
emptyMessage: currentConfig.emptyMessage || "검색 결과가 없습니다",
|
||||||
minSearchLength: currentConfig.minSearchLength || 1,
|
pageSize: currentConfig.pageSize || 20,
|
||||||
defaultValue: currentConfig.defaultValue || "",
|
minSearchLength: currentConfig.minSearchLength || 1,
|
||||||
required: currentConfig.required || false,
|
defaultValue: currentConfig.defaultValue || "",
|
||||||
readonly: currentConfig.readonly || false,
|
required: currentConfig.required || false,
|
||||||
apiEndpoint: currentConfig.apiEndpoint || "",
|
readonly: currentConfig.readonly || false,
|
||||||
filters: currentConfig.filters || {},
|
apiEndpoint: currentConfig.apiEndpoint || "",
|
||||||
});
|
filters: currentConfig.filters || {},
|
||||||
}, [widget.webTypeConfig]);
|
});
|
||||||
|
}
|
||||||
|
}, [widget.webTypeConfig, isUserEditing]);
|
||||||
|
|
||||||
// 설정 업데이트 핸들러
|
// 설정 업데이트 핸들러 (즉시 부모에게 전달 - 드롭다운, 체크박스 등)
|
||||||
const updateConfig = (field: keyof EntityTypeConfig, value: any) => {
|
const updateConfig = (field: keyof EntityTypeConfig, value: any) => {
|
||||||
const newConfig = { ...localConfig, [field]: value };
|
const newConfig = { ...localConfig, [field]: value };
|
||||||
setLocalConfig(newConfig);
|
setLocalConfig(newConfig);
|
||||||
onUpdateProperty("webTypeConfig", newConfig);
|
onUpdateProperty("webTypeConfig", newConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 입력 필드용 업데이트 (로컬 상태만)
|
||||||
|
const updateConfigLocal = (field: keyof EntityTypeConfig, value: any) => {
|
||||||
|
setIsUserEditing(true);
|
||||||
|
setLocalConfig({ ...localConfig, [field]: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 입력 완료 시 부모에게 전달
|
||||||
|
const handleInputBlur = () => {
|
||||||
|
setIsUserEditing(false);
|
||||||
|
onUpdateProperty("webTypeConfig", localConfig);
|
||||||
|
};
|
||||||
|
|
||||||
// 필드 추가
|
// 필드 추가
|
||||||
const addDisplayField = () => {
|
const addDisplayField = () => {
|
||||||
if (!newFieldName.trim() || !newFieldLabel.trim()) return;
|
if (!newFieldName.trim() || !newFieldLabel.trim()) return;
|
||||||
|
|
@ -106,11 +121,18 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
updateConfig("displayFields", newFields);
|
updateConfig("displayFields", newFields);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 필드 업데이트
|
// 필드 업데이트 (입력 중)
|
||||||
const updateDisplayField = (index: number, field: keyof EntityField, value: any) => {
|
const updateDisplayField = (index: number, field: keyof EntityField, value: any) => {
|
||||||
|
setIsUserEditing(true);
|
||||||
const newFields = [...localConfig.displayFields];
|
const newFields = [...localConfig.displayFields];
|
||||||
newFields[index] = { ...newFields[index], [field]: value };
|
newFields[index] = { ...newFields[index], [field]: value };
|
||||||
updateConfig("displayFields", newFields);
|
setLocalConfig({ ...localConfig, displayFields: newFields });
|
||||||
|
};
|
||||||
|
|
||||||
|
// 필드 업데이트 완료 (onBlur)
|
||||||
|
const handleFieldBlur = () => {
|
||||||
|
setIsUserEditing(false);
|
||||||
|
onUpdateProperty("webTypeConfig", localConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 검색 필드 토글
|
// 검색 필드 토글
|
||||||
|
|
@ -163,7 +185,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<Database className="h-4 w-4" />
|
<Database className="h-4 w-4" />
|
||||||
엔티티 설정
|
엔티티 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -181,9 +203,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="entityType"
|
id="entityType"
|
||||||
value={localConfig.entityType || ""}
|
value={localConfig.entityType || ""}
|
||||||
onChange={(e) => updateConfig("entityType", e.target.value)}
|
onChange={(e) => updateConfigLocal("entityType", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="user, product, department..."
|
placeholder="user, product, department..."
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -196,7 +219,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => applyEntityType(entity.value)}
|
onClick={() => applyEntityType(entity.value)}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
{entity.label}
|
{entity.label}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -211,9 +234,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="apiEndpoint"
|
id="apiEndpoint"
|
||||||
value={localConfig.apiEndpoint || ""}
|
value={localConfig.apiEndpoint || ""}
|
||||||
onChange={(e) => updateConfig("apiEndpoint", e.target.value)}
|
onChange={(e) => updateConfigLocal("apiEndpoint", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="/api/entities/user"
|
placeholder="/api/entities/user"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -230,9 +254,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="valueField"
|
id="valueField"
|
||||||
value={localConfig.valueField || ""}
|
value={localConfig.valueField || ""}
|
||||||
onChange={(e) => updateConfig("valueField", e.target.value)}
|
onChange={(e) => updateConfigLocal("valueField", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="id"
|
placeholder="id"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -243,9 +268,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="labelField"
|
id="labelField"
|
||||||
value={localConfig.labelField || ""}
|
value={localConfig.labelField || ""}
|
||||||
onChange={(e) => updateConfig("labelField", e.target.value)}
|
onChange={(e) => updateConfigLocal("labelField", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="name"
|
placeholder="name"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -263,13 +289,13 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={newFieldName}
|
value={newFieldName}
|
||||||
onChange={(e) => setNewFieldName(e.target.value)}
|
onChange={(e) => setNewFieldName(e.target.value)}
|
||||||
placeholder="필드명"
|
placeholder="필드명"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={newFieldLabel}
|
value={newFieldLabel}
|
||||||
onChange={(e) => setNewFieldLabel(e.target.value)}
|
onChange={(e) => setNewFieldLabel(e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Select value={newFieldType} onValueChange={setNewFieldType}>
|
<Select value={newFieldType} onValueChange={setNewFieldType}>
|
||||||
<SelectTrigger className="w-24 text-xs">
|
<SelectTrigger className="w-24 text-xs">
|
||||||
|
|
@ -287,7 +313,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={addDisplayField}
|
onClick={addDisplayField}
|
||||||
disabled={!newFieldName.trim() || !newFieldLabel.trim()}
|
disabled={!newFieldName.trim() || !newFieldLabel.trim()}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
<Plus className="h-3 w-3" />
|
<Plus className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -302,19 +328,24 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<div key={index} className="flex items-center gap-2 rounded border p-2">
|
<div key={index} className="flex items-center gap-2 rounded border p-2">
|
||||||
<Switch
|
<Switch
|
||||||
checked={field.visible}
|
checked={field.visible}
|
||||||
onCheckedChange={(checked) => updateDisplayField(index, "visible", checked)}
|
onCheckedChange={(checked) => {
|
||||||
|
updateDisplayField(index, "visible", checked);
|
||||||
|
handleFieldBlur();
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={field.name}
|
value={field.name}
|
||||||
onChange={(e) => updateDisplayField(index, "name", e.target.value)}
|
onChange={(e) => updateDisplayField(index, "name", e.target.value)}
|
||||||
|
onBlur={handleFieldBlur}
|
||||||
placeholder="필드명"
|
placeholder="필드명"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={field.label}
|
value={field.label}
|
||||||
onChange={(e) => updateDisplayField(index, "label", e.target.value)}
|
onChange={(e) => updateDisplayField(index, "label", e.target.value)}
|
||||||
|
onBlur={handleFieldBlur}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Select value={field.type} onValueChange={(value) => updateDisplayField(index, "type", value)}>
|
<Select value={field.type} onValueChange={(value) => updateDisplayField(index, "type", value)}>
|
||||||
<SelectTrigger className="w-24 text-xs">
|
<SelectTrigger className="w-24 text-xs">
|
||||||
|
|
@ -332,7 +363,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
size="sm"
|
size="sm"
|
||||||
variant={localConfig.searchFields.includes(field.name) ? "default" : "outline"}
|
variant={localConfig.searchFields.includes(field.name) ? "default" : "outline"}
|
||||||
onClick={() => toggleSearchField(field.name)}
|
onClick={() => toggleSearchField(field.name)}
|
||||||
className="p-1 text-xs" style={{ fontSize: "12px" }}
|
className="p-1 text-xs"
|
||||||
title={localConfig.searchFields.includes(field.name) ? "검색 필드에서 제거" : "검색 필드로 추가"}
|
title={localConfig.searchFields.includes(field.name) ? "검색 필드에서 제거" : "검색 필드로 추가"}
|
||||||
>
|
>
|
||||||
<Search className="h-3 w-3" />
|
<Search className="h-3 w-3" />
|
||||||
|
|
@ -341,7 +372,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
onClick={() => removeDisplayField(index)}
|
onClick={() => removeDisplayField(index)}
|
||||||
className="p-1 text-xs" style={{ fontSize: "12px" }}
|
className="p-1 text-xs"
|
||||||
>
|
>
|
||||||
<Trash2 className="h-3 w-3" />
|
<Trash2 className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -362,9 +393,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="placeholder"
|
id="placeholder"
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfigLocal("placeholder", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="엔티티를 선택하세요"
|
placeholder="엔티티를 선택하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -375,9 +407,10 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
<Input
|
<Input
|
||||||
id="emptyMessage"
|
id="emptyMessage"
|
||||||
value={localConfig.emptyMessage || ""}
|
value={localConfig.emptyMessage || ""}
|
||||||
onChange={(e) => updateConfig("emptyMessage", e.target.value)}
|
onChange={(e) => updateConfigLocal("emptyMessage", e.target.value)}
|
||||||
|
onBlur={handleInputBlur}
|
||||||
placeholder="검색 결과가 없습니다"
|
placeholder="검색 결과가 없습니다"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -393,7 +426,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("minSearchLength", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("minSearchLength", parseInt(e.target.value))}
|
||||||
min={0}
|
min={0}
|
||||||
max={10}
|
max={10}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -408,7 +441,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("pageSize", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("pageSize", parseInt(e.target.value))}
|
||||||
min={5}
|
min={5}
|
||||||
max={100}
|
max={100}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -462,7 +495,7 @@ export const EntityConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder='{"status": "active", "department": "IT"}'
|
placeholder='{"status": "active", "department": "IT"}'
|
||||||
className="font-mono text-xs" style={{ fontSize: "12px" }}
|
className="font-mono text-xs"
|
||||||
rows={3}
|
rows={3}
|
||||||
/>
|
/>
|
||||||
<p className="text-muted-foreground text-xs">API 요청에 추가될 필터 조건을 JSON 형태로 입력하세요.</p>
|
<p className="text-muted-foreground text-xs">API 요청에 추가될 필터 조건을 JSON 형태로 입력하세요.</p>
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<Upload className="h-4 w-4" />
|
<Upload className="h-4 w-4" />
|
||||||
파일 업로드 설정
|
파일 업로드 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -133,7 +133,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.uploadText || ""}
|
value={localConfig.uploadText || ""}
|
||||||
onChange={(e) => updateConfig("uploadText", e.target.value)}
|
onChange={(e) => updateConfig("uploadText", e.target.value)}
|
||||||
placeholder="파일을 선택하거나 여기에 드래그하세요"
|
placeholder="파일을 선택하거나 여기에 드래그하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.browseText || ""}
|
value={localConfig.browseText || ""}
|
||||||
onChange={(e) => updateConfig("browseText", e.target.value)}
|
onChange={(e) => updateConfig("browseText", e.target.value)}
|
||||||
placeholder="파일 선택"
|
placeholder="파일 선택"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -196,7 +196,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
min={0.1}
|
min={0.1}
|
||||||
max={1024}
|
max={1024}
|
||||||
step={0.1}
|
step={0.1}
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<span className="text-muted-foreground text-xs">MB</span>
|
<span className="text-muted-foreground text-xs">MB</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -214,7 +214,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("maxFiles", parseInt(e.target.value))}
|
onChange={(e) => updateConfig("maxFiles", parseInt(e.target.value))}
|
||||||
min={1}
|
min={1}
|
||||||
max={100}
|
max={100}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -257,7 +257,7 @@ export const FileConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={newFileType}
|
value={newFileType}
|
||||||
onChange={(e) => setNewFileType(e.target.value)}
|
onChange={(e) => setNewFileType(e.target.value)}
|
||||||
placeholder=".pdf 또는 pdf"
|
placeholder=".pdf 또는 pdf"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" onClick={addFileType} disabled={!newFileType.trim()} className="text-xs">
|
<Button size="sm" onClick={addFileType} disabled={!newFileType.trim()} className="text-xs">
|
||||||
추가
|
추가
|
||||||
|
|
|
||||||
|
|
@ -236,11 +236,11 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<h4 className="flex items-center gap-2 text-xs font-medium" style={{ fontSize: "12px" }}>
|
<h4 className="flex items-center gap-2 text-xs font-medium">
|
||||||
<Workflow className="h-4 w-4" />
|
<Workflow className="h-4 w-4" />
|
||||||
플로우 단계별 표시 설정
|
플로우 단계별 표시 설정
|
||||||
</h4>
|
</h4>
|
||||||
<p className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<p className="text-muted-foreground text-xs">
|
||||||
플로우의 특정 단계에서만 이 버튼을 표시하거나 숨길 수 있습니다
|
플로우의 특정 단계에서만 이 버튼을 표시하거나 숨길 수 있습니다
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -256,7 +256,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
setTimeout(() => applyConfig(), 0);
|
setTimeout(() => applyConfig(), 0);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="flow-control-enabled" className="text-xs font-medium" style={{ fontSize: "12px" }}>
|
<Label htmlFor="flow-control-enabled" className="text-xs font-medium">
|
||||||
플로우 단계에 따라 버튼 표시 제어
|
플로우 단계에 따라 버튼 표시 제어
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -265,7 +265,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
<>
|
<>
|
||||||
{/* 대상 플로우 선택 */}
|
{/* 대상 플로우 선택 */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-xs font-medium" style={{ fontSize: "12px" }}>
|
<Label className="text-xs font-medium">
|
||||||
대상 플로우
|
대상 플로우
|
||||||
</Label>
|
</Label>
|
||||||
<Select
|
<Select
|
||||||
|
|
@ -275,7 +275,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
setTimeout(() => applyConfig(), 0);
|
setTimeout(() => applyConfig(), 0);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-6 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 text-xs">
|
||||||
<SelectValue placeholder="플로우 위젯 선택" />
|
<SelectValue placeholder="플로우 위젯 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -283,7 +283,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
const flowConfig = (fw as any).componentConfig || {};
|
const flowConfig = (fw as any).componentConfig || {};
|
||||||
const flowName = flowConfig.flowName || `플로우 ${fw.id}`;
|
const flowName = flowConfig.flowName || `플로우 ${fw.id}`;
|
||||||
return (
|
return (
|
||||||
<SelectItem key={fw.id} value={fw.id} style={{ fontSize: "12px" }}>
|
<SelectItem key={fw.id} value={fw.id} className="text-xs">
|
||||||
{flowName}
|
{flowName}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
);
|
);
|
||||||
|
|
@ -298,7 +298,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
{/* 단계 선택 */}
|
{/* 단계 선택 */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label className="text-xs font-medium" style={{ fontSize: "12px" }}>
|
<Label className="text-xs font-medium">
|
||||||
표시할 단계
|
표시할 단계
|
||||||
</Label>
|
</Label>
|
||||||
<div className="flex gap-1">
|
<div className="flex gap-1">
|
||||||
|
|
@ -307,7 +307,6 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={selectAll}
|
onClick={selectAll}
|
||||||
className="h-7 px-2 text-xs"
|
className="h-7 px-2 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
모두 선택
|
모두 선택
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -316,7 +315,6 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={selectNone}
|
onClick={selectNone}
|
||||||
className="h-7 px-2 text-xs"
|
className="h-7 px-2 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
모두 해제
|
모두 해제
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -325,7 +323,6 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={invertSelection}
|
onClick={invertSelection}
|
||||||
className="h-7 px-2 text-xs"
|
className="h-7 px-2 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
반전
|
반전
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -347,9 +344,8 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
<Label
|
<Label
|
||||||
htmlFor={`step-${step.id}`}
|
htmlFor={`step-${step.id}`}
|
||||||
className="flex flex-1 items-center gap-2 text-xs"
|
className="flex flex-1 items-center gap-2 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<Badge variant="outline" className="text-xs" style={{ fontSize: "12px" }}>
|
<Badge variant="outline" className="text-xs">
|
||||||
Step {step.stepOrder}
|
Step {step.stepOrder}
|
||||||
</Badge>
|
</Badge>
|
||||||
<span>{step.stepName}</span>
|
<span>{step.stepName}</span>
|
||||||
|
|
@ -363,7 +359,7 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
|
|
||||||
{/* 정렬 방식 */}
|
{/* 정렬 방식 */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="group-align" className="text-xs font-medium" style={{ fontSize: "12px" }}>
|
<Label htmlFor="group-align" className="text-xs font-medium">
|
||||||
정렬 방식
|
정렬 방식
|
||||||
</Label>
|
</Label>
|
||||||
<Select
|
<Select
|
||||||
|
|
@ -373,23 +369,23 @@ export const FlowVisibilityConfigPanel: React.FC<FlowVisibilityConfigPanelProps>
|
||||||
onUpdateProperty("webTypeConfig.flowVisibilityConfig.groupAlign", value);
|
onUpdateProperty("webTypeConfig.flowVisibilityConfig.groupAlign", value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger id="group-align" className="h-6 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger id="group-align" className="h-6 text-xs">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="start" style={{ fontSize: "12px" }}>
|
<SelectItem value="start" className="text-xs">
|
||||||
시작점 정렬
|
시작점 정렬
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="center" style={{ fontSize: "12px" }}>
|
<SelectItem value="center" className="text-xs">
|
||||||
중앙 정렬
|
중앙 정렬
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="end" style={{ fontSize: "12px" }}>
|
<SelectItem value="end" className="text-xs">
|
||||||
끝점 정렬
|
끝점 정렬
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="space-between" style={{ fontSize: "12px" }}>
|
<SelectItem value="space-between" className="text-xs">
|
||||||
양 끝 정렬
|
양 끝 정렬
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="space-around" style={{ fontSize: "12px" }}>
|
<SelectItem value="space-around" className="text-xs">
|
||||||
균등 배분
|
균등 배분
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export function FlowWidgetConfigPanel({ config = {}, onChange }: FlowWidgetConfi
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div className="flex items-center gap-2 rounded-md border px-3 py-2">
|
<div className="flex items-center gap-2 rounded-md border px-3 py-2">
|
||||||
<Loader2 className="h-4 w-4 animate-spin" />
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>로딩 중...</span>
|
<span className="text-muted-foreground text-xs">로딩 중...</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>숫자 설정</CardTitle>
|
<CardTitle className="flex items-center gap-2 text-xs">숫자 설정</CardTitle>
|
||||||
<CardDescription className="text-xs">숫자 입력 필드의 세부 설정을 관리합니다.</CardDescription>
|
<CardDescription className="text-xs">숫자 입력 필드의 세부 설정을 관리합니다.</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
|
|
@ -73,7 +73,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="숫자를 입력하세요"
|
placeholder="숫자를 입력하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.min ?? ""}
|
value={localConfig.min ?? ""}
|
||||||
onChange={(e) => updateConfig("min", e.target.value ? parseFloat(e.target.value) : undefined)}
|
onChange={(e) => updateConfig("min", e.target.value ? parseFloat(e.target.value) : undefined)}
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -101,7 +101,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.max ?? ""}
|
value={localConfig.max ?? ""}
|
||||||
onChange={(e) => updateConfig("max", e.target.value ? parseFloat(e.target.value) : undefined)}
|
onChange={(e) => updateConfig("max", e.target.value ? parseFloat(e.target.value) : undefined)}
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -118,7 +118,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
placeholder="1"
|
placeholder="1"
|
||||||
min="0"
|
min="0"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-muted-foreground text-xs">증가/감소 버튼 클릭 시 변경되는 값의 크기</p>
|
<p className="text-muted-foreground text-xs">증가/감소 버튼 클릭 시 변경되는 값의 크기</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -158,7 +158,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
placeholder="2"
|
placeholder="2"
|
||||||
min="0"
|
min="0"
|
||||||
max="10"
|
max="10"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -223,7 +223,7 @@ export const NumberConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
min={localConfig.min}
|
min={localConfig.min}
|
||||||
max={localConfig.max}
|
max={localConfig.max}
|
||||||
step={localConfig.step}
|
step={localConfig.step}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<div className="text-muted-foreground mt-2 text-xs">
|
<div className="text-muted-foreground mt-2 text-xs">
|
||||||
{localConfig.format === "currency" && "통화 형식으로 표시됩니다."}
|
{localConfig.format === "currency" && "통화 형식으로 표시됩니다."}
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<Radio className="h-4 w-4" />
|
<Radio className="h-4 w-4" />
|
||||||
라디오버튼 설정
|
라디오버튼 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -188,7 +188,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.groupLabel || ""}
|
value={localConfig.groupLabel || ""}
|
||||||
onChange={(e) => updateConfig("groupLabel", e.target.value)}
|
onChange={(e) => updateConfig("groupLabel", e.target.value)}
|
||||||
placeholder="라디오버튼 그룹 제목"
|
placeholder="라디오버튼 그룹 제목"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -201,7 +201,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.groupName || ""}
|
value={localConfig.groupName || ""}
|
||||||
onChange={(e) => updateConfig("groupName", e.target.value)}
|
onChange={(e) => updateConfig("groupName", e.target.value)}
|
||||||
placeholder="자동 생성 (필드명 기반)"
|
placeholder="자동 생성 (필드명 기반)"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-muted-foreground text-xs">비워두면 필드명을 기반으로 자동 생성됩니다.</p>
|
<p className="text-muted-foreground text-xs">비워두면 필드명을 기반으로 자동 생성됩니다.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -252,19 +252,19 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={newOptionLabel}
|
value={newOptionLabel}
|
||||||
onChange={(e) => setNewOptionLabel(e.target.value)}
|
onChange={(e) => setNewOptionLabel(e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={newOptionValue}
|
value={newOptionValue}
|
||||||
onChange={(e) => setNewOptionValue(e.target.value)}
|
onChange={(e) => setNewOptionValue(e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={addOption}
|
onClick={addOption}
|
||||||
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
<Plus className="h-3 w-3" />
|
<Plus className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -278,7 +278,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={bulkOptions}
|
value={bulkOptions}
|
||||||
onChange={(e) => setBulkOptions(e.target.value)}
|
onChange={(e) => setBulkOptions(e.target.value)}
|
||||||
placeholder="한 줄당 하나씩 입력하세요. 라벨만 입력하면 값과 동일하게 설정됩니다. 라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다. 예시: 서울 부산 대구시|daegu"
|
placeholder="한 줄당 하나씩 입력하세요. 라벨만 입력하면 값과 동일하게 설정됩니다. 라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다. 예시: 서울 부산 대구시|daegu"
|
||||||
className="h-20 text-xs" style={{ fontSize: "12px" }}
|
className="h-20 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
|
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
|
||||||
옵션 추가
|
옵션 추가
|
||||||
|
|
@ -295,13 +295,13 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={option.label}
|
value={option.label}
|
||||||
onChange={(e) => updateOption(index, "label", e.target.value)}
|
onChange={(e) => updateOption(index, "label", e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={option.value}
|
value={option.value}
|
||||||
onChange={(e) => updateOption(index, "value", e.target.value)}
|
onChange={(e) => updateOption(index, "value", e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Switch
|
<Switch
|
||||||
checked={!option.disabled}
|
checked={!option.disabled}
|
||||||
|
|
@ -328,7 +328,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
id="defaultValue"
|
id="defaultValue"
|
||||||
value={localConfig.defaultValue || ""}
|
value={localConfig.defaultValue || ""}
|
||||||
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
||||||
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
|
className="w-full rounded-md border px-3 py-1 text-xs"
|
||||||
>
|
>
|
||||||
<option value="">선택하지 않음</option>
|
<option value="">선택하지 않음</option>
|
||||||
{localConfig.options.map((option, index) => (
|
{localConfig.options.map((option, index) => (
|
||||||
|
|
@ -390,7 +390,7 @@ export const RadioConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
disabled={localConfig.readonly || option.disabled}
|
disabled={localConfig.readonly || option.disabled}
|
||||||
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
|
required={localConfig.required && index === 0} // 첫 번째에만 required 표시
|
||||||
defaultChecked={localConfig.defaultValue === option.value}
|
defaultChecked={localConfig.defaultValue === option.value}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor={`preview-radio-${index}`} className="text-xs">
|
<Label htmlFor={`preview-radio-${index}`} className="text-xs">
|
||||||
{option.label}
|
{option.label}
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<List className="h-4 w-4" />
|
<List className="h-4 w-4" />
|
||||||
선택박스 설정
|
선택박스 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -173,7 +173,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="선택하세요"
|
placeholder="선택하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -186,7 +186,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.emptyMessage || ""}
|
value={localConfig.emptyMessage || ""}
|
||||||
onChange={(e) => updateConfig("emptyMessage", e.target.value)}
|
onChange={(e) => updateConfig("emptyMessage", e.target.value)}
|
||||||
placeholder="선택 가능한 옵션이 없습니다"
|
placeholder="선택 가능한 옵션이 없습니다"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -247,19 +247,19 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={newOptionLabel}
|
value={newOptionLabel}
|
||||||
onChange={(e) => setNewOptionLabel(e.target.value)}
|
onChange={(e) => setNewOptionLabel(e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={newOptionValue}
|
value={newOptionValue}
|
||||||
onChange={(e) => setNewOptionValue(e.target.value)}
|
onChange={(e) => setNewOptionValue(e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={addOption}
|
onClick={addOption}
|
||||||
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
disabled={!newOptionLabel.trim() || !newOptionValue.trim()}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
<Plus className="h-3 w-3" />
|
<Plus className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -273,7 +273,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={bulkOptions}
|
value={bulkOptions}
|
||||||
onChange={(e) => setBulkOptions(e.target.value)}
|
onChange={(e) => setBulkOptions(e.target.value)}
|
||||||
placeholder="한 줄당 하나씩 입력하세요. 라벨만 입력하면 값과 동일하게 설정됩니다. 라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다. 예시: 서울 부산 대구시|daegu"
|
placeholder="한 줄당 하나씩 입력하세요. 라벨만 입력하면 값과 동일하게 설정됩니다. 라벨|값 형식으로 입력하면 별도 값을 설정할 수 있습니다. 예시: 서울 부산 대구시|daegu"
|
||||||
className="h-20 text-xs" style={{ fontSize: "12px" }}
|
className="h-20 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
|
<Button size="sm" onClick={addBulkOptions} disabled={!bulkOptions.trim()} className="text-xs">
|
||||||
옵션 추가
|
옵션 추가
|
||||||
|
|
@ -290,13 +290,13 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={option.label}
|
value={option.label}
|
||||||
onChange={(e) => updateOption(index, "label", e.target.value)}
|
onChange={(e) => updateOption(index, "label", e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
value={option.value}
|
value={option.value}
|
||||||
onChange={(e) => updateOption(index, "value", e.target.value)}
|
onChange={(e) => updateOption(index, "value", e.target.value)}
|
||||||
placeholder="값"
|
placeholder="값"
|
||||||
className="flex-1 text-xs" style={{ fontSize: "12px" }}
|
className="flex-1 text-xs"
|
||||||
/>
|
/>
|
||||||
<Switch
|
<Switch
|
||||||
checked={!option.disabled}
|
checked={!option.disabled}
|
||||||
|
|
@ -323,7 +323,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
id="defaultValue"
|
id="defaultValue"
|
||||||
value={localConfig.defaultValue || ""}
|
value={localConfig.defaultValue || ""}
|
||||||
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
||||||
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
|
className="w-full rounded-md border px-3 py-1 text-xs"
|
||||||
>
|
>
|
||||||
<option value="">선택하지 않음</option>
|
<option value="">선택하지 않음</option>
|
||||||
{localConfig.options.map((option, index) => (
|
{localConfig.options.map((option, index) => (
|
||||||
|
|
@ -376,7 +376,7 @@ export const SelectConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
disabled={localConfig.readonly}
|
disabled={localConfig.readonly}
|
||||||
required={localConfig.required}
|
required={localConfig.required}
|
||||||
multiple={localConfig.multiple}
|
multiple={localConfig.multiple}
|
||||||
className="w-full rounded-md border px-3 py-1 text-xs" style={{ fontSize: "12px" }}
|
className="w-full rounded-md border px-3 py-1 text-xs"
|
||||||
defaultValue={localConfig.defaultValue}
|
defaultValue={localConfig.defaultValue}
|
||||||
>
|
>
|
||||||
<option value="" disabled>
|
<option value="" disabled>
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,15 @@ export function TabsConfigPanel({ config, onChange }: TabsConfigPanelProps) {
|
||||||
loadScreens();
|
loadScreens();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 컴포넌트 변경 시 로컬 상태 동기화
|
// 컴포넌트 변경 시 로컬 상태 동기화 (초기화만, 입력 중에는 동기화하지 않음)
|
||||||
|
const [isUserEditing, setIsUserEditing] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLocalTabs(config.tabs || []);
|
// 사용자가 입력 중이 아닐 때만 동기화
|
||||||
}, [config.tabs]);
|
if (!isUserEditing) {
|
||||||
|
setLocalTabs(config.tabs || []);
|
||||||
|
}
|
||||||
|
}, [config.tabs, isUserEditing]);
|
||||||
|
|
||||||
// 탭 추가
|
// 탭 추가
|
||||||
const handleAddTab = () => {
|
const handleAddTab = () => {
|
||||||
|
|
@ -85,11 +90,18 @@ export function TabsConfigPanel({ config, onChange }: TabsConfigPanelProps) {
|
||||||
onChange({ ...config, tabs: updatedTabs });
|
onChange({ ...config, tabs: updatedTabs });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 탭 라벨 변경
|
// 탭 라벨 변경 (입력 중)
|
||||||
const handleLabelChange = (tabId: string, label: string) => {
|
const handleLabelChange = (tabId: string, label: string) => {
|
||||||
|
setIsUserEditing(true);
|
||||||
const updatedTabs = localTabs.map((tab) => (tab.id === tabId ? { ...tab, label } : tab));
|
const updatedTabs = localTabs.map((tab) => (tab.id === tabId ? { ...tab, label } : tab));
|
||||||
setLocalTabs(updatedTabs);
|
setLocalTabs(updatedTabs);
|
||||||
onChange({ ...config, tabs: updatedTabs });
|
// onChange는 onBlur에서 호출
|
||||||
|
};
|
||||||
|
|
||||||
|
// 탭 라벨 변경 완료 (포커스 아웃 시)
|
||||||
|
const handleLabelBlur = () => {
|
||||||
|
setIsUserEditing(false);
|
||||||
|
onChange({ ...config, tabs: localTabs });
|
||||||
};
|
};
|
||||||
|
|
||||||
// 탭 화면 선택
|
// 탭 화면 선택
|
||||||
|
|
@ -271,6 +283,7 @@ export function TabsConfigPanel({ config, onChange }: TabsConfigPanelProps) {
|
||||||
<Input
|
<Input
|
||||||
value={tab.label}
|
value={tab.label}
|
||||||
onChange={(e) => handleLabelChange(tab.id, e.target.value)}
|
onChange={(e) => handleLabelChange(tab.id, e.target.value)}
|
||||||
|
onBlur={handleLabelBlur}
|
||||||
placeholder="탭 이름"
|
placeholder="탭 이름"
|
||||||
className="h-8 text-xs sm:h-9 sm:text-sm"
|
className="h-8 text-xs sm:h-9 sm:text-sm"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>텍스트 설정</CardTitle>
|
<CardTitle className="flex items-center gap-2 text-xs">텍스트 설정</CardTitle>
|
||||||
<CardDescription className="text-xs">텍스트 입력 필드의 세부 설정을 관리합니다.</CardDescription>
|
<CardDescription className="text-xs">텍스트 입력 필드의 세부 설정을 관리합니다.</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
|
|
@ -72,7 +72,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="입력 안내 텍스트"
|
placeholder="입력 안내 텍스트"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("minLength", e.target.value ? parseInt(e.target.value) : undefined)}
|
onChange={(e) => updateConfig("minLength", e.target.value ? parseInt(e.target.value) : undefined)}
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
min="0"
|
min="0"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|
@ -102,7 +102,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
onChange={(e) => updateConfig("maxLength", e.target.value ? parseInt(e.target.value) : undefined)}
|
onChange={(e) => updateConfig("maxLength", e.target.value ? parseInt(e.target.value) : undefined)}
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
min="1"
|
min="1"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -141,7 +141,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.pattern || ""}
|
value={localConfig.pattern || ""}
|
||||||
onChange={(e) => updateConfig("pattern", e.target.value)}
|
onChange={(e) => updateConfig("pattern", e.target.value)}
|
||||||
placeholder="예: [A-Za-z0-9]+"
|
placeholder="예: [A-Za-z0-9]+"
|
||||||
className="font-mono text-xs" style={{ fontSize: "12px" }}
|
className="font-mono text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-muted-foreground text-xs">JavaScript 정규식 패턴을 입력하세요.</p>
|
<p className="text-muted-foreground text-xs">JavaScript 정규식 패턴을 입력하세요.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -219,7 +219,7 @@ export const TextConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
minLength={localConfig.minLength}
|
minLength={localConfig.minLength}
|
||||||
pattern={localConfig.pattern}
|
pattern={localConfig.pattern}
|
||||||
autoComplete={localConfig.autoComplete}
|
autoComplete={localConfig.autoComplete}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center gap-2 text-xs">
|
||||||
<AlignLeft className="h-4 w-4" />
|
<AlignLeft className="h-4 w-4" />
|
||||||
텍스트영역 설정
|
텍스트영역 설정
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -88,7 +88,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.placeholder || ""}
|
value={localConfig.placeholder || ""}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="내용을 입력하세요"
|
placeholder="내용을 입력하세요"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
value={localConfig.defaultValue || ""}
|
value={localConfig.defaultValue || ""}
|
||||||
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
onChange={(e) => updateConfig("defaultValue", e.target.value)}
|
||||||
placeholder="기본 텍스트 내용"
|
placeholder="기본 텍스트 내용"
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
rows={3}
|
rows={3}
|
||||||
/>
|
/>
|
||||||
{localConfig.showCharCount && (
|
{localConfig.showCharCount && (
|
||||||
|
|
@ -151,7 +151,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
placeholder="자동 (CSS로 제어)"
|
placeholder="자동 (CSS로 제어)"
|
||||||
min={10}
|
min={10}
|
||||||
max={200}
|
max={200}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-muted-foreground text-xs">비워두면 CSS width로 제어됩니다.</p>
|
<p className="text-muted-foreground text-xs">비워두면 CSS width로 제어됩니다.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -203,7 +203,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
placeholder="제한 없음"
|
placeholder="제한 없음"
|
||||||
min={0}
|
min={0}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
placeholder="제한 없음"
|
placeholder="제한 없음"
|
||||||
min={1}
|
min={1}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -333,7 +333,7 @@ export const TextareaConfigPanel: React.FC<WebTypeConfigPanelProps> = ({
|
||||||
resize: localConfig.resizable ? "both" : "none",
|
resize: localConfig.resizable ? "both" : "none",
|
||||||
minHeight: localConfig.autoHeight ? "auto" : undefined,
|
minHeight: localConfig.autoHeight ? "auto" : undefined,
|
||||||
}}
|
}}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
wrap={localConfig.wrap}
|
wrap={localConfig.wrap}
|
||||||
/>
|
/>
|
||||||
{localConfig.showCharCount && (
|
{localConfig.showCharCount && (
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ export const FlowButtonGroupDialog: React.FC<FlowButtonGroupDialogProps> = ({
|
||||||
max={100}
|
max={100}
|
||||||
value={gap}
|
value={gap}
|
||||||
onChange={(e) => setGap(Number(e.target.value))}
|
onChange={(e) => setGap(Number(e.target.value))}
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
<Badge variant="outline" className="text-xs">
|
<Badge variant="outline" className="text-xs">
|
||||||
{gap}px
|
{gap}px
|
||||||
|
|
@ -109,7 +109,7 @@ export const FlowButtonGroupDialog: React.FC<FlowButtonGroupDialogProps> = ({
|
||||||
정렬 방식
|
정렬 방식
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={align} onValueChange={(value: any) => setAlign(value)}>
|
<Select value={align} onValueChange={(value: any) => setAlign(value)}>
|
||||||
<SelectTrigger id="align" className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger id="align" className="h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ export function ComponentsPanel({
|
||||||
onSearchChange(value);
|
onSearchChange(value);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="h-8 pl-8 text-xs" style={{ fontSize: "12px" }}
|
className="h-8 pl-8 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -458,7 +458,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
updateSettings({ options: newOptions });
|
updateSettings({ options: newOptions });
|
||||||
}}
|
}}
|
||||||
placeholder="옵션명"
|
placeholder="옵션명"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -483,7 +483,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
const newOption = { label: "", value: "" };
|
const newOption = { label: "", value: "" };
|
||||||
updateSettings({ options: [...(localSettings.options || []), newOption] });
|
updateSettings({ options: [...(localSettings.options || []), newOption] });
|
||||||
}}
|
}}
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
>
|
>
|
||||||
<Plus className="mr-1 h-3 w-3" />
|
<Plus className="mr-1 h-3 w-3" />
|
||||||
옵션 추가
|
옵션 추가
|
||||||
|
|
@ -548,7 +548,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.min || ""}
|
value={localSettings.min || ""}
|
||||||
onChange={(e) => updateSettings({ min: e.target.value ? Number(e.target.value) : undefined })}
|
onChange={(e) => updateSettings({ min: e.target.value ? Number(e.target.value) : undefined })}
|
||||||
placeholder="최소값"
|
placeholder="최소값"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -558,7 +558,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.max || ""}
|
value={localSettings.max || ""}
|
||||||
onChange={(e) => updateSettings({ max: e.target.value ? Number(e.target.value) : undefined })}
|
onChange={(e) => updateSettings({ max: e.target.value ? Number(e.target.value) : undefined })}
|
||||||
placeholder="최대값"
|
placeholder="최대값"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -571,7 +571,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.step || "0.01"}
|
value={localSettings.step || "0.01"}
|
||||||
onChange={(e) => updateSettings({ step: e.target.value })}
|
onChange={(e) => updateSettings({ step: e.target.value })}
|
||||||
placeholder="0.01"
|
placeholder="0.01"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -589,7 +589,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
type="date"
|
type="date"
|
||||||
value={localSettings.minDate || ""}
|
value={localSettings.minDate || ""}
|
||||||
onChange={(e) => updateSettings({ minDate: e.target.value })}
|
onChange={(e) => updateSettings({ minDate: e.target.value })}
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -598,7 +598,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
type="date"
|
type="date"
|
||||||
value={localSettings.maxDate || ""}
|
value={localSettings.maxDate || ""}
|
||||||
onChange={(e) => updateSettings({ maxDate: e.target.value })}
|
onChange={(e) => updateSettings({ maxDate: e.target.value })}
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -626,7 +626,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.maxLength || ""}
|
value={localSettings.maxLength || ""}
|
||||||
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
|
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
|
||||||
placeholder="최대 문자 수"
|
placeholder="최대 문자 수"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -635,7 +635,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.placeholder || ""}
|
value={localSettings.placeholder || ""}
|
||||||
onChange={(e) => updateSettings({ placeholder: e.target.value })}
|
onChange={(e) => updateSettings({ placeholder: e.target.value })}
|
||||||
placeholder="입력 안내 텍스트"
|
placeholder="입력 안내 텍스트"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -652,7 +652,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.rows || "3"}
|
value={localSettings.rows || "3"}
|
||||||
onChange={(e) => updateSettings({ rows: Number(e.target.value) })}
|
onChange={(e) => updateSettings({ rows: Number(e.target.value) })}
|
||||||
placeholder="3"
|
placeholder="3"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -662,7 +662,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.maxLength || ""}
|
value={localSettings.maxLength || ""}
|
||||||
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
|
onChange={(e) => updateSettings({ maxLength: e.target.value ? Number(e.target.value) : undefined })}
|
||||||
placeholder="최대 문자 수"
|
placeholder="최대 문자 수"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -678,7 +678,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.accept || ""}
|
value={localSettings.accept || ""}
|
||||||
onChange={(e) => updateSettings({ accept: e.target.value })}
|
onChange={(e) => updateSettings({ accept: e.target.value })}
|
||||||
placeholder=".jpg,.png,.pdf"
|
placeholder=".jpg,.png,.pdf"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -688,7 +688,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
value={localSettings.maxSize ? localSettings.maxSize / 1024 / 1024 : "10"}
|
value={localSettings.maxSize ? localSettings.maxSize / 1024 / 1024 : "10"}
|
||||||
onChange={(e) => updateSettings({ maxSize: Number(e.target.value) * 1024 * 1024 })}
|
onChange={(e) => updateSettings({ maxSize: Number(e.target.value) * 1024 * 1024 })}
|
||||||
placeholder="10"
|
placeholder="10"
|
||||||
className="h-7 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
|
|
@ -1132,7 +1132,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
{/* 기본 설정 */}
|
{/* 기본 설정 */}
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center space-x-2 text-xs">
|
||||||
<Settings className="h-4 w-4" />
|
<Settings className="h-4 w-4" />
|
||||||
<span>기본 설정</span>
|
<span>기본 설정</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -1184,7 +1184,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
onUpdateComponent({ enableAdd: checked as boolean });
|
onUpdateComponent({ enableAdd: checked as boolean });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="enable-add" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="enable-add" className="text-xs">
|
||||||
데이터 추가 기능
|
데이터 추가 기능
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1198,7 +1198,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
onUpdateComponent({ enableEdit: checked as boolean });
|
onUpdateComponent({ enableEdit: checked as boolean });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="enable-edit" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="enable-edit" className="text-xs">
|
||||||
데이터 수정 기능
|
데이터 수정 기능
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1212,7 +1212,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
onUpdateComponent({ enableDelete: checked as boolean });
|
onUpdateComponent({ enableDelete: checked as boolean });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="enable-delete" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="enable-delete" className="text-xs">
|
||||||
데이터 삭제 기능
|
데이터 삭제 기능
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1220,7 +1220,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
|
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="add-button-text" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="add-button-text" className="text-xs">
|
||||||
추가 버튼 텍스트
|
추가 버튼 텍스트
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1233,12 +1233,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
placeholder="추가"
|
placeholder="추가"
|
||||||
disabled={!localValues.enableAdd}
|
disabled={!localValues.enableAdd}
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-button-text" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="edit-button-text" className="text-xs">
|
||||||
수정 버튼 텍스트
|
수정 버튼 텍스트
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1251,12 +1251,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
placeholder="수정"
|
placeholder="수정"
|
||||||
disabled={!localValues.enableEdit}
|
disabled={!localValues.enableEdit}
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="delete-button-text" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="delete-button-text" className="text-xs">
|
||||||
삭제 버튼 텍스트
|
삭제 버튼 텍스트
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1269,7 +1269,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
placeholder="삭제"
|
placeholder="삭제"
|
||||||
disabled={!localValues.enableDelete}
|
disabled={!localValues.enableDelete}
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1284,7 +1284,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-title" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-title" className="text-xs">
|
||||||
모달 제목
|
모달 제목
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1298,12 +1298,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="새 데이터 추가"
|
placeholder="새 데이터 추가"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-width" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-width" className="text-xs">
|
||||||
모달 크기
|
모달 크기
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
|
|
@ -1328,7 +1328,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-description" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-description" className="text-xs">
|
||||||
모달 설명
|
모달 설명
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1342,13 +1342,13 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="모달에 표시될 설명을 입력하세요"
|
placeholder="모달에 표시될 설명을 입력하세요"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-layout" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-layout" className="text-xs">
|
||||||
레이아웃
|
레이아웃
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
|
|
@ -1370,7 +1370,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
|
|
||||||
{localValues.modalLayout === "grid" && (
|
{localValues.modalLayout === "grid" && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-grid-columns" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-grid-columns" className="text-xs">
|
||||||
그리드 컬럼 수
|
그리드 컬럼 수
|
||||||
</Label>
|
</Label>
|
||||||
<select
|
<select
|
||||||
|
|
@ -1394,7 +1394,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-submit-text" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-submit-text" className="text-xs">
|
||||||
제출 버튼 텍스트
|
제출 버튼 텍스트
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1408,12 +1408,12 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="추가"
|
placeholder="추가"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="modal-cancel-text" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="modal-cancel-text" className="text-xs">
|
||||||
취소 버튼 텍스트
|
취소 버튼 텍스트
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1427,7 +1427,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="취소"
|
placeholder="취소"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1441,7 +1441,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-modal-title" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="edit-modal-title" className="text-xs">
|
||||||
모달 제목
|
모달 제목
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1455,13 +1455,13 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="데이터 수정"
|
placeholder="데이터 수정"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-gray-500">비워두면 기본 제목이 표시됩니다</p>
|
<p className="text-xs text-gray-500">비워두면 기본 제목이 표시됩니다</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-modal-description" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="edit-modal-description" className="text-xs">
|
||||||
모달 설명
|
모달 설명
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -1475,7 +1475,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="선택한 데이터를 수정합니다"
|
placeholder="선택한 데이터를 수정합니다"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-gray-500">비워두면 설명이 표시되지 않습니다</p>
|
<p className="text-xs text-gray-500">비워두면 설명이 표시되지 않습니다</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1494,7 +1494,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
onUpdateComponent({ showSearchButton: checked as boolean });
|
onUpdateComponent({ showSearchButton: checked as boolean });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="show-search-button" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="show-search-button" className="text-xs">
|
||||||
검색 버튼 표시
|
검색 버튼 표시
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1509,7 +1509,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
onUpdateComponent({ enableExport: checked as boolean });
|
onUpdateComponent({ enableExport: checked as boolean });
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="enable-export" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="enable-export" className="text-xs">
|
||||||
내보내기 기능
|
내보내기 기능
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1521,7 +1521,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
<TabsContent value="columns" className="mt-4 max-h-[70vh] overflow-y-auto">
|
<TabsContent value="columns" className="mt-4 max-h-[70vh] overflow-y-auto">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center space-x-2 text-xs">
|
||||||
<Columns className="h-4 w-4" />
|
<Columns className="h-4 w-4" />
|
||||||
<span>컬럼 설정</span>
|
<span>컬럼 설정</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -1654,7 +1654,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder="표시명을 입력하세요"
|
placeholder="표시명을 입력하세요"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -1947,7 +1947,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
placeholder="고정값 입력..."
|
placeholder="고정값 입력..."
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -1967,7 +1967,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
<TabsContent value="filters" className="mt-4 max-h-[70vh] overflow-y-auto">
|
<TabsContent value="filters" className="mt-4 max-h-[70vh] overflow-y-auto">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center space-x-2 text-xs">
|
||||||
<Filter className="h-4 w-4" />
|
<Filter className="h-4 w-4" />
|
||||||
<span>필터 설정</span>
|
<span>필터 설정</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -1995,7 +1995,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
{component.filters.length === 0 ? (
|
{component.filters.length === 0 ? (
|
||||||
<div className="text-muted-foreground py-8 text-center">
|
<div className="text-muted-foreground py-8 text-center">
|
||||||
<Filter className="mx-auto mb-2 h-8 w-8 opacity-50" />
|
<Filter className="mx-auto mb-2 h-8 w-8 opacity-50" />
|
||||||
<p className="text-xs" style={{ fontSize: "12px" }}>필터가 없습니다</p>
|
<p className="text-xs">필터가 없습니다</p>
|
||||||
<p className="text-xs">컬럼을 추가하면 자동으로 필터가 생성됩니다</p>
|
<p className="text-xs">컬럼을 추가하면 자동으로 필터가 생성됩니다</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -2073,7 +2073,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
updateFilter(index, { label: newValue });
|
updateFilter(index, { label: newValue });
|
||||||
}}
|
}}
|
||||||
placeholder="필터 이름 입력..."
|
placeholder="필터 이름 입력..."
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-muted-foreground mt-1 text-xs">
|
<p className="text-muted-foreground mt-1 text-xs">
|
||||||
|
|
@ -2192,7 +2192,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
<TabsContent value="modal" className="mt-4 max-h-[70vh] overflow-y-auto">
|
<TabsContent value="modal" className="mt-4 max-h-[70vh] overflow-y-auto">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center space-x-2 text-xs" style={{ fontSize: "12px" }}>
|
<CardTitle className="flex items-center space-x-2 text-xs">
|
||||||
<Settings className="h-4 w-4" />
|
<Settings className="h-4 w-4" />
|
||||||
<span>모달 및 페이징 설정</span>
|
<span>모달 및 페이징 설정</span>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
|
@ -2342,7 +2342,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="show-page-size-selector" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="show-page-size-selector" className="text-xs">
|
||||||
페이지 크기 선택기 표시
|
페이지 크기 선택기 표시
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2362,7 +2362,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="show-page-info" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="show-page-info" className="text-xs">
|
||||||
페이지 정보 표시
|
페이지 정보 표시
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -2382,7 +2382,7 @@ const DataTableConfigPanelComponent: React.FC<DataTableConfigPanelProps> = ({
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="show-first-last" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="show-first-last" className="text-xs">
|
||||||
처음/마지막 버튼 표시
|
처음/마지막 버튼 표시
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -196,7 +195,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -211,7 +209,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, "layoutConfig.grid.gap", parseInt(e.target.value))
|
onUpdateProperty(layoutComponent.id, "layoutConfig.grid.gap", parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -256,7 +253,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="row">가로 (row)</option>
|
<option value="row">가로 (row)</option>
|
||||||
<option value="column">세로 (column)</option>
|
<option value="column">세로 (column)</option>
|
||||||
|
|
@ -316,7 +312,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-20 rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-20 rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
<span className="text-xs text-gray-500">개</span>
|
<span className="text-xs text-gray-500">개</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -332,7 +327,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, "layoutConfig.flexbox.gap", parseInt(e.target.value))
|
onUpdateProperty(layoutComponent.id, "layoutConfig.flexbox.gap", parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -348,7 +342,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
value={layoutComponent.layoutConfig?.split?.direction || "horizontal"}
|
value={layoutComponent.layoutConfig?.split?.direction || "horizontal"}
|
||||||
onChange={(e) => onUpdateProperty(layoutComponent.id, "layoutConfig.split.direction", e.target.value)}
|
onChange={(e) => onUpdateProperty(layoutComponent.id, "layoutConfig.split.direction", e.target.value)}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="horizontal">가로 분할</option>
|
<option value="horizontal">가로 분할</option>
|
||||||
<option value="vertical">세로 분할</option>
|
<option value="vertical">세로 분할</option>
|
||||||
|
|
@ -398,7 +391,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="">컬럼을 선택하세요</option>
|
<option value="">컬럼을 선택하세요</option>
|
||||||
{currentTable.columns?.map((column) => (
|
{currentTable.columns?.map((column) => (
|
||||||
|
|
@ -421,7 +413,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="">컬럼을 선택하세요</option>
|
<option value="">컬럼을 선택하세요</option>
|
||||||
{currentTable.columns?.map((column) => (
|
{currentTable.columns?.map((column) => (
|
||||||
|
|
@ -444,7 +435,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="">컬럼을 선택하세요</option>
|
<option value="">컬럼을 선택하세요</option>
|
||||||
{currentTable.columns?.map((column) => (
|
{currentTable.columns?.map((column) => (
|
||||||
|
|
@ -467,7 +457,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="">컬럼을 선택하세요</option>
|
<option value="">컬럼을 선택하세요</option>
|
||||||
{currentTable.columns?.map((column) => (
|
{currentTable.columns?.map((column) => (
|
||||||
|
|
@ -495,7 +484,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className="bg-primary text-primary-foreground hover:bg-primary/90 rounded px-2 py-1 text-xs"
|
className="bg-primary text-primary-foreground hover:bg-primary/90 rounded px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
+ 컬럼 추가
|
+ 컬럼 추가
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -519,7 +507,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className="flex-1 rounded border border-gray-300 px-2 py-1 text-xs"
|
className="flex-1 rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
<option value="">컬럼을 선택하세요</option>
|
<option value="">컬럼을 선택하세요</option>
|
||||||
{currentTable.columns?.map((col) => (
|
{currentTable.columns?.map((col) => (
|
||||||
|
|
@ -542,7 +529,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 rounded px-2 py-1 text-xs"
|
className="bg-destructive text-destructive-foreground hover:bg-destructive/90 rounded px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
삭제
|
삭제
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -578,7 +564,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardsPerRow", parseInt(e.target.value))
|
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardsPerRow", parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -593,7 +578,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardSpacing", parseInt(e.target.value))
|
onUpdateProperty(layoutComponent.id, "layoutConfig.card.cardSpacing", parseInt(e.target.value))
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -683,7 +667,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -711,7 +694,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, `zones.${index}.size.width`, e.target.value)
|
onUpdateProperty(layoutComponent.id, `zones.${index}.size.width`, e.target.value)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
placeholder="100%"
|
placeholder="100%"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -724,7 +706,6 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
onUpdateProperty(layoutComponent.id, `zones.${index}.size.height`, e.target.value)
|
onUpdateProperty(layoutComponent.id, `zones.${index}.size.height`, e.target.value)
|
||||||
}
|
}
|
||||||
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
className="w-full rounded border border-gray-300 px-2 py-1 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
placeholder="auto"
|
placeholder="auto"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -1007,7 +988,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
<h3 className="font-medium text-gray-900">컴포넌트 설정</h3>
|
<h3 className="font-medium text-gray-900">컴포넌트 설정</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center space-x-2">
|
<div className="mt-2 flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
타입:
|
타입:
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentType}</span>
|
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentType}</span>
|
||||||
|
|
@ -1057,7 +1038,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
<h3 className="font-medium text-gray-900">파일 컴포넌트 설정</h3>
|
<h3 className="font-medium text-gray-900">파일 컴포넌트 설정</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center space-x-2">
|
<div className="mt-2 flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
타입:
|
타입:
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-purple-100 px-2 py-1 text-xs font-medium text-purple-800">파일 업로드</span>
|
<span className="rounded bg-purple-100 px-2 py-1 text-xs font-medium text-purple-800">파일 업로드</span>
|
||||||
|
|
@ -1146,14 +1127,14 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
{/* 컴포넌트 정보 */}
|
{/* 컴포넌트 정보 */}
|
||||||
<div className="mb-4 space-y-2">
|
<div className="mb-4 space-y-2">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
컴포넌트:
|
컴포넌트:
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentId}</span>
|
<span className="rounded bg-green-100 px-2 py-1 text-xs font-medium text-green-800">{componentId}</span>
|
||||||
</div>
|
</div>
|
||||||
{webType && currentBaseInputType && (
|
{webType && currentBaseInputType && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
입력 타입:
|
입력 타입:
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
|
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
|
||||||
|
|
@ -1163,7 +1144,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
)}
|
)}
|
||||||
{selectedComponent.columnName && (
|
{selectedComponent.columnName && (
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
컬럼:
|
컬럼:
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-700">{selectedComponent.columnName}</span>
|
<span className="text-xs text-gray-700">{selectedComponent.columnName}</span>
|
||||||
|
|
@ -1375,7 +1356,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
<h3 className="font-medium text-gray-900">상세 설정</h3>
|
<h3 className="font-medium text-gray-900">상세 설정</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 flex items-center space-x-2">
|
<div className="mt-2 flex items-center space-x-2">
|
||||||
<span className="text-muted-foreground text-xs" style={{ fontSize: "12px" }}>
|
<span className="text-muted-foreground text-xs">
|
||||||
입력 타입:
|
입력 타입:
|
||||||
</span>
|
</span>
|
||||||
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
|
<span className="rounded bg-blue-100 px-2 py-1 text-xs font-medium text-blue-800">
|
||||||
|
|
@ -1390,7 +1371,7 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="block text-sm font-medium text-gray-700">세부 타입 선택</label>
|
<label className="block text-sm font-medium text-gray-700">세부 타입 선택</label>
|
||||||
<Select value={localDetailType} onValueChange={handleDetailTypeChange}>
|
<Select value={localDetailType} onValueChange={handleDetailTypeChange}>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0 bg-white text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 w-full px-2 py-0 bg-white text-xs">
|
||||||
<SelectValue placeholder="세부 타입을 선택하세요" />
|
<SelectValue placeholder="세부 타입을 선택하세요" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ export const FlowButtonGroupPanel: React.FC<FlowButtonGroupPanelProps> = ({
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={() => onSelectGroup(groupInfo.buttons.map((b) => b.id))}
|
onClick={() => onSelectGroup(groupInfo.buttons.map((b) => b.id))}
|
||||||
className="h-7 px-2 text-xs" style={{ fontSize: "12px" }}
|
className="h-7 px-2 text-xs"
|
||||||
>
|
>
|
||||||
선택
|
선택
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -152,7 +152,7 @@ export const FlowButtonGroupPanel: React.FC<FlowButtonGroupPanelProps> = ({
|
||||||
{groupInfo.buttons.map((button) => (
|
{groupInfo.buttons.map((button) => (
|
||||||
<div
|
<div
|
||||||
key={button.id}
|
key={button.id}
|
||||||
className="flex items-center gap-2 rounded bg-white px-2 py-1.5 text-xs" style={{ fontSize: "12px" }}
|
className="flex items-center gap-2 rounded bg-white px-2 py-1.5 text-xs"
|
||||||
>
|
>
|
||||||
<div className="h-2 w-2 rounded-full bg-blue-500" />
|
<div className="h-2 w-2 rounded-full bg-blue-500" />
|
||||||
<span className="flex-1 truncate font-medium">
|
<span className="flex-1 truncate font-medium">
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ export default function LayoutsPanel({
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<CardTitle className="text-xs" style={{ fontSize: "12px" }}>{layout.name}</CardTitle>
|
<CardTitle className="text-xs">{layout.name}</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="pt-0">
|
<CardContent className="pt-0">
|
||||||
{layout.description && (
|
{layout.description && (
|
||||||
|
|
|
||||||
|
|
@ -652,7 +652,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
|
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="required" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="required" className="text-xs">
|
||||||
필수 입력
|
필수 입력
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -668,7 +668,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
|
||||||
}}
|
}}
|
||||||
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
|
className="border-input bg-background text-primary focus:ring-ring h-4 w-4 rounded border focus:ring-2 focus:ring-offset-2"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="readonly" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="readonly" className="text-xs">
|
||||||
읽기 전용
|
읽기 전용
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -990,7 +990,7 @@ const PropertiesPanelComponent: React.FC<PropertiesPanelProps> = ({
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-accent col-span-2 rounded-lg p-3 text-center">
|
<div className="bg-accent col-span-2 rounded-lg p-3 text-center">
|
||||||
<p className="text-primary text-xs" style={{ fontSize: "12px" }}>카드 레이아웃은 자동으로 크기가 계산됩니다</p>
|
<p className="text-primary text-xs">카드 레이아웃은 자동으로 크기가 계산됩니다</p>
|
||||||
<p className="mt-1 text-xs text-blue-500">카드 개수와 간격 설정은 상세설정에서 조정하세요</p>
|
<p className="mt-1 text-xs text-blue-500">카드 개수와 간격 설정은 상세설정에서 조정하세요</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-xs font-medium">해상도 프리셋</Label>
|
<Label className="text-xs font-medium">해상도 프리셋</Label>
|
||||||
<Select value={selectedPreset} onValueChange={handlePresetChange}>
|
<Select value={selectedPreset} onValueChange={handlePresetChange}>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0" style={{ fontSize: "12px" }}>
|
<SelectTrigger className=" text-xsh-6 w-full px-2 py-0">
|
||||||
<SelectValue placeholder="해상도를 선택하세요" />
|
<SelectValue placeholder="해상도를 선택하세요" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -147,8 +147,7 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
|
||||||
placeholder="1920"
|
placeholder="1920"
|
||||||
min="1"
|
min="1"
|
||||||
step="1"
|
step="1"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -160,16 +159,14 @@ const ResolutionPanel: React.FC<ResolutionPanelProps> = ({ currentResolution, on
|
||||||
placeholder="1080"
|
placeholder="1080"
|
||||||
min="1"
|
min="1"
|
||||||
step="1"
|
step="1"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleCustomResolution}
|
onClick={handleCustomResolution}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
>
|
>
|
||||||
적용
|
적용
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export const RowSettingsPanel: React.FC<RowSettingsPanelProps> = ({ row, onUpdat
|
||||||
variant={row.gap === preset ? "default" : "outline"}
|
variant={row.gap === preset ? "default" : "outline"}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => onUpdateRow({ gap: preset })}
|
onClick={() => onUpdateRow({ gap: preset })}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
{GAP_PRESETS[preset].label}
|
{GAP_PRESETS[preset].label}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -130,7 +130,7 @@ export const RowSettingsPanel: React.FC<RowSettingsPanelProps> = ({ row, onUpdat
|
||||||
variant={row.padding === preset ? "default" : "outline"}
|
variant={row.padding === preset ? "default" : "outline"}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => onUpdateRow({ padding: preset })}
|
onClick={() => onUpdateRow({ padding: preset })}
|
||||||
className="text-xs" style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
>
|
>
|
||||||
{GAP_PRESETS[preset].label}
|
{GAP_PRESETS[preset].label}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
|
||||||
|
|
@ -528,7 +528,7 @@ export const TemplatesPanel: React.FC<TemplatesPanelProps> = ({ onDragStart }) =
|
||||||
<div className="flex items-center justify-between rounded-xl bg-amber-50/80 border border-amber-200/60 p-3 text-amber-800 mb-4">
|
<div className="flex items-center justify-between rounded-xl bg-amber-50/80 border border-amber-200/60 p-3 text-amber-800 mb-4">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Info className="h-4 w-4" />
|
<Info className="h-4 w-4" />
|
||||||
<span className="text-xs" style={{ fontSize: "12px" }}>템플릿 로딩 실패, 기본 템플릿 사용 중</span>
|
<span className="text-xs">템플릿 로딩 실패, 기본 템플릿 사용 중</span>
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" variant="outline" onClick={() => refetch()} className="border-amber-300 text-amber-700 hover:bg-amber-100">
|
<Button size="sm" variant="outline" onClick={() => refetch()} className="border-amber-300 text-amber-700 hover:bg-amber-100">
|
||||||
<RefreshCw className="h-4 w-4" />
|
<RefreshCw className="h-4 w-4" />
|
||||||
|
|
|
||||||
|
|
@ -718,8 +718,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
onChange={(e) => handleUpdate("label", e.target.value)}
|
onChange={(e) => handleUpdate("label", e.target.value)}
|
||||||
placeholder="라벨"
|
placeholder="라벨"
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -755,7 +753,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
step={1}
|
step={1}
|
||||||
placeholder="10"
|
placeholder="10"
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -769,8 +766,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
onChange={(e) => handleUpdate("placeholder", e.target.value)}
|
onChange={(e) => handleUpdate("placeholder", e.target.value)}
|
||||||
placeholder="입력 안내 텍스트"
|
placeholder="입력 안내 텍스트"
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -784,8 +779,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
onChange={(e) => handleUpdate("title", e.target.value)}
|
onChange={(e) => handleUpdate("title", e.target.value)}
|
||||||
placeholder="제목"
|
placeholder="제목"
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -799,8 +792,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
onChange={(e) => handleUpdate("description", e.target.value)}
|
onChange={(e) => handleUpdate("description", e.target.value)}
|
||||||
placeholder="설명"
|
placeholder="설명"
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -842,7 +833,6 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -854,8 +844,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
value={currentPosition.z || 1}
|
value={currentPosition.z || 1}
|
||||||
onChange={(e) => handleUpdate("position.z", parseInt(e.target.value) || 1)}
|
onChange={(e) => handleUpdate("position.z", parseInt(e.target.value) || 1)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -873,8 +862,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
value={selectedComponent.style?.labelText || selectedComponent.label || ""}
|
value={selectedComponent.style?.labelText || selectedComponent.label || ""}
|
||||||
onChange={(e) => handleUpdate("style.labelText", e.target.value)}
|
onChange={(e) => handleUpdate("style.labelText", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-2">
|
<div className="grid grid-cols-2 gap-2">
|
||||||
|
|
@ -884,8 +872,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
value={selectedComponent.style?.labelFontSize || "12px"}
|
value={selectedComponent.style?.labelFontSize || "12px"}
|
||||||
onChange={(e) => handleUpdate("style.labelFontSize", e.target.value)}
|
onChange={(e) => handleUpdate("style.labelFontSize", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
|
|
@ -895,8 +882,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
value={selectedComponent.style?.labelColor || "#212121"}
|
value={selectedComponent.style?.labelColor || "#212121"}
|
||||||
onChange={(e) => handleUpdate("style.labelColor", e.target.value)}
|
onChange={(e) => handleUpdate("style.labelColor", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -907,8 +893,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
value={selectedComponent.style?.labelMarginBottom || "4px"}
|
value={selectedComponent.style?.labelMarginBottom || "4px"}
|
||||||
onChange={(e) => handleUpdate("style.labelMarginBottom", e.target.value)}
|
onChange={(e) => handleUpdate("style.labelMarginBottom", e.target.value)}
|
||||||
className="h-6 w-full px-2 py-0 text-xs"
|
className="h-6 w-full px-2 py-0 text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
style={{ fontSize: "12px" }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center space-x-2 pt-5">
|
<div className="flex items-center space-x-2 pt-5">
|
||||||
|
|
@ -1059,7 +1044,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
<div>
|
<div>
|
||||||
<Label>세부 타입</Label>
|
<Label>세부 타입</Label>
|
||||||
<Select value={localComponentDetailType || webType} onValueChange={handleDetailTypeChange}>
|
<Select value={localComponentDetailType || webType} onValueChange={handleDetailTypeChange}>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="세부 타입 선택" />
|
<SelectValue placeholder="세부 타입 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -1266,7 +1251,7 @@ export const UnifiedPropertiesPanel: React.FC<UnifiedPropertiesPanelProps> = ({
|
||||||
<div>
|
<div>
|
||||||
<Label>입력 타입</Label>
|
<Label>입력 타입</Label>
|
||||||
<Select value={widget.webType} onValueChange={(value) => handleUpdate("webType", value)}>
|
<Select value={widget.webType} onValueChange={(value) => handleUpdate("webType", value)}>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
|
||||||
<>
|
<>
|
||||||
<Separator />
|
<Separator />
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="multiple" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="multiple" className="text-xs">
|
||||||
다중 선택
|
다중 선택
|
||||||
</Label>
|
</Label>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -121,7 +121,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="searchable" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="searchable" className="text-xs">
|
||||||
검색 가능
|
검색 가능
|
||||||
</Label>
|
</Label>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -259,7 +259,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
|
||||||
|
|
||||||
{baseType === "date" && (
|
{baseType === "date" && (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="showTime" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="showTime" className="text-xs">
|
||||||
시간 입력 포함
|
시간 입력 포함
|
||||||
</Label>
|
</Label>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
@ -395,7 +395,7 @@ export const WebTypeConfigPanel: React.FC<WebTypeConfigPanelProps> = ({ webType,
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<Label htmlFor="fileMultiple" className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor="fileMultiple" className="text-xs">
|
||||||
다중 파일 선택
|
다중 파일 선택
|
||||||
</Label>
|
</Label>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ export const CheckboxTypeConfigPanel: React.FC<CheckboxTypeConfigPanelProps> = (
|
||||||
라벨 위치
|
라벨 위치
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.labelPosition} onValueChange={(value) => updateConfig("labelPosition", value)}>
|
<Select value={localValues.labelPosition} onValueChange={(value) => updateConfig("labelPosition", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="라벨 위치 선택" />
|
<SelectValue placeholder="라벨 위치 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -194,18 +194,18 @@ export const CheckboxTypeConfigPanel: React.FC<CheckboxTypeConfigPanelProps> = (
|
||||||
<Label className="text-sm font-medium text-gray-700">미리보기</Label>
|
<Label className="text-sm font-medium text-gray-700">미리보기</Label>
|
||||||
<div className="mt-2 flex items-center space-x-2">
|
<div className="mt-2 flex items-center space-x-2">
|
||||||
{localValues.labelPosition === "left" && localValues.checkboxText && (
|
{localValues.labelPosition === "left" && localValues.checkboxText && (
|
||||||
<span className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</span>
|
<span className="text-xs">{localValues.checkboxText}</span>
|
||||||
)}
|
)}
|
||||||
{localValues.labelPosition === "top" && localValues.checkboxText && (
|
{localValues.labelPosition === "top" && localValues.checkboxText && (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</div>
|
<div className="text-xs">{localValues.checkboxText}</div>
|
||||||
<Checkbox checked={localValues.defaultChecked} className="mt-1" />
|
<Checkbox checked={localValues.defaultChecked} className="mt-1" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(localValues.labelPosition === "right" || localValues.labelPosition === "bottom") && (
|
{(localValues.labelPosition === "right" || localValues.labelPosition === "bottom") && (
|
||||||
<>
|
<>
|
||||||
<Checkbox checked={localValues.defaultChecked} />
|
<Checkbox checked={localValues.defaultChecked} />
|
||||||
{localValues.checkboxText && <span className="text-xs" style={{ fontSize: "12px" }}>{localValues.checkboxText}</span>}
|
{localValues.checkboxText && <span className="text-xs">{localValues.checkboxText}</span>}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{localValues.labelPosition === "left" && <Checkbox checked={localValues.defaultChecked} />}
|
{localValues.labelPosition === "left" && <Checkbox checked={localValues.defaultChecked} />}
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@ export const CodeTypeConfigPanel: React.FC<CodeTypeConfigPanelProps> = ({ config
|
||||||
프로그래밍 언어
|
프로그래밍 언어
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.language} onValueChange={(value) => updateConfig("language", value)}>
|
<Select value={localValues.language} onValueChange={(value) => updateConfig("language", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="언어 선택" />
|
<SelectValue placeholder="언어 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-60">
|
<SelectContent className="max-h-60">
|
||||||
|
|
@ -140,7 +140,7 @@ export const CodeTypeConfigPanel: React.FC<CodeTypeConfigPanelProps> = ({ config
|
||||||
테마
|
테마
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.theme} onValueChange={(value) => updateConfig("theme", value)}>
|
<Select value={localValues.theme} onValueChange={(value) => updateConfig("theme", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="테마 선택" />
|
<SelectValue placeholder="테마 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ export const DateTypeConfigPanel: React.FC<DateTypeConfigPanelProps> = ({ config
|
||||||
}, 0);
|
}, 0);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="날짜 형식 선택" />
|
<SelectValue placeholder="날짜 형식 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||||
표시 형식
|
표시 형식
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.displayFormat} onValueChange={(value) => updateConfig("displayFormat", value)}>
|
<Select value={localValues.displayFormat} onValueChange={(value) => updateConfig("displayFormat", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="형식 선택" />
|
<SelectValue placeholder="형식 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -267,7 +267,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||||
{/* 기존 필터 목록 */}
|
{/* 기존 필터 목록 */}
|
||||||
<div className="max-h-40 space-y-2 overflow-y-auto">
|
<div className="max-h-40 space-y-2 overflow-y-auto">
|
||||||
{Object.entries(safeConfig.filters || {}).map(([field, value]) => (
|
{Object.entries(safeConfig.filters || {}).map(([field, value]) => (
|
||||||
<div key={field} className="flex items-center space-x-2 rounded border p-2 text-xs" style={{ fontSize: "12px" }}>
|
<div key={field} className="flex items-center space-x-2 rounded border p-2 text-xs">
|
||||||
<Input
|
<Input
|
||||||
value={field}
|
value={field}
|
||||||
onChange={(e) => updateFilter(field, e.target.value, value as string)}
|
onChange={(e) => updateFilter(field, e.target.value, value as string)}
|
||||||
|
|
@ -317,7 +317,7 @@ export const EntityTypeConfigPanel: React.FC<EntityTypeConfigPanelProps> = ({ co
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="flex items-center space-x-2 rounded border bg-white p-2">
|
<div className="flex items-center space-x-2 rounded border bg-white p-2">
|
||||||
<Search className="h-4 w-4 text-gray-400" />
|
<Search className="h-4 w-4 text-gray-400" />
|
||||||
<div className="text-muted-foreground flex-1 text-xs" style={{ fontSize: "12px" }}>
|
<div className="text-muted-foreground flex-1 text-xs">
|
||||||
{localValues.placeholder || `${localValues.referenceTable || "엔터티"}를 선택하세요`}
|
{localValues.placeholder || `${localValues.referenceTable || "엔터티"}를 선택하세요`}
|
||||||
</div>
|
</div>
|
||||||
<Database className="h-4 w-4 text-gray-400" />
|
<Database className="h-4 w-4 text-gray-400" />
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ export const NumberTypeConfigPanel: React.FC<NumberTypeConfigPanelProps> = ({ co
|
||||||
숫자 형식
|
숫자 형식
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
|
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="숫자 형식 선택" />
|
<SelectValue placeholder="숫자 형식 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,7 @@ export const RadioTypeConfigPanel: React.FC<RadioTypeConfigPanelProps> = ({ conf
|
||||||
{(safeConfig.options || []).map((option) => (
|
{(safeConfig.options || []).map((option) => (
|
||||||
<div key={option.value} className="flex items-center space-x-2">
|
<div key={option.value} className="flex items-center space-x-2">
|
||||||
<RadioGroupItem value={option.value} id={`preview-${option.value}`} />
|
<RadioGroupItem value={option.value} id={`preview-${option.value}`} />
|
||||||
<Label htmlFor={`preview-${option.value}`} className="text-xs" style={{ fontSize: "12px" }}>
|
<Label htmlFor={`preview-${option.value}`} className="text-xs">
|
||||||
{option.label}
|
{option.label}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ export const SelectTypeConfigPanel: React.FC<SelectTypeConfigPanelProps> = ({ co
|
||||||
value={localValues.placeholder}
|
value={localValues.placeholder}
|
||||||
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
onChange={(e) => updateConfig("placeholder", e.target.value)}
|
||||||
placeholder="옵션을 선택하세요"
|
placeholder="옵션을 선택하세요"
|
||||||
className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }} style={{ fontSize: "12px" }}
|
className="mt-1 h-6 w-full px-2 py-0 text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({
|
||||||
입력 형식
|
입력 형식
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
|
<Select value={localValues.format} onValueChange={(value) => updateConfig("format", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="입력 형식 선택" />
|
<SelectValue placeholder="입력 형식 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
@ -332,7 +332,7 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({
|
||||||
자동값 타입
|
자동값 타입
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={localValues.autoValueType} onValueChange={(value) => updateConfig("autoValueType", value)}>
|
<Select value={localValues.autoValueType} onValueChange={(value) => updateConfig("autoValueType", value)}>
|
||||||
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="mt-1 h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder="자동값 타입 선택" />
|
<SelectValue placeholder="자동값 타입 선택" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ export const TextareaTypeConfigPanel: React.FC<TextareaTypeConfigPanelProps> = (
|
||||||
<Label className="text-sm font-medium text-gray-700">미리보기</Label>
|
<Label className="text-sm font-medium text-gray-700">미리보기</Label>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<textarea
|
<textarea
|
||||||
className="w-full rounded border border-gray-300 p-2 text-xs" style={{ fontSize: "12px" }}
|
className="w-full rounded border border-gray-300 p-2 text-xs"
|
||||||
rows={localValues.rows}
|
rows={localValues.rows}
|
||||||
placeholder={localValues.placeholder || "텍스트를 입력하세요..."}
|
placeholder={localValues.placeholder || "텍스트를 입력하세요..."}
|
||||||
style={{
|
style={{
|
||||||
|
|
|
||||||
|
|
@ -1194,7 +1194,7 @@ export function FlowWidget({
|
||||||
setStepDataPage(1); // 페이지 크기 변경 시 첫 페이지로
|
setStepDataPage(1); // 페이지 크기 변경 시 첫 페이지로
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ export default function InputWidget({ widget, value, onChange, className }: Inpu
|
||||||
required={widget.required}
|
required={widget.required}
|
||||||
readOnly={widget.readonly}
|
readOnly={widget.readonly}
|
||||||
className={cn("h-6 w-full text-xs", widget.readonly && "bg-muted/50 cursor-not-allowed")}
|
className={cn("h-6 w-full text-xs", widget.readonly && "bg-muted/50 cursor-not-allowed")}
|
||||||
style={{ fontSize: "12px" }}
|
className="text-xs"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default function SelectWidget({ widget, value, onChange, options = [], cl
|
||||||
</Label>
|
</Label>
|
||||||
)}
|
)}
|
||||||
<Select value={value} onValueChange={handleChange} disabled={widget.readonly}>
|
<Select value={value} onValueChange={handleChange} disabled={widget.readonly}>
|
||||||
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs" style={{ fontSize: "12px" }}>
|
<SelectTrigger className="h-6 w-full px-2 py-0 text-xs">
|
||||||
<SelectValue placeholder={widget.placeholder || "선택해주세요"} />
|
<SelectValue placeholder={widget.placeholder || "선택해주세요"} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue