From 2c0dca08b43c330b54324c26e4a6b9ab05f20ad0 Mon Sep 17 00:00:00 2001 From: leeheejin Date: Wed, 1 Oct 2025 18:17:30 +0900 Subject: [PATCH] =?UTF-8?q?console.log=20=EC=A3=BC=EC=84=9D=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20-=20=EA=B0=9C=EB=B0=9C=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - menu, company, screenMng, i18n, tableMng 모듈 console 주석 처리 - 총 55개 파일 수정 - 빌드 에러 수정 완료 - 백엔드 서버 정상 작동 확인 관련 파일: - frontend/components/admin/MenuManagement.tsx - frontend/components/admin/MenuFormModal.tsx - frontend/components/admin/ScreenAssignmentTab.tsx - frontend/components/admin/CompanyTable.tsx - frontend/components/admin/MultiLang.tsx - frontend/app/(main)/admin/tableMng/page.tsx - 기타 screen 관련 컴포넌트 49개 파일 --- backend-node/package-lock.json | 317 +++++++++++- frontend/app/(main)/admin/tableMng/page.tsx | 36 +- frontend/components/admin/AddColumnModal.tsx | 2 +- frontend/components/admin/CompanyTable.tsx | 2 +- .../components/admin/CreateTableModal.tsx | 4 +- frontend/components/admin/DDLLogViewer.tsx | 4 +- frontend/components/admin/MenuFormModal.tsx | 184 +++---- frontend/components/admin/MenuManagement.tsx | 144 +++--- frontend/components/admin/MultiLang.tsx | 50 +- .../components/admin/ScreenAssignmentTab.tsx | 40 +- .../components/screen/CopyScreenModal.tsx | 4 +- .../components/screen/CreateScreenModal.tsx | 6 +- .../EnhancedInteractiveScreenViewer.tsx | 2 +- .../screen/FileAttachmentDetailModal.tsx | 6 +- frontend/components/screen/FloatingPanel.tsx | 14 +- .../screen/InteractiveDataTable.tsx | 80 +-- .../screen/InteractiveScreenViewer.tsx | 98 ++-- .../screen/InteractiveScreenViewerDynamic.tsx | 36 +- .../components/screen/MenuAssignmentModal.tsx | 22 +- .../screen/OptimizedButtonComponent.tsx | 44 +- .../components/screen/RealtimePreview.tsx | 126 ++--- frontend/components/screen/ScreenDesigner.tsx | 132 ++--- .../components/screen/ScreenDesigner_new.tsx | 8 +- .../components/screen/ScreenDesigner_old.tsx | 28 +- frontend/components/screen/ScreenList.tsx | 18 +- frontend/components/screen/ScreenPreview.tsx | 2 +- .../screen/SimpleScreenDesigner.tsx | 2 +- .../components/screen/TableTypeSelector.tsx | 12 +- .../components/screen/TemplateManager.tsx | 6 +- .../config-panels/ButtonConfigPanel.tsx | 8 +- .../ButtonDataflowConfigPanel.tsx | 20 +- .../ImprovedButtonControlConfigPanel.tsx | 6 +- .../screen/filters/AdvancedSearchFilters.tsx | 4 +- .../screen/panels/ComponentsPanel.tsx | 6 +- .../screen/panels/DataTableConfigPanel.tsx | 332 ++++++------- .../screen/panels/DetailSettingsPanel.tsx | 124 ++--- .../panels/FileComponentConfigPanel.tsx | 460 +++++++++--------- .../components/screen/panels/LayoutsPanel.tsx | 16 +- .../screen/panels/PropertiesPanel.tsx | 136 +++--- .../screen/panels/TemplatesPanel.tsx | 2 +- .../CheckboxTypeConfigPanel.tsx | 14 +- .../webtype-configs/CodeTypeConfigPanel.tsx | 12 +- .../webtype-configs/DateTypeConfigPanel.tsx | 158 +++--- .../webtype-configs/EntityTypeConfigPanel.tsx | 12 +- .../webtype-configs/FileTypeConfigPanel.tsx | 12 +- .../webtype-configs/NumberTypeConfigPanel.tsx | 16 +- .../webtype-configs/RadioTypeConfigPanel.tsx | 42 +- .../webtype-configs/SelectTypeConfigPanel.tsx | 40 +- .../webtype-configs/TextTypeConfigPanel.tsx | 14 +- .../TextareaTypeConfigPanel.tsx | 14 +- .../components/screen/widgets/FileUpload.tsx | 314 ++++++------ .../screen/widgets/types/ButtonWidget.tsx | 2 +- .../components/screen/widgets/types/index.ts | 2 +- frontend/hooks/useCompanyManagement.ts | 8 +- frontend/lib/api/company.ts | 18 +- 55 files changed, 1757 insertions(+), 1464 deletions(-) diff --git a/backend-node/package-lock.json b/backend-node/package-lock.json index e8a1fdb3..291847f8 100644 --- a/backend-node/package-lock.json +++ b/backend-node/package-lock.json @@ -18,13 +18,15 @@ "express": "^4.18.2", "express-rate-limit": "^7.1.5", "helmet": "^7.1.0", + "imap": "^0.8.19", "joi": "^17.11.0", "jsonwebtoken": "^9.0.2", + "mailparser": "^3.7.4", "mssql": "^11.0.1", "multer": "^1.4.5-lts.1", "mysql2": "^3.15.0", "node-cron": "^4.2.1", - "nodemailer": "^6.9.7", + "nodemailer": "^6.10.1", "oracledb": "^6.9.0", "pg": "^8.16.3", "redis": "^4.6.10", @@ -36,13 +38,15 @@ "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/fs-extra": "^11.0.4", + "@types/imap": "^0.8.42", "@types/jest": "^29.5.11", "@types/jsonwebtoken": "^9.0.5", + "@types/mailparser": "^3.4.6", "@types/morgan": "^1.9.9", "@types/multer": "^1.4.13", "@types/node": "^20.10.5", "@types/node-cron": "^3.0.11", - "@types/nodemailer": "^6.4.14", + "@types/nodemailer": "^6.4.20", "@types/oracledb": "^6.9.1", "@types/pg": "^8.15.5", "@types/sanitize-html": "^2.9.5", @@ -2312,6 +2316,19 @@ "@redis/client": "^1.0.0" } }, + "node_modules/@selderee/plugin-htmlparser2": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", + "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "selderee": "^0.11.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/@sideway/address": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", @@ -3184,6 +3201,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/imap": { + "version": "0.8.42", + "resolved": "https://registry.npmjs.org/@types/imap/-/imap-0.8.42.tgz", + "integrity": "sha512-FusePG9Cp2GYN6OLow9xBCkjznFkAR7WCz0Fm+j1p/ER6C8V8P71DtjpSmwrZsS7zekCeqdTPHEk9N5OgPwcsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3250,6 +3277,30 @@ "@types/node": "*" } }, + "node_modules/@types/mailparser": { + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/@types/mailparser/-/mailparser-3.4.6.tgz", + "integrity": "sha512-wVV3cnIKzxTffaPH8iRnddX1zahbYB1ZEoAxyhoBo3TBCBuK6nZ8M8JYO/RhsCuuBVOw/DEN/t/ENbruwlxn6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "iconv-lite": "^0.6.3" + } + }, + "node_modules/@types/mailparser/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", @@ -3319,9 +3370,9 @@ "license": "MIT" }, "node_modules/@types/nodemailer": { - "version": "6.4.19", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.19.tgz", - "integrity": "sha512-Fi8DwmuAduTk1/1MpkR9EwS0SsDvYXx5RxivAVII1InDCIxmhj/iQm3W8S3EVb/0arnblr6PK0FK4wYa7bwdLg==", + "version": "6.4.20", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.20.tgz", + "integrity": "sha512-uj83z0GqwqMUE6RI4EKptPlav0FYE6vpIlqJAnxzu+/sSezRdbH69rSBCMsdW6DdsCAzoFQZ52c2UIlhRVQYDA==", "dev": true, "license": "MIT", "dependencies": { @@ -4868,7 +4919,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5022,7 +5072,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "dev": true, "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", @@ -5037,7 +5086,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, "funding": [ { "type": "github", @@ -5050,7 +5098,6 @@ "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" @@ -5066,7 +5113,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", @@ -5160,11 +5206,19 @@ "node": ">= 0.8" } }, + "node_modules/encoding-japanese": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.2.0.tgz", + "integrity": "sha512-EuJWwlHPZ1LbADuKTClvHtwbaFn4rOD+dRAbWysqEOXRc2Uui0hJInNJrsdH0c+OhJA4nrCBdSkW4DD5YxAo6A==", + "license": "MIT", + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -6198,6 +6252,15 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, "node_modules/helmet": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.2.0.tgz", @@ -6214,11 +6277,26 @@ "dev": true, "license": "MIT" }, + "node_modules/html-to-text": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", + "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", + "license": "MIT", + "dependencies": { + "@selderee/plugin-htmlparser2": "^0.11.0", + "deepmerge": "^4.3.1", + "dom-serializer": "^2.0.0", + "htmlparser2": "^8.0.2", + "selderee": "^0.11.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/htmlparser2": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -6335,6 +6413,42 @@ "dev": true, "license": "ISC" }, + "node_modules/imap": { + "version": "0.8.19", + "resolved": "https://registry.npmjs.org/imap/-/imap-0.8.19.tgz", + "integrity": "sha512-z5DxEA1uRnZG73UcPA4ES5NSCGnPuuouUx43OPX7KZx1yzq3N8/vx2mtXEShT5inxB3pRgnfG1hijfu7XN2YMw==", + "dependencies": { + "readable-stream": "1.1.x", + "utf7": ">=1.0.2" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/imap/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/imap/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/imap/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -7403,6 +7517,15 @@ "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", "license": "MIT" }, + "node_modules/leac": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", + "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -7427,6 +7550,42 @@ "node": ">= 0.8.0" } }, + "node_modules/libbase64": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.3.0.tgz", + "integrity": "sha512-GgOXd0Eo6phYgh0DJtjQ2tO8dc0IVINtZJeARPeiIJqge+HdsWSuaDTe8ztQ7j/cONByDZ3zeB325AHiv5O0dg==", + "license": "MIT" + }, + "node_modules/libmime": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/libmime/-/libmime-5.3.7.tgz", + "integrity": "sha512-FlDb3Wtha8P01kTL3P9M+ZDNDWPKPmKHWaU/cG/lg5pfuAwdflVpZE+wm9m7pKmC5ww6s+zTxBKS1p6yl3KpSw==", + "license": "MIT", + "dependencies": { + "encoding-japanese": "2.2.0", + "iconv-lite": "0.6.3", + "libbase64": "1.3.0", + "libqp": "2.1.1" + } + }, + "node_modules/libmime/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/libqp": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/libqp/-/libqp-2.1.1.tgz", + "integrity": "sha512-0Wd+GPz1O134cP62YU2GTOPNA7Qgl09XwCqM5zpBv87ERCXdfDtyKXvV7c9U22yWJh44QZqBocFnXN11K96qow==", + "license": "MIT" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -7434,6 +7593,15 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7554,6 +7722,56 @@ "url": "https://github.com/sponsors/wellwelwel" } }, + "node_modules/mailparser": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.7.4.tgz", + "integrity": "sha512-Beh4yyR4jLq3CZZ32asajByrXnW8dLyKCAQD3WvtTiBnMtFWhxO+wa93F6sJNjDmfjxXs4NRNjw3XAGLqZR3Vg==", + "license": "MIT", + "dependencies": { + "encoding-japanese": "2.2.0", + "he": "1.2.0", + "html-to-text": "9.0.5", + "iconv-lite": "0.6.3", + "libmime": "5.3.7", + "linkify-it": "5.0.0", + "mailsplit": "5.4.5", + "nodemailer": "7.0.4", + "punycode.js": "2.3.1", + "tlds": "1.259.0" + } + }, + "node_modules/mailparser/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mailparser/node_modules/nodemailer": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.4.tgz", + "integrity": "sha512-9O00Vh89/Ld2EcVCqJ/etd7u20UhME0f/NToPfArwPEe1Don1zy4mAIz6ariRr7mJ2RDxtaDzN0WJVdVXPtZaw==", + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/mailsplit": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.5.tgz", + "integrity": "sha512-oMfhmvclR689IIaQmIcR5nODnZRRVwAKtqFT407TIvmhX2OLUBnshUTcxzQBt3+96sZVDud9NfSe1NxAkUNXEQ==", + "license": "(MIT OR EUPL-1.1+)", + "dependencies": { + "libbase64": "1.3.0", + "libmime": "5.3.7", + "libqp": "2.1.1" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -8202,6 +8420,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseley": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", + "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", + "license": "MIT", + "dependencies": { + "leac": "^0.6.0", + "peberminta": "^0.9.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -8264,6 +8495,15 @@ "node": ">=8" } }, + "node_modules/peberminta": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", + "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/pg": { "version": "8.16.3", "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", @@ -8610,6 +8850,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -8924,6 +9173,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/selderee": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", + "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", + "license": "MIT", + "dependencies": { + "parseley": "^0.12.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -9525,6 +9786,15 @@ "dev": true, "license": "MIT" }, + "node_modules/tlds": { + "version": "1.259.0", + "resolved": "https://registry.npmjs.org/tlds/-/tlds-1.259.0.tgz", + "integrity": "sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==", + "license": "MIT", + "bin": { + "tlds": "bin.js" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -9771,6 +10041,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/uglify-js": { "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", @@ -9848,6 +10124,23 @@ "punycode": "^2.1.0" } }, + "node_modules/utf7": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utf7/-/utf7-1.0.2.tgz", + "integrity": "sha512-qQrPtYLLLl12NF4DrM9CvfkxkYI97xOb5dsnGZHE3teFr0tWiEZ9UdgMPczv24vl708cYMpe6mGXGHrotIp3Bw==", + "dependencies": { + "semver": "~5.3.0" + } + }, + "node_modules/utf7/node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/frontend/app/(main)/admin/tableMng/page.tsx b/frontend/app/(main)/admin/tableMng/page.tsx index 68dd59ba..e415fec8 100644 --- a/frontend/app/(main)/admin/tableMng/page.tsx +++ b/frontend/app/(main)/admin/tableMng/page.tsx @@ -103,7 +103,7 @@ export default function TableManagementPage() { setUiTexts(response.data.data); } } catch (error) { - console.error("다국어 텍스트 로드 실패:", error); + // console.error("다국어 텍스트 로드 실패:", error); } }; @@ -125,20 +125,20 @@ export default function TableManagementPage() { // 이미 로드된 경우이지만 빈 배열이 아닌 경우만 스킵 const existingColumns = referenceTableColumns[tableName]; if (existingColumns && existingColumns.length > 0) { - console.log(`🎯 참조 테이블 컬럼 이미 로드됨: ${tableName}`, existingColumns); + // console.log(`🎯 참조 테이블 컬럼 이미 로드됨: ${tableName}`, existingColumns); return; } - console.log(`🎯 참조 테이블 컬럼 로드 시작: ${tableName}`); + // console.log(`🎯 참조 테이블 컬럼 로드 시작: ${tableName}`); try { const result = await entityJoinApi.getReferenceTableColumns(tableName); - console.log(`🎯 참조 테이블 컬럼 로드 성공: ${tableName}`, result.columns); + // console.log(`🎯 참조 테이블 컬럼 로드 성공: ${tableName}`, result.columns); setReferenceTableColumns((prev) => ({ ...prev, [tableName]: result.columns, })); } catch (error) { - console.error(`참조 테이블 컬럼 로드 실패: ${tableName}`, error); + // console.error(`참조 테이블 컬럼 로드 실패: ${tableName}`, error); setReferenceTableColumns((prev) => ({ ...prev, [tableName]: [], @@ -177,24 +177,24 @@ export default function TableManagementPage() { const loadCommonCodeCategories = async () => { try { const response = await commonCodeApi.categories.getList({ isActive: true }); - console.log("🔍 공통코드 카테고리 API 응답:", response); + // console.log("🔍 공통코드 카테고리 API 응답:", response); if (response.success && response.data) { - console.log("📋 공통코드 카테고리 데이터:", response.data); + // console.log("📋 공통코드 카테고리 데이터:", response.data); const categories = response.data.map((category) => { - console.log("🏷️ 카테고리 항목:", category); + // console.log("🏷️ 카테고리 항목:", category); return { value: category.category_code, label: category.category_name || category.category_code, }; }); - console.log("✅ 매핑된 카테고리 옵션:", categories); + // console.log("✅ 매핑된 카테고리 옵션:", categories); setCommonCodeCategories(categories); } } catch (error) { - console.error("공통코드 카테고리 로드 실패:", error); + // console.error("공통코드 카테고리 로드 실패:", error); // 에러는 로그만 남기고 사용자에게는 알리지 않음 (선택적 기능) } }; @@ -213,7 +213,7 @@ export default function TableManagementPage() { toast.error(response.data.message || "테이블 목록 로드에 실패했습니다."); } } catch (error) { - console.error("테이블 목록 로드 실패:", error); + // console.error("테이블 목록 로드 실패:", error); toast.error("테이블 목록 로드 중 오류가 발생했습니다."); } finally { setLoading(false); @@ -251,7 +251,7 @@ export default function TableManagementPage() { toast.error(response.data.message || "컬럼 정보 로드에 실패했습니다."); } } catch (error) { - console.error("컬럼 타입 정보 로드 실패:", error); + // console.error("컬럼 타입 정보 로드 실패:", error); toast.error("컬럼 정보 로드 중 오류가 발생했습니다."); } finally { setColumnsLoading(false); @@ -411,7 +411,7 @@ export default function TableManagementPage() { displayColumn: column.displayColumn || "", // 🎯 Entity 조인에서 표시할 컬럼명 }; - console.log("저장할 컬럼 설정:", columnSetting); + // console.log("저장할 컬럼 설정:", columnSetting); const response = await apiClient.post(`/table-management/tables/${selectedTable}/columns/settings`, [ columnSetting, @@ -430,7 +430,7 @@ export default function TableManagementPage() { toast.error(response.data.message || "컬럼 설정 저장에 실패했습니다."); } } catch (error) { - console.error("컬럼 설정 저장 실패:", error); + // console.error("컬럼 설정 저장 실패:", error); toast.error("컬럼 설정 저장 중 오류가 발생했습니다."); } }; @@ -448,7 +448,7 @@ export default function TableManagementPage() { description: tableDescription, }); } catch (error) { - console.warn("테이블 라벨 저장 실패 (API 미구현 가능):", error); + // console.warn("테이블 라벨 저장 실패 (API 미구현 가능):", error); } } @@ -467,7 +467,7 @@ export default function TableManagementPage() { displayColumn: column.displayColumn || "", // 🎯 Entity 조인에서 표시할 컬럼명 })); - console.log("저장할 전체 설정:", { tableLabel, tableDescription, columnSettings }); + // console.log("저장할 전체 설정:", { tableLabel, tableDescription, columnSettings }); // 전체 테이블 설정을 한 번에 저장 const response = await apiClient.post( @@ -492,7 +492,7 @@ export default function TableManagementPage() { } } } catch (error) { - console.error("설정 저장 실패:", error); + // console.error("설정 저장 실패:", error); toast.error("설정 저장 중 오류가 발생했습니다."); } }; @@ -525,7 +525,7 @@ export default function TableManagementPage() { entityColumns.forEach((col) => { if (col.referenceTable) { - console.log(`🎯 기존 Entity 컬럼 발견, 참조 테이블 컬럼 로드: ${col.columnName} -> ${col.referenceTable}`); + // console.log(`🎯 기존 Entity 컬럼 발견, 참조 테이블 컬럼 로드: ${col.columnName} -> ${col.referenceTable}`); loadReferenceTableColumns(col.referenceTable); } }); diff --git a/frontend/components/admin/AddColumnModal.tsx b/frontend/components/admin/AddColumnModal.tsx index 2fd6c33e..5bb76508 100644 --- a/frontend/components/admin/AddColumnModal.tsx +++ b/frontend/components/admin/AddColumnModal.tsx @@ -175,7 +175,7 @@ export function AddColumnModal({ isOpen, onClose, tableName, onSuccess }: AddCol toast.error(result.error?.details || result.message); } } catch (error: any) { - console.error("컬럼 추가 실패:", error); + // console.error("컬럼 추가 실패:", error); toast.error(error.response?.data?.error?.details || "컬럼 추가에 실패했습니다."); } finally { setLoading(false); diff --git a/frontend/components/admin/CompanyTable.tsx b/frontend/components/admin/CompanyTable.tsx index 949bebc5..2bc4e10c 100644 --- a/frontend/components/admin/CompanyTable.tsx +++ b/frontend/components/admin/CompanyTable.tsx @@ -43,7 +43,7 @@ export function CompanyTable({ companies, isLoading, onEdit, onDelete }: Company ); }; // 상태에 따른 Badge 색상 결정 - console.log(companies); + // console.log(companies); // 로딩 상태 렌더링 if (isLoading) { return ( diff --git a/frontend/components/admin/CreateTableModal.tsx b/frontend/components/admin/CreateTableModal.tsx index de0b3aa3..07dae653 100644 --- a/frontend/components/admin/CreateTableModal.tsx +++ b/frontend/components/admin/CreateTableModal.tsx @@ -172,7 +172,7 @@ export function CreateTableModal({ isOpen, onClose, onSuccess }: CreateTableModa toast.error("검증 실패. 오류를 확인해주세요."); } } catch (error: any) { - console.error("테이블 검증 실패:", error); + // console.error("테이블 검증 실패:", error); toast.error("검증 중 오류가 발생했습니다."); } finally { setValidating(false); @@ -210,7 +210,7 @@ export function CreateTableModal({ isOpen, onClose, onSuccess }: CreateTableModa toast.error(result.error?.details || result.message); } } catch (error: any) { - console.error("테이블 생성 실패:", error); + // console.error("테이블 생성 실패:", error); toast.error(error.response?.data?.error?.details || "테이블 생성에 실패했습니다."); } finally { setLoading(false); diff --git a/frontend/components/admin/DDLLogViewer.tsx b/frontend/components/admin/DDLLogViewer.tsx index c6a44023..c978f162 100644 --- a/frontend/components/admin/DDLLogViewer.tsx +++ b/frontend/components/admin/DDLLogViewer.tsx @@ -64,7 +64,7 @@ export function DDLLogViewer({ isOpen, onClose }: DDLLogViewerProps) { setLogs(logsResult.logs); setStatistics(statsResult); } catch (error) { - console.error("DDL 로그 로드 실패:", error); + // console.error("DDL 로그 로드 실패:", error); toast.error("DDL 로그를 불러오는데 실패했습니다."); } finally { if (showLoading) setLoading(false); @@ -101,7 +101,7 @@ export function DDLLogViewer({ isOpen, onClose }: DDLLogViewerProps) { toast.success(`${result.deletedCount}개의 오래된 로그가 삭제되었습니다.`); loadData(false); } catch (error) { - console.error("로그 정리 실패:", error); + // console.error("로그 정리 실패:", error); toast.error("로그 정리에 실패했습니다."); } }; diff --git a/frontend/components/admin/MenuFormModal.tsx b/frontend/components/admin/MenuFormModal.tsx index f87b4905..501a0b8d 100644 --- a/frontend/components/admin/MenuFormModal.tsx +++ b/frontend/components/admin/MenuFormModal.tsx @@ -46,21 +46,21 @@ export const MenuFormModal: React.FC = ({ parentCompanyCode, uiTexts, }) => { - console.log("🎯 MenuFormModal 렌더링 - Props:", { - isOpen, - menuId, - parentId, - menuType, - level, - parentCompanyCode, - }); + // console.log("🎯 MenuFormModal 렌더링 - Props:", { + // isOpen, + // menuId, + // parentId, + // menuType, + // level, + // parentCompanyCode, + // }); // 다국어 텍스트 가져오기 함수 const getText = (key: string, fallback?: string): string => { return uiTexts[key] || fallback || key; }; - console.log("🔍 MenuFormModal 컴포넌트 마운트됨"); + // console.log("🔍 MenuFormModal 컴포넌트 마운트됨"); const [formData, setFormData] = useState({ parentObjId: parentId || "0", @@ -93,20 +93,20 @@ export const MenuFormModal: React.FC = ({ try { const response = await screenApi.getScreens({ size: 1000 }); // 모든 화면 가져오기 - console.log("🔍 화면 목록 로드 디버깅:", { - totalScreens: response.data.length, - firstScreen: response.data[0], - firstScreenFields: response.data[0] ? Object.keys(response.data[0]) : [], - firstScreenValues: response.data[0] ? Object.values(response.data[0]) : [], - allScreenIds: response.data - .map((s) => ({ - screenId: s.screenId, - legacyId: s.id, - name: s.screenName, - code: s.screenCode, - })) - .slice(0, 5), // 처음 5개만 출력 - }); + // console.log("🔍 화면 목록 로드 디버깅:", { + // totalScreens: response.data.length, + // firstScreen: response.data[0], + // firstScreenFields: response.data[0] ? Object.keys(response.data[0]) : [], + // firstScreenValues: response.data[0] ? Object.values(response.data[0]) : [], + // allScreenIds: response.data + // .map((s) => ({ + // screenId: s.screenId, + // legacyId: s.id, + // name: s.screenName, + // code: s.screenCode, + // })) + // .slice(0, 5), // 처음 5개만 출력 + // }); setScreens(response.data); console.log("✅ 화면 목록 로드 완료:", response.data.length); @@ -118,14 +118,14 @@ export const MenuFormModal: React.FC = ({ // 화면 선택 시 URL 자동 설정 const handleScreenSelect = (screen: ScreenDefinition) => { - console.log("🖥️ 화면 선택 디버깅:", { - screen, - screenId: screen.screenId, - screenIdType: typeof screen.screenId, - legacyId: screen.id, - allFields: Object.keys(screen), - screenValues: Object.values(screen), - }); + // console.log("🖥️ 화면 선택 디버깅:", { + // screen, + // screenId: screen.screenId, + // screenIdType: typeof screen.screenId, + // legacyId: screen.id, + // allFields: Object.keys(screen), + // screenValues: Object.values(screen), + // }); // ScreenDefinition에서는 screenId 필드를 사용 const actualScreenId = screen.screenId || screen.id; @@ -154,26 +154,26 @@ export const MenuFormModal: React.FC = ({ menuUrl: screenUrl, })); - console.log("🖥️ 화면 선택 완료:", { - screenId: screen.screenId, - legacyId: screen.id, - actualScreenId, - screenName: screen.screenName, - menuType: menuType, - formDataMenuType: formData.menuType, - isAdminMenu, - generatedUrl: screenUrl, - }); + // console.log("🖥️ 화면 선택 완료:", { + // screenId: screen.screenId, + // legacyId: screen.id, + // actualScreenId, + // screenName: screen.screenName, + // menuType: menuType, + // formDataMenuType: formData.menuType, + // isAdminMenu, + // generatedUrl: screenUrl, + // }); }; // URL 타입 변경 시 처리 const handleUrlTypeChange = (type: "direct" | "screen") => { - console.log("🔄 URL 타입 변경:", { - from: urlType, - to: type, - currentSelectedScreen: selectedScreen?.screenName, - currentUrl: formData.menuUrl, - }); + // console.log("🔄 URL 타입 변경:", { + // from: urlType, + // to: type, + // currentSelectedScreen: selectedScreen?.screenName, + // currentUrl: formData.menuUrl, + // }); setUrlType(type); @@ -225,7 +225,7 @@ export const MenuFormModal: React.FC = ({ try { setLoading(true); console.log("API 호출 시작 - menuId:", menuId); - console.log("API URL:", `/admin/menus/${menuId}`); + // console.log("API URL:", `/admin/menus/${menuId}`); const response = await menuApi.getMenuInfo(menuId); console.log("메뉴 정보 조회 응답:", response); @@ -285,29 +285,29 @@ export const MenuFormModal: React.FC = ({ // "/screens/123" 또는 "/screens/123?mode=admin" 형태에서 ID 추출 const screenId = menuUrl.match(/\/screens\/(\d+)/)?.[1]; if (screenId) { - console.log("🔍 기존 메뉴에서 화면 ID 추출:", { - menuUrl, - screenId, - hasAdminParam: menuUrl.includes("mode=admin"), - currentScreensCount: screens.length, - }); + // console.log("🔍 기존 메뉴에서 화면 ID 추출:", { + // menuUrl, + // screenId, + // hasAdminParam: menuUrl.includes("mode=admin"), + // currentScreensCount: screens.length, + // }); // 화면 설정 함수 const setScreenFromId = () => { const screen = screens.find((s) => s.screenId.toString() === screenId || s.id?.toString() === screenId); if (screen) { setSelectedScreen(screen); - console.log("🖥️ 기존 메뉴의 할당된 화면 설정:", { - screen, - originalUrl: menuUrl, - hasAdminParam: menuUrl.includes("mode=admin"), - }); + // console.log("🖥️ 기존 메뉴의 할당된 화면 설정:", { + // screen, + // originalUrl: menuUrl, + // hasAdminParam: menuUrl.includes("mode=admin"), + // }); return true; } else { - console.warn("⚠️ 해당 ID의 화면을 찾을 수 없음:", { - screenId, - availableScreens: screens.map((s) => ({ screenId: s.screenId, id: s.id, name: s.screenName })), - }); + // console.warn("⚠️ 해당 ID의 화면을 찾을 수 없음:", { + // screenId, + // availableScreens: screens.map((s) => ({ screenId: s.screenId, id: s.id, name: s.screenName })), + // }); return false; } }; @@ -330,26 +330,26 @@ export const MenuFormModal: React.FC = ({ setSelectedScreen(null); } - console.log("설정된 폼 데이터:", { - objid: menu.objid || menu.OBJID, - parentObjId: menu.parent_obj_id || menu.PARENT_OBJ_ID || "0", - menuNameKor: menu.menu_name_kor || menu.MENU_NAME_KOR || "", - menuUrl: menu.menu_url || menu.MENU_URL || "", - menuDesc: menu.menu_desc || menu.MENU_DESC || "", - seq: menu.seq || menu.SEQ || 1, - menuType: convertedMenuType, - status: convertedStatus, - companyCode: companyCode, - langKey: langKey, - }); + // console.log("설정된 폼 데이터:", { + // objid: menu.objid || menu.OBJID, + // parentObjId: menu.parent_obj_id || menu.PARENT_OBJ_ID || "0", + // menuNameKor: menu.menu_name_kor || menu.MENU_NAME_KOR || "", + // menuUrl: menu.menu_url || menu.MENU_URL || "", + // menuDesc: menu.menu_desc || menu.MENU_DESC || "", + // seq: menu.seq || menu.SEQ || 1, + // menuType: convertedMenuType, + // status: convertedStatus, + // companyCode: companyCode, + // langKey: langKey, + // }); } } catch (error: any) { console.error("메뉴 정보 로딩 오류:", error); - console.error("오류 상세 정보:", { - message: error?.message, - stack: error?.stack, - response: error?.response, - }); + // console.error("오류 상세 정보:", { + // message: error?.message, + // stack: error?.stack, + // response: error?.response, + // }); toast.error(getText(MENU_MANAGEMENT_KEYS.MESSAGE_ERROR_LOAD_MENU_INFO)); } finally { setLoading(false); @@ -390,13 +390,13 @@ export const MenuFormModal: React.FC = ({ langKey: "", // 다국어 키 초기화 }); - console.log("메뉴 등록 기본값 설정:", { - parentObjId: parentId || "0", - menuType: defaultMenuType, - status: "ACTIVE", - companyCode: "", - langKey: "", - }); + // console.log("메뉴 등록 기본값 설정:", { + // parentObjId: parentId || "0", + // menuType: defaultMenuType, + // status: "ACTIVE", + // companyCode: "", + // langKey: "", + // }); } }, [menuId, parentId, menuType]); @@ -448,11 +448,11 @@ export const MenuFormModal: React.FC = ({ const screen = screens.find((s) => s.screenId.toString() === screenId || s.id?.toString() === screenId); if (screen) { setSelectedScreen(screen); - console.log("✅ 기존 메뉴의 할당된 화면 자동 설정 완료:", { - screenId, - screenName: screen.screenName, - menuUrl, - }); + // console.log("✅ 기존 메뉴의 할당된 화면 자동 설정 완료:", { + // screenId, + // screenName: screen.screenName, + // menuUrl, + // }); } } } diff --git a/frontend/components/admin/MenuManagement.tsx b/frontend/components/admin/MenuManagement.tsx index c92f0a2d..81c94ae0 100644 --- a/frontend/components/admin/MenuManagement.tsx +++ b/frontend/components/admin/MenuManagement.tsx @@ -195,7 +195,7 @@ export const MenuManagement: React.FC = () => { defaultTexts[key] = defaultText; }); setUiTexts(defaultTexts); - console.log("🌐 초기 기본 텍스트 설정 완료:", Object.keys(defaultTexts).length); + // console.log("🌐 초기 기본 텍스트 설정 완료:", Object.keys(defaultTexts).length); }; // 기본 텍스트 반환 함수 @@ -303,20 +303,20 @@ export const MenuManagement: React.FC = () => { // uiTexts 상태 변경 감지 useEffect(() => { - console.log("🔄 uiTexts 상태 변경됨:", { - count: Object.keys(uiTexts).length, - sampleKeys: Object.keys(uiTexts).slice(0, 5), - sampleValues: Object.entries(uiTexts) - .slice(0, 3) - .map(([k, v]) => `${k}: ${v}`), - }); + // console.log("🔄 uiTexts 상태 변경됨:", { + // count: Object.keys(uiTexts).length, + // sampleKeys: Object.keys(uiTexts).slice(0, 5), + // sampleValues: Object.entries(uiTexts) + // .slice(0, 3) + // .map(([k, v]) => `${k}: ${v}`), + // }); }, [uiTexts]); // 컴포넌트 마운트 후 다국어 텍스트 강제 로드 (userLang이 아직 설정되지 않았을 수 있음) useEffect(() => { const timer = setTimeout(() => { if (userLang && !uiTextsLoading) { - console.log("🔄 컴포넌트 마운트 후 다국어 텍스트 강제 로드"); + // console.log("🔄 컴포넌트 마운트 후 다국어 텍스트 강제 로드"); loadUITexts(); } }, 300); // 300ms 후 실행 @@ -328,7 +328,7 @@ export const MenuManagement: React.FC = () => { useEffect(() => { const fallbackTimer = setTimeout(() => { if (!uiTextsLoading && Object.keys(uiTexts).length === 0) { - console.log("🔄 안전장치: 컴포넌트 마운트 후 강제 다국어 텍스트 로드"); + // console.log("🔄 안전장치: 컴포넌트 마운트 후 강제 다국어 텍스트 로드"); // 사용자 언어가 설정되지 않았을 때만 기본 텍스트 설정 if (!userLang) { initializeDefaultTexts(); @@ -378,15 +378,15 @@ export const MenuManagement: React.FC = () => { }, [isCompanyDropdownOpen]); const loadMenus = async (showLoading = true) => { - console.log(`📋 메뉴 목록 조회 시작 (showLoading: ${showLoading})`); + // console.log(`📋 메뉴 목록 조회 시작 (showLoading: ${showLoading})`); try { if (showLoading) { setLoading(true); } await refreshMenus(); - console.log("📋 메뉴 목록 조회 성공"); + // console.log("📋 메뉴 목록 조회 성공"); } catch (error) { - console.error("❌ 메뉴 목록 조회 실패:", error); + // console.error("❌ 메뉴 목록 조회 실패:", error); toast.error(getUITextSync("message.error.load.menu.list")); } finally { if (showLoading) { @@ -397,21 +397,21 @@ export const MenuManagement: React.FC = () => { // 회사 목록 조회 const loadCompanies = async () => { - console.log("🏢 회사 목록 조회 시작"); + // console.log("🏢 회사 목록 조회 시작"); try { const response = await apiClient.get("/admin/companies"); if (response.data.success) { - console.log("🏢 회사 목록 응답:", response.data); + // console.log("🏢 회사 목록 응답:", response.data); const companyList = response.data.data.map((company: any) => ({ code: company.company_code || company.companyCode, name: company.company_name || company.companyName, })); - console.log("🏢 변환된 회사 목록:", companyList); + // console.log("🏢 변환된 회사 목록:", companyList); setCompanies(companyList); } } catch (error) { - console.error("❌ 회사 목록 조회 실패:", error); + // console.error("❌ 회사 목록 조회 실패:", error); } }; @@ -421,7 +421,7 @@ export const MenuManagement: React.FC = () => { // userLang이 설정되지 않았으면 기본값 설정 if (!userLang) { - console.log("🌐 사용자 언어가 설정되지 않음, 기본값 설정"); + // console.log("🌐 사용자 언어가 설정되지 않음, 기본값 설정"); const defaultTexts: Record = {}; MENU_MANAGEMENT_LANG_KEYS.forEach((key) => { defaultTexts[key] = getDefaultText(key); // 기본 한국어 텍스트 사용 @@ -432,7 +432,7 @@ export const MenuManagement: React.FC = () => { // 사용자 언어가 설정된 경우, 기존 uiTexts가 비어있으면 기본 텍스트로 초기화 if (Object.keys(uiTexts).length === 0) { - console.log("🌐 기존 uiTexts가 비어있음, 기본 텍스트로 초기화"); + // console.log("🌐 기존 uiTexts가 비어있음, 기본 텍스트로 초기화"); const defaultTexts: Record = {}; MENU_MANAGEMENT_LANG_KEYS.forEach((key) => { defaultTexts[key] = getDefaultText(key); @@ -440,14 +440,14 @@ export const MenuManagement: React.FC = () => { setUiTexts(defaultTexts); } - console.log("🌐 UI 다국어 텍스트 로드 시작", { - userLang, - apiParams: { - companyCode: "*", - menuCode: "menu.management", - userLang: userLang, - }, - }); + // console.log("🌐 UI 다국어 텍스트 로드 시작", { + // userLang, + // apiParams: { + // companyCode: "*", + // menuCode: "menu.management", + // userLang: userLang, + // }, + // }); setUiTextsLoading(true); try { @@ -467,28 +467,28 @@ export const MenuManagement: React.FC = () => { if (response.data.success) { const translations = response.data.data; - console.log("🌐 배치 다국어 텍스트 응답:", translations); + // console.log("🌐 배치 다국어 텍스트 응답:", translations); // 번역 결과를 상태에 저장 (기존 uiTexts와 병합) const mergedTranslations = { ...uiTexts, ...translations }; - console.log("🔧 setUiTexts 호출 전:", { - translationsCount: Object.keys(translations).length, - mergedCount: Object.keys(mergedTranslations).length, - }); + // console.log("🔧 setUiTexts 호출 전:", { + // translationsCount: Object.keys(translations).length, + // mergedCount: Object.keys(mergedTranslations).length, + // }); setUiTexts(mergedTranslations); - console.log("🔧 setUiTexts 호출 후 - mergedTranslations:", mergedTranslations); + // console.log("🔧 setUiTexts 호출 후 - mergedTranslations:", mergedTranslations); // 번역 캐시에 저장 (다른 컴포넌트에서도 사용할 수 있도록) setTranslationCache(userLang, mergedTranslations); } else { - console.error("❌ 다국어 텍스트 배치 조회 실패:", response.data.message); + // console.error("❌ 다국어 텍스트 배치 조회 실패:", response.data.message); // API 실패 시에도 기존 uiTexts는 유지 - console.log("🔄 API 실패로 인해 기존 uiTexts 유지"); + // console.log("🔄 API 실패로 인해 기존 uiTexts 유지"); } } catch (error) { - console.error("❌ UI 다국어 텍스트 로드 실패:", error); + // console.error("❌ UI 다국어 텍스트 로드 실패:", error); // API 실패 시에도 기존 uiTexts는 유지 - console.log("🔄 API 실패로 인해 기존 uiTexts 유지"); + // console.log("🔄 API 실패로 인해 기존 uiTexts 유지"); } finally { setUiTextsLoading(false); } @@ -519,12 +519,12 @@ export const MenuManagement: React.FC = () => { // 다국어 API 테스트 함수 (getUITextSync 사용) const testMultiLangAPI = async () => { - console.log("🧪 다국어 API 테스트 시작"); + // console.log("🧪 다국어 API 테스트 시작"); try { const text = getUITextSync("menu.management.admin"); - console.log("🧪 다국어 API 테스트 결과:", text); + // console.log("🧪 다국어 API 테스트 결과:", text); } catch (error) { - console.error("❌ 다국어 API 테스트 실패:", error); + // console.error("❌ 다국어 API 테스트 실패:", error); } }; @@ -576,14 +576,14 @@ export const MenuManagement: React.FC = () => { }; const handleEditMenu = (menuId: string) => { - console.log("🔧 메뉴 수정 시작 - menuId:", menuId); + // console.log("🔧 메뉴 수정 시작 - menuId:", menuId); // 현재 메뉴 정보 찾기 const currentMenus = selectedMenuType === "admin" ? adminMenus : userMenus; const menuToEdit = currentMenus.find((menu) => (menu.objid || menu.OBJID) === menuId); if (menuToEdit) { - console.log("수정할 메뉴 정보:", menuToEdit); + // console.log("수정할 메뉴 정보:", menuToEdit); setFormData({ menuId: menuId, @@ -593,15 +593,15 @@ export const MenuManagement: React.FC = () => { parentCompanyCode: menuToEdit.company_code || menuToEdit.COMPANY_CODE || "", }); - console.log("설정된 formData:", { - menuId: menuId, - parentId: menuToEdit.parent_obj_id || menuToEdit.PARENT_OBJ_ID || "", - menuType: selectedMenuType, - level: 0, - parentCompanyCode: menuToEdit.company_code || menuToEdit.COMPANY_CODE || "", - }); + // console.log("설정된 formData:", { + // menuId: menuId, + // parentId: menuToEdit.parent_obj_id || menuToEdit.PARENT_OBJ_ID || "", + // menuType: selectedMenuType, + // level: 0, + // parentCompanyCode: menuToEdit.company_code || menuToEdit.COMPANY_CODE || "", + // }); } else { - console.error("수정할 메뉴를 찾을 수 없음:", menuId); + // console.error("수정할 메뉴를 찾을 수 없음:", menuId); } setFormModalOpen(true); @@ -640,31 +640,31 @@ export const MenuManagement: React.FC = () => { setDeleting(true); try { const menuIds = Array.from(selectedMenus); - console.log("삭제할 메뉴 IDs:", menuIds); + // console.log("삭제할 메뉴 IDs:", menuIds); toast.info(getUITextSync("message.menu.delete.processing")); const response = await menuApi.deleteMenusBatch(menuIds); - console.log("삭제 API 응답:", response); - console.log("응답 구조:", { - success: response.success, - data: response.data, - message: response.message, - }); + // console.log("삭제 API 응답:", response); + // console.log("응답 구조:", { + // success: response.success, + // data: response.data, + // message: response.message, + // }); if (response.success && response.data) { const { deletedCount, failedCount } = response.data; - console.log("삭제 결과:", { deletedCount, failedCount }); + // console.log("삭제 결과:", { deletedCount, failedCount }); // 선택된 메뉴 초기화 setSelectedMenus(new Set()); // 메뉴 목록 즉시 새로고침 (로딩 상태 없이) - console.log("메뉴 목록 새로고침 시작"); + // console.log("메뉴 목록 새로고침 시작"); await loadMenus(false); // 전역 메뉴 상태도 업데이트 await refreshMenus(); - console.log("메뉴 목록 새로고침 완료"); + // console.log("메뉴 목록 새로고침 완료"); // 삭제 결과 메시지 if (failedCount === 0) { @@ -678,11 +678,11 @@ export const MenuManagement: React.FC = () => { ); } } else { - console.error("삭제 실패:", response); + // console.error("삭제 실패:", response); toast.error(response.message || "메뉴 삭제에 실패했습니다."); } } catch (error) { - console.error("메뉴 삭제 중 오류:", error); + // console.error("메뉴 삭제 중 오류:", error); toast.error(getUITextSync("message.menu.delete.failed")); } finally { setDeleting(false); @@ -718,7 +718,7 @@ export const MenuManagement: React.FC = () => { toast.error(response.message); } } catch (error) { - console.error("메뉴 상태 토글 오류:", error); + // console.error("메뉴 상태 토글 오류:", error); toast.error(getUITextSync("message.menu.status.toggle.failed")); } }; @@ -785,15 +785,15 @@ export const MenuManagement: React.FC = () => { const userMenusCount = useMemo(() => userMenus?.length || 0, [userMenus]); // 디버깅을 위한 간단한 상태 표시 - console.log("🔍 MenuManagement 렌더링 상태:", { - loading, - uiTextsLoading, - uiTextsCount, - adminMenusCount, - userMenusCount, - selectedMenuType, - userLang, - }); + // console.log("🔍 MenuManagement 렌더링 상태:", { + // loading, + // uiTextsLoading, + // uiTextsCount, + // adminMenusCount, + // userMenusCount, + // selectedMenuType, + // userLang, + // }); if (loading) { return ( diff --git a/frontend/components/admin/MultiLang.tsx b/frontend/components/admin/MultiLang.tsx index d77e0110..0d9c2a98 100644 --- a/frontend/components/admin/MultiLang.tsx +++ b/frontend/components/admin/MultiLang.tsx @@ -64,9 +64,9 @@ export default function MultiLangPage() { // 회사 목록 조회 const fetchCompanies = async () => { try { - console.log("회사 목록 조회 시작"); + // console.log("회사 목록 조회 시작"); const response = await apiClient.get("/admin/companies"); - console.log("회사 목록 응답 데이터:", response.data); + // console.log("회사 목록 응답 데이터:", response.data); const data = response.data; if (data.success) { @@ -74,13 +74,13 @@ export default function MultiLangPage() { code: company.company_code, name: company.company_name, })); - console.log("변환된 회사 목록:", companyList); + // console.log("변환된 회사 목록:", companyList); setCompanies(companyList); } else { - console.error("회사 목록 조회 실패:", data.message); + // console.error("회사 목록 조회 실패:", data.message); } } catch (error) { - console.error("회사 목록 조회 실패:", error); + // console.error("회사 목록 조회 실패:", error); } }; @@ -93,7 +93,7 @@ export default function MultiLangPage() { setLanguages(data.data); } } catch (error) { - console.error("언어 목록 조회 실패:", error); + // console.error("언어 목록 조회 실패:", error); } }; @@ -103,13 +103,13 @@ export default function MultiLangPage() { const response = await apiClient.get("/multilang/keys"); const data = response.data; if (data.success) { - console.log("✅ 전체 키 목록 로드:", data.data.length, "개"); + // console.log("✅ 전체 키 목록 로드:", data.data.length, "개"); setLangKeys(data.data); } else { - console.error("❌ 키 목록 로드 실패:", data.message); + // console.error("❌ 키 목록 로드 실패:", data.message); } } catch (error) { - console.error("다국어 키 목록 조회 실패:", error); + // console.error("다국어 키 목록 조회 실패:", error); } }; @@ -146,25 +146,25 @@ export default function MultiLangPage() { // 선택된 키의 다국어 텍스트 조회 const fetchLangTexts = async (keyId: number) => { try { - console.log("다국어 텍스트 조회 시작: keyId =", keyId); + // console.log("다국어 텍스트 조회 시작: keyId =", keyId); const response = await apiClient.get(`/multilang/keys/${keyId}/texts`); const data = response.data; - console.log("다국어 텍스트 조회 응답:", data); + // console.log("다국어 텍스트 조회 응답:", data); if (data.success) { setLangTexts(data.data); // 편집용 텍스트 초기화 const editingData = data.data.map((text: LangText) => ({ ...text })); setEditingTexts(editingData); - console.log("편집용 텍스트 설정:", editingData); + // console.log("편집용 텍스트 설정:", editingData); } } catch (error) { - console.error("다국어 텍스트 조회 실패:", error); + // console.error("다국어 텍스트 조회 실패:", error); } }; // 언어 키 선택 처리 const handleKeySelect = (key: LangKey) => { - console.log("언어 키 선택:", key); + // console.log("언어 키 선택:", key); setSelectedKey(key); fetchLangTexts(key.keyId); }; @@ -172,9 +172,9 @@ export default function MultiLangPage() { // 디버깅용 useEffect useEffect(() => { if (selectedKey) { - console.log("선택된 키 변경:", selectedKey); - console.log("언어 목록:", languages); - console.log("편집 텍스트:", editingTexts); + // console.log("선택된 키 변경:", selectedKey); + // console.log("언어 목록:", languages); + // console.log("편집 텍스트:", editingTexts); } }, [selectedKey, languages, editingTexts]); @@ -222,7 +222,7 @@ export default function MultiLangPage() { fetchLangTexts(selectedKey.keyId); } } catch (error) { - console.error("텍스트 저장 실패:", error); + // console.error("텍스트 저장 실패:", error); alert("저장에 실패했습니다."); } }; @@ -271,7 +271,7 @@ export default function MultiLangPage() { alert(`오류: ${result.message}`); } } catch (error) { - console.error("언어 저장 중 오류:", error); + // console.error("언어 저장 중 오류:", error); alert("언어 저장 중 오류가 발생했습니다."); } }; @@ -307,7 +307,7 @@ export default function MultiLangPage() { alert(`${failedDeletes.length}개의 언어 삭제에 실패했습니다.`); } } catch (error) { - console.error("언어 삭제 중 오류:", error); + // console.error("언어 삭제 중 오류:", error); alert("언어 삭제 중 오류가 발생했습니다."); } }; @@ -369,7 +369,7 @@ export default function MultiLangPage() { } } } catch (error) { - console.error("언어 키 저장 실패:", error); + // console.error("언어 키 저장 실패:", error); alert("언어 키 저장에 실패했습니다."); } }; @@ -397,7 +397,7 @@ export default function MultiLangPage() { alert("상태 변경 중 오류가 발생했습니다."); } } catch (error) { - console.error("키 상태 토글 실패:", error); + // console.error("키 상태 토글 실패:", error); alert("키 상태 변경 중 오류가 발생했습니다."); } }; @@ -414,7 +414,7 @@ export default function MultiLangPage() { alert("언어 상태 변경 중 오류가 발생했습니다."); } } catch (error) { - console.error("언어 상태 토글 실패:", error); + // console.error("언어 상태 토글 실패:", error); alert("언어 상태 변경 중 오류가 발생했습니다."); } }; @@ -463,7 +463,7 @@ export default function MultiLangPage() { alert("일부 키 삭제에 실패했습니다."); } } catch (error) { - console.error("선택된 키 삭제 실패:", error); + // console.error("선택된 키 삭제 실패:", error); alert("선택된 키 삭제에 실패했습니다."); } }; @@ -485,7 +485,7 @@ export default function MultiLangPage() { } } } catch (error) { - console.error("언어 키 삭제 실패:", error); + // console.error("언어 키 삭제 실패:", error); alert("언어 키 삭제에 실패했습니다."); } }; diff --git a/frontend/components/admin/ScreenAssignmentTab.tsx b/frontend/components/admin/ScreenAssignmentTab.tsx index 26081e95..18c84e5c 100644 --- a/frontend/components/admin/ScreenAssignmentTab.tsx +++ b/frontend/components/admin/ScreenAssignmentTab.tsx @@ -40,15 +40,15 @@ export const ScreenAssignmentTab: React.FC = ({ menus const [selectedScreen, setSelectedScreen] = useState(null); // 디버그: 전달받은 메뉴 데이터 확인 - console.log("ScreenAssignmentTab - 전달받은 메뉴 데이터:", { - total: menus.length, - sample: menus.slice(0, 3), - keys: menus.length > 0 ? Object.keys(menus[0]) : [], - }); + // console.log("ScreenAssignmentTab - 전달받은 메뉴 데이터:", { + // total: menus.length, + // sample: menus.slice(0, 3), + // keys: menus.length > 0 ? Object.keys(menus[0]) : [], + // }); // 메뉴 선택 const handleMenuSelect = async (menuId: string) => { - console.log("메뉴 선택:", menuId); + // console.log("메뉴 선택:", menuId); setSelectedMenuId(menuId); // 다양한 형식의 objid 대응 @@ -57,7 +57,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus return objid?.toString() === menuId; }); - console.log("선택된 메뉴:", menu); + // console.log("선택된 메뉴:", menu); setSelectedMenu(menu || null); if (menu) { @@ -75,7 +75,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus const screens = await menuScreenApi.getScreensByMenu(menuObjid); setAssignedScreens(screens); } catch (error) { - console.error("할당된 화면 로드 실패:", error); + // console.error("할당된 화면 로드 실패:", error); toast.error("할당된 화면 목록을 불러오는데 실패했습니다."); } finally { setLoading(false); @@ -94,7 +94,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus setAvailableScreens(available); } catch (error) { - console.error("사용 가능한 화면 로드 실패:", error); + // console.error("사용 가능한 화면 로드 실패:", error); toast.error("사용 가능한 화면 목록을 불러오는데 실패했습니다."); } }; @@ -118,7 +118,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus setShowAssignDialog(false); setSelectedScreen(null); } catch (error) { - console.error("화면 할당 실패:", error); + // console.error("화면 할당 실패:", error); toast.error("화면 할당에 실패했습니다."); } }; @@ -142,7 +142,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus setShowUnassignDialog(false); setSelectedScreen(null); } catch (error) { - console.error("화면 할당 해제 실패:", error); + // console.error("화면 할당 해제 실패:", error); toast.error("화면 할당 해제에 실패했습니다."); } }; @@ -162,14 +162,14 @@ export const ScreenAssignmentTab: React.FC = ({ menus // 단순화된 메뉴 옵션 생성 (모든 메뉴를 평면적으로 표시) const getMenuOptions = (menuList: MenuItem[]): JSX.Element[] => { - console.log("메뉴 옵션 생성:", { - total: menuList.length, - sample: menuList.slice(0, 3).map((m) => ({ - objid: m.objid || m.OBJID || (m as any).objid, - name: m.menu_name_kor || m.MENU_NAME_KOR || (m as any).menu_name_kor, - parent: m.parent_obj_id || m.PARENT_OBJ_ID || (m as any).parent_obj_id, - })), - }); + // console.log("메뉴 옵션 생성:", { + // total: menuList.length, + // sample: menuList.slice(0, 3).map((m) => ({ + // objid: m.objid || m.OBJID || (m as any).objid, + // name: m.menu_name_kor || m.MENU_NAME_KOR || (m as any).menu_name_kor, + // parent: m.parent_obj_id || m.PARENT_OBJ_ID || (m as any).parent_obj_id, + // })), + // }); if (!menuList || menuList.length === 0) { return [ @@ -188,7 +188,7 @@ export const ScreenAssignmentTab: React.FC = ({ menus // 들여쓰기 (레벨에 따라) const indent = " ".repeat(Math.max(0, lev)); - console.log("메뉴 항목:", { index, menuObjid, menuName, lev }); + // console.log("메뉴 항목:", { index, menuObjid, menuName, lev }); return ( diff --git a/frontend/components/screen/CopyScreenModal.tsx b/frontend/components/screen/CopyScreenModal.tsx index d540a783..ee4d6fe5 100644 --- a/frontend/components/screen/CopyScreenModal.tsx +++ b/frontend/components/screen/CopyScreenModal.tsx @@ -50,7 +50,7 @@ export default function CopyScreenModal({ isOpen, onClose, sourceScreen, onCopyS const newCode = await screenApi.generateScreenCode(sourceScreen.companyCode); setScreenCode(newCode); } catch (error) { - console.error("화면 코드 생성 실패:", error); + // console.error("화면 코드 생성 실패:", error); toast.error("화면 코드 생성에 실패했습니다."); } }; @@ -84,7 +84,7 @@ export default function CopyScreenModal({ isOpen, onClose, sourceScreen, onCopyS onCopySuccess(); handleClose(); } catch (error: any) { - console.error("화면 복사 실패:", error); + // console.error("화면 복사 실패:", error); const errorMessage = error.response?.data?.message || "화면 복사에 실패했습니다."; toast.error(errorMessage); } finally { diff --git a/frontend/components/screen/CreateScreenModal.tsx b/frontend/components/screen/CreateScreenModal.tsx index 7a221cd7..45c9e6d5 100644 --- a/frontend/components/screen/CreateScreenModal.tsx +++ b/frontend/components/screen/CreateScreenModal.tsx @@ -31,7 +31,7 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated }: Cre const generatedCode = await screenApi.generateScreenCode(companyCode); setScreenCode(generatedCode); } catch (e) { - console.error("화면 코드 생성 실패", e); + // console.error("화면 코드 생성 실패", e); } }; @@ -44,7 +44,7 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated }: Cre if (abort) return; setTables(list.map((t) => ({ tableName: t.tableName, displayName: t.displayName || t.tableName }))); } catch (e) { - console.error("테이블 목록 조회 실패", e); + // console.error("테이블 목록 조회 실패", e); setTables([]); } }; @@ -93,7 +93,7 @@ export default function CreateScreenModal({ open, onOpenChange, onCreated }: Cre setTableName(""); setDescription(""); } catch (e) { - console.error("화면 생성 실패", e); + // console.error("화면 생성 실패", e); // 필요 시 토스트 추가 가능 } finally { setSubmitting(false); diff --git a/frontend/components/screen/EnhancedInteractiveScreenViewer.tsx b/frontend/components/screen/EnhancedInteractiveScreenViewer.tsx index 8c553b3c..3207a522 100644 --- a/frontend/components/screen/EnhancedInteractiveScreenViewer.tsx +++ b/frontend/components/screen/EnhancedInteractiveScreenViewer.tsx @@ -292,7 +292,7 @@ export const EnhancedInteractiveScreenViewer: React.FC throw new Error(response.message || '파일 업로드에 실패했습니다.'); } } catch (error) { - console.error('파일 업로드 오류:', error); + // console.error('파일 업로드 오류:', error); toast.dismiss(); toast.error('파일 업로드에 실패했습니다.'); } finally { @@ -243,7 +243,7 @@ export const FileAttachmentDetailModal: React.FC toast.dismiss(); toast.success(`${file.realFileName} 다운로드가 완료되었습니다.`); } catch (error) { - console.error('파일 다운로드 오류:', error); + // console.error('파일 다운로드 오류:', error); toast.dismiss(); toast.error('파일 다운로드에 실패했습니다.'); } @@ -275,7 +275,7 @@ export const FileAttachmentDetailModal: React.FC toast.dismiss(); toast.success(`${file.realFileName}이 삭제되었습니다.`); } catch (error) { - console.error('파일 삭제 오류:', error); + // console.error('파일 삭제 오류:', error); toast.dismiss(); toast.error('파일 삭제에 실패했습니다.'); } diff --git a/frontend/components/screen/FloatingPanel.tsx b/frontend/components/screen/FloatingPanel.tsx index c853aa7d..fc3bd2a6 100644 --- a/frontend/components/screen/FloatingPanel.tsx +++ b/frontend/components/screen/FloatingPanel.tsx @@ -113,13 +113,13 @@ export const FloatingPanel: React.FC = ({ const newHeight = Math.min(Math.max(minHeight, contentHeight + headerHeight + padding), maxHeight); - console.log(`🔧 패널 높이 자동 조정:`, { - panelId: id, - contentHeight, - calculatedHeight: newHeight, - currentHeight: panelSize.height, - willUpdate: Math.abs(panelSize.height - newHeight) > 10, - }); + // console.log(`🔧 패널 높이 자동 조정:`, { + // panelId: id, + // contentHeight, + // calculatedHeight: newHeight, + // currentHeight: panelSize.height, + // willUpdate: Math.abs(panelSize.height - newHeight) > 10, + // }); // 현재 높이와 다르면 업데이트 if (Math.abs(panelSize.height - newHeight) > 10) { diff --git a/frontend/components/screen/InteractiveDataTable.tsx b/frontend/components/screen/InteractiveDataTable.tsx index f6b38cb4..4c552b39 100644 --- a/frontend/components/screen/InteractiveDataTable.tsx +++ b/frontend/components/screen/InteractiveDataTable.tsx @@ -150,7 +150,7 @@ export const InteractiveDataTable: React.FC = ({ return options; } } catch (error) { - console.error(`공통코드 옵션 로드 실패: ${categoryCode}`, error); + // console.error(`공통코드 옵션 로드 실패: ${categoryCode}`, error); } return []; @@ -176,7 +176,7 @@ export const InteractiveDataTable: React.FC = ({ return { hasFiles, fileCount, files: response.files || [] }; } catch (error) { - console.error("파일 상태 확인 오류:", error); + // console.error("파일 상태 확인 오류:", error); return { hasFiles: false, fileCount: 0, files: [] }; } }, @@ -235,7 +235,7 @@ export const InteractiveDataTable: React.FC = ({ return { hasFiles, fileCount, files, targetObjid }; } catch (error) { - console.error("컬럼별 파일 상태 확인 오류:", error); + // console.error("컬럼별 파일 상태 확인 오류:", error); return { hasFiles: false, fileCount: 0, files: [], targetObjid: null }; } }, @@ -301,13 +301,13 @@ export const InteractiveDataTable: React.FC = ({ // 이미지 로딩 실패 시 대체 URL 시도 const handleImageError = useCallback(() => { if (!imageLoadError && previewImage) { - console.error("이미지 로딩 실패:", previewImage); + // console.error("이미지 로딩 실패:", previewImage); setImageLoadError(true); // 대체 URL 생성 (직접 파일 경로 사용) if (previewImage.path) { const altUrl = getDirectFileUrl(previewImage.path); - console.log("대체 URL 시도:", altUrl); + // console.log("대체 URL 시도:", altUrl); setAlternativeImageUrl(altUrl); } else { toast.error("이미지를 불러올 수 없습니다."); @@ -365,7 +365,7 @@ export const InteractiveDataTable: React.FC = ({ try { return tableColumn?.detailSettings ? JSON.parse(tableColumn.detailSettings) : {}; } catch { - console.warn("상세 설정 파싱 실패:", tableColumn?.detailSettings); + // console.warn("상세 설정 파싱 실패:", tableColumn?.detailSettings); return {}; } }, @@ -483,7 +483,7 @@ export const InteractiveDataTable: React.FC = ({ setFileStatusMap(statusMap); }); } catch (error) { - console.error("❌ 테이블 데이터 조회 실패:", error); + // console.error("❌ 테이블 데이터 조회 실패:", error); setData([]); setTotal(0); setTotalPages(1); @@ -503,7 +503,7 @@ export const InteractiveDataTable: React.FC = ({ setCurrentUser(response.data); } } catch (error) { - console.error("현재 사용자 정보 로드 실패:", error); + // console.error("현재 사용자 정보 로드 실패:", error); } }; @@ -515,14 +515,14 @@ export const InteractiveDataTable: React.FC = ({ const handleRefreshFileStatus = async (event: CustomEvent) => { const { tableName, recordId, columnName, targetObjid, fileCount } = event.detail; - console.log("🔄 InteractiveDataTable 파일 상태 새로고침 이벤트 수신:", { - tableName, - recordId, - columnName, - targetObjid, - fileCount, - currentTableName: component.tableName - }); + // console.log("🔄 InteractiveDataTable 파일 상태 새로고침 이벤트 수신:", { + // tableName, + // recordId, + // columnName, + // targetObjid, + // fileCount, + // currentTableName: component.tableName + // }); // 현재 테이블과 일치하는지 확인 if (tableName === component.tableName) { @@ -534,12 +534,12 @@ export const InteractiveDataTable: React.FC = ({ [columnKey]: { hasFiles: fileCount > 0, fileCount } })); - console.log("✅ 파일 상태 업데이트 완료:", { - recordId, - columnKey, - hasFiles: fileCount > 0, - fileCount - }); + // console.log("✅ 파일 상태 업데이트 완료:", { + // recordId, + // columnKey, + // hasFiles: fileCount > 0, + // fileCount + // }); } }; @@ -559,7 +559,7 @@ export const InteractiveDataTable: React.FC = ({ const columns = await tableTypeApi.getColumns(component.tableName); setTableColumns(columns); } catch (error) { - console.error("테이블 컬럼 정보 로드 실패:", error); + // console.error("테이블 컬럼 정보 로드 실패:", error); } }; @@ -820,7 +820,7 @@ export const InteractiveDataTable: React.FC = ({ handleAddFormChange(columnName, fileNames); } } catch (error) { - console.error("파일 업로드 실패:", error); + // console.error("파일 업로드 실패:", error); alert("파일 업로드에 실패했습니다."); } finally { setUploadingFiles((prev) => ({ ...prev, [columnName]: false })); @@ -898,7 +898,7 @@ export const InteractiveDataTable: React.FC = ({ setIsAdding(true); // 실제 API 호출로 데이터 추가 - console.log("🔥 추가할 데이터:", addFormData); + // console.log("🔥 추가할 데이터:", addFormData); await tableTypeApi.addTableData(component.tableName, addFormData); // 모달 닫기 및 폼 초기화 @@ -908,7 +908,7 @@ export const InteractiveDataTable: React.FC = ({ // 첫 페이지로 이동하여 새 데이터 확인 loadData(1, searchValues); } catch (error) { - console.error("데이터 추가 실패:", error); + // console.error("데이터 추가 실패:", error); alert("데이터 추가에 실패했습니다."); } finally { setIsAdding(false); @@ -921,8 +921,8 @@ export const InteractiveDataTable: React.FC = ({ setIsEditing(true); // 실제 API 호출로 데이터 수정 - console.log("🔥 수정할 데이터:", editFormData); - console.log("🔥 원본 데이터:", editingRowData); + // console.log("🔥 수정할 데이터:", editFormData); + // console.log("🔥 원본 데이터:", editingRowData); if (editingRowData) { await tableTypeApi.editTableData(component.tableName, editingRowData, editFormData); @@ -937,7 +937,7 @@ export const InteractiveDataTable: React.FC = ({ loadData(currentPage, searchValues); } } catch (error) { - console.error("데이터 수정 실패:", error); + // console.error("데이터 수정 실패:", error); alert("데이터 수정에 실패했습니다."); } finally { setIsEditing(false); @@ -971,7 +971,7 @@ export const InteractiveDataTable: React.FC = ({ const selectedData = Array.from(selectedRows).map((index) => data[index]); // 실제 삭제 API 호출 - console.log("🗑️ 삭제할 데이터:", selectedData); + // console.log("🗑️ 삭제할 데이터:", selectedData); await tableTypeApi.deleteTableData(component.tableName, selectedData); // 선택 해제 및 다이얼로그 닫기 @@ -981,7 +981,7 @@ export const InteractiveDataTable: React.FC = ({ // 데이터 새로고침 loadData(currentPage, searchValues); } catch (error) { - console.error("데이터 삭제 실패:", error); + // console.error("데이터 삭제 실패:", error); alert("데이터 삭제에 실패했습니다."); } finally { setIsDeleting(false); @@ -1544,7 +1544,7 @@ export const InteractiveDataTable: React.FC = ({ // File 객체 유효성 검사 if (!(file instanceof File) && !(file instanceof Blob)) { - console.error("❌ 잘못된 파일 객체:", file); + // console.error("❌ 잘못된 파일 객체:", file); toast.error("파일 객체가 손상되었습니다. 파일을 다시 업로드해주세요."); return; } @@ -1560,7 +1560,7 @@ export const InteractiveDataTable: React.FC = ({ toast.success(`${fileInfo.name} 다운로드가 완료되었습니다.`); return; } catch (error) { - console.error("❌ 로컬 파일 다운로드 오류:", error); + // console.error("❌ 로컬 파일 다운로드 오류:", error); toast.error("로컬 파일 다운로드에 실패했습니다. 파일을 다시 업로드해주세요."); return; } @@ -1580,7 +1580,7 @@ export const InteractiveDataTable: React.FC = ({ toast.success(`${fileInfo.name} 다운로드가 완료되었습니다.`); } catch (error) { - console.error("파일 다운로드 오류:", error); + // console.error("파일 다운로드 오류:", error); toast.error(`${fileInfo.name} 다운로드에 실패했습니다.`); } }, []); @@ -1589,7 +1589,7 @@ export const InteractiveDataTable: React.FC = ({ const handleDeleteLinkedFile = useCallback( async (fileId: string, fileName: string) => { try { - console.log("🗑️ 파일 삭제 시작:", { fileId, fileName }); + // console.log("🗑️ 파일 삭제 시작:", { fileId, fileName }); // 삭제 확인 다이얼로그 if (!confirm(`"${fileName}" 파일을 삭제하시겠습니까?`)) { @@ -1605,7 +1605,7 @@ export const InteractiveDataTable: React.FC = ({ }); const result = response.data; - console.log("📡 파일 삭제 API 응답:", result); + // console.log("📡 파일 삭제 API 응답:", result); if (!result.success) { throw new Error(result.message || "파일 삭제 실패"); @@ -1622,15 +1622,15 @@ export const InteractiveDataTable: React.FC = ({ try { const response = await getLinkedFiles(component.tableName, recordId); setLinkedFiles(response.files || []); - console.log("📁 파일 목록 새로고침 완료:", response.files?.length || 0); + // console.log("📁 파일 목록 새로고침 완료:", response.files?.length || 0); } catch (error) { - console.error("파일 목록 새로고침 실패:", error); + // console.error("파일 목록 새로고침 실패:", error); } } - console.log("✅ 파일 삭제 완료:", fileName); + // console.log("✅ 파일 삭제 완료:", fileName); } catch (error) { - console.error("❌ 파일 삭제 실패:", error); + // console.error("❌ 파일 삭제 실패:", error); toast.error(`"${fileName}" 파일 삭제에 실패했습니다.`); } }, diff --git a/frontend/components/screen/InteractiveScreenViewer.tsx b/frontend/components/screen/InteractiveScreenViewer.tsx index 264a384a..85b2a7c4 100644 --- a/frontend/components/screen/InteractiveScreenViewer.tsx +++ b/frontend/components/screen/InteractiveScreenViewer.tsx @@ -153,7 +153,7 @@ export const InteractiveScreenViewer: React.FC = ( const loadPopupLayout = async () => { try { setPopupLoading(true); - console.log("🔍 팝업 화면 로드 시작:", popupScreen); + // console.log("🔍 팝업 화면 로드 시작:", popupScreen); // 화면 레이아웃과 화면 정보를 병렬로 가져오기 const [layout, screen] = await Promise.all([ @@ -180,7 +180,7 @@ export const InteractiveScreenViewer: React.FC = ( // 팝업 formData 초기화 setPopupFormData({}); } catch (error) { - console.error("❌ 팝업 화면 로드 실패:", error); + // console.error("❌ 팝업 화면 로드 실패:", error); setPopupLayout([]); setPopupScreenInfo(null); } finally { @@ -203,27 +203,27 @@ export const InteractiveScreenViewer: React.FC = ( // 폼 데이터 업데이트 const updateFormData = (fieldName: string, value: any) => { - console.log(`🔄 updateFormData: ${fieldName} = "${value}" (외부콜백: ${!!onFormDataChange})`); + // console.log(`🔄 updateFormData: ${fieldName} = "${value}" (외부콜백: ${!!onFormDataChange})`); // 항상 로컬 상태도 업데이트 setLocalFormData((prev) => ({ ...prev, [fieldName]: value, })); - console.log(`💾 로컬 상태 업데이트: ${fieldName} = "${value}"`); + // console.log(`💾 로컬 상태 업데이트: ${fieldName} = "${value}"`); // 외부 콜백이 있는 경우에도 전달 (개별 필드 단위로) if (onFormDataChange) { onFormDataChange(fieldName, value); - console.log(`📤 외부 콜백으로 전달: ${fieldName} = "${value}"`); + // console.log(`📤 외부 콜백으로 전달: ${fieldName} = "${value}"`); } }; // 자동입력 필드들의 값을 formData에 초기 설정 React.useEffect(() => { - console.log("🚀 자동입력 초기화 useEffect 실행 - allComponents 개수:", allComponents.length); + // console.log("🚀 자동입력 초기화 useEffect 실행 - allComponents 개수:", allComponents.length); const initAutoInputFields = () => { - console.log("🔧 initAutoInputFields 실행 시작"); + // console.log("🔧 initAutoInputFields 실행 시작"); allComponents.forEach(comp => { if (comp.type === 'widget') { const widget = comp as WidgetComponent; @@ -258,7 +258,7 @@ export const InteractiveScreenViewer: React.FC = ( updateFormData(fieldName, autoValue); } else { - console.log(`⏭️ 자동입력 건너뜀 (값 있음): ${fieldName} = "${currentValue}"`); + // console.log(`⏭️ 자동입력 건너뜀 (값 있음): ${fieldName} = "${currentValue}"`); } } } @@ -378,7 +378,7 @@ export const InteractiveScreenViewer: React.FC = ( // 입력 검증 함수 const handleInputChange = (e: React.ChangeEvent) => { const value = e.target.value; - console.log(`📝 입력 변경: ${fieldName} = "${value}"`); + // console.log(`📝 입력 변경: ${fieldName} = "${value}"`); // 형식별 실시간 검증 if (config?.format && config.format !== "none") { @@ -386,7 +386,7 @@ export const InteractiveScreenViewer: React.FC = ( if (pattern) { const regex = new RegExp(`^${pattern}$`); if (value && !regex.test(value)) { - console.log(`❌ 형식 검증 실패: ${fieldName} = "${value}"`); + // console.log(`❌ 형식 검증 실패: ${fieldName} = "${value}"`); return; // 유효하지 않은 입력 차단 } } @@ -394,11 +394,11 @@ export const InteractiveScreenViewer: React.FC = ( // 길이 제한 검증 if (config?.maxLength && value.length > config.maxLength) { - console.log(`❌ 길이 제한 초과: ${fieldName} = "${value}" (최대: ${config.maxLength})`); + // console.log(`❌ 길이 제한 초과: ${fieldName} = "${value}" (최대: ${config.maxLength})`); return; // 최대 길이 초과 차단 } - console.log(`✅ updateFormData 호출: ${fieldName} = "${value}"`); + // console.log(`✅ updateFormData 호출: ${fieldName} = "${value}"`); updateFormData(fieldName, value); }; @@ -797,16 +797,16 @@ export const InteractiveScreenViewer: React.FC = ( // 파일 선택을 취소한 경우 (files가 null이거나 길이가 0) if (!files || files.length === 0) { - console.log("📁 파일 선택 취소됨 - 기존 파일 유지"); + // console.log("📁 파일 선택 취소됨 - 기존 파일 유지"); // 현재 저장된 파일이 있는지 확인 const currentStoredValue = externalFormData?.[fieldName] || localFormData[fieldName]; if (currentStoredValue) { - console.log("📁 기존 파일 있음 - 유지:", currentStoredValue); + // console.log("📁 기존 파일 있음 - 유지:", currentStoredValue); // 기존 파일이 있으면 그대로 유지 (아무것도 하지 않음) return; } else { - console.log("📁 기존 파일 없음 - 빈 상태 유지"); + // console.log("📁 기존 파일 없음 - 빈 상태 유지"); // 기존 파일이 없으면 빈 상태 유지 return; } @@ -831,7 +831,7 @@ export const InteractiveScreenViewer: React.FC = ( const uploadResult = await uploadFilesAndCreateData(files); if (uploadResult.success) { - console.log("📁 업로드 완료된 파일 데이터:", uploadResult.data); + // console.log("📁 업로드 완료된 파일 데이터:", uploadResult.data); setLocalFormData(prev => ({ ...prev, [fieldName]: uploadResult.data })); @@ -845,7 +845,7 @@ export const InteractiveScreenViewer: React.FC = ( throw new Error("파일 업로드에 실패했습니다."); } } catch (error) { - console.error("파일 업로드 오류:", error); + // console.error("파일 업로드 오류:", error); toast.error("파일 업로드에 실패했습니다."); // 파일 입력 초기화 @@ -1023,12 +1023,12 @@ export const InteractiveScreenViewer: React.FC = ( isCodeType: true, // 코드 타입임을 명시 }} onEvent={(event: string, data: any) => { - console.log(`Code widget event: ${event}`, data); + // console.log(`Code widget event: ${event}`, data); }} /> ); } catch (error) { - console.error("DynamicWebTypeRenderer 로딩 실패, 기본 Select 사용:", error); + // console.error("DynamicWebTypeRenderer 로딩 실패, 기본 Select 사용:", error); // 폴백: 기본 Select 컴포넌트 사용 return applyStyles( @@ -1148,21 +1148,21 @@ export const InteractiveScreenViewer: React.FC = ( await handleCustomAction(); break; default: - console.log(`알 수 없는 액션 타입: ${actionType}`); + // console.log(`알 수 없는 액션 타입: ${actionType}`); } } catch (error) { - console.error(`버튼 액션 실행 오류 (${actionType}):`, error); + // console.error(`버튼 액션 실행 오류 (${actionType}):`, error); alert(`작업 중 오류가 발생했습니다: ${error.message}`); } }; // 저장 액션 (개선된 버전) const handleSaveAction = async () => { - console.log("💾 저장 시작"); + // console.log("💾 저장 시작"); // 개선된 검증 시스템이 활성화된 경우 if (enhancedValidation) { - console.log("🔍 개선된 검증 시스템 사용"); + // console.log("🔍 개선된 검증 시스템 사용"); const success = await enhancedValidation.saveForm(); if (success) { toast.success("데이터가 성공적으로 저장되었습니다!"); @@ -1172,7 +1172,7 @@ export const InteractiveScreenViewer: React.FC = ( // 기존 방식 (레거시 지원) const currentFormData = { ...localFormData, ...externalFormData }; - console.log("💾 기존 방식으로 저장 - currentFormData:", currentFormData); + // console.log("💾 기존 방식으로 저장 - currentFormData:", currentFormData); // formData 유효성 체크를 완화 (빈 객체라도 위젯이 있으면 저장 진행) const hasWidgets = allComponents.some(comp => comp.type === 'widget'); @@ -1249,7 +1249,7 @@ export const InteractiveScreenViewer: React.FC = ( existingValue: value }); } else if (!isAutoInput) { - console.log(`📝 일반 입력 필드: ${fieldName} = "${value}"`); + // console.log(`📝 일반 입력 필드: ${fieldName} = "${value}"`); } } @@ -1260,7 +1260,7 @@ export const InteractiveScreenViewer: React.FC = ( mappedData[saveKey] = value; } else if (widget.columnName) { // 값이 없지만 columnName이 있는 경우, 빈 문자열로 저장 - console.log(`⚠️ ${widget.columnName} 필드에 값이 없어 빈 문자열로 저장`); + // console.log(`⚠️ ${widget.columnName} 필드에 값이 없어 빈 문자열로 저장`); mappedData[widget.columnName] = ""; } } @@ -1275,20 +1275,20 @@ export const InteractiveScreenViewer: React.FC = ( }); // 각 컴포넌트의 상세 정보 로그 - console.log("🔍 컴포넌트별 데이터 수집 상세:"); + // console.log("🔍 컴포넌트별 데이터 수집 상세:"); allComponents.forEach(comp => { if (comp.type === 'widget') { const widget = comp as WidgetComponent; const fieldName = widget.columnName || widget.id; const value = currentFormData[fieldName]; const hasValue = value !== undefined && value !== null && value !== ''; - console.log(` - ${fieldName} (${widget.widgetType}): "${value}" (값있음: ${hasValue}, 컬럼명: ${widget.columnName})`); + // console.log(` - ${fieldName} (${widget.widgetType}): "${value}" (값있음: ${hasValue}, 컬럼명: ${widget.columnName})`); } }); // 매핑된 데이터가 비어있으면 경고 if (Object.keys(mappedData).length === 0) { - console.warn("⚠️ 매핑된 데이터가 없습니다. 빈 데이터로 저장됩니다."); + // console.warn("⚠️ 매핑된 데이터가 없습니다. 빈 데이터로 저장됩니다."); } // 테이블명 결정 (화면 정보에서 가져오거나 첫 번째 컴포넌트의 테이블명 사용) @@ -1302,13 +1302,13 @@ export const InteractiveScreenViewer: React.FC = ( data: mappedData, }; - console.log("🚀 API 저장 요청:", saveData); + // console.log("🚀 API 저장 요청:", saveData); const result = await dynamicFormApi.saveFormData(saveData); if (result.success) { alert("저장되었습니다."); - console.log("✅ 저장 성공:", result.data); + // console.log("✅ 저장 성공:", result.data); // 저장 후 데이터 초기화 (선택사항) if (onFormDataChange) { @@ -1322,7 +1322,7 @@ export const InteractiveScreenViewer: React.FC = ( throw new Error(result.message || "저장에 실패했습니다."); } } catch (error: any) { - console.error("❌ 저장 실패:", error); + // console.error("❌ 저장 실패:", error); alert(`저장 중 오류가 발생했습니다: ${error.message}`); } }; @@ -1355,13 +1355,13 @@ export const InteractiveScreenViewer: React.FC = ( } try { - console.log("🗑️ 삭제 실행:", { recordId, tableName, formData }); + // console.log("🗑️ 삭제 실행:", { recordId, tableName, formData }); const result = await dynamicFormApi.deleteFormDataFromTable(recordId, tableName); if (result.success) { alert("삭제되었습니다."); - console.log("✅ 삭제 성공"); + // console.log("✅ 삭제 성공"); // 삭제 후 폼 초기화 if (onFormDataChange) { @@ -1375,28 +1375,28 @@ export const InteractiveScreenViewer: React.FC = ( throw new Error(result.message || "삭제에 실패했습니다."); } } catch (error: any) { - console.error("❌ 삭제 실패:", error); + // console.error("❌ 삭제 실패:", error); alert(`삭제 중 오류가 발생했습니다: ${error.message}`); } }; // 편집 액션 const handleEditAction = () => { - console.log("✏️ 편집 모드 활성화"); + // console.log("✏️ 편집 모드 활성화"); // 읽기 전용 모드를 편집 모드로 전환 alert("편집 모드로 전환되었습니다."); }; // 추가 액션 const handleAddAction = () => { - console.log("➕ 새 항목 추가"); + // console.log("➕ 새 항목 추가"); // 새 항목 추가 로직 alert("새 항목을 추가할 수 있습니다."); }; // 검색 액션 const handleSearchAction = () => { - console.log("🔍 검색 실행:", formData); + // console.log("🔍 검색 실행:", formData); // 검색 로직 const searchTerms = Object.values(formData).filter(v => v && v.toString().trim()); if (searchTerms.length === 0) { @@ -1416,21 +1416,21 @@ export const InteractiveScreenViewer: React.FC = ( }); onFormDataChange(resetData); } - console.log("🔄 폼 초기화 완료"); + // console.log("🔄 폼 초기화 완료"); alert("입력이 초기화되었습니다."); } }; // 제출 액션 const handleSubmitAction = async () => { - console.log("📤 폼 제출:", formData); + // console.log("📤 폼 제출:", formData); // 제출 로직 alert("제출되었습니다."); }; // 닫기 액션 const handleCloseAction = () => { - console.log("❌ 닫기 액션 실행"); + // console.log("❌ 닫기 액션 실행"); // 모달 내부에서 실행되는지 확인 const isInModal = document.querySelector('[role="dialog"]') !== null; @@ -1438,7 +1438,7 @@ export const InteractiveScreenViewer: React.FC = ( if (isInModal) { // 모달 내부인 경우: 모달의 닫기 버튼 클릭하거나 모달 닫기 이벤트 발생 - console.log("🔄 모달 내부에서 닫기 - 모달 닫기 시도"); + // console.log("🔄 모달 내부에서 닫기 - 모달 닫기 시도"); // 모달의 닫기 버튼을 찾아서 클릭 const modalCloseButton = document.querySelector('[role="dialog"] button[aria-label*="Close"], [role="dialog"] button[data-dismiss="modal"], [role="dialog"] .dialog-close'); @@ -1451,18 +1451,18 @@ export const InteractiveScreenViewer: React.FC = ( } } else if (isInPopup) { // 팝업 창인 경우 - console.log("🔄 팝업 창 닫기"); + // console.log("🔄 팝업 창 닫기"); window.close(); } else { // 일반 페이지인 경우 - 이전 페이지로 이동하지 않고 아무것도 하지 않음 - console.log("🔄 일반 페이지에서 닫기 - 아무 동작 하지 않음"); + // console.log("🔄 일반 페이지에서 닫기 - 아무 동작 하지 않음"); alert("닫기 버튼이 클릭되었습니다."); } }; // 팝업 액션 const handlePopupAction = () => { - console.log("🎯 팝업 액션 실행:", { popupScreenId: config?.popupScreenId }); + // console.log("🎯 팝업 액션 실행:", { popupScreenId: config?.popupScreenId }); if (config?.popupScreenId) { // 화면 모달 열기 @@ -1528,12 +1528,12 @@ export const InteractiveScreenViewer: React.FC = ( if (result instanceof Promise) { await result; } - console.log("⚡ 커스텀 액션 실행 완료"); + // console.log("⚡ 커스텀 액션 실행 완료"); } catch (error) { throw new Error(`커스텀 액션 실행 실패: ${error.message}`); } } else { - console.log("⚡ 커스텀 액션이 설정되지 않았습니다."); + // console.log("⚡ 커스텀 액션이 설정되지 않았습니다."); } }; @@ -1619,7 +1619,7 @@ export const InteractiveScreenViewer: React.FC = ( company_code: file.companyCode })); - console.log("💾 attach_file_info 형태로 변환된 데이터:", fileInfoForDB); + // console.log("💾 attach_file_info 형태로 변환된 데이터:", fileInfoForDB); // FormData에는 파일 연결 정보만 저장 (간단한 형태) const formDataValue = { @@ -1633,7 +1633,7 @@ export const InteractiveScreenViewer: React.FC = ( })) }; - console.log("📝 FormData 저장값:", { fieldName, formDataValue }); + // console.log("📝 FormData 저장값:", { fieldName, formDataValue }); onFormDataChange(fieldName, formDataValue); // TODO: 실제 API 연동 시 attach_file_info 테이블에 저장 diff --git a/frontend/components/screen/InteractiveScreenViewerDynamic.tsx b/frontend/components/screen/InteractiveScreenViewerDynamic.tsx index 013b3d27..6d8b2efa 100644 --- a/frontend/components/screen/InteractiveScreenViewerDynamic.tsx +++ b/frontend/components/screen/InteractiveScreenViewerDynamic.tsx @@ -119,7 +119,7 @@ export const InteractiveScreenViewerDynamic: React.FC { - console.log(`🎯 InteractiveScreenViewerDynamic handleFormDataChange 호출: ${fieldName} = "${value}"`); - console.log(`📋 onFormDataChange 존재 여부:`, !!onFormDataChange); + // console.log(`🎯 InteractiveScreenViewerDynamic handleFormDataChange 호출: ${fieldName} = "${value}"`); + // console.log(`📋 onFormDataChange 존재 여부:`, !!onFormDataChange); if (onFormDataChange) { - console.log(`📤 InteractiveScreenViewerDynamic -> onFormDataChange 호출: ${fieldName} = "${value}"`); + // console.log(`📤 InteractiveScreenViewerDynamic -> onFormDataChange 호출: ${fieldName} = "${value}"`); onFormDataChange(fieldName, value); } else { - console.log(`💾 InteractiveScreenViewerDynamic 로컬 상태 업데이트: ${fieldName} = "${value}"`); + // console.log(`💾 InteractiveScreenViewerDynamic 로컬 상태 업데이트: ${fieldName} = "${value}"`); setLocalFormData((prev) => ({ ...prev, [fieldName]: value })); } }; @@ -240,14 +240,14 @@ export const InteractiveScreenViewerDynamic: React.FC { // 이벤트 처리 - console.log(`Widget event: ${event}`, data); + // console.log(`Widget event: ${event}`, data); }} /> ); return applyStyles(dynamicElement); } catch (error) { - console.error(`웹타입 "${widgetType}" 대화형 렌더링 실패:`, error); + // console.error(`웹타입 "${widgetType}" 대화형 렌더링 실패:`, error); // 오류 발생 시 폴백으로 기본 input 렌더링 const fallbackElement = ( { if (!config?.confirmationEnabled || window.confirm(config.confirmationMessage || "정말 삭제하시겠습니까?")) { - console.log("🗑️ 삭제 액션 실행"); + // console.log("🗑️ 삭제 액션 실행"); toast.success("삭제가 완료되었습니다."); } }; @@ -355,7 +355,7 @@ export const InteractiveScreenViewerDynamic: React.FC { - console.log("📝 실제 화면 파일 업로드 완료:", data); + // console.log("📝 실제 화면 파일 업로드 완료:", data); if (onFormDataChange) { Object.entries(data).forEach(([key, value]) => { onFormDataChange(key, value); @@ -486,25 +486,25 @@ export const InteractiveScreenViewerDynamic: React.FC { - console.log("🔄 실제 화면 추가 이벤트 발생 (지연 100ms)"); + // console.log("🔄 실제 화면 추가 이벤트 발생 (지연 100ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true } })); }, 100); setTimeout(() => { - console.log("🔄 실제 화면 추가 이벤트 발생 (지연 500ms)"); + // console.log("🔄 실제 화면 추가 이벤트 발생 (지연 500ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true, attempt: 2 } })); diff --git a/frontend/components/screen/MenuAssignmentModal.tsx b/frontend/components/screen/MenuAssignmentModal.tsx index deceff6f..a52f2369 100644 --- a/frontend/components/screen/MenuAssignmentModal.tsx +++ b/frontend/components/screen/MenuAssignmentModal.tsx @@ -71,13 +71,13 @@ export const MenuAssignmentModal: React.FC = ({ company_name: menu.company_name || menu.COMPANY_NAME, })); - console.log("로드된 관리자 메뉴 목록:", { - total: normalizedAdminMenus.length, - sample: normalizedAdminMenus.slice(0, 3), - }); + // console.log("로드된 관리자 메뉴 목록:", { + // total: normalizedAdminMenus.length, + // sample: normalizedAdminMenus.slice(0, 3), + // }); setMenus(normalizedAdminMenus); } catch (error) { - console.error("메뉴 목록 로드 실패:", error); + // console.error("메뉴 목록 로드 실패:", error); toast.error("메뉴 목록을 불러오는데 실패했습니다."); } finally { setLoading(false); @@ -117,10 +117,10 @@ export const MenuAssignmentModal: React.FC = ({ if (menuObjid > 0) { const screens = await menuScreenApi.getScreensByMenu(menuObjid); setExistingScreens(screens); - console.log(`메뉴 "${menu.menu_name_kor}"에 할당된 화면:`, screens); + // console.log(`메뉴 "${menu.menu_name_kor}"에 할당된 화면:`, screens); } } catch (error) { - console.error("할당된 화면 조회 실패:", error); + // console.error("할당된 화면 조회 실패:", error); setExistingScreens([]); } } @@ -166,13 +166,13 @@ export const MenuAssignmentModal: React.FC = ({ // 기존 화면 교체인 경우 기존 화면들 먼저 제거 if (replaceExisting && existingScreens.length > 0) { - console.log("기존 화면들 제거 중...", existingScreens); + // console.log("기존 화면들 제거 중...", existingScreens); for (const existingScreen of existingScreens) { try { await menuScreenApi.unassignScreenFromMenu(existingScreen.screenId, menuObjid); - console.log(`기존 화면 "${existingScreen.screenName}" 제거 완료`); + // console.log(`기존 화면 "${existingScreen.screenName}" 제거 완료`); } catch (error) { - console.error(`기존 화면 "${existingScreen.screenName}" 제거 실패:`, error); + // console.error(`기존 화면 "${existingScreen.screenName}" 제거 실패:`, error); } } } @@ -202,7 +202,7 @@ export const MenuAssignmentModal: React.FC = ({ } }, 3000); } catch (error: any) { - console.error("화면 할당 실패:", error); + // console.error("화면 할당 실패:", error); const errorMessage = error.response?.data?.message || "화면 할당에 실패했습니다."; toast.error(errorMessage); } finally { diff --git a/frontend/components/screen/OptimizedButtonComponent.tsx b/frontend/components/screen/OptimizedButtonComponent.tsx index 6d1ca380..107c9d42 100644 --- a/frontend/components/screen/OptimizedButtonComponent.tsx +++ b/frontend/components/screen/OptimizedButtonComponent.tsx @@ -62,7 +62,7 @@ export const OptimizedButtonComponent: React.FC = ({ const startTime = performance.now(); try { - console.log(`🔘 Button clicked: ${component.id} (${config?.actionType})`); + // console.log(`🔘 Button clicked: ${component.id} (${config?.actionType})`); // 🔥 확장된 컨텍스트 데이터 수집 const contextData = { @@ -88,14 +88,14 @@ export const OptimizedButtonComponent: React.FC = ({ // 🔥 제어 전용 액션인지 확인 const isControlOnlyAction = config?.actionType === "control"; - console.log("🎯 OptimizedButtonComponent 실행:", { - actionType: config?.actionType, - isControlOnlyAction, - enableDataflowControl: config?.enableDataflowControl, - hasDataflowConfig: !!config?.dataflowConfig, - selectedRows, - selectedRowsData, - }); + // console.log("🎯 OptimizedButtonComponent 실행:", { + // actionType: config?.actionType, + // isControlOnlyAction, + // enableDataflowControl: config?.enableDataflowControl, + // hasDataflowConfig: !!config?.dataflowConfig, + // selectedRows, + // selectedRowsData, + // }); if (config?.enableDataflowControl && config?.dataflowConfig) { // 🔥 확장된 제어 검증 먼저 실행 @@ -131,7 +131,7 @@ export const OptimizedButtonComponent: React.FC = ({ await executeOriginalAction(config?.actionType || "save", contextData); } } catch (error) { - console.error("Button execution failed:", error); + // console.error("Button execution failed:", error); toast.error("버튼 실행 중 오류가 발생했습니다."); setLastResult({ success: false, error: error.message }); } finally { @@ -142,9 +142,9 @@ export const OptimizedButtonComponent: React.FC = ({ // 성능 로깅 if (totalTime > 200) { - console.warn(`🐌 Slow button execution: ${totalTime.toFixed(2)}ms`); + // console.warn(`🐌 Slow button execution: ${totalTime.toFixed(2)}ms`); } else { - console.log(`⚡ Button execution: ${totalTime.toFixed(2)}ms`); + // console.log(`⚡ Button execution: ${totalTime.toFixed(2)}ms`); } } }, [isExecuting, disabled, component.id, config?.actionType, config?.enableDataflowControl, formData, clickCount]); @@ -212,22 +212,22 @@ export const OptimizedButtonComponent: React.FC = ({ switch (actionType) { case "save": - console.log("💾 Save action completed:", result); + // console.log("💾 Save action completed:", result); break; case "delete": - console.log("🗑️ Delete action completed:", result); + // console.log("🗑️ Delete action completed:", result); break; case "search": - console.log("🔍 Search action completed:", result); + // console.log("🔍 Search action completed:", result); break; case "add": - console.log("➕ Add action completed:", result); + // console.log("➕ Add action completed:", result); break; case "edit": - console.log("✏️ Edit action completed:", result); + // console.log("✏️ Edit action completed:", result); break; default: - console.log(`✅ ${actionType} action completed:`, result); + // console.log(`✅ ${actionType} action completed:`, result); } }; @@ -289,7 +289,7 @@ export const OptimizedButtonComponent: React.FC = ({ return newSet; }); - console.error("Background job failed:", status.result); + // console.error("Background job failed:", status.result); toast.error("백그라운드 처리 중 오류가 발생했습니다.", { duration: 3000 }); return; } @@ -298,7 +298,7 @@ export const OptimizedButtonComponent: React.FC = ({ if (pollCount < maxPolls && (status.status === "pending" || status.status === "processing")) { setTimeout(pollJobStatus, pollInterval); } else if (pollCount >= maxPolls) { - console.warn(`Background job polling timeout: ${jobId}`); + // console.warn(`Background job polling timeout: ${jobId}`); setBackgroundJobs((prev) => { const newSet = new Set(prev); newSet.delete(jobId); @@ -306,7 +306,7 @@ export const OptimizedButtonComponent: React.FC = ({ }); } } catch (error) { - console.error("Failed to check job status:", error); + // console.error("Failed to check job status:", error); setBackgroundJobs((prev) => { const newSet = new Set(prev); newSet.delete(jobId); @@ -388,7 +388,7 @@ export const OptimizedButtonComponent: React.FC = ({ ): Promise => { // 🔥 제어 액션은 여기서 처리하지 않음 (이미 위에서 처리됨) if (actionType === "control") { - console.warn("제어 액션은 executeOriginalAction에서 처리되지 않아야 합니다."); + // console.warn("제어 액션은 executeOriginalAction에서 처리되지 않아야 합니다."); return; } diff --git a/frontend/components/screen/RealtimePreview.tsx b/frontend/components/screen/RealtimePreview.tsx index 82e1db47..5841313a 100644 --- a/frontend/components/screen/RealtimePreview.tsx +++ b/frontend/components/screen/RealtimePreview.tsx @@ -112,7 +112,7 @@ const WidgetRenderer: React.FC<{ component: ComponentData }> = ({ component }) = const { widgetType, label, placeholder, required, readonly, columnName, style } = widget; // 디버깅: 실제 widgetType 값 확인 - console.log("RealtimePreviewDynamic - widgetType:", widgetType, "columnName:", columnName); + // console.log("RealtimePreviewDynamic - widgetType:", widgetType, "columnName:", columnName); // 사용자가 테두리를 설정했는지 확인 const hasCustomBorder = style && (style.borderWidth || style.borderStyle || style.borderColor || style.border); @@ -129,11 +129,11 @@ const WidgetRenderer: React.FC<{ component: ComponentData }> = ({ component }) = // 파일 컴포넌트는 별도 로직에서 처리하므로 여기서는 제외 if (isFileComponent(widget)) { - console.log("🎯 RealtimePreview - 파일 컴포넌트 감지 (별도 처리):", { - componentId: widget.id, - widgetType: widgetType, - isFileComponent: true - }); + // console.log("🎯 RealtimePreview - 파일 컴포넌트 감지 (별도 처리):", { + // componentId: widget.id, + // widgetType: widgetType, + // isFileComponent: true + // }); return
파일 컴포넌트 (별도 렌더링)
; } @@ -154,7 +154,7 @@ const WidgetRenderer: React.FC<{ component: ComponentData }> = ({ component }) = /> ); } catch (error) { - console.error(`웹타입 "${widgetType}" 렌더링 실패:`, error); + // console.error(`웹타입 "${widgetType}" 렌더링 실패:`, error); // 오류 발생 시 폴백으로 기본 input 렌더링 return ; } @@ -226,66 +226,66 @@ export const RealtimePreviewDynamic: React.FC = ({ // 전역 파일 상태 변경 감지 (해당 컴포넌트만) useEffect(() => { const handleGlobalFileStateChange = (event: CustomEvent) => { - console.log("🎯🎯🎯 RealtimePreview 이벤트 수신:", { - eventComponentId: event.detail.componentId, - currentComponentId: component.id, - isMatch: event.detail.componentId === component.id, - filesCount: event.detail.files?.length || 0, - action: event.detail.action, - delayed: event.detail.delayed || false, - attempt: event.detail.attempt || 1, - eventDetail: event.detail - }); + // console.log("🎯🎯🎯 RealtimePreview 이벤트 수신:", { + // eventComponentId: event.detail.componentId, + // currentComponentId: component.id, + // isMatch: event.detail.componentId === component.id, + // filesCount: event.detail.files?.length || 0, + // action: event.detail.action, + // delayed: event.detail.delayed || false, + // attempt: event.detail.attempt || 1, + // eventDetail: event.detail + // }); if (event.detail.componentId === component.id) { - console.log("✅✅✅ RealtimePreview 파일 상태 변경 감지 - 리렌더링 시작:", { - componentId: component.id, - filesCount: event.detail.files?.length || 0, - action: event.detail.action, - oldTrigger: fileUpdateTrigger, - delayed: event.detail.delayed || false, - attempt: event.detail.attempt || 1 - }); + // console.log("✅✅✅ RealtimePreview 파일 상태 변경 감지 - 리렌더링 시작:", { + // componentId: component.id, + // filesCount: event.detail.files?.length || 0, + // action: event.detail.action, + // oldTrigger: fileUpdateTrigger, + // delayed: event.detail.delayed || false, + // attempt: event.detail.attempt || 1 + // }); setFileUpdateTrigger(prev => { const newTrigger = prev + 1; - console.log("🔄🔄🔄 fileUpdateTrigger 업데이트:", { - old: prev, - new: newTrigger, - componentId: component.id, - attempt: event.detail.attempt || 1 - }); + // console.log("🔄🔄🔄 fileUpdateTrigger 업데이트:", { + // old: prev, + // new: newTrigger, + // componentId: component.id, + // attempt: event.detail.attempt || 1 + // }); return newTrigger; }); } else { - console.log("❌ 컴포넌트 ID 불일치:", { - eventComponentId: event.detail.componentId, - currentComponentId: component.id - }); + // console.log("❌ 컴포넌트 ID 불일치:", { + // eventComponentId: event.detail.componentId, + // currentComponentId: component.id + // }); } }; // 강제 업데이트 함수 등록 const forceUpdate = (componentId: string, files: any[]) => { - console.log("🔥🔥🔥 RealtimePreview 강제 업데이트 호출:", { - targetComponentId: componentId, - currentComponentId: component.id, - isMatch: componentId === component.id, - filesCount: files.length - }); + // console.log("🔥🔥🔥 RealtimePreview 강제 업데이트 호출:", { + // targetComponentId: componentId, + // currentComponentId: component.id, + // isMatch: componentId === component.id, + // filesCount: files.length + // }); if (componentId === component.id) { - console.log("✅✅✅ RealtimePreview 강제 업데이트 적용:", { - componentId: component.id, - filesCount: files.length, - oldTrigger: fileUpdateTrigger - }); + // console.log("✅✅✅ RealtimePreview 강제 업데이트 적용:", { + // componentId: component.id, + // filesCount: files.length, + // oldTrigger: fileUpdateTrigger + // }); setFileUpdateTrigger(prev => { const newTrigger = prev + 1; - console.log("🔄🔄🔄 강제 fileUpdateTrigger 업데이트:", { - old: prev, - new: newTrigger, - componentId: component.id - }); + // console.log("🔄🔄🔄 강제 fileUpdateTrigger 업데이트:", { + // old: prev, + // new: newTrigger, + // componentId: component.id + // }); return newTrigger; }); } @@ -300,14 +300,14 @@ export const RealtimePreviewDynamic: React.FC = ({ (window as any).forceRealtimePreviewUpdate = forceUpdate; } } catch (error) { - console.warn("RealtimePreview 이벤트 리스너 등록 실패:", error); + // console.warn("RealtimePreview 이벤트 리스너 등록 실패:", error); } return () => { try { window.removeEventListener('globalFileStateChanged', handleGlobalFileStateChange as EventListener); } catch (error) { - console.warn("RealtimePreview 이벤트 리스너 제거 실패:", error); + // console.warn("RealtimePreview 이벤트 리스너 제거 실패:", error); } }; } @@ -423,16 +423,16 @@ export const RealtimePreviewDynamic: React.FC = ({ // 최신 파일 정보 사용 (전역 상태 > 컴포넌트 속성) const currentFiles = globalFiles.length > 0 ? globalFiles : uploadedFiles; - console.log("🔍 RealtimePreview 파일 컴포넌트 렌더링:", { - componentId: component.id, - uploadedFilesCount: uploadedFiles.length, - globalFilesCount: globalFiles.length, - currentFilesCount: currentFiles.length, - currentFiles: currentFiles.map((f: any) => ({ objid: f.objid, name: f.realFileName || f.name })), - componentType: component.type, - fileUpdateTrigger: fileUpdateTrigger, - timestamp: new Date().toISOString() - }); + // console.log("🔍 RealtimePreview 파일 컴포넌트 렌더링:", { + // componentId: component.id, + // uploadedFilesCount: uploadedFiles.length, + // globalFilesCount: globalFiles.length, + // currentFilesCount: currentFiles.length, + // currentFiles: currentFiles.map((f: any) => ({ objid: f.objid, name: f.realFileName || f.name })), + // componentType: component.type, + // fileUpdateTrigger: fileUpdateTrigger, + // timestamp: new Date().toISOString() + // }); return (
diff --git a/frontend/components/screen/ScreenDesigner.tsx b/frontend/components/screen/ScreenDesigner.tsx index c765e788..7ad4df42 100644 --- a/frontend/components/screen/ScreenDesigner.tsx +++ b/frontend/components/screen/ScreenDesigner.tsx @@ -201,14 +201,14 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD const restoreFileComponentsData = useCallback(async (components: ComponentData[]) => { if (!selectedScreen?.screenId) return; - console.log("🔄 파일 컴포넌트 데이터 복원 시작:", components.length); + // console.log("🔄 파일 컴포넌트 데이터 복원 시작:", components.length); try { // 실제 DB에서 화면의 모든 파일 정보 조회 const fileResponse = await ScreenFileAPI.getScreenComponentFiles(selectedScreen.screenId); if (!fileResponse.success) { - console.warn("⚠️ 파일 정보 조회 실패:", fileResponse); + // console.warn("⚠️ 파일 정보 조회 실패:", fileResponse); return; } @@ -271,7 +271,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD } } } catch (error) { - console.error("❌ 파일 컴포넌트 데이터 복원 실패:", error); + // console.error("❌ 파일 컴포넌트 데이터 복원 실패:", error); toast.error("파일 데이터 복원 중 오류가 발생했습니다."); } }, [selectedScreen?.screenId]); @@ -723,11 +723,11 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD useEffect(() => { const initComponents = async () => { try { - console.log("🚀 컴포넌트 시스템 초기화 시작..."); + // console.log("🚀 컴포넌트 시스템 초기화 시작..."); await initializeComponents(); - console.log("✅ 컴포넌트 시스템 초기화 완료"); + // console.log("✅ 컴포넌트 시스템 초기화 완료"); } catch (error) { - console.error("❌ 컴포넌트 시스템 초기화 실패:", error); + // console.error("❌ 컴포넌트 시스템 초기화 실패:", error); } }; @@ -746,13 +746,13 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD if (!selectedScreen?.screenId) return; try { - console.log("🔄 화면 파일 복원 시작:", selectedScreen.screenId); + // console.log("🔄 화면 파일 복원 시작:", selectedScreen.screenId); // 해당 화면의 모든 파일 조회 const response = await ScreenFileAPI.getScreenComponentFiles(selectedScreen.screenId); if (response.success && response.componentFiles) { - console.log("📁 복원할 파일 데이터:", response.componentFiles); + // console.log("📁 복원할 파일 데이터:", response.componentFiles); // 각 컴포넌트별로 파일 복원 (전역 상태와 localStorage 우선 적용) Object.entries(response.componentFiles).forEach(([componentId, serverFiles]) => { @@ -769,7 +769,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD currentLocalStorageFiles = JSON.parse(storedFiles); } } catch (e) { - console.warn("localStorage 파일 파싱 실패:", e); + // console.warn("localStorage 파일 파싱 실패:", e); } } @@ -777,12 +777,12 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD let finalFiles = serverFiles; if (currentGlobalFiles.length > 0) { finalFiles = currentGlobalFiles; - console.log(`📂 컴포넌트 ${componentId} 전역 상태 우선 적용:`, finalFiles.length, "개"); + // console.log(`📂 컴포넌트 ${componentId} 전역 상태 우선 적용:`, finalFiles.length, "개"); } else if (currentLocalStorageFiles.length > 0) { finalFiles = currentLocalStorageFiles; - console.log(`📂 컴포넌트 ${componentId} localStorage 우선 적용:`, finalFiles.length, "개"); + // console.log(`📂 컴포넌트 ${componentId} localStorage 우선 적용:`, finalFiles.length, "개"); } else { - console.log(`📂 컴포넌트 ${componentId} 서버 데이터 적용:`, finalFiles.length, "개"); + // console.log(`📂 컴포넌트 ${componentId} 서버 데이터 적용:`, finalFiles.length, "개"); } // 전역 상태에 파일 저장 @@ -821,17 +821,17 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }; }); - console.log("✅ 화면 파일 복원 완료"); + // console.log("✅ 화면 파일 복원 완료"); } } catch (error) { - console.error("❌ 화면 파일 복원 오류:", error); + // console.error("❌ 화면 파일 복원 오류:", error); } }, [selectedScreen?.screenId]); // 전역 파일 상태 변경 이벤트 리스너 useEffect(() => { const handleGlobalFileStateChange = (event: CustomEvent) => { - console.log("🔄 ScreenDesigner: 전역 파일 상태 변경 감지", event.detail); + // console.log("🔄 ScreenDesigner: 전역 파일 상태 변경 감지", event.detail); setForceRenderTrigger(prev => prev + 1); }; @@ -881,7 +881,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }; setTables([tableInfo]); // 단일 테이블 정보만 설정 } catch (error) { - console.error("테이블 정보 로드 실패:", error); + // console.error("테이블 정보 로드 실패:", error); toast.error(`테이블 '${selectedScreen.tableName}' 정보를 불러오는데 실패했습니다.`); } }; @@ -923,13 +923,13 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 저장된 해상도 정보가 있으면 적용, 없으면 기본값 사용 if (response.screenResolution) { setScreenResolution(response.screenResolution); - console.log("💾 저장된 해상도 불러옴:", response.screenResolution); + // console.log("💾 저장된 해상도 불러옴:", response.screenResolution); } else { // 기본 해상도 (Full HD) const defaultResolution = SCREEN_RESOLUTIONS.find((r) => r.name === "Full HD (1920×1080)") || SCREEN_RESOLUTIONS[0]; setScreenResolution(defaultResolution); - console.log("🔧 기본 해상도 적용:", defaultResolution); + // console.log("🔧 기본 해상도 적용:", defaultResolution); } setLayout(layoutWithDefaultGrid); @@ -940,7 +940,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD restoreFileComponentsData(layoutWithDefaultGrid.components); } } catch (error) { - console.error("레이아웃 로드 실패:", error); + // console.error("레이아웃 로드 실패:", error); toast.error("화면 레이아웃을 불러오는데 실패했습니다."); } }; @@ -989,8 +989,8 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }); newLayout.components = adjustedComponents; - console.log("격자 설정 변경으로 컴포넌트 위치 및 크기 자동 조정:", adjustedComponents.length, "개"); - console.log("새로운 격자 정보:", newGridInfo); + // console.log("격자 설정 변경으로 컴포넌트 위치 및 크기 자동 조정:", adjustedComponents.length, "개"); + // console.log("새로운 격자 정보:", newGridInfo); } setLayout(newLayout); @@ -1033,7 +1033,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 강제 격자 재조정 핸들러 (해상도 변경 후 수동 격자 맞춤용) const handleForceGridUpdate = useCallback(() => { if (!layout.gridSettings?.snapToGrid || layout.components.length === 0) { - console.log("격자 재조정 생략: 스냅 비활성화 또는 컴포넌트 없음"); + // console.log("격자 재조정 생략: 스냅 비활성화 또는 컴포넌트 없음"); return; } @@ -1114,7 +1114,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 저장 성공 후 메뉴 할당 모달 열기 setShowMenuAssignmentModal(true); } catch (error) { - console.error("저장 실패:", error); + // console.error("저장 실패:", error); toast.error("저장 중 오류가 발생했습니다."); } finally { setIsSaving(false); @@ -1581,7 +1581,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 존 클릭 핸들러 const handleZoneClick = useCallback((zoneId: string) => { - console.log("🎯 존 클릭:", zoneId); + // console.log("🎯 존 클릭:", zoneId); // 필요시 존 선택 로직 추가 }, []); @@ -1648,7 +1648,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD return; } } catch (error) { - console.error("드래그 데이터 파싱 오류:", error); + // console.error("드래그 데이터 파싱 오류:", error); return; } } @@ -1810,15 +1810,15 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD e.preventDefault(); const dragData = e.dataTransfer.getData("application/json"); - console.log("🎯 드롭 이벤트:", { dragData }); + // console.log("🎯 드롭 이벤트:", { dragData }); if (!dragData) { - console.log("❌ 드래그 데이터가 없습니다"); + // console.log("❌ 드래그 데이터가 없습니다"); return; } try { const parsedData = JSON.parse(dragData); - console.log("📋 파싱된 데이터:", parsedData); + // console.log("📋 파싱된 데이터:", parsedData); // 템플릿 드래그인 경우 if (parsedData.type === "template") { @@ -1871,7 +1871,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }, }; } else if (type === "column") { - console.log("🔄 컬럼 드롭 처리:", { webType: column.widgetType, columnName: column.columnName }); + // console.log("🔄 컬럼 드롭 처리:", { webType: column.widgetType, columnName: column.columnName }); // 현재 해상도에 맞는 격자 정보로 기본 크기 계산 const currentGridInfo = layout.gridSettings ? calculateGridInfo(screenResolution.width, screenResolution.height, { @@ -2052,7 +2052,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 웹타입을 새로운 컴포넌트 ID로 매핑 const componentId = getComponentIdFromWebType(column.widgetType); - console.log(`🔄 폼 컨테이너 드롭: ${column.widgetType} → ${componentId}`); + // console.log(`🔄 폼 컨테이너 드롭: ${column.widgetType} → ${componentId}`); newComponent = { id: generateComponentId(), @@ -2096,7 +2096,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD } else { // 일반 캔버스에 드롭한 경우 - 새로운 컴포넌트 시스템 사용 const componentId = getComponentIdFromWebType(column.widgetType); - console.log(`🔄 캔버스 드롭: ${column.widgetType} → ${componentId}`); + // console.log(`🔄 캔버스 드롭: ${column.widgetType} → ${componentId}`); newComponent = { id: generateComponentId(), @@ -2186,7 +2186,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 속성 패널 자동 열기 openPanel("properties"); } catch (error) { - console.error("드롭 처리 실패:", error); + // console.error("드롭 처리 실패:", error); } }, [layout, gridInfo, saveToHistory, openPanel], @@ -2237,7 +2237,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD } // 다른 컴포넌트 타입의 더블클릭 처리는 여기에 추가 - console.log("더블클릭된 컴포넌트:", component.type, component.id); + // console.log("더블클릭된 컴포넌트:", component.type, component.id); }, [], ); @@ -2339,7 +2339,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD componentsToMove = [...componentsToMove, ...additionalComponents]; } - console.log("드래그 시작:", component.id, "이동할 컴포넌트 수:", componentsToMove.length); + // console.log("드래그 시작:", component.id, "이동할 컴포넌트 수:", componentsToMove.length); console.log("마우스 위치:", { clientX: event.clientX, clientY: event.clientY, @@ -2706,7 +2706,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD const deleteComponent = useCallback(() => { // 다중 선택된 컴포넌트가 있는 경우 if (groupState.selectedComponents.length > 0) { - console.log("🗑️ 다중 컴포넌트 삭제:", groupState.selectedComponents.length, "개"); + // console.log("🗑️ 다중 컴포넌트 삭제:", groupState.selectedComponents.length, "개"); let newComponents = [...layout.components]; @@ -2751,7 +2751,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 단일 선택된 컴포넌트 삭제 if (!selectedComponent) return; - console.log("🗑️ 단일 컴포넌트 삭제:", selectedComponent.id); + // console.log("🗑️ 단일 컴포넌트 삭제:", selectedComponent.id); let newComponents; @@ -2789,12 +2789,12 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 다중 선택된 컴포넌트들 복사 const componentsToCopy = layout.components.filter((comp) => groupState.selectedComponents.includes(comp.id)); setClipboard(componentsToCopy); - console.log("다중 컴포넌트 복사:", componentsToCopy.length, "개"); + // console.log("다중 컴포넌트 복사:", componentsToCopy.length, "개"); toast.success(`${componentsToCopy.length}개 컴포넌트가 복사되었습니다.`); } else if (selectedComponent) { // 단일 컴포넌트 복사 setClipboard([selectedComponent]); - console.log("단일 컴포넌트 복사:", selectedComponent.id); + // console.log("단일 컴포넌트 복사:", selectedComponent.id); toast.success("컴포넌트가 복사되었습니다."); } }, [selectedComponent, groupState.selectedComponents, layout.components]); @@ -2837,14 +2837,14 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD selectedComponents: newComponents.map((comp) => comp.id), })); - console.log("컴포넌트 붙여넣기 완료:", newComponents.length, "개"); + // console.log("컴포넌트 붙여넣기 완료:", newComponents.length, "개"); toast.success(`${newComponents.length}개 컴포넌트가 붙여넣어졌습니다.`); }, [clipboard, layout, saveToHistory]); // 그룹 생성 (임시 비활성화) const handleGroupCreate = useCallback( (componentIds: string[], title: string, style?: any) => { - console.log("그룹 생성 기능이 임시 비활성화되었습니다."); + // console.log("그룹 생성 기능이 임시 비활성화되었습니다."); toast.info("그룹 기능이 임시 비활성화되었습니다."); return; @@ -3047,13 +3047,13 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD return; } - console.log("🔄 그룹 생성 다이얼로그 표시"); + // console.log("🔄 그룹 생성 다이얼로그 표시"); setShowGroupCreateDialog(true); }, [groupState.selectedComponents]); // 그룹 해제 함수 (임시 비활성화) const ungroupComponents = useCallback(() => { - console.log("그룹 해제 기능이 임시 비활성화되었습니다."); + // console.log("그룹 해제 기능이 임시 비활성화되었습니다."); toast.info("그룹 해제 기능이 임시 비활성화되었습니다."); return; @@ -3166,7 +3166,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 키보드 이벤트 처리 (브라우저 기본 기능 완전 차단) useEffect(() => { const handleKeyDown = async (e: KeyboardEvent) => { - console.log("🎯 키 입력 감지:", { key: e.key, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }); + // console.log("🎯 키 입력 감지:", { key: e.key, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }); // 🚫 브라우저 기본 단축키 완전 차단 목록 const browserShortcuts = [ @@ -3219,7 +3219,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }); if (isBrowserShortcut) { - console.log("🚫 브라우저 기본 단축키 차단:", e.key); + // console.log("🚫 브라우저 기본 단축키 차단:", e.key); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3229,38 +3229,38 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 1. 그룹 관련 단축키 if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "g" && !e.shiftKey) { - console.log("🔄 그룹 생성 단축키"); + // console.log("🔄 그룹 생성 단축키"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); if (groupState.selectedComponents.length >= 2) { - console.log("✅ 그룹 생성 실행"); + // console.log("✅ 그룹 생성 실행"); createGroup(); } else { - console.log("⚠️ 선택된 컴포넌트가 부족함 (2개 이상 필요)"); + // console.log("⚠️ 선택된 컴포넌트가 부족함 (2개 이상 필요)"); } return false; } if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key?.toLowerCase() === "g") { - console.log("🔄 그룹 해제 단축키"); + // console.log("🔄 그룹 해제 단축키"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); if (selectedComponent && selectedComponent.type === "group") { - console.log("✅ 그룹 해제 실행"); + // console.log("✅ 그룹 해제 실행"); ungroupComponents(); } else { - console.log("⚠️ 선택된 그룹이 없음"); + // console.log("⚠️ 선택된 그룹이 없음"); } return false; } // 2. 전체 선택 (애플리케이션 내에서만) if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "a") { - console.log("🔄 전체 선택 (애플리케이션 내)"); + // console.log("🔄 전체 선택 (애플리케이션 내)"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3271,7 +3271,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 3. 실행취소/다시실행 if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "z" && !e.shiftKey) { - console.log("🔄 실행취소"); + // console.log("🔄 실행취소"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3283,7 +3283,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "y") || ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key?.toLowerCase() === "z") ) { - console.log("🔄 다시실행"); + // console.log("🔄 다시실행"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3293,7 +3293,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 4. 복사 (컴포넌트 복사) if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "c") { - console.log("🔄 컴포넌트 복사"); + // console.log("🔄 컴포넌트 복사"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3303,7 +3303,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 5. 붙여넣기 (컴포넌트 붙여넣기) if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "v") { - console.log("🔄 컴포넌트 붙여넣기"); + // console.log("🔄 컴포넌트 붙여넣기"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3313,7 +3313,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 6. 삭제 (단일/다중 선택 지원) if (e.key === "Delete" && (selectedComponent || groupState.selectedComponents.length > 0)) { - console.log("🗑️ 컴포넌트 삭제 (단축키)"); + // console.log("🗑️ 컴포넌트 삭제 (단축키)"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3323,7 +3323,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 7. 선택 해제 if (e.key === "Escape") { - console.log("🔄 선택 해제"); + // console.log("🔄 선택 해제"); setSelectedComponent(null); setGroupState((prev) => ({ ...prev, selectedComponents: [], isGrouping: false })); return false; @@ -3331,7 +3331,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 8. 저장 (Ctrl+S는 레이아웃 저장용으로 사용) if ((e.ctrlKey || e.metaKey) && e.key?.toLowerCase() === "s") { - console.log("💾 레이아웃 저장"); + // console.log("💾 레이아웃 저장"); e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); @@ -3353,13 +3353,13 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD await screenApi.saveLayout(selectedScreen.screenId, layoutWithResolution); toast.success("레이아웃이 저장되었습니다."); } catch (error) { - console.error("레이아웃 저장 실패:", error); + // console.error("레이아웃 저장 실패:", error); toast.error("레이아웃 저장에 실패했습니다."); } finally { setIsSaving(false); } } else { - console.log("⚠️ 저장할 컴포넌트가 없습니다"); + // console.log("⚠️ 저장할 컴포넌트가 없습니다"); toast.warning("저장할 컴포넌트가 없습니다."); } return false; @@ -3455,7 +3455,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }} onDrop={(e) => { e.preventDefault(); - console.log("🎯 캔버스 드롭 이벤트 발생"); + // console.log("🎯 캔버스 드롭 이벤트 발생"); handleDrop(e); }} > @@ -3555,7 +3555,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD onZoneClick={handleZoneClick} // 설정 변경 핸들러 (테이블 페이지 크기 등 설정을 상세설정에 반영) onConfigChange={(config) => { - console.log("📤 테이블 설정 변경을 상세설정에 반영:", config); + // console.log("📤 테이블 설정 변경을 상세설정에 반영:", config); // 컴포넌트의 componentConfig 업데이트 const updatedComponents = layout.components.map(comp => { @@ -3667,7 +3667,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD onZoneClick={handleZoneClick} // 설정 변경 핸들러 (자식 컴포넌트용) onConfigChange={(config) => { - console.log("📤 자식 컴포넌트 설정 변경을 상세설정에 알림:", config); + // console.log("📤 자식 컴포넌트 설정 변경을 상세설정에 알림:", config); // TODO: 실제 구현은 DetailSettingsPanel과의 연동 필요 }} /> @@ -3732,13 +3732,13 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD searchTerm={searchTerm} onSearchChange={setSearchTerm} onDragStart={(e, table, column) => { - console.log("🚀 드래그 시작:", { table: table.tableName, column: column?.columnName }); + // console.log("🚀 드래그 시작:", { table: table.tableName, column: column?.columnName }); const dragData = { type: column ? "column" : "table", table, column, }; - console.log("📦 드래그 데이터:", dragData); + // console.log("📦 드래그 데이터:", dragData); e.dataTransfer.setData("application/json", JSON.stringify(dragData)); }} selectedTableName={selectedScreen.tableName} @@ -3984,7 +3984,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD onClose={() => setShowMenuAssignmentModal(false)} screenInfo={selectedScreen} onAssignmentComplete={() => { - console.log("메뉴 할당 완료"); + // console.log("메뉴 할당 완료"); // 필요시 추가 작업 수행 }} onBackToList={onBackToList} diff --git a/frontend/components/screen/ScreenDesigner_new.tsx b/frontend/components/screen/ScreenDesigner_new.tsx index bbec213c..16a50f3f 100644 --- a/frontend/components/screen/ScreenDesigner_new.tsx +++ b/frontend/components/screen/ScreenDesigner_new.tsx @@ -223,7 +223,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD const response = await screenApi.getTableInfo([selectedScreen.tableName]); setTables(response.data || []); } catch (error) { - console.error("테이블 정보 로드 실패:", error); + // console.error("테이블 정보 로드 실패:", error); toast.error("테이블 정보를 불러오는데 실패했습니다."); } finally { setIsLoading(false); @@ -247,7 +247,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD setHasUnsavedChanges(false); } } catch (error) { - console.error("레이아웃 로드 실패:", error); + // console.error("레이아웃 로드 실패:", error); toast.error("화면 레이아웃을 불러오는데 실패했습니다."); } finally { setIsLoading(false); @@ -271,7 +271,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD toast.error("저장에 실패했습니다."); } } catch (error) { - console.error("저장 실패:", error); + // console.error("저장 실패:", error); toast.error("저장 중 오류가 발생했습니다."); } finally { setIsSaving(false); @@ -346,7 +346,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 속성 패널 자동 열기 openPanel("properties"); } catch (error) { - console.error("드롭 처리 실패:", error); + // console.error("드롭 처리 실패:", error); } }, [layout, gridInfo, saveToHistory, openPanel], diff --git a/frontend/components/screen/ScreenDesigner_old.tsx b/frontend/components/screen/ScreenDesigner_old.tsx index ec019066..fb0e9a96 100644 --- a/frontend/components/screen/ScreenDesigner_old.tsx +++ b/frontend/components/screen/ScreenDesigner_old.tsx @@ -410,7 +410,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD } try { - console.log(`=== 테이블 정보 조회 시작: ${selectedScreen.tableName} ===`); + // console.log(`=== 테이블 정보 조회 시작: ${selectedScreen.tableName} ===`); const startTime = performance.now(); // 최적화된 단일 테이블 조회 API 사용 @@ -421,29 +421,29 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD }); const endTime = performance.now(); - console.log(`테이블 조회 완료: ${(endTime - startTime).toFixed(2)}ms`); + // console.log(`테이블 조회 완료: ${(endTime - startTime).toFixed(2)}ms`); if (response.ok) { const data = await response.json(); if (data.success && data.data) { setTables([data.data]); - console.log(`테이블 ${selectedScreen.tableName} 로드 완료, 컬럼 ${data.data.columns.length}개`); + // console.log(`테이블 ${selectedScreen.tableName} 로드 완료, 컬럼 ${data.data.columns.length}개`); } else { - console.error("테이블 조회 실패:", data.message); + // console.error("테이블 조회 실패:", data.message); // 선택된 화면의 테이블에 대한 임시 데이터 생성 setTables([createMockTableForScreen(selectedScreen.tableName)]); } } else if (response.status === 404) { - console.warn(`테이블 ${selectedScreen.tableName}을 찾을 수 없습니다.`); + // console.warn(`테이블 ${selectedScreen.tableName}을 찾을 수 없습니다.`); // 테이블이 존재하지 않는 경우 임시 데이터 생성 setTables([createMockTableForScreen(selectedScreen.tableName)]); } else { - console.error("테이블 조회 실패:", response.status); + // console.error("테이블 조회 실패:", response.status); // 선택된 화면의 테이블에 대한 임시 데이터 생성 setTables([createMockTableForScreen(selectedScreen.tableName)]); } } catch (error) { - console.error("테이블 조회 중 오류:", error); + // console.error("테이블 조회 중 오류:", error); // 선택된 화면의 테이블에 대한 임시 데이터 생성 setTables([createMockTableForScreen(selectedScreen.tableName)]); } @@ -562,7 +562,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD // 웹타입에 따른 위젯 타입 매핑 const getWidgetTypeFromWebType = useCallback((webType: string): string => { - console.log("getWidgetTypeFromWebType - input webType:", webType); + // console.log("getWidgetTypeFromWebType - input webType:", webType); switch (webType) { case "text": return "text"; @@ -599,7 +599,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD case "file": return "file"; default: - console.log("getWidgetTypeFromWebType - default case, returning text for:", webType); + // console.log("getWidgetTypeFromWebType - default case, returning text for:", webType); return "text"; } }, []); @@ -986,7 +986,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD setHasUnsavedChanges(false); // 저장 완료 시 변경사항 플래그 해제 toast.success("레이아웃이 성공적으로 저장되었습니다."); } catch (error) { - console.error("레이아웃 저장 실패:", error); + // console.error("레이아웃 저장 실패:", error); toast.error("레이아웃 저장에 실패했습니다."); } finally { setIsSaving(false); @@ -1027,7 +1027,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD setHasUnsavedChanges(false); } } catch (error) { - console.error("레이아웃 로드 실패:", error); + // console.error("레이아웃 로드 실패:", error); // 에러 시에도 기본 레이아웃으로 초기화 const defaultLayout = { components: [], @@ -1282,7 +1282,7 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD saveToHistory(newLayout); } } catch (error) { - console.error("드롭 처리 중 오류:", error); + // console.error("드롭 처리 중 오류:", error); } setDragState({ @@ -1686,9 +1686,9 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD className="flex cursor-pointer items-center space-x-2 p-2 pl-6 hover:bg-gray-100" draggable onDragStart={(e) => { - console.log("Drag start - column:", column.columnName, "webType:", column.webType); + // console.log("Drag start - column:", column.columnName, "webType:", column.webType); const widgetType = getWidgetTypeFromWebType(column.webType || "text"); - console.log("Drag start - widgetType:", widgetType); + // console.log("Drag start - widgetType:", widgetType); startDrag( { type: "widget", diff --git a/frontend/components/screen/ScreenList.tsx b/frontend/components/screen/ScreenList.tsx index 6d3865f5..384aee00 100644 --- a/frontend/components/screen/ScreenList.tsx +++ b/frontend/components/screen/ScreenList.tsx @@ -100,7 +100,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setTotalPages(Math.max(1, Math.ceil((resp.total || 0) / 20))); } } catch (e) { - console.error("화면 목록 조회 실패", e); + // console.error("화면 목록 조회 실패", e); if (activeTab === "active") { setScreens([]); } else { @@ -127,7 +127,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setScreens(resp.data || []); setTotalPages(Math.max(1, Math.ceil((resp.total || 0) / 20))); } catch (e) { - console.error("화면 목록 조회 실패", e); + // console.error("화면 목록 조회 실패", e); } finally { setLoading(false); } @@ -139,7 +139,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr const handleEdit = (screen: ScreenDefinition) => { // 편집 모달 열기 - console.log("편집:", screen); + // console.log("편집:", screen); }; const handleDelete = async (screen: ScreenDefinition) => { @@ -157,7 +157,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setDeleteDialogOpen(true); } } catch (error) { - console.error("의존성 체크 실패:", error); + // console.error("의존성 체크 실패:", error); // 의존성 체크 실패 시에도 삭제 다이얼로그는 열어줌 setDeleteDialogOpen(true); } finally { @@ -177,7 +177,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setDeleteReason(""); setDependencies([]); } catch (error: any) { - console.error("화면 삭제 실패:", error); + // console.error("화면 삭제 실패:", error); // 의존성 오류인 경우 경고창 표시 if (error.response?.status === 409 && error.response?.data?.code === "SCREEN_HAS_DEPENDENCIES") { @@ -208,7 +208,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setActiveTab("active"); reloadScreens(); } catch (error) { - console.error("화면 복원 실패:", error); + // console.error("화면 복원 실패:", error); alert("화면 복원에 실패했습니다."); } }; @@ -227,7 +227,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr setPermanentDeleteDialogOpen(false); setScreenToPermanentDelete(null); } catch (error) { - console.error("화면 영구 삭제 실패:", error); + // console.error("화면 영구 삭제 실패:", error); alert("화면 영구 삭제에 실패했습니다."); } }; @@ -283,7 +283,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr alert(message); } catch (error) { - console.error("일괄 삭제 실패:", error); + // console.error("일괄 삭제 실패:", error); alert("일괄 삭제에 실패했습니다."); } finally { setBulkDeleting(false); @@ -297,7 +297,7 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr const handleView = (screen: ScreenDefinition) => { // 미리보기 모달 열기 - console.log("미리보기:", screen); + // console.log("미리보기:", screen); }; const handleCopySuccess = () => { diff --git a/frontend/components/screen/ScreenPreview.tsx b/frontend/components/screen/ScreenPreview.tsx index 742441c2..83890156 100644 --- a/frontend/components/screen/ScreenPreview.tsx +++ b/frontend/components/screen/ScreenPreview.tsx @@ -127,7 +127,7 @@ export default function ScreenPreview({ layout, screenName, className }: ScreenP // 폼 데이터 출력 const logFormData = () => { - console.log("폼 데이터:", formData); + // console.log("폼 데이터:", formData); }; return ( diff --git a/frontend/components/screen/SimpleScreenDesigner.tsx b/frontend/components/screen/SimpleScreenDesigner.tsx index 9ffabf3d..e4b8f726 100644 --- a/frontend/components/screen/SimpleScreenDesigner.tsx +++ b/frontend/components/screen/SimpleScreenDesigner.tsx @@ -52,7 +52,7 @@ export default function SimpleScreenDesigner({ selectedScreen, onBackToList }: S await screenApi.saveLayout(selectedScreen.screenId, layoutWithResolution); toast.success("화면이 저장되었습니다."); } catch (error) { - console.error("저장 실패:", error); + // console.error("저장 실패:", error); toast.error("저장 중 오류가 발생했습니다."); } finally { setIsSaving(false); diff --git a/frontend/components/screen/TableTypeSelector.tsx b/frontend/components/screen/TableTypeSelector.tsx index 05397a13..5da49312 100644 --- a/frontend/components/screen/TableTypeSelector.tsx +++ b/frontend/components/screen/TableTypeSelector.tsx @@ -42,7 +42,7 @@ export default function TableTypeSelector({ const tableList = await tableTypeApi.getTables(); setTables(tableList); } catch (error) { - console.error("테이블 목록 조회 실패:", error); + // console.error("테이블 목록 조회 실패:", error); // API 호출 실패 시 기본 테이블 목록 사용 const fallbackTables = [ { tableName: "user_info", displayName: "사용자 정보", description: "사용자 기본 정보", columnCount: "25" }, @@ -89,7 +89,7 @@ export default function TableTypeSelector({ setColumns(formattedColumns); } catch (error) { - console.error("컬럼 정보 조회 실패:", error); + // console.error("컬럼 정보 조회 실패:", error); // API 호출 실패 시 기본 컬럼 정보 사용 const fallbackColumns: ColumnInfo[] = [ { @@ -167,9 +167,9 @@ export default function TableTypeSelector({ // 로컬 상태 업데이트 setColumns((prev) => prev.map((col) => (col.columnName === columnName ? { ...col, webType } : col))); - console.log(`컬럼 ${columnName}의 웹 타입을 ${webType}로 변경했습니다.`); + // console.log(`컬럼 ${columnName}의 웹 타입을 ${webType}로 변경했습니다.`); } catch (error) { - console.error("웹 타입 설정 실패:", error); + // console.error("웹 타입 설정 실패:", error); alert("웹 타입 설정에 실패했습니다. 다시 시도해주세요."); } }; @@ -193,9 +193,9 @@ export default function TableTypeSelector({ // 로컬 상태 업데이트 setColumns((prev) => prev.map((col) => (col.columnName === columnName ? { ...col, inputType } : col))); - console.log(`컬럼 ${columnName}의 입력 타입을 ${inputType}로 변경했습니다.`); + // console.log(`컬럼 ${columnName}의 입력 타입을 ${inputType}로 변경했습니다.`); } catch (error) { - console.error("입력 타입 변경 실패:", error); + // console.error("입력 타입 변경 실패:", error); alert("입력 타입 설정에 실패했습니다. 다시 시도해주세요."); } }; diff --git a/frontend/components/screen/TemplateManager.tsx b/frontend/components/screen/TemplateManager.tsx index 4d759137..dd627395 100644 --- a/frontend/components/screen/TemplateManager.tsx +++ b/frontend/components/screen/TemplateManager.tsx @@ -44,7 +44,7 @@ export default function TemplateManager({ }); setTemplates(templateList); } catch (error) { - console.error("템플릿 목록 조회 실패:", error); + // console.error("템플릿 목록 조회 실패:", error); // API 호출 실패 시 기본 템플릿 목록 사용 const fallbackTemplates: ScreenTemplate[] = [ { @@ -196,7 +196,7 @@ export default function TemplateManager({ } alert("템플릿이 삭제되었습니다."); } catch (error) { - console.error("템플릿 삭제 실패:", error); + // console.error("템플릿 삭제 실패:", error); alert("템플릿 삭제에 실패했습니다. 다시 시도해주세요."); } }; @@ -204,7 +204,7 @@ export default function TemplateManager({ // 새 템플릿 생성 const handleCreateTemplate = () => { // TODO: 새 템플릿 생성 모달 또는 페이지로 이동 - console.log("새 템플릿 생성"); + // console.log("새 템플릿 생성"); }; // 템플릿 내보내기 diff --git a/frontend/components/screen/config-panels/ButtonConfigPanel.tsx b/frontend/components/screen/config-panels/ButtonConfigPanel.tsx index 8939db1f..216a15fb 100644 --- a/frontend/components/screen/config-panels/ButtonConfigPanel.tsx +++ b/frontend/components/screen/config-panels/ButtonConfigPanel.tsx @@ -39,9 +39,9 @@ export const ButtonConfigPanel: React.FC = ({ component, const fetchScreens = async () => { try { setScreensLoading(true); - console.log("🔍 화면 목록 API 호출 시작"); + // console.log("🔍 화면 목록 API 호출 시작"); const response = await apiClient.get("/screen-management/screens"); - console.log("✅ 화면 목록 API 응답:", response.data); + // console.log("✅ 화면 목록 API 응답:", response.data); if (response.data.success && Array.isArray(response.data.data)) { const screenList = response.data.data.map((screen: any) => ({ @@ -50,10 +50,10 @@ export const ButtonConfigPanel: React.FC = ({ component, description: screen.description, })); setScreens(screenList); - console.log("✅ 화면 목록 설정 완료:", screenList.length, "개"); + // console.log("✅ 화면 목록 설정 완료:", screenList.length, "개"); } } catch (error) { - console.error("❌ 화면 목록 로딩 실패:", error); + // console.error("❌ 화면 목록 로딩 실패:", error); } finally { setScreensLoading(false); } diff --git a/frontend/components/screen/config-panels/ButtonDataflowConfigPanel.tsx b/frontend/components/screen/config-panels/ButtonDataflowConfigPanel.tsx index 7a1b168c..a465694f 100644 --- a/frontend/components/screen/config-panels/ButtonDataflowConfigPanel.tsx +++ b/frontend/components/screen/config-panels/ButtonDataflowConfigPanel.tsx @@ -77,7 +77,7 @@ export const ButtonDataflowConfigPanel: React.FC const loadDiagrams = async () => { try { setDiagramsLoading(true); - console.log("🔍 데이터플로우 관계 목록 로딩..."); + // console.log("🔍 데이터플로우 관계 목록 로딩..."); const response = await apiClient.get("/test-button-dataflow/diagrams"); @@ -90,10 +90,10 @@ export const ButtonDataflowConfigPanel: React.FC })); setDiagrams(diagramList); - console.log(`✅ 관계 ${diagramList.length}개 로딩 완료`); + // console.log(`✅ 관계 ${diagramList.length}개 로딩 완료`); } } catch (error) { - console.error("❌ 관계 목록 로딩 실패:", error); + // console.error("❌ 관계 목록 로딩 실패:", error); setDiagrams([]); } finally { setDiagramsLoading(false); @@ -106,15 +106,15 @@ export const ButtonDataflowConfigPanel: React.FC const loadRelationships = async (diagramId: number) => { try { setRelationshipsLoading(true); - console.log(`🔍 관계 ${diagramId} 관계 목록 로딩...`); + // console.log(`🔍 관계 ${diagramId} 관계 목록 로딩...`); const response = await apiClient.get(`/test-button-dataflow/diagrams/${diagramId}/relationships`); if (response.data.success && Array.isArray(response.data.data)) { - console.log("🔍 백엔드에서 받은 관계 데이터:", response.data.data); + // console.log("🔍 백엔드에서 받은 관계 데이터:", response.data.data); const relationshipList = response.data.data.map((rel: any) => { - console.log("🔍 개별 관계 데이터:", rel); + // console.log("🔍 개별 관계 데이터:", rel); // 여러 가지 가능한 필드명 시도 (백엔드 로그 기준으로 수정) const relationshipName = @@ -137,15 +137,15 @@ export const ButtonDataflowConfigPanel: React.FC category: rel.category || rel.type || "data-save", }; - console.log("🔍 매핑된 관계 데이터:", mappedRel); + // console.log("🔍 매핑된 관계 데이터:", mappedRel); return mappedRel; }); setRelationships(relationshipList); - console.log(`✅ 관계 ${relationshipList.length}개 로딩 완료:`, relationshipList); + // console.log(`✅ 관계 ${relationshipList.length}개 로딩 완료:`, relationshipList); } } catch (error) { - console.error("❌ 관계 목록 로딩 실패:", error); + // console.error("❌ 관계 목록 로딩 실패:", error); setRelationships([]); } finally { setRelationshipsLoading(false); @@ -169,7 +169,7 @@ export const ButtonDataflowConfigPanel: React.FC setPreviewData(response.data.data); } } catch (error) { - console.error("❌ 관계 미리보기 로딩 실패:", error); + // console.error("❌ 관계 미리보기 로딩 실패:", error); } }; diff --git a/frontend/components/screen/config-panels/ImprovedButtonControlConfigPanel.tsx b/frontend/components/screen/config-panels/ImprovedButtonControlConfigPanel.tsx index c5b741ac..2a26a1c3 100644 --- a/frontend/components/screen/config-panels/ImprovedButtonControlConfigPanel.tsx +++ b/frontend/components/screen/config-panels/ImprovedButtonControlConfigPanel.tsx @@ -63,7 +63,7 @@ export const ImprovedButtonControlConfigPanel: React.FC { try { setLoading(true); - console.log("🔍 전체 관계 목록 로딩..."); + // console.log("🔍 전체 관계 목록 로딩..."); const response = await apiClient.get("/test-button-dataflow/relationships/all"); @@ -77,10 +77,10 @@ export const ImprovedButtonControlConfigPanel: React.FC = ({ setCodeOptions((prev) => ({ ...prev, [codeCategory]: options })); } catch (error) { - console.error(`코드 카테고리 ${codeCategory} 로드 실패:`, error); + // console.error(`코드 카테고리 ${codeCategory} 로드 실패:`, error); setCodeOptions((prev) => ({ ...prev, [codeCategory]: [] })); } finally { setLoadingStates((prev) => ({ ...prev, [codeCategory]: false })); @@ -134,7 +134,7 @@ export const AdvancedSearchFilters: React.FC = ({ setEntityOptions((prev) => ({ ...prev, [key]: options })); } catch (error) { - console.error(`엔티티 ${tableName}.${columnName} 로드 실패:`, error); + // console.error(`엔티티 ${tableName}.${columnName} 로드 실패:`, error); setEntityOptions((prev) => ({ ...prev, [key]: [] })); } finally { setLoadingStates((prev) => ({ ...prev, [key]: false })); diff --git a/frontend/components/screen/panels/ComponentsPanel.tsx b/frontend/components/screen/panels/ComponentsPanel.tsx index 68f44705..d22016c5 100644 --- a/frontend/components/screen/panels/ComponentsPanel.tsx +++ b/frontend/components/screen/panels/ComponentsPanel.tsx @@ -21,12 +21,12 @@ export function ComponentsPanel({ className }: ComponentsPanelProps) { // 레지스트리에서 모든 컴포넌트 조회 const allComponents = useMemo(() => { const components = ComponentRegistry.getAllComponents(); - console.log("🔍 ComponentsPanel - 로드된 컴포넌트:", components.map(c => ({ id: c.id, name: c.name, category: c.category }))); + // console.log("🔍 ComponentsPanel - 로드된 컴포넌트:", components.map(c => ({ id: c.id, name: c.name, category: c.category }))); // 수동으로 table-list 컴포넌트 추가 (임시) const hasTableList = components.some(c => c.id === 'table-list'); if (!hasTableList) { - console.log("⚠️ table-list 컴포넌트가 없어서 수동 추가"); + // console.log("⚠️ table-list 컴포넌트가 없어서 수동 추가"); components.push({ id: "table-list", name: "테이블 리스트", @@ -92,7 +92,7 @@ export function ComponentsPanel({ className }: ComponentsPanelProps) { type: "component", component: component, }; - console.log("🚀 컴포넌트 드래그 시작:", component.name, dragData); + // console.log("🚀 컴포넌트 드래그 시작:", component.name, dragData); e.dataTransfer.setData("application/json", JSON.stringify(dragData)); e.dataTransfer.effectAllowed = "copy"; }; diff --git a/frontend/components/screen/panels/DataTableConfigPanel.tsx b/frontend/components/screen/panels/DataTableConfigPanel.tsx index f408b009..1532633f 100644 --- a/frontend/components/screen/panels/DataTableConfigPanel.tsx +++ b/frontend/components/screen/panels/DataTableConfigPanel.tsx @@ -106,47 +106,47 @@ const DataTableConfigPanelComponent: React.FC = ({ // 컴포넌트 변경 시 로컬 값 동기화 useEffect(() => { - console.log("🔄 DataTableConfig: 컴포넌트 변경 감지", { - componentId: component.id, - title: component.title, - searchButtonText: component.searchButtonText, - columnsCount: component.columns.length, - filtersCount: component.filters.length, - columnIds: component.columns.map((col) => col.id), - filterColumnNames: component.filters.map((filter) => filter.columnName), - timestamp: new Date().toISOString(), - }); + // console.log("🔄 DataTableConfig: 컴포넌트 변경 감지", { + // componentId: component.id, + // title: component.title, + // searchButtonText: component.searchButtonText, + // columnsCount: component.columns.length, + // filtersCount: component.filters.length, + // columnIds: component.columns.map((col) => col.id), + // filterColumnNames: component.filters.map((filter) => filter.columnName), + // timestamp: new Date().toISOString(), + // }); // 컬럼과 필터 상세 정보 로그 if (component.columns.length > 0) { - console.log( - "📋 현재 컬럼 목록:", - component.columns.map((col) => ({ - id: col.id, - columnName: col.columnName, - label: col.label, - visible: col.visible, - gridColumns: col.gridColumns, - })), - ); + // console.log( + // "📋 현재 컬럼 목록:", + // component.columns.map((col) => ({ + // id: col.id, + // columnName: col.columnName, + // label: col.label, + // visible: col.visible, + // gridColumns: col.gridColumns, + // })), + // ); } // 로컬 상태 정보 로그 - console.log("🔧 로컬 상태 정보:", { - localColumnInputsCount: Object.keys(localColumnInputs).length, - localColumnCheckboxesCount: Object.keys(localColumnCheckboxes).length, - localColumnGridColumnsCount: Object.keys(localColumnGridColumns).length, - }); + // console.log("🔧 로컬 상태 정보:", { + // localColumnInputsCount: Object.keys(localColumnInputs).length, + // localColumnCheckboxesCount: Object.keys(localColumnCheckboxes).length, + // localColumnGridColumnsCount: Object.keys(localColumnGridColumns).length, + // }); if (component.filters.length > 0) { - console.log( - "🔍 현재 필터 목록:", - component.filters.map((filter) => ({ - columnName: filter.columnName, - widgetType: filter.widgetType, - label: filter.label, - })), - ); + // console.log( + // "🔍 현재 필터 목록:", + // component.filters.map((filter) => ({ + // columnName: filter.columnName, + // widgetType: filter.widgetType, + // label: filter.label, + // })), + // ); } setLocalValues({ @@ -252,11 +252,11 @@ const DataTableConfigPanelComponent: React.FC = ({ const filterKey = `${filter.columnName}-${index}`; if (!(filterKey in newFilterInputs)) { newFilterInputs[filterKey] = filter.label || filter.columnName; - console.log("🆕 새 필터 로컬 상태 추가:", { - filterKey, - label: filter.label, - columnName: filter.columnName, - }); + // console.log("🆕 새 필터 로컬 상태 추가:", { + // filterKey, + // label: filter.label, + // columnName: filter.columnName, + // }); } }); @@ -266,16 +266,16 @@ const DataTableConfigPanelComponent: React.FC = ({ ); Object.keys(newFilterInputs).forEach((key) => { if (!currentFilterKeys.has(key)) { - console.log("🗑️ 삭제된 필터 로컬 상태 제거:", { filterKey: key }); + // console.log("🗑️ 삭제된 필터 로컬 상태 제거:", { filterKey: key }); delete newFilterInputs[key]; } }); - console.log("📝 필터 로컬 상태 동기화 완료:", { - prevCount: Object.keys(prev).length, - newCount: Object.keys(newFilterInputs).length, - newKeys: Object.keys(newFilterInputs), - }); + // console.log("📝 필터 로컬 상태 동기화 완료:", { + // prevCount: Object.keys(prev).length, + // newCount: Object.keys(newFilterInputs).length, + // newKeys: Object.keys(newFilterInputs), + // }); return newFilterInputs; }); @@ -313,20 +313,20 @@ const DataTableConfigPanelComponent: React.FC = ({ const table = tables.find((t) => t.tableName === tableName); if (!table) return; - console.log("🔄 테이블 변경:", { - tableName, - currentTableName: localValues.tableName, - table, - columnsCount: table.columns.length, - }); + // console.log("🔄 테이블 변경:", { + // tableName, + // currentTableName: localValues.tableName, + // table, + // columnsCount: table.columns.length, + // }); // 테이블 변경 시 컬럼을 자동으로 추가하지 않음 (사용자가 수동으로 추가해야 함) const defaultColumns: DataTableColumn[] = []; - console.log("✅ 생성된 컬럼 설정:", { - defaultColumnsCount: defaultColumns.length, - visibleColumns: defaultColumns.filter((col) => col.visible).length, - }); + // console.log("✅ 생성된 컬럼 설정:", { + // defaultColumnsCount: defaultColumns.length, + // visibleColumns: defaultColumns.filter((col) => col.visible).length, + // }); // 상태 업데이트를 한 번에 처리 setTimeout(() => { @@ -363,7 +363,7 @@ const DataTableConfigPanelComponent: React.FC = ({ async (columnId: string, webTypeConfig: any) => { // 1. 먼저 화면 컴포넌트의 컬럼 설정 업데이트 const updatedColumns = component.columns.map((col) => (col.id === columnId ? { ...col, webTypeConfig } : col)); - console.log("🔄 컬럼 상세 설정 업데이트:", { columnId, webTypeConfig, updatedColumns }); + // console.log("🔄 컬럼 상세 설정 업데이트:", { columnId, webTypeConfig, updatedColumns }); onUpdateComponent({ columns: updatedColumns }); // 2. 테이블 타입 관리에도 반영 (라디오 타입인 경우) @@ -371,14 +371,14 @@ const DataTableConfigPanelComponent: React.FC = ({ if (targetColumn && targetColumn.widgetType === "radio" && selectedTable) { try { // TODO: 테이블 타입 관리 API 호출하여 웹 타입과 상세 설정 업데이트 - console.log("📡 테이블 타입 관리 업데이트 필요:", { - tableName: component.tableName, - columnName: targetColumn.columnName, - webType: "radio", - detailSettings: JSON.stringify(webTypeConfig), - }); + // console.log("📡 테이블 타입 관리 업데이트 필요:", { + // tableName: component.tableName, + // columnName: targetColumn.columnName, + // webType: "radio", + // detailSettings: JSON.stringify(webTypeConfig), + // }); } catch (error) { - console.error("테이블 타입 관리 업데이트 실패:", error); + // console.error("테이블 타입 관리 업데이트 실패:", error); } } }, @@ -731,11 +731,11 @@ const DataTableConfigPanelComponent: React.FC = ({ return newGridColumns; }); - console.log("🗑️ 컬럼 삭제:", { - columnId, - columnName: columnToRemove?.columnName, - remainingColumns: updatedColumns.length, - }); + // console.log("🗑️ 컬럼 삭제:", { + // columnId, + // columnName: columnToRemove?.columnName, + // remainingColumns: updatedColumns.length, + // }); onUpdateComponent({ columns: updatedColumns, @@ -748,7 +748,7 @@ const DataTableConfigPanelComponent: React.FC = ({ const updateFilter = useCallback( (index: number, updates: Partial) => { const updatedFilters = component.filters.map((filter, i) => (i === index ? { ...filter, ...updates } : filter)); - console.log("🔄 필터 업데이트:", { index, updates, updatedFilters }); + // console.log("🔄 필터 업데이트:", { index, updates, updatedFilters }); onUpdateComponent({ filters: updatedFilters }); }, [component.filters, onUpdateComponent], @@ -782,30 +782,30 @@ const DataTableConfigPanelComponent: React.FC = ({ displayColumn: targetColumn.displayColumn, }; - console.log("➕ 필터 추가 시작:", { - targetColumnName: targetColumn.columnName, - targetColumnLabel: targetColumn.columnLabel, - inferredWidgetType: widgetType, - currentFiltersCount: component.filters.length, - }); + // console.log("➕ 필터 추가 시작:", { + // targetColumnName: targetColumn.columnName, + // targetColumnLabel: targetColumn.columnLabel, + // inferredWidgetType: widgetType, + // currentFiltersCount: component.filters.length, + // }); - console.log("➕ 생성된 새 필터:", { - columnName: newFilter.columnName, - widgetType: newFilter.widgetType, - label: newFilter.label, - gridColumns: newFilter.gridColumns, - }); + // console.log("➕ 생성된 새 필터:", { + // columnName: newFilter.columnName, + // widgetType: newFilter.widgetType, + // label: newFilter.label, + // gridColumns: newFilter.gridColumns, + // }); const updatedFilters = [...component.filters, newFilter]; - console.log("🔄 필터 업데이트 호출:", { - filtersToAdd: 1, - totalFiltersAfter: updatedFilters.length, - updatedFilters: updatedFilters.map((filter) => ({ - columnName: filter.columnName, - widgetType: filter.widgetType, - label: filter.label, - })), - }); + // console.log("🔄 필터 업데이트 호출:", { + // filtersToAdd: 1, + // totalFiltersAfter: updatedFilters.length, + // updatedFilters: updatedFilters.map((filter) => ({ + // columnName: filter.columnName, + // widgetType: filter.widgetType, + // label: filter.label, + // })), + // }); // 먼저 로컬 상태를 업데이트하고 const filterKey = `${newFilter.columnName}-${component.filters.length}`; @@ -814,12 +814,12 @@ const DataTableConfigPanelComponent: React.FC = ({ ...prev, [filterKey]: newFilter.label, }; - console.log("📝 필터 로컬 상태 업데이트:", { - filterKey, - newLabel: newFilter.label, - prevState: prev, - newState, - }); + // console.log("📝 필터 로컬 상태 업데이트:", { + // filterKey, + // newLabel: newFilter.label, + // prevState: prev, + // newState, + // }); return newState; }); @@ -829,10 +829,10 @@ const DataTableConfigPanelComponent: React.FC = ({ // 필터 추가 후 필터 탭으로 자동 이동 setActiveTab("filters"); - console.log("🔍 필터 추가 후 탭 이동:", { - activeTab: "filters", - isExternalControl: !!onTabChange, - }); + // console.log("🔍 필터 추가 후 탭 이동:", { + // activeTab: "filters", + // isExternalControl: !!onTabChange, + // }); // 강제로 리렌더링을 트리거하기 위해 여러 방법 사용 setTimeout(() => { @@ -840,23 +840,23 @@ const DataTableConfigPanelComponent: React.FC = ({ ...prev, [filterKey]: newFilter.label, })); - console.log("🔄 setTimeout에서 강제 로컬 상태 업데이트:", { filterKey, label: newFilter.label }); + // console.log("🔄 setTimeout에서 강제 로컬 상태 업데이트:", { filterKey, label: newFilter.label }); }, 0); // 추가적인 강제 업데이트 setTimeout(() => { setLocalFilterInputs((prev) => { const updated = { ...prev, [filterKey]: newFilter.label }; - console.log("🔄 두 번째 강제 업데이트:", { updated }); + // console.log("🔄 두 번째 강제 업데이트:", { updated }); return updated; }); }, 100); - console.log("✅ 필터 추가 완료 - 로컬 상태와 컴포넌트 모두 업데이트됨", { - filterKey, - newFilterLabel: newFilter.label, - switchedToTab: "filters", - }); + // console.log("✅ 필터 추가 완료 - 로컬 상태와 컴포넌트 모두 업데이트됨", { + // filterKey, + // newFilterLabel: newFilter.label, + // switchedToTab: "filters", + // }); }, [selectedTable, component.filters, onUpdateComponent]); // 필터 삭제 @@ -916,24 +916,24 @@ const DataTableConfigPanelComponent: React.FC = ({ // 필터는 자동으로 추가하지 않음 (사용자가 수동으로 추가) - console.log("➕ 컬럼 추가 시작:", { - targetColumnName: targetColumn.columnName, - targetColumnLabel: targetColumn.columnLabel, - inferredWidgetType: widgetType, - currentColumnsCount: component.columns.length, - currentFiltersCount: component.filters.length, - }); + // console.log("➕ 컬럼 추가 시작:", { + // targetColumnName: targetColumn.columnName, + // targetColumnLabel: targetColumn.columnLabel, + // inferredWidgetType: widgetType, + // currentColumnsCount: component.columns.length, + // currentFiltersCount: component.filters.length, + // }); - console.log("➕ 생성된 새 컬럼:", { - id: newColumn.id, - columnName: newColumn.columnName, - label: newColumn.label, - widgetType: newColumn.widgetType, - filterable: newColumn.filterable, - visible: newColumn.visible, - sortable: newColumn.sortable, - searchable: newColumn.searchable, - }); + // console.log("➕ 생성된 새 컬럼:", { + // id: newColumn.id, + // columnName: newColumn.columnName, + // label: newColumn.label, + // widgetType: newColumn.widgetType, + // filterable: newColumn.filterable, + // visible: newColumn.visible, + // sortable: newColumn.sortable, + // searchable: newColumn.searchable, + // }); // 필터는 수동으로만 추가 @@ -943,11 +943,11 @@ const DataTableConfigPanelComponent: React.FC = ({ ...prev, [newColumn.id]: newColumn.label, }; - console.log("🔄 로컬 컬럼 상태 업데이트:", { - newColumnId: newColumn.id, - newLabel: newColumn.label, - totalLocalInputs: Object.keys(newInputs).length, - }); + // console.log("🔄 로컬 컬럼 상태 업데이트:", { + // newColumnId: newColumn.id, + // newLabel: newColumn.label, + // totalLocalInputs: Object.keys(newInputs).length, + // }); return newInputs; }); @@ -972,28 +972,28 @@ const DataTableConfigPanelComponent: React.FC = ({ columns: [...component.columns, newColumn], }; - console.log("🔄 컴포넌트 업데이트 호출:", { - columnsToAdd: 1, - totalColumnsAfter: updates.columns?.length, - hasColumns: !!updates.columns, - updateKeys: Object.keys(updates), - }); + // console.log("🔄 컴포넌트 업데이트 호출:", { + // columnsToAdd: 1, + // totalColumnsAfter: updates.columns?.length, + // hasColumns: !!updates.columns, + // updateKeys: Object.keys(updates), + // }); - console.log("🔄 업데이트 상세 내용:", { - columns: updates.columns?.map((col) => ({ id: col.id, columnName: col.columnName, label: col.label })), - }); + // console.log("🔄 업데이트 상세 내용:", { + // columns: updates.columns?.map((col) => ({ id: col.id, columnName: col.columnName, label: col.label })), + // }); onUpdateComponent(updates); // 컬럼 추가 후 컬럼 탭으로 자동 이동 setActiveTab("columns"); - console.log("📋 컬럼 추가 후 탭 이동:", { - activeTab: "columns", - isExternalControl: !!onTabChange, - }); + // console.log("📋 컬럼 추가 후 탭 이동:", { + // activeTab: "columns", + // isExternalControl: !!onTabChange, + // }); - console.log("✅ 컬럼 추가 완료 - onUpdateComponent 호출됨"); + // console.log("✅ 컬럼 추가 완료 - onUpdateComponent 호출됨"); }, [selectedTable, component.columns, component.filters, onUpdateComponent], ); @@ -1022,11 +1022,11 @@ const DataTableConfigPanelComponent: React.FC = ({ }, }; - console.log("📁 가상 파일 컬럼 추가:", { - columnName: newColumn.columnName, - label: newColumn.label, - isVirtualFileColumn: newColumn.isVirtualFileColumn, - }); + // console.log("📁 가상 파일 컬럼 추가:", { + // columnName: newColumn.columnName, + // label: newColumn.label, + // isVirtualFileColumn: newColumn.isVirtualFileColumn, + // }); // 로컬 상태에 새 컬럼 입력값 추가 setLocalColumnInputs((prev) => ({ @@ -1060,7 +1060,7 @@ const DataTableConfigPanelComponent: React.FC = ({ // 컬럼 추가 후 컬럼 탭으로 자동 이동 setActiveTab("columns"); - console.log("✅ 가상 파일 컬럼 추가 완료"); + // console.log("✅ 가상 파일 컬럼 추가 완료"); }, [component.columns, onUpdateComponent]); return ( @@ -1386,7 +1386,7 @@ const DataTableConfigPanelComponent: React.FC = ({ value={localValues.gridColumns.toString()} onChange={(e) => { const gridColumns = parseInt(e.target.value, 10); - console.log("🔄 테이블 그리드 컬럼 수 변경:", gridColumns); + // console.log("🔄 테이블 그리드 컬럼 수 변경:", gridColumns); setLocalValues((prev) => ({ ...prev, gridColumns })); onUpdateComponent({ gridColumns }); }} @@ -1406,7 +1406,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="show-search-button" checked={localValues.showSearchButton} onCheckedChange={(checked) => { - console.log("🔄 검색 버튼 표시 변경:", checked); + // console.log("🔄 검색 버튼 표시 변경:", checked); setLocalValues((prev) => ({ ...prev, showSearchButton: checked as boolean })); onUpdateComponent({ showSearchButton: checked as boolean }); }} @@ -1421,7 +1421,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="enable-export" checked={localValues.enableExport} onCheckedChange={(checked) => { - console.log("🔄 내보내기 기능 변경:", checked); + // console.log("🔄 내보내기 기능 변경:", checked); setLocalValues((prev) => ({ ...prev, enableExport: checked as boolean })); onUpdateComponent({ enableExport: checked as boolean }); }} @@ -1501,7 +1501,7 @@ const DataTableConfigPanelComponent: React.FC = ({ { - console.log("🔄 컬럼 표시 변경:", { columnId: column.id, checked }); + // console.log("🔄 컬럼 표시 변경:", { columnId: column.id, checked }); setLocalColumnCheckboxes((prev) => ({ ...prev, [column.id]: { ...prev[column.id], visible: checked as boolean }, @@ -1582,7 +1582,7 @@ const DataTableConfigPanelComponent: React.FC = ({ value={(localColumnGridColumns[column.id] ?? column.gridColumns).toString()} onValueChange={(value) => { const newGridColumns = parseInt(value); - console.log("🔄 컬럼 그리드 컬럼 변경:", { columnId: column.id, newGridColumns }); + // console.log("🔄 컬럼 그리드 컬럼 변경:", { columnId: column.id, newGridColumns }); setLocalColumnGridColumns((prev) => ({ ...prev, [column.id]: newGridColumns, @@ -1609,7 +1609,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id={`sortable-${column.id}`} checked={localColumnCheckboxes[column.id]?.sortable ?? column.sortable} onCheckedChange={(checked) => { - console.log("🔄 컬럼 정렬 가능 변경:", { columnId: column.id, checked }); + // console.log("🔄 컬럼 정렬 가능 변경:", { columnId: column.id, checked }); setLocalColumnCheckboxes((prev) => ({ ...prev, [column.id]: { ...prev[column.id], sortable: checked as boolean }, @@ -1627,7 +1627,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id={`searchable-${column.id}`} checked={localColumnCheckboxes[column.id]?.searchable ?? column.searchable} onCheckedChange={(checked) => { - console.log("🔄 컬럼 검색 가능 변경:", { columnId: column.id, checked }); + // console.log("🔄 컬럼 검색 가능 변경:", { columnId: column.id, checked }); setLocalColumnCheckboxes((prev) => ({ ...prev, [column.id]: { ...prev[column.id], searchable: checked as boolean }, @@ -1967,13 +1967,13 @@ const DataTableConfigPanelComponent: React.FC = ({ const filterKey = `${filter.columnName}-${index}`; const localValue = localFilterInputs[filterKey]; const finalValue = localValue !== undefined ? localValue : filter.label; - console.log("🎯 필터 입력 값 결정:", { - filterKey, - localValue, - filterLabel: filter.label, - finalValue, - allLocalInputs: Object.keys(localFilterInputs), - }); + // console.log("🎯 필터 입력 값 결정:", { + // filterKey, + // localValue, + // filterLabel: filter.label, + // finalValue, + // allLocalInputs: Object.keys(localFilterInputs), + // }); return finalValue; })()} onChange={(e) => { @@ -2109,7 +2109,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="pagination-enabled" checked={localValues.paginationEnabled} onCheckedChange={(checked) => { - console.log("🔄 페이지네이션 사용 변경:", checked); + // console.log("🔄 페이지네이션 사용 변경:", checked); setLocalValues((prev) => ({ ...prev, paginationEnabled: checked as boolean })); onUpdateComponent({ pagination: { ...component.pagination, enabled: checked as boolean }, @@ -2151,7 +2151,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="show-page-size-selector" checked={localValues.showPageSizeSelector} onCheckedChange={(checked) => { - console.log("🔄 페이지 크기 선택기 표시 변경:", checked); + // console.log("🔄 페이지 크기 선택기 표시 변경:", checked); setLocalValues((prev) => ({ ...prev, showPageSizeSelector: checked as boolean })); onUpdateComponent({ pagination: { @@ -2171,7 +2171,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="show-page-info" checked={localValues.showPageInfo} onCheckedChange={(checked) => { - console.log("🔄 페이지 정보 표시 변경:", checked); + // console.log("🔄 페이지 정보 표시 변경:", checked); setLocalValues((prev) => ({ ...prev, showPageInfo: checked as boolean })); onUpdateComponent({ pagination: { @@ -2191,7 +2191,7 @@ const DataTableConfigPanelComponent: React.FC = ({ id="show-first-last" checked={localValues.showFirstLast} onCheckedChange={(checked) => { - console.log("🔄 처음/마지막 버튼 표시 변경:", checked); + // console.log("🔄 처음/마지막 버튼 표시 변경:", checked); setLocalValues((prev) => ({ ...prev, showFirstLast: checked as boolean })); onUpdateComponent({ pagination: { diff --git a/frontend/components/screen/panels/DetailSettingsPanel.tsx b/frontend/components/screen/panels/DetailSettingsPanel.tsx index 9c6f858b..fb292d5e 100644 --- a/frontend/components/screen/panels/DetailSettingsPanel.tsx +++ b/frontend/components/screen/panels/DetailSettingsPanel.tsx @@ -46,17 +46,17 @@ export const DetailSettingsPanel: React.FC = ({ // 데이터베이스에서 입력 가능한 웹타입들을 동적으로 가져오기 const { webTypes } = useWebTypes({ active: "Y" }); - console.log(`🔍 DetailSettingsPanel props:`, { - selectedComponent: selectedComponent?.id, - componentType: selectedComponent?.type, - currentTableName, - currentTable: currentTable?.tableName, - selectedComponentTableName: selectedComponent?.tableName, - }); - console.log(`🔍 DetailSettingsPanel webTypes 로드됨:`, webTypes?.length, "개"); - console.log(`🔍 webTypes:`, webTypes); - console.log(`🔍 DetailSettingsPanel selectedComponent:`, selectedComponent); - console.log(`🔍 DetailSettingsPanel selectedComponent.widgetType:`, selectedComponent?.widgetType); + // console.log(`🔍 DetailSettingsPanel props:`, { + // selectedComponent: selectedComponent?.id, + // componentType: selectedComponent?.type, + // currentTableName, + // currentTable: currentTable?.tableName, + // selectedComponentTableName: selectedComponent?.tableName, + // }); + // console.log(`🔍 DetailSettingsPanel webTypes 로드됨:`, webTypes?.length, "개"); + // console.log(`🔍 webTypes:`, webTypes); + // console.log(`🔍 DetailSettingsPanel selectedComponent:`, selectedComponent); + // console.log(`🔍 DetailSettingsPanel selectedComponent.widgetType:`, selectedComponent?.widgetType); const inputableWebTypes = webTypes.map((wt) => wt.web_type); // 레이아웃 컴포넌트 설정 렌더링 함수 @@ -198,7 +198,7 @@ export const DetailSettingsPanel: React.FC = ({ value={layoutComponent.layoutConfig?.flexbox?.direction || "row"} onChange={(e) => { const newDirection = e.target.value; - console.log("🔄 플렉스박스 방향 변경:", newDirection); + // console.log("🔄 플렉스박스 방향 변경:", newDirection); // 방향 설정 업데이트 onUpdateProperty(layoutComponent.id, "layoutConfig.flexbox.direction", newDirection); @@ -217,11 +217,11 @@ export const DetailSettingsPanel: React.FC = ({ }, })); - console.log("🔄 존 크기 자동 조정:", { - direction: newDirection, - zoneCount, - updatedZones: updatedZones.map((z) => ({ id: z.id, size: z.size })), - }); + // console.log("🔄 존 크기 자동 조정:", { + // direction: newDirection, + // zoneCount, + // updatedZones: updatedZones.map((z) => ({ id: z.id, size: z.size })), + // }); onUpdateProperty(layoutComponent.id, "zones", updatedZones); } @@ -698,27 +698,27 @@ export const DetailSettingsPanel: React.FC = ({ const renderWebTypeConfig = (widget: WidgetComponent) => { const currentConfig = widget.webTypeConfig || {}; - console.log("🎨 DetailSettingsPanel renderWebTypeConfig 호출:", { - componentId: widget.id, - widgetType: widget.widgetType, - currentConfig, - configExists: !!currentConfig, - configKeys: Object.keys(currentConfig), - configStringified: JSON.stringify(currentConfig), - widgetWebTypeConfig: widget.webTypeConfig, - widgetWebTypeConfigExists: !!widget.webTypeConfig, - timestamp: new Date().toISOString(), - }); - console.log("🎨 selectedComponent 전체:", selectedComponent); + // console.log("🎨 DetailSettingsPanel renderWebTypeConfig 호출:", { + // componentId: widget.id, + // widgetType: widget.widgetType, + // currentConfig, + // configExists: !!currentConfig, + // configKeys: Object.keys(currentConfig), + // configStringified: JSON.stringify(currentConfig), + // widgetWebTypeConfig: widget.webTypeConfig, + // widgetWebTypeConfigExists: !!widget.webTypeConfig, + // timestamp: new Date().toISOString(), + // }); + // console.log("🎨 selectedComponent 전체:", selectedComponent); const handleConfigChange = (newConfig: WebTypeConfig) => { - console.log("🔧 WebTypeConfig 업데이트:", { - widgetType: widget.widgetType, - oldConfig: currentConfig, - newConfig, - componentId: widget.id, - isEqual: JSON.stringify(currentConfig) === JSON.stringify(newConfig), - }); + // console.log("🔧 WebTypeConfig 업데이트:", { + // widgetType: widget.widgetType, + // oldConfig: currentConfig, + // newConfig, + // componentId: widget.id, + // isEqual: JSON.stringify(currentConfig) === JSON.stringify(newConfig), + // }); // 강제 새 객체 생성으로 React 변경 감지 보장 const freshConfig = { ...newConfig }; @@ -727,18 +727,18 @@ export const DetailSettingsPanel: React.FC = ({ // 1순위: DB에서 지정된 설정 패널 사용 const dbWebType = webTypes.find((wt) => wt.web_type === widget.widgetType); - console.log(`🎨 웹타입 "${widget.widgetType}" DB 조회 결과:`, dbWebType); + // console.log(`🎨 웹타입 "${widget.widgetType}" DB 조회 결과:`, dbWebType); if (dbWebType?.config_panel) { - console.log(`🎨 웹타입 "${widget.widgetType}" → DB 지정 설정 패널 "${dbWebType.config_panel}" 사용`); + // console.log(`🎨 웹타입 "${widget.widgetType}" → DB 지정 설정 패널 "${dbWebType.config_panel}" 사용`); const ConfigPanelComponent = getConfigPanelComponent(dbWebType.config_panel); - console.log(`🎨 getConfigPanelComponent 결과:`, ConfigPanelComponent); + // console.log(`🎨 getConfigPanelComponent 결과:`, ConfigPanelComponent); if (ConfigPanelComponent) { - console.log(`🎨 ✅ ConfigPanelComponent 렌더링 시작`); + // console.log(`🎨 ✅ ConfigPanelComponent 렌더링 시작`); return ; } else { - console.log(`🎨 ❌ ConfigPanelComponent가 null - 기본 설정 표시`); + // console.log(`🎨 ❌ ConfigPanelComponent가 null - 기본 설정 표시`); return (
⚙️ 기본 설정 @@ -748,7 +748,7 @@ export const DetailSettingsPanel: React.FC = ({ ); } } else { - console.log(`🎨 config_panel이 없음 - 기본 설정 표시`); + // console.log(`🎨 config_panel이 없음 - 기본 설정 표시`); return (
⚙️ 기본 설정 @@ -771,10 +771,10 @@ export const DetailSettingsPanel: React.FC = ({ // 컴포넌트 타입별 설정 패널 렌더링 const renderComponentConfigPanel = () => { - console.log("🔍 renderComponentConfigPanel - selectedComponent:", selectedComponent); + // console.log("🔍 renderComponentConfigPanel - selectedComponent:", selectedComponent); if (!selectedComponent) { - console.error("❌ selectedComponent가 undefined입니다!"); + // console.error("❌ selectedComponent가 undefined입니다!"); return (
@@ -835,11 +835,11 @@ export const DetailSettingsPanel: React.FC = ({ // 새로운 컴포넌트 타입들에 대한 설정 패널 확인 const componentType = selectedComponent?.componentConfig?.type || selectedComponent?.type; - console.log("🔍 DetailSettingsPanel componentType 확인:", { - selectedComponentType: selectedComponent?.type, - componentConfigType: selectedComponent?.componentConfig?.type, - finalComponentType: componentType, - }); + // console.log("🔍 DetailSettingsPanel componentType 확인:", { + // selectedComponentType: selectedComponent?.type, + // componentConfigType: selectedComponent?.componentConfig?.type, + // finalComponentType: componentType, + // }); const hasNewConfigPanel = componentType && @@ -861,7 +861,7 @@ export const DetailSettingsPanel: React.FC = ({ "badge-status", ].includes(componentType); - console.log("🔍 hasNewConfigPanel:", hasNewConfigPanel); + // console.log("🔍 hasNewConfigPanel:", hasNewConfigPanel); if (hasNewConfigPanel) { return ( @@ -944,7 +944,7 @@ export const DetailSettingsPanel: React.FC = ({ // 레거시 버튼을 새로운 컴포넌트 시스템으로 강제 변환 if (selectedComponent.type === "button") { - console.log("🔄 레거시 버튼을 새로운 컴포넌트 시스템으로 변환:", selectedComponent); + // console.log("🔄 레거시 버튼을 새로운 컴포넌트 시스템으로 변환:", selectedComponent); // 레거시 버튼을 새로운 시스템으로 변환 const convertedComponent = { @@ -970,7 +970,7 @@ export const DetailSettingsPanel: React.FC = ({ const componentId = (selectedComponent as any).componentType || selectedComponent.componentConfig?.type; const webType = selectedComponent.componentConfig?.webType; - console.log("🔧 새로운 컴포넌트 시스템 설정 패널:", { componentId, webType }); + // console.log("🔧 새로운 컴포넌트 시스템 설정 패널:", { componentId, webType }); if (!componentId) { return ( @@ -1011,23 +1011,23 @@ export const DetailSettingsPanel: React.FC = ({ componentId={componentId} config={(() => { const config = selectedComponent.componentConfig || {}; - console.log("🔍 DetailSettingsPanel에서 전달하는 config:", config); - console.log("🔍 selectedComponent 전체:", selectedComponent); + // console.log("🔍 DetailSettingsPanel에서 전달하는 config:", config); + // console.log("🔍 selectedComponent 전체:", selectedComponent); return config; })()} screenTableName={selectedComponent.tableName || currentTable?.tableName || currentTableName} tableColumns={(() => { - console.log("🔍 DetailSettingsPanel tableColumns 전달:", { - currentTable, - columns: currentTable?.columns, - columnsLength: currentTable?.columns?.length, - sampleColumn: currentTable?.columns?.[0], - deptCodeColumn: currentTable?.columns?.find((col) => col.columnName === "dept_code"), - }); + // console.log("🔍 DetailSettingsPanel tableColumns 전달:", { + // currentTable, + // columns: currentTable?.columns, + // columnsLength: currentTable?.columns?.length, + // sampleColumn: currentTable?.columns?.[0], + // deptCodeColumn: currentTable?.columns?.find((col) => col.columnName === "dept_code"), + // }); return currentTable?.columns || []; })()} onChange={(newConfig) => { - console.log("🔧 컴포넌트 설정 변경:", newConfig); + // console.log("🔧 컴포넌트 설정 변경:", newConfig); // 개별 속성별로 업데이트하여 다른 속성과의 충돌 방지 Object.entries(newConfig).forEach(([key, value]) => { onUpdateProperty(selectedComponent.id, `componentConfig.${key}`, value); diff --git a/frontend/components/screen/panels/FileComponentConfigPanel.tsx b/frontend/components/screen/panels/FileComponentConfigPanel.tsx index 5f2d9b95..9575ce05 100644 --- a/frontend/components/screen/panels/FileComponentConfigPanel.tsx +++ b/frontend/components/screen/panels/FileComponentConfigPanel.tsx @@ -28,13 +28,13 @@ export const FileComponentConfigPanel: React.FC = currentTable, currentTableName, }) => { - console.log("🎨🎨🎨 FileComponentConfigPanel 렌더링:", { - componentId: component?.id, - componentType: component?.type, - hasOnUpdateProperty: !!onUpdateProperty, - currentTable, - currentTableName - }); + // console.log("🎨🎨🎨 FileComponentConfigPanel 렌더링:", { + // componentId: component?.id, + // componentType: component?.type, + // hasOnUpdateProperty: !!onUpdateProperty, + // currentTable, + // currentTableName + // }); // fileConfig가 없는 경우 초기화 React.useEffect(() => { if (!component.fileConfig) { @@ -90,11 +90,11 @@ export const FileComponentConfigPanel: React.FC = const currentState = getGlobalFileState(); const newState = updater(currentState); (window as any).globalFileState = newState; - console.log("🌐 전역 파일 상태 업데이트:", { - componentId: component.id, - newFileCount: newState[component.id]?.length || 0, - totalComponents: Object.keys(newState).length - }); + // console.log("🌐 전역 파일 상태 업데이트:", { + // componentId: component.id, + // newFileCount: newState[component.id]?.length || 0, + // totalComponents: Object.keys(newState).length + // }); // 강제 리렌더링을 위한 이벤트 발생 window.dispatchEvent(new CustomEvent('globalFileStateChanged', { @@ -103,13 +103,13 @@ export const FileComponentConfigPanel: React.FC = // 디버깅용 전역 함수 등록 (window as any).debugFileState = () => { - console.log("🔍 전역 파일 상태 디버깅:", { - globalState: (window as any).globalFileState, - localStorage: Object.keys(localStorage).filter(key => key.startsWith('fileComponent_')).map(key => ({ - key, - data: JSON.parse(localStorage.getItem(key) || '[]') - })) - }); + // console.log("🔍 전역 파일 상태 디버깅:", { + // globalState: (window as any).globalFileState, + // localStorage: Object.keys(localStorage).filter(key => key.startsWith('fileComponent_')).map(key => ({ + // key, + // data: JSON.parse(localStorage.getItem(key) || '[]') + // })) + // }); }; } }; @@ -136,7 +136,7 @@ export const FileComponentConfigPanel: React.FC = try { parsedBackupFiles = JSON.parse(backupFiles); } catch (error) { - console.error("백업 파일 파싱 실패:", error); + // console.error("백업 파일 파싱 실패:", error); } } @@ -144,7 +144,7 @@ export const FileComponentConfigPanel: React.FC = try { parsedTempFiles = JSON.parse(tempBackupFiles); } catch (error) { - console.error("임시 파일 파싱 실패:", error); + // console.error("임시 파일 파싱 실패:", error); } } @@ -153,7 +153,7 @@ export const FileComponentConfigPanel: React.FC = try { parsedFileUploadFiles = JSON.parse(fileUploadBackupFiles); } catch (error) { - console.error("FileUploadComponent 백업 파일 파싱 실패:", error); + // console.error("FileUploadComponent 백업 파일 파싱 실패:", error); } } @@ -164,19 +164,19 @@ export const FileComponentConfigPanel: React.FC = parsedTempFiles.length > 0 ? parsedTempFiles : componentFiles; - console.log("🚀 FileComponentConfigPanel 초기화:", { - componentId: component.id, - componentFiles: componentFiles.length, - globalFiles: globalFiles.length, - backupFiles: parsedBackupFiles.length, - tempFiles: parsedTempFiles.length, - fileUploadFiles: parsedFileUploadFiles.length, // 🎯 실제 화면 파일 수 - finalFiles: finalFiles.length, - source: globalFiles.length > 0 ? 'global' : - parsedFileUploadFiles.length > 0 ? 'fileUploadComponent' : // 🎯 실제 화면 소스 - parsedBackupFiles.length > 0 ? 'localStorage' : - parsedTempFiles.length > 0 ? 'temp' : 'component' - }); + // console.log("🚀 FileComponentConfigPanel 초기화:", { + // componentId: component.id, + // componentFiles: componentFiles.length, + // globalFiles: globalFiles.length, + // backupFiles: parsedBackupFiles.length, + // tempFiles: parsedTempFiles.length, + // fileUploadFiles: parsedFileUploadFiles.length, // 🎯 실제 화면 파일 수 + // finalFiles: finalFiles.length, + // source: globalFiles.length > 0 ? 'global' : + // parsedFileUploadFiles.length > 0 ? 'fileUploadComponent' : // 🎯 실제 화면 소스 + // parsedBackupFiles.length > 0 ? 'localStorage' : + // parsedTempFiles.length > 0 ? 'temp' : 'component' + // }); return finalFiles; }; @@ -188,10 +188,10 @@ export const FileComponentConfigPanel: React.FC = setTimeout(() => { onUpdateProperty(component.id, "uploadedFiles", initialFiles); onUpdateProperty(component.id, "lastFileUpdate", Date.now()); - console.log("🔄 초기화 시 컴포넌트 속성 동기화:", { - componentId: component.id, - fileCount: initialFiles.length - }); + // console.log("🔄 초기화 시 컴포넌트 속성 동기화:", { + // componentId: component.id, + // fileCount: initialFiles.length + // }); }, 0); } return initialFiles; @@ -216,15 +216,15 @@ export const FileComponentConfigPanel: React.FC = // 파일 업로드 처리 const handleFileUpload = useCallback(async (files: FileList | File[]) => { - console.log("🚀🚀🚀 FileComponentConfigPanel 파일 업로드 시작:", { - filesCount: files?.length || 0, - componentId: component?.id, - componentType: component?.type, - hasOnUpdateProperty: !!onUpdateProperty - }); + // console.log("🚀🚀🚀 FileComponentConfigPanel 파일 업로드 시작:", { + // filesCount: files?.length || 0, + // componentId: component?.id, + // componentType: component?.type, + // hasOnUpdateProperty: !!onUpdateProperty + // }); if (!files || files.length === 0) { - console.log("❌ 파일이 없음"); + // console.log("❌ 파일이 없음"); return; } @@ -251,23 +251,23 @@ export const FileComponentConfigPanel: React.FC = if (!isAllowed) { toast.error(`${file.name}: 허용되지 않는 파일 형식입니다. (허용: ${acceptTypes.join(', ')})`); - console.log(`파일 검증 실패:`, { - fileName: file.name, - fileType: file.type, - fileExt, - acceptTypes, - isAllowed - }); + // console.log(`파일 검증 실패:`, { + // fileName: file.name, + // fileType: file.type, + // fileExt, + // acceptTypes, + // isAllowed + // }); continue; } } - console.log(`파일 검증 성공:`, { - fileName: file.name, - fileType: file.type, - fileSize: file.size, - acceptTypesCount: acceptTypes.length - }); + // console.log(`파일 검증 성공:`, { + // fileName: file.name, + // fileType: file.type, + // fileSize: file.size, + // acceptTypesCount: acceptTypes.length + // }); validFiles.push(file); } @@ -280,27 +280,27 @@ export const FileComponentConfigPanel: React.FC = const duplicates: string[] = []; const uniqueFiles: File[] = []; - console.log("🔍 중복 파일 체크:", { - uploadedFiles: existingFiles.length, - existingFileNames: existingFileNames, - newFiles: validFiles.map(f => f.name.toLowerCase()) - }); + // console.log("🔍 중복 파일 체크:", { + // uploadedFiles: existingFiles.length, + // existingFileNames: existingFileNames, + // newFiles: validFiles.map(f => f.name.toLowerCase()) + // }); validFiles.forEach(file => { const fileName = file.name.toLowerCase(); if (existingFileNames.includes(fileName)) { duplicates.push(file.name); - console.log("❌ 중복 파일 발견:", file.name); + // console.log("❌ 중복 파일 발견:", file.name); } else { uniqueFiles.push(file); - console.log("✅ 새로운 파일:", file.name); + // console.log("✅ 새로운 파일:", file.name); } }); - console.log("🔍 중복 체크 결과:", { - duplicates: duplicates, - uniqueFiles: uniqueFiles.map(f => f.name) - }); + // console.log("🔍 중복 체크 결과:", { + // duplicates: duplicates, + // uniqueFiles: uniqueFiles.map(f => f.name) + // }); if (duplicates.length > 0) { toast.error(`중복된 파일이 있습니다: ${duplicates.join(', ')}`, { @@ -319,11 +319,11 @@ export const FileComponentConfigPanel: React.FC = const filesToUpload = uniqueFiles.length > 0 ? uniqueFiles : validFiles; try { - console.log("🔄 파일 업로드 시작:", { - originalFiles: validFiles.length, - filesToUpload: filesToUpload.length, - uploading - }); + // console.log("🔄 파일 업로드 시작:", { + // originalFiles: validFiles.length, + // filesToUpload: filesToUpload.length, + // uploading + // }); setUploading(true); toast.loading(`${filesToUpload.length}개 파일 업로드 중...`); @@ -344,21 +344,21 @@ export const FileComponentConfigPanel: React.FC = // 3차: 기본값 설정 if (!screenId) { screenId = 40; // 기본 화면 ID (디자인 모드용) - console.warn("⚠️ screenId를 찾을 수 없어 기본값(40) 사용"); + // console.warn("⚠️ screenId를 찾을 수 없어 기본값(40) 사용"); } const componentId = component.id; const fieldName = component.columnName || component.id || 'file_attachment'; - console.log("📋 파일 업로드 기본 정보:", { - screenId, - screenIdSource: (window as any).__CURRENT_SCREEN_ID__ ? 'global' : 'url_or_default', - componentId, - fieldName, - docType: localInputs.docType, - docTypeName: localInputs.docTypeName, - currentPath: typeof window !== 'undefined' ? window.location.pathname : 'unknown' - }); + // console.log("📋 파일 업로드 기본 정보:", { + // screenId, + // screenIdSource: (window as any).__CURRENT_SCREEN_ID__ ? 'global' : 'url_or_default', + // componentId, + // fieldName, + // docType: localInputs.docType, + // docTypeName: localInputs.docTypeName, + // currentPath: typeof window !== 'undefined' ? window.location.pathname : 'unknown' + // }); const response = await uploadFiles({ files: filesToUpload, @@ -372,11 +372,11 @@ export const FileComponentConfigPanel: React.FC = docTypeName: localInputs.docTypeName, }); - console.log("📤 파일 업로드 응답:", response); + // console.log("📤 파일 업로드 응답:", response); if (response.success && (response.data || response.files)) { const filesData = response.data || response.files; - console.log("📁 업로드된 파일 데이터:", filesData); + // console.log("📁 업로드된 파일 데이터:", filesData); const newFiles: FileInfo[] = filesData.map((file: any) => ({ objid: file.objid || `temp_${Date.now()}_${Math.random()}`, savedFileName: file.saved_file_name || file.savedFileName, @@ -431,10 +431,10 @@ export const FileComponentConfigPanel: React.FC = source: 'designMode' // 🎯 화면설계 모드에서 온 이벤트임을 표시 }; - console.log("🚀🚀🚀 FileComponentConfigPanel 이벤트 발생:", eventDetail); - console.log("🔍 현재 컴포넌트 ID:", component.id); - console.log("🔍 업로드된 파일 수:", updatedFiles.length); - console.log("🔍 파일 목록:", updatedFiles.map(f => f.name)); + // console.log("🚀🚀🚀 FileComponentConfigPanel 이벤트 발생:", eventDetail); + // console.log("🔍 현재 컴포넌트 ID:", component.id); + // console.log("🔍 업로드된 파일 수:", updatedFiles.length); + // console.log("🔍 파일 목록:", updatedFiles.map(f => f.name)); const event = new CustomEvent('globalFileStateChanged', { detail: eventDetail @@ -444,49 +444,49 @@ export const FileComponentConfigPanel: React.FC = const listenerCount = window.getEventListeners ? window.getEventListeners(window)?.globalFileStateChanged?.length || 0 : 'unknown'; - console.log("🔍 globalFileStateChanged 리스너 수:", listenerCount); + // console.log("🔍 globalFileStateChanged 리스너 수:", listenerCount); window.dispatchEvent(event); - console.log("✅✅✅ globalFileStateChanged 이벤트 발생 완료"); + // console.log("✅✅✅ globalFileStateChanged 이벤트 발생 완료"); // 강제로 모든 RealtimePreview 컴포넌트에게 알림 (여러 번) setTimeout(() => { - console.log("🔄 추가 이벤트 발생 (지연 100ms)"); + // console.log("🔄 추가 이벤트 발생 (지연 100ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true } })); }, 100); setTimeout(() => { - console.log("🔄 추가 이벤트 발생 (지연 300ms)"); + // console.log("🔄 추가 이벤트 발생 (지연 300ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true, attempt: 2 } })); }, 300); setTimeout(() => { - console.log("🔄 추가 이벤트 발생 (지연 500ms)"); + // console.log("🔄 추가 이벤트 발생 (지연 500ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true, attempt: 3 } })); }, 500); // 직접 전역 상태 강제 업데이트 - console.log("🔄 전역 상태 강제 업데이트 시도"); + // console.log("🔄 전역 상태 강제 업데이트 시도"); if ((window as any).forceRealtimePreviewUpdate) { (window as any).forceRealtimePreviewUpdate(component.id, updatedFiles); } } - console.log("🔄 FileComponentConfigPanel 자동 저장:", { - componentId: component.id, - uploadedFiles: updatedFiles.length, - status: "자동 영구 저장됨", - onUpdatePropertyExists: typeof onUpdateProperty === 'function', - globalFileStateUpdated: getGlobalFileState()[component.id]?.length || 0, - localStorageBackup: localStorage.getItem(`fileComponent_${component.id}_files`) ? 'saved' : 'not saved' - }); + // console.log("🔄 FileComponentConfigPanel 자동 저장:", { + // componentId: component.id, + // uploadedFiles: updatedFiles.length, + // status: "자동 영구 저장됨", + // onUpdatePropertyExists: typeof onUpdateProperty === 'function', + // globalFileStateUpdated: getGlobalFileState()[component.id]?.length || 0, + // localStorageBackup: localStorage.getItem(`fileComponent_${component.id}_files`) ? 'saved' : 'not saved' + // }); // 그리드 파일 상태 새로고침 이벤트 발생 if (typeof window !== 'undefined') { @@ -505,40 +505,40 @@ export const FileComponentConfigPanel: React.FC = } }); window.dispatchEvent(refreshEvent); - console.log("🔄 FileComponentConfigPanel 그리드 새로고침 이벤트 발생:", { - tableName, - recordId, - columnName, - targetObjid, - fileCount: updatedFiles.length - }); + // console.log("🔄 FileComponentConfigPanel 그리드 새로고침 이벤트 발생:", { + // tableName, + // recordId, + // columnName, + // targetObjid, + // fileCount: updatedFiles.length + // }); } toast.dismiss(); toast.success(`${validFiles.length}개 파일이 성공적으로 업로드되었습니다.`); - console.log("✅ 파일 업로드 성공:", { - newFilesCount: newFiles.length, - totalFiles: updatedFiles.length, - componentId: component.id, - updatedFiles: updatedFiles.map(f => ({ objid: f.objid, name: f.realFileName })) - }); + // console.log("✅ 파일 업로드 성공:", { + // newFilesCount: newFiles.length, + // totalFiles: updatedFiles.length, + // componentId: component.id, + // updatedFiles: updatedFiles.map(f => ({ objid: f.objid, name: f.realFileName })) + // }); } else { throw new Error(response.message || '파일 업로드에 실패했습니다.'); } } catch (error: any) { - console.error('❌ 파일 업로드 오류:', { - error, - errorMessage: error?.message, - errorResponse: error?.response?.data, - errorStatus: error?.response?.status, - componentId: component?.id, - screenId, - fieldName - }); + // console.error('❌ 파일 업로드 오류:', { + // error, + // errorMessage: error?.message, + // errorResponse: error?.response?.data, + // errorStatus: error?.response?.status, + // componentId: component?.id, + // screenId, + // fieldName + // }); toast.dismiss(); toast.error(`파일 업로드에 실패했습니다: ${error?.message || '알 수 없는 오류'}`); } finally { - console.log("🏁 파일 업로드 완료, 로딩 상태 해제"); + // console.log("🏁 파일 업로드 완료, 로딩 상태 해제"); setUploading(false); } }, [localInputs, localValues, uploadedFiles, onUpdateProperty, currentTableName, component, acceptTypes]); @@ -553,24 +553,24 @@ export const FileComponentConfigPanel: React.FC = }); toast.success(`${file.realFileName || file.name} 다운로드가 완료되었습니다.`); } catch (error) { - console.error('파일 다운로드 오류:', error); + // console.error('파일 다운로드 오류:', error); toast.error('파일 다운로드에 실패했습니다.'); } }, []); // 파일 삭제 처리 const handleFileDelete = useCallback(async (fileId: string) => { - console.log("🗑️🗑️🗑️ FileComponentConfigPanel 파일 삭제 시작:", { - fileId, - componentId: component?.id, - currentFilesCount: uploadedFiles.length, - hasOnUpdateProperty: !!onUpdateProperty - }); + // console.log("🗑️🗑️🗑️ FileComponentConfigPanel 파일 삭제 시작:", { + // fileId, + // componentId: component?.id, + // currentFilesCount: uploadedFiles.length, + // hasOnUpdateProperty: !!onUpdateProperty + // }); try { - console.log("📡 deleteFile API 호출 시작..."); + // console.log("📡 deleteFile API 호출 시작..."); await deleteFile(fileId, 'temp_record'); - console.log("✅ deleteFile API 호출 성공"); + // console.log("✅ deleteFile API 호출 성공"); const updatedFiles = uploadedFiles.filter(file => file.objid !== fileId && file.id !== fileId); setUploadedFiles(updatedFiles); @@ -591,12 +591,12 @@ export const FileComponentConfigPanel: React.FC = localStorage.setItem(backupKey, JSON.stringify(updatedFiles)); localStorage.setItem(tempBackupKey, JSON.stringify(updatedFiles)); - console.log("🗑️ FileComponentConfigPanel 파일 삭제:", { - componentId: component.id, - deletedFileId: fileId, - remainingFiles: updatedFiles.length, - timestamp: timestamp - }); + // console.log("🗑️ FileComponentConfigPanel 파일 삭제:", { + // componentId: component.id, + // deletedFileId: fileId, + // remainingFiles: updatedFiles.length, + // timestamp: timestamp + // }); // 🎯 RealtimePreview 동기화를 위한 전역 이벤트 발생 if (typeof window !== 'undefined') { @@ -610,39 +610,39 @@ export const FileComponentConfigPanel: React.FC = source: 'designMode' // 🎯 화면설계 모드에서 온 이벤트임을 표시 }; - console.log("🚀🚀🚀 FileComponentConfigPanel 삭제 이벤트 발생:", eventDetail); + // console.log("🚀🚀🚀 FileComponentConfigPanel 삭제 이벤트 발생:", eventDetail); const event = new CustomEvent('globalFileStateChanged', { detail: eventDetail }); window.dispatchEvent(event); - console.log("✅✅✅ globalFileStateChanged 삭제 이벤트 발생 완료"); + // console.log("✅✅✅ globalFileStateChanged 삭제 이벤트 발생 완료"); // 추가 지연 이벤트들 setTimeout(() => { try { - console.log("🔄 추가 삭제 이벤트 발생 (지연 100ms)"); + // console.log("🔄 추가 삭제 이벤트 발생 (지연 100ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true } })); } catch (error) { - console.warn("FileComponentConfigPanel 지연 이벤트 발생 실패:", error); + // console.warn("FileComponentConfigPanel 지연 이벤트 발생 실패:", error); } }, 100); setTimeout(() => { try { - console.log("🔄 추가 삭제 이벤트 발생 (지연 300ms)"); + // console.log("🔄 추가 삭제 이벤트 발생 (지연 300ms)"); window.dispatchEvent(new CustomEvent('globalFileStateChanged', { detail: { ...eventDetail, delayed: true, attempt: 2 } })); } catch (error) { - console.warn("FileComponentConfigPanel 지연 이벤트 발생 실패:", error); + // console.warn("FileComponentConfigPanel 지연 이벤트 발생 실패:", error); } }, 300); } catch (error) { - console.warn("FileComponentConfigPanel 이벤트 발생 실패:", error); + // console.warn("FileComponentConfigPanel 이벤트 발생 실패:", error); } // 그리드 파일 상태 새로고침 이벤트도 유지 @@ -663,20 +663,20 @@ export const FileComponentConfigPanel: React.FC = }); window.dispatchEvent(refreshEvent); } catch (error) { - console.warn("FileComponentConfigPanel refreshFileStatus 이벤트 발생 실패:", error); + // console.warn("FileComponentConfigPanel refreshFileStatus 이벤트 발생 실패:", error); } - console.log("🔄 FileComponentConfigPanel 파일 삭제 후 그리드 새로고침:", { - tableName, - recordId, - columnName, - targetObjid, - fileCount: updatedFiles.length - }); + // console.log("🔄 FileComponentConfigPanel 파일 삭제 후 그리드 새로고침:", { + // tableName, + // recordId, + // columnName, + // targetObjid, + // fileCount: updatedFiles.length + // }); } toast.success('파일이 삭제되었습니다.'); } catch (error) { - console.error('파일 삭제 오류:', error); + // console.error('파일 삭제 오류:', error); toast.error('파일 삭제에 실패했습니다.'); } }, [uploadedFiles, onUpdateProperty, component.id]); @@ -703,16 +703,16 @@ export const FileComponentConfigPanel: React.FC = const tempBackupKey = `fileComponent_${component.id}_files_temp`; localStorage.removeItem(tempBackupKey); - console.log("💾 파일 저장 완료:", { - componentId: component.id, - fileCount: uploadedFiles.length, - timestamp: timestamp, - files: uploadedFiles.map(f => ({ objid: f.objid, name: f.realFileName })) - }); + // console.log("💾 파일 저장 완료:", { + // componentId: component.id, + // fileCount: uploadedFiles.length, + // timestamp: timestamp, + // files: uploadedFiles.map(f => ({ objid: f.objid, name: f.realFileName })) + // }); toast.success(`${uploadedFiles.length}개 파일이 영구 저장되었습니다.`); } catch (error) { - console.error('파일 저장 오류:', error); + // console.error('파일 저장 오류:', error); toast.error('파일 저장에 실패했습니다.'); } }, [uploadedFiles, onUpdateProperty, component.id, setGlobalFileState]); @@ -732,21 +732,21 @@ export const FileComponentConfigPanel: React.FC = e.preventDefault(); setDragOver(false); const files = e.dataTransfer.files; - console.log("📂 드래그앤드롭 이벤트:", { - filesCount: files.length, - files: files.length > 0 ? Array.from(files).map(f => f.name) : [], - componentId: component?.id - }); + // console.log("📂 드래그앤드롭 이벤트:", { + // filesCount: files.length, + // files: files.length > 0 ? Array.from(files).map(f => f.name) : [], + // componentId: component?.id + // }); if (files.length > 0) { handleFileUpload(files); } }, [handleFileUpload, component?.id]); const handleFileSelect = useCallback((e: React.ChangeEvent) => { - console.log("📁 파일 선택 이벤트:", { - filesCount: e.target.files?.length || 0, - files: e.target.files ? Array.from(e.target.files).map(f => f.name) : [] - }); + // console.log("📁 파일 선택 이벤트:", { + // filesCount: e.target.files?.length || 0, + // files: e.target.files ? Array.from(e.target.files).map(f => f.name) : [] + // }); const files = e.target.files; if (files && files.length > 0) { @@ -782,27 +782,27 @@ export const FileComponentConfigPanel: React.FC = if (prevComponentIdRef.current !== component.id) { // 새로운 컴포넌트로 변경된 경우 - console.log("🔄 FileComponentConfigPanel 새 컴포넌트 선택:", { - prevComponentId: prevComponentIdRef.current, - newComponentId: component.id, - componentFiles: componentFiles.length, - action: "새 컴포넌트 → 상태 초기화", - globalFileStateExists: !!getGlobalFileState()[component.id], - globalFileStateLength: getGlobalFileState()[component.id]?.length || 0, - localStorageExists: !!localStorage.getItem(`fileComponent_${component.id}_files`), - onUpdatePropertyExists: typeof onUpdateProperty === 'function' - }); + // console.log("🔄 FileComponentConfigPanel 새 컴포넌트 선택:", { + // prevComponentId: prevComponentIdRef.current, + // newComponentId: component.id, + // componentFiles: componentFiles.length, + // action: "새 컴포넌트 → 상태 초기화", + // globalFileStateExists: !!getGlobalFileState()[component.id], + // globalFileStateLength: getGlobalFileState()[component.id]?.length || 0, + // localStorageExists: !!localStorage.getItem(`fileComponent_${component.id}_files`), + // onUpdatePropertyExists: typeof onUpdateProperty === 'function' + // }); // 1순위: 전역 상태에서 파일 복원 const globalFileState = getGlobalFileState(); const globalFiles = globalFileState[component.id]; if (globalFiles && globalFiles.length > 0) { - console.log("🌐 전역 상태에서 파일 복원:", { - componentId: component.id, - globalFiles: globalFiles.length, - action: "전역 상태 → 상태 복원" - }); + // console.log("🌐 전역 상태에서 파일 복원:", { + // componentId: component.id, + // globalFiles: globalFiles.length, + // action: "전역 상태 → 상태 복원" + // }); setUploadedFiles(globalFiles); onUpdateProperty(component.id, "uploadedFiles", globalFiles); } @@ -814,11 +814,11 @@ export const FileComponentConfigPanel: React.FC = if (backupFiles && componentFiles.length === 0) { try { const parsedBackupFiles = JSON.parse(backupFiles); - console.log("📂 localStorage에서 파일 복원:", { - componentId: component.id, - backupFiles: parsedBackupFiles.length, - action: "백업 → 상태 복원" - }); + // console.log("📂 localStorage에서 파일 복원:", { + // componentId: component.id, + // backupFiles: parsedBackupFiles.length, + // action: "백업 → 상태 복원" + // }); setUploadedFiles(parsedBackupFiles); // 전역 상태에도 저장 setGlobalFileState(prev => ({ @@ -828,7 +828,7 @@ export const FileComponentConfigPanel: React.FC = // 컴포넌트 속성에도 복원 onUpdateProperty(component.id, "uploadedFiles", parsedBackupFiles); } catch (error) { - console.error("백업 파일 복원 실패:", error); + // console.error("백업 파일 복원 실패:", error); setUploadedFiles(componentFiles); } } else { @@ -839,12 +839,12 @@ export const FileComponentConfigPanel: React.FC = prevComponentIdRef.current = component.id; } else if (componentFiles.length > 0 && JSON.stringify(componentFiles) !== JSON.stringify(uploadedFiles)) { // 같은 컴포넌트에서 파일이 업데이트된 경우 - console.log("🔄 FileComponentConfigPanel 파일 동기화:", { - componentId: component.id, - componentFiles: componentFiles.length, - currentFiles: uploadedFiles.length, - action: "컴포넌트 → 상태 동기화" - }); + // console.log("🔄 FileComponentConfigPanel 파일 동기화:", { + // componentId: component.id, + // componentFiles: componentFiles.length, + // currentFiles: uploadedFiles.length, + // action: "컴포넌트 → 상태 동기화" + // }); setUploadedFiles(componentFiles); } }, [component.id]); // 컴포넌트 ID가 변경될 때만 초기화 @@ -855,24 +855,24 @@ export const FileComponentConfigPanel: React.FC = const { componentId, files, fileCount, isRestore, source } = event.detail; if (componentId === component.id) { - console.log("🌐 FileComponentConfigPanel 전역 상태 변경 감지:", { - componentId, - fileCount, - isRestore: !!isRestore, - source: source || 'unknown', - files: files?.map((f: any) => ({ objid: f.objid, name: f.realFileName })) - }); + // console.log("🌐 FileComponentConfigPanel 전역 상태 변경 감지:", { + // componentId, + // fileCount, + // isRestore: !!isRestore, + // source: source || 'unknown', + // files: files?.map((f: any) => ({ objid: f.objid, name: f.realFileName })) + // }); if (files && Array.isArray(files)) { setUploadedFiles(files); // 🎯 실제 화면에서 온 이벤트이거나 화면 복원인 경우 컴포넌트 속성도 업데이트 if (isRestore || source === 'realScreen') { - console.log("✅✅✅ 실제 화면 → 화면설계 모드 동기화 적용:", { - componentId, - fileCount: files.length, - source: source || 'restore' - }); + // console.log("✅✅✅ 실제 화면 → 화면설계 모드 동기화 적용:", { + // componentId, + // fileCount: files.length, + // source: source || 'restore' + // }); onUpdateProperty(component.id, "uploadedFiles", files); onUpdateProperty(component.id, "lastFileUpdate", Date.now()); @@ -881,12 +881,12 @@ export const FileComponentConfigPanel: React.FC = try { const backupKey = `fileComponent_${component.id}_files`; localStorage.setItem(backupKey, JSON.stringify(files)); - console.log("💾 실제 화면 동기화 후 localStorage 백업 업데이트:", { - componentId: component.id, - fileCount: files.length - }); + // console.log("💾 실제 화면 동기화 후 localStorage 백업 업데이트:", { + // componentId: component.id, + // fileCount: files.length + // }); } catch (e) { - console.warn("localStorage 백업 업데이트 실패:", e); + // console.warn("localStorage 백업 업데이트 실패:", e); } // 전역 상태 업데이트 @@ -895,10 +895,10 @@ export const FileComponentConfigPanel: React.FC = [component.id]: files })); } else if (isRestore) { - console.log("✅ 파일 컴포넌트 설정 패널 데이터 복원 완료:", { - componentId, - restoredFileCount: files.length - }); + // console.log("✅ 파일 컴포넌트 설정 패널 데이터 복원 완료:", { + // componentId, + // restoredFileCount: files.length + // }); } } } @@ -1119,18 +1119,18 @@ export const FileComponentConfigPanel: React.FC = onDragLeave={handleDragLeave} onDrop={handleDrop} onClick={() => { - console.log("🖱️ 파일 업로드 영역 클릭:", { - uploading, - inputElement: document.getElementById('file-input-config'), - componentId: component?.id - }); + // console.log("🖱️ 파일 업로드 영역 클릭:", { + // uploading, + // inputElement: document.getElementById('file-input-config'), + // componentId: component?.id + // }); if (!uploading) { const input = document.getElementById('file-input-config'); if (input) { - console.log("✅ 파일 input 클릭 실행"); + // console.log("✅ 파일 input 클릭 실행"); input.click(); } else { - console.log("❌ 파일 input 요소를 찾을 수 없음"); + // console.log("❌ 파일 input 요소를 찾을 수 없음"); } } }} diff --git a/frontend/components/screen/panels/LayoutsPanel.tsx b/frontend/components/screen/panels/LayoutsPanel.tsx index 0e20434a..38b2a475 100644 --- a/frontend/components/screen/panels/LayoutsPanel.tsx +++ b/frontend/components/screen/panels/LayoutsPanel.tsx @@ -108,14 +108,14 @@ export default function LayoutsPanel({ height: 400, // 높이는 고정 }; - console.log("🎯 카드 레이아웃 동적 크기 계산:", { - gridColumns: 8, - screenResolution, - gridSettings, - gridInfo, - calculatedWidth, - finalSize: calculatedSize, - }); + // console.log("🎯 카드 레이아웃 동적 크기 계산:", { + // gridColumns: 8, + // screenResolution, + // gridSettings, + // gridInfo, + // calculatedWidth, + // finalSize: calculatedSize, + // }); } // 새 레이아웃 컴포넌트 데이터 생성 diff --git a/frontend/components/screen/panels/PropertiesPanel.tsx b/frontend/components/screen/panels/PropertiesPanel.tsx index e36191a8..b12d843f 100644 --- a/frontend/components/screen/panels/PropertiesPanel.tsx +++ b/frontend/components/screen/panels/PropertiesPanel.tsx @@ -34,7 +34,7 @@ const DataTableConfigPanelWrapper: React.FC<{ // 안정화된 업데이트 핸들러 const handleUpdateComponent = React.useCallback( (updates: Partial) => { - console.log("🔄 DataTable 래퍼 컴포넌트 업데이트:", updates); + // console.log("🔄 DataTable 래퍼 컴포넌트 업데이트:", updates); // 변경사항이 있는지 확인 (간단한 비교로 성능 향상) const hasChanges = Object.entries(updates).some(([key, value]) => { @@ -48,7 +48,7 @@ const DataTableConfigPanelWrapper: React.FC<{ }); if (!hasChanges) { - console.log("⏭️ 래퍼: 변경사항 없음, 업데이트 스킵"); + // console.log("⏭️ 래퍼: 변경사항 없음, 업데이트 스킵"); return; } @@ -123,18 +123,18 @@ const PropertiesPanelComponent: React.FC = ({ canUngroup = false, }) => { // 🔍 디버깅: PropertiesPanel 렌더링 및 dragState 전달 확인 - console.log("📍 PropertiesPanel 렌더링:", { - renderTime: Date.now(), - selectedComponentId: selectedComponent?.id, - dragState: dragState - ? { - isDragging: dragState.isDragging, - draggedComponentId: dragState.draggedComponent?.id, - currentPosition: dragState.currentPosition, - dragStateRef: dragState, // 객체 참조 확인 - } - : "null", - }); + // console.log("📍 PropertiesPanel 렌더링:", { + // renderTime: Date.now(), + // selectedComponentId: selectedComponent?.id, + // dragState: dragState + // ? { + // isDragging: dragState.isDragging, + // draggedComponentId: dragState.draggedComponent?.id, + // currentPosition: dragState.currentPosition, + // dragStateRef: dragState, // 객체 참조 확인 + // } + // : "null", + // }); // 동적 웹타입 목록 가져오기 - API에서 직접 조회 const { webTypes, isLoading: isWebTypesLoading } = useWebTypes({ active: "Y" }); @@ -160,11 +160,11 @@ const PropertiesPanelComponent: React.FC = ({ // 실시간 위치 계산 (드래그 중일 때는 dragState.currentPosition 사용) const getCurrentPosition = () => { if (dragState?.isDragging && dragState.draggedComponent?.id === selectedComponent?.id) { - console.log("🎯 드래그 중 실시간 위치:", { - draggedId: dragState.draggedComponent?.id, - selectedId: selectedComponent?.id, - currentPosition: dragState.currentPosition, - }); + // console.log("🎯 드래그 중 실시간 위치:", { + // draggedId: dragState.draggedComponent?.id, + // selectedId: selectedComponent?.id, + // currentPosition: dragState.currentPosition, + // }); return { x: Math.round(dragState.currentPosition.x), y: Math.round(dragState.currentPosition.y), @@ -225,22 +225,22 @@ const PropertiesPanelComponent: React.FC = ({ const group = selectedComponent.type === "group" ? (selectedComponent as GroupComponent) : null; const area = selectedComponent.type === "area" ? (selectedComponent as AreaComponent) : null; - console.log("🔄 PropertiesPanel: 컴포넌트 변경 감지", { - componentId: selectedComponent.id, - componentType: selectedComponent.type, - isDragging: dragState?.isDragging, - justFinishedDrag: dragState?.justFinishedDrag, - currentValues: { - placeholder: widget?.placeholder, - title: group?.title || area?.title, - description: area?.description, - actualPositionX: selectedComponent.position.x, - actualPositionY: selectedComponent.position.y, - dragPositionX: dragState?.currentPosition.x, - dragPositionY: dragState?.currentPosition.y, - }, - getCurrentPosResult: getCurrentPosition(), - }); + // console.log("🔄 PropertiesPanel: 컴포넌트 변경 감지", { + // componentId: selectedComponent.id, + // componentType: selectedComponent.type, + // isDragging: dragState?.isDragging, + // justFinishedDrag: dragState?.justFinishedDrag, + // currentValues: { + // placeholder: widget?.placeholder, + // title: group?.title || area?.title, + // description: area?.description, + // actualPositionX: selectedComponent.position.x, + // actualPositionY: selectedComponent.position.y, + // dragPositionX: dragState?.currentPosition.x, + // dragPositionY: dragState?.currentPosition.y, + // }, + // getCurrentPosResult: getCurrentPosition(), + // }); // 드래그 중이 아닐 때만 localInputs 업데이트 (드래그 완료 후 최종 위치 반영) if (!dragState?.isDragging || dragState.draggedComponent?.id !== selectedComponent.id) { @@ -270,10 +270,10 @@ const PropertiesPanelComponent: React.FC = ({ widgetType: widget?.widgetType || "text", }); - console.log("✅ localInputs 업데이트 완료:", { - positionX: currentPos.x.toString(), - positionY: currentPos.y.toString(), - }); + // console.log("✅ localInputs 업데이트 완료:", { + // positionX: currentPos.x.toString(), + // positionY: currentPos.y.toString(), + // }); } } }, [ @@ -307,24 +307,24 @@ const PropertiesPanelComponent: React.FC = ({ }; // 🔍 디버깅: 컴포넌트 구조 확인 - console.log("🔍 PropertiesPanel 삭제 액션 디버깅:", { - componentType: selectedComponent.type, - componentId: selectedComponent.id, - componentConfig: selectedComponent.componentConfig, - config: selectedComponent.config, - webTypeConfig: selectedComponent.webTypeConfig, - actionType1: selectedComponent.componentConfig?.action?.type, - actionType2: selectedComponent.config?.action?.type, - actionType3: selectedComponent.webTypeConfig?.actionType, - isDeleteAction: isDeleteAction(), - currentLabelColor: selectedComponent.style?.labelColor, - }); + // console.log("🔍 PropertiesPanel 삭제 액션 디버깅:", { + // componentType: selectedComponent.type, + // componentId: selectedComponent.id, + // componentConfig: selectedComponent.componentConfig, + // config: selectedComponent.config, + // webTypeConfig: selectedComponent.webTypeConfig, + // actionType1: selectedComponent.componentConfig?.action?.type, + // actionType2: selectedComponent.config?.action?.type, + // actionType3: selectedComponent.webTypeConfig?.actionType, + // isDeleteAction: isDeleteAction(), + // currentLabelColor: selectedComponent.style?.labelColor, + // }); // 액션에 따른 라벨 색상 자동 설정 if (isDeleteAction()) { // 삭제 액션일 때 빨간색으로 설정 (이미 빨간색이 아닌 경우에만) if (selectedComponent.style?.labelColor !== '#ef4444') { - console.log("🔴 삭제 액션 감지: 라벨 색상을 빨간색으로 자동 설정"); + // console.log("🔴 삭제 액션 감지: 라벨 색상을 빨간색으로 자동 설정"); onUpdateProperty("style", { ...selectedComponent.style, labelColor: '#ef4444' @@ -339,7 +339,7 @@ const PropertiesPanelComponent: React.FC = ({ } else { // 다른 액션일 때 기본 파란색으로 리셋 (현재 빨간색인 경우에만) if (selectedComponent.style?.labelColor === '#ef4444') { - console.log("🔵 일반 액션 감지: 라벨 색상을 기본 파란색으로 리셋"); + // console.log("🔵 일반 액션 감지: 라벨 색상을 기본 파란색으로 리셋"); onUpdateProperty("style", { ...selectedComponent.style, labelColor: '#3b83f6' @@ -365,12 +365,12 @@ const PropertiesPanelComponent: React.FC = ({ // 렌더링 시마다 실행되는 직접적인 드래그 상태 체크 if (dragState?.isDragging && dragState.draggedComponent?.id === selectedComponent?.id) { - console.log("🎯 렌더링 중 드래그 상태 감지:", { - isDragging: dragState.isDragging, - draggedId: dragState.draggedComponent?.id, - selectedId: selectedComponent?.id, - currentPosition: dragState.currentPosition, - }); + // console.log("🎯 렌더링 중 드래그 상태 감지:", { + // isDragging: dragState.isDragging, + // draggedId: dragState.draggedComponent?.id, + // selectedId: selectedComponent?.id, + // currentPosition: dragState.currentPosition, + // }); const newPosition = { x: dragState.currentPosition.x, @@ -379,10 +379,10 @@ const PropertiesPanelComponent: React.FC = ({ // 위치가 변경되었는지 확인 if (lastDragPosition.x !== newPosition.x || lastDragPosition.y !== newPosition.y) { - console.log("🔄 위치 변경 감지됨:", { - oldPosition: lastDragPosition, - newPosition: newPosition, - }); + // console.log("🔄 위치 변경 감지됨:", { + // oldPosition: lastDragPosition, + // newPosition: newPosition, + // }); // 다음 렌더링 사이클에서 업데이트 setTimeout(() => { setLastDragPosition(newPosition); @@ -542,7 +542,7 @@ const PropertiesPanelComponent: React.FC = ({ value={localInputs.placeholder} onChange={(e) => { const newValue = e.target.value; - console.log("🔄 placeholder 변경:", newValue); + // console.log("🔄 placeholder 변경:", newValue); setLocalInputs((prev) => ({ ...prev, placeholder: newValue })); onUpdateProperty("placeholder", newValue); }} @@ -610,7 +610,7 @@ const PropertiesPanelComponent: React.FC = ({ const isDragging = dragState?.isDragging && dragState.draggedComponent?.id === selectedComponent?.id; if (isDragging) { const realTimeX = Math.round(dragState.currentPosition.x); - console.log("🔥 실시간 X 렌더링:", realTimeX, "forceRender:", forceRender); + // console.log("🔥 실시간 X 렌더링:", realTimeX, "forceRender:", forceRender); return realTimeX.toString(); } return localInputs.positionX; @@ -640,7 +640,7 @@ const PropertiesPanelComponent: React.FC = ({ const isDragging = dragState?.isDragging && dragState.draggedComponent?.id === selectedComponent?.id; if (isDragging) { const realTimeY = Math.round(dragState.currentPosition.y); - console.log("🔥 실시간 Y 렌더링:", realTimeY, "forceRender:", forceRender); + // console.log("🔥 실시간 Y 렌더링:", realTimeY, "forceRender:", forceRender); return realTimeY.toString(); } return localInputs.positionY; @@ -770,7 +770,7 @@ const PropertiesPanelComponent: React.FC = ({ id="labelDisplay" checked={localInputs.labelDisplay} onChange={(e) => { - console.log("🔄 라벨 표시 변경:", e.target.checked); + // console.log("🔄 라벨 표시 변경:", e.target.checked); setLocalInputs((prev) => ({ ...prev, labelDisplay: e.target.checked })); onUpdateProperty("style.labelDisplay", e.target.checked); }} @@ -788,7 +788,7 @@ const PropertiesPanelComponent: React.FC = ({ value={localInputs.labelText} onChange={(e) => { const newValue = e.target.value; - console.log("🔄 라벨 텍스트 변경:", newValue); + // console.log("🔄 라벨 텍스트 변경:", newValue); setLocalInputs((prev) => ({ ...prev, labelText: newValue })); // 기본 라벨과 스타일 라벨을 모두 업데이트 onUpdateProperty("label", newValue); diff --git a/frontend/components/screen/panels/TemplatesPanel.tsx b/frontend/components/screen/panels/TemplatesPanel.tsx index 49c7b974..3c2ca768 100644 --- a/frontend/components/screen/panels/TemplatesPanel.tsx +++ b/frontend/components/screen/panels/TemplatesPanel.tsx @@ -446,7 +446,7 @@ export const TemplatesPanel: React.FC = ({ onDragStart }) = const dynamicTemplates = React.useMemo(() => { if (error || !dbTemplates) { // 오류 발생 시 폴백 템플릿 사용 - console.warn("템플릿 로딩 실패, 폴백 템플릿 사용:", error); + // console.warn("템플릿 로딩 실패, 폴백 템플릿 사용:", error); return fallbackTemplates; } diff --git a/frontend/components/screen/panels/webtype-configs/CheckboxTypeConfigPanel.tsx b/frontend/components/screen/panels/webtype-configs/CheckboxTypeConfigPanel.tsx index cdda13f6..72910b32 100644 --- a/frontend/components/screen/panels/webtype-configs/CheckboxTypeConfigPanel.tsx +++ b/frontend/components/screen/panels/webtype-configs/CheckboxTypeConfigPanel.tsx @@ -89,13 +89,13 @@ export const CheckboxTypeConfigPanel: React.FC = ( }; const newConfig = JSON.parse(JSON.stringify(currentValues)); - console.log("☑️ CheckboxTypeConfig 업데이트:", { - key, - value, - oldConfig: safeConfig, - newConfig, - localValues, - }); + // console.log("☑️ CheckboxTypeConfig 업데이트:", { + // key, + // value, + // oldConfig: safeConfig, + // newConfig, + // localValues, + // }); setTimeout(() => { onConfigChange(newConfig); diff --git a/frontend/components/screen/panels/webtype-configs/CodeTypeConfigPanel.tsx b/frontend/components/screen/panels/webtype-configs/CodeTypeConfigPanel.tsx index b4ba3f98..5e23b3ef 100644 --- a/frontend/components/screen/panels/webtype-configs/CodeTypeConfigPanel.tsx +++ b/frontend/components/screen/panels/webtype-configs/CodeTypeConfigPanel.tsx @@ -104,12 +104,12 @@ export const CodeTypeConfigPanel: React.FC = ({ config // 실제 config 업데이트 const newConfig = { ...safeConfig, [key]: value }; - console.log("💻 CodeTypeConfig 업데이트:", { - key, - value, - oldConfig: safeConfig, - newConfig, - }); + // console.log("💻 CodeTypeConfig 업데이트:", { + // key, + // value, + // oldConfig: safeConfig, + // newConfig, + // }); onConfigChange(newConfig); }; diff --git a/frontend/components/screen/panels/webtype-configs/DateTypeConfigPanel.tsx b/frontend/components/screen/panels/webtype-configs/DateTypeConfigPanel.tsx index 77b8b6b4..1e30def2 100644 --- a/frontend/components/screen/panels/webtype-configs/DateTypeConfigPanel.tsx +++ b/frontend/components/screen/panels/webtype-configs/DateTypeConfigPanel.tsx @@ -26,10 +26,10 @@ export const DateTypeConfigPanel: React.FC = ({ config // 로컬 상태로 실시간 입력 관리 const [localValues, setLocalValues] = useState(() => { - console.log("📅 DateTypeConfigPanel 초기 상태 설정:", { - config, - safeConfig, - }); + // console.log("📅 DateTypeConfigPanel 초기 상태 설정:", { + // config, + // safeConfig, + // }); return { format: safeConfig.format, @@ -46,23 +46,23 @@ export const DateTypeConfigPanel: React.FC = ({ config // config가 실제로 존재하고 의미있는 데이터가 있을 때만 업데이트 const hasValidConfig = config && Object.keys(config).length > 0; - console.log("📅 DateTypeConfigPanel config 변경 감지:", { - config, - configExists: !!config, - configKeys: config ? Object.keys(config) : [], - hasValidConfig, - safeConfig, - safeConfigKeys: Object.keys(safeConfig), - currentLocalValues: localValues, - configStringified: JSON.stringify(config), - safeConfigStringified: JSON.stringify(safeConfig), - willUpdateLocalValues: hasValidConfig, - timestamp: new Date().toISOString(), - }); + // console.log("📅 DateTypeConfigPanel config 변경 감지:", { + // config, + // configExists: !!config, + // configKeys: config ? Object.keys(config) : [], + // hasValidConfig, + // safeConfig, + // safeConfigKeys: Object.keys(safeConfig), + // currentLocalValues: localValues, + // configStringified: JSON.stringify(config), + // safeConfigStringified: JSON.stringify(safeConfig), + // willUpdateLocalValues: hasValidConfig, + // timestamp: new Date().toISOString(), + // }); // config가 없거나 비어있으면 로컬 상태를 유지 if (!hasValidConfig) { - console.log("⚠️ config가 없거나 비어있음 - 로컬 상태 유지"); + // console.log("⚠️ config가 없거나 비어있음 - 로컬 상태 유지"); return; } @@ -84,25 +84,25 @@ export const DateTypeConfigPanel: React.FC = ({ config localValues.minDate !== newLocalValues.minDate || localValues.maxDate !== newLocalValues.maxDate; - console.log("🔄 로컬 상태 업데이트 검사:", { - oldLocalValues: localValues, - newLocalValues, - hasChanges, - changes: { - format: localValues.format !== newLocalValues.format, - showTime: localValues.showTime !== newLocalValues.showTime, - defaultValue: localValues.defaultValue !== newLocalValues.defaultValue, - placeholder: localValues.placeholder !== newLocalValues.placeholder, - minDate: localValues.minDate !== newLocalValues.minDate, - maxDate: localValues.maxDate !== newLocalValues.maxDate, - }, - }); + // console.log("🔄 로컬 상태 업데이트 검사:", { + // oldLocalValues: localValues, + // newLocalValues, + // hasChanges, + // changes: { + // format: localValues.format !== newLocalValues.format, + // showTime: localValues.showTime !== newLocalValues.showTime, + // defaultValue: localValues.defaultValue !== newLocalValues.defaultValue, + // placeholder: localValues.placeholder !== newLocalValues.placeholder, + // minDate: localValues.minDate !== newLocalValues.minDate, + // maxDate: localValues.maxDate !== newLocalValues.maxDate, + // }, + // }); if (hasChanges) { - console.log("✅ 로컬 상태 업데이트 실행"); + // console.log("✅ 로컬 상태 업데이트 실행"); setLocalValues(newLocalValues); } else { - console.log("⏭️ 변경사항 없음 - 로컬 상태 유지"); + // console.log("⏭️ 변경사항 없음 - 로컬 상태 유지"); } }, [JSON.stringify(config)]); @@ -112,36 +112,36 @@ export const DateTypeConfigPanel: React.FC = ({ config // 실제 config 업데이트 - 현재 로컬 상태를 기반으로 새 객체 생성 (safeConfig 기본값 덮어쓰기 방지) const newConfig = JSON.parse(JSON.stringify({ ...localValues, [key]: value })); - console.log("📅 DateTypeConfig 업데이트:", { - key, - value, - oldConfig: safeConfig, - newConfig, - localValues, - timestamp: new Date().toISOString(), - changes: { - format: newConfig.format !== safeConfig.format, - showTime: newConfig.showTime !== safeConfig.showTime, - placeholder: newConfig.placeholder !== safeConfig.placeholder, - minDate: newConfig.minDate !== safeConfig.minDate, - maxDate: newConfig.maxDate !== safeConfig.maxDate, - defaultValue: newConfig.defaultValue !== safeConfig.defaultValue, - }, - willCallOnConfigChange: true, - }); + // console.log("📅 DateTypeConfig 업데이트:", { + // key, + // value, + // oldConfig: safeConfig, + // newConfig, + // localValues, + // timestamp: new Date().toISOString(), + // changes: { + // format: newConfig.format !== safeConfig.format, + // showTime: newConfig.showTime !== safeConfig.showTime, + // placeholder: newConfig.placeholder !== safeConfig.placeholder, + // minDate: newConfig.minDate !== safeConfig.minDate, + // maxDate: newConfig.maxDate !== safeConfig.maxDate, + // defaultValue: newConfig.defaultValue !== safeConfig.defaultValue, + // }, + // willCallOnConfigChange: true, + // }); - console.log("🔄 onConfigChange 호출 직전:", { - newConfig, - configStringified: JSON.stringify(newConfig), - }); + // console.log("🔄 onConfigChange 호출 직전:", { + // newConfig, + // configStringified: JSON.stringify(newConfig), + // }); // 약간의 지연을 두고 업데이트 (배치 업데이트 방지) setTimeout(() => { - console.log("✅ onConfigChange 호출 완료:", { - key, - newConfig, - timestamp: new Date().toISOString(), - }); + // console.log("✅ onConfigChange 호출 완료:", { + // key, + // newConfig, + // timestamp: new Date().toISOString(), + // }); onConfigChange(newConfig); }, 0); }; @@ -156,11 +156,11 @@ export const DateTypeConfigPanel: React.FC = ({ config