From 946d61f8dfb27fd00fdbea9703709e5f6a593f26 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 2 Sep 2026 06:33:19 +0900 Subject: [PATCH] =?UTF-8?q?feat(B07):=20GROUP=20=EB=AC=B6=EC=9D=8C=20JSON?= =?UTF-8?q?=20=EC=A0=80=EC=9E=A5=C2=B7=EB=B3=B5=EC=9B=90,=20=EC=A4=8C=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `groupId` 를 도면 JSON 에 실어 [저장] 뒤 다시 연 도면에서도 묶음 유지. 엔티티 13종의 `toJson` 대신 직렬화 한 곳(export/import)에서 붙이고, 복원은 순번이 아니라 id 로 — `compact` 가 null 을 걷어 index 가 어긋남. - `setScreenScale` 의 매 호출 `console.log` 제거 — 줌·팬마다 콘솔을 덮었음. - 검증: `group-id-roundtrip.test.ts` 신규, `npx vitest run` 87건 중 81 passed, 실패 6건은 작업 전과 동일한 기존 결함. `npm run build` 통과. Co-Authored-By: Claude Opus 5 (1M context) --- .../screenCanvas.drawController.ts | 1 - .../openwebcad/src/entities/Entity.ts | 2 ++ .../export-entities-to-json.ts | 6 +++- .../group-id-roundtrip.test.ts | 30 +++++++++++++++++++ .../import-entities-from-json.ts | 6 ++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/group-id-roundtrip.test.ts diff --git a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts index 753a1803..f37b3199 100644 --- a/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts +++ b/B07_DesignDetail/openwebcad/src/drawControllers/screenCanvas.drawController.ts @@ -69,7 +69,6 @@ export class ScreenCanvasDrawController implements DrawController { } public setScreenScale(newScreenScale: number) { - console.log(`set screen scale: ${newScreenScale}`); this.screenScale = newScreenScale; triggerReactUpdate(StateVariable.screenZoom); } diff --git a/B07_DesignDetail/openwebcad/src/entities/Entity.ts b/B07_DesignDetail/openwebcad/src/entities/Entity.ts index 23dc7403..135f4be9 100644 --- a/B07_DesignDetail/openwebcad/src/entities/Entity.ts +++ b/B07_DesignDetail/openwebcad/src/entities/Entity.ts @@ -86,6 +86,8 @@ export interface JsonEntity { lineWidth: number; lineDash?: number[]; layerId: string; + /** GROUP 묶음 식별자 — 저장·복원에서 그대로 실어 나른다 */ + groupId?: string; shapeData: TShapeJsonData | null; children?: JsonEntity[]; } diff --git a/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/export-entities-to-json.ts b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/export-entities-to-json.ts index d33f56c1..b0d59331 100644 --- a/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/export-entities-to-json.ts +++ b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/export-entities-to-json.ts @@ -14,7 +14,11 @@ export async function exportEntitiesToJsonFile() { export async function exportEntitiesAndLayersToJsonString() { const entities = getEntities(); - const jsonEntities = entities.map((entity) => entity.toJson()); + // groupId는 엔티티 13종의 toJson을 다 고치는 대신 여기 한 곳에서 붙인다. + const jsonEntities = entities.map(async (entity) => { + const json = await entity.toJson(); + return json && entity.groupId ? { ...json, groupId: entity.groupId } : json; + }); const jsonDrawingFile: JsonDrawingFileSerialized = { entities: compact(await Promise.all(jsonEntities)), // TODO use a mapLimit to avoid overloading the event loop layers: getLayers(), diff --git a/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/group-id-roundtrip.test.ts b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/group-id-roundtrip.test.ts new file mode 100644 index 00000000..d0ee722c --- /dev/null +++ b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/group-id-roundtrip.test.ts @@ -0,0 +1,30 @@ +import { Point } from '@flatten-js/core'; +import { describe, expect, it } from 'vitest'; +import { LineEntity } from '../../entities/LineEntity.ts'; +import { setEntities, setLayers } from '../../state.ts'; +import { exportEntitiesAndLayersToJsonString } from './export-entities-to-json.ts'; +import { getEntitiesAndLayersFromJsonString } from './import-entities-from-json.ts'; + +describe('groupId 저장·복원', () => { + it('GROUP 묶음이 JSON 왕복 뒤에도 한 덩어리로 남는다', async () => { + const layer = { id: 'layer-1', isLocked: false, isVisible: true, name: '작업' }; + const groupId = 'group-1'; + const first = new LineEntity(layer.id, new Point(0, 0), new Point(1, 0)); + const second = new LineEntity(layer.id, new Point(1, 0), new Point(1, 1)); + const loner = new LineEntity(layer.id, new Point(2, 2), new Point(3, 3)); + first.groupId = groupId; + second.groupId = groupId; + + setLayers([layer]); + setEntities([first, second, loner]); + + const restored = await getEntitiesAndLayersFromJsonString( + await exportEntitiesAndLayersToJsonString() + ); + const byId = new Map(restored.entities.map((entity) => [entity.id, entity])); + + expect(byId.get(first.id)?.groupId).toBe(groupId); + expect(byId.get(second.id)?.groupId).toBe(groupId); + expect(byId.get(loner.id)?.groupId).toBeUndefined(); + }); +}); diff --git a/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/import-entities-from-json.ts b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/import-entities-from-json.ts index c121cf78..6cfbf049 100644 --- a/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/import-entities-from-json.ts +++ b/B07_DesignDetail/openwebcad/src/helpers/import-export-handlers/import-entities-from-json.ts @@ -77,6 +77,12 @@ export async function getEntitiesAndLayersFromJsonObject( ); const entities = compact(await Promise.all(entityPromises)); + // 순번이 아니라 id로 되돌린다 — compact가 null을 걷어 index가 어긋날 수 있다. + const groupIdById = new Map(data.entities.map((entity) => [entity.id, entity.groupId])); + for (const entity of entities) { + const groupId = groupIdById.get(entity.id); + if (groupId) entity.groupId = groupId; + } let layers = data.layers; if (data.layers.length === 0) { layers = [getNewLayer()];