diff --git a/frontend/components/screen-embedding/EmbeddedScreen.tsx b/frontend/components/screen-embedding/EmbeddedScreen.tsx index d8e62c00..17cd240f 100644 --- a/frontend/components/screen-embedding/EmbeddedScreen.tsx +++ b/frontend/components/screen-embedding/EmbeddedScreen.tsx @@ -40,32 +40,33 @@ export const EmbeddedScreen = forwardRef(null); const [screenInfo, setScreenInfo] = useState(null); const [formData, setFormData] = useState>(initialFormData || {}); // ๐Ÿ†• ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋กœ ์‹œ์ž‘ + const [formDataVersion, setFormDataVersion] = useState(0); // ๐Ÿ†• ํผ ๋ฐ์ดํ„ฐ ๋ฒ„์ „ (๊ฐ•์ œ ๋ฆฌ๋ Œ๋”๋ง์šฉ) // ์ปดํฌ๋„ŒํŠธ ์ฐธ์กฐ ๋งต const componentRefs = useRef>(new Map()); - + // ๋ถ„ํ•  ํŒจ๋„ ์ปจํ…์ŠคํŠธ (๋ถ„ํ•  ํŒจ๋„ ๋‚ด๋ถ€์— ์žˆ์„ ๋•Œ๋งŒ ์‚ฌ์šฉ) const splitPanelContext = useSplitPanelContext(); - + // ๐Ÿ†• ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ (์ €์žฅ ์•ก์…˜์— ํ•„์š”) const { userId, userName, companyCode } = useAuth(); // ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ์‹ค์ œ ์˜์—ญ ๊ณ„์‚ฐ (๊ฐ€๋กœํญ ๋งž์ถค์„ ์œ„ํ•ด) const contentBounds = React.useMemo(() => { if (layout.length === 0) return { width: 0, height: 0 }; - + let maxRight = 0; let maxBottom = 0; - + layout.forEach((component) => { const { position: compPosition = { x: 0, y: 0 }, size = { width: 200, height: 40 } } = component; const right = (compPosition.x || 0) + (size.width || 200); const bottom = (compPosition.y || 0) + (size.height || 40); - + if (right > maxRight) maxRight = right; if (bottom > maxBottom) maxBottom = bottom; }); - + return { width: maxRight, height: maxBottom }; }, [layout]); @@ -92,26 +93,49 @@ export const EmbeddedScreen = forwardRef { // ์šฐ์ธก ํ™”๋ฉด์ธ ๊ฒฝ์šฐ์—๋งŒ ์ ์šฉ - if (position !== "right" || !splitPanelContext) return; - - // ์ž๋™ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ด ๋น„ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ์Šคํ‚ต - if (splitPanelContext.disableAutoDataTransfer) { - console.log("๐Ÿ”— [EmbeddedScreen] ์ž๋™ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ๋น„ํ™œ์„ฑํ™”๋จ - ๋ฒ„ํŠผ ํด๋ฆญ์œผ๋กœ๋งŒ ์ „๋‹ฌ"); + if (position !== "right" || !splitPanelContext) { return; } - - const mappedData = splitPanelContext.getMappedParentData(); - if (Object.keys(mappedData).length > 0) { - console.log("๐Ÿ”— [EmbeddedScreen] ๋ถ„ํ•  ํŒจ๋„ ๋ถ€๋ชจ ๋ฐ์ดํ„ฐ ์ž๋™ ๋ฐ˜์˜:", mappedData); - setFormData((prev) => ({ - ...prev, - ...mappedData, - })); + + // ์ž๋™ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ด ๋น„ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ ์Šคํ‚ต + if (splitPanelContext.disableAutoDataTransfer) { + return; } - }, [position, splitPanelContext, splitPanelContext?.selectedLeftData]); + + // ๐Ÿ†• ํ˜„์žฌ ํ™”๋ฉด์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์—์„œ columnName ์ˆ˜์ง‘ + const allColumnNames = layout.filter((comp) => comp.columnName).map((comp) => comp.columnName as string); + + // ๐Ÿ†• ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๋นˆ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ ํ›„, selectedLeftData๋กœ ๋ฎ์–ด์“ฐ๊ธฐ + const initializedFormData: Record = {}; + + // ๋จผ์ € ๋ชจ๋“  ์ปฌ๋Ÿผ์„ ๋นˆ ๋ฌธ์ž์—ด๋กœ ์ดˆ๊ธฐํ™” + allColumnNames.forEach((colName) => { + initializedFormData[colName] = ""; + }); + + // selectedLeftData๊ฐ€ ์žˆ์œผ๋ฉด ํ•ด๋‹น ๊ฐ’์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ + if (selectedLeftData && Object.keys(selectedLeftData).length > 0) { + Object.keys(selectedLeftData).forEach((key) => { + // null/undefined๋Š” ๋นˆ ๋ฌธ์ž์—ด๋กœ, ๋‚˜๋จธ์ง€๋Š” ๊ทธ๋Œ€๋กœ + initializedFormData[key] = selectedLeftData[key] ?? ""; + }); + } + + console.log("๐Ÿ”— [EmbeddedScreen] ์šฐ์ธก ํผ ๋ฐ์ดํ„ฐ ๊ต์ฒด:", { + allColumnNames, + selectedLeftDataKeys: selectedLeftData ? Object.keys(selectedLeftData) : [], + initializedFormDataKeys: Object.keys(initializedFormData), + }); + + setFormData(initializedFormData); + setFormDataVersion((v) => v + 1); // ๐Ÿ†• ๋ฒ„์ „ ์ฆ๊ฐ€๋กœ ์ปดํฌ๋„ŒํŠธ ๊ฐ•์ œ ๋ฆฌ๋ Œ๋”๋ง + }, [position, splitPanelContext, selectedLeftData, layout]); // ์„ ํƒ ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ ์ „ํŒŒ useEffect(() => { @@ -377,15 +401,15 @@ export const EmbeddedScreen = forwardRefํ™”๋ฉด์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

) : ( -
{layout.map((component) => { const { position: compPosition = { x: 0, y: 0, z: 1 }, size = { width: 200, height: 40 } } = component; - + // ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ปจํ…Œ์ด๋„ˆ ๋„ˆ๋น„๋ฅผ ์ดˆ๊ณผํ•˜์ง€ ์•Š๋„๋ก ๋„ˆ๋น„ ์กฐ์ • // ๋ถ€๋ชจ ์ปจํ…Œ์ด๋„ˆ์˜ 100%๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐ const componentStyle: React.CSSProperties = { @@ -397,13 +421,9 @@ export const EmbeddedScreen = forwardRef +
= ({ } } - // ๐Ÿ†• ๋ถ„ํ•  ํŒจ๋„ ์šฐ์ธก์ด๋ฉด screenContext.formData์™€ props.formData๋ฅผ ๋ณ‘ํ•ฉ - // screenContext.formData: RepeaterFieldGroup ๋“ฑ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ง์ ‘ ์—…๋ฐ์ดํŠธํ•œ ๋ฐ์ดํ„ฐ - // props.formData: ๋ถ€๋ชจ์—์„œ ์ „๋‹ฌ๋œ ํผ ๋ฐ์ดํ„ฐ + // ๐Ÿ†• ๋ถ„ํ•  ํŒจ๋„ ์šฐ์ธก์ด๋ฉด ์—ฌ๋Ÿฌ ์†Œ์Šค์—์„œ formData๋ฅผ ๋ณ‘ํ•ฉ + // ์šฐ์„ ์ˆœ์œ„: props.formData > screenContext.formData > splitPanelParentData const screenContextFormData = screenContext?.formData || {}; const propsFormData = formData || {}; - // ๋ณ‘ํ•ฉ: props.formData๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜๊ณ , screenContext.formData๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ - // (RepeaterFieldGroup ๋ฐ์ดํ„ฐ๋Š” screenContext์—๋งŒ ์žˆ์Œ) - const effectiveFormData = { ...propsFormData, ...screenContextFormData }; + // ๋ณ‘ํ•ฉ: splitPanelParentData๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ, props.formData, screenContext.formData ์ˆœ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œ + // (์ผ๋ฐ˜ ํผ ํ•„๋“œ๋Š” props.formData, RepeaterFieldGroup์€ screenContext.formData์— ์žˆ์Œ) + let effectiveFormData = { ...propsFormData, ...screenContextFormData }; + + // ๐Ÿ†• ๋ถ„ํ•  ํŒจ๋„ ์šฐ์ธก์ด๊ณ  formData๊ฐ€ ๋น„์–ด์žˆ์œผ๋ฉด splitPanelParentData ์‚ฌ์šฉ + if (splitPanelPosition === "right" && Object.keys(effectiveFormData).length === 0 && splitPanelParentData) { + effectiveFormData = { ...splitPanelParentData }; + console.log("๐Ÿ” [ButtonPrimary] ๋ถ„ํ•  ํŒจ๋„ ์šฐ์ธก - splitPanelParentData ์‚ฌ์šฉ:", Object.keys(effectiveFormData)); + } console.log("๐Ÿ” [ButtonPrimary] formData ์„ ํƒ:", { hasScreenContextFormData: Object.keys(screenContextFormData).length > 0, screenContextKeys: Object.keys(screenContextFormData), hasPropsFormData: Object.keys(propsFormData).length > 0, propsFormDataKeys: Object.keys(propsFormData), + hasSplitPanelParentData: !!splitPanelParentData && Object.keys(splitPanelParentData).length > 0, splitPanelPosition, effectiveFormDataKeys: Object.keys(effectiveFormData), }); diff --git a/frontend/lib/registry/components/text-input/TextInputComponent.tsx b/frontend/lib/registry/components/text-input/TextInputComponent.tsx index ad37f19f..8ffa8afe 100644 --- a/frontend/lib/registry/components/text-input/TextInputComponent.tsx +++ b/frontend/lib/registry/components/text-input/TextInputComponent.tsx @@ -53,7 +53,7 @@ export const TextInputComponent: React.FC = ({ // ์ž๋™์ƒ์„ฑ๋œ ๊ฐ’ ์ƒํƒœ const [autoGeneratedValue, setAutoGeneratedValue] = useState(""); - + // API ํ˜ธ์ถœ ์ค‘๋ณต ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ref const isGeneratingRef = React.useRef(false); const hasGeneratedRef = React.useRef(false); @@ -104,7 +104,6 @@ export const TextInputComponent: React.FC = ({ const currentFormValue = formData?.[component.columnName]; const currentComponentValue = component.value; - // ์ž๋™์ƒ์„ฑ๋œ ๊ฐ’์ด ์—†๊ณ , ํ˜„์žฌ ๊ฐ’๋„ ์—†์„ ๋•Œ๋งŒ ์ƒ์„ฑ if (!autoGeneratedValue && !currentFormValue && !currentComponentValue) { isGeneratingRef.current = true; // ์ƒ์„ฑ ์‹œ์ž‘ ํ”Œ๋ž˜๊ทธ @@ -145,7 +144,7 @@ export const TextInputComponent: React.FC = ({ if (isInteractive && onFormDataChange && component.columnName) { console.log("๐Ÿ“ formData ์—…๋ฐ์ดํŠธ:", component.columnName, generatedValue); onFormDataChange(component.columnName, generatedValue); - + // ์ฑ„๋ฒˆ ๊ทœ์น™ ID๋„ ํ•จ๊ป˜ ์ €์žฅ (์ €์žฅ ์‹œ์ ์— ์‹ค์ œ ํ• ๋‹นํ•˜๊ธฐ ์œ„ํ•จ) if (testAutoGeneration.type === "numbering_rule" && testAutoGeneration.options?.numberingRuleId) { const ruleIdKey = `${component.columnName}_numberingRuleId`; @@ -181,12 +180,12 @@ export const TextInputComponent: React.FC = ({ // width๋Š” ํ•ญ์ƒ 100%๋กœ ๊ณ ์ • (๋ถ€๋ชจ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ gridColumns๋กœ ํฌ๊ธฐ ์ œ์–ด) width: "100%", // ์ˆจ๊น€ ๊ธฐ๋Šฅ: ํŽธ์ง‘ ๋ชจ๋“œ์—์„œ๋งŒ ์—ฐํ•˜๊ฒŒ ํ‘œ์‹œ - ...(isHidden && - isDesignMode && { - opacity: 0.4, - backgroundColor: "hsl(var(--muted))", - pointerEvents: "auto", - }), + ...(isHidden && + isDesignMode && { + opacity: 0.4, + backgroundColor: "hsl(var(--muted))", + pointerEvents: "auto", + }), }; // ๋””์ž์ธ ๋ชจ๋“œ ์Šคํƒ€์ผ @@ -361,7 +360,7 @@ export const TextInputComponent: React.FC = ({
{/* ๋ผ๋ฒจ ๋ Œ๋”๋ง */} {component.label && component.style?.labelDisplay !== false && ( -