From d9d5b490570c450a892739495a1bcc6f49239d12 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 10:21:00 +0900 Subject: [PATCH 1/2] =?UTF-8?q?st:=20refactor:=20-=20Real=20Grid=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20@rsone/components=20?= =?UTF-8?q?=EB=A1=9C=20=EB=AA=A8=EB=93=88=ED=99=94=20-=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=8F=99=EC=A0=81=20import=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=20=EC=88=98=EC=A0=95(engName=20->=20urlPath)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/middleware.ts | 4 +- apps/st/package.json | 1 + apps/st/src/app/providers/app-provider.tsx | 2 + apps/st/src/components/css/DataGrid.css | 105 ---- apps/st/src/components/module/DataGrid.tsx | 10 +- apps/st/src/components/module/TabDataGrid.tsx | 58 +-- .../management/SeweragePenetrationRateMng.tsx | 2 +- .../review/SeweragePenetrationRateRvw.tsx | 123 +---- .../ManagementVerificationRule.tsx | 11 + .../SeweragePenetrationRateColumnRvw.ts | 190 +++---- apps/st/src/entities/code/@x/posting.ts | 1 + apps/st/src/entities/code/api/code-service.ts | 14 + .../src/entities/code/api/lwpocode-service.ts | 73 +++ .../src/entities/code/api/upcode-service.ts | 47 ++ apps/st/src/entities/code/index.ts | 19 + .../src/entities/code/model/code-interface.ts | 10 + .../entities/code/model/lwpocode-interface.ts | 69 +++ .../entities/code/model/upcode-interface.ts | 52 ++ apps/st/src/entities/code/ui/code-select.tsx | 47 ++ .../pages/statistics/ui/statistics-page.tsx | 4 +- apps/st/src/shared/config/api.ts | 2 +- apps/st/src/store/tab-store.ts | 9 +- apps/st/tsconfig.json | 3 +- packages/rsone/.gitignore | 26 + packages/rsone/components/grid/DataGrid.tsx | 352 +++++++++++++ .../rsone/components/grid/TabDataGrid.tsx | 470 ++++++++++++++++++ .../rsone/components/grid/css/DataGrid.css | 105 ++++ packages/rsone/components/index.ts | 8 + .../rsone/components/store/alert-store.ts | 25 + packages/rsone/components/store/tab-store.ts | 137 +++++ .../rsone/components/type/DataGrid.type.ts | 87 ++++ packages/rsone/components/ui/alert-dialog.tsx | 34 ++ packages/rsone/package.json | 41 ++ packages/rsone/tsconfig.build.json | 10 + packages/rsone/tsconfig.json | 38 ++ packages/rsone/tsup.config.ts | 17 + pnpm-lock.yaml | 37 ++ 37 files changed, 1898 insertions(+), 345 deletions(-) create mode 100644 apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx create mode 100644 apps/st/src/entities/code/@x/posting.ts create mode 100644 apps/st/src/entities/code/api/code-service.ts create mode 100644 apps/st/src/entities/code/api/lwpocode-service.ts create mode 100644 apps/st/src/entities/code/api/upcode-service.ts create mode 100644 apps/st/src/entities/code/index.ts create mode 100644 apps/st/src/entities/code/model/code-interface.ts create mode 100644 apps/st/src/entities/code/model/lwpocode-interface.ts create mode 100644 apps/st/src/entities/code/model/upcode-interface.ts create mode 100644 apps/st/src/entities/code/ui/code-select.tsx create mode 100644 packages/rsone/.gitignore create mode 100644 packages/rsone/components/grid/DataGrid.tsx create mode 100644 packages/rsone/components/grid/TabDataGrid.tsx create mode 100644 packages/rsone/components/grid/css/DataGrid.css create mode 100644 packages/rsone/components/index.ts create mode 100644 packages/rsone/components/store/alert-store.ts create mode 100644 packages/rsone/components/store/tab-store.ts create mode 100644 packages/rsone/components/type/DataGrid.type.ts create mode 100644 packages/rsone/components/ui/alert-dialog.tsx create mode 100644 packages/rsone/package.json create mode 100644 packages/rsone/tsconfig.build.json create mode 100644 packages/rsone/tsconfig.json create mode 100644 packages/rsone/tsup.config.ts diff --git a/apps/st/middleware.ts b/apps/st/middleware.ts index 4ed1ed018..8b1ecb501 100644 --- a/apps/st/middleware.ts +++ b/apps/st/middleware.ts @@ -32,7 +32,7 @@ export function middleware(req: NextRequest) { `[Request]\n Original Pathname: ${pathname}`, ]; - if (pathname.startsWith("/st-service")) { + if (pathname.startsWith("/st-management-service") || pathname.startsWith("/st-input-service")) { const requestHeaders = new Headers(req.headers); const token = req.cookies.get(CLAIM_NAME)?.value; const userId = req.cookies.get(AUTH_USER_ID)?.value; @@ -138,5 +138,5 @@ export function middleware(req: NextRequest) { } export const config = { - matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-service/:path*", "/"], + matcher: ["/server/:path*", "/attach-service/:path*", "/api/link/:path*", "/st-management-service/:path*", "/st-input-service/:path*", "/"], }; diff --git a/apps/st/package.json b/apps/st/package.json index b6de459f8..a501dde6a 100644 --- a/apps/st/package.json +++ b/apps/st/package.json @@ -12,6 +12,7 @@ "@common/assets": "workspace:*", "@common/components": "workspace:*", "@common/config": "workspace:*", + "@rsone/components": "workspace:*", "@fontsource-variable/noto-sans-kr": "^5.2.5", "@frontend-opensource/use-react-hooks": "^1.1.4", "@fullcalendar/core": "^6.1.17", diff --git a/apps/st/src/app/providers/app-provider.tsx b/apps/st/src/app/providers/app-provider.tsx index efd1f308e..70e69eee8 100644 --- a/apps/st/src/app/providers/app-provider.tsx +++ b/apps/st/src/app/providers/app-provider.tsx @@ -13,6 +13,7 @@ import { PromptDialog } from "@/shared/ui/prompt-dialog"; import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; import { SelectPromptDialog } from "@/shared/ui/select-prompt-dialog"; import { PromptProvider, StoreProvider } from "@/shared/providers"; +import { AlertDialog as RsoneAlertDialog } from "@rsone/components"; const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { const queryClient = new QueryClient(); @@ -31,6 +32,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { + diff --git a/apps/st/src/components/css/DataGrid.css b/apps/st/src/components/css/DataGrid.css index b7d8352da..e69de29bb 100644 --- a/apps/st/src/components/css/DataGrid.css +++ b/apps/st/src/components/css/DataGrid.css @@ -1,105 +0,0 @@ -/* RealGrid2 폰트 설정 - 루트 폰트와 일치 */ -.rg-root, -.rg-grid, -.rg-body, -.rg-cell, -.rg-header, -.rg-head, -.rg-rowbarcontainer { - font-family: "Noto Sans KR", sans-serif !important; - font-size: 12px !important; - font-weight: 500; - color: #333 !important; -} - -/* RealGrid2 컨테이너 스타일 */ -.rg-root { - border-radius: 0.5rem !important; - overflow: hidden !important; - border: 1px solid #dbe2e6 !important; -} - -.rg-grid { - border-radius: 0.5rem !important; - /* box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.06); */ -} - -/* 헤더 스타일 */ -.rg-header, -.rg-head, -.rg-foot, -.rg-footer, -.rg-fixed-footer { - background-color: #f5f7fa !important; - color: #333 !important; -} - -/* 헤더 셀 스타일 */ -.rg-header .rg-cell, -.rg-head .rg-cell { - background-color: #f5f7fa !important; -} - -/* 헤더 필터링 영역 위치 조정 - 오른쪽 여백 추가 */ -.rg-header-filtering { - left: auto !important; - right: 8px !important; -} - -/* 그룹 헤더 스타일 */ -.rg-header-group, -.rg-header-group-cell { - background-color: #f5f7fa !important; -} - -/* 첫 번째 헤더 셀 - 왼쪽 상단 모서리 */ -.rg-header .rg-cell:first-child, -.rg-head .rg-cell:first-child { - border-top-left-radius: 8px !important; -} - -/* 마지막 헤더 셀 - 오른쪽 상단 모서리 */ -.rg-header .rg-cell:last-child, -.rg-head .rg-cell:last-child { - border-top-right-radius: 8px !important; -} - -/* border color 통일 */ -.rg-header .rg-table tr td, -.rg-head .rg-table tr td:not(:first-child), -.rg-body .rg-table tr td, -.rg-rowbarcontainer .rg-table tr td:not(:first-child) { - border-left: 1px solid #dbe2e6 !important; - border-bottom: 1px solid #dbe2e6 !important; - border-right: none !important; -} -.rg-rowindicator-head, -.rg-rowbarcontainer .rg-table tr td:first-child { - border-right: none !important; - border-bottom: 1px solid #dbe2e6 !important; - border-left: none !important; -} -.rg-footer .rg-table tr td, -.rg-fixed-footer .rg-table tr td, -.rg-foot .rg-table tr td { - border-right: 1px solid #dbe2e6 !important; - border-top: 1px solid #dbe2e6 !important; -} - -.rg-rowbarcontainer .rg-table tr td { - background-color: #f5f7fa !important; -} - -/* 푸터 마지막 요소 - 오른쪽 border 제거 */ -.rg-footer .rg-table tr td:last-child { - border-right: none !important; -} - -/* 고정 컬럼 바 */ -.rg-fixed-column-bar { - background-color: #ccc !important; - border-right: 1px solid #ccc !important; -} - - - diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 44f2ef56c..0b65f124a 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -312,10 +312,12 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport 가져오기 } - {isExcelExport && } + {isExcelExport && + + }
handleFileChange(e, tabKey)} />
- {isExcelImport && ( - - )} - + } + {isExcelExport && + + }
{ const gridView = el.gridView; if (!gridView) return; - + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); if (!currentInfo) return; - + gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN }); gridView.header.height = 60; - + // 헤더 체크박스 표시 여부 설정 gridView.setOptions({ checkBar: { visible: showHeaderCheckbox }, rowIndicator: { visible: false }, }); - + // footer가 있는 컬럼이 있으면 footer 높이 설정 const hasFooter = currentInfo.columns.some(col => col.footer); if (hasFooter) { gridView.footer.height = 40; } - + gridView.setOptions({ summaryMode: "aggregate" }); - + // footer의 valueCallback 설정 currentInfo.columns.forEach(col => { if (col.footer && col.footer.valueCallback) { @@ -364,21 +366,21 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r } } }); - + // 고정 컬럼 설정 if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { gridView.setFixedOptions({ colCount: currentInfo.fixedColumns, }); } - + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 if (el.dataProvider) { const dataProvider = el.dataProvider; const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; const fieldMap = new Map(); - + currentInfo.columns.forEach(col => { if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { fieldMap.set(col.fieldName, col.valueType); @@ -395,13 +397,13 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r // 기존 필드 정보 가져오기 const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); - + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 const fieldsToUpdate = fieldsToSet.filter(field => { const existingDataType = existingFieldMap.get(field.fieldName); return existingDataType !== field.dataType; }); - + if (fieldsToUpdate.length > 0) { // 기존 필드 정보를 유지하면서 dataType만 업데이트 // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 @@ -409,14 +411,14 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r fieldName: f.fieldName, dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' })); - + // 새로 추가할 필드가 있으면 추가 fieldsToSet.forEach(field => { if (!existingFieldMap.has(field.fieldName)) { allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); } }); - + // setFields를 호출하여 필드의 dataType 업데이트 (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) .setFields(allFields); diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx index bc3bf889c..1db839f81 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx @@ -1,5 +1,5 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index fd625fb72..c80e0ce82 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,112 +1,16 @@ -import { ValueType } from "realgrid"; +import { DataGrid } from "@rsone/components"; import SearchForm from "@/components/module/SearchForm"; - -import DataGrid from "@/components/module/DataGrid"; import SaveButton from "@/components/button/SaveButton"; import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import type { ColumnConfig } from "@/components/type/DataGrid.type"; + +import { SeweragePenetrationRateInfoList } from "@/components/util/column/review/SeweragePenetrationRateColumnRvw"; import { useState } from "react"; const SeweragePenetrationRateRvw = () => { - const columns: ColumnConfig[] = [ - { name: 'sn', fieldName: '순번', header: { text: '순번' }, mergeCells: true, editable: false, sortdisable: true }, - { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, - { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, - { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, - { name: '수계', fieldName: '수계', header: { text: '수계' } }, - { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, - { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, - { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, - { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, - { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, - { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, - { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, - { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, - { name: '계', fieldName: '계', header: { text: '계' } }, - //공공하수처리인구 - { name: '합계', fieldName: '합계', header: { text: '합계' } }, - { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, - { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, - { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, - //폐수처리인구(명) - { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, - { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, - { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, - { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, - - { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, - { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, - { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, - { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, - { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, - { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, - { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, - { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, - { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, - { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, - ]; - - const columnLayout = [ - 'sn', - { - name: 'groupA', - hideChildHeaders: false, - header: { text: '행정구역' }, - items: ['sido', 'sgg'], - }, - '구분', - '수계', - 'bstrm', - { - name: 'groupB', - hideChildHeaders: false, - header: { text: '수계영향권별분류류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - hideChildHeaders: false, - header: { text: '하수처리구역내' }, - items: [ - '계', - { - name: 'pblswrgGroup', - hideChildHeaders: false, - header: { text: '공공하수처리인구(명)' }, - items: ['합계', '1차처리', '2차처리', '3차처리'], - }, - { - name: 'wstrGroup', - hideChildHeaders: false, - header: { text: '폐수처리인구(명)' }, - items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - hideChildHeaders: false, - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ]; const approveFunc = () => { console.log('approveFunc'); @@ -133,13 +37,22 @@ const SeweragePenetrationRateRvw = () => { return ( <> -
- - - - +
+
+ + + + +
- + ); }; diff --git a/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx new file mode 100644 index 000000000..040a68b51 --- /dev/null +++ b/apps/st/src/components/statistics/verification/ManagementVerificationRule.tsx @@ -0,0 +1,11 @@ +import SearchForm from "@/components/module/SearchForm"; + +const ManagementVerificationRule = () => { + return ( + <> + + + ); +}; + +export default ManagementVerificationRule; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts index d792174b7..fe7869a48 100644 --- a/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SeweragePenetrationRateColumnRvw.ts @@ -1,95 +1,99 @@ -export const SeweragePenetrationRateInfoList = [ - { - tabKey: 'a', - tabLabel: '하수도 보급률 현황', - rowStartNum: 3, // 수계영향권 및 처리구역 내/외 3단 헤더 구조 - fixedColumns: 2, // 순번, 시도, 구군까지 고정 - columns: [ - /* 1. 행정 및 수계 정보 */ - { name: 'sido', fieldName: 'SIDO', header: { text: '시도' }, editable: false }, - { name: 'sgg', fieldName: 'GUGUN', header: { text: '구군' }, editable: false }, - { name: 'GBN', fieldName: 'GBN', header: { text: '구분' }, editable: false }, - { name: 'WTR_SYS', fieldName: 'WTR_SYS', header: { text: '수계' }, editable: false }, - { name: 'bstrm', fieldName: 'BSTRM', header: { text: '지류' }, editable: false }, - { name: 'mdbsn', fieldName: 'MDBSN', header: { text: '세부단위유역' }, editable: false }, - { name: 'lgbsn', fieldName: 'LGBSN', header: { text: '중권역' }, editable: false }, - { name: 'mdmbsn', fieldName: 'MDMBSN', header: { text: '소권역' }, editable: false }, - { name: 'specl_cntrpln_ar', fieldName: 'SPECL_CNTRPLN_AR', header: { text: '특별대책지역' }, editable: false }, +import { ValueType } from "realgrid"; +import type { ColumnConfig } from "@rsone/components"; - /* 2. 인구 및 면적 총계 */ - { name: 'popltn_sm', fieldName: 'POPLTN_SM', header: { text: '총인구(명)' }, editable: false }, - { name: 'ar_sm', fieldName: 'AR_SM', header: { text: '총면적(㎢)' }, editable: false }, +export const SeweragePenetrationRateInfoList = { + columns: [ + { name: 'sido', fieldName: '시도', header: { text: '시도' }, mergeCells: true, editable: false, sortdisable: true }, + { name: 'sgg', fieldName: '시군구', header: { text: '시군구' }, mergeCells: true, editable: false, sortdisable: true }, + { name: '구분', fieldName: '구분', header: { text: '구분' }, editable: false, sortdisable: true }, + { name: '수계', fieldName: '수계', header: { text: '수계' } }, + { name: 'bstrm', fieldName: '지류', header: { text: '지류' } }, + { name: 'mdbsn', fieldName: '세부단위유역', header: { text: '세부단위유역' } }, + { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, + { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, + { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, + { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, + { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, + { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, + { name: '계', fieldName: '계', header: { text: '계' } }, + //공공하수처리인구 + { name: '합계', fieldName: '합계', header: { text: '합계' } }, + { name: '1차처리', fieldName: '1차처리', header: { text: '1차처리' } }, + { name: '2차처리', fieldName: '2차처리', header: { text: '2차처리' } }, + { name: '3차처리', fieldName: '3차처리', header: { text: '3차처리' } }, + //폐수처리인구(명) + { name: '(폐수처리인구)합계', fieldName: '(폐수처리인구)합계', header: { text: '합계' } }, + { name: '(폐수처리인구)1차처리', fieldName: '(폐수처리인구)1차처리', header: { text: '1차처리' } }, + { name: '(폐수처리인구)2차처리', fieldName: '(폐수처리인구)2차처리', header: { text: '2차처리' } }, + { name: '(폐수처리인구)3차처리', fieldName: '(폐수처리인구)3차처리', header: { text: '3차처리' } }, - /* 3. 하수처리구역 내 상세 */ - { name: 'inner_sm', fieldName: 'INNER_SM', header: { text: '계' }, editable: false }, - // 공공하수처리인구 - { name: 'pbl_sm', fieldName: 'PBL_SM', header: { text: '합계' }, editable: false }, - { name: 'pbl_1ch', fieldName: 'PBL_1CH', header: { text: '1차처리' }, editable: false }, - { name: 'pbl_2ch', fieldName: 'PBL_2CH', header: { text: '2차처리' }, editable: false }, - { name: 'pbl_3ch', fieldName: 'PBL_3CH', header: { text: '3차처리' }, editable: false }, - // 폐수처리인구 - { name: 'wstr_sm', fieldName: 'WSTR_SM', header: { text: '합계' }, editable: false }, - { name: 'wstr_1ch', fieldName: 'WSTR_1CH', header: { text: '1차처리' }, editable: false }, - { name: 'wstr_2ch', fieldName: 'WSTR_2CH', header: { text: '2차처리' }, editable: false }, - { name: 'wstr_3ch', fieldName: 'WSTR_3CH', header: { text: '3차처리' }, editable: false }, - - { name: 'not_conect_popltn', fieldName: 'NOT_CONECT_POPLTN', header: { text: '미접속인구' }, editable: false }, - { name: 'swge_proc_zone_inner_ar', fieldName: 'SWGE_PROC_ZONE_INNER_AR', header: { text: '면적(㎢)' }, editable: false }, - - /* 4. 하수처리구역 외 상세 */ - { name: 'swge_proc_zone_outer_sm', fieldName: 'SWGE_PROC_ZONE_OUTER_SM', header: { text: '계' }, editable: false }, - { name: 'town_unproc_popltn', fieldName: 'TOWN_UNPROC_POPLTN', header: { text: '미처리인구' }, editable: false }, - { name: 'town_swtt_popltn', fieldName: 'TOWN_SWTT_POPLTN', header: { text: '오수처리인구' }, editable: false }, - { name: 'town_wrrtn_popltn', fieldName: 'TOWN_WRRTN_POPLTN', header: { text: '정화조인구' }, editable: false }, - { name: 'swge_proc_zone_outer_ar', fieldName: 'SWGE_PROC_ZONE_OUTER_AR', header: { text: '면적(㎢)' }, editable: false }, - - /* 5. 보급율 및 지표 */ - { name: 'pblswrg_popltn_suprt', fieldName: 'PBLSWRG_POPLTN_SUPRT', header: { text: '공공하수처리구역\n인구보급율(%)' }, editable: false }, - { name: 'adtrt_popltn_suprt', fieldName: 'ADTRT_POPLTN_SUPRT', header: { text: '고도처리\n인구보급율(%)' }, editable: false }, - { name: 'swrg_instlrt', fieldName: 'SWRG_INSTLRT', header: { text: '하수도설치율(%)' }, editable: false }, - { name: 'rmk', fieldName: 'RMK', header: { text: '비고' }, editable: false }, - ], - columnLayout: [ - { name: 'groupA', header: { text: '행정구역' }, items: ['sido', 'sgg'] }, - 'GBN', - 'WTR_SYS', - 'bstrm', - { - name: 'groupB', - header: { text: '수계영향권별분류' }, - items: ['mdbsn', 'lgbsn', 'mdmbsn'], - }, - 'specl_cntrpln_ar', - 'popltn_sm', - 'ar_sm', - { - name: 'groupD', - header: { text: '하수처리구역내' }, - items: [ - 'inner_sm', - { - name: 'pblswrgGroup', - header: { text: '공공하수처리인구(명)' }, - items: ['pbl_sm', 'pbl_1ch', 'pbl_2ch', 'pbl_3ch'], - }, - { - name: 'wstrGroup', - header: { text: '폐수처리인구(명)' }, - items: ['wstr_sm', 'wstr_1ch', 'wstr_2ch', 'wstr_3ch'], - }, - 'not_conect_popltn', - 'swge_proc_zone_inner_ar' - ], - }, - { - name: 'groupE', - header: { text: '하수처리구역외' }, - items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], - }, - 'pblswrg_popltn_suprt', - 'adtrt_popltn_suprt', - 'swrg_instlrt', - 'rmk', - ] - } -]; \ No newline at end of file + { name: 'not_conect_popltn', fieldName: '미접속인구', header: { text: '미접속인구' } }, + { name: 'swge_proc_zone_inner_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'swge_proc_zone_outer_sm', fieldName: '합계', header: { text: '계' } }, + { name: 'town_unproc_popltn', fieldName: '미처리인구', header: { text: '미처리인구' } }, + { name: 'town_swtt_popltn', fieldName: '오수처리인구', header: { text: '오수처리인구' } }, + { name: 'town_wrrtn_popltn', fieldName: '정화조인구', header: { text: '정화조인구' } }, + { name: 'swge_proc_zone_outer_ar', fieldName: '면적(㎢)', header: { text: '면적(㎢)' } }, + { name: 'pblswrg_popltn_suprt', fieldName: '공공하수처리구역인구보급율(%)', header: { text: '공공하수처리구역인구보급율(%)' } }, + { name: 'adtrt_popltn_suprt', fieldName: '고도처리인구보급율(%)', header: { text: `고도처리인구보급율(%)` } }, + { name: 'swrg_instlrt', fieldName: '하수도설치율(%)', header: { text: '하수도설치율(%)' } }, + { name: 'rmk', fieldName: '비고', header: { text: '비고' } }, + ] as ColumnConfig[], + columnLayout: [ + { + name: 'groupA', + hideChildHeaders: false, + header: { text: '행정구역' }, + items: ['sido', 'sgg'], + }, + '구분', + '수계', + 'bstrm', + { + name: 'groupB', + hideChildHeaders: false, + header: { text: '수계영향권별분류류' }, + items: ['mdbsn', 'lgbsn', 'mdmbsn'], + }, + 'specl_cntrpln_ar', + 'popltn_sm', + 'ar_sm', + { + name: 'groupD', + hideChildHeaders: false, + header: { text: '하수처리구역내' }, + items: [ + '계', + { + name: 'pblswrgGroup', + hideChildHeaders: false, + header: { text: '공공하수처리인구(명)' }, + items: ['합계', '1차처리', '2차처리', '3차처리'], + }, + { + name: 'wstrGroup', + hideChildHeaders: false, + header: { text: '폐수처리인구(명)' }, + items: ['(폐수처리인구)합계', '(폐수처리인구)1차처리', '(폐수처리인구)2차처리', '(폐수처리인구)3차처리'], + }, + 'not_conect_popltn', + 'swge_proc_zone_inner_ar' + ], + }, + { + name: 'groupE', + hideChildHeaders: false, + header: { text: '하수처리구역외' }, + items: ['swge_proc_zone_outer_sm', 'town_unproc_popltn', 'town_swtt_popltn', 'town_wrrtn_popltn', 'swge_proc_zone_outer_ar'], + }, + 'pblswrg_popltn_suprt', + 'adtrt_popltn_suprt', + 'swrg_instlrt', + 'rmk', + ], + fixedColumns: 2, + rowStartNum: 3 +}; \ No newline at end of file diff --git a/apps/st/src/entities/code/@x/posting.ts b/apps/st/src/entities/code/@x/posting.ts new file mode 100644 index 000000000..0525684d9 --- /dev/null +++ b/apps/st/src/entities/code/@x/posting.ts @@ -0,0 +1 @@ +export { CodeSelect } from "../ui/code-select"; diff --git a/apps/st/src/entities/code/api/code-service.ts b/apps/st/src/entities/code/api/code-service.ts new file mode 100644 index 000000000..0d1055f6a --- /dev/null +++ b/apps/st/src/entities/code/api/code-service.ts @@ -0,0 +1,14 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import type { CodeService, ICode } from "../model/code-interface"; + +export class CodeApiService implements CodeService { + public async getCode(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.CODE}/${upCd}`, + ); + return response.data; + } +} + +export const CodeApi = new CodeApiService(); diff --git a/apps/st/src/entities/code/api/lwpocode-service.ts b/apps/st/src/entities/code/api/lwpocode-service.ts new file mode 100644 index 000000000..818ddb120 --- /dev/null +++ b/apps/st/src/entities/code/api/lwpocode-service.ts @@ -0,0 +1,73 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import { + LwpoCodeFormSchema, + type LwpoCodeService, + type LwpoCodeList, + type LwpoCodeDetail, + type LwpoCodeParams, + type LwpoCodeFormData, +} from "../model/lwpocode-interface"; + +export class LwpoCodeApiService implements LwpoCodeService { + public async getLwpoCodeList(params?: LwpoCodeParams): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}`, + { params }, + ); + return response.data; + } + + public async getUpCodeLwpoCodeList(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/up-cd/${upCd}`, + ); + return response.data; + } + + public async lwpoCodeDetail( + upCd: string, + lwpoCd: string, + ): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + ); + return response.data; + } + + public async createLwpoCode(data: LwpoCodeFormData): Promise { + const validatedData = LwpoCodeFormSchema.parse(data); + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}`, + validatedData, + ); + return response.data; + } + + public async updateLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise { + const validatedData = LwpoCodeFormSchema.parse(data); + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + validatedData, + ); + return response.data; + } + + public async deleteLwpoCode(upCd: string, lwpoCd: string): Promise { + await client.delete( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/${lwpoCd}/up-cd/${upCd}`, + ); + } + + public async codeRefreshAll(): Promise { + await client.post( + `${ENDPOINT.CMS_SERVICE.LWPO_CODE}/cache/refresh-all`, + ); + } +} + +export const LwpoCodeApi = new LwpoCodeApiService(); diff --git a/apps/st/src/entities/code/api/upcode-service.ts b/apps/st/src/entities/code/api/upcode-service.ts new file mode 100644 index 000000000..dcccd9534 --- /dev/null +++ b/apps/st/src/entities/code/api/upcode-service.ts @@ -0,0 +1,47 @@ +import { client } from "@/shared/api"; +import { ENDPOINT } from "@/shared/config"; +import { + upCodeFormSchema, + type UpCodeService, + type UpCodeList, + type UpCodeDetail, + type UpCodeParams, + type UpCodeFormData, +} from "../model/upcode-interface"; + +export class UpCodeApiService implements UpCodeService { + public async getUpCodeList(params?: UpCodeParams): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.UP_CODE}`, + { params }, + ); + return response.data; + } + + public async upCodeDetail(upCd: string): Promise { + const response = await client.get( + `${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`, + ); + return response.data; + } + + public async createUpCode(data: UpCodeFormData): Promise { + const validatedData = upCodeFormSchema.parse(data); + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.UP_CODE}`, + validatedData, + ); + return response.data; + } + + public async updateUpCode(upCd: string, data: UpCodeFormData): Promise { + const validatedData = upCodeFormSchema.parse(data); + const response = await client.put( + `${ENDPOINT.CMS_SERVICE.UP_CODE}/${upCd}`, + validatedData, + ); + return response.data; + } +} + +export const UpCodeApi = new UpCodeApiService(); diff --git a/apps/st/src/entities/code/index.ts b/apps/st/src/entities/code/index.ts new file mode 100644 index 000000000..e166e2c29 --- /dev/null +++ b/apps/st/src/entities/code/index.ts @@ -0,0 +1,19 @@ +export { CodeApi } from "./api/code-service"; +export type { ICode } from "./model/code-interface"; +export { CodeSelect } from "./ui/code-select"; + +export { UpCodeApi } from "./api/upcode-service"; +export { + upCodeFormSchema, + type UpCode, + type UpCodeFormData, + type UpCodeParams, +} from "./model/upcode-interface"; + +export { LwpoCodeApi } from "./api/lwpocode-service"; +export { + LwpoCodeFormSchema, + type LwpoCode, + type LwpoCodeFormData, + type LwpoCodeParams, +} from "./model/lwpocode-interface"; diff --git a/apps/st/src/entities/code/model/code-interface.ts b/apps/st/src/entities/code/model/code-interface.ts new file mode 100644 index 000000000..4562e2559 --- /dev/null +++ b/apps/st/src/entities/code/model/code-interface.ts @@ -0,0 +1,10 @@ +export interface ICode { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + unit: string; +} + +export interface CodeService { + getCode(upCd: string): Promise; +} diff --git a/apps/st/src/entities/code/model/lwpocode-interface.ts b/apps/st/src/entities/code/model/lwpocode-interface.ts new file mode 100644 index 000000000..2538c1c30 --- /dev/null +++ b/apps/st/src/entities/code/model/lwpocode-interface.ts @@ -0,0 +1,69 @@ +import { z } from "zod"; +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface LwpoCodeParams extends PageableParams { + upCd?: string; + lwpoCd?: string; + lwpoCdNm?: string; + useYn?: string; +} + +export interface LwpoCode { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + lwpoCdExpln: string; + unit: string; + prntLwpoCd: string; + useYn: string; + sortSeq: number; + regDt: string; + rgTr: string; + rgTrNm: string; + mdfcnDt: string; + mdFr: string; +} + +export interface LwpoCodeDetail extends LwpoCodeFormData { + lwpoCd: string; + upCd: string; + lwpoCdNm: string; + lwpoCdExpln: string; + unit: string; + prntLwpoCd: string; + useYn: string; + sortSeq: 0; +} + +export const LwpoCodeFormSchema = z.object({ + lwpoCd: z.string().max(10).nonempty(), + upCd: z.string().max(10).nonempty(), + lwpoCdNm: z.string().max(100).nonempty(), + lwpoCdExpln: z.string().max(1000).nullish(), + unit: z.string().max(20).nullish(), + prntLwpoCd: z.string().max(10).nullish(), + useYn: z.string(), + sortSeq: z.number(), + delYn: z.string(), +}); + +export type LwpoCodeFormData = z.infer; +export type LwpoCodeList = PageableList; + +export interface LwpoCodeService { + getLwpoCodeList(params: LwpoCodeParams): Promise; + getUpCodeLwpoCodeList(upCd: string): Promise; + lwpoCodeDetail(upCd: string, lwpoCd: string): Promise; + updateLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise; + createLwpoCode(data: LwpoCodeFormData): Promise; + deleteLwpoCode( + upCd: string, + lwpoCd: string, + data: LwpoCodeFormData, + ): Promise; + codeRefreshAll(): Promise; +} diff --git a/apps/st/src/entities/code/model/upcode-interface.ts b/apps/st/src/entities/code/model/upcode-interface.ts new file mode 100644 index 000000000..73bf4f3ae --- /dev/null +++ b/apps/st/src/entities/code/model/upcode-interface.ts @@ -0,0 +1,52 @@ +import { z } from "zod"; +import type { PageableParams, PageableList } from "@/shared/model"; + +export interface UpCodeParams extends PageableParams { + keyword?: string; + upCd?: string; + cdSe?: string; + useYn?: string; + siteId?: string; +} + +export interface UpCode { + upCd: string; + upCdNm: string; + upCdExpln: string; + cdSe: string; + siteId: string; + useYn: string; + regDt: string; +} + +export interface UpCodeDetail extends UpCodeFormData { + upCd: string; + upCdNm: string; + upCdExpln: string; + cdSe: string; + siteId: string; + useYn: string; + delYn: string; + regDt: string; + rgTrNm: string; +} + +export const upCodeFormSchema = z.object({ + upCd: z.string().max(10).nonempty(), + upCdNm: z.string().max(100).nonempty(), + upCdExpln: z.string().max(1000).nullish(), + cdSe: z.string().max(10).nonempty(), + siteId: z.string().max(2).nullish(), + useYn: z.string(), + delYn: z.string(), +}); + +export type UpCodeFormData = z.infer; +export type UpCodeList = PageableList; + +export interface UpCodeService { + getUpCodeList(params: UpCodeParams): Promise; + upCodeDetail(upCodeId: string): Promise; + updateUpCode(upCodeId: string, data: UpCodeFormData): Promise; + createUpCode(data: UpCodeFormData): Promise; +} diff --git a/apps/st/src/entities/code/ui/code-select.tsx b/apps/st/src/entities/code/ui/code-select.tsx new file mode 100644 index 000000000..08df4ce51 --- /dev/null +++ b/apps/st/src/entities/code/ui/code-select.tsx @@ -0,0 +1,47 @@ +import { useQuery } from "@tanstack/react-query"; +import { + cn, + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@common/components"; +import { ENDPOINT } from "@/shared/config"; +import { CodeApi } from "../api/code-service"; + +type CodeSelectProps = { + upCd: string; + placeholder?: string; + className?: string; +} & React.ComponentPropsWithoutRef; + +function CodeSelect({ + upCd, + placeholder = "선택", + className, + ...props +}: CodeSelectProps) { + const { data: code } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.CODE, upCd], + queryFn: () => CodeApi.getCode(upCd), + enabled: !!upCd, + }); + + return ( + + ); +} + +export { CodeSelect }; diff --git a/apps/st/src/pages/statistics/ui/statistics-page.tsx b/apps/st/src/pages/statistics/ui/statistics-page.tsx index 3efa3b04f..7513b0ffe 100644 --- a/apps/st/src/pages/statistics/ui/statistics-page.tsx +++ b/apps/st/src/pages/statistics/ui/statistics-page.tsx @@ -6,6 +6,8 @@ import { useTabStore } from "@/store/tab-store"; import Dashboard from "@/components/Dashboard"; import { SkeletonPage } from "@/shared/ui/skeleton-page"; +import "@rsone/components/index.css"; + const StatisticsPage = () => { const { tabs, activeTabId } = useTabStore(); @@ -38,7 +40,7 @@ const StatisticsPage = () => { {tabs.map((tab) => { // 렌더링 시점에 컴포넌트가 없으면 바로 로드 if (!componentCache.current.has(tab.id)) { - const componentName = tab.id; + const componentName = tab.urlPath; const parentComponentName = tab.parentEngNm; const DynamicComponent = dynamic( diff --git a/apps/st/src/shared/config/api.ts b/apps/st/src/shared/config/api.ts index 61c2bec0e..8325c0e32 100644 --- a/apps/st/src/shared/config/api.ts +++ b/apps/st/src/shared/config/api.ts @@ -65,7 +65,7 @@ export const ENDPOINT = { POST_EVALUATION: "/board-service/api/v1/pstEvl", }, ST_SERVICE: { - COMMON: "/st-service/api/v1/common", + COMMON: "/st-management-service/api/v1/common", } }; diff --git a/apps/st/src/store/tab-store.ts b/apps/st/src/store/tab-store.ts index f5b49bb29..cdbaad91f 100644 --- a/apps/st/src/store/tab-store.ts +++ b/apps/st/src/store/tab-store.ts @@ -4,7 +4,8 @@ import type { MenuItem } from "@/entities/menu"; export interface Tab { id: string; // 고유 ID (menuEngNm) label: string; // 탭에 표시될 이름 - path: string; // URL 경로 + path: string; // 메뉴 경로 + urlPath: string; // url 경로 parentEngNm: string; // 부모 menuEngNm menuItem: MenuItem; // 메뉴 정보 } @@ -38,11 +39,12 @@ const useTabStoreHook = create((set, get) => ({ return true; } - if (tabs.length < 10) { + if (tabs.length < 100) { const newTab: Tab = { id: tabId, label: menuItem.menuKornNm, path: menuItem.menuPath, + urlPath: menuItem.urlPath, parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '', menuItem, }; @@ -112,5 +114,4 @@ const useTabStoreHook = create((set, get) => ({ })); export const useTabStore = useTabStoreHook; -export const getTabStoreState = () => useTabStoreHook.getState(); - +export const getTabStoreState = () => useTabStoreHook.getState(); \ No newline at end of file diff --git a/apps/st/tsconfig.json b/apps/st/tsconfig.json index 5b8c29899..e91347649 100644 --- a/apps/st/tsconfig.json +++ b/apps/st/tsconfig.json @@ -27,7 +27,8 @@ "@/*": ["./*"], "@common/components": ["../../../packages/common/components/src/"], "@common/config": ["../../../packages/common/config/dist/"], - "@common/network": ["../../../packages/common/network/"] + "@common/network": ["../../../packages/common/network/"], + "@rsone/components": ["../../../packages/rsone/dist/"] } }, "include": [ diff --git a/packages/rsone/.gitignore b/packages/rsone/.gitignore new file mode 100644 index 000000000..3ece3c8a7 --- /dev/null +++ b/packages/rsone/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env* \ No newline at end of file diff --git a/packages/rsone/components/grid/DataGrid.tsx b/packages/rsone/components/grid/DataGrid.tsx new file mode 100644 index 000000000..4c9a50522 --- /dev/null +++ b/packages/rsone/components/grid/DataGrid.tsx @@ -0,0 +1,352 @@ +import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { DataGridProps } from "../type/DataGrid.type" +import JSZip from "jszip" +import * as XLSX from "xlsx" +import { Button } from "@common/components"; +import { useAlertStore } from "../store/alert-store"; +import { useTabStore } from "../store/tab-store"; + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +// Window 인터페이스 확장 +declare global { + interface Window { + JSZip: typeof JSZip; + } +} + +// RealGrid가 jszip을 사용할 수 있도록 전역에 등록 +if (typeof window !== "undefined") { + window.JSZip = JSZip; +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, isExcelExport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { + const { columns, columnLayout } = columnInfo; + const gridRef = useRef(null); + const fileInputRef = useRef(null); + const { setMessage: alert } = useAlertStore((state) => state); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + + const exportExcel = () => { + if (rowData.length === 0) { + alert('데이터가 없습니다.'); + return; + } + + if (!gridRef.current?.gridView) return; + + const gridView = gridRef.current.gridView; + + const menuName = menuList + ?.flatMap((m) => m.children || []) + .flatMap((subM) => subM || []) + .find((s) => s.menuEngNm === activeTabId) + ?.menuKornNm || 'export'; + + gridView.exportGrid({ + type: 'excel', + target: 'local', + fileName: `${menuName}.xlsx`, + footer: 'hidden', + done: () => { + alert('내보내기가 완료되었습니다.'); + }, + }); + }; + + const importExcel = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + try { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + alert('파일을 읽을 수 없습니다.'); + return; + } + + // SheetJS로 엑셀 파일을 JSON으로 변환 + const workbook = XLSX.read(data, { type: 'array', cellDates: true }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName || '']; + + if (!worksheet || !worksheet['!ref']) { + alert('워크시트를 읽을 수 없습니다.'); + return; + } + + const range = XLSX.utils.decode_range(worksheet['!ref']); + const headerRowCount = rowStartNum || 1; // 기본값 1 + const headerStartRow = Math.max(0, headerRowCount - 1); // 0-based index + + // 각 컬럼별로 헤더 찾기 (rowStartNum 행부터 위로 올라가면서) + const headers: string[] = []; + const headerRowIndexes: number[] = []; + + for (let col = range.s.c; col <= range.e.c; col++) { + let headerValue = ''; + let headerRowIndex = headerStartRow; + + // rowStartNum 행부터 시작해서 위로 올라가면서 헤더 찾기 + for (let rowIndex = headerStartRow; rowIndex >= 0; rowIndex--) { + const cell = worksheet[XLSX.utils.encode_cell({ r: rowIndex, c: col })]; + if (cell && cell.v !== undefined && cell.v !== null && cell.v !== '') { + headerValue = String(cell.v); + headerRowIndex = rowIndex; + break; + } + } + + // 헤더를 찾지 못한 경우 기본값 사용 + if (!headerValue) { + headerValue = `Column${col + 1}`; + headerRowIndex = headerStartRow; + } + + headers.push(headerValue); + headerRowIndexes.push(headerRowIndex); + } + + // 실제 데이터가 시작하는 행 찾기 (헤더가 있는 최대 행 번호 + 1) + const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; + const dataStartRow = maxHeaderRowIndex + 1; + + // 데이터 행 읽기 + const dataRows: Record[] = []; + for (let row = dataStartRow; row <= range.e.r; row++) { + const rowData: Record = {}; + let hasData = false; + + for (let colIndex = 0; colIndex < headers.length; colIndex++) { + const col = range.s.c + colIndex; + const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; + const headerName = headers[colIndex] || `Column${colIndex + 1}`; + + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } + + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { + hasData = true; + } + + rowData[headerName] = cellValue; + } + + // 데이터가 하나라도 있는 행만 추가 + if (hasData) { + dataRows.push(rowData); + } + } + setRowData(dataRows); + } catch (error) { + console.error('엑셀 파일 파싱 오류:', error); + alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); + } finally { + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + } + }; + + reader.onerror = () => { + alert('파일 읽기 중 오류가 발생했습니다.'); + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + }; + + reader.readAsArrayBuffer(file); + } catch (error) { + console.error('엑셀 파일 가져오기 오류:', error); + alert('엑셀 파일 가져오기 중 오류가 발생했습니다.'); + if (fileInputRef.current) { + fileInputRef.current.value = ''; + } + } + }; + + useEffect(() => { + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; + + const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + + (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + // 고정 컬럼 설정 + if (fixedColumns !== undefined && fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: fixedColumns, + }); + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + }, [columns, columnLayout, fixedColumns, rowData, showHeaderCheckbox]); + + return ( +
+ +
+ {isExcelImport && + + } + {isExcelExport && + + } +
+
+ + {columns.map((column) => ( + + ))} + +
+
+ ); +}; + +export default DataGrid; \ No newline at end of file diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx new file mode 100644 index 000000000..191ebaea3 --- /dev/null +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -0,0 +1,470 @@ +import { useRef, useEffect, useState } from "react" +import { ValueType } from "realgrid" + +import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" +import { RealGridReact, RGDataColumn } from "realgrid-react" +import type { TabDataGridProps } from "../type/DataGrid.type" +import JSZip from "jszip" +import * as XLSX from "xlsx" +import { useAlertStore } from "../store/alert-store"; +import { useTabStore } from "../store/tab-store"; + +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; +import { Button } from "@common/components"; + +// RealGrid 타입 확장 +declare module "realgrid" { + interface GridView { + setOptions(options: { + footer?: { visible?: boolean }; + summaryMode?: 'aggregate' | 'statistical' | 'none'; + checkBar?: { visible?: boolean }; + }): void; + } +} + +// Window 인터페이스 확장 +declare global { + interface Window { + JSZip: typeof JSZip; + } +} + +// RealGrid가 jszip을 사용할 수 있도록 전역에 등록 +if (typeof window !== "undefined") { + window.JSZip = JSZip; +} + +RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); + +const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { + // 각 탭별로 그리드 ref와 데이터를 관리 + const gridRefs = useRef>(new Map()); + const fileInputRefs = useRef>(new Map()); + const { setMessage: alert } = useAlertStore((state) => state); + const activeTabId = useTabStore((state) => state.activeTabId); + const menuList = useTabStore((state) => state.menuList); + const [activeTab, setActiveTab] = useState(() => { + // 초기 활성 탭을 첫 번째 tabKey로 설정 + const firstTab = columnInfo[0]; + return firstTab?.tabKey || ''; + }); + + const exportExcel = (tabKey: string) => { + const currentRowData = rowDataMap.get(tabKey) || []; + if (currentRowData.length === 0) { + alert('데이터가 없습니다.'); + return; + } + + const gridRef = gridRefs.current.get(tabKey); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + + const menuName = menuList + ?.flatMap((m) => m.children || []) + .flatMap((subM) => subM || []) + .find((s) => s.menuEngNm === activeTabId) + ?.menuKornNm || 'export'; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + const tabLabel = columnInfoItem?.tabLabel || tabKey; + gridView.exportGrid({ + type: 'excel', + target: 'local', + fileName: `${menuName}_${tabLabel}.xlsx`, + footer: 'hidden', + done: () => { + alert('내보내기가 완료되었습니다.'); + }, + }); + }; + + const importExcel = (tabKey: string) => { + const fileInput = fileInputRefs.current.get(tabKey); + fileInput?.click(); + }; + + const handleFileChange = async (e: React.ChangeEvent, tabKey: string) => { + const file = e.target.files?.[0]; + if (!file) return; + + const columnInfoItem = columnInfo.find(info => info.tabKey === tabKey); + if (!columnInfoItem) return; + + const rowStartNum = columnInfoItem.rowStartNum || 1; + + try { + const reader = new FileReader(); + reader.onload = (event) => { + try { + const data = event.target?.result; + if (!data) { + alert('파일을 읽을 수 없습니다.'); + return; + } + + // SheetJS로 엑셀 파일을 JSON으로 변환 + const workbook = XLSX.read(data, { type: 'array', cellDates: true }); + const firstSheetName = workbook.SheetNames[0]; + const worksheet = workbook.Sheets[firstSheetName || '']; + + if (!worksheet || !worksheet['!ref']) { + alert('워크시트를 읽을 수 없습니다.'); + return; + } + + const range = XLSX.utils.decode_range(worksheet['!ref']); + const headerRowCount = rowStartNum || 1; // 기본값 1 + const headerStartRow = Math.max(0, headerRowCount - 1); // 0-based index + + // 각 컬럼별로 헤더 찾기 (rowStartNum 행부터 위로 올라가면서) + const headers: string[] = []; + const headerRowIndexes: number[] = []; + + for (let col = range.s.c; col <= range.e.c; col++) { + let headerValue = ''; + let headerRowIndex = headerStartRow; + + // rowStartNum 행부터 시작해서 위로 올라가면서 헤더 찾기 + for (let rowIndex = headerStartRow; rowIndex >= 0; rowIndex--) { + const cell = worksheet[XLSX.utils.encode_cell({ r: rowIndex, c: col })]; + if (cell && cell.v !== undefined && cell.v !== null && cell.v !== '') { + headerValue = String(cell.v); + headerRowIndex = rowIndex; + break; + } + } + + // 헤더를 찾지 못한 경우 기본값 사용 + if (!headerValue) { + headerValue = `Column${col + 1}`; + headerRowIndex = headerStartRow; + } + + headers.push(headerValue); + headerRowIndexes.push(headerRowIndex); + } + + // 실제 데이터가 시작하는 행 찾기 (헤더가 있는 최대 행 번호 + 1) + const maxHeaderRowIndex = headerRowIndexes.length > 0 ? Math.max(...headerRowIndexes) : headerStartRow; + const dataStartRow = maxHeaderRowIndex + 1; + + // 데이터 행 읽기 + const dataRows: Record[] = []; + for (let row = dataStartRow; row <= range.e.r; row++) { + const rowData: Record = {}; + let hasData = false; + + for (let colIndex = 0; colIndex < headers.length; colIndex++) { + const col = range.s.c + colIndex; + const cell = worksheet[XLSX.utils.encode_cell({ r: row, c: col })]; + const headerName = headers[colIndex] || `Column${colIndex + 1}`; + + let cellValue: string | number = ''; + if (cell && cell.v !== undefined && cell.v !== null) { + // 엑셀 셀 타입이 숫자이거나 값이 숫자인 경우 숫자로 변환 + if (cell.t === 'n' || (typeof cell.v === 'number' && !isNaN(cell.v))) { + cellValue = cell.v as number; + } else { + const stringValue = String(cell.v); + // 문자열이지만 숫자로 변환 가능한 경우 숫자로 변환 + const numericValue = Number(stringValue.replace(/,/g, '')); + if (!isNaN(numericValue) && stringValue.trim() !== '') { + cellValue = numericValue; + } else { + cellValue = stringValue; + } + } + } + + if (cellValue !== '' && cellValue !== null && cellValue !== undefined) { + hasData = true; + } + + rowData[headerName] = cellValue; + } + + // 데이터가 하나라도 있는 행만 추가 + if (hasData) { + dataRows.push(rowData); + } + } + + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, dataRows); + return newMap; + }); + } catch (error) { + console.error('엑셀 파일 파싱 오류:', error); + alert('엑셀 파일 파싱 중 오류가 발생했습니다.'); + } finally { + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + reader.onerror = () => { + alert('파일 읽기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + }; + + reader.readAsArrayBuffer(file); + } catch (error) { + console.error('엑셀 파일 가져오기 오류:', error); + alert('엑셀 파일 가져오기 중 오류가 발생했습니다.'); + const fileInput = fileInputRefs.current.get(tabKey); + if (fileInput) { + fileInput.value = ''; + } + } + }; + + // 초기 데이터 설정 + useEffect(() => { + if (rows.length > 0) { + columnInfo.forEach((info) => { + const tabKey = info.tabKey; + if (!rowDataMap.has(tabKey)) { + setRowDataMap(prev => { + const newMap = new Map(prev); + newMap.set(tabKey, rows); + return newMap; + }); + } + }); + } + }, [rows, columnInfo]); + + // 활성 탭이 변경될 때마다 fitStyle 재적용 (그리드가 보일 때) + useEffect(() => { + const gridRef = gridRefs.current.get(activeTab); + if (!gridRef?.gridView) return; + + const gridView = gridRef.gridView; + // 약간의 지연을 두고 설정 (그리드 렌더링 완료 후) + const timer = setTimeout(() => { + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.refresh(); + }, 50); + + return () => clearTimeout(timer); + }, [activeTab]); + + if (columnInfo.length === 0) { + return
컬럼 정보가 없습니다.
; + } + + return ( +
+ + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const tabLabel = info.tabLabel || tabKey; + return ( + + {tabLabel} + + ); + })} + + + {columnInfo.map((info) => { + const tabKey = info.tabKey; + const { columns, columnLayout } = info; + const currentRowData = rowDataMap.get(tabKey) || []; + + return ( + +
+ { + if (el) { + fileInputRefs.current.set(tabKey, el); + } else { + fileInputRefs.current.delete(tabKey); + } + }} + type="file" + accept=".xlsx,.xls,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" + style={{ display: 'none' }} + onChange={(e) => handleFileChange(e, tabKey)} + /> +
+ {isExcelImport && + + } + {isExcelExport && + + } +
+
+ { + if (el) { + gridRefs.current.set(tabKey, el); + // 그리드가 생성된 직후 fitStyle 설정 + if (el.gridView) { + setTimeout(() => { + const gridView = el.gridView; + if (!gridView) return; + + const currentInfo = columnInfo.find(info => info.tabKey === tabKey); + if (!currentInfo) return; + + gridView.setDisplayOptions({ + fitStyle: GridFitStyle.EVEN + }); + gridView.header.height = 60; + + // 헤더 체크박스 표시 여부 설정 + gridView.setOptions({ + checkBar: { visible: showHeaderCheckbox }, + rowIndicator: { visible: false }, + }); + + // footer가 있는 컬럼이 있으면 footer 높이 설정 + const hasFooter = currentInfo.columns.some(col => col.footer); + if (hasFooter) { + gridView.footer.height = 40; + } + + gridView.setOptions({ + summaryMode: "aggregate" + }); + + // footer의 valueCallback 설정 + currentInfo.columns.forEach(col => { + if (col.footer && col.footer.valueCallback) { + const column = gridView.columnByName(col.name); + if (column && column.footer) { + (column.footer as { valueCallback?: typeof col.footer.valueCallback }).valueCallback = col.footer.valueCallback; + } + } + }); + + // 고정 컬럼 설정 + if (currentInfo.fixedColumns !== undefined && currentInfo.fixedColumns > 0) { + gridView.setFixedOptions({ + colCount: currentInfo.fixedColumns, + }); + } + + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 + // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + if (el.dataProvider) { + const dataProvider = el.dataProvider; + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + currentInfo.columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + } + }, 0); + } + } else { + gridRefs.current.delete(tabKey); + } + }} + autoGenerateField={true} + layout={columnLayout} + rows={currentRowData} + > + {columns.map((column) => ( + + ))} + +
+
+
+ ); + })} +
+
+ ); +}; + +export default TabDataGrid; \ No newline at end of file diff --git a/packages/rsone/components/grid/css/DataGrid.css b/packages/rsone/components/grid/css/DataGrid.css new file mode 100644 index 000000000..b7d8352da --- /dev/null +++ b/packages/rsone/components/grid/css/DataGrid.css @@ -0,0 +1,105 @@ +/* RealGrid2 폰트 설정 - 루트 폰트와 일치 */ +.rg-root, +.rg-grid, +.rg-body, +.rg-cell, +.rg-header, +.rg-head, +.rg-rowbarcontainer { + font-family: "Noto Sans KR", sans-serif !important; + font-size: 12px !important; + font-weight: 500; + color: #333 !important; +} + +/* RealGrid2 컨테이너 스타일 */ +.rg-root { + border-radius: 0.5rem !important; + overflow: hidden !important; + border: 1px solid #dbe2e6 !important; +} + +.rg-grid { + border-radius: 0.5rem !important; + /* box-shadow: 0 0 10px -1px rgba(0, 0, 0, 0.06); */ +} + +/* 헤더 스타일 */ +.rg-header, +.rg-head, +.rg-foot, +.rg-footer, +.rg-fixed-footer { + background-color: #f5f7fa !important; + color: #333 !important; +} + +/* 헤더 셀 스타일 */ +.rg-header .rg-cell, +.rg-head .rg-cell { + background-color: #f5f7fa !important; +} + +/* 헤더 필터링 영역 위치 조정 - 오른쪽 여백 추가 */ +.rg-header-filtering { + left: auto !important; + right: 8px !important; +} + +/* 그룹 헤더 스타일 */ +.rg-header-group, +.rg-header-group-cell { + background-color: #f5f7fa !important; +} + +/* 첫 번째 헤더 셀 - 왼쪽 상단 모서리 */ +.rg-header .rg-cell:first-child, +.rg-head .rg-cell:first-child { + border-top-left-radius: 8px !important; +} + +/* 마지막 헤더 셀 - 오른쪽 상단 모서리 */ +.rg-header .rg-cell:last-child, +.rg-head .rg-cell:last-child { + border-top-right-radius: 8px !important; +} + +/* border color 통일 */ +.rg-header .rg-table tr td, +.rg-head .rg-table tr td:not(:first-child), +.rg-body .rg-table tr td, +.rg-rowbarcontainer .rg-table tr td:not(:first-child) { + border-left: 1px solid #dbe2e6 !important; + border-bottom: 1px solid #dbe2e6 !important; + border-right: none !important; +} +.rg-rowindicator-head, +.rg-rowbarcontainer .rg-table tr td:first-child { + border-right: none !important; + border-bottom: 1px solid #dbe2e6 !important; + border-left: none !important; +} +.rg-footer .rg-table tr td, +.rg-fixed-footer .rg-table tr td, +.rg-foot .rg-table tr td { + border-right: 1px solid #dbe2e6 !important; + border-top: 1px solid #dbe2e6 !important; +} + +.rg-rowbarcontainer .rg-table tr td { + background-color: #f5f7fa !important; +} + +/* 푸터 마지막 요소 - 오른쪽 border 제거 */ +.rg-footer .rg-table tr td:last-child { + border-right: none !important; +} + +/* 고정 컬럼 바 */ +.rg-fixed-column-bar { + background-color: #ccc !important; + border-right: 1px solid #ccc !important; +} + + + diff --git a/packages/rsone/components/index.ts b/packages/rsone/components/index.ts new file mode 100644 index 000000000..767d0dc79 --- /dev/null +++ b/packages/rsone/components/index.ts @@ -0,0 +1,8 @@ +import "./grid/css/DataGrid.css"; + +export { default as DataGrid } from "./grid/DataGrid"; +export { default as TabDataGrid } from "./grid/TabDataGrid"; +export * from "./type/DataGrid.type"; +export * from "./store/alert-store"; +export * from "./store/tab-store"; +export { AlertDialog } from "./ui/alert-dialog"; \ No newline at end of file diff --git a/packages/rsone/components/store/alert-store.ts b/packages/rsone/components/store/alert-store.ts new file mode 100644 index 000000000..3313ed87d --- /dev/null +++ b/packages/rsone/components/store/alert-store.ts @@ -0,0 +1,25 @@ +import { create } from "zustand"; + +export type AlertState = { + message: string; + callback?: () => void; +}; + +export type AlertActions = { + setMessage: (message: string, callback?: () => void) => void; +}; + +export type AlertStore = AlertState & AlertActions; + +interface AlertStoreState extends AlertStore {} + +const useAlertStoreHook = create((set) => ({ + message: "", + callback: undefined, + setMessage: (message: string, callback?: () => void) => + set(() => ({ message, callback })), +})); + +export const useAlertStore = useAlertStoreHook; +export const getAlertStoreState = () => useAlertStoreHook.getState(); + diff --git a/packages/rsone/components/store/tab-store.ts b/packages/rsone/components/store/tab-store.ts new file mode 100644 index 000000000..def86ecb3 --- /dev/null +++ b/packages/rsone/components/store/tab-store.ts @@ -0,0 +1,137 @@ +import { create } from "zustand"; + +// MenuItem 타입 정의 (필요한 필드만 포함) +export interface MenuItem { + menuCd: number; + menuKornNm: string; + menuEngNm: string; + parentId: number | null; + sortSeq: number; + iconNm?: string; + children: MenuItem[] | null; + levelNo: number; + urlPath: string; + menuLnkgTypeCd: string; + menuLnkgSn: number; + menuPath: string; + qrcd: string; + useYn: string; + otptYn: string; + newWndwYn: string; + requiredUrlPath: boolean; + menuHlpCn: string; +} + +export interface Tab { + id: string; // 고유 ID (menuEngNm) + label: string; // 탭에 표시될 이름 + path: string; // 메뉴 경로 + urlPath: string; // url 경로 + parentEngNm: string; // 부모 menuEngNm + menuItem: MenuItem; // 메뉴 정보 +} + +interface TabStore { + tabs: Tab[]; + activeTabId: string | null; + menuList: MenuItem[] | null; + addTab: (menuItem: MenuItem) => boolean; + removeTab: (tabId: string) => void; + setActiveTab: (tabId: string) => void; + setMenuList: (menuList: MenuItem[] | null) => void; + closeAllTabs: () => void; + closeOtherTabs: (tabId: string) => void; +} + +const useTabStoreHook = create((set, get) => ({ + tabs: [], + activeTabId: null, + menuList: null, + addTab: (menuItem: MenuItem) => { + const { tabs, menuList } = get(); + const tabId = menuItem.menuEngNm || ''; + + // 이미 존재하는 탭인지 확인 + const existingTab = tabs.find((tab) => tab.id === tabId); + + if (existingTab) { + // 이미 존재하면 활성화만 + set({ activeTabId: tabId }); + return true; + } + + if (tabs.length < 100) { + const newTab: Tab = { + id: tabId, + label: menuItem.menuKornNm, + path: menuItem.menuPath, + urlPath: menuItem.urlPath, + parentEngNm: menuList?.find((m) => m.menuCd === menuItem.parentId)?.menuEngNm || '', + menuItem, + }; + + set({ + tabs: [...tabs, newTab], + activeTabId: tabId, + }); + + return true; + } else { + return false; + } + }, + removeTab: (tabId: string): void => { + const { tabs, activeTabId } = get(); + const newTabs = tabs.filter((tab) => tab.id !== tabId); + + // 닫는 탭이 현재 활성 탭이면 다른 탭으로 전환 + let newActiveTabId = activeTabId; + if (activeTabId === tabId) { + const closedTabIndex = tabs.findIndex((tab) => tab.id === tabId); + if (newTabs.length > 0) { + // 닫힌 탭의 이전 탭을 활성화, 없으면 다음 탭 + if (closedTabIndex > 0) { + const prevTab = tabs[closedTabIndex - 1]; + newActiveTabId = prevTab ? prevTab.id : null; + } else { + const firstTab = newTabs[0]; + newActiveTabId = firstTab ? firstTab.id : null; + } + } else { + newActiveTabId = null; + } + } + + set({ + tabs: newTabs, + activeTabId: newActiveTabId, + }); + }, + setActiveTab: (tabId: string) => { + set({ activeTabId: tabId }); + }, + setMenuList: (menuList: MenuItem[] | null) => { + set({ menuList }); + }, + closeAllTabs: () => { + set({ + tabs: [], + activeTabId: null, + }); + }, + closeOtherTabs: (tabId: string) => { + const { tabs } = get(); + const tabToKeep = tabs.find((tab) => tab.id === tabId); + + if (tabToKeep) { + set({ + tabs: [tabToKeep], + activeTabId: tabId, + }); + } + }, +})); + +export const useTabStore = useTabStoreHook; +export const getTabStoreState = () => useTabStoreHook.getState(); + diff --git a/packages/rsone/components/type/DataGrid.type.ts b/packages/rsone/components/type/DataGrid.type.ts new file mode 100644 index 000000000..3c405546f --- /dev/null +++ b/packages/rsone/components/type/DataGrid.type.ts @@ -0,0 +1,87 @@ +import React from "react"; +import { ValueType } from "realgrid"; + +// RealGrid 타입 정의 +export type GridView = { + getSummary(field: string, summary: 'sum' | 'avg' | 'count' | 'max' | 'min'): number | undefined; + getDataSource(): { + getRowCount(): number; + getValue(rowIndex: number, field: string): number | string; + getDataRowId(dataRow: number): number | string; + }; + getDataRow(itemIndex: number): number; +}; + +export type MergeCallback = (grid: GridView, column: DataColumn, itemIndex: number, value: number | string | null | undefined) => number | null; + +export type DataColumn = { + name: string; + fieldName: string; +}; + +export type ColumnFooter = { + text?: string; + expression?: string; + numberFormat?: string; +}; + +export type ColumnConfig = { + name: string; + fieldName: string; + header: { text: string }; + editable?: boolean; // 셀 편집 가능 여부 + mergeCells?: boolean; + sortdisable?: boolean; + valueType?: ValueType; + dataFormat?: string; + footer?: { + text?: string; + expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; + numberFormat?: string; + valueCallback?: (grid: GridView, column: DataColumn, footerIndex: number, columnFooter: ColumnFooter, value: number | string | undefined) => number | string; + }, +}; + +export type ColumnLayoutItem = string | { + name: string; + hideChildHeaders?: boolean; + header: { text: string }; + items: (string | ColumnLayoutItem)[]; +}; + +export type ColumnInfo = { + columns: ColumnConfig[]; + columnLayout: ColumnLayoutItem[]; +}; + +export type ColumnInfoList = { + tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 + columns: ColumnConfig[]; + columnLayout: ColumnLayoutItem[]; + rowStartNum?: number; + fixedColumns?: number; + tabLabel?: string; // 탭에 표시될 레이블 +} + +export type DataGridProps = { + columnInfo: ColumnInfo; + rowStartNum?: number; // 헤더 행 개수 (1부터 시작, 예: 2면 1행과 2행까지 헤더로 간주) + isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; + onRowsChange?: (rows: Record[]) => void; + fixedColumns?: number; // 고정할 컬럼 개수 (좌측부터) + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowData: Record[]; + setRowData: React.Dispatch[]>>; +}; + +export type TabDataGridProps = { + columnInfo: ColumnInfoList[]; + rows?: Record[]; + isExcelImport?: boolean; // 엑셀 가져오기 유무 + isExcelExport?: boolean; + onRowsChange?: (rows: Record[]) => void; + showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowDataMap: Map[]>; + setRowDataMap: React.Dispatch[]>>>; +}; \ No newline at end of file diff --git a/packages/rsone/components/ui/alert-dialog.tsx b/packages/rsone/components/ui/alert-dialog.tsx new file mode 100644 index 000000000..e6227ac3d --- /dev/null +++ b/packages/rsone/components/ui/alert-dialog.tsx @@ -0,0 +1,34 @@ +import { + Dialog, + DialogContent, + DialogFooter, + DialogClose, + Button, +} from "@common/components"; +import { useAlertStore } from "../store/alert-store"; + +function AlertDialog() { + const { message, callback, setMessage } = useAlertStore((state) => state); + const handleOpenChange = () => { + setMessage("", undefined); + callback?.(); + }; + return ( + + +
+

+ {message} +

+
+ + + + + +
+
+ ); +} + +export { AlertDialog }; \ No newline at end of file diff --git a/packages/rsone/package.json b/packages/rsone/package.json new file mode 100644 index 000000000..b5e7f6c3d --- /dev/null +++ b/packages/rsone/package.json @@ -0,0 +1,41 @@ +{ + "name": "@rsone/components", + "version": "1.0.0", + "private": true, + "sideEffects": false, + "type": "module", + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + }, + "./index.css": "./dist/index.css" + }, + "files": [ + "dist/**" + ], + "scripts": { + "build": "tsup", + "clean": "rm -rf dist" + }, + "dependencies": { + "@common/components": "workspace:*", + "realgrid": "^2.9.5", + "realgrid-react": "^0.9.7", + "jszip": "^3.10.1", + "xlsx": "^0.18.5", + "zustand": "^5.0.3" + }, + "peerDependencies": { + "react": "^19.2.1", + "react-dom": "^19.2.1" + }, + "devDependencies": { + "tsup": "8.3.6", + "typescript": "~5.6.2" + } +} \ No newline at end of file diff --git a/packages/rsone/tsconfig.build.json b/packages/rsone/tsconfig.build.json new file mode 100644 index 000000000..adc74fce3 --- /dev/null +++ b/packages/rsone/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "./tsconfig.json", + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "jsx": "react-jsx", + "incremental": false + } +} \ No newline at end of file diff --git a/packages/rsone/tsconfig.json b/packages/rsone/tsconfig.json new file mode 100644 index 000000000..cd23787e0 --- /dev/null +++ b/packages/rsone/tsconfig.json @@ -0,0 +1,38 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "target": "ES2020", + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable" + ], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "isolatedModules": true, + "jsx": "react-jsx", + "noEmit": false, + "incremental": true, + "strict": true, + "baseUrl": ".", + "paths": { + "@/*": [ + "components/*" + ], + "@common/components": [ + "../common/components/src" + ] + } + }, + "exclude": [ + "**/node_modules", + "**/.*/*", + "dist" + ], + "include": [ + "**/*.ts", + "**/*.tsx" + ] +} \ No newline at end of file diff --git a/packages/rsone/tsup.config.ts b/packages/rsone/tsup.config.ts new file mode 100644 index 000000000..dcb9e8b62 --- /dev/null +++ b/packages/rsone/tsup.config.ts @@ -0,0 +1,17 @@ +import path from "path"; +import { defineConfig } from "tsup"; + +export default defineConfig((options) => ({ + entry: ["components/index.ts"], + splitting: true, + treeshake: true, + clean: true, + dts: true, + format: ["esm"], + external: ["react", "react-dom", "realgrid", "realgrid-react"], + platform: "browser", + target: ["es2020"], + tsconfig: path.resolve(__dirname, "tsconfig.build.json"), + sourcemap: !options.watch, + minify: !options.watch, +})); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a17a827c5..ab7fd8d4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -936,6 +936,9 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.1.8 version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@rsone/components': + specifier: workspace:* + version: link:../../packages/rsone '@tanstack/react-query': specifier: ^5.67.1 version: 5.90.12(react@19.2.3) @@ -1626,6 +1629,40 @@ importers: specifier: ^5.3.3 version: 5.9.3 + packages/rsone: + dependencies: + '@common/components': + specifier: workspace:* + version: link:../common/components + jszip: + specifier: ^3.10.1 + version: 3.10.1 + react: + specifier: ^19.2.1 + version: 19.2.3 + react-dom: + specifier: ^19.2.1 + version: 19.2.3(react@19.2.3) + realgrid: + specifier: ^2.9.5 + version: 2.9.6 + realgrid-react: + specifier: ^0.9.7 + version: 0.9.8(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + xlsx: + specifier: ^0.18.5 + version: 0.18.5 + zustand: + specifier: ^5.0.3 + version: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)) + devDependencies: + tsup: + specifier: 8.3.6 + version: 8.3.6(jiti@2.6.1)(postcss@8.5.6)(typescript@5.6.3) + typescript: + specifier: ~5.6.2 + version: 5.6.3 + packages: '@adobe/css-tools@4.4.4': From 5492ea70ed07969e1e23dfda0343d4909b9aabd0 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Fri, 9 Jan 2026 13:21:55 +0900 Subject: [PATCH 2/2] =?UTF-8?q?st:=20refactor:=20-=20=ED=86=B5=EA=B3=84=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=20=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC=20&?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD=20managemen?= =?UTF-8?q?t=20->=20input=20&=20Mng=20->=20Inp=20-=20@rsone/component=20?= =?UTF-8?q?=EB=AA=A8=EB=93=88=20=EC=88=98=EC=A0=95=20pnpm=20build=20--filt?= =?UTF-8?q?er=20@rsone/components=20=ED=9B=84=20st=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20install=20=ED=95=84=EC=9A=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/app/(with-base-layout)/layout.tsx | 17 ++++++++++--- apps/st/src/components/module/DataGrid.tsx | 2 +- apps/st/src/components/module/TabDataGrid.tsx | 2 +- .../ExcretaTreatmentFacilityInp.tsx} | 8 +++---- .../PrivateSewageFacilityInp.tsx} | 24 +++++++++---------- .../PublicSewageFacilityInp.tsx} | 8 +++---- .../PumpingStationInp.tsx} | 8 +++---- .../SewageExcretaRelatedInp.tsx} | 4 ++-- .../SewageExcretaSlurgeInp.tsx} | 4 ++-- .../SewagePipeInp.tsx} | 22 ++++++++--------- .../SewagePipeMaintainInp.tsx} | 14 +++++------ .../SewageReservoirPumpInp.tsx} | 14 +++++------ .../SewerageFinanceInp.tsx} | 18 +++++++------- .../SeweragePenetrationRateInp.tsx} | 6 ++--- .../SewerageServiceLevelInp.tsx} | 4 ++-- .../StatsInputSatusInp.tsx} | 6 ++--- .../WaterReuseInp.tsx} | 20 ++++++++-------- .../NotEnteredStatus.tsx | 0 .../StatisticsInputManagement.tsx | 0 .../StatisticsPopulationManagement.tsx | 6 ++--- .../StatisticsReviewHistory.tsx | 0 .../ExcretaTreatmentFacilityMngColumn.ts | 0 .../PublicSewageFacilityMngColumn.ts | 0 .../PumpingStationMngColumn.ts | 0 .../SeweragePenetrationRateMngColumn.ts | 0 .../StatsInputSatusMngColumn.ts | 0 ...PrivateSewageDesignationStatusMngColumn.ts | 0 .../SepticTankStatusMngColumn.ts | 0 .../SewageTreatmentFacilityStatusMngColumn.ts | 0 .../sewagePipe/ConnectionStatusMngColumn.ts | 0 .../FacilityInstallStatusMngColumn.ts | 0 .../sewagePipe/ManholeStatusMngColumn.ts | 0 .../sewagePipe/PipeDiameterStatusMngColumn.ts | 0 .../sewagePipe/PipeTypeStatusMngColumn.ts | 0 .../RegionalFacilityStatusMngColumn.ts | 0 .../PipeDredgingStatusMngColumn.ts | 0 .../RepairStatusMngColumn.ts | 0 .../RainfallPumpStationMngColumn.ts | 0 .../SewageReservoirMngColumn.ts | 0 .../sewerageFinance/CauserBurdenMngColumn.ts | 0 .../SewerageChargeMngColumn.ts | 0 .../SewerageFinanceSettlementMngColumn.ts | 0 .../SewerageUsageFeeMngColumn.ts | 0 ...ublicSewageTreatmentWaterReuseMngColumn.ts | 0 ...nfallUtilizationFacilityStatusMngColumn.ts | 0 .../RecycledWaterStatusMngColumn.ts | 0 ...erReuseBussinessApprovalStatusMngColumn.ts | 0 ...rReuseDesignConstructionStatusMngColumn.ts | 0 .../review/PrivateSewageFacilityColumnRvw.ts | 3 --- .../review/SewageExcretaRelatedColumnRvw.ts | 3 --- .../review/SewageExcretaSlurgeColumnRvw.ts | 3 --- .../util/column/review/SewagePipeColumnRvw.ts | 3 --- .../review/SewageReservoirPumpColumnRvw.ts | 4 ---- .../column/review/SewerageFinanceColumnRvw.ts | 3 --- .../review/SewerageServiceLevelColumnRvw.ts | 3 --- .../util/column/review/WaterReuseColumnRvw.ts | 3 --- apps/st/src/store/tab-store.ts | 2 +- packages/rsone/components/grid/DataGrid.tsx | 2 +- .../rsone/components/grid/TabDataGrid.tsx | 2 +- 59 files changed, 101 insertions(+), 117 deletions(-) rename apps/st/src/components/statistics/{management/ExcretaTreatmentFacilityMng.tsx => input/ExcretaTreatmentFacilityInp.tsx} (89%) rename apps/st/src/components/statistics/{management/PrivateSewageFacilityMng.tsx => input/PrivateSewageFacilityInp.tsx} (71%) rename apps/st/src/components/statistics/{management/PublicSewageFacilityMng.tsx => input/PublicSewageFacilityInp.tsx} (90%) rename apps/st/src/components/statistics/{management/PumpingStationMng.tsx => input/PumpingStationInp.tsx} (91%) rename apps/st/src/components/statistics/{management/SewageExcretaRelatedMng.tsx => input/SewageExcretaRelatedInp.tsx} (72%) rename apps/st/src/components/statistics/{management/SewageExcretaSlurgeMng.tsx => input/SewageExcretaSlurgeInp.tsx} (74%) rename apps/st/src/components/statistics/{management/SewagePipeMng.tsx => input/SewagePipeInp.tsx} (81%) rename apps/st/src/components/statistics/{management/SewagePipeMaintainMng.tsx => input/SewagePipeMaintainInp.tsx} (82%) rename apps/st/src/components/statistics/{management/SewageReservoirPumpMng.tsx => input/SewageReservoirPumpInp.tsx} (82%) rename apps/st/src/components/statistics/{management/SewerageFinanceMng.tsx => input/SewerageFinanceInp.tsx} (81%) rename apps/st/src/components/statistics/{management/SeweragePenetrationRateMng.tsx => input/SeweragePenetrationRateInp.tsx} (92%) rename apps/st/src/components/statistics/{management/SewerageServiceLevelMng.tsx => input/SewerageServiceLevelInp.tsx} (71%) rename apps/st/src/components/statistics/{management/StatsInputSatusMng.tsx => input/StatsInputSatusInp.tsx} (91%) rename apps/st/src/components/statistics/{management/WaterReuseMng.tsx => input/WaterReuseInp.tsx} (78%) rename apps/st/src/components/statistics/{system => management}/NotEnteredStatus.tsx (100%) rename apps/st/src/components/statistics/{system => management}/StatisticsInputManagement.tsx (100%) rename apps/st/src/components/statistics/{system => management}/StatisticsPopulationManagement.tsx (53%) rename apps/st/src/components/statistics/{system => management}/StatisticsReviewHistory.tsx (100%) rename apps/st/src/components/util/column/{management => input}/ExcretaTreatmentFacilityMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/PublicSewageFacilityMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/PumpingStationMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/SeweragePenetrationRateMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/StatsInputSatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/SepticTankStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/ConnectionStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/FacilityInstallStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/ManholeStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/PipeDiameterStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/PipeTypeStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipe/RegionalFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewagePipeMaintain/RepairStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageReservoirPump/RainfallPumpStationMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewageReservoirPump/SewageReservoirMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/CauserBurdenMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageChargeMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageFinanceSettlementMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/sewerageFinance/SewerageUsageFeeMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/RecycledWaterStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts (100%) rename apps/st/src/components/util/column/{management => input}/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts (100%) diff --git a/apps/st/app/(with-base-layout)/layout.tsx b/apps/st/app/(with-base-layout)/layout.tsx index b6f1e1cf8..3b79033ad 100644 --- a/apps/st/app/(with-base-layout)/layout.tsx +++ b/apps/st/app/(with-base-layout)/layout.tsx @@ -7,6 +7,7 @@ import { useQueryClient, useQuery } from "@tanstack/react-query"; import type { MenuItem } from "@/entities/menu"; import { useMenuStore, useAlertStore } from "@/shared/lib"; import { useTabStore, getTabStoreState } from "@/store/tab-store"; +import { useTabStore as gridTabStore } from "@rsone/components"; import { getConfig } from "@common/config"; import { getCookie } from "@/shared/lib"; import { getMenuList } from "../../../../packages/common/components/src/api"; @@ -33,6 +34,9 @@ export default function WithBaseLayout({ const addTab = useTabStore((state) => state.addTab); const setActiveTab = useTabStore((state) => state.setActiveTab); const setMenuList = useTabStore((state) => state.setMenuList); + const addTabForGrid = gridTabStore((state) => state.addTab); + const setActiveTabForGrid = gridTabStore((state) => state.setActiveTab); + const setMenuListForGrid = gridTabStore((state) => state.setMenuList); const alert = useAlertStore((state) => state.setMessage); const { data: menuListData } = useQuery({ @@ -44,8 +48,9 @@ export default function WithBaseLayout({ useEffect(() => { if (menuListData) { setMenuList(menuListData); + setMenuListForGrid(menuListData); } - }, [menuListData, setMenuList]); + }, [menuListData, setMenuList, setMenuListForGrid]); useEffect(() => { if (!pathname) return; @@ -55,18 +60,24 @@ export default function WithBaseLayout({ const tab = currentTabs.find((t) => t.path === pathname); if (tab) { setActiveTab(tab.id); + setActiveTabForGrid(tab.id); } - }, [pathname, setActiveTab]); + }, [pathname, setActiveTab, setActiveTabForGrid]); const handleMenuClick = useCallback((item: MenuItem) => { setCurrentMenuInfo(item); const addTabResult: boolean = addTab(item); + + // packages/rsone의 스토어에도 동기화 + if (addTabResult) { + addTabForGrid(item); + } if (!addTabResult) { alert(`최대 추가 할 수 있는 화면 수를 초과 하였습니다. 기존 화면을 닫은 후 이용해주세요.`); } - }, [setCurrentMenuInfo, addTab]); + }, [setCurrentMenuInfo, addTab, addTabForGrid]); return ( 07. 분뇨처리시설 -const ExcretaTreatmentFacilityMng = () => { +const ExcretaTreatmentFacilityInp = () => { const submitExceptionFunc = () => { console.log('submit exception'); @@ -47,4 +47,4 @@ const ExcretaTreatmentFacilityMng = () => { ); }; -export default ExcretaTreatmentFacilityMng; \ No newline at end of file +export default ExcretaTreatmentFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx similarity index 71% rename from apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx rename to apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx index a55219cdd..6037d0f05 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/input/PrivateSewageFacilityInp.tsx @@ -1,25 +1,25 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from "@rsone/components"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn" -import { SepticTankStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn" -import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn" +import { SewageTreatmentFacilityStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn" +import { SepticTankStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn" +import { PrivateSewageDesignationStatusMngColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn" // 하수도 통계 관리 > 08. 개인하수처리시설 -const PrivateSewageFacilityMng = () => { +const PrivateSewageFacilityInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const PrivateSewageFacilityMngColumnList = [ - SewageTreatmentFacilityStatusMngColumn, - SepticTankStatusMngColumn, - PrivateSewageDesignationStatusMngColumn - ]; + const PrivateSewageFacilityInpColumnList = [ + SewageTreatmentFacilityStatusMngColumn, + SepticTankStatusMngColumn, + PrivateSewageDesignationStatusMngColumn + ]; const submitExceptionFunc = () => { // TODO: 예외 제출 로직 구현 @@ -51,9 +51,9 @@ const PrivateSewageFacilityMng = () => {
- + ); }; -export default PrivateSewageFacilityMng; \ No newline at end of file +export default PrivateSewageFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx similarity index 90% rename from apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx rename to apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx index 4a2478ef9..39b7ed480 100644 --- a/apps/st/src/components/statistics/management/PublicSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/input/PublicSewageFacilityInp.tsx @@ -1,15 +1,15 @@ import SearchForm from '@/components/module/SearchForm'; -import DataGrid from '@/components/module/DataGrid'; +import { DataGrid } from '@rsone/components'; import SubmitButton from '@/components/button/SumitButton'; import SaveButton from '@/components/button/SaveButton'; import SubmitExceptionButton from '@/components/button/SubmitExceptionButton'; import OperateDataButton from '@/components/button/OperateDataButton'; import { useState } from 'react'; -import { PublicSewageFacilityMngColumn } from '@/components/util/column/management/PublicSewageFacilityMngColumn'; +import { PublicSewageFacilityMngColumn } from '@/components/util/column/input/PublicSewageFacilityMngColumn'; // 하수도 통계 관리 > 06. 공공하수처리시설 -const PublicSewageFacilityMng = () => { +const PublicSewageFacilityInp = () => { const SubmitExceptionFunc = () => { console.log('submitException'); @@ -47,4 +47,4 @@ const PublicSewageFacilityMng = () => { ); }; -export default PublicSewageFacilityMng; \ No newline at end of file +export default PublicSewageFacilityInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/PumpingStationMng.tsx b/apps/st/src/components/statistics/input/PumpingStationInp.tsx similarity index 91% rename from apps/st/src/components/statistics/management/PumpingStationMng.tsx rename to apps/st/src/components/statistics/input/PumpingStationInp.tsx index 18647218a..e1b846292 100644 --- a/apps/st/src/components/statistics/management/PumpingStationMng.tsx +++ b/apps/st/src/components/statistics/input/PumpingStationInp.tsx @@ -1,14 +1,14 @@ import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; +import { DataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { PumpingStationMngColumn } from "@/components/util/column/management/PumpingStationMngColumn" +import { PumpingStationMngColumn } from "@/components/util/column/input/PumpingStationMngColumn" // 하수도 통계 관리 > 05. 펌프장 -const PumpingStationMng = () => { +const PumpingStationInp = () => { const SubmitExceptionFunc = () => { console.log('submit exception'); @@ -46,4 +46,4 @@ const PumpingStationMng = () => { ); }; -export default PumpingStationMng; \ No newline at end of file +export default PumpingStationInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx similarity index 72% rename from apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx rename to apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx index e0d5ab6ba..d0cfa9b83 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaRelatedMng.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaRelatedInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "@/components/module/SearchForm"; // 하수도 통계 관리 > 12. 하수 및 분뇨관련산업 -const SewageExcretaRelatedMng = () => { +const SewageExcretaRelatedInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewageExcretaRelatedMng = () => { ); }; -export default SewageExcretaRelatedMng; \ No newline at end of file +export default SewageExcretaRelatedInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx similarity index 74% rename from apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx rename to apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx index fc3ac670f..4035ea184 100644 --- a/apps/st/src/components/statistics/management/SewageExcretaSlurgeMng.tsx +++ b/apps/st/src/components/statistics/input/SewageExcretaSlurgeInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "@/components/module/SearchForm"; // 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 -const SewageExcretaSlurgeMng = () => { +const SewageExcretaSlurgeInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewageExcretaSlurgeMng = () => { ); }; -export default SewageExcretaSlurgeMng; \ No newline at end of file +export default SewageExcretaSlurgeInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx similarity index 81% rename from apps/st/src/components/statistics/management/SewagePipeMng.tsx rename to apps/st/src/components/statistics/input/SewagePipeInp.tsx index 725717013..7bdd82819 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,28 +1,28 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDateButton from "@/components/button/OperateDataButton"; -import { RegionalFacilityStatusMngColumn } from "@/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn"; -import { FacilityInstallStatusMngColumn } from "@/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn"; -import { PipeTypeStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn"; -import { PipeDiameterStatusMngColumn } from "@/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn"; -import { ManholeStatusMngColumn } from "@/components/util/column/management/sewagePipe/ManholeStatusMngColumn"; +import { RegionalFacilityStatusMngColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn"; +import { FacilityInstallStatusMngColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn"; +import { PipeTypeStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn"; +import { PipeDiameterStatusMngColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn"; +import { ManholeStatusMngColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusMngColumn"; import { AdminAreaConnectionMngColumn, TreatmentPlantConnectionMngColumn -} from "@/components/util/column/management/sewagePipe/ConnectionStatusMngColumn"; +} from "@/components/util/column/input/sewagePipe/ConnectionStatusMngColumn"; // 하수도 통계 관리 > 02. 하수관로 -const SewagePipeMng = () => { +const SewagePipeInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMngColumnList = [ + const SewagePipeInpColumnList = [ RegionalFacilityStatusMngColumn, FacilityInstallStatusMngColumn, PipeTypeStatusMngColumn, @@ -69,9 +69,9 @@ const SewagePipeMng = () => {
- + ); }; -export default SewagePipeMng; \ No newline at end of file +export default SewagePipeInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx similarity index 82% rename from apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx rename to apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx index 8e27653f3..1620c26d2 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeMaintainInp.tsx @@ -1,21 +1,21 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { RepairStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn"; -import { PipeDredgingStatusMngColumn } from "@/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn"; +import { RepairStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn"; +import { PipeDredgingStatusMngColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn"; // 하수도 통계 관리 > 03. 하수관로 유지관리 -const SewagePipeMaintainMng = () => { +const SewagePipeMaintainInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewagePipeMaintainMngColumnList = [ + const SewagePipeMaintainInpColumnList = [ RepairStatusMngColumn, PipeDredgingStatusMngColumn ]; @@ -51,9 +51,9 @@ const SewagePipeMaintainMng = () => { - + ); }; -export default SewagePipeMaintainMng; \ No newline at end of file +export default SewagePipeMaintainInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx similarity index 82% rename from apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx rename to apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx index 615bf21be..ed8697882 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/input/SewageReservoirPumpInp.tsx @@ -1,20 +1,20 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import { SewageReservoirMngColumn } from "@/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn"; -import { RainfallPumpStationMngColumn } from "@/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn"; +import { SewageReservoirMngColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn"; +import { RainfallPumpStationMngColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn"; // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 -const SewageReservoirPumpMng = () => { +const SewageReservoirPumpInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List - const SewageReservoirPumpMngColumnList = [ + const SewageReservoirPumpInpColumnList = [ SewageReservoirMngColumn, RainfallPumpStationMngColumn ]; @@ -48,9 +48,9 @@ const SewageReservoirPumpMng = () => { - + ); }; -export default SewageReservoirPumpMng; \ No newline at end of file +export default SewageReservoirPumpInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx similarity index 81% rename from apps/st/src/components/statistics/management/SewerageFinanceMng.tsx rename to apps/st/src/components/statistics/input/SewerageFinanceInp.tsx index 8ea794818..d4120c2f2 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/input/SewerageFinanceInp.tsx @@ -1,22 +1,22 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; -import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn" -import { SewerageChargeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageChargeMngColumn" -import { SewerageUsageFeeMngColumn } from "@/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn" -import { CauserBurdenMngColumn } from "@/components/util/column/management/sewerageFinance/CauserBurdenMngColumn" +import { SewerageFinanceSettlementMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn" +import { SewerageChargeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeMngColumn" +import { SewerageUsageFeeMngColumn } from "@/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn" +import { CauserBurdenMngColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenMngColumn" // 하수도 통계 관리 > 09. 하수도재정 -const SewerageFinanceMng = () => { +const SewerageFinanceInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const SewerageFinanceMngList = [ + const SewerageFinanceInpList = [ SewerageFinanceSettlementMngColumn, SewerageChargeMngColumn, SewerageUsageFeeMngColumn, @@ -54,9 +54,9 @@ const SewerageFinanceMng = () => { - + ); }; -export default SewerageFinanceMng; \ No newline at end of file +export default SewerageFinanceInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx similarity index 92% rename from apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx rename to apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx index 1db839f81..bed3fa5d4 100644 --- a/apps/st/src/components/statistics/management/SeweragePenetrationRateMng.tsx +++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx @@ -7,10 +7,10 @@ import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import { useState } from "react"; -import { SeweragePenetrationRateMngColumn } from "@/components/util/column/management/SeweragePenetrationRateMngColumn"; +import { SeweragePenetrationRateMngColumn } from "@/components/util/column/input/SeweragePenetrationRateMngColumn"; // 하수도 통계 관리 > 01. 하수도 보급률 -const SeweragePenetrationRateMng = () => { +const SeweragePenetrationRateInp = () => { const SubmitExceptionFunc = () => { console.log('submit exception'); @@ -57,4 +57,4 @@ const SeweragePenetrationRateMng = () => { ); }; -export default SeweragePenetrationRateMng; \ No newline at end of file +export default SeweragePenetrationRateInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx similarity index 71% rename from apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx rename to apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx index e7bdc2945..904bb42f6 100644 --- a/apps/st/src/components/statistics/management/SewerageServiceLevelMng.tsx +++ b/apps/st/src/components/statistics/input/SewerageServiceLevelInp.tsx @@ -1,7 +1,7 @@ import SearchForm from "../../module/SearchForm"; // 하수도 통계 관리 > 13. 하수도 서비스 수준 -const SewerageServiceLevelMng = () => { +const SewerageServiceLevelInp = () => { return ( <> @@ -9,4 +9,4 @@ const SewerageServiceLevelMng = () => { ); }; -export default SewerageServiceLevelMng; \ No newline at end of file +export default SewerageServiceLevelInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx similarity index 91% rename from apps/st/src/components/statistics/management/StatsInputSatusMng.tsx rename to apps/st/src/components/statistics/input/StatsInputSatusInp.tsx index c753f23c7..b4fbb367a 100644 --- a/apps/st/src/components/statistics/management/StatsInputSatusMng.tsx +++ b/apps/st/src/components/statistics/input/StatsInputSatusInp.tsx @@ -4,10 +4,10 @@ import ApproveButton from "@/components/button/ApproveButton"; import RejectButton from "@/components/button/RejectButton"; import { useState } from "react"; -import { StatsInputSatusMngColumn } from "@/components/util/column/management/StatsInputSatusMngColumn"; +import { StatsInputSatusMngColumn } from "@/components/util/column/input/StatsInputSatusMngColumn"; // 하수도 통계 관리 > 00. 통계 입력 현황 -const StatsInputSatusMng = () => { +const StatsInputSatusInp = () => { const rejectFunc = () => { console.log('reject'); @@ -35,4 +35,4 @@ const StatsInputSatusMng = () => { ); }; -export default StatsInputSatusMng; \ No newline at end of file +export default StatsInputSatusInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/management/WaterReuseMng.tsx b/apps/st/src/components/statistics/input/WaterReuseInp.tsx similarity index 78% rename from apps/st/src/components/statistics/management/WaterReuseMng.tsx rename to apps/st/src/components/statistics/input/WaterReuseInp.tsx index 1edfa2ee1..d8a3b8bc3 100644 --- a/apps/st/src/components/statistics/management/WaterReuseMng.tsx +++ b/apps/st/src/components/statistics/input/WaterReuseInp.tsx @@ -1,25 +1,25 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import TabDataGrid from "@/components/module/TabDataGrid"; +import { TabDataGrid } from '@rsone/components'; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; import OperateDataButton from "@/components/button/OperateDataButton" -import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; -import { RecycledWaterStatusMngColumn } from "@/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn"; -import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; -import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; -import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; +import { PublicSewageTreatmentWaterReuseMngColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn"; +import { RecycledWaterStatusMngColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn"; +import { RainfallUtilizationFacilityStatusMngColumn } from "@/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn"; +import { TreatmentWaterReuseDesignConstructionStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn"; +import { TreatmentWaterReuseBussinessApprovalStatusMngColumn } from "@/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn"; // 하수도 통계 관리 > 10. 물 재이용 -const WaterReuseMng = () => { +const WaterReuseInp = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab list - const WaterReuseMngColumnList = [ + const WaterReuseInpColumnList = [ PublicSewageTreatmentWaterReuseMngColumn, RecycledWaterStatusMngColumn, RainfallUtilizationFacilityStatusMngColumn, @@ -63,9 +63,9 @@ const WaterReuseMng = () => { - + ); }; -export default WaterReuseMng; \ No newline at end of file +export default WaterReuseInp; \ No newline at end of file diff --git a/apps/st/src/components/statistics/system/NotEnteredStatus.tsx b/apps/st/src/components/statistics/management/NotEnteredStatus.tsx similarity index 100% rename from apps/st/src/components/statistics/system/NotEnteredStatus.tsx rename to apps/st/src/components/statistics/management/NotEnteredStatus.tsx diff --git a/apps/st/src/components/statistics/system/StatisticsInputManagement.tsx b/apps/st/src/components/statistics/management/StatisticsInputManagement.tsx similarity index 100% rename from apps/st/src/components/statistics/system/StatisticsInputManagement.tsx rename to apps/st/src/components/statistics/management/StatisticsInputManagement.tsx diff --git a/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx similarity index 53% rename from apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx rename to apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx index 688c15d7e..dabf80854 100644 --- a/apps/st/src/components/statistics/system/StatisticsPopulationManagement.tsx +++ b/apps/st/src/components/statistics/management/StatisticsPopulationManagement.tsx @@ -1,11 +1,9 @@ -import { useState } from "react"; +// import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import DataGrid from "@/components/module/DataGrid"; -import type { ColumnConfig } from "@/components/type/DataGrid.type"; const StatisticsPopulationManagement = () => { - const [rowData, setRowData] = useState[]>([]); + // const [rowData, setRowData] = useState[]>([]); return ( <> diff --git a/apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx b/apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx similarity index 100% rename from apps/st/src/components/statistics/system/StatisticsReviewHistory.tsx rename to apps/st/src/components/statistics/management/StatisticsReviewHistory.tsx diff --git a/apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts b/apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/ExcretaTreatmentFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/ExcretaTreatmentFacilityMngColumn.ts diff --git a/apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts b/apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/PublicSewageFacilityMngColumn.ts rename to apps/st/src/components/util/column/input/PublicSewageFacilityMngColumn.ts diff --git a/apps/st/src/components/util/column/management/PumpingStationMngColumn.ts b/apps/st/src/components/util/column/input/PumpingStationMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/PumpingStationMngColumn.ts rename to apps/st/src/components/util/column/input/PumpingStationMngColumn.ts diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts rename to apps/st/src/components/util/column/input/SeweragePenetrationRateMngColumn.ts diff --git a/apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts b/apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/StatsInputSatusMngColumn.ts rename to apps/st/src/components/util/column/input/StatsInputSatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/PrivateSewageDesignationStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/SepticTankStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SepticTankStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/privateSewageFacility/SewageTreatmentFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/ConnectionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/FacilityInstallStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/FacilityInstallStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/ManholeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/ManholeStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/PipeDiameterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeDiameterStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/PipeTypeStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/PipeTypeStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipe/RegionalFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipe/RegionalFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts b/apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewagePipeMaintain/RepairStatusMngColumn.ts rename to apps/st/src/components/util/column/input/sewagePipeMaintain/RepairStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageReservoirPump/RainfallPumpStationMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/RainfallPumpStationMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts b/apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewageReservoirPump/SewageReservoirMngColumn.ts rename to apps/st/src/components/util/column/input/sewageReservoirPump/SewageReservoirMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/CauserBurdenMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/CauserBurdenMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/CauserBurdenMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageChargeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageChargeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageChargeMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageFinanceSettlementMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageFinanceSettlementMngColumn.ts diff --git a/apps/st/src/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn.ts b/apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/sewerageFinance/SewerageUsageFeeMngColumn.ts rename to apps/st/src/components/util/column/input/sewerageFinance/SewerageUsageFeeMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/PublicSewageTreatmentWaterReuseMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RainfallUtilizationFacilityStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/RecycledWaterStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/RecycledWaterStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseBussinessApprovalStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts b/apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts similarity index 100% rename from apps/st/src/components/util/column/management/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts rename to apps/st/src/components/util/column/input/waterReuse/TreatmentWaterReuseDesignConstructionStatusMngColumn.ts diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts index 9e3d2c8ba..e5ade8499 100644 --- a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts +++ b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawPrivateSewageList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts index e9bcfac0d..16f2c6701 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaRelatedColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawExcretaRelatedList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts index 4cf62583e..856f0582e 100644 --- a/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageExcretaSlurgeColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawSludgeList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts index 1158e32d3..bdeb4d6ce 100644 --- a/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewagePipeColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const baseYear = new Date().getFullYear(); const rawList = [ diff --git a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts index 66cc56fd7..be1b6911c 100644 --- a/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewageReservoirPumpColumnRvw.ts @@ -1,7 +1,3 @@ - -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawReservoirList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts index 242c2169b..c98b026c5 100644 --- a/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageFinanceColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawFinanceList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts index b762c43f4..36a3fcedd 100644 --- a/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts +++ b/apps/st/src/components/util/column/review/SewerageServiceLevelColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawServiceLevelList = [ { tabKey: 'a', diff --git a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts index 0498dd9d6..d23df45c1 100644 --- a/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts +++ b/apps/st/src/components/util/column/review/WaterReuseColumnRvw.ts @@ -1,6 +1,3 @@ -import type { GridView, DataColumn } from "@/components/type/DataGrid.type"; -import { getFooterSummary } from "@/components/util/grid/footerSummary"; - const rawWaterReuseList = [ { tabKey: 'a', diff --git a/apps/st/src/store/tab-store.ts b/apps/st/src/store/tab-store.ts index cdbaad91f..6c48a5074 100644 --- a/apps/st/src/store/tab-store.ts +++ b/apps/st/src/store/tab-store.ts @@ -39,7 +39,7 @@ const useTabStoreHook = create((set, get) => ({ return true; } - if (tabs.length < 100) { + if (tabs.length < 10) { const newTab: Tab = { id: tabId, label: menuItem.menuKornNm, diff --git a/packages/rsone/components/grid/DataGrid.tsx b/packages/rsone/components/grid/DataGrid.tsx index 4c9a50522..21d921130 100644 --- a/packages/rsone/components/grid/DataGrid.tsx +++ b/packages/rsone/components/grid/DataGrid.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect } from "react" import { ValueType } from "realgrid" -import RealGrid, { GridFitStyle, type DisplayOptions, SortDirection } from "realgrid" +import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { DataGridProps } from "../type/DataGrid.type" import JSZip from "jszip" diff --git a/packages/rsone/components/grid/TabDataGrid.tsx b/packages/rsone/components/grid/TabDataGrid.tsx index 191ebaea3..f125d0c86 100644 --- a/packages/rsone/components/grid/TabDataGrid.tsx +++ b/packages/rsone/components/grid/TabDataGrid.tsx @@ -1,7 +1,7 @@ import { useRef, useEffect, useState } from "react" import { ValueType } from "realgrid" -import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" +import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" import type { TabDataGridProps } from "../type/DataGrid.type" import JSZip from "jszip"