Merge branch 'iipbs/st/dev' of https://www.onasys.co.kr:3000/ONAANDALL/frontend into iipbs/st/dev

This commit is contained in:
2026-03-30 17:11:10 +09:00
22 changed files with 2556 additions and 2512 deletions
+1 -1
View File
@@ -25,7 +25,7 @@
},
"devDependencies": {
"eslint": "^9.0.0",
"eslint-config-next": "15.4.0",
"eslint-config-next": "15.3.8",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -52,7 +52,7 @@
"@types/node": "^22.13.1",
"@types/webpack": "^5.28.5",
"eslint": "^9.0.0",
"eslint-config-next": "15.4.0",
"eslint-config-next": "15.3.8",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -46,7 +46,7 @@
"@types/node": "^22.13.1",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -52,7 +52,7 @@
"@types/node": "^22.13.1",
"@types/webpack": "^5.28.5",
"eslint": "^9.0.0",
"eslint-config-next": "15.4.0",
"eslint-config-next": "15.3.8",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -41,7 +41,7 @@
"@types/node": "^22.17.0",
"@types/webpack": "^5.28.5",
"eslint": "^9.0.0",
"eslint-config-next": "15.4.0",
"eslint-config-next": "15.3.8",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -29,7 +29,7 @@
"@eslint/eslintrc": "^3",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
+2 -2
View File
@@ -29,8 +29,8 @@
"@eslint/eslintrc": "^3",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"postcss": "^8",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
+1
View File
@@ -17,3 +17,4 @@ NEXT_PUBLIC_DC_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/dc-s
NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000/sewerage-service
NEXT_PUBLIC_NGII_URL = http://172.29.143.87/poiact
NEXT_PUBLIC_NGII_PARAM = BDE2BEF39DAFEC293AB6730150F222AC&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={y}&tilerow={x}
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
+1 -1
View File
@@ -37,7 +37,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"tailwindcss": "^3.4.17",
"typescript": "^5.6.3"
+1 -1
View File
@@ -15,4 +15,4 @@ NEXT_PUBLIC_NGII_URL = http://172.29.143.87/poiact
NEXT_PUBLIC_NGII_PARAM = BDE2BEF39DAFEC293AB6730150F222AC&service=WMTS&request=GetTile&version=1.0.0&format=image/png&layer=korean_map&style=korean&tilematrixset=korean&tilematrix={z}&tilecol={y}&tilerow={x}
NEXT_PUBLIC_SEWERAGE_API_URL = http://apigateway.iipbs-was.svc.cluster.local:8000
NEXT_PUBLIC_DC_URL = http://apigateway.iipbs-was.svc.cluster.local:8000
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
+1 -1
View File
@@ -48,7 +48,7 @@
"@types/node": "^22.13.1",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
+1 -1
View File
@@ -62,7 +62,7 @@
"@types/node": "^22.13.1",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"eslint-plugin-react-hooks": "^5.0.0",
"postcss": "^8",
"prettier": "^3.4.2",
@@ -1,30 +1,30 @@
"use client";
import { useState, useEffect, useMemo } from 'react';
import { CodeSelectWithAll } from '@/entities/code';
import {
Button,
Label,
Select,
SelectTrigger,
SelectContent,
SelectValue,
SelectItem,
DataTable,
} from "@common/components";
import { LoadingWithAnimation } from '@common/components';
import { NoData } from '@/shared/ui/no-data';
import DetailComponent from './generalVerification/DetailComponent';
import RegistDialog from './generalVerification/RegistDialog';
import { useEffect, useMemo, useState } from "react";
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { getGeneralVerificationColumns } from '@/components/util/column/management/GeneralVerificationColumn';
import type { GeneralverificationList } from '@/entities/statistics/model/general-verification-interface';
import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
import { useAlertStore } from '@/shared/lib';
import { useAlertStore } from "@/shared/lib";
import { NoData } from "@/shared/ui/no-data";
import { CodeSelectWithAll } from "@/entities/code";
import { generalverificationApiService } from "@/entities/statistics/api/general-verification-service";
import type { GeneralverificationList } from "@/entities/statistics/model/general-verification-interface";
import {
Button,
DataTable,
Label,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@common/components";
import { LoadingWithAnimation } from "@common/components";
import DetailComponent from "./generalVerification/DetailComponent";
import RegistDialog from "./generalVerification/RegistDialog";
import { getGeneralVerificationColumns } from "@/components/util/column/management/GeneralVerificationColumn";
const GeneralVerificationManagement = () => {
const [searchValues, setSearchValues] = useState<{
@@ -32,12 +32,16 @@ const GeneralVerificationManagement = () => {
useYn: string;
vrfcClsfCd: string;
}>({
statsCd: '',
useYn: '',
vrfcClsfCd: '',
statsCd: "",
useYn: "",
vrfcClsfCd: "",
});
const [vrfcMasterData, setVrfcMasterData] = useState<GeneralverificationList[]>([]);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
const [vrfcMasterData, setVrfcMasterData] = useState<
GeneralverificationList[]
>([]);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>(
{},
);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [selectedVrfcRow, setSelectedVrfcRow] = useState<number | null>(null);
const [showRegistForm, setShowRegistForm] = useState<boolean>(false);
@@ -53,21 +57,26 @@ const GeneralVerificationManagement = () => {
trgtStatsCd: searchValues.statsCd,
vrfcClsfCd: searchValues.vrfcClsfCd,
useYn: searchValues.useYn,
}).filter(([, value]) => value !== '' && value !== 'ALL')
}).filter(([, value]) => value !== "" && value !== "ALL"),
);
const response = await generalverificationApiService.getGeneralverificationList(params);
const response =
await generalverificationApiService.getGeneralverificationList(
params,
);
if (response.status === 'success') {
if (response.status === "success") {
setVrfcMasterData(response.data);
setRowSelection({});
setSelectedVrfcRow(null);
setShowRegistForm(false);
} else {
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
alert(
response.message || "데이터 조회 중 오류가 발생했습니다.",
);
}
} catch {
alert('데이터 조회 중 오류가 발생했습니다.');
alert("데이터 조회 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
@@ -98,48 +107,67 @@ const GeneralVerificationManagement = () => {
setSelectedVrfcRow(null);
handleSearch();
setShowRegistForm(false);
}
};
useEffect(() => {
handleSearch();
}, []);
return (
<div className="h-full">
<div className="card card-border">
<div className="flex items-center gap-8 p-2">
<div className="flex items-center gap-2">
<Label className="text-label">
통계항목
</Label>
<>
<div className="card card-border !mx-0">
<div className="flex items-center gap-6 pl-2">
<div className="flex items-center gap-4">
<Label className="text-label">통계항목</Label>
<CodeSelectWithAll
upCd="STITEM"
value={searchValues.statsCd}
onValueChange={(value) => setSearchValues({ ...searchValues, statsCd: value })}
onValueChange={(value) =>
setSearchValues({
...searchValues,
statsCd: value,
})
}
placeholder="전체"
className="w-[16rem]"
/>
</div>
<div className="flex items-center gap-2">
<Label className="text-label">
검증분류
</Label>
<Select value={searchValues.vrfcClsfCd} onValueChange={(value) => setSearchValues({ ...searchValues, vrfcClsfCd: value })}>
<div className="flex items-center gap-4">
<Label className="text-label">검증분류</Label>
<Select
value={searchValues.vrfcClsfCd}
onValueChange={(value) =>
setSearchValues({
...searchValues,
vrfcClsfCd: value,
})
}
>
<SelectTrigger className="w-[10rem]">
<SelectValue placeholder="전체"></SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value="ALL">전체</SelectItem>
<SelectItem value="DO_SI">도단위 검증</SelectItem>
<SelectItem value="SI_GU">시단위 검증</SelectItem>
<SelectItem value="DO_SI">
도단위 검증
</SelectItem>
<SelectItem value="SI_GU">
시단위 검증
</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center gap-2">
<Label className="text-label">
사용여부
</Label>
<Select value={searchValues.useYn} onValueChange={(value) => setSearchValues({ ...searchValues, useYn: value })}>
<div className="flex items-center gap-4">
<Label className="text-label">사용여부</Label>
<Select
value={searchValues.useYn}
onValueChange={(value) =>
setSearchValues({
...searchValues,
useYn: value,
})
}
>
<SelectTrigger className="w-[10rem]">
<SelectValue placeholder="전체"></SelectValue>
</SelectTrigger>
@@ -150,53 +178,64 @@ const GeneralVerificationManagement = () => {
</SelectContent>
</Select>
</div>
<div className="flex items-center gap-2 ml-auto">
<Button color="green" className="h-[3.2rem] w-[96px]" type="button" onClick={handleReset}>
초기화
</Button>
<Button className="h-[3.2rem] w-[96px]" type="button" onClick={handleSearch}>
<div className="ml-auto flex items-center gap-2">
<Button
color="green"
className="h-[3.2rem]"
onClick={handleSearch}
>
조회
</Button>
</div>
</div>
</div>
<div className="card !my-0 flex flex-col !p-0">
<div className='flex items-center justify-end gap-[0.6rem] px-[1.2rem]'>
<RegistDialog open={showRegistForm} onOpenChange={setShowRegistForm} onSuccess={handleSearch}>
<Button className="h-[3.2rem] w-[96px]" type="button">
등록
<Button
color="gray"
className="h-[3.2rem]"
onClick={handleReset}
>
초기화
</Button>
</RegistDialog>
</div>
<div className="flex justify-center gap-5 !p-0 h-[65vh]">
<div className="card card-border w-1/2 !mx-0 flex flex-col">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">일반 검증 목록</h3>
</div>
<div className="card !m-4 h-full overflow-auto !p-0">
{isLoading && (
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
<div className="relative size-[5rem]">
<LoadingWithAnimation color="primary" />
</div>
</div>
)}
{isLoading ? null
:
vrfcMasterData.length > 0 ?
<DataTable table={table} onRowClick={(value) => handleVrfcMasterRowClick(value)} />
:
<div className="flex h-full items-center justify-center">
<NoData />
</div>
}
</div>
</div>
<DetailComponent selectedVrfcRow={selectedVrfcRow} />
</div>
</div>
</div>
<div className="flex h-[65vh] justify-center gap-5 !p-0">
<div className="card card-border !mx-0 flex w-1/2 flex-col">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">
일반 검증 목록
</h3>
<RegistDialog
open={showRegistForm}
onOpenChange={setShowRegistForm}
onSuccess={handleSearch}
>
<Button>등록</Button>
</RegistDialog>
</div>
<div className="card !mx-2 !my-4 h-full overflow-auto !p-0">
{isLoading && (
<div className="[data-theme='black']:bg-transparent absolute inset-0 z-50 flex items-center justify-center rounded-lg p-10">
<div className="relative size-[5rem]">
<LoadingWithAnimation color="primary" />
</div>
</div>
)}
{isLoading ? null : vrfcMasterData.length > 0 ? (
<DataTable
table={table}
onRowClick={(value) =>
handleVrfcMasterRowClick(value)
}
/>
) : (
<div className="flex h-full items-center justify-center">
<NoData />
</div>
)}
</div>
</div>
<DetailComponent selectedVrfcRow={selectedVrfcRow} />
</div>
</>
);
};
export default GeneralVerificationManagement;
export default GeneralVerificationManagement;
@@ -179,7 +179,7 @@ const ImrVerificationHistory = () => {
stAnlsRsltApi.getImrResultList(selectedHistory!.anlsSn, {
page: 0,
size: 100,
sort: "rsltSn,asc",
sort: "admdstCd,asc",
}),
enabled: !!selectedHistory,
});
@@ -19,6 +19,7 @@ import type {
} from "@/entities/statistics/model/verification-target-management-interface";
import {
Button,
cn,
Dialog,
DialogContent,
DialogFooter,
@@ -32,6 +33,7 @@ import {
TabsTrigger,
} from "@common/components";
import GeneralVerificationManagement from "./GeneralVerificationManagement";
import { VerificationTargetDialog } from "./VerificationTargetDialog";
import DataGrid from "@/components/module/DataGrid";
@@ -39,9 +41,9 @@ import DataGrid from "@/components/module/DataGrid";
const TAB_CONFIG = {
HB: { value: "HB", label: "H-B", columnInfo: hbArticleColumnInfo },
IMR: { value: "IMR", label: "I-MR", columnInfo: imrArticleColumnInfo },
VV: {
value: "VV",
label: "Validation",
GENERAL: {
value: "GENERAL",
label: "일반",
columnInfo: validationArticleColumnInfo,
},
} as const;
@@ -253,83 +255,90 @@ function VerificationArticleManagement() {
</TabsTrigger>
))}
</TabsList>
{activeTab !== "GENERAL" && (
<div className="card card-border !mx-0">
<form onSubmit={handleSubmit}>
<div className="flex items-center gap-6 pl-2">
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap text-label">
통계항목
</Label>
<CodeSelect
upCd="STITEM"
value={statsCd}
onValueChange={setStatsCd}
placeholder="선택"
className="w-[16rem]"
/>
</div>
<div className="card card-border !mx-0">
<form onSubmit={handleSubmit}>
<div className="flex items-center gap-4">
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
통계항목
</Label>
<CodeSelect
upCd="STITEM"
value={statsCd}
onValueChange={setStatsCd}
placeholder="선택"
className="w-[16rem]"
/>
</div>
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap text-label">
검증명
</Label>
<Input
value={vrfcTrgtNm}
onChange={(e) =>
setVrfcTrgtNm(e.target.value)
}
placeholder="검증명"
className="w-[20rem]"
/>
</div>
<div className="flex items-center gap-4">
<Label className="whitespace-nowrap px-4 text-label">
검증명
</Label>
<Input
value={vrfcTrgtNm}
onChange={(e) =>
setVrfcTrgtNm(e.target.value)
}
placeholder="검증명"
className="w-[20rem]"
/>
<div className="ml-auto flex gap-2">
<Button
type="button"
color="white"
onClick={handleCheckColumns}
disabled={
checkColumnsMutation.isPending
}
>
컬럼 검사
</Button>
<Button
type="button"
onClick={handleRegister}
>
등록
</Button>
<Button type="submit" color="green">
조회
</Button>
<Button
type="button"
color="gray"
onClick={handleInitialize}
>
초기화
</Button>
</div>
</div>
<div className="ml-auto flex gap-2">
<Button
type="button"
color="white"
className="h-[3.6rem]"
onClick={handleCheckColumns}
disabled={checkColumnsMutation.isPending}
>
컬럼 검사
</Button>
<Button
type="button"
className="h-[3.6rem]"
onClick={handleRegister}
>
등록
</Button>
<Button
type="submit"
color="green"
className="h-[3.6rem]"
>
조회
</Button>
<Button
type="button"
color="gray"
className="h-[3.6rem]"
onClick={handleInitialize}
>
초기화
</Button>
</div>
</div>
</form>
</div>
</form>
</div>
)}
{Object.entries(TAB_CONFIG).map(([key, config]) => (
<TabsContent key={key} value={config.value}>
<DataGrid
columnInfo={columnInfo}
rowData={rowData}
setRowData={() => {}}
onRowClick={handleRowClick}
isExcelImport={false}
/>
<TabsContent
key={key}
value={config.value}
className={cn(
activeTab === "GENERAL" &&
"!mt-[0.6rem] border-none p-0 shadow-none",
)}
>
{activeTab !== "GENERAL" ? (
<DataGrid
columnInfo={columnInfo}
rowData={rowData}
setRowData={() => {}}
onRowClick={handleRowClick}
isExcelImport={false}
/>
) : (
<GeneralVerificationManagement />
)}
</TabsContent>
))}
@@ -89,7 +89,7 @@ const HbVerificationDetail: React.FC<HbVerificationDetailProps> = ({
검증 결과 상세
</h3>
<div className="flex">
<div className="flex-[0.5] p-4">
<div className="flex-1 p-4">
<RegionalGrid
anlsSn={anlsSn}
vrfcTrgtSn={selectedVrfcTrgtSn}
@@ -102,7 +102,7 @@ const HbVerificationDetail: React.FC<HbVerificationDetailProps> = ({
appliedFilter={appliedFilter}
/>
</div>
<div className="flex flex-[0.5] flex-col gap-4 p-4 pt-[4.8rem]">
<div className="flex flex-col gap-4 p-4 pt-[4.8rem]">
<Indicators
anlsSn={anlsSn}
vrfcTrgtSn={selectedVrfcTrgtSn}
@@ -52,6 +52,32 @@ interface DataPoint extends LinePoint {
item: StAnlsRsltResponse;
}
/** 모든 점의 x·y를 합쳐 두 축이 같은 [min, max] 구간을 쓰도록 할 때 사용 */
function getUnifiedLinearRange(data: ChartData<"scatter">): {
min: number;
max: number;
} | null {
const values: number[] = [];
for (const ds of data.datasets) {
for (const pt of ds.data) {
if (pt && typeof pt === "object" && "x" in pt && "y" in pt) {
const p = pt as LinePoint;
if (Number.isFinite(p.x)) values.push(p.x);
if (Number.isFinite(p.y)) values.push(p.y);
}
}
}
if (values.length === 0) return null;
const min = Math.min(...values);
const max = Math.max(...values);
if (min === max) {
const pad = Math.abs(min) * 0.05 || 1;
return { min: min - pad, max: max + pad };
}
const padding = (max - min) * 0.02;
return { min: min - padding, max: max + padding };
}
function matchesAdmdstFilter(
admdstCd: string,
sidoCd: string | null | undefined,
@@ -172,6 +198,8 @@ const ScatterChart: React.FC<ScatterChartProps> = ({
],
};
const axisRange = getUnifiedLinearRange(data);
const options: ChartOptions<"scatter"> = {
responsive: true,
maintainAspectRatio: false,
@@ -230,6 +258,8 @@ const ScatterChart: React.FC<ScatterChartProps> = ({
x: {
type: "linear",
position: "bottom",
min: axisRange?.min,
max: axisRange?.max,
title: {
display: true,
text: "이전년도 값",
@@ -237,6 +267,8 @@ const ScatterChart: React.FC<ScatterChartProps> = ({
},
y: {
type: "linear",
min: axisRange?.min,
max: axisRange?.max,
title: {
display: true,
text: "당해년도 값",
@@ -267,7 +299,7 @@ const ScatterChart: React.FC<ScatterChartProps> = ({
</div>
</div>
) : chartConfig ? (
<div className="h-[48rem] w-full">
<div className="size-[52rem]">
<Scatter
data={chartConfig.data}
options={chartConfig.options}
@@ -2,8 +2,13 @@ import { ValueType } from "realgrid";
import type { ColumnInfo } from "@/components/type/DataGrid.type";
/** 공통: 시도·구군·행정구역 */
const IMR_VISIBLE_REGION_COLUMNS = ["sido", "gugun", "adstDong"] as const;
/** 공통: 시도·구군·행정구역·당해년도 */
const IMR_VISIBLE_REGION_COLUMNS = [
"sido",
"gugun",
"adstDong",
"cryrVl",
] as const;
/** ST00020003, ST00020005: 시도·구군·행정구역·관종구분 */
const IMR_VISIBLE_REGION_AND_PIPE_SE_COLUMNS = [
+2 -1
View File
@@ -20,4 +20,5 @@ NEXT_PUBLIC_NGII_PARAM = BDE2BEF39DAFEC293AB6730150F222AC&service=WMTS&request=G
NEXT_PUBLIC_HASUDOINFO = https://www.hasudoinfo.or.kr
NEXT_PUBLIC_HASUDOINFO_IN = http://10.101.163.102:8889
NEXT_PUBLIC_FINDADRESS_URL=https://business.juso.go.kr/addrlink/addrLinkApi.do
NEXT_PRIVATE_WR_ADDRESS_KEY = U01TXOFVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA=
NEXT_PRIVATE_WR_ADDRESS_KEY = U01TXOFVVEgyMDI1MDgyODE0MTAxNzExNjEyMjA=
NEXT_PUBLIC_CM_LOGIN_PAGE_URL = http://dev.onasys.co.kr:3000/auth/login
+1 -1
View File
@@ -51,7 +51,7 @@
"@eslint/eslintrc": "^3",
"@types/webpack": "^5.28.5",
"eslint": "^9",
"eslint-config-next": "15.1.7",
"eslint-config-next": "15.3.8",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
+23 -22
View File
@@ -8,28 +8,28 @@
"apps/*",
"packages/*"
],
"scripts": {
"build": "turbo run build",
"build:common": "turbo run build --filter=@common/*",
"dev": "turbo run dev",
"build:cm": "turbo run build --filter=cm",
"build:cs": "turbo run build --filter=cs",
"build:sn": "turbo run build --filter=sn",
"build:wr": "turbo run build --filter=wr",
"build:fo": "turbo run build --filter=fo",
"build:dm": "turbo run build --filter=dm",
"build:dm_new": "turbo run build --filter=dm_new",
"dev:cm": "turbo run dev --filter=cm",
"dev:cs": "turbo run dev --filter=cs",
"dev:sn": "turbo run dev --filter=sn",
"dev:wr": "turbo run dev --filter=wr",
"dev:fo": "turbo run dev --filter=fo",
"dev:dm": "turbo run dev --filter=dm",
"dev:dm_new": "turbo run dev --filter=dm_new",
"preview:components": "turbo run storybook --filter=@common/components",
"preinstall": "npx only-allow pnpm",
"prepare": "husky"
},
"scripts": {
"build": "turbo run build",
"build:common": "turbo run build --filter=@common/*",
"dev": "turbo run dev",
"build:cm": "turbo run build --filter=cm",
"build:cs": "turbo run build --filter=cs",
"build:sn": "turbo run build --filter=sn",
"build:wr": "turbo run build --filter=wr",
"build:fo": "turbo run build --filter=fo",
"build:dm": "turbo run build --filter=dm",
"build:dm_new": "turbo run build --filter=dm_new",
"dev:cm": "turbo run dev --filter=cm",
"dev:cs": "turbo run dev --filter=cs",
"dev:sn": "turbo run dev --filter=sn",
"dev:wr": "turbo run dev --filter=wr",
"dev:fo": "turbo run dev --filter=fo",
"dev:dm": "turbo run dev --filter=dm",
"dev:dm_new": "turbo run dev --filter=dm_new",
"preview:components": "turbo run storybook --filter=@common/components",
"preinstall": "npx only-allow pnpm",
"prepare": "husky"
},
"dependencies": {
"chart.js": "^4.4.8",
"react": "^19.2.1",
@@ -39,6 +39,7 @@
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@next/eslint-plugin-next": "^15.3.8",
"@types/node": "^22.13.1",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
+2258 -2302
View File
File diff suppressed because it is too large Load Diff