- cn() 유틸 신규 (clsx + tailwind-merge, 시맨틱 토큰 classGroup 등록) - theme.css @layer utilities로 직접 정의 (Tailwind v4 복합 이름 매핑 실패 대응): text-heading/label/hint/on-vivid/on-bright, bg-surface-raised/overlay - badgeVariants (CVA) 재구축: 8 intent x 4 size, rem 기반, !important 제거 - Badge 컴포넌트가 cn(badgeVariants, className)로 override 허용 - DataTable width 의미 변경: 고정 -> 선호 최소 너비 (minWidth), truncate + title 툴팁 - dateFormat.ts sv-SE 로케일로 YYYY-MM-DD HH:mm:ss 일관된 KST 출력 - ColorPicker 신규 (팔레트 + native color + hex 입력) - shared/constants/ 19개 카탈로그: violation/alert/event/enforcement/patrol/ engine/userRole/device/parentResolution/modelDeployment/gearGroup/darkVessel/ httpStatus/userAccount/loginResult/permission/vesselAnalysis/connection/trainingZone + kpiUiMap. 백엔드 enum/code_master 기반 SSOT - i18n ko/en common.json에 카테고리 섹션 추가 - adminApi.fetchRoles()가 updateRoleColorCache 자동 호출 - 공통 컴포넌트 (ExcelExport/NotificationBanner/Pagination/SaveButton) 시맨틱 토큰 적용
126 lines
3.5 KiB
TypeScript
126 lines
3.5 KiB
TypeScript
/**
|
|
* 위험도/알림 등급 공통 카탈로그
|
|
*
|
|
* SSOT: backend `code_master` 그룹 EVENT_LEVEL (V008 시드).
|
|
* 향후 `GET /api/code-master?groupCode=EVENT_LEVEL`로 fetch 예정.
|
|
*
|
|
* **공통 Badge 컴포넌트와 연동**: 가능한 한 `<Badge intent={getAlertLevelIntent(level)}>` 사용.
|
|
* 카드 컨테이너 등 분리된 클래스가 필요한 경우만 `ALERT_LEVELS.classes` 사용.
|
|
*
|
|
* 사용처: Dashboard, MonitoringDashboard, EventList, LiveMapView, VesselDetail,
|
|
* MobileService, ChinaFishing 등 모든 위험도 배지 / 알림 / 마커
|
|
*/
|
|
|
|
import type { BadgeIntent } from '@lib/theme/variants';
|
|
|
|
export type AlertLevel = 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
|
|
|
|
export interface AlertLevelMeta {
|
|
code: AlertLevel;
|
|
i18nKey: string;
|
|
fallback: { ko: string; en: string };
|
|
/** 공통 Badge 컴포넌트 intent (badgeVariants 와 동기화) */
|
|
intent: BadgeIntent;
|
|
/** Tailwind 클래스 묶음 — 카드/컨테이너 전용 (배지가 아님)
|
|
* 배지에는 `<Badge intent={meta.intent}>` 사용 권장.
|
|
* 여기서 bg/border는 약한 알파 — 카드 배경에 텍스트가 묻히지 않도록.
|
|
*/
|
|
classes: {
|
|
bg: string;
|
|
text: string;
|
|
border: string;
|
|
dot: string;
|
|
/** 진한 배경 (액션 버튼 등) */
|
|
bgSolid: string;
|
|
};
|
|
/** hex 색상 (지도 마커, 차트, 인라인 style 용) */
|
|
hex: string;
|
|
order: number;
|
|
}
|
|
|
|
export const ALERT_LEVELS: Record<AlertLevel, AlertLevelMeta> = {
|
|
CRITICAL: {
|
|
code: 'CRITICAL',
|
|
i18nKey: 'alert.critical',
|
|
fallback: { ko: '심각', en: 'Critical' },
|
|
intent: 'critical',
|
|
classes: {
|
|
bg: 'bg-red-500/10',
|
|
text: 'text-red-300',
|
|
border: 'border-red-500/30',
|
|
dot: 'bg-red-500',
|
|
bgSolid: 'bg-red-500',
|
|
},
|
|
hex: '#ef4444',
|
|
order: 1,
|
|
},
|
|
HIGH: {
|
|
code: 'HIGH',
|
|
i18nKey: 'alert.high',
|
|
fallback: { ko: '높음', en: 'High' },
|
|
intent: 'high',
|
|
classes: {
|
|
bg: 'bg-orange-500/10',
|
|
text: 'text-orange-300',
|
|
border: 'border-orange-500/30',
|
|
dot: 'bg-orange-500',
|
|
bgSolid: 'bg-orange-500',
|
|
},
|
|
hex: '#f97316',
|
|
order: 2,
|
|
},
|
|
MEDIUM: {
|
|
code: 'MEDIUM',
|
|
i18nKey: 'alert.medium',
|
|
fallback: { ko: '보통', en: 'Medium' },
|
|
intent: 'warning',
|
|
classes: {
|
|
bg: 'bg-yellow-500/10',
|
|
text: 'text-yellow-300',
|
|
border: 'border-yellow-500/30',
|
|
dot: 'bg-yellow-500',
|
|
bgSolid: 'bg-yellow-500',
|
|
},
|
|
hex: '#eab308',
|
|
order: 3,
|
|
},
|
|
LOW: {
|
|
code: 'LOW',
|
|
i18nKey: 'alert.low',
|
|
fallback: { ko: '낮음', en: 'Low' },
|
|
intent: 'info',
|
|
classes: {
|
|
bg: 'bg-blue-500/10',
|
|
text: 'text-blue-300',
|
|
border: 'border-blue-500/30',
|
|
dot: 'bg-blue-500',
|
|
bgSolid: 'bg-blue-500',
|
|
},
|
|
hex: '#3b82f6',
|
|
order: 4,
|
|
},
|
|
};
|
|
|
|
export function getAlertLevelMeta(level: string): AlertLevelMeta | undefined {
|
|
return ALERT_LEVELS[level as AlertLevel];
|
|
}
|
|
|
|
export function getAlertLevelLabel(
|
|
level: string,
|
|
t: (key: string, opts?: { defaultValue?: string }) => string,
|
|
lang: 'ko' | 'en' = 'ko',
|
|
): string {
|
|
const meta = getAlertLevelMeta(level);
|
|
if (!meta) return level;
|
|
return t(meta.i18nKey, { defaultValue: meta.fallback[lang] });
|
|
}
|
|
|
|
export function getAlertLevelHex(level: string): string {
|
|
return getAlertLevelMeta(level)?.hex ?? '#6b7280';
|
|
}
|
|
|
|
/** 공통 Badge intent 매핑 */
|
|
export function getAlertLevelIntent(level: string): BadgeIntent {
|
|
return getAlertLevelMeta(level)?.intent ?? 'muted';
|
|
}
|