feat: 채번 규칙 테이블 기반 자동 필터링 구현

- 채번 규칙 scope_type을 table로 단순화
- 화면의 테이블명을 자동으로 감지하여 채번 규칙 필터링
- TextInputConfigPanel에 screenTableName prop 추가
- getAvailableNumberingRulesForScreen API로 테이블 기반 조회
- NumberingRuleDesigner에서 자동으로 테이블명 설정
- webTypeConfigConverter 유틸리티 추가 (기존 화면 호환성)
- AutoGenerationConfig 타입 개선 (enabled, options.numberingRuleId)
- 채번 규칙 선택 UI에서 ID 제거, 설명 추가
- 불필요한 console.log 제거

Backend:
- numberingRuleService: 테이블 기반 필터링 로직 구현
- numberingRuleController: available-for-screen 엔드포인트 수정

Frontend:
- TextInputConfigPanel: 테이블명 기반 채번 규칙 로드
- NumberingRuleDesigner: 적용 범위 UI 제거, 테이블명 자동 설정
- ScreenDesigner: webTypeConfig → autoGeneration 변환 로직 통합
- DetailSettingsPanel: autoGeneration 속성 매핑 개선
This commit is contained in:
kjs
2025-11-07 14:27:07 +09:00
parent 5b79bfb19d
commit 4294fbf608
23 changed files with 2941 additions and 135 deletions

View File

@@ -752,17 +752,27 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
// console.log("🎨 selectedComponent 전체:", selectedComponent);
const handleConfigChange = (newConfig: WebTypeConfig) => {
// console.log("🔧 WebTypeConfig 업데이트:", {
// widgetType: widget.widgetType,
// oldConfig: currentConfig,
// newConfig,
// componentId: widget.id,
// isEqual: JSON.stringify(currentConfig) === JSON.stringify(newConfig),
// });
// 강제 새 객체 생성으로 React 변경 감지 보장
const freshConfig = { ...newConfig };
onUpdateProperty(widget.id, "webTypeConfig", freshConfig);
// TextTypeConfig의 자동입력 설정을 autoGeneration으로도 매핑
const textConfig = newConfig as any;
if (textConfig.autoInput && textConfig.autoValueType === "numbering_rule" && textConfig.numberingRuleId) {
onUpdateProperty(widget.id, "autoGeneration", {
type: "numbering_rule",
enabled: true,
options: {
numberingRuleId: textConfig.numberingRuleId,
},
});
} else if (textConfig.autoInput === false) {
// 자동입력이 비활성화되면 autoGeneration도 비활성화
onUpdateProperty(widget.id, "autoGeneration", {
type: "none",
enabled: false,
});
}
};
// 1순위: DB에서 지정된 설정 패널 사용
@@ -776,7 +786,13 @@ export const DetailSettingsPanel: React.FC<DetailSettingsPanelProps> = ({
if (ConfigPanelComponent) {
// console.log(`🎨 ✅ ConfigPanelComponent 렌더링 시작`);
return <ConfigPanelComponent config={currentConfig} onConfigChange={handleConfigChange} />;
return (
<ConfigPanelComponent
config={currentConfig}
onConfigChange={handleConfigChange}
tableName={currentTableName} // 화면 테이블명 전달
/>
);
} else {
// console.log(`🎨 ❌ ConfigPanelComponent가 null - WebTypeConfigPanel 사용`);
return (

View File

@@ -7,15 +7,24 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { Checkbox } from "@/components/ui/checkbox";
import { Textarea } from "@/components/ui/textarea";
import { TextTypeConfig } from "@/types/screen";
import { getAvailableNumberingRules } from "@/lib/api/numberingRule";
import { getAvailableNumberingRules, getAvailableNumberingRulesForScreen } from "@/lib/api/numberingRule";
import { NumberingRuleConfig } from "@/types/numbering-rule";
interface TextTypeConfigPanelProps {
config: TextTypeConfig;
onConfigChange: (config: TextTypeConfig) => void;
tableName?: string; // 화면의 테이블명 (선택)
menuObjid?: number; // 메뉴 objid (선택)
}
export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config, onConfigChange }) => {
export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({
config,
onConfigChange,
tableName,
menuObjid,
}) => {
console.log("🔍 TextTypeConfigPanel 마운트:", { tableName, menuObjid, config });
// 기본값이 설정된 config 사용
const safeConfig = {
minLength: undefined,
@@ -54,16 +63,46 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
// 채번 규칙 목록 로드
useEffect(() => {
const loadRules = async () => {
console.log("🔄 채번 규칙 로드 시작:", {
autoValueType: localValues.autoValueType,
tableName,
hasTableName: !!tableName,
});
setLoadingRules(true);
try {
// TODO: 현재 메뉴 objid를 화면 정보에서 가져와야 함
// 지금은 menuObjid 없이 호출 (global 규칙만 조회)
const response = await getAvailableNumberingRules();
let response;
// 테이블명이 있으면 테이블 기반 필터링 사용
if (tableName) {
console.log("📋 테이블 기반 채번 규칙 조회 API 호출:", { tableName });
response = await getAvailableNumberingRulesForScreen(tableName);
console.log("📋 API 응답:", response);
} else {
// 테이블명이 없으면 빈 배열 (테이블 필수)
console.warn("⚠️ 테이블명이 없어 채번 규칙을 조회할 수 없습니다");
setNumberingRules([]);
setLoadingRules(false);
return;
}
if (response.success && response.data) {
setNumberingRules(response.data);
console.log("✅ 채번 규칙 로드 성공:", {
count: response.data.length,
rules: response.data.map((r: any) => ({
ruleId: r.ruleId,
ruleName: r.ruleName,
tableName: r.tableName,
})),
});
} else {
console.warn("⚠️ 채번 규칙 조회 실패:", response.error);
setNumberingRules([]);
}
} catch (error) {
console.error("채번 규칙 목록 로드 실패:", error);
console.error("채번 규칙 목록 로드 실패:", error);
setNumberingRules([]);
} finally {
setLoadingRules(false);
}
@@ -71,9 +110,12 @@ export const TextTypeConfigPanel: React.FC<TextTypeConfigPanelProps> = ({ config
// autoValueType이 numbering_rule일 때만 로드
if (localValues.autoValueType === "numbering_rule") {
console.log("✅ autoValueType === 'numbering_rule', 규칙 로드 시작");
loadRules();
} else {
console.log("⏭️ autoValueType !== 'numbering_rule', 규칙 로드 스킵:", localValues.autoValueType);
}
}, [localValues.autoValueType]);
}, [localValues.autoValueType, tableName]);
// config가 변경될 때 로컬 상태 동기화
useEffect(() => {