jskim-node #17

Merged
jskim merged 9 commits from jskim-node into main 2026-04-10 01:42:53 +00:00
7 changed files with 210 additions and 21 deletions
Showing only changes of commit 909fe9d42a - Show all commits

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}

View File

@@ -54,6 +54,7 @@ export default function EquipmentInspectionRecordPage() {
const [records, setRecords] = useState<InspectionRecord[]>([]);
const [inspectionItems, setInspectionItems] = useState<Map<string, InspectionItem>>(new Map());
const [equipments, setEquipments] = useState<Map<string, EquipmentInfo>>(new Map());
const [categoryMap, setCategoryMap] = useState<Record<string, Record<string, string>>>({});
const [loading, setLoading] = useState(false);
const [selectedId, setSelectedId] = useState<string | null>(null);
const [filterValues, setFilterValues] = useState<FilterValue[]>([]);
@@ -102,6 +103,25 @@ export default function EquipmentInspectionRecordPage() {
eMap.set(e.id, e);
});
setEquipments(eMap);
// 카테고리 코드→라벨 매핑 (점검주기, 점검방법)
try {
const catCols = ["inspection_cycle", "inspection_method"];
const catResults = await Promise.all(
catCols.map((col) =>
apiClient.get(`/table-categories/equipment_inspection_item/${col}/values`).catch(() => ({ data: [] })),
),
);
const cMap: Record<string, Record<string, string>> = {};
catCols.forEach((col, idx) => {
const vals: { code: string; label: string }[] = catResults[idx].data?.data ?? catResults[idx].data ?? [];
cMap[col] = {};
vals.forEach((v: any) => { cMap[col][v.valueCode || v.code] = v.valueLabel || v.label; });
});
setCategoryMap(cMap);
} catch {
// 카테고리 조회 실패 무시
}
} catch (err) {
console.error("점검기록 조회 실패:", err);
} finally {
@@ -125,6 +145,13 @@ export default function EquipmentInspectionRecordPage() {
const getEquipName = (code: string) => equipments.get(code)?.equipment_name || code || "-";
// ─── 카테고리 코드→라벨 변환 ──────────────────────────
const resolveCategory = (col: string, code: string) => {
if (!code) return "-";
return categoryMap[col]?.[code] || code;
};
// ─── 엑셀 다운로드 ─────────────────────────────────────
const handleExcel = async () => {
@@ -281,9 +308,9 @@ export default function EquipmentInspectionRecordPage() {
<h3 className="text-[13px] font-bold mb-2"> </h3>
<div className="grid grid-cols-2 gap-2 text-sm">
<DetailRow label="점검항목" value={selectedItem.inspection_item || "-"} />
<DetailRow label="점검주기" value={selectedItem.inspection_cycle || "-"} />
<DetailRow label="점검주기" value={resolveCategory("inspection_cycle", selectedItem.inspection_cycle)} />
<DetailRow label="점검내용" value={selectedItem.inspection_content || "-"} span2 />
<DetailRow label="점검방법" value={selectedItem.inspection_method || "-"} span2 />
<DetailRow label="점검방법" value={resolveCategory("inspection_method", selectedItem.inspection_method)} span2 />
<DetailRow label="하한치" value={selectedItem.lower_limit || "-"} />
<DetailRow label="상한치" value={selectedItem.upper_limit || "-"} />
<DetailRow label="단위" value={selectedItem.unit || "-"} />
@@ -318,7 +345,7 @@ function DetailRow({
return (
<div className={cn("flex flex-col gap-0.5", span2 && "col-span-2")}>
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wider">{label}</span>
{badge || <span className="text-xs">{value}</span>}
{badge ? <div className="w-fit">{badge}</div> : <span className="text-xs">{value}</span>}
</div>
);
}