feat: Enhance dynamic form and BOM item editor functionality

- Added support for updating the `updated_date` field in the DynamicFormService, ensuring accurate timestamp management.
- Refactored the BomItemEditorComponent to improve data handling by filtering valid fields before saving, enhancing data integrity.
- Introduced a mechanism to track existing item IDs to prevent duplicates during item addition, improving user experience and data consistency.
- Streamlined the save process in ButtonActionExecutor by reorganizing the event handling logic, ensuring better integration with EditModal components.
This commit is contained in:
DDD1542
2026-02-27 13:09:20 +09:00
parent c86337832a
commit 649bd77bbb
4 changed files with 315 additions and 53 deletions

View File

@@ -812,7 +812,7 @@ export function BomItemEditorComponent({
: null;
if (node._isNew) {
const payload: Record<string, any> = {
const raw: Record<string, any> = {
...node.data,
[fkColumn]: bomId,
[parentKeyColumn]: realParentId,
@@ -821,10 +821,16 @@ export function BomItemEditorComponent({
company_code: companyCode || undefined,
version_id: saveVersionId || undefined,
};
delete payload.id;
delete payload.tempId;
delete payload._isNew;
delete payload._isDeleted;
// bom_detail에 유효한 필드만 남기기 (item_info 조인 필드 제거)
const payload: Record<string, any> = {};
const validKeys = new Set([
fkColumn, parentKeyColumn, "seq_no", "level", "child_item_id",
"quantity", "unit", "loss_rate", "remark", "process_type",
"base_qty", "revision", "version_id", "company_code", "writer",
]);
Object.keys(raw).forEach((k) => {
if (validKeys.has(k)) payload[k] = raw[k];
});
const resp = await apiClient.post(
`/table-management/tables/${mainTableName}/add`,
@@ -835,17 +841,14 @@ export function BomItemEditorComponent({
savedCount++;
} else if (node.id) {
const updatedData: Record<string, any> = {
...node.data,
id: node.id,
[fkColumn]: bomId,
[parentKeyColumn]: realParentId,
seq_no: String(seqNo),
level: String(level),
};
delete updatedData.tempId;
delete updatedData._isNew;
delete updatedData._isDeleted;
Object.keys(updatedData).forEach((k) => {
if (k.startsWith(`${sourceFk}_`)) delete updatedData[k];
["quantity", "unit", "loss_rate", "remark", "process_type", "base_qty", "revision", "child_item_id", "version_id", "company_code"].forEach((k) => {
if (node.data[k] !== undefined) updatedData[k] = node.data[k];
});
await apiClient.put(
@@ -934,6 +937,20 @@ export function BomItemEditorComponent({
setItemSearchOpen(true);
}, []);
// 이미 추가된 품목 ID 목록 (중복 방지용)
const existingItemIds = useMemo(() => {
const ids = new Set<string>();
const collect = (nodes: BomItemNode[]) => {
for (const n of nodes) {
const fk = n.data[cfg.dataSource?.foreignKey || "child_item_id"];
if (fk) ids.add(fk);
collect(n.children);
}
};
collect(treeData);
return ids;
}, [treeData, cfg]);
// 루트 품목 추가 시작
const handleAddRoot = useCallback(() => {
setAddTargetParentId(null);
@@ -1353,18 +1370,7 @@ export function BomItemEditorComponent({
onClose={() => setItemSearchOpen(false)}
onSelect={handleItemSelect}
companyCode={companyCode}
existingItemIds={useMemo(() => {
const ids = new Set<string>();
const collect = (nodes: BomItemNode[]) => {
for (const n of nodes) {
const fk = n.data[cfg.dataSource?.foreignKey || "child_item_id"];
if (fk) ids.add(fk);
collect(n.children);
}
};
collect(treeData);
return ids;
}, [treeData, cfg])}
existingItemIds={existingItemIds}
/>
</div>
);