From 2da037171261e349b723a486b69fb68f4c03a9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A0=95=EC=9E=AC=EC=9B=85?= Date: Thu, 18 Dec 2025 09:28:44 +0900 Subject: [PATCH] =?UTF-8?q?'=EC=88=98=EC=A3=BC=EB=B6=80=ED=84=B0=EC=B6=9C?= =?UTF-8?q?=ED=95=98=EA=B9=8C=EC=A7=80'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 13 +- .gitignore | 155 + CLAUDE.md | 9 + mes기획서_리액트/.claude/CLAUDE.md | 673 + mes기획서_리액트/.claude/settings.local.json | 61 + mes기획서_리액트/FINAL_TEST_REPORT.txt | 178 + mes기획서_리액트/PLAYWRIGHT_TEST_REPORT.txt | 247 + .../TEST_MENU_DETAILED_RESULT.txt | 56 + mes기획서_리액트/TEST_MENU_FINAL_RESULT.txt | 80 + mes기획서_리액트/TEST_MENU_RESULT.txt | 76 + mes기획서_리액트/TEST_REPORT.md | 141 + mes기획서_리액트/TEST_SUMMARY.txt | 141 + mes기획서_리액트/TEST_SUMMARY_REPORT.md | 300 + mes기획서_리액트/browser_test.js | 54 + mes기획서_리액트/browser_test.png | Bin 0 -> 4253 bytes mes기획서_리액트/build/asset-manifest.json | 13 + mes기획서_리액트/build/index.html | 1 + .../build/static/css/main.064d61cb.css | 2 + .../build/static/css/main.064d61cb.css.map | 1 + .../build/static/js/main.73ec66f8.js | 3 + .../build/static/js/main.73ec66f8.js.LICENSE.txt | 59 + .../build/static/js/main.73ec66f8.js.map | 1 + .../claudedocs/e2e_process_validation_20251216.md | 1040 + .../claudedocs/git-conflict-analysis.md | 155 + .../research_mes_erp_solutions_20251215.md | 1008 + .../claudedocs/기능정의서_작업지시관리.md | 427 + mes기획서_리액트/debug1.png | Bin 0 -> 4253 bytes mes기획서_리액트/debug_final.png | Bin 0 -> 4253 bytes mes기획서_리액트/error.png | Bin 0 -> 4253 bytes mes기획서_리액트/final_test.js | 200 + mes기획서_리액트/find_menus.js | 49 + mes기획서_리액트/inspect_page.js | 62 + mes기획서_리액트/package.json | 31 + mes기획서_리액트/page_structure.html | 37 + mes기획서_리액트/public/index.html | 285 + mes기획서_리액트/run-test.js | 88 + .../screenshots-basis/거래처기준관리.png | Bin 0 -> 53910 bytes .../screenshots-basis/검사기준관리.png | Bin 0 -> 54103 bytes .../screenshots-basis/공정기준관리.png | Bin 0 -> 57520 bytes .../screenshots-basis/품목기준관리.png | Bin 0 -> 59995 bytes .../screenshots-basis/현장기준관리.png | Bin 0 -> 54135 bytes mes기획서_리액트/scripts/auto-commit.js | 101 + mes기획서_리액트/scripts/auto-commit.log | 14342 +++ mes기획서_리액트/src/App.jsx | 80049 ++++++++++++++++ .../src/components/AllMenuFeatureDocPanel.jsx | 653 + .../src/components/BusinessFlowChart.jsx | 676 + .../src/components/CommonUXGuide.jsx | 2382 + .../src/components/CompleteIntegrationTestTab.jsx | 537 + .../src/components/ComprehensiveFlowPanel.jsx | 494 + .../src/components/DetailedFlowDiagram.jsx | 423 + .../src/components/DetailedProcessFlowChart.jsx | 1104 + .../src/components/FeatureBadgeOverlay.jsx | 337 + .../src/components/FeatureDocPanel.jsx | 458 + .../src/components/PolicyGuide.jsx | 807 + .../src/components/PriceListSimple.jsx | 582 + .../src/components/ProcessFlowChart.jsx | 519 + .../src/components/ProcessIntegrationTestTab.jsx | 597 + .../src/components/ProductionUserFlow.jsx | 3096 + .../src/components/QuoteDetailNew.jsx | 481 + .../src/components/QuoteDocumentDialogs.jsx | 473 + .../src/components/UserFlowChartViewer.jsx | 479 + .../src/components/UserFlowNavigator.jsx | 1299 + .../src/components/UserFlowPanel.jsx | 1128 + mes기획서_리액트/src/configs/bomConfig.js | 456 + .../src/configs/businessFlowConfig.js | 447 + .../src/configs/codeRuleConfig.js | 506 + mes기획서_리액트/src/configs/commonSchema.js | 84 + .../src/configs/comprehensiveMenuFeatures.js | 1335 + .../src/configs/costCalculationConfig.js | 529 + .../src/configs/customerMasterConfig.js | 225 + .../src/configs/defectWorkflowConfig.js | 437 + .../src/configs/documentTemplateConfig.js | 4645 + .../src/configs/e2eTestDataConfig.js | 944 + .../src/configs/featureDefinitions.js | 2484 + mes기획서_리액트/src/configs/index.js | 60 + .../src/configs/inspectionMasterConfig.js | 561 + .../src/configs/itemMasterConfig.js | 1119 + mes기획서_리액트/src/configs/lotFifoConfig.js | 340 + .../src/configs/menuDefinitions.js | 149 + .../src/configs/numberRuleConfig.js | 258 + .../src/configs/orderMasterConfig.js | 160 + .../src/configs/outboundMasterConfig.js | 395 + mes기획서_리액트/src/configs/policyConfig.js | 528 + .../src/configs/processMasterConfig.js | 496 + .../src/configs/productionKpiConfig.js | 549 + .../src/configs/productionMasterConfig.js | 530 + .../src/configs/qualityEnhancementConfig.js | 274 + .../src/configs/safetyStockConfig.js | 463 + .../src/configs/screenActionDefinitions.js | 1701 + .../src/configs/screenFeatureDefinitions.js | 1393 + .../src/configs/screenFeatureDocuments.js | 1782 + .../src/configs/screenFeatureTemplates.js | 2319 + .../src/configs/siteMasterConfig.js | 220 + mes기획서_리액트/src/configs/tenantConfig.js | 1157 + .../src/configs/userFlowPatterns.js | 757 + mes기획서_리액트/src/e2eTestUtils.js | 350 + mes기획서_리액트/src/index.js | 10 + .../src/utils/mesCompleteIntegration.js | 1476 + .../src/utils/mesFullIntegrationTest.js | 1106 + .../src/utils/mesIntegrationUtils.js | 927 + .../src/utils/mesRealProcessTest.js | 1333 + .../src/utils/processIntegrationTest.js | 1195 + mes기획서_리액트/step1_menu.png | Bin 0 -> 4253 bytes mes기획서_리액트/step2_tab.png | Bin 0 -> 4253 bytes .../temp_backup/sam-mes-system_4.jsx | 26801 ++++++ mes기획서_리액트/test-basis-management-v2.js | 105 + mes기획서_리액트/test-basis-management-v3.js | 100 + mes기획서_리액트/test-basis-management.js | 107 + mes기획서_리액트/test-detailed.js | 155 + mes기획서_리액트/test-final.js | 151 + mes기획서_리액트/test-integration.js | 579 + mes기획서_리액트/test-menu-correct.js | 219 + mes기획서_리액트/test-menu-detailed.js | 233 + mes기획서_리액트/test-menu.js | 177 + mes기획서_리액트/test-production.js | 62 + .../01-step1-login-page.png | Bin 0 -> 83179 bytes .../02-step2-after-login.png | Bin 0 -> 83000 bytes .../03-step3-menu-expanded.png | Bin 0 -> 82723 bytes .../04-step6-품목기준관리.png | Bin 0 -> 82355 bytes .../05-step7-공정기준관리.png | Bin 0 -> 82421 bytes .../06-step8-검사기준관리.png | Bin 0 -> 82421 bytes .../07-step9-거래처기준관리.png | Bin 0 -> 82244 bytes .../08-step10-현장기준관리.png | Bin 0 -> 82421 bytes .../01-01-after-click-standard-info.png | Bin 0 -> 82705 bytes .../test-screenshots-menu/01-step1-login-page.png | Bin 0 -> 83179 bytes .../test-screenshots-menu/02-step2-after-login.png | Bin 0 -> 83179 bytes .../03-step3-menu-expanded.png | Bin 0 -> 82705 bytes .../test-screenshots-menu/04-step6-품목기준관리.png | Bin 0 -> 82705 bytes .../test-screenshots-menu/05-step7-공정기준관리.png | Bin 0 -> 82705 bytes .../test-screenshots-menu/06-step8-검사기준관리.png | Bin 0 -> 82528 bytes .../07-step9-거래처기준관리.png | Bin 0 -> 82705 bytes .../08-step10-현장기준관리.png | Bin 0 -> 82528 bytes .../test-screenshots/01-01-initial-page.png | Bin 0 -> 83187 bytes .../test-screenshots/01-step1-initial-page.png | Bin 0 -> 83187 bytes .../test-screenshots/02-02-initial-buttons.png | Bin 0 -> 83187 bytes .../test-screenshots/02-step2-after-menu-click.png | Bin 0 -> 74814 bytes .../test-screenshots/03-step3-found-customer.png | Bin 0 -> 69940 bytes .../04-step4-found-production-button.png | Bin 0 -> 69944 bytes .../05-step4-after-click-production.png | Bin 0 -> 67974 bytes .../test-screenshots/06-step5-final-status.png | Bin 0 -> 67844 bytes mes기획서_리액트/test-workflow.js | 495 + mes기획서_리액트/test.js | 28 + mes기획서_리액트/test_final.js | 50 + mes기획서_리액트/test_menu_complete.js | 126 + mes기획서_리액트/test_menu_structure.js | 142 + mes기획서_리액트/test_quote.js | 137 + mes기획서_리액트/test_quote2.js | 136 + mes기획서_리액트/test_result_report.txt | 44 + mes기획서_리액트/test_results.png | Bin 0 -> 104106 bytes mes기획서_리액트/test_results.txt | 13 + mes기획서_리액트/test_results_1.png | Bin 0 -> 103453 bytes .../test_screenshots/01_initial_page.png | Bin 0 -> 80599 bytes .../test_screenshots/02_menu_expanded.png | Bin 0 -> 79445 bytes .../test_screenshots/02_menu_visible.png | Bin 0 -> 80599 bytes .../test_screenshots/03_거래처기준관리.png | Bin 0 -> 56589 bytes .../test_screenshots/03_검사기준관리.png | Bin 0 -> 56987 bytes .../test_screenshots/03_공정기준관리.png | Bin 0 -> 59999 bytes .../test_screenshots/03_품목기준관리.png | Bin 0 -> 62986 bytes .../test_screenshots/03_현장기준관리.png | Bin 0 -> 56726 bytes .../test_screenshots/04_final_state.png | Bin 0 -> 56726 bytes .../test_screenshots/inspect_login_page.png | Bin 0 -> 80599 bytes mes기획서_리액트/test_with_correct_tabs.js | 195 + mes기획서_리액트/verify_wl_stk.js | 55 + 163 files changed, 180472 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 mes기획서_리액트/.claude/CLAUDE.md create mode 100644 mes기획서_리액트/.claude/settings.local.json create mode 100644 mes기획서_리액트/FINAL_TEST_REPORT.txt create mode 100644 mes기획서_리액트/PLAYWRIGHT_TEST_REPORT.txt create mode 100644 mes기획서_리액트/TEST_MENU_DETAILED_RESULT.txt create mode 100644 mes기획서_리액트/TEST_MENU_FINAL_RESULT.txt create mode 100644 mes기획서_리액트/TEST_MENU_RESULT.txt create mode 100644 mes기획서_리액트/TEST_REPORT.md create mode 100644 mes기획서_리액트/TEST_SUMMARY.txt create mode 100644 mes기획서_리액트/TEST_SUMMARY_REPORT.md create mode 100644 mes기획서_리액트/browser_test.js create mode 100644 mes기획서_리액트/browser_test.png create mode 100644 mes기획서_리액트/build/asset-manifest.json create mode 100644 mes기획서_리액트/build/index.html create mode 100644 mes기획서_리액트/build/static/css/main.064d61cb.css create mode 100644 mes기획서_리액트/build/static/css/main.064d61cb.css.map create mode 100644 mes기획서_리액트/build/static/js/main.73ec66f8.js create mode 100644 mes기획서_리액트/build/static/js/main.73ec66f8.js.LICENSE.txt create mode 100644 mes기획서_리액트/build/static/js/main.73ec66f8.js.map create mode 100644 mes기획서_리액트/claudedocs/e2e_process_validation_20251216.md create mode 100644 mes기획서_리액트/claudedocs/git-conflict-analysis.md create mode 100644 mes기획서_리액트/claudedocs/research_mes_erp_solutions_20251215.md create mode 100644 mes기획서_리액트/claudedocs/기능정의서_작업지시관리.md create mode 100644 mes기획서_리액트/debug1.png create mode 100644 mes기획서_리액트/debug_final.png create mode 100644 mes기획서_리액트/error.png create mode 100644 mes기획서_리액트/final_test.js create mode 100644 mes기획서_리액트/find_menus.js create mode 100644 mes기획서_리액트/inspect_page.js create mode 100644 mes기획서_리액트/package.json create mode 100644 mes기획서_리액트/page_structure.html create mode 100644 mes기획서_리액트/public/index.html create mode 100644 mes기획서_리액트/run-test.js create mode 100644 mes기획서_리액트/screenshots-basis/거래처기준관리.png create mode 100644 mes기획서_리액트/screenshots-basis/검사기준관리.png create mode 100644 mes기획서_리액트/screenshots-basis/공정기준관리.png create mode 100644 mes기획서_리액트/screenshots-basis/품목기준관리.png create mode 100644 mes기획서_리액트/screenshots-basis/현장기준관리.png create mode 100644 mes기획서_리액트/scripts/auto-commit.js create mode 100644 mes기획서_리액트/scripts/auto-commit.log create mode 100644 mes기획서_리액트/src/App.jsx create mode 100644 mes기획서_리액트/src/components/AllMenuFeatureDocPanel.jsx create mode 100644 mes기획서_리액트/src/components/BusinessFlowChart.jsx create mode 100644 mes기획서_리액트/src/components/CommonUXGuide.jsx create mode 100644 mes기획서_리액트/src/components/CompleteIntegrationTestTab.jsx create mode 100644 mes기획서_리액트/src/components/ComprehensiveFlowPanel.jsx create mode 100644 mes기획서_리액트/src/components/DetailedFlowDiagram.jsx create mode 100644 mes기획서_리액트/src/components/DetailedProcessFlowChart.jsx create mode 100644 mes기획서_리액트/src/components/FeatureBadgeOverlay.jsx create mode 100644 mes기획서_리액트/src/components/FeatureDocPanel.jsx create mode 100644 mes기획서_리액트/src/components/PolicyGuide.jsx create mode 100644 mes기획서_리액트/src/components/PriceListSimple.jsx create mode 100644 mes기획서_리액트/src/components/ProcessFlowChart.jsx create mode 100644 mes기획서_리액트/src/components/ProcessIntegrationTestTab.jsx create mode 100644 mes기획서_리액트/src/components/ProductionUserFlow.jsx create mode 100644 mes기획서_리액트/src/components/QuoteDetailNew.jsx create mode 100644 mes기획서_리액트/src/components/QuoteDocumentDialogs.jsx create mode 100644 mes기획서_리액트/src/components/UserFlowChartViewer.jsx create mode 100644 mes기획서_리액트/src/components/UserFlowNavigator.jsx create mode 100644 mes기획서_리액트/src/components/UserFlowPanel.jsx create mode 100644 mes기획서_리액트/src/configs/bomConfig.js create mode 100644 mes기획서_리액트/src/configs/businessFlowConfig.js create mode 100644 mes기획서_리액트/src/configs/codeRuleConfig.js create mode 100644 mes기획서_리액트/src/configs/commonSchema.js create mode 100644 mes기획서_리액트/src/configs/comprehensiveMenuFeatures.js create mode 100644 mes기획서_리액트/src/configs/costCalculationConfig.js create mode 100644 mes기획서_리액트/src/configs/customerMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/defectWorkflowConfig.js create mode 100644 mes기획서_리액트/src/configs/documentTemplateConfig.js create mode 100644 mes기획서_리액트/src/configs/e2eTestDataConfig.js create mode 100644 mes기획서_리액트/src/configs/featureDefinitions.js create mode 100644 mes기획서_리액트/src/configs/index.js create mode 100644 mes기획서_리액트/src/configs/inspectionMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/itemMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/lotFifoConfig.js create mode 100644 mes기획서_리액트/src/configs/menuDefinitions.js create mode 100644 mes기획서_리액트/src/configs/numberRuleConfig.js create mode 100644 mes기획서_리액트/src/configs/orderMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/outboundMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/policyConfig.js create mode 100644 mes기획서_리액트/src/configs/processMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/productionKpiConfig.js create mode 100644 mes기획서_리액트/src/configs/productionMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/qualityEnhancementConfig.js create mode 100644 mes기획서_리액트/src/configs/safetyStockConfig.js create mode 100644 mes기획서_리액트/src/configs/screenActionDefinitions.js create mode 100644 mes기획서_리액트/src/configs/screenFeatureDefinitions.js create mode 100644 mes기획서_리액트/src/configs/screenFeatureDocuments.js create mode 100644 mes기획서_리액트/src/configs/screenFeatureTemplates.js create mode 100644 mes기획서_리액트/src/configs/siteMasterConfig.js create mode 100644 mes기획서_리액트/src/configs/tenantConfig.js create mode 100644 mes기획서_리액트/src/configs/userFlowPatterns.js create mode 100644 mes기획서_리액트/src/e2eTestUtils.js create mode 100644 mes기획서_리액트/src/index.js create mode 100644 mes기획서_리액트/src/utils/mesCompleteIntegration.js create mode 100644 mes기획서_리액트/src/utils/mesFullIntegrationTest.js create mode 100644 mes기획서_리액트/src/utils/mesIntegrationUtils.js create mode 100644 mes기획서_리액트/src/utils/mesRealProcessTest.js create mode 100644 mes기획서_리액트/src/utils/processIntegrationTest.js create mode 100644 mes기획서_리액트/step1_menu.png create mode 100644 mes기획서_리액트/step2_tab.png create mode 100644 mes기획서_리액트/temp_backup/sam-mes-system_4.jsx create mode 100644 mes기획서_리액트/test-basis-management-v2.js create mode 100644 mes기획서_리액트/test-basis-management-v3.js create mode 100644 mes기획서_리액트/test-basis-management.js create mode 100644 mes기획서_리액트/test-detailed.js create mode 100644 mes기획서_리액트/test-final.js create mode 100644 mes기획서_리액트/test-integration.js create mode 100644 mes기획서_리액트/test-menu-correct.js create mode 100644 mes기획서_리액트/test-menu-detailed.js create mode 100644 mes기획서_리액트/test-menu.js create mode 100644 mes기획서_리액트/test-production.js create mode 100644 mes기획서_리액트/test-screenshots-correct/01-step1-login-page.png create mode 100644 mes기획서_리액트/test-screenshots-correct/02-step2-after-login.png create mode 100644 mes기획서_리액트/test-screenshots-correct/03-step3-menu-expanded.png create mode 100644 mes기획서_리액트/test-screenshots-correct/04-step6-품목기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-correct/05-step7-공정기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-correct/06-step8-검사기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-correct/07-step9-거래처기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-correct/08-step10-현장기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-menu-detailed/01-01-after-click-standard-info.png create mode 100644 mes기획서_리액트/test-screenshots-menu/01-step1-login-page.png create mode 100644 mes기획서_리액트/test-screenshots-menu/02-step2-after-login.png create mode 100644 mes기획서_리액트/test-screenshots-menu/03-step3-menu-expanded.png create mode 100644 mes기획서_리액트/test-screenshots-menu/04-step6-품목기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-menu/05-step7-공정기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-menu/06-step8-검사기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-menu/07-step9-거래처기준관리.png create mode 100644 mes기획서_리액트/test-screenshots-menu/08-step10-현장기준관리.png create mode 100644 mes기획서_리액트/test-screenshots/01-01-initial-page.png create mode 100644 mes기획서_리액트/test-screenshots/01-step1-initial-page.png create mode 100644 mes기획서_리액트/test-screenshots/02-02-initial-buttons.png create mode 100644 mes기획서_리액트/test-screenshots/02-step2-after-menu-click.png create mode 100644 mes기획서_리액트/test-screenshots/03-step3-found-customer.png create mode 100644 mes기획서_리액트/test-screenshots/04-step4-found-production-button.png create mode 100644 mes기획서_리액트/test-screenshots/05-step4-after-click-production.png create mode 100644 mes기획서_리액트/test-screenshots/06-step5-final-status.png create mode 100644 mes기획서_리액트/test-workflow.js create mode 100644 mes기획서_리액트/test.js create mode 100644 mes기획서_리액트/test_final.js create mode 100644 mes기획서_리액트/test_menu_complete.js create mode 100644 mes기획서_리액트/test_menu_structure.js create mode 100644 mes기획서_리액트/test_quote.js create mode 100644 mes기획서_리액트/test_quote2.js create mode 100644 mes기획서_리액트/test_result_report.txt create mode 100644 mes기획서_리액트/test_results.png create mode 100644 mes기획서_리액트/test_results.txt create mode 100644 mes기획서_리액트/test_results_1.png create mode 100644 mes기획서_리액트/test_screenshots/01_initial_page.png create mode 100644 mes기획서_리액트/test_screenshots/02_menu_expanded.png create mode 100644 mes기획서_리액트/test_screenshots/02_menu_visible.png create mode 100644 mes기획서_리액트/test_screenshots/03_거래처기준관리.png create mode 100644 mes기획서_리액트/test_screenshots/03_검사기준관리.png create mode 100644 mes기획서_리액트/test_screenshots/03_공정기준관리.png create mode 100644 mes기획서_리액트/test_screenshots/03_품목기준관리.png create mode 100644 mes기획서_리액트/test_screenshots/03_현장기준관리.png create mode 100644 mes기획서_리액트/test_screenshots/04_final_state.png create mode 100644 mes기획서_리액트/test_screenshots/inspect_login_page.png create mode 100644 mes기획서_리액트/test_with_correct_tabs.js create mode 100644 mes기획서_리액트/verify_wl_stk.js diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 926e4c5..02bd6e7 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,18 @@ "permissions": { "allow": [ "Bash(git config:*)", - "Bash(git push http://jungjaewoong:12345678@114.203.209.83:3000/SamProject/sam-design.git main)" + "Bash(git push http://jungjaewoong:12345678@114.203.209.83:3000/SamProject/sam-design.git main)", + "Bash(git pull http://jungjaewoong:12345678@114.203.209.83:3000/SamProject/sam-design.git main --rebase)", + "Bash(git stash:*)", + "Bash(npm install:*)", + "Bash(npm run dev:*)", + "Bash(git add:*)", + "Bash(git commit -m \"$(cat <<''EOF''\n문서 추가: 기준정보 및 영업관리 모듈 가이드\n\n- master-data-modules.md: 기준정보 모듈 문서 추가\n- sales-management-modules.md: 영업관리 모듈 문서 추가\n- validation-usage.md: 유효성 검사 사용법 업데이트\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude \nEOF\n)\")", + "Bash(git fetch http://jungjaewoong:12345678@114.203.209.83:3000/SamProject/sam-design.git main)", + "Bash(git commit:*)", + "Bash(for file in QuoteManagement.tsx QuoteManagement3Write.tsx QuoteManagement3List.tsx QuoteManagement3Detail.tsx)", + "Bash(do echo '=== $file ===' diff 'c:/샘프로젝트_mvp_figma_react/MES Solution Website Structure 251202/src/components/$file' c:/샘프로젝트_mvp_figma_react/sam-design/src/components/$file)", + "Bash(git checkout:*)" ], "deny": [], "ask": [] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e2ead0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,155 @@ +############################################ +# Laravel +############################################ +/vendor/ +/node_modules/ +/bootstrap/cache/ +/storage/*.key +/storage/app/* +/storage/framework/* +/storage/logs/* +!storage/.gitignore +.env +.env.* +.phpunit.result.cache +Homestead.yaml +Homestead.json +npm-debug.log +yarn-error.log +vite.config.js +vite.config.ts +public/storage +public/hot +public/mix-manifest.json +public/build/ + +/storage/pail/ +public/js/*.map +public/css/*.map + +############################################ +# CodeIgniter (CI3 or CI4) +############################################ +/system/ +application/cache/* +application/logs/* +writable/cache/ +writable/logs/ +writable/session/ +writable/uploads/ +!application/cache/index.html +!application/logs/index.html + +############################################ +# IDE - PhpStorm +############################################ +.idea/ +/*.iml +*.iws +*.ipr + +############################################ +# IDE - VS Code +############################################ +.vscode/ + +############################################ +# IDE - Cursor AI +############################################ +.cursor/ + +############################################ +# OS & 에디터 임시 파일 +############################################ +.DS_Store +Thumbs.db +ehthumbs.db +desktop.ini +*.swp +*.swo +*.tmp +*.bak +*.old +*.orig + +############################################ +# 로그, 백업, 덤프 +############################################ +*.log +*.sql +*.sqlite +*.db +*.tar +*.gz +*.zip +*.7z +*.backup + +# 프로젝트 내 백업 폴더 +/backup/ +/backups/ + +############################################ +# 이미지, 문서, 동영상 등 업로드 제외 +*.jpg +*.jpeg +*.png +*.gif +*.bmp +*.svg +*.webp +*.ico + +*.pdf +*.doc +*.docx +*.xls +*.xlsx +*.ppt +*.pptx +*.hwp + +*.mp3 +*.wav +*.ogg +*.mp4 +*.avi +*.mov +*.wmv +*.mkv + +############################################ +# JetBrains Fleet / Laravel Nova / Zed IDE +############################################ +/.fleet/ +/.nova/ +/.zed/ + +############################################ +# PHP 도구 및 설정 파일 +############################################ +/.phpactor.json +/auth.json +/.phpunit.cache + + +############################################ +# 기타 +############################################ +.env.local +.env.backup +*.cache +*.coverage +*.out +*.pid +*.seed +*.seed.php +_ide_helper.php +_ide_helper_models.php + +# 모든 위치의 data 폴더 내부 파일 무시 +**/data/* +# 단, 폴더 자체는 추적 (비어 있어도 gitkeep을 위해) +!**/data/ +# 그리고 .gitkeep은 예외로 추적 +!**/data/.gitkeep diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8e07a9f --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,9 @@ +# 프로젝트 규칙 + +## Git 관련 +- `package-lock.json` 파일은 git에 커밋하지 않음 (`.gitignore`에 추가됨) +- 원격 저장소: http://114.203.209.83:3000/SamProject/sam-design.git + +## 개발 서버 +- `npm run dev`로 실행 +- 기본 포트: 3000 (또는 사용 가능한 다음 포트) diff --git a/mes기획서_리액트/.claude/CLAUDE.md b/mes기획서_리액트/.claude/CLAUDE.md new file mode 100644 index 0000000..9566ce3 --- /dev/null +++ b/mes기획서_리액트/.claude/CLAUDE.md @@ -0,0 +1,673 @@ +# SAM MES 프로젝트 스타일 규칙 + +이 프로젝트는 기획서/와이어프레임 용도로 제작되었습니다. 모든 작업에서 아래 스타일 규칙을 준수해야 합니다. + +## 필수 스타일 규칙 + +### 1. 그레이스케일 와이어프레임 +- 모든 UI 요소는 그레이스케일로 표시 +- 메인 컨테이너에 `filter: grayscale(100%)` 적용 +- 기능정의서 영역(FeatureBadgeOverlay, FeatureDescriptionPanel)은 그레이스케일 외부에 배치하여 컬러 유지 + +### 2. 폰트 색상 +- **모든 폰트 색상은 순수 검정색 #000000으로 적용** +- index.html의 전역 CSS: `body, body * { color: #000000 !important; }` + +### 3. 버튼 스타일 +- **색깔 버튼(primary, 파란색, 초록색 등)은 검정색 배경(#000000) + 흰색 텍스트(#ffffff)** +- **흰색/outline 버튼은 흰색 배경 + 검정색 텍스트(#000000)** +- index.html의 전역 CSS로 `.bg-blue-600`, `.bg-green-600` 등을 검정색으로 오버라이드 +- Hover 상태: `#333333` + +### 4. 기능 뱃지 색상 +- **C키로 추가하는 뱃지는 기본 빨간색(red) 적용** +- `addInlineBadge` 함수에서 `color: 'red'` 설정 +- 기능정의서 패널의 뱃지는 컬러로 표시 (그레이스케일 외부에 배치) + +### 5. 모달/다이얼로그 아이콘 규칙 +- **모달 및 다이얼로그 콘텐츠 영역에는 아이콘을 적용하지 않음** +- 기본 버튼(닫기 X 버튼 등)은 예외로 아이콘 허용 +- 섹션 헤더에 숫자 뱃지나 이모지 아이콘 사용 금지 +- 적용 대상 선택 등의 버튼에 이모지 아이콘 사용 금지 + +### 6. 페이지 타이틀 규칙 +- **페이지 타이틀은 "메뉴명 + 목록/등록/수정/상세" 형식으로 통일** +- "관리" 단어는 제거 (예: "견적관리 - 목록" → "견적 목록") +- 올바른 예시: + - 견적 목록, 견적 등록, 견적 상세 + - 수주 목록, 수주 등록, 수주 상세 + - 거래처 목록, 거래처 등록 + - 작업지시 목록, 작업지시 등록, 작업지시 수정, 작업지시 상세 + - 출하 목록, 출하 등록, 출하 상세, 출하 수정 + +### 7. 기능정의서 패널 아이콘 규칙 +- **기능정의서 패널 콘텐츠 영역에는 아이콘 사용 금지** +- 버튼형 아이콘만 허용 (Edit3, Database, Save, Download, Upload, Plus, Trash2, ChevronDown) +- 섹션 헤더(UI 정보, 기능 정보, 데이터 연동)에 아이콘 사용 금지 +- 빈 목록 안내 영역에 아이콘 사용 금지 + +### 8. 기능정의서 데이터 로컬 스토리지 저장 +- **기능정의서 뱃지 데이터는 항상 localStorage에 자동 저장** +- 저장 키: `featureBadges_current` (실시간 저장), `featureBadges_committed` (커밋된 버전) +- 브라우저 새로고침해도 데이터 유지 +- 자동 백업 옵션 제공 (매일 JSON 파일 다운로드) + +### 9. 기능정의서 뱃지 위치 규칙 +- **뱃지는 스크롤과 함께 UI 요소에 붙어서 이동해야 함** +- 뱃지 위치는 절대 픽셀 좌표(absoluteX, absoluteY)로 저장 +- 스크롤 컨테이너(main) 내부에 배치하여 스크롤 시 자연스럽게 따라다님 +- 레거시 호환을 위해 비율 좌표(x, y)도 함께 저장 + +### 10. 기능정의서 뱃지 색상 규칙 +- **기본 색상은 빨간색(#FF0000, red)** +- 사용자가 6가지 색상 중 선택 가능: 빨강, 파랑, 초록, 보라, 주황, 회색 +- 뱃지 추가/수정 시 색상 선택 UI 제공 +- 색상 정보는 뱃지 데이터의 `color` 속성에 저장 + +### 11. 기능정의서 패널 레이아웃 규칙 +- **기능정의서 패널은 화면을 밀고 나와야 함 (레이어 형태로 덮으면 안됨)** +- 패널은 메인 레이아웃의 flex 컨테이너 내부에 배치 +- 패널 너비: 320px (w-80) +- 패널 열림 시 메인 컨텐츠 영역이 줄어듦 + +### 12. 목록 페이지 공통 UX 규칙 +- **모든 목록 페이지는 체크박스 선택 + 동적 작업 컬럼 기능 포함** + +#### 목록 정렬 규칙 (필수) +- **기본 정렬: 번호 내림차순 (최신순)** +- 모든 목록은 **번호가 가장 높은 항목(최신 등록)이 최상단**에 위치 +- 예: QT-2025-100 → QT-2025-099 → QT-2025-001 순서 +- 날짜 기준이 아닌 **등록 번호(ID) 기준** 정렬 + +**정렬 구현 방법:** +```javascript +// 방법 1: ID 기준 내림차순 (권장) +const sortedData = [...data].sort((a, b) => b.id - a.id); + +// 방법 2: 문서번호 기준 내림차순 +const sortedData = [...data].sort((a, b) => b.documentNo.localeCompare(a.documentNo)); + +// 방법 3: 등록일시 기준 내림차순 +const sortedData = [...data].sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); +``` + +**적용 대상:** +- 견적 목록, 수주 목록, 출하 목록 +- 작업지시 목록, 검사 목록 +- 거래처 목록, 품목 목록 +- 모든 기준정보/마스터 목록 + +#### 목록 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리) +- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 우측 정렬) +- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지) +- **레이아웃 구성**: + ``` + ┌─────────────────────────────────────────────────────────────────┐ + │ [아이콘] 메뉴명 목록 │ + ├─────────────────────────────────────────────────────────────────┤ + │ ┌────────────┐ │ + │ │ + 메뉴 등록 │ │ + │ └────────────┘ │ + └─────────────────────────────────────────────────────────────────┘ + ``` + +- **컴포넌트 구조**: + ```jsx +
+ {/* 타이틀 영역 */} +

+ + 메뉴명 목록 +

+ {/* 버튼 영역 - 타이틀 아래, 우측 정렬 */} +
+ +
+
+ ``` + +- **스타일 규칙**: + - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지) + - 아이콘 색상: `text-blue-500` + - 아이콘 크기: `w-6 h-6` + - 버튼 영역: `flex items-center justify-end` (우측 정렬) + +#### 목록 페이지 리포트 카드 규칙 +- **카드 개수**: 정확히 4개의 리포트 카드만 표시 +- **레이아웃**: 한 줄에 4개 카드 (`grid grid-cols-4 gap-4`) +- **카드 구조**: + ```jsx +
+
+

라벨1

+

값1

+
+
+

라벨2

+

값2

+
+
+

라벨3

+

값3

+
+
+

라벨4

+

값4

+
+
+ ``` + +- **리포트 카드 예시**: + - 견적 목록: 이번 달 견적 금액, 진행중 견적 금액, 이번 주 신규 견적, 이번 달 수주 전환율 + - 수주 목록: 이번 달 수주 금액, 진행중 수주 건수, 이번 주 신규 수주, 완료 수주 건수 + - 작업지시 목록: 오늘 작업 건수, 진행중 건수, 완료 건수, 지연 건수 + - 재고 목록: 총 품목 수, 재고 부족 품목, 이번 달 입고, 이번 달 출고 + +#### 목록 페이지 검색 영역 규칙 +- **검색바 위치**: 리포트 카드 바로 아래, 테이블 위에 배치 +- **검색바 구조**: 한 줄로 길게 전체 너비 사용 (`w-full`) +- **레이아웃 구성**: + ``` + ┌─────────────────────────────────────────────────────────────────┐ + │ 🔍 검색어 입력 placeholder... │ + └─────────────────────────────────────────────────────────────────┘ + ``` + +- **컴포넌트 구조**: + ```jsx +
+
+ + setSearchTerm(e.target.value)} + /> +
+
+ ``` + +- **검색 placeholder 예시**: + - 견적 목록: "견적번호, 발주처, 담당자, 제품명, 현장코드, 현장명 검색..." + - 수주 목록: "수주번호, 거래처, 담당자, 제품명 검색..." + - 작업지시 목록: "작업지시번호, 현장명, 공정, 작업자 검색..." + - 재고 목록: "품목코드, 품목명, 창고, 위치 검색..." + +#### 목록 페이지 전체 레이아웃 순서 +``` +1. 헤더 (타이틀 + 등록 버튼) +2. 리포트 카드 4개 (한 줄) +3. 검색바 (한 줄, 전체 너비) +4. 테이블 (체크박스 + 데이터 + 작업 컬럼) +``` + +#### 선택 상태별 동작 (필수) +| 선택 개수 | 작업 컬럼 | 테이블 우측 상단 | 각 행 버튼 | +|----------|----------|----------------|----------| +| 0개 | 숨김 | - | - | +| 1개 | 표시 | - | 수정, 삭제 | +| 2개 이상 | 표시 | 선택 삭제 (N) 버튼 | 수정, 삭제 (각 행마다) | + +**핵심 동작 원칙:** +- 체크박스 선택 시 해당 행에만 수정/삭제 버튼 표시 +- 선택 해제 시 버튼 즉시 숨김 +- 작업 컬럼 헤더는 1개 이상 선택 시에만 표시 +- 선택되지 않은 행의 작업 컬럼은 빈 셀로 표시 + +**구현 코드 예시:** +```jsx +{/* 테이블 헤더 */} + + + + 번호 + 제목 + {/* ... 기타 컬럼 */} + {hasSelection && 작업} + + + +{/* 테이블 바디 */} + + {data.map(item => ( + + handleSelect(item.id)} /> + {item.no} + {item.title} + {/* ... 기타 컬럼 */} + {hasSelection && ( + + {isSelected(item.id) && ( +
+ + +
+ )} + + )} + + ))} + +``` + +#### 테이블 구조 +- 첫 번째 컬럼: 체크박스 (헤더에 전체선택) +- 마지막 컬럼: 작업 (1개 이상 선택 시에만 표시, 선택된 행에만 버튼 표시) +- 선택된 행: `bg-blue-50` 배경색 적용 +- 다중 선택(2개+) 시: 테이블 상단 우측에 "선택 삭제 (N)" 버튼 표시 + +#### useListSelection 훅 사용법 +**훅 위치**: `src/App.jsx` 라인 3368 + +**목록 컴포넌트에서 사용**: +```javascript +const { selectedIds, handleSelect, handleSelectAll, clearSelection, + isAllSelected, hasSelection, isMultiSelect, isSelected } = useListSelection(filteredData); +``` + +**반환값 설명**: +- `selectedIds`: 선택된 항목 ID 배열 +- `handleSelect(id)`: 단일 항목 선택/해제 +- `handleSelectAll(e)`: 전체 선택/해제 +- `clearSelection()`: 선택 초기화 +- `isAllSelected`: 전체 선택 여부 (boolean) +- `hasSelection`: 1개 이상 선택 여부 (boolean) +- `isMultiSelect`: 2개 이상 선택 여부 (boolean) +- `isSelected(id)`: 특정 항목 선택 여부 (function) + +### 13. 등록 페이지 공통 UX 규칙 +- **등록 페이지는 일관된 헤더 + 버튼 + 섹션 구조 사용** + +#### 등록 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리) +- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 우측 정렬) → 섹션 영역 +- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지) +- **레이아웃 구성**: + ``` + ┌─────────────────────────────────────────────────────────────────┐ + │ [아이콘] 메뉴명 등록 │ + ├─────────────────────────────────────────────────────────────────┤ + │ ┌────────┐ ┌────────────┐ │ + │ │ × 취소 │ │ 💾 저장 │ │ + │ └────────┘ └────────────┘ │ + ├─────────────────────────────────────────────────────────────────┤ + │ ┌─────────────────────────────────────────────────────────────┐ │ + │ │ 기본 정보 (섹션 타이틀) │ │ + │ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ │ + │ │ │ 필드1 │ │ 필드2 │ │ 필드3 │ │ │ + │ │ │ [입력값] │ │ [입력값] │ │ [입력값] │ │ │ + │ │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ + │ └─────────────────────────────────────────────────────────────┘ │ + └─────────────────────────────────────────────────────────────────┘ + ``` + +- **타이틀 영역**: + - 좌측에 아이콘 + 메뉴명 + "등록" 텍스트 + - 예시: `[FileText 아이콘] 견적 등록`, `[Users 아이콘] 거래처 등록` + +- **버튼 영역**: + - 타이틀 **아래 별도 줄**, 우측 정렬 + - 취소 버튼(outline) + 저장 버튼(primary) 순서 + - 취소 버튼: `variant="outline"` 또는 `variant="secondary"` + - 저장 버튼: `variant="primary"` (검정 배경) + +- **컴포넌트 구조**: + ```jsx +
+ {/* 헤더 영역 - 타이틀/버튼 분리 */} +
+ {/* 타이틀 영역 */} +

+ + 메뉴명 등록 +

+ {/* 버튼 영역 - 타이틀 아래, 우측 정렬 */} +
+ + +
+
+ + {/* 섹션 영역 */} + +
+ ... + ... + ... +
+
+
+ ``` + +- **스타일 규칙**: + - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지) + - 아이콘 색상: `text-blue-500` + - 아이콘 크기: `w-6 h-6` + - 버튼 영역: `flex items-center justify-end gap-2` (우측 정렬) + +#### 섹션 내 필드 반응형 그리드 규칙 (필수) +- **데스크탑(lg 이상)**: 3컬럼 (`lg:grid-cols-3`) +- **태블릿(md)**: 2컬럼 (`md:grid-cols-2`) +- **모바일(기본)**: 1컬럼 (`grid-cols-1`) +- **Tailwind 클래스**: `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4` + +#### 긴 필드 처리 +- 비고, 설명 등 긴 텍스트 필드는 `col-span-full` 또는 `lg:col-span-3`으로 전체 너비 사용 +- 예시: + ```jsx +
+ + + +
+ ``` + +#### 적용 대상 +- 견적 등록, 수주 등록, 거래처 등록, 품목 등록 +- 작업지시 등록, 출하 등록, 검사 등록 +- 모든 기준정보/마스터 등록 페이지 + +### 14. 상세 페이지 공통 UX 규칙 +- **상세 페이지는 섹션 기반 레이아웃 사용 (탭 사용 금지)** +- 정보 표시용 상세 페이지에서는 탭 대신 Card 섹션으로 모든 정보를 순차적으로 표시 +- 탭은 문서 전환(견적서/산출내역서/발주서 등)이나 목록 필터링에만 사용 + +#### 상세 페이지 헤더 레이아웃 규칙 (필수 - 타이틀/버튼 분리) +- **헤더 구조**: 타이틀 영역(위) → 버튼 영역(아래, 좌측:문서버튼 / 우측:액션버튼) +- **핵심 원칙**: 타이틀과 버튼은 반드시 **별도 줄**에 배치 (같은 줄 금지) +- **레이아웃 구성**: + ``` + ┌─────────────────────────────────────────────────────────────────┐ + │ [아이콘] 메뉴명 상세 │ + ├─────────────────────────────────────────────────────────────────┤ + │ ┌──────────────────┐ ┌──────────┐ ┌────────┐ │ + │ │ 📄 문서1 │ 📄 문서2 │ │ 목록 │ │ 수정 │ │ + │ └──────────────────┘ └──────────┘ └────────┘ │ + └─────────────────────────────────────────────────────────────────┘ + ``` + +- **타이틀 영역** (첫째 줄): + - 아이콘 + 메뉴명 + "상세" 텍스트 + - 상태 뱃지가 있을 경우 타이틀 옆에 배치 가능 + - 예시: `[FileText 아이콘] 견적 상세 [QT-2025-001] [최초작성]` + +- **버튼 영역** (둘째 줄): + - **좌측**: 관련 문서 출력/조회 버튼 (견적서, 산출내역서, 발주서, 작업지시서 등) + - **우측**: 페이지 액션 버튼 (목록, 수정, 최종확정, 삭제 등) + - 문서 버튼 스타일: `flex items-center gap-1 px-3 py-1.5 text-sm border rounded hover:bg-gray-50` + - 액션 버튼 스타일: `flex items-center gap-1 px-4 py-2 border rounded hover:bg-gray-50` + +- **컴포넌트 구조**: + ```jsx +
+ {/* 타이틀 영역 */} +
+

+ + 메뉴명 상세 +

+
+ QT-2025-001 + +
+
+ {/* 버튼 영역 - 좌측:문서버튼 / 우측:액션버튼 */} +
+ {/* 좌측: 문서 버튼 */} +
+ + +
+ {/* 우측: 액션 버튼 */} +
+ + +
+
+
+ ``` + +- **스타일 규칙**: + - 타이틀 폰트: `text-xl font-bold` (text-2xl 금지) + - 아이콘 색상: `text-blue-500` + - 아이콘 크기: `w-6 h-6` + - 버튼 영역: `flex items-center justify-between` (좌우 분리) + +- **적용 대상 상세 페이지**: + - 견적 상세: 견적서, 산출내역서, 발주서 | 목록, 수정, 최종확정 + - 수주 상세: 수주확인서, 작업지시서 | 목록, 수정 + - 작업지시 상세: 작업지시서 | 목록, 수정 + - 출하 상세: 출고증, 거래명세서 | 목록, 수정 + - 품질검사 상세: 검사성적서 | 목록, 수정 + - 거래처 상세: - | 목록, 수정, 삭제 + - 품목 상세: - | 목록, 수정, 삭제 + - 공정 상세: - | 목록, 수정, 삭제 + +#### 섹션 내 항목 반응형 그리드 규칙 +- **데스크탑(lg 이상)**: 3컬럼 (`lg:grid-cols-3`) +- **태블릿(md)**: 2컬럼 (`md:grid-cols-2`) +- **모바일(기본)**: 1컬럼 (`grid-cols-1`) +- Tailwind 클래스: `grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4` + +#### 적용 대상 +- 기본정보, 등록정보, 작업정보 등 필드-값 형태의 섹션 +- 공정관리 상세, 거래처 상세, 품목 상세 등 모든 마스터 상세 페이지 + +#### 예외 사항 +- 테이블/목록 형태의 섹션은 반응형 그리드 대신 스크롤 또는 카드 리스트 사용 +- 긴 텍스트(설명, 비고 등)는 필요시 `lg:col-span-3`으로 전체 너비 사용 가능 + +### 15. 채번관리 규칙 (문서번호 자동생성) +- **모든 문서번호는 정해진 채번 패턴에 따라 자동 생성** +- 채번 규칙은 `src/configs/documentTemplateConfig.js`의 `numberingRules`에 정의 +- 채번 설정 UI는 기준정보 > 채번관리 메뉴에서 관리 + +#### 문서유형별 채번 패턴 (필수) +| 문서유형 | 접두사 | 패턴 | 예시 | 리셋 주기 | +|---------|--------|------|------|----------| +| 견적서 | QT | QT-YYMMDD-## | QT-251216-01 | 일간 | +| 수주확인서 | SO | SO-YYMMDD-## | SO-251216-01 | 일간 | +| 출하지시서 | SL | SL-YYMMDD-## | SL-251216-01 | 일간 | +| 작업지시서 | WO | WO-YYMMDD-## | WO-251216-01 | 일간 | +| 작업지시서(스크린) | WO-SCR | WO-SCR-YYMMDD-## | WO-SCR-251216-01 | 일간 | +| 작업지시서(슬랫) | WO-SLT | WO-SLT-YYMMDD-## | WO-SLT-251216-01 | 일간 | +| 작업지시서(절곡) | WO-FLD | WO-FLD-YYMMDD-## | WO-FLD-251216-01 | 일간 | +| 수입검사 | IQC | IQC-YYMMDD-## | IQC-251216-01 | 일간 | +| 공정검사 | PQC | PQC-YYMMDD-## | PQC-251216-01 | 일간 | +| 최종검사 | FQC | FQC-YYMMDD-## | FQC-251216-01 | 일간 | +| 부적합보고서 | NCR | NCR-YYMMDD-## | NCR-251216-01 | 일간 | +| 작업일지(스크린) | WL-SCR | WL-SCR-YYMMDD-## | WL-SCR-251216-01 | 일간 | +| 작업일지(절곡) | WL-FLD | WL-FLD-YYMMDD-## | WL-FLD-251216-01 | 일간 | +| 작업일지(슬랫) | WL-SLT | WL-SLT-YYMMDD-## | WL-SLT-251216-01 | 일간 | +| 발주서 | PO | PO-YYMMDD-## | PO-251216-01 | 일간 | +| LOT번호 | LOT | LOT-YYYYMMDD-### | LOT-20251216-001 | 일간 | + +#### 채번 변수 설명 +| 변수 | 설명 | 예시 | +|------|------|------| +| YYYY | 4자리 연도 | 2025 | +| YY | 2자리 연도 | 25 | +| MM | 월 (01-12) | 12 | +| DD | 일 (01-31) | 16 | +| ## | 일련번호 (2자리) | 01, 02, 99 | +| ### | 일련번호 (3자리) | 001, 002, 999 | +| {TYPE} | 문서유형 코드 | QT, SO, WO | + +#### 채번 규칙 구현 +```javascript +// 문서번호 생성 함수 예시 +const generateDocumentNo = (type, date = new Date()) => { + const yy = String(date.getFullYear()).slice(-2); + const mm = String(date.getMonth() + 1).padStart(2, '0'); + const dd = String(date.getDate()).padStart(2, '0'); + const seq = getNextSequence(type, date); // 당일 순번 조회 + return `${type}-${yy}${mm}${dd}-${String(seq).padStart(2, '0')}`; +}; + +// 사용 예시 +const quoteNo = generateDocumentNo('QT'); // QT-251216-01 +const orderNo = generateDocumentNo('SO'); // SO-251216-01 +const workOrderNo = generateDocumentNo('WO-SCR'); // WO-SCR-251216-01 +``` + +### 16. 공통 코드관리 규칙 (품목코드/거래처코드/LOT번호) +- **모든 코드는 정해진 규칙에 따라 생성** +- 코드 규칙은 `src/configs/codeRuleConfig.js`에 정의 +- 코드 설정 UI는 기준정보 > 공통코드 메뉴에서 관리 + +#### 품목코드 체계 (품목유형별) +| 품목유형 | 패턴 | 예시 | 설명 | +|---------|------|------|------| +| 부자재 | {품목코드}-{규격} | SCR-0.3T | 품목코드와 규격 조합 | +| 원자재 | {품목코드}-{규격} | STEEL-1.2T | 품목코드와 규격 조합 | +| 소모품 | {품목명}-{규격} | 볼트-M8×20 | 품목명과 규격 조합 | +| 구매부품 | {품목코드}-{전원}-{용량} | E-220V-300KG | 품목, 전원, 용량 조합 | +| 조립부품 | {유형약어}{폭}{높이} | RC3040 | 약어+폭(백단위)+높이(백단위) | +| 절곡부품 | {유형약어}{폭}{높이} | CB2430 | 약어+폭(백단위)+높이(백단위) | +| 제품 | {유형약어}{폭}{높이} | SH3040 | 약어+폭(백단위)+높이(백단위) | + +#### 품목코드 약어 매핑 +**제품 유형:** +| 제품 | 약어 | +|------|------| +| 방화셔터 | SH | +| 방화문 | DR | +| 방연셔터 | SS | +| 자동문 | AD | +| 오버헤드도어 | OH | +| 하이스피드도어 | HS | +| 스틸셔터 | ST | +| 그릴셔터 | GS | + +**부품 유형:** +| 조립부품 | 약어 | 절곡부품 | 약어 | +|---------|------|---------|------| +| 셔터박스 | RC | 커버박스 | CB | +| 슬랫조립체 | SL | 가이드레일 | GR | +| 가이드조립체 | GD | 바텀바 | BB | +| 개폐기조립체 | OP | 행거브라켓 | HB | +| 제어반조립체 | CT | 중간가이드 | MG | + +#### 거래처/현장 코드 체계 +| 대상 | 접두사 | 패턴 | 예시 | +|------|--------|------|------| +| 거래처(고객) | CUS | CUS-### | CUS-001 | +| 거래처(공급처) | SUP | SUP-### | SUP-001 | +| 현장 | S | S-### | S-001 | + +#### LOT번호 체계 (생산추적용) +**LOT번호 형식**: `{제품코드}-{종류코드}-{날짜코드}-{규격코드}` +- 예시: `G-I-4A05-53` (연기차단재-화이바원단-2024년10월05일-W50×3000) + +**날짜코드 규칙:** +| 구분 | 규칙 | 예시 | +|------|------|------| +| 연도 | 끝자리 숫자 (0-9) | 2024년 → 4 | +| 월 | 1-9, A(10), B(11), C(12) | 10월 → A | +| 일 | 2자리 숫자 (01-31) | 5일 → 05 | + +**제품코드 매핑:** +| 제품 | 코드 | +|------|------| +| 가이드레일(벽면형) | R | +| 가이드레일(측면형) | S | +| 케이스 | C | +| 하단마감재(스크린) | B | +| 하단마감재(철재) | T | +| L-Bar | L | +| 연기차단재 | G | + +#### 코드 생성 함수 사용법 +```javascript +import { generateItemCode, generateLotNo } from '@/configs/codeRuleConfig'; + +// 품목코드 자동생성 +const itemCode = generateItemCode('제품', { + productType: '방화셔터', + width: 3000, + height: 4000 +}); // 결과: SH3040 + +// LOT번호 자동생성 +const lotNo = generateLotNo('연기차단재', '화이바원단(W50)', new Date(), 'W50×3000'); +// 결과: G-I-4C16-53 +``` + +### 17. 채번/코드 관련 파일 구조 +``` +src/configs/ +├── codeRuleConfig.js # 품목코드, LOT번호 규칙 정의 +├── documentTemplateConfig.js # 문서번호 채번 규칙 정의 (numberingRules 섹션) +└── menuDefinitions.js # 채번관리 메뉴 정의 +``` + +## 스타일 적용 위치 + +| 규칙 | 적용 위치 | +|------|----------| +| 그레이스케일 | `src/App.jsx` - 메인 컨테이너 div에 filter 속성 | +| 검정 폰트 | `public/index.html` - `
\ No newline at end of file diff --git a/mes기획서_리액트/build/static/css/main.064d61cb.css b/mes기획서_리액트/build/static/css/main.064d61cb.css new file mode 100644 index 0000000..869cc68 --- /dev/null +++ b/mes기획서_리액트/build/static/css/main.064d61cb.css @@ -0,0 +1,2 @@ +.react-flow{direction:ltr}.react-flow__container{height:100%;left:0;position:absolute;top:0;width:100%}.react-flow__pane{cursor:grab;z-index:1}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:grabbing}.react-flow__viewport{pointer-events:none;transform-origin:0 0;z-index:2}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{overflow:visible;pointer-events:none}.react-flow__connection-path,.react-flow__edge-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{cursor:pointer;pointer-events:visibleStroke}.react-flow__edge.animated path{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection .animated{stroke-dasharray:5;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none;transform-origin:0 0}.react-flow__node{box-sizing:border-box;cursor:grab;pointer-events:all;position:absolute;transform-origin:0 0;-webkit-user-select:none;user-select:none}.react-flow__node.dragging{cursor:grabbing}.react-flow__nodesselection{pointer-events:none;transform-origin:left top;z-index:3}.react-flow__nodesselection-rect{cursor:grab;pointer-events:all;position:absolute}.react-flow__handle{background:#1a192b;border:1px solid #fff;border-radius:100%;height:6px;min-height:5px;min-width:5px;pointer-events:none;position:absolute;width:6px}.react-flow__handle.connectionindicator{cursor:crosshair;pointer-events:all}.react-flow__handle-bottom{bottom:-4px;left:50%;top:auto;transform:translate(-50%)}.react-flow__handle-top{left:50%;top:-4px;transform:translate(-50%)}.react-flow__handle-left{left:-4px;top:50%;transform:translateY(-50%)}.react-flow__handle-right{right:-4px;top:50%;transform:translateY(-50%)}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{margin:15px;position:absolute;z-index:5}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;transform:translateX(-50%)}.react-flow__attribution{background:#ffffff80;font-size:10px;margin:0;padding:2px 3px}.react-flow__attribution a{color:#999;text-decoration:none}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{height:100%;pointer-events:none;position:absolute;-webkit-user-select:none;user-select:none;width:100%}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-group,.react-flow__node-input,.react-flow__node-output{background-color:#fff;border:1px solid #1a192b;border-radius:3px;color:#222;font-size:12px;padding:10px;text-align:center;width:150px}.react-flow__node-default.selectable:hover,.react-flow__node-group.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover{box-shadow:0 1px 4px 1px #00000014}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:#f0f0f040}.react-flow__nodesselection-rect,.react-flow__selection{background:#0059dc14;border:1px dotted #0059dccc}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px #00000014}.react-flow__controls-button{align-items:center;background:#fefefe;border:none;border-bottom:1px solid #eee;box-sizing:initial;cursor:pointer;display:flex;height:16px;justify-content:center;padding:5px;-webkit-user-select:none;user-select:none;width:16px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{max-height:12px;max-width:12px;width:100%}.react-flow__controls-button:disabled{pointer-events:none}.react-flow__controls-button:disabled svg{fill-opacity:.4}.react-flow__minimap{background-color:#fff}.react-flow__minimap svg{display:block}.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.bottom,.react-flow__resize-control.top{cursor:ns-resize}.react-flow__resize-control.bottom.right,.react-flow__resize-control.top.left{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:#3367d9;border:1px solid #fff;border-radius:1px;height:4px;transform:translate(-50%,-50%);width:4px}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.bottom.left,.react-flow__resize-control.handle.top.left{left:0}.react-flow__resize-control.handle.bottom.right,.react-flow__resize-control.handle.top.right{left:100%}.react-flow__resize-control.line{border:0 solid #3367d9}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{height:100%;top:0;transform:translate(-50%);width:1px}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.bottom,.react-flow__resize-control.line.top{height:1px;left:0;transform:translateY(-50%);width:100%}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%} +/*# sourceMappingURL=main.064d61cb.css.map*/ \ No newline at end of file diff --git a/mes기획서_리액트/build/static/css/main.064d61cb.css.map b/mes기획서_리액트/build/static/css/main.064d61cb.css.map new file mode 100644 index 0000000..2c99374 --- /dev/null +++ b/mes기획서_리액트/build/static/css/main.064d61cb.css.map @@ -0,0 +1 @@ +{"version":3,"file":"static/css/main.064d61cb.css","mappings":"AAEA,YACE,aACF,CACA,uBAGE,WAAY,CAEZ,MAAO,CAJP,iBAAkB,CAGlB,KAAM,CAFN,UAIF,CACA,kBAGE,WAAY,CAFZ,SAGF,CACA,4BACI,cACF,CACF,2BAEI,eACF,CACF,sBAGE,mBAAoB,CAFpB,oBAAqB,CACrB,SAEF,CACA,sBACE,SACF,CACA,uBACE,SACF,CACA,sFAEE,YACF,CACA,+BAEE,gBAAiB,CADjB,mBAEF,CACA,oDAEE,cAAe,CACf,cAAe,CACf,SACF,CACA,kBAEE,cAAe,CADf,4BAEF,CACA,gCACI,kBAAmB,CAEX,sCACV,CACF,6DACI,qBAAsB,CAEd,cACV,CACF,2BACI,mBACF,CACF,mFAGI,YACF,CACF,wJAGI,WACF,CACF,8BACI,kBACF,CACF,yBACI,SACF,CACF,yCACI,mBAAoB,CACpB,wBAAyB,CAEjB,gBACV,CACF,wBACE,mBACF,CACA,kCACI,kBAAmB,CAEX,sCACV,CACF,4BACE,YACF,CACA,mBACE,mBAAoB,CACpB,oBACF,CACA,kBAOE,qBAAsB,CAEtB,WAAY,CAJZ,kBAAmB,CAJnB,iBAAkB,CAKlB,oBAAqB,CAJrB,wBAAyB,CAEjB,gBAMV,CACA,2BAEI,eACF,CACF,4BAGE,mBAAoB,CADpB,yBAA0B,CAD1B,SAGF,CACA,iCAII,WAAY,CAFZ,kBAAmB,CADnB,iBAIF,CACF,oBAOE,kBAAmB,CACnB,qBAAuB,CACvB,kBAAmB,CAHnB,UAAW,CAFX,cAAe,CADf,aAAc,CADd,mBAAoB,CADpB,iBAAkB,CAIlB,SAKF,CACA,wCAEI,gBAAiB,CADjB,kBAEF,CACF,2BAGI,WAAY,CADZ,QAAS,CADT,QAAS,CAGT,yBACF,CACF,wBACI,QAAS,CACT,QAAS,CACT,yBACF,CACF,yBAEI,SAAU,CADV,OAAQ,CAER,0BACF,CACF,0BACI,UAAW,CACX,OAAQ,CACR,0BACF,CACF,yBACE,WAAY,CACZ,kBACF,CACA,mBAGE,WAAY,CAFZ,iBAAkB,CAClB,SAEF,CACA,uBACI,KACF,CACF,0BACI,QACF,CACF,wBACI,MACF,CACF,yBACI,OACF,CACF,0BACI,QAAS,CACT,0BACF,CACF,yBAEE,oBAAoC,CADpC,cAAe,CAGf,QAAS,CADT,eAEF,CACA,2BAEI,UAAW,CADX,oBAEF,CAMF,oBACE,GACE,oBACF,CACF,CACA,gCAGE,WAAY,CACZ,mBAAoB,CAHpB,iBAAkB,CAIlB,wBAAyB,CAEjB,gBAAiB,CALzB,UAMF,CACA,kDACM,WACF,CACJ,uBACI,cACF,CACF,8EAEI,YACF,CACF,mGAaE,qBAAuB,CADvB,wBAAqB,CAPrB,iBAAkB,CAGlB,UAAW,CADX,cAAe,CAHf,YAAa,CAKb,iBAAkB,CAHlB,WAQF,CACA,uKACM,kCACF,CACJ,iiBAYM,6BACF,CACJ,wBACE,0BACF,CACA,wDAEE,oBAAkC,CAClC,2BACF,CACA,wJAII,YACF,CACF,sBACE,gCACF,CACA,6BAOI,kBAAmB,CALnB,kBAAmB,CACnB,WAA6B,CAA7B,4BAA6B,CAC7B,kBAAuB,CAMvB,cAAe,CALf,YAAa,CAIb,WAAY,CAHZ,sBAAuB,CAQvB,WAAY,CAHZ,wBAAyB,CAEjB,gBAAiB,CALzB,UAOF,CACF,mCACM,kBACF,CACJ,iCAGM,eAAgB,CADhB,cAAe,CADf,UAGF,CACJ,sCACM,mBACF,CACJ,0CACQ,eACF,CACN,qBACE,qBACF,CACA,yBACE,aACF,CACA,4BACE,iBACF,CACA,mEAEE,gBACF,CACA,mEAEE,gBACF,CACA,8EAEE,kBACF,CACA,8EAEE,kBACF,CAEA,mCAKE,wBAAyB,CAFzB,qBAAsB,CACtB,iBAAkB,CAFlB,UAAW,CAIX,8BAAgC,CALhC,SAMF,CACA,wCACE,MAAO,CACP,OACF,CACA,yCACE,SAAU,CACV,OACF,CACA,uCACE,QAAS,CACT,KACF,CACA,0CACE,QAAS,CACT,QACF,CAIA,2FACE,MACF,CAIA,6FACE,SACF,CAEA,iCAGE,sBACF,CACA,6EAKE,WAAY,CADZ,KAAM,CADN,yBAA6B,CAD7B,SAIF,CACA,sCAEE,qBAAsB,CADtB,MAEF,CACA,uCAEE,sBAAuB,CADvB,SAEF,CACA,6EAEE,UAAW,CAEX,MAAO,CADP,0BAA6B,CAE7B,UACF,CACA,qCAEE,oBAAqB,CADrB,KAEF,CACA,wCACE,uBAAwB,CACxB,QACF","sources":["../node_modules/reactflow/dist/style.css"],"sourcesContent":["/* this gets exported as style.css and can be used for the default theming */\n/* these are the necessary styles for React Flow, they get used by base.css and style.css */\n.react-flow {\n direction: ltr;\n}\n.react-flow__container {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n}\n.react-flow__pane {\n z-index: 1;\n cursor: -webkit-grab;\n cursor: grab;\n}\n.react-flow__pane.selection {\n cursor: pointer;\n }\n.react-flow__pane.dragging {\n cursor: -webkit-grabbing;\n cursor: grabbing;\n }\n.react-flow__viewport {\n transform-origin: 0 0;\n z-index: 2;\n pointer-events: none;\n}\n.react-flow__renderer {\n z-index: 4;\n}\n.react-flow__selection {\n z-index: 6;\n}\n.react-flow__nodesselection-rect:focus,\n.react-flow__nodesselection-rect:focus-visible {\n outline: none;\n}\n.react-flow .react-flow__edges {\n pointer-events: none;\n overflow: visible;\n}\n.react-flow__edge-path,\n.react-flow__connection-path {\n stroke: #b1b1b7;\n stroke-width: 1;\n fill: none;\n}\n.react-flow__edge {\n pointer-events: visibleStroke;\n cursor: pointer;\n}\n.react-flow__edge.animated path {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n.react-flow__edge.animated path.react-flow__edge-interaction {\n stroke-dasharray: none;\n -webkit-animation: none;\n animation: none;\n }\n.react-flow__edge.inactive {\n pointer-events: none;\n }\n.react-flow__edge.selected,\n .react-flow__edge:focus,\n .react-flow__edge:focus-visible {\n outline: none;\n }\n.react-flow__edge.selected .react-flow__edge-path,\n .react-flow__edge:focus .react-flow__edge-path,\n .react-flow__edge:focus-visible .react-flow__edge-path {\n stroke: #555;\n }\n.react-flow__edge-textwrapper {\n pointer-events: all;\n }\n.react-flow__edge-textbg {\n fill: white;\n }\n.react-flow__edge .react-flow__edge-text {\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n }\n.react-flow__connection {\n pointer-events: none;\n}\n.react-flow__connection .animated {\n stroke-dasharray: 5;\n -webkit-animation: dashdraw 0.5s linear infinite;\n animation: dashdraw 0.5s linear infinite;\n }\n.react-flow__connectionline {\n z-index: 1001;\n}\n.react-flow__nodes {\n pointer-events: none;\n transform-origin: 0 0;\n}\n.react-flow__node {\n position: absolute;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n box-sizing: border-box;\n cursor: -webkit-grab;\n cursor: grab;\n}\n.react-flow__node.dragging {\n cursor: -webkit-grabbing;\n cursor: grabbing;\n }\n.react-flow__nodesselection {\n z-index: 3;\n transform-origin: left top;\n pointer-events: none;\n}\n.react-flow__nodesselection-rect {\n position: absolute;\n pointer-events: all;\n cursor: -webkit-grab;\n cursor: grab;\n }\n.react-flow__handle {\n position: absolute;\n pointer-events: none;\n min-width: 5px;\n min-height: 5px;\n width: 6px;\n height: 6px;\n background: #1a192b;\n border: 1px solid white;\n border-radius: 100%;\n}\n.react-flow__handle.connectionindicator {\n pointer-events: all;\n cursor: crosshair;\n }\n.react-flow__handle-bottom {\n top: auto;\n left: 50%;\n bottom: -4px;\n transform: translate(-50%, 0);\n }\n.react-flow__handle-top {\n left: 50%;\n top: -4px;\n transform: translate(-50%, 0);\n }\n.react-flow__handle-left {\n top: 50%;\n left: -4px;\n transform: translate(0, -50%);\n }\n.react-flow__handle-right {\n right: -4px;\n top: 50%;\n transform: translate(0, -50%);\n }\n.react-flow__edgeupdater {\n cursor: move;\n pointer-events: all;\n}\n.react-flow__panel {\n position: absolute;\n z-index: 5;\n margin: 15px;\n}\n.react-flow__panel.top {\n top: 0;\n }\n.react-flow__panel.bottom {\n bottom: 0;\n }\n.react-flow__panel.left {\n left: 0;\n }\n.react-flow__panel.right {\n right: 0;\n }\n.react-flow__panel.center {\n left: 50%;\n transform: translateX(-50%);\n }\n.react-flow__attribution {\n font-size: 10px;\n background: rgba(255, 255, 255, 0.5);\n padding: 2px 3px;\n margin: 0;\n}\n.react-flow__attribution a {\n text-decoration: none;\n color: #999;\n }\n@-webkit-keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n.react-flow__edgelabel-renderer {\n position: absolute;\n width: 100%;\n height: 100%;\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.react-flow__edge.updating .react-flow__edge-path {\n stroke: #777;\n }\n.react-flow__edge-text {\n font-size: 10px;\n }\n.react-flow__node.selectable:focus,\n .react-flow__node.selectable:focus-visible {\n outline: none;\n }\n.react-flow__node-default,\n.react-flow__node-input,\n.react-flow__node-output,\n.react-flow__node-group {\n padding: 10px;\n border-radius: 3px;\n width: 150px;\n font-size: 12px;\n color: #222;\n text-align: center;\n border-width: 1px;\n border-style: solid;\n border-color: #1a192b;\n background-color: white;\n}\n.react-flow__node-default.selectable:hover, .react-flow__node-input.selectable:hover, .react-flow__node-output.selectable:hover, .react-flow__node-group.selectable:hover {\n box-shadow: 0 1px 4px 1px rgba(0, 0, 0, 0.08);\n }\n.react-flow__node-default.selectable.selected,\n .react-flow__node-default.selectable:focus,\n .react-flow__node-default.selectable:focus-visible,\n .react-flow__node-input.selectable.selected,\n .react-flow__node-input.selectable:focus,\n .react-flow__node-input.selectable:focus-visible,\n .react-flow__node-output.selectable.selected,\n .react-flow__node-output.selectable:focus,\n .react-flow__node-output.selectable:focus-visible,\n .react-flow__node-group.selectable.selected,\n .react-flow__node-group.selectable:focus,\n .react-flow__node-group.selectable:focus-visible {\n box-shadow: 0 0 0 0.5px #1a192b;\n }\n.react-flow__node-group {\n background-color: rgba(240, 240, 240, 0.25);\n}\n.react-flow__nodesselection-rect,\n.react-flow__selection {\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n.react-flow__nodesselection-rect:focus,\n .react-flow__nodesselection-rect:focus-visible,\n .react-flow__selection:focus,\n .react-flow__selection:focus-visible {\n outline: none;\n }\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n.react-flow__controls-button {\n border: none;\n background: #fefefe;\n border-bottom: 1px solid #eee;\n box-sizing: content-box;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n padding: 5px;\n }\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n.react-flow__controls-button svg {\n width: 100%;\n max-width: 12px;\n max-height: 12px;\n }\n.react-flow__controls-button:disabled {\n pointer-events: none;\n }\n.react-flow__controls-button:disabled svg {\n fill-opacity: 0.4;\n }\n.react-flow__minimap {\n background-color: #fff;\n}\n.react-flow__minimap svg {\n display: block;\n}\n.react-flow__resize-control {\n position: absolute;\n}\n.react-flow__resize-control.left,\n.react-flow__resize-control.right {\n cursor: ew-resize;\n}\n.react-flow__resize-control.top,\n.react-flow__resize-control.bottom {\n cursor: ns-resize;\n}\n.react-flow__resize-control.top.left,\n.react-flow__resize-control.bottom.right {\n cursor: nwse-resize;\n}\n.react-flow__resize-control.bottom.left,\n.react-flow__resize-control.top.right {\n cursor: nesw-resize;\n}\n/* handle styles */\n.react-flow__resize-control.handle {\n width: 4px;\n height: 4px;\n border: 1px solid #fff;\n border-radius: 1px;\n background-color: #3367d9;\n transform: translate(-50%, -50%);\n}\n.react-flow__resize-control.handle.left {\n left: 0;\n top: 50%;\n}\n.react-flow__resize-control.handle.right {\n left: 100%;\n top: 50%;\n}\n.react-flow__resize-control.handle.top {\n left: 50%;\n top: 0;\n}\n.react-flow__resize-control.handle.bottom {\n left: 50%;\n top: 100%;\n}\n.react-flow__resize-control.handle.top.left {\n left: 0;\n}\n.react-flow__resize-control.handle.bottom.left {\n left: 0;\n}\n.react-flow__resize-control.handle.top.right {\n left: 100%;\n}\n.react-flow__resize-control.handle.bottom.right {\n left: 100%;\n}\n/* line styles */\n.react-flow__resize-control.line {\n border-color: #3367d9;\n border-width: 0;\n border-style: solid;\n}\n.react-flow__resize-control.line.left,\n.react-flow__resize-control.line.right {\n width: 1px;\n transform: translate(-50%, 0);\n top: 0;\n height: 100%;\n}\n.react-flow__resize-control.line.left {\n left: 0;\n border-left-width: 1px;\n}\n.react-flow__resize-control.line.right {\n left: 100%;\n border-right-width: 1px;\n}\n.react-flow__resize-control.line.top,\n.react-flow__resize-control.line.bottom {\n height: 1px;\n transform: translate(0, -50%);\n left: 0;\n width: 100%;\n}\n.react-flow__resize-control.line.top {\n top: 0;\n border-top-width: 1px;\n}\n.react-flow__resize-control.line.bottom {\n border-bottom-width: 1px;\n top: 100%;\n}\n"],"names":[],"ignoreList":[],"sourceRoot":""} \ No newline at end of file diff --git a/mes기획서_리액트/build/static/js/main.73ec66f8.js b/mes기획서_리액트/build/static/js/main.73ec66f8.js new file mode 100644 index 0000000..d8db166 --- /dev/null +++ b/mes기획서_리액트/build/static/js/main.73ec66f8.js @@ -0,0 +1,3 @@ +/*! For license information please see main.73ec66f8.js.LICENSE.txt */ +(()=>{"use strict";var e={43:(e,t,s)=>{e.exports=s(202)},153:(e,t,s)=>{var r=s(43),a=Symbol.for("react.element"),l=Symbol.for("react.fragment"),n=Object.prototype.hasOwnProperty,i=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,d={key:!0,ref:!0,__self:!0,__source:!0};function o(e,t,s){var r,l={},o=null,c=null;for(r in void 0!==s&&(o=""+s),void 0!==t.key&&(o=""+t.key),void 0!==t.ref&&(c=t.ref),t)n.call(t,r)&&!d.hasOwnProperty(r)&&(l[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===l[r]&&(l[r]=t[r]);return{$$typeof:a,type:e,key:o,ref:c,props:l,_owner:i.current}}t.Fragment=l,t.jsx=o,t.jsxs=o},202:(e,t)=>{var s=Symbol.for("react.element"),r=Symbol.for("react.portal"),a=Symbol.for("react.fragment"),l=Symbol.for("react.strict_mode"),n=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),d=Symbol.for("react.context"),o=Symbol.for("react.forward_ref"),c=Symbol.for("react.suspense"),m=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),p=Symbol.iterator;var u={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,g={};function y(e,t,s){this.props=e,this.context=t,this.refs=g,this.updater=s||u}function b(){}function N(e,t,s){this.props=e,this.context=t,this.refs=g,this.updater=s||u}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if("object"!==typeof e&&"function"!==typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=y.prototype;var j=N.prototype=new b;j.constructor=N,h(j,y.prototype),j.isPureReactComponent=!0;var f=Array.isArray,v=Object.prototype.hasOwnProperty,w={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function k(e,t,r){var a,l={},n=null,i=null;if(null!=t)for(a in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(n=""+t.key),t)v.call(t,a)&&!S.hasOwnProperty(a)&&(l[a]=t[a]);var d=arguments.length-2;if(1===d)l.children=r;else if(1{function s(e,t){var s=e.length;e.push(t);e:for(;0>>1,a=e[r];if(!(0>>1;rl(d,s))ol(c,d)?(e[r]=c,e[o]=s,r=o):(e[r]=d,e[i]=s,r=i);else{if(!(ol(c,s)))break e;e[r]=c,e[o]=s,r=o}}}return t}function l(e,t){var s=e.sortIndex-t.sortIndex;return 0!==s?s:e.id-t.id}if("object"===typeof performance&&"function"===typeof performance.now){var n=performance;t.unstable_now=function(){return n.now()}}else{var i=Date,d=i.now();t.unstable_now=function(){return i.now()-d}}var o=[],c=[],m=1,x=null,p=3,u=!1,h=!1,g=!1,y="function"===typeof setTimeout?setTimeout:null,b="function"===typeof clearTimeout?clearTimeout:null,N="undefined"!==typeof setImmediate?setImmediate:null;function j(e){for(var t=r(c);null!==t;){if(null===t.callback)a(c);else{if(!(t.startTime<=e))break;a(c),t.sortIndex=t.expirationTime,s(o,t)}t=r(c)}}function f(e){if(g=!1,j(e),!h)if(null!==r(o))h=!0,O(v);else{var t=r(c);null!==t&&P(f,t.startTime-e)}}function v(e,s){h=!1,g&&(g=!1,b(C),C=-1),u=!0;var l=p;try{for(j(s),x=r(o);null!==x&&(!(x.expirationTime>s)||e&&!D());){var n=x.callback;if("function"===typeof n){x.callback=null,p=x.priorityLevel;var i=n(x.expirationTime<=s);s=t.unstable_now(),"function"===typeof i?x.callback=i:x===r(o)&&a(o),j(s)}else a(o);x=r(o)}if(null!==x)var d=!0;else{var m=r(c);null!==m&&P(f,m.startTime-s),d=!1}return d}finally{x=null,p=l,u=!1}}"undefined"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var w,S=!1,k=null,C=-1,T=5,I=-1;function D(){return!(t.unstable_now()-Ie||125n?(e.sortIndex=l,s(c,e),null===r(o)&&e===r(c)&&(g?(b(C),C=-1):g=!0,P(f,l-n))):(e.sortIndex=i,s(o,e),h||u||(h=!0,O(v))),e},t.unstable_shouldYield=D,t.unstable_wrapCallback=function(e){var t=p;return function(){var s=p;p=t;try{return e.apply(this,arguments)}finally{p=s}}}},330:(e,t,s)=>{var r=s(43);var a="function"===typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e===1/t)||e!==e&&t!==t},l=r.useState,n=r.useEffect,i=r.useLayoutEffect,d=r.useDebugValue;function o(e){var t=e.getSnapshot;e=e.value;try{var s=t();return!a(e,s)}catch(r){return!0}}var c="undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement?function(e,t){return t()}:function(e,t){var s=t(),r=l({inst:{value:s,getSnapshot:t}}),a=r[0].inst,c=r[1];return i(function(){a.value=s,a.getSnapshot=t,o(a)&&c({inst:a})},[e,s,t]),n(function(){return o(a)&&c({inst:a}),e(function(){o(a)&&c({inst:a})})},[e]),d(s),s};t.useSyncExternalStore=void 0!==r.useSyncExternalStore?r.useSyncExternalStore:c},391:(e,t,s)=>{var r=s(950);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},443:(e,t,s)=>{e.exports=s(717)},461:(e,t,s)=>{e.exports=s(330)},579:(e,t,s)=>{e.exports=s(153)},717:(e,t,s)=>{var r=s(43),a=s(461);var l="function"===typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e===1/t)||e!==e&&t!==t},n=a.useSyncExternalStore,i=r.useRef,d=r.useEffect,o=r.useMemo,c=r.useDebugValue;t.useSyncExternalStoreWithSelector=function(e,t,s,r,a){var m=i(null);if(null===m.current){var x={hasValue:!1,value:null};m.current=x}else x=m.current;m=o(function(){function e(e){if(!d){if(d=!0,n=e,e=r(e),void 0!==a&&x.hasValue){var t=x.value;if(a(t,e))return i=t}return i=e}if(t=i,l(n,e))return t;var s=r(e);return void 0!==a&&a(t,s)?(n=e,t):(n=e,i=s)}var n,i,d=!1,o=void 0===s?null:s;return[function(){return e(t())},null===o?void 0:function(){return e(o())}]},[t,s,r,a]);var p=n(e,m[0],m[1]);return d(function(){x.hasValue=!0,x.value=p},[p]),c(p),p}},730:(e,t,s)=>{var r=s(43),a=s(853);function l(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,s=1;s