diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index 6948defeb..8d2ab711e 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -7,8 +7,9 @@ import ApproveButton from "@/components/button/ApproveButton"; import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; -import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumnRvw"; +import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/review/PrivateSewageFacilityColumn"; +// 하수도 통계 관리 08.개인하수처리시설 const PrivateSewageFacilityRvw = () => { const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); @@ -35,11 +36,13 @@ const PrivateSewageFacilityRvw = () => { return ( <> -
- - - - +
+
+ + + + +
diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts new file mode 100644 index 000000000..c626ba504 --- /dev/null +++ b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumn.ts @@ -0,0 +1,139 @@ +import { ValueType } from "realgrid"; + +// 하수도 통계 관리 08.개인하수처리시설 +const rawPrivateSewageList = [ + { + tabKey: 'a', + tabLabel: '처리용량별 오수처리시설 현황', + rowStartNum: 3, + fixedColumns: 2, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'STTY_SM', fieldName: '총계', header: { text: '총계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_SM', fieldName: '계(처리구역 내)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_2', fieldName: '2이하(처리구역 내)', header: { text: '2이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_3', fieldName: '3~10(처리구역 내)', header: { text: '3~10' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_11', fieldName: '11~20(처리구역 내)', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_21', fieldName: '21~50(처리구역 내)', header: { text: '21~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_51', fieldName: '51~100(처리구역 내)', header: { text: '51~100' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_101', fieldName: '101~500(처리구역 내)', header: { text: '101~500' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_INNER_501', fieldName: '501이상(처리구역 내)', header: { text: '501이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_SM', fieldName: '계(처리구역 외)', header: { text: '계' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_2', fieldName: '2이하(처리구역 외)', header: { text: '2이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_3', fieldName: '3~10(처리구역 외)', header: { text: '3~10' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_11', fieldName: '11~20(처리구역 외)', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_21', fieldName: '21~50(처리구역 외)', header: { text: '21~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_51', fieldName: '51~100(처리구역 외)', header: { text: '51~100' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_101', fieldName: '101~500(처리구역 외)', header: { text: '101~500' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'STTY_ZONE_OUTER_501', fieldName: '501이상(처리구역 외)', header: { text: '501이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'STTY_SM', + { + name: 'individualGroup', header: { text: '오수처리시설' }, + items: [ + { + name: 'innerGroup', header: { text: '하수처리구역 내(㎥/일)' }, + items: ['STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501'] + }, + { + name: 'outerGroup', header: { text: '하수처리구역 외(㎥/일)' }, + items: ['STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501'] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'b', + tabLabel: '정화조현황', + rowStartNum: 4, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'TOT_FCLTY_CNT', fieldName: '총 시설 수(A+D)', header: { text: '총 시설 수\n(A+D)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_SM', fieldName: '총계 A=(B+C)/2', header: { text: '총계\nA=(B+C)/2' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_NPFL', fieldName: '자연유하', header: { text: '자연유하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ENFCT_PUMP', fieldName: '강제펌핑식', header: { text: '강제펌핑식' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_TFM', fieldName: '살수여상', header: { text: '살수여상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ARTM', fieldName: '폭기방법', header: { text: '폭기방법' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_CTARM', fieldName: '접촉폭기', header: { text: '접촉폭기' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_ETC', fieldName: '기타(방식)', header: { text: '기타' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_SM', fieldName: '계(C)', header: { text: '계(C)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_1', fieldName: '10인조 이하', header: { text: '10인조 이하' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_2', fieldName: '11~20', header: { text: '11~20' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_3', fieldName: '21~30', header: { text: '21~30' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_4', fieldName: '31~50', header: { text: '31~50' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_5', fieldName: '51~199', header: { text: '51~199' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_6', fieldName: '200~499', header: { text: '200~499' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_7', fieldName: '500~999', header: { text: '500~999' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'SPZI_PROC_CPC_8', fieldName: '1,000이상', header: { text: '1,000이상' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } } + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', 'TOT_FCLTY_CNT', + { + name: 'innerMainGroup', header: { text: '하수처리구역 내' }, + items: [ + 'SPZI_SM', + { + name: 'innerMethodGroup', header: { text: '처리방식별' }, + items: [{ name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC'] + }, + { + name: 'innerCpcGroup', header: { text: '처리용량별' }, + items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] + } + ] + }, + 'RMK' + ] + }, + { + tabKey: 'c', + tabLabel: '개인하수도 관리지역 지정공고 현황', + rowStartNum: 3, + fixedColumns: 1, + columns: [ + { name: 'SIDO', fieldName: '시도', header: { text: '시도' } }, + { name: 'GUGUN', fieldName: '시군구', header: { text: '시군구' } }, + { name: 'YR_GBN', fieldName: '구분', header: { text: '구분' } }, + { name: 'MGMT_AR', fieldName: '공고지역(개소)', header: { text: '공고지역\n(개소)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0' }, + { name: 'APPN_SCOPE', fieldName: '지정범위(㎢)', header: { text: '지정범위\n(㎢)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'WRRTN_CNT', fieldName: '개소수(정화조)', header: { text: '개소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'WRRTN_CPC', fieldName: '처리용량(인/일)', header: { text: '처리용량\n(인/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'STTY_CNT', fieldName: '개소수(오수시설)', header: { text: '개소수' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'STTY_CPC', fieldName: '처리용량(㎥/일)', header: { text: '처리용량\n(㎥/일)' }, valueType: ValueType.NUMBER, numberFormat: '#,##0.0' }, + { name: 'RMK', fieldName: '비고', header: { text: '비고' } }, + ], + columnLayout: [ + { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, + 'YR_GBN', + { + name: 'mgmtMainGroup', header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, + items: [ + 'MGMT_AR', 'APPN_SCOPE', + { name: 'septictankGroup', header: { text: '정화조' }, items: ['WRRTN_CNT', 'WRRTN_CPC'] }, + { name: 'sewageFacGroup', header: { text: '오수시설' }, items: ['STTY_CNT', 'STTY_CPC'] } + ] + }, + 'RMK' + ] + } +]; + +export const PrivateSewageFacilityInfoListRvw = rawPrivateSewageList.map(tab => ({ + ...tab, + columns: tab.columns.map(col => ({ + ...col, + editable: false + })) +})); \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts b/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts deleted file mode 100644 index e5ade8499..000000000 --- a/apps/st/src/components/util/column/review/PrivateSewageFacilityColumnRvw.ts +++ /dev/null @@ -1,161 +0,0 @@ -const rawPrivateSewageList = [ - { - tabKey: 'a', - tabLabel: '처리용량별 오수처리시설 현황', - rowStartNum: 3, - fixedColumns: 2, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 총계 */ - { name: 'STTY_SM', fieldName: 'STTY_SM', header: { text: '총계' } }, - - /* 3. 하수처리구역 내 */ - { name: 'STTY_ZONE_INNER_SM', fieldName: 'STTY_ZONE_INNER_SM', header: { text: '계' } }, - { name: 'STTY_ZONE_INNER_2', fieldName: 'STTY_ZONE_INNER_2', header: { text: '2이하' } }, - { name: 'STTY_ZONE_INNER_3', fieldName: 'STTY_ZONE_INNER_3', header: { text: '3~10' } }, - { name: 'STTY_ZONE_INNER_11', fieldName: 'STTY_ZONE_INNER_11', header: { text: '11~20' } }, - { name: 'STTY_ZONE_INNER_21', fieldName: 'STTY_ZONE_INNER_21', header: { text: '21~50' } }, - { name: 'STTY_ZONE_INNER_51', fieldName: 'STTY_ZONE_INNER_51', header: { text: '51~100' } }, - { name: 'STTY_ZONE_INNER_101', fieldName: 'STTY_ZONE_INNER_101', header: { text: '101~500' } }, - { name: 'STTY_ZONE_INNER_501', fieldName: 'STTY_ZONE_INNER_501', header: { text: '501이상' } }, - - /* 4. 하수처리구역 외 */ - { name: 'STTY_ZONE_OUTER_SM', fieldName: 'STTY_ZONE_OUTER_SM', header: { text: '계' } }, - { name: 'STTY_ZONE_OUTER_2', fieldName: 'STTY_ZONE_OUTER_2', header: { text: '2이하' } }, - { name: 'STTY_ZONE_OUTER_3', fieldName: 'STTY_ZONE_OUTER_3', header: { text: '3~10' } }, - { name: 'STTY_ZONE_OUTER_11', fieldName: 'STTY_ZONE_OUTER_11', header: { text: '11~20' } }, - { name: 'STTY_ZONE_OUTER_21', fieldName: 'STTY_ZONE_OUTER_21', header: { text: '21~50' } }, - { name: 'STTY_ZONE_OUTER_51', fieldName: 'STTY_ZONE_OUTER_51', header: { text: '51~100' } }, - { name: 'STTY_ZONE_OUTER_101', fieldName: 'STTY_ZONE_OUTER_101', header: { text: '101~500' } }, - { name: 'STTY_ZONE_OUTER_501', fieldName: 'STTY_ZONE_OUTER_501', header: { text: '501이상' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'STTY_SM', - { - name: 'individualGroup', header: { text: '오수처리시설' }, - items: [ - { - name: 'innerGroup', header: { text: '하수처리구역 내(㎥/일)' }, - items: ['STTY_ZONE_INNER_SM', 'STTY_ZONE_INNER_2', 'STTY_ZONE_INNER_3', 'STTY_ZONE_INNER_11', 'STTY_ZONE_INNER_21', 'STTY_ZONE_INNER_51', 'STTY_ZONE_INNER_101', 'STTY_ZONE_INNER_501'] - }, - { - name: 'outerGroup', header: { text: '하수처리구역 외(㎥/일)' }, - items: ['STTY_ZONE_OUTER_SM', 'STTY_ZONE_OUTER_2', 'STTY_ZONE_OUTER_3', 'STTY_ZONE_OUTER_11', 'STTY_ZONE_OUTER_21', 'STTY_ZONE_OUTER_51', 'STTY_ZONE_OUTER_101', 'STTY_ZONE_OUTER_501'] - } - ] - }, - 'RMK' - ] - }, - { - tabKey: 'b', - tabLabel: '정화조현황', - rowStartNum: 4, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - { name: 'TOT_FCLTY_CNT', fieldName: 'TOT_FCLTY_CNT', header: { text: '총 시설 수\n(A+D)' } }, - - /* 2. 하수처리구역 내 - 총계 및 처리방식별 */ - { name: 'SPZI_SM', fieldName: 'SPZI_SM', header: { text: '총계\nA=(B+C)/2' } }, - { name: 'SPZI_NPFL', fieldName: 'SPZI_NPFL', header: { text: '자연유하' } }, - { name: 'SPZI_ENFCT_PUMP', fieldName: 'SPZI_ENFCT_PUMP', header: { text: '강제펌핑식' } }, - { name: 'SPZI_TFM', fieldName: 'SPZI_TFM', header: { text: '살수여상' } }, - { name: 'SPZI_ARTM', fieldName: 'SPZI_ARTM', header: { text: '폭기방법' } }, - { name: 'SPZI_CTARM', fieldName: 'SPZI_CTARM', header: { text: '접촉폭기' } }, - { name: 'SPZI_ETC', fieldName: 'SPZI_ETC', header: { text: '기타' } }, - - /* 3. 하수처리구역 내 - 처리용량별 */ - { name: 'SPZI_PROC_CPC_SM', fieldName: 'SPZI_PROC_CPC_SM', header: { text: '계(C)' } }, - { name: 'SPZI_PROC_CPC_1', fieldName: 'SPZI_PROC_CPC_1', header: { text: '10인조 이하' } }, - { name: 'SPZI_PROC_CPC_2', fieldName: 'SPZI_PROC_CPC_2', header: { text: '11~20' } }, - { name: 'SPZI_PROC_CPC_3', fieldName: 'SPZI_PROC_CPC_3', header: { text: '21~30' } }, - { name: 'SPZI_PROC_CPC_4', fieldName: 'SPZI_PROC_CPC_4', header: { text: '31~50' } }, - { name: 'SPZI_PROC_CPC_5', fieldName: 'SPZI_PROC_CPC_5', header: { text: '51~199' } }, - { name: 'SPZI_PROC_CPC_6', fieldName: 'SPZI_PROC_CPC_6', header: { text: '200~499' } }, - { name: 'SPZI_PROC_CPC_7', fieldName: 'SPZI_PROC_CPC_7', header: { text: '500~999' } }, - { name: 'SPZI_PROC_CPC_8', fieldName: 'SPZI_PROC_CPC_8', header: { text: '1,000이상' } }, - - /* 4. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } } - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', 'TOT_FCLTY_CNT', - { - name: 'innerMainGroup', header: { text: '하수처리구역 내' }, - items: [ - 'SPZI_SM', - { - name: 'innerMethodGroup', header: { text: '처리방식별' }, - items: [{ name: 'innerTankGroup', header: { text: '부패탱크' }, items: ['SPZI_NPFL', 'SPZI_ENFCT_PUMP'] }, 'SPZI_TFM', 'SPZI_ARTM', 'SPZI_CTARM', 'SPZI_ETC'] - }, - { - name: 'innerCpcGroup', header: { text: '처리용량별' }, - items: ['SPZI_PROC_CPC_SM', 'SPZI_PROC_CPC_1', 'SPZI_PROC_CPC_2', 'SPZI_PROC_CPC_3', 'SPZI_PROC_CPC_4', 'SPZI_PROC_CPC_5', 'SPZI_PROC_CPC_6', 'SPZI_PROC_CPC_7', 'SPZI_PROC_CPC_8'] - } - ] - }, - 'RMK' - ] - }, - { - tabKey: 'c', - tabLabel: '개인하수도 관리지역 지정공고 현황', - rowStartNum: 3, - fixedColumns: 1, - columns: [ - /* 1. 행정 및 기본 정보 */ - { name: 'SIDO', fieldName: 'SIDO', header: { text: '시도' } }, - { name: 'GUGUN', fieldName: 'GUGUN', header: { text: '시군구' } }, - { name: 'YR_GBN', fieldName: 'YR_GBN', header: { text: '구분' } }, - - /* 2. 관리지역 공고 현황 */ - { name: 'MGMT_AR', fieldName: 'MGMT_AR', header: { text: '공고지역\n(개소)' } }, - { name: 'APPN_SCOPE', fieldName: 'APPN_SCOPE', header: { text: '지정범위\n(㎢)' } }, - - /* 3. 정화조 상세 */ - { name: 'WRRTN_CNT', fieldName: 'WRRTN_CNT', header: { text: '개소수' } }, - { name: 'WRRTN_CPC', fieldName: 'WRRTN_CPC', header: { text: '처리용량\n(인/일)' } }, - - /* 4. 오수시설 상세 */ - { name: 'STTY_CNT', fieldName: 'STTY_CNT', header: { text: '개소수' } }, - { name: 'STTY_CPC', fieldName: 'STTY_CPC', header: { text: '처리용량\n(㎥/일)' } }, - - /* 5. 비고 */ - { name: 'RMK', fieldName: 'RMK', header: { text: '비고' } }, - ], - columnLayout: [ - { name: 'addrGroup', header: { text: '행정구역' }, items: ['SIDO', 'GUGUN'] }, - 'YR_GBN', - { - name: 'mgmtMainGroup', header: { text: '개인하수도관리지역공고현황\n(하수도법 제34조의2)' }, - items: [ - 'MGMT_AR', 'APPN_SCOPE', - { name: 'septictankGroup', header: { text: '정화조' }, items: ['WRRTN_CNT', 'WRRTN_CPC'] }, - { name: 'sewageFacGroup', header: { text: '오수시설' }, items: ['STTY_CNT', 'STTY_CPC'] } - ] - }, - 'RMK' - ] - } -]; - -export const PrivateSewageFacilityInfoListRvw = rawPrivateSewageList.map(tab => ({ - ...tab, - columns: tab.columns.map(col => ({ - ...col, - editable: false - })) -})); \ No newline at end of file