@things-factory/board-ui 10.1.45 → 10.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-client/pages/board-list-page.js +1 -1
- package/dist-client/pages/board-list-page.js.map +1 -1
- package/dist-client/pages/board-modeller-page.d.ts +13 -0
- package/dist-client/pages/board-modeller-page.js +43 -1
- package/dist-client/pages/board-modeller-page.js.map +1 -1
- package/dist-client/pages/board-template/board-template-list-page.js +1 -1
- package/dist-client/pages/board-template/board-template-list-page.js.map +1 -1
- package/dist-client/pages/play-list-page.js +1 -1
- package/dist-client/pages/play-list-page.js.map +1 -1
- package/dist-client/pages/theme/theme-list-page.js +2 -2
- package/dist-client/pages/theme/theme-list-page.js.map +1 -1
- package/dist-client/styles/board-card-styles.js +1 -4
- package/dist-client/styles/board-card-styles.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/board-basic-info.js +3 -24
- package/dist-client/viewparts/board-basic-info.js.map +1 -1
- package/dist-client/viewparts/board-info-link.js +1 -18
- package/dist-client/viewparts/board-info-link.js.map +1 -1
- package/dist-client/viewparts/board-info-template.js +1 -18
- package/dist-client/viewparts/board-info-template.js.map +1 -1
- package/dist-client/viewparts/board-template-info.d.ts +1 -0
- package/dist-client/viewparts/board-template-info.js +7 -12
- package/dist-client/viewparts/board-template-info.js.map +1 -1
- package/dist-client/viewparts/group-info-basic.d.ts +1 -0
- package/dist-client/viewparts/group-info-basic.js +6 -7
- package/dist-client/viewparts/group-info-basic.js.map +1 -1
- package/dist-client/viewparts/group-info-import.js +1 -1
- package/dist-client/viewparts/group-info-import.js.map +1 -1
- package/dist-client/viewparts/info-dialog-styles.js +12 -1
- package/dist-client/viewparts/info-dialog-styles.js.map +1 -1
- package/dist-client/viewparts/play-group-info-basic.d.ts +1 -0
- package/dist-client/viewparts/play-group-info-basic.js +6 -7
- package/dist-client/viewparts/play-group-info-basic.js.map +1 -1
- package/package.json +7 -7
- package/translations/en.json +0 -16
- package/translations/ja.json +88 -16
- package/translations/ko.json +0 -16
- package/translations/ms.json +94 -20
- package/translations/zh.json +89 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-modeller-page.js","sourceRoot":"","sources":["../../client/pages/board-modeller-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport 'things-scene-components'\nimport '@operato/board/ox-board-modeller.js'\nimport '@operato/oops'\nimport '@things-factory/board-ai'\n\nimport gql from 'graphql-tag'\nimport { getModellerToolbarMode, ModellerToolbarMode } from '../setting-let/board-modeller-setting-let.js'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { BoardModeller } from '@operato/board/ox-board-modeller.js'\nimport { LoadTracker, SceneSearchEngine } from '@hatiolab/things-scene'\nimport { OxPropertyEditor } from '@operato/property-editor'\nimport { PageView, FontController } from '@operato/shell'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport {\n applyScenePatchVerbose,\n dispatchSceneAction,\n dispatchSceneEditOp,\n findSceneComponent,\n type SceneEditOp,\n type SceneEditPatch\n} from '@operato/scene-ops'\nimport { client, gqlContext, subscribe } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\n\nimport { provider } from '@operato/board/board-provider.js'\nimport '../board-placement-tray.js' // 배치 팔레트 오버레이(호스트-등록 provider 있을 때만 표시)\nimport { boardPlacementProvider } from '@operato/board/board-placement-palette.js'\nimport components from 'things-scene-components-with-tools'\nimport { notify, notifyError } from '../utils/notify-helper.js'\nimport { PatchApplyGate } from '../utils/patch-apply-gate.js'\nimport { diffBoardModel } from '../utils/board-model-diff.js'\n\nexport { findSceneComponent }\n\n/** 서버 PatchEntry.reverted=true 플래그 영속용 mutation. */\nconst REVERT_PATCH_MUTATION = gql`\n mutation RevertPatch($patchId: String!) {\n revertPatch(patchId: $patchId)\n }\n`\n\n/**\n * default 위에 override 를 깊게 merge.\n * - override 의 키 값이 undefined 가 아닌 경우 우선 적용\n * - override 의 nested object 는 default 와 deep merge\n * - array / primitive 는 override 가 그대로 우선\n */\nfunction mergeDefaultsDeep(defaults: any, override: any): any {\n if (defaults === null || defaults === undefined) return override\n if (override === null || override === undefined) return defaults\n if (typeof defaults !== 'object' || typeof override !== 'object') return override\n if (Array.isArray(defaults) || Array.isArray(override)) return override\n\n const out: any = { ...defaults }\n for (const key of Object.keys(override)) {\n const dv = (defaults as any)[key]\n const ov = (override as any)[key]\n if (\n dv !== null &&\n ov !== null &&\n typeof dv === 'object' &&\n typeof ov === 'object' &&\n !Array.isArray(dv) &&\n !Array.isArray(ov)\n ) {\n out[key] = mergeDefaultsDeep(dv, ov)\n } else if (ov !== undefined) {\n out[key] = ov\n }\n }\n return out\n}\n\n@customElement('board-modeller-page')\nexport class BoardModellerPage extends PageView {\n constructor() {\n super()\n\n components.forEach(({ templates = [], groups = [] }) => {\n groups.forEach(group => BoardModeller.registerGroup(group))\n BoardModeller.registerTemplate(templates)\n })\n\n /* 컴포넌트에서 정의된 에디터들을 MODELLER_EDITORS에 등록 */\n const addedEditors = {}\n for (const component in components) {\n let { editors } = components[component]\n\n editors &&\n editors.forEach(editor => {\n let { type, element } = editor\n\n addedEditors[type] = element\n })\n }\n\n OxPropertyEditor.register(addedEditors)\n }\n\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n\n overflow: hidden;\n position: relative;\n }\n\n .modeller-area {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n }\n\n ox-board-modeller {\n flex: 1;\n }\n\n /*\n * The assistant's door and its column, on the scheme's own surfaces. The door is a quiet\n * tonal pill on the canvas, like the save FAB beside it; open, it takes the pressed tone.\n */\n .ai-toggle {\n position: absolute;\n right: 12px;\n bottom: 12px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 36px;\n padding: 0 14px 0 11px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 999px;\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n font: 500 0.8rem/1 var(--theme-font, Roboto, sans-serif);\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n transition: background 0.15s, transform 0.1s;\n }\n .ai-toggle md-icon {\n --md-icon-size: 18px;\n color: var(--md-sys-color-primary);\n font-variation-settings: 'FILL' 1;\n }\n .ai-toggle:hover { background: var(--md-sys-color-surface-container-highest); }\n .ai-toggle:active { transform: scale(0.97); }\n .ai-toggle.open {\n border-color: transparent;\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n .ai-toggle.open md-icon { color: inherit; font-variation-settings: 'FILL' 0; }\n\n .ai-panel {\n flex: 0 0 340px;\n display: flex;\n min-width: 0;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n background: var(--md-sys-color-surface-container-low);\n color: var(--md-sys-color-on-surface);\n }\n\n ox-assistant-chat { flex: 1; }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n @media (max-width: 900px) {\n .ai-panel {\n flex-basis: 100%;\n position: absolute;\n inset: 0;\n z-index: 20;\n }\n }\n `\n ]\n\n @property({ type: String }) boardId?: string | null\n @property({ type: String }) boardName?: string = ''\n /* Read from the user's board-modeller setting each time the page is shown. */\n @state() private toolbarMode: ModellerToolbarMode = 'contextual'\n @property({ type: Object }) model: any = null\n @property({ type: Array }) selected: any = []\n @property({ type: Number }) mode?: number = 1\n @property({ type: Boolean }) hideProperty?: boolean = false\n @property({ type: String }) overlay?: string | null = null\n @property({ type: Object }) scene: any = null\n @property({ type: Array }) componentGroupList?: any[] = BoardModeller.groups\n @property({ type: Array }) propertyEditor: any\n @property({ type: Boolean }) preparing?: boolean\n\n /** AI 협력 세션 id — 현재 활성 세션. boardId 변경 시 자동 ensure. 다중 세션 시 활성 1개. */\n @state() chatSessionId?: string\n\n /** 보드의 모든 ChatSession (탭으로 표시). */\n @state() chatSessions: Array<{ id: string; name?: string; createdAt?: string }> = []\n\n /** AI 채팅 패널 열림 상태 (기본 닫힘) */\n @state() aiPanelOpen = false\n\n /**\n * 적용된 patch 별 inverse op 시퀀스 — Revert 기능용.\n *\n * Map<patchId, inverseOps[]>: 각 patch 적용 시점에 계산해 저장. revert 클릭\n * 시 역순 in-place 적용. 페이지 reload 시 손실 — reload 후 revert 시도는\n * notify 로 안내 (메모리 외 영속은 별개 작업).\n */\n private patchInverses = new Map<string, SceneEditOp[]>()\n\n // C2 실시간 공동편집 — apply-once 게이트(echo/순서 무관 dedup) + board-patch 구독.\n private _patchGate = new PatchApplyGate()\n private _patchSub?: { unsubscribe: () => void | Promise<void> }\n // C3 직접편집 캡처 — 마지막으로 동기화된(서버/타참여자가 아는) 모델. diff 의 baseline.\n private _syncedModel: any = null\n\n /** 모델러에 등록된 컴포넌트 type 목록 — chat 호출 시 LLM 에 전달 (lazy cache) */\n private _knownTypesCache?: string[]\n /** 등록된 type 의 group 분류 — categories 로 LLM 에 전달 */\n private _knownCategoriesCache?: string[]\n\n private get knownTypes(): string[] {\n if (!this._knownTypesCache) {\n const types = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.type === 'string') types.add(t.type)\n }\n }\n this._knownTypesCache = Array.from(types).sort()\n }\n return this._knownTypesCache\n }\n\n private get knownCategories(): string[] {\n if (!this._knownCategoriesCache) {\n const cats = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.group === 'string') cats.add(t.group)\n }\n }\n this._knownCategoriesCache = Array.from(cats).sort()\n }\n return this._knownCategoriesCache\n }\n\n /**\n * type 별 유효 속성 스킴 — LLM 이 정확한 컴포넌트를 만들도록 (lazy cache).\n *\n * 핵심: 좌표 표현은 type 마다 다르다 (left/top vs cx/cy vs points 등).\n * 따라서 OMIT 하지 않고 `geometryKeys` 로 별도 노출 → LLM 이 type 별 좌표 키 사용 가능.\n */\n private _componentSchemasCache?: Array<{\n type: string\n description?: string\n group?: string\n /** template.model 의 좌표/크기 관련 키들 — type 별 다름 */\n geometryKeys?: string[]\n /** 좌표 외 type 특화 속성 (default 값 또는 nested 키 목록) */\n properties?: Record<string, any>\n }>\n\n private get componentSchemas() {\n if (!this._componentSchemasCache) {\n const out: Array<{\n type: string\n description?: string\n group?: string\n geometryKeys?: string[]\n properties?: Record<string, any>\n }> = []\n const NON_PROPS = new Set(['type', 'id', 'name', 'class'])\n // 좌표/크기/경로 관련 키들 — type 마다 다른 조합으로 사용\n const GEOMETRY_KEYS = new Set([\n 'left',\n 'top',\n 'right',\n 'bottom',\n 'x',\n 'y',\n 'cx',\n 'cy',\n 'width',\n 'height',\n 'rx',\n 'ry',\n 'radius',\n 'rotation',\n 'translate',\n 'scale',\n 'points',\n 'path',\n 'vertices',\n 'verticles',\n 'startX',\n 'startY',\n 'endX',\n 'endY',\n 'startPoint',\n 'endPoint'\n ])\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (!t || typeof t.type !== 'string') continue\n const properties: Record<string, any> = {}\n const geometryKeys: string[] = []\n const model: any = t.model || {}\n for (const key of Object.keys(model)) {\n if (NON_PROPS.has(key)) continue\n if (GEOMETRY_KEYS.has(key)) {\n geometryKeys.push(key)\n continue\n }\n const v = model[key]\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n properties[key] = Object.fromEntries(\n Object.keys(v)\n .slice(0, 8)\n .map(k => [k, null])\n )\n } else if (Array.isArray(v)) {\n properties[key] = []\n } else {\n properties[key] = v\n }\n }\n out.push({\n type: t.type,\n description: t.description || undefined,\n group: t.group || undefined,\n geometryKeys: geometryKeys.length > 0 ? geometryKeys : undefined,\n properties: Object.keys(properties).length > 0 ? properties : undefined\n })\n }\n }\n this._componentSchemasCache = out\n }\n return this._componentSchemasCache\n }\n\n private board: any = null\n private _loadTracker?: LoadTracker\n private _fontCtrl = new FontController(this)\n @query('ox-board-modeller') modeller?: BoardModeller\n\n get context() {\n return {\n title: this.board ? this.boardName : this.preparing ? 'Fetching board...' : '',\n help: 'board-modeller/modeller',\n widebleed: true,\n /* No title row: the canvas is the subject here, the name is in the browser tab and the\n * property panel already. Same call figure-modeller-page.ts makes; the title itself stays\n * because the tab and the document title read it. */\n heading: false\n }\n }\n\n get oopsNote() {\n return {\n icon: 'color_lens',\n title: i18next.t('title.no board to design'),\n description: i18next.t('text.no board to design')\n }\n }\n\n async refresh() {\n if (!this.boardId) {\n this.board = null\n this.model = null\n\n return\n }\n try {\n // 이전 보드 완전히 클리어\n this.board = null\n this.model = null\n this._loadTracker = new LoadTracker()\n this._loadTracker.setPhase('fetch')\n this.preparing = true\n this.updateContext()\n\n const response = await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n model\n }\n }\n `,\n variables: { id: this.boardId },\n context: gqlContext()\n })\n\n this._loadTracker?.setPhase('parse')\n\n const board = response.data.board\n\n if (!board) {\n this.board = null\n throw new Error('board not found')\n }\n\n this.board = {\n ...board,\n model: JSON.parse(board.model)\n }\n\n this.boardName = this.board.name\n this.model = {\n ...this.board.model\n }\n\n // AI 협력 세션 — 보드 전환 시 이전 보드의 세션 / 세션 리스트 정리 (chat panel 의\n // sessionId/sessions 변화 감지 → history 비우고 새로 로드). 패널 열린 채 보드 옮겼다면\n // 새 보드의 세션 리스트를 즉시 ensure (fire-and-forget — 에러는 ensureChatSession 처리).\n this.chatSessionId = undefined\n this.chatSessions = []\n if (this.aiPanelOpen && this.boardId) {\n this.ensureChatSession()\n }\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n this.updateContext()\n }\n }\n\n /** 패널 토글 시 호출 — 열 때만 chatSession 보장 (세션 리스트 로드 + 활성 세션 결정) */\n private async toggleAIPanel() {\n const willOpen = !this.aiPanelOpen\n if (willOpen && this.boardId) {\n await this.ensureChatSession()\n }\n this.aiPanelOpen = willOpen\n }\n\n /** 보드의 모든 ChatSession 목록을 로드 + 활성 세션 보장.\n * - 세션이 0 개면 startBoardAISession 으로 첫 세션 생성 (단일 세션 UX 호환)\n * - 활성 세션 미설정 시 첫 번째 세션을 활성으로\n * - 이미 활성 세션 set 돼있고 list 에 포함되면 유지 */\n private async ensureChatSession() {\n if (!this.boardId) return\n try {\n const result = await client.query({\n query: gql`\n query ChatSessionsByBoard($boardId: String!) {\n chatSessionsByBoard(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext(),\n fetchPolicy: 'network-only'\n })\n let sessions: Array<{ id: string; name?: string; createdAt?: string }> =\n result.data?.chatSessionsByBoard ?? []\n\n if (sessions.length === 0) {\n // 첫 세션 ensure (idempotent)\n const created = await client.mutate({\n mutation: gql`\n mutation StartBoardAISession($boardId: String!) {\n startBoardAISession(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext()\n })\n const s = created.data?.startBoardAISession\n if (s) sessions = [s]\n }\n\n this.chatSessions = sessions\n // 활성 세션 결정 — 기존 active 가 list 에 있으면 유지, 아니면 첫 번째\n if (!this.chatSessionId || !sessions.some(s => s.id === this.chatSessionId)) {\n this.chatSessionId = sessions[0]?.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /** `@` mention popup 의 도메인 사용자 후보 — chat 의 userProvider prop 으로 wire.\n * query 변할 때마다 호출되므로 server query (`domainUsersForMention`) 를 그대로 위임. */\n private fetchDomainUsersForMention = async (\n query: string\n ): Promise<Array<{ id: string; name?: string; email?: string }>> => {\n try {\n const result = await client.query({\n query: gql`\n query DomainUsersForMention($query: String, $limit: Int) {\n domainUsersForMention(query: $query, limit: $limit) {\n id\n name\n email\n }\n }\n `,\n variables: { query: query || null, limit: 50 },\n context: gqlContext(),\n fetchPolicy: 'cache-first'\n })\n return result.data?.domainUsersForMention ?? []\n } catch (ex) {\n // 조용히 — chat panel 이 빈 결과로 처리\n console.warn('[board-modeller-page] fetchDomainUsersForMention failed:', ex)\n return []\n }\n }\n\n /** 채팅 패널의 탭 클릭 — 활성 세션 전환. */\n private onChatSessionSwitch = (e: CustomEvent) => {\n const newId = e.detail?.sessionId\n if (typeof newId === 'string' && newId !== this.chatSessionId) {\n this.chatSessionId = newId\n }\n }\n\n /** 채팅 패널의 \"+\" 버튼 — 새 세션 생성 후 활성으로 전환. */\n private onChatSessionCreate = async () => {\n if (!this.boardId) return\n try {\n const created = await client.mutate({\n mutation: gql`\n mutation CreateChatSession($boardId: String!, $name: String) {\n createChatSession(boardId: $boardId, name: $name) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId, name: null },\n context: gqlContext()\n })\n const s = created.data?.createChatSession\n if (s) {\n this.chatSessions = [...this.chatSessions, s]\n this.chatSessionId = s.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 모델러의 selected (things-scene Component 인스턴스 배열) 에서 refid 추출.\n *\n * refid 는 things-scene 이 모든 컴포넌트에 자동 발급하는 universal numeric handle.\n * AI 의 selection 표현은 항상 refid 기반 (id 는 데이터 바인딩 이름이며 unique 가\n * 아니라 targeting 에 부적합).\n */\n private extractSelectedRefids(): number[] {\n const sel = this.selected || []\n return sel\n .map((c: any) => {\n if (!c || typeof c.get !== 'function') return null\n const refid = c.get('refid')\n return typeof refid === 'number' && Number.isFinite(refid) ? refid : null\n })\n .filter((x: number | null): x is number => x !== null)\n }\n\n /**\n * AI 채팅 mention popup (`#`) 검색 위임 — things-scene SceneSearchEngine 으로 wrap.\n *\n * F-key Finder 와 동일한 검색 룰 (id → name → tag → type → class → text → data → property)\n * 을 그대로 mention popup 에 재사용. 컴포넌트 트리를 직접 순회하므로 model JSON 으로\n * 변환할 필요 없음 — 일관성 + 성능 이점.\n *\n * 반환 구조 (FilterResult) 는 chat 의 mention-popup 표시 모델. host 는 things-scene\n * Component 에서 refid/id/type/tag/class/text 를 뽑아 candidate 로 채워 넘긴다.\n */\n private searchSceneForMention = (() => {\n const engine = new SceneSearchEngine()\n return (query: string): any[] => {\n const root = (this.scene as any)?.root\n if (!root) return []\n const results = engine.search(root, query)\n return results.map(r => {\n const c: any = r.component\n const refid = typeof c.get === 'function' ? c.get('refid') : undefined\n const id = typeof c.get === 'function' ? c.get('id') : undefined\n const type = typeof c.get === 'function' ? c.get('type') : undefined\n const tag = typeof c.get === 'function' ? c.get('tag') : undefined\n const cls = typeof c.get === 'function' ? c.get('class') : undefined\n const text = typeof c.get === 'function' ? c.get('text') : undefined\n return {\n candidate: {\n refid: typeof refid === 'number' ? refid : undefined,\n label: id || type || 'unknown',\n type: typeof type === 'string' ? type : 'unknown',\n id: typeof id === 'string' && id ? id : undefined,\n tag: typeof tag === 'string' && tag ? tag : undefined,\n class: typeof cls === 'string' && cls ? cls : undefined,\n text: typeof text === 'string' && text ? text : undefined\n },\n matchType: r.matchType,\n matchValue: r.matchValue\n }\n })\n }\n })()\n\n /**\n * 라이브 보드 모델 — things-scene 캔버스가 들고 있는 가장 최신 상태의 deep clone.\n *\n * 사용자 수작업 편집은 scene.model 에만 반영되고 this.model property 에는 자동\n * 동기화되지 않는다. AI 한테 보드 상태를 넘기거나 patch 를 적용할 때는 반드시\n * 이쪽을 쓴다.\n *\n * id 와 refid 는 별개 필드 — 컴포넌트는 model.id (선택, 사용자/AI 가 명시 설정)\n * 와 model.refid (필수, things-scene 자동 발급) 를 둘 다 가질 수 있고 AI 가\n * 양쪽을 구별해서 다룬다 (tool 인자가 분리됨). 따라서 여기서는 model 을 mutate\n * 하지 않고 raw deep clone 만 반환.\n */\n private getLiveBoard(): any {\n const sceneModel = (this.scene as any)?.model\n if (sceneModel) {\n return JSON.parse(JSON.stringify(sceneModel))\n }\n return this.model\n }\n\n /**\n * 채팅에서 patch 도착 — things-scene 에 in-place 적용.\n *\n * 핵심: `this.model = next` 로 모델을 통째 교체하면 ox-scene-viewer 가 scene 을\n * dispose → 재생성 → undo 히스토리/dirty 플래그가 모두 초기화된다.\n * 따라서 일반 add/modify/remove 는 scene 의 in-place mutation API 로 적용 →\n * commander 가 자동으로 snapshot push → CMD+Z 와 저장 안내 팝업이 정상 동작.\n *\n * 'replace' op (보드 전체 교체) 만은 부득이 wholesale 경로로 빠진다 — 이 경우는\n * 사용자에게 명시적으로 안내 후 진행.\n */\n private onSceneEditPatch = (e: CustomEvent) => {\n const { patch, patchId } = e.detail || {}\n if (!patch) return\n // C2: 같은 patch 를 이 클라이언트에서 1회만. 원격 구독이 먼저 적용했으면 로컬 낙관적 적용 skip.\n if (!this._patchGate.tryClaim(patchId)) return\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n const hasReplace = (patch.ops || []).some((op: SceneEditOp) => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(patch, patchId)\n return\n }\n\n try {\n const missed: SceneEditOp[] = []\n // 각 op 의 inverse — dispatcher 가 적용 직전/직후 scene 상태로 계산해 반환.\n // 누적했다가 onBoardEditRevert 가 역순 in-place 적용으로 복원.\n const inverseOps: SceneEditOp[] = []\n const normalize = (c: any) => this.normalizeComponent(c)\n\n for (const op of patch.ops as SceneEditOp[]) {\n const r = dispatchSceneEditOp(scene, op, { normalize })\n if (r.applied) {\n inverseOps.push(...r.inverseOps)\n } else {\n missed.push(op)\n }\n }\n\n // patch 단위로 inverse 보관 — Revert 시 역순 적용\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n\n if (missed.length > 0) {\n const missedDesc = missed\n .map((op: any) => {\n if (op.op === 'modify' || op.op === 'remove') return `refid=${op.refid}`\n if (op.op === 'modifyScene') return 'modifyBoard (scene root unavailable)'\n return op.op\n })\n .join(', ')\n notify(\n 'warn',\n `AI 가 ${missed.length}개의 변경을 시도했지만 적용되지 않았습니다: ${missedDesc}`\n )\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 'replace' op 적용 — scene 통째로 재생성 (undo 히스토리 초기화).\n *\n * AI 가 보드 전체 재구성을 요청한 경우. 사용자에게 history 손실 안내.\n * board-import 데이터 wholesale 적용 등 드문 케이스에 한정.\n *\n * Revert 지원 — replace 직전 보드 model 을 inverse 로 보관 (또 다른 replace).\n */\n private applyPatchWholesale(patch: SceneEditPatch, patchId?: string) {\n try {\n const baseBoard = this.getLiveBoard()\n const inverseOps: SceneEditOp[] = baseBoard\n ? [{ op: 'replace', model: JSON.parse(JSON.stringify(baseBoard)) }]\n : []\n const report = applyScenePatchVerbose(baseBoard, patch)\n const next = report.model as any\n if (report.applied.length === 0) return\n const normalized = (next.components || []).map((c: any) => this.normalizeComponent(c))\n this.model = {\n ...(baseBoard || {}),\n ...(next.width !== undefined && { width: next.width }),\n ...(next.height !== undefined && { height: next.height }),\n components: normalized\n }\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n notify('info', '보드 전체가 교체되어 실행 취소(undo) 히스토리가 초기화되었습니다.')\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n // ── C2: board-patch 실시간 구독 (원격 편집을 이 화면에 반영) ─────────────────────\n private async _subscribeBoardPatches(boardId: string) {\n this._unsubscribeBoardPatches()\n try {\n this._patchSub = await subscribe(\n {\n query: gql`\n subscription ($boardId: String!) {\n boardPatchActivity(boardId: $boardId) {\n id\n opsJson\n source\n summary\n }\n }\n `,\n variables: { boardId }\n },\n { next: ({ data }: any) => this._onRemotePatch(data?.boardPatchActivity) }\n )\n } catch (ex) {\n // 구독 실패 시 협업만 비활성 — 로컬 편집은 정상.\n notifyError(ex)\n }\n }\n\n private _unsubscribeBoardPatches() {\n try {\n this._patchSub?.unsubscribe()\n } catch {\n /* ignore */\n }\n this._patchSub = undefined\n }\n\n /**\n * 원격 patch 도착 — apply-once 게이트 통과 시 in-place 적용. 자기발신 echo 는 게이트가 차단\n * (로컬 onSceneEditPatch 가 이미 같은 patchId 를 claim). 원격분은 revert 인버스 미보관(프로토타입).\n */\n private _onRemotePatch(entry: any) {\n if (!entry?.id) return\n if (!this._patchGate.tryClaim(entry.id)) return\n // server PatchEntry.opsJson 은 GraphQLJSON — 이미 parsed SceneEditOp[] 로 도착(추가 parse 불필요).\n const ops: SceneEditOp[] = Array.isArray(entry.opsJson) ? entry.opsJson : []\n if (!ops.length) return\n const scene = this.scene as any\n if (!scene) return // scene 준비 전 도착분 드롭 (프로토타입 — 큐잉 미지원)\n\n const patch: SceneEditPatch = { ops, summary: entry.summary, confidence: 0 } as SceneEditPatch\n if (ops.some(op => op.op === 'replace')) {\n this.applyPatchWholesale(patch)\n this._syncedModel = this.getLiveBoard() // baseline 동기 — 원격 변경 재캡처 방지\n return\n }\n const normalize = (c: any) => this.normalizeComponent(c)\n for (const op of ops) {\n // echo 안전(멱등): 이미 존재하는 refid 의 add 는 skip. 내 직접편집 echo 가 게이트 claim\n // 보다 먼저 도착해도 중복 생성 안 됨. (modify/remove 는 본래 멱등)\n if (\n op.op === 'add' &&\n (op as any).component?.refid != null &&\n findSceneComponent(scene, { refid: (op as any).component.refid })\n ) {\n continue\n }\n try {\n dispatchSceneEditOp(scene, op, { normalize })\n } catch (ex) {\n notifyError(ex)\n }\n }\n this._syncedModel = this.getLiveBoard() // 원격 변경을 baseline 에 반영 (다음 저장서 재캡처 방지)\n }\n\n /**\n * 채팅에서 board-edit-revert 도착 — 누적된 inverse 를 역순 in-place 적용.\n *\n * - 메모리상 patchInverses Map 만 본다. 페이지 reload 후엔 inverse 가 없어\n * 되돌릴 수 없음 (사용자에게 안내).\n * - 성공 시 서버 revertPatch mutation 호출 → PatchEntry.reverted=true 영속.\n * - in-place 적용이라 undo/dirty/selection 보존 (chatViaTools 의 모든 강점 그대로).\n */\n private onBoardEditRevert = async (e: CustomEvent) => {\n const { patchId } = e.detail || {}\n if (!patchId) return\n const inverses = this.patchInverses.get(patchId)\n if (!inverses || inverses.length === 0) {\n notify(\n 'warn',\n '이 변경은 자동 되돌릴 수 없습니다 (페이지 새로고침 이후 적용된 변경은 메모리에 inverse 가 없습니다).'\n )\n return\n }\n\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n try {\n // 역순 적용 — 마지막 op 부터 되돌림. 단일 patch 안에서도 순서 의미 있음\n // (예: add 후 modify 한 시퀀스를 되돌리려면 modify(원본) 후 remove)\n const reversed = [...inverses].reverse()\n const reverseFakePatch: SceneEditPatch = {\n ops: reversed,\n summary: 'revert',\n confidence: 1\n }\n // hasReplace 면 wholesale, 그렇지 않으면 in-place — 일반 onSceneEditPatch 와 동일\n const hasReplace = reversed.some(op => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(reverseFakePatch)\n } else {\n // in-place 직접 적용 — 새 inverse 누적은 안 함 (revert 의 revert 는 redo, 별개 기능)\n this.applyInverseOpsInPlace(scene, reversed)\n }\n\n this.patchInverses.delete(patchId)\n await this.recordRevertOnServer(patchId)\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * inverse op 시퀀스를 things-scene 위에 in-place 적용 (snapshot/undo 보존).\n * dispatcher 재사용 — inverse 누적은 무시 (revert 의 revert 는 redo, 별개 기능).\n */\n private applyInverseOpsInPlace(scene: any, ops: SceneEditOp[]): void {\n const normalize = (c: any) => this.normalizeComponent(c)\n for (const op of ops) {\n dispatchSceneEditOp(scene, op, { normalize })\n }\n }\n\n /** 서버 PatchEntry.reverted=true 영속 — fail 해도 UI 는 이미 되돌렸으니 warn 만. */\n private async recordRevertOnServer(patchId: string): Promise<void> {\n try {\n await client.mutate({ mutation: REVERT_PATCH_MUTATION, variables: { patchId } })\n } catch (e: any) {\n console.warn('[board-modeller] revertPatch server persist failed:', e?.message ?? e)\n }\n }\n\n /**\n * AI 가 ephemeral scene action (selection / view / mode) 을 실행하라고 요청.\n *\n * scene-edit-patch 와 별개 채널 — 모델 변경 X, undo 영향 X, dirty flag 무관.\n * things-scene API 직접 호출. 잘못된 action / 누락된 컴포넌트는 console.warn 만.\n */\n private onSceneActionExecute = (e: CustomEvent) => {\n const { actions } = e.detail || {}\n if (!Array.isArray(actions) || actions.length === 0) return\n const scene = this.scene as any\n if (!scene) return\n\n let modeChanged = false\n for (const action of actions) {\n try {\n dispatchSceneAction(scene, action)\n if (action?.action === 'setSceneMode') modeChanged = true\n } catch (ex: any) {\n console.warn('[board-modeller] action execute failed:', action, ex?.message ?? ex)\n }\n }\n // setSceneMode 가 있었으면 page 의 reactive mode 도 동기 (Lit re-render 트리거)\n if (modeChanged) this.mode = scene.mode\n }\n\n /**\n * AI 가 만든 컴포넌트를 things-scene 이 기대하는 완전한 형태로 normalize.\n * BoardModeller 에 등록된 template.model (default 값) 위에 AI 응답을 덮어쓴다.\n * 이 단계 없이 things-scene 에 넣으면 필수 속성 누락 시 render 에서 crash 가능\n * (예: gauge-circle 의 value 가 undefined → toString() TypeError).\n */\n private normalizeComponent(c: any): any {\n if (!c || typeof c !== 'object' || typeof c.type !== 'string') return c\n const template = this.findTemplateByType(c.type)\n if (!template || !template.model) return c\n return mergeDefaultsDeep(template.model, c)\n }\n\n private findTemplateByType(type: string): any {\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && t.type === type) return t\n }\n }\n return undefined\n }\n\n async updated(changes) {\n if (changes.has('boardId')) {\n try {\n if (await hasPrivilege({ privilege: 'mutation', category: 'board' })) {\n this.refresh()\n // C2: 보드 변경 시 그 보드의 실시간 patch 구독 (이전 보드 구독은 해제).\n if (this.boardId) this._subscribeBoardPatches(this.boardId)\n else this._unsubscribeBoardPatches()\n } else {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n }\n } catch {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n }\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this._unsubscribeBoardPatches()\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n getModellerToolbarMode().then(mode => (this.toolbarMode = mode))\n }\n\n if (this.active) {\n this.boardId = lifecycle.resourceId\n } else {\n this.boardId = null\n this.board = null\n this.model = null\n this.preparing = false\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n this.updateContext()\n }\n }\n\n render() {\n const oops = !this.preparing && !this.model && this.oopsNote\n\n return html`\n <div class=\"modeller-area\">\n ${oops\n ? html`<ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note>`\n : html`\n <ox-board-modeller\n .boardName=${this.boardName || ''}\n .contextualToolbar=${this.toolbarMode !== 'toolbar'}\n .contextualToolbarPlacement=${this.toolbarMode === 'docked' ? 'docked' : 'floating'}\n .mode=${this.mode}\n .loadTracker=${this._loadTracker}\n @mode-changed=${e => {\n this.mode = e.detail.value\n }}\n .model=${this.model}\n @model-changed=${e => {\n this.model = e.detail.value\n }}\n .scene=${this.scene}\n @scene-changed=${e => {\n this.scene = e.detail.value\n }}\n .selected=${this.selected}\n @selected-changed=${e => {\n this.selected = e.detail.value\n }}\n .provider=${provider}\n @save-model=${e => this.saveBoard()}\n .componentGroupList=${this.componentGroupList}\n .fonts=${this._fontCtrl.fonts}\n .hideProperty=${this.hideProperty}\n >\n </ox-board-modeller>\n `}\n ${this.scene && boardPlacementProvider()\n ? html`<board-placement-tray .boardId=${this.boardId} .scene=${this.scene}></board-placement-tray>`\n : nothing}\n ${this.boardId\n ? html`\n <button\n class=\"ai-toggle ${this.aiPanelOpen ? 'open' : ''}\"\n title=\"${i18next.t('text.ai_assistant') || 'AI Assistant'}\"\n @click=${this.toggleAIPanel}>\n <md-icon>${this.aiPanelOpen ? 'close' : 'auto_awesome'}</md-icon>AI\n </button>\n `\n : nothing}\n </div>\n ${this.aiPanelOpen\n ? html`\n <div class=\"ai-panel\">\n <ox-assistant-chat\n chat-endpoint=\"boardAIChat\"\n .sessionId=${this.chatSessionId}\n .sessions=${this.chatSessions}\n .currentBoard=${this.model}\n .boardProvider=${() => this.getLiveBoard()}\n .searchProvider=${this.searchSceneForMention}\n .userProvider=${this.fetchDomainUsersForMention}\n .knownTypes=${this.knownTypes}\n .categories=${this.knownCategories}\n .componentSchemas=${this.componentSchemas}\n .selectedRefids=${this.extractSelectedRefids()}\n @session-switch=${this.onChatSessionSwitch}\n @session-create=${this.onChatSessionCreate}\n @scene-edit-patch=${this.onSceneEditPatch}\n @board-edit-revert=${this.onBoardEditRevert}\n @scene-action-execute=${this.onSceneActionExecute}>\n </ox-assistant-chat>\n </div>\n `\n : nothing}\n `\n }\n\n async updateBoard() {\n try {\n this.preparing = true\n\n const { id, name, description, groupId } = this.board\n const model = JSON.stringify(this.scene.model)\n\n await client.mutate({\n mutation: gql`\n mutation UpdateBoard($id: String!, $patch: BoardPatch!) {\n updateBoard(id: $id, patch: $patch) {\n id\n }\n }\n `,\n variables: {\n id,\n patch: { name, description, model, groupId }\n },\n context: gqlContext()\n })\n\n notify('info', i18next.t('text.saved'))\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n }\n\n this.updateContext()\n }\n\n async saveBoard() {\n await this.updateBoard()\n this.modeller?.preserve()\n // C3: 저장 후(이산적·사용자 의도) 직접편집을 ops 로 캡처해 방송. best-effort —\n // 실패해도 저장 자체엔 영향 없음(이미 완료). (라이브 per-edit 동기화는 C3c 후보.)\n this._captureDirectEdits()\n }\n\n /**\n * C3: 마지막 동기 모델 → 현재 모델 diff 를 recordDirectPatch 로 기록(=같은 board 구독자 방송).\n * 반환된 patchId 를 게이트에 claim → 자기발신 echo skip. baseline 갱신.\n * sessionId 없으면(AI 세션 미연결) skip — 협업 비활성, 편집은 정상.\n */\n private async _captureDirectEdits() {\n try {\n if (!this.chatSessionId) return\n const current = this.getLiveBoard()\n if (!current) return\n if (!this._syncedModel) {\n this._syncedModel = current // 첫 저장 = baseline 확립 (이전 상태 미상이라 방송 안 함)\n return\n }\n const ops = diffBoardModel(this._syncedModel, current)\n this._syncedModel = current\n if (ops.length === 0) return\n\n const res = await client.mutate({\n mutation: gql`\n mutation RecordDirectPatch($sessionId: String!, $ops: JSON!, $summary: String) {\n recordDirectPatch(sessionId: $sessionId, ops: $ops, summary: $summary) {\n id\n }\n }\n `,\n variables: { sessionId: this.chatSessionId, ops, summary: `직접 편집 ${ops.length}건` },\n context: gqlContext()\n })\n const id = res?.data?.recordDirectPatch?.id\n if (id) this._patchGate.tryClaim(id) // 내 직접편집의 broadcast echo 차단\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n async canDeactivate(): Promise<boolean> {\n if (this.modeller?.hasUnpreservedChanges()) {\n return await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('prompt.sure to navigate away?'),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n return true\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"board-modeller-page.js","sourceRoot":"","sources":["../../client/pages/board-modeller-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport 'things-scene-components'\nimport '@operato/board/ox-board-modeller.js'\nimport '@operato/oops'\nimport '@things-factory/board-ai'\n\nimport gql from 'graphql-tag'\nimport { getModellerToolbarMode, ModellerToolbarMode } from '../setting-let/board-modeller-setting-let.js'\nimport { css, html, nothing } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { BoardModeller } from '@operato/board/ox-board-modeller.js'\nimport { LoadTracker, SceneSearchEngine } from '@hatiolab/things-scene'\nimport { OxPropertyEditor } from '@operato/property-editor'\nimport { PageView, FontController } from '@operato/shell'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport {\n applyScenePatchVerbose,\n dispatchSceneAction,\n dispatchSceneEditOp,\n findSceneComponent,\n type SceneEditOp,\n type SceneEditPatch\n} from '@operato/scene-ops'\nimport { client, gqlContext, subscribe } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { OxPrompt } from '@operato/popup/ox-prompt.js'\n\nimport { provider } from '@operato/board/board-provider.js'\nimport '../board-placement-tray.js' // 배치 팔레트 오버레이(호스트-등록 provider 있을 때만 표시)\nimport { boardPlacementProvider } from '@operato/board/board-placement-palette.js'\nimport components from 'things-scene-components-with-tools'\nimport { notify, notifyError } from '../utils/notify-helper.js'\nimport { PatchApplyGate } from '../utils/patch-apply-gate.js'\nimport { diffBoardModel } from '../utils/board-model-diff.js'\n\nexport { findSceneComponent }\n\n/** 서버 PatchEntry.reverted=true 플래그 영속용 mutation. */\nconst REVERT_PATCH_MUTATION = gql`\n mutation RevertPatch($patchId: String!) {\n revertPatch(patchId: $patchId)\n }\n`\n\n/**\n * default 위에 override 를 깊게 merge.\n * - override 의 키 값이 undefined 가 아닌 경우 우선 적용\n * - override 의 nested object 는 default 와 deep merge\n * - array / primitive 는 override 가 그대로 우선\n */\nfunction mergeDefaultsDeep(defaults: any, override: any): any {\n if (defaults === null || defaults === undefined) return override\n if (override === null || override === undefined) return defaults\n if (typeof defaults !== 'object' || typeof override !== 'object') return override\n if (Array.isArray(defaults) || Array.isArray(override)) return override\n\n const out: any = { ...defaults }\n for (const key of Object.keys(override)) {\n const dv = (defaults as any)[key]\n const ov = (override as any)[key]\n if (\n dv !== null &&\n ov !== null &&\n typeof dv === 'object' &&\n typeof ov === 'object' &&\n !Array.isArray(dv) &&\n !Array.isArray(ov)\n ) {\n out[key] = mergeDefaultsDeep(dv, ov)\n } else if (ov !== undefined) {\n out[key] = ov\n }\n }\n return out\n}\n\n@customElement('board-modeller-page')\nexport class BoardModellerPage extends PageView {\n constructor() {\n super()\n\n components.forEach(({ templates = [], groups = [] }) => {\n groups.forEach(group => BoardModeller.registerGroup(group))\n BoardModeller.registerTemplate(templates)\n })\n\n /* 컴포넌트에서 정의된 에디터들을 MODELLER_EDITORS에 등록 */\n const addedEditors = {}\n for (const component in components) {\n let { editors } = components[component]\n\n editors &&\n editors.forEach(editor => {\n let { type, element } = editor\n\n addedEditors[type] = element\n })\n }\n\n OxPropertyEditor.register(addedEditors)\n }\n\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: row;\n\n overflow: hidden;\n position: relative;\n }\n\n .modeller-area {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n }\n\n ox-board-modeller {\n flex: 1;\n }\n\n /*\n * The assistant's door and its column, on the scheme's own surfaces. The door is a quiet\n * tonal pill on the canvas, like the save FAB beside it; open, it takes the pressed tone.\n */\n .ai-toggle {\n position: absolute;\n right: 12px;\n bottom: 12px;\n z-index: 10;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n height: 36px;\n padding: 0 14px 0 11px;\n border: 1px solid var(--md-sys-color-outline-variant);\n border-radius: 999px;\n background: var(--md-sys-color-surface-container-high);\n color: var(--md-sys-color-on-surface);\n font: 500 0.8rem/1 var(--theme-font, Roboto, sans-serif);\n cursor: pointer;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n transition: background 0.15s, transform 0.1s;\n }\n .ai-toggle md-icon {\n --md-icon-size: 18px;\n color: var(--md-sys-color-primary);\n font-variation-settings: 'FILL' 1;\n }\n .ai-toggle:hover { background: var(--md-sys-color-surface-container-highest); }\n .ai-toggle:active { transform: scale(0.97); }\n .ai-toggle.open {\n border-color: transparent;\n background: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n }\n .ai-toggle.open md-icon { color: inherit; font-variation-settings: 'FILL' 0; }\n\n .ai-panel {\n flex: 0 0 340px;\n display: flex;\n min-width: 0;\n border-left: 1px solid var(--md-sys-color-outline-variant);\n background: var(--md-sys-color-surface-container-low);\n color: var(--md-sys-color-on-surface);\n }\n\n ox-assistant-chat { flex: 1; }\n\n ox-oops-note {\n display: block;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n @media (max-width: 900px) {\n .ai-panel {\n flex-basis: 100%;\n position: absolute;\n inset: 0;\n z-index: 20;\n }\n }\n `\n ]\n\n @property({ type: String }) boardId?: string | null\n @property({ type: String }) boardName?: string = ''\n /* Read from the user's board-modeller setting each time the page is shown. */\n @state() private toolbarMode: ModellerToolbarMode = 'contextual'\n @property({ type: Object }) model: any = null\n @property({ type: Array }) selected: any = []\n @property({ type: Number }) mode?: number = 1\n @property({ type: Boolean }) hideProperty?: boolean = false\n @property({ type: String }) overlay?: string | null = null\n @property({ type: Object }) scene: any = null\n @property({ type: Array }) componentGroupList?: any[] = BoardModeller.groups\n @property({ type: Array }) propertyEditor: any\n @property({ type: Boolean }) preparing?: boolean\n\n /** AI 협력 세션 id — 현재 활성 세션. boardId 변경 시 자동 ensure. 다중 세션 시 활성 1개. */\n @state() chatSessionId?: string\n\n /** 보드의 모든 ChatSession (탭으로 표시). */\n @state() chatSessions: Array<{ id: string; name?: string; createdAt?: string }> = []\n\n /** AI 채팅 패널 열림 상태 (기본 닫힘) */\n @state() aiPanelOpen = false\n /**\n * The conversation the AI panel stands in — the mode the app server registered as the default for\n * a board (ADR-0061 decision 7). The server then owns persona, tool categories and model. Absent\n * when the app registered none: the panel keeps its older, undeclared behaviour.\n */\n @state() aiMode?: { kind: string; target?: string }\n private aiModeResolved = false\n\n /**\n * 적용된 patch 별 inverse op 시퀀스 — Revert 기능용.\n *\n * Map<patchId, inverseOps[]>: 각 patch 적용 시점에 계산해 저장. revert 클릭\n * 시 역순 in-place 적용. 페이지 reload 시 손실 — reload 후 revert 시도는\n * notify 로 안내 (메모리 외 영속은 별개 작업).\n */\n private patchInverses = new Map<string, SceneEditOp[]>()\n\n // C2 실시간 공동편집 — apply-once 게이트(echo/순서 무관 dedup) + board-patch 구독.\n private _patchGate = new PatchApplyGate()\n private _patchSub?: { unsubscribe: () => void | Promise<void> }\n // C3 직접편집 캡처 — 마지막으로 동기화된(서버/타참여자가 아는) 모델. diff 의 baseline.\n private _syncedModel: any = null\n\n /** 모델러에 등록된 컴포넌트 type 목록 — chat 호출 시 LLM 에 전달 (lazy cache) */\n private _knownTypesCache?: string[]\n /** 등록된 type 의 group 분류 — categories 로 LLM 에 전달 */\n private _knownCategoriesCache?: string[]\n\n private get knownTypes(): string[] {\n if (!this._knownTypesCache) {\n const types = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.type === 'string') types.add(t.type)\n }\n }\n this._knownTypesCache = Array.from(types).sort()\n }\n return this._knownTypesCache\n }\n\n private get knownCategories(): string[] {\n if (!this._knownCategoriesCache) {\n const cats = new Set<string>()\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && typeof t.group === 'string') cats.add(t.group)\n }\n }\n this._knownCategoriesCache = Array.from(cats).sort()\n }\n return this._knownCategoriesCache\n }\n\n /**\n * type 별 유효 속성 스킴 — LLM 이 정확한 컴포넌트를 만들도록 (lazy cache).\n *\n * 핵심: 좌표 표현은 type 마다 다르다 (left/top vs cx/cy vs points 등).\n * 따라서 OMIT 하지 않고 `geometryKeys` 로 별도 노출 → LLM 이 type 별 좌표 키 사용 가능.\n */\n private _componentSchemasCache?: Array<{\n type: string\n description?: string\n group?: string\n /** template.model 의 좌표/크기 관련 키들 — type 별 다름 */\n geometryKeys?: string[]\n /** 좌표 외 type 특화 속성 (default 값 또는 nested 키 목록) */\n properties?: Record<string, any>\n }>\n\n private get componentSchemas() {\n if (!this._componentSchemasCache) {\n const out: Array<{\n type: string\n description?: string\n group?: string\n geometryKeys?: string[]\n properties?: Record<string, any>\n }> = []\n const NON_PROPS = new Set(['type', 'id', 'name', 'class'])\n // 좌표/크기/경로 관련 키들 — type 마다 다른 조합으로 사용\n const GEOMETRY_KEYS = new Set([\n 'left',\n 'top',\n 'right',\n 'bottom',\n 'x',\n 'y',\n 'cx',\n 'cy',\n 'width',\n 'height',\n 'rx',\n 'ry',\n 'radius',\n 'rotation',\n 'translate',\n 'scale',\n 'points',\n 'path',\n 'vertices',\n 'verticles',\n 'startX',\n 'startY',\n 'endX',\n 'endY',\n 'startPoint',\n 'endPoint'\n ])\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (!t || typeof t.type !== 'string') continue\n const properties: Record<string, any> = {}\n const geometryKeys: string[] = []\n const model: any = t.model || {}\n for (const key of Object.keys(model)) {\n if (NON_PROPS.has(key)) continue\n if (GEOMETRY_KEYS.has(key)) {\n geometryKeys.push(key)\n continue\n }\n const v = model[key]\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n properties[key] = Object.fromEntries(\n Object.keys(v)\n .slice(0, 8)\n .map(k => [k, null])\n )\n } else if (Array.isArray(v)) {\n properties[key] = []\n } else {\n properties[key] = v\n }\n }\n out.push({\n type: t.type,\n description: t.description || undefined,\n group: t.group || undefined,\n geometryKeys: geometryKeys.length > 0 ? geometryKeys : undefined,\n properties: Object.keys(properties).length > 0 ? properties : undefined\n })\n }\n }\n this._componentSchemasCache = out\n }\n return this._componentSchemasCache\n }\n\n private board: any = null\n private _loadTracker?: LoadTracker\n private _fontCtrl = new FontController(this)\n @query('ox-board-modeller') modeller?: BoardModeller\n\n get context() {\n return {\n title: this.board ? this.boardName : this.preparing ? 'Fetching board...' : '',\n help: 'board-modeller/modeller',\n widebleed: true,\n /* No title row: the canvas is the subject here, the name is in the browser tab and the\n * property panel already. Same call figure-modeller-page.ts makes; the title itself stays\n * because the tab and the document title read it. */\n heading: false\n }\n }\n\n get oopsNote() {\n return {\n icon: 'color_lens',\n title: i18next.t('title.no board to design'),\n description: i18next.t('text.no board to design')\n }\n }\n\n async refresh() {\n if (!this.boardId) {\n this.board = null\n this.model = null\n\n return\n }\n try {\n // 이전 보드 완전히 클리어\n this.board = null\n this.model = null\n this._loadTracker = new LoadTracker()\n this._loadTracker.setPhase('fetch')\n this.preparing = true\n this.updateContext()\n\n const response = await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n model\n }\n }\n `,\n variables: { id: this.boardId },\n context: gqlContext()\n })\n\n this._loadTracker?.setPhase('parse')\n\n const board = response.data.board\n\n if (!board) {\n this.board = null\n throw new Error('board not found')\n }\n\n this.board = {\n ...board,\n model: JSON.parse(board.model)\n }\n\n this.boardName = this.board.name\n this.model = {\n ...this.board.model\n }\n\n // AI 협력 세션 — 보드 전환 시 이전 보드의 세션 / 세션 리스트 정리 (chat panel 의\n // sessionId/sessions 변화 감지 → history 비우고 새로 로드). 패널 열린 채 보드 옮겼다면\n // 새 보드의 세션 리스트를 즉시 ensure (fire-and-forget — 에러는 ensureChatSession 처리).\n this.chatSessionId = undefined\n this.chatSessions = []\n if (this.aiMode) this.aiMode = { ...this.aiMode, target: this.boardId ?? undefined }\n if (this.aiPanelOpen && this.boardId) {\n this.ensureChatSession()\n }\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n this.updateContext()\n }\n }\n\n /** 패널 토글 시 호출 — 열 때만 chatSession 보장 (세션 리스트 로드 + 활성 세션 결정) */\n private async toggleAIPanel() {\n const willOpen = !this.aiPanelOpen\n if (willOpen && this.boardId) {\n await Promise.all([this.ensureChatSession(), this.resolveAIMode()])\n }\n this.aiPanelOpen = willOpen\n }\n\n /** Ask the server which conversation a board opens in. Once per page; the target follows the board. */\n private async resolveAIMode() {\n if (this.aiModeResolved) return\n this.aiModeResolved = true\n try {\n const result = await client.query({\n query: gql`\n query BoardAssistantModes($subject: String!) {\n assistantModes(subject: $subject) {\n kind\n isDefault\n }\n }\n `,\n variables: { subject: 'board' },\n context: gqlContext()\n })\n const modes = (result.data?.assistantModes ?? []) as Array<{ kind: string; isDefault: boolean }>\n const chosen = modes.find(m => m.isDefault) ?? modes[0]\n this.aiMode = chosen ? { kind: chosen.kind, target: this.boardId ?? undefined } : undefined\n } catch (e) {\n /* A server without ai-assistant's mode door: stay undeclared rather than break the panel. */\n this.aiMode = undefined\n }\n }\n\n private onAssistantModeChange(e: CustomEvent) {\n const kind = e.detail?.kind\n if (kind) this.aiMode = { kind, target: this.boardId ?? undefined }\n }\n\n /** 보드의 모든 ChatSession 목록을 로드 + 활성 세션 보장.\n * - 세션이 0 개면 startBoardAISession 으로 첫 세션 생성 (단일 세션 UX 호환)\n * - 활성 세션 미설정 시 첫 번째 세션을 활성으로\n * - 이미 활성 세션 set 돼있고 list 에 포함되면 유지 */\n private async ensureChatSession() {\n if (!this.boardId) return\n try {\n const result = await client.query({\n query: gql`\n query ChatSessionsByBoard($boardId: String!) {\n chatSessionsByBoard(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext(),\n fetchPolicy: 'network-only'\n })\n let sessions: Array<{ id: string; name?: string; createdAt?: string }> =\n result.data?.chatSessionsByBoard ?? []\n\n if (sessions.length === 0) {\n // 첫 세션 ensure (idempotent)\n const created = await client.mutate({\n mutation: gql`\n mutation StartBoardAISession($boardId: String!) {\n startBoardAISession(boardId: $boardId) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId },\n context: gqlContext()\n })\n const s = created.data?.startBoardAISession\n if (s) sessions = [s]\n }\n\n this.chatSessions = sessions\n // 활성 세션 결정 — 기존 active 가 list 에 있으면 유지, 아니면 첫 번째\n if (!this.chatSessionId || !sessions.some(s => s.id === this.chatSessionId)) {\n this.chatSessionId = sessions[0]?.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /** `@` mention popup 의 도메인 사용자 후보 — chat 의 userProvider prop 으로 wire.\n * query 변할 때마다 호출되므로 server query (`domainUsersForMention`) 를 그대로 위임. */\n private fetchDomainUsersForMention = async (\n query: string\n ): Promise<Array<{ id: string; name?: string; email?: string }>> => {\n try {\n const result = await client.query({\n query: gql`\n query DomainUsersForMention($query: String, $limit: Int) {\n domainUsersForMention(query: $query, limit: $limit) {\n id\n name\n email\n }\n }\n `,\n variables: { query: query || null, limit: 50 },\n context: gqlContext(),\n fetchPolicy: 'cache-first'\n })\n return result.data?.domainUsersForMention ?? []\n } catch (ex) {\n // 조용히 — chat panel 이 빈 결과로 처리\n console.warn('[board-modeller-page] fetchDomainUsersForMention failed:', ex)\n return []\n }\n }\n\n /** 채팅 패널의 탭 클릭 — 활성 세션 전환. */\n private onChatSessionSwitch = (e: CustomEvent) => {\n const newId = e.detail?.sessionId\n if (typeof newId === 'string' && newId !== this.chatSessionId) {\n this.chatSessionId = newId\n }\n }\n\n /** 채팅 패널의 \"+\" 버튼 — 새 세션 생성 후 활성으로 전환. */\n private onChatSessionCreate = async () => {\n if (!this.boardId) return\n try {\n const created = await client.mutate({\n mutation: gql`\n mutation CreateChatSession($boardId: String!, $name: String) {\n createChatSession(boardId: $boardId, name: $name) {\n id\n name\n createdAt\n }\n }\n `,\n variables: { boardId: this.boardId, name: null },\n context: gqlContext()\n })\n const s = created.data?.createChatSession\n if (s) {\n this.chatSessions = [...this.chatSessions, s]\n this.chatSessionId = s.id\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 모델러의 selected (things-scene Component 인스턴스 배열) 에서 refid 추출.\n *\n * refid 는 things-scene 이 모든 컴포넌트에 자동 발급하는 universal numeric handle.\n * AI 의 selection 표현은 항상 refid 기반 (id 는 데이터 바인딩 이름이며 unique 가\n * 아니라 targeting 에 부적합).\n */\n private extractSelectedRefids(): number[] {\n const sel = this.selected || []\n return sel\n .map((c: any) => {\n if (!c || typeof c.get !== 'function') return null\n const refid = c.get('refid')\n return typeof refid === 'number' && Number.isFinite(refid) ? refid : null\n })\n .filter((x: number | null): x is number => x !== null)\n }\n\n /**\n * AI 채팅 mention popup (`#`) 검색 위임 — things-scene SceneSearchEngine 으로 wrap.\n *\n * F-key Finder 와 동일한 검색 룰 (id → name → tag → type → class → text → data → property)\n * 을 그대로 mention popup 에 재사용. 컴포넌트 트리를 직접 순회하므로 model JSON 으로\n * 변환할 필요 없음 — 일관성 + 성능 이점.\n *\n * 반환 구조 (FilterResult) 는 chat 의 mention-popup 표시 모델. host 는 things-scene\n * Component 에서 refid/id/type/tag/class/text 를 뽑아 candidate 로 채워 넘긴다.\n */\n private searchSceneForMention = (() => {\n const engine = new SceneSearchEngine()\n return (query: string): any[] => {\n const root = (this.scene as any)?.root\n if (!root) return []\n const results = engine.search(root, query)\n return results.map(r => {\n const c: any = r.component\n const refid = typeof c.get === 'function' ? c.get('refid') : undefined\n const id = typeof c.get === 'function' ? c.get('id') : undefined\n const type = typeof c.get === 'function' ? c.get('type') : undefined\n const tag = typeof c.get === 'function' ? c.get('tag') : undefined\n const cls = typeof c.get === 'function' ? c.get('class') : undefined\n const text = typeof c.get === 'function' ? c.get('text') : undefined\n return {\n candidate: {\n refid: typeof refid === 'number' ? refid : undefined,\n label: id || type || 'unknown',\n type: typeof type === 'string' ? type : 'unknown',\n id: typeof id === 'string' && id ? id : undefined,\n tag: typeof tag === 'string' && tag ? tag : undefined,\n class: typeof cls === 'string' && cls ? cls : undefined,\n text: typeof text === 'string' && text ? text : undefined\n },\n matchType: r.matchType,\n matchValue: r.matchValue\n }\n })\n }\n })()\n\n /**\n * 라이브 보드 모델 — things-scene 캔버스가 들고 있는 가장 최신 상태의 deep clone.\n *\n * 사용자 수작업 편집은 scene.model 에만 반영되고 this.model property 에는 자동\n * 동기화되지 않는다. AI 한테 보드 상태를 넘기거나 patch 를 적용할 때는 반드시\n * 이쪽을 쓴다.\n *\n * id 와 refid 는 별개 필드 — 컴포넌트는 model.id (선택, 사용자/AI 가 명시 설정)\n * 와 model.refid (필수, things-scene 자동 발급) 를 둘 다 가질 수 있고 AI 가\n * 양쪽을 구별해서 다룬다 (tool 인자가 분리됨). 따라서 여기서는 model 을 mutate\n * 하지 않고 raw deep clone 만 반환.\n */\n private getLiveBoard(): any {\n const sceneModel = (this.scene as any)?.model\n if (sceneModel) {\n return JSON.parse(JSON.stringify(sceneModel))\n }\n return this.model\n }\n\n /**\n * 채팅에서 patch 도착 — things-scene 에 in-place 적용.\n *\n * 핵심: `this.model = next` 로 모델을 통째 교체하면 ox-scene-viewer 가 scene 을\n * dispose → 재생성 → undo 히스토리/dirty 플래그가 모두 초기화된다.\n * 따라서 일반 add/modify/remove 는 scene 의 in-place mutation API 로 적용 →\n * commander 가 자동으로 snapshot push → CMD+Z 와 저장 안내 팝업이 정상 동작.\n *\n * 'replace' op (보드 전체 교체) 만은 부득이 wholesale 경로로 빠진다 — 이 경우는\n * 사용자에게 명시적으로 안내 후 진행.\n */\n private onSceneEditPatch = (e: CustomEvent) => {\n const { patch, patchId } = e.detail || {}\n if (!patch) return\n // C2: 같은 patch 를 이 클라이언트에서 1회만. 원격 구독이 먼저 적용했으면 로컬 낙관적 적용 skip.\n if (!this._patchGate.tryClaim(patchId)) return\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n const hasReplace = (patch.ops || []).some((op: SceneEditOp) => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(patch, patchId)\n return\n }\n\n try {\n const missed: SceneEditOp[] = []\n // 각 op 의 inverse — dispatcher 가 적용 직전/직후 scene 상태로 계산해 반환.\n // 누적했다가 onBoardEditRevert 가 역순 in-place 적용으로 복원.\n const inverseOps: SceneEditOp[] = []\n const normalize = (c: any) => this.normalizeComponent(c)\n\n for (const op of patch.ops as SceneEditOp[]) {\n const r = dispatchSceneEditOp(scene, op, { normalize })\n if (r.applied) {\n inverseOps.push(...r.inverseOps)\n } else {\n missed.push(op)\n }\n }\n\n // patch 단위로 inverse 보관 — Revert 시 역순 적용\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n\n if (missed.length > 0) {\n const missedDesc = missed\n .map((op: any) => {\n if (op.op === 'modify' || op.op === 'remove') return `refid=${op.refid}`\n if (op.op === 'modifyScene') return 'modifyBoard (scene root unavailable)'\n return op.op\n })\n .join(', ')\n notify(\n 'warn',\n `AI 가 ${missed.length}개의 변경을 시도했지만 적용되지 않았습니다: ${missedDesc}`\n )\n }\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * 'replace' op 적용 — scene 통째로 재생성 (undo 히스토리 초기화).\n *\n * AI 가 보드 전체 재구성을 요청한 경우. 사용자에게 history 손실 안내.\n * board-import 데이터 wholesale 적용 등 드문 케이스에 한정.\n *\n * Revert 지원 — replace 직전 보드 model 을 inverse 로 보관 (또 다른 replace).\n */\n private applyPatchWholesale(patch: SceneEditPatch, patchId?: string) {\n try {\n const baseBoard = this.getLiveBoard()\n const inverseOps: SceneEditOp[] = baseBoard\n ? [{ op: 'replace', model: JSON.parse(JSON.stringify(baseBoard)) }]\n : []\n const report = applyScenePatchVerbose(baseBoard, patch)\n const next = report.model as any\n if (report.applied.length === 0) return\n const normalized = (next.components || []).map((c: any) => this.normalizeComponent(c))\n this.model = {\n ...(baseBoard || {}),\n ...(next.width !== undefined && { width: next.width }),\n ...(next.height !== undefined && { height: next.height }),\n components: normalized\n }\n if (patchId && inverseOps.length > 0) {\n this.patchInverses.set(patchId, inverseOps)\n }\n notify('info', '보드 전체가 교체되어 실행 취소(undo) 히스토리가 초기화되었습니다.')\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n // ── C2: board-patch 실시간 구독 (원격 편집을 이 화면에 반영) ─────────────────────\n private async _subscribeBoardPatches(boardId: string) {\n this._unsubscribeBoardPatches()\n try {\n this._patchSub = await subscribe(\n {\n query: gql`\n subscription ($boardId: String!) {\n boardPatchActivity(boardId: $boardId) {\n id\n opsJson\n source\n summary\n }\n }\n `,\n variables: { boardId }\n },\n { next: ({ data }: any) => this._onRemotePatch(data?.boardPatchActivity) }\n )\n } catch (ex) {\n // 구독 실패 시 협업만 비활성 — 로컬 편집은 정상.\n notifyError(ex)\n }\n }\n\n private _unsubscribeBoardPatches() {\n try {\n this._patchSub?.unsubscribe()\n } catch {\n /* ignore */\n }\n this._patchSub = undefined\n }\n\n /**\n * 원격 patch 도착 — apply-once 게이트 통과 시 in-place 적용. 자기발신 echo 는 게이트가 차단\n * (로컬 onSceneEditPatch 가 이미 같은 patchId 를 claim). 원격분은 revert 인버스 미보관(프로토타입).\n */\n private _onRemotePatch(entry: any) {\n if (!entry?.id) return\n if (!this._patchGate.tryClaim(entry.id)) return\n // server PatchEntry.opsJson 은 GraphQLJSON — 이미 parsed SceneEditOp[] 로 도착(추가 parse 불필요).\n const ops: SceneEditOp[] = Array.isArray(entry.opsJson) ? entry.opsJson : []\n if (!ops.length) return\n const scene = this.scene as any\n if (!scene) return // scene 준비 전 도착분 드롭 (프로토타입 — 큐잉 미지원)\n\n const patch: SceneEditPatch = { ops, summary: entry.summary, confidence: 0 } as SceneEditPatch\n if (ops.some(op => op.op === 'replace')) {\n this.applyPatchWholesale(patch)\n this._syncedModel = this.getLiveBoard() // baseline 동기 — 원격 변경 재캡처 방지\n return\n }\n const normalize = (c: any) => this.normalizeComponent(c)\n for (const op of ops) {\n // echo 안전(멱등): 이미 존재하는 refid 의 add 는 skip. 내 직접편집 echo 가 게이트 claim\n // 보다 먼저 도착해도 중복 생성 안 됨. (modify/remove 는 본래 멱등)\n if (\n op.op === 'add' &&\n (op as any).component?.refid != null &&\n findSceneComponent(scene, { refid: (op as any).component.refid })\n ) {\n continue\n }\n try {\n dispatchSceneEditOp(scene, op, { normalize })\n } catch (ex) {\n notifyError(ex)\n }\n }\n this._syncedModel = this.getLiveBoard() // 원격 변경을 baseline 에 반영 (다음 저장서 재캡처 방지)\n }\n\n /**\n * 채팅에서 board-edit-revert 도착 — 누적된 inverse 를 역순 in-place 적용.\n *\n * - 메모리상 patchInverses Map 만 본다. 페이지 reload 후엔 inverse 가 없어\n * 되돌릴 수 없음 (사용자에게 안내).\n * - 성공 시 서버 revertPatch mutation 호출 → PatchEntry.reverted=true 영속.\n * - in-place 적용이라 undo/dirty/selection 보존 (chatViaTools 의 모든 강점 그대로).\n */\n private onBoardEditRevert = async (e: CustomEvent) => {\n const { patchId } = e.detail || {}\n if (!patchId) return\n const inverses = this.patchInverses.get(patchId)\n if (!inverses || inverses.length === 0) {\n notify(\n 'warn',\n '이 변경은 자동 되돌릴 수 없습니다 (페이지 새로고침 이후 적용된 변경은 메모리에 inverse 가 없습니다).'\n )\n return\n }\n\n const scene = this.scene as any\n if (!scene) {\n notifyError(new Error('Scene not initialized'))\n return\n }\n\n try {\n // 역순 적용 — 마지막 op 부터 되돌림. 단일 patch 안에서도 순서 의미 있음\n // (예: add 후 modify 한 시퀀스를 되돌리려면 modify(원본) 후 remove)\n const reversed = [...inverses].reverse()\n const reverseFakePatch: SceneEditPatch = {\n ops: reversed,\n summary: 'revert',\n confidence: 1\n }\n // hasReplace 면 wholesale, 그렇지 않으면 in-place — 일반 onSceneEditPatch 와 동일\n const hasReplace = reversed.some(op => op.op === 'replace')\n if (hasReplace) {\n this.applyPatchWholesale(reverseFakePatch)\n } else {\n // in-place 직접 적용 — 새 inverse 누적은 안 함 (revert 의 revert 는 redo, 별개 기능)\n this.applyInverseOpsInPlace(scene, reversed)\n }\n\n this.patchInverses.delete(patchId)\n await this.recordRevertOnServer(patchId)\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n /**\n * inverse op 시퀀스를 things-scene 위에 in-place 적용 (snapshot/undo 보존).\n * dispatcher 재사용 — inverse 누적은 무시 (revert 의 revert 는 redo, 별개 기능).\n */\n private applyInverseOpsInPlace(scene: any, ops: SceneEditOp[]): void {\n const normalize = (c: any) => this.normalizeComponent(c)\n for (const op of ops) {\n dispatchSceneEditOp(scene, op, { normalize })\n }\n }\n\n /** 서버 PatchEntry.reverted=true 영속 — fail 해도 UI 는 이미 되돌렸으니 warn 만. */\n private async recordRevertOnServer(patchId: string): Promise<void> {\n try {\n await client.mutate({ mutation: REVERT_PATCH_MUTATION, variables: { patchId } })\n } catch (e: any) {\n console.warn('[board-modeller] revertPatch server persist failed:', e?.message ?? e)\n }\n }\n\n /**\n * AI 가 ephemeral scene action (selection / view / mode) 을 실행하라고 요청.\n *\n * scene-edit-patch 와 별개 채널 — 모델 변경 X, undo 영향 X, dirty flag 무관.\n * things-scene API 직접 호출. 잘못된 action / 누락된 컴포넌트는 console.warn 만.\n */\n private onSceneActionExecute = (e: CustomEvent) => {\n const { actions } = e.detail || {}\n if (!Array.isArray(actions) || actions.length === 0) return\n const scene = this.scene as any\n if (!scene) return\n\n let modeChanged = false\n for (const action of actions) {\n try {\n dispatchSceneAction(scene, action)\n if (action?.action === 'setSceneMode') modeChanged = true\n } catch (ex: any) {\n console.warn('[board-modeller] action execute failed:', action, ex?.message ?? ex)\n }\n }\n // setSceneMode 가 있었으면 page 의 reactive mode 도 동기 (Lit re-render 트리거)\n if (modeChanged) this.mode = scene.mode\n }\n\n /**\n * AI 가 만든 컴포넌트를 things-scene 이 기대하는 완전한 형태로 normalize.\n * BoardModeller 에 등록된 template.model (default 값) 위에 AI 응답을 덮어쓴다.\n * 이 단계 없이 things-scene 에 넣으면 필수 속성 누락 시 render 에서 crash 가능\n * (예: gauge-circle 의 value 가 undefined → toString() TypeError).\n */\n private normalizeComponent(c: any): any {\n if (!c || typeof c !== 'object' || typeof c.type !== 'string') return c\n const template = this.findTemplateByType(c.type)\n if (!template || !template.model) return c\n return mergeDefaultsDeep(template.model, c)\n }\n\n private findTemplateByType(type: string): any {\n for (const group of BoardModeller.groups || []) {\n for (const t of group.templates || []) {\n if (t && t.type === type) return t\n }\n }\n return undefined\n }\n\n async updated(changes) {\n if (changes.has('boardId')) {\n try {\n if (await hasPrivilege({ privilege: 'mutation', category: 'board' })) {\n this.refresh()\n // C2: 보드 변경 시 그 보드의 실시간 patch 구독 (이전 보드 구독은 해제).\n if (this.boardId) this._subscribeBoardPatches(this.boardId)\n else this._unsubscribeBoardPatches()\n } else {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n }\n } catch {\n this.boardId = null\n this.model = null\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n }\n }\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n this._unsubscribeBoardPatches()\n }\n\n pageUpdated(changes, lifecycle) {\n if (this.active) {\n getModellerToolbarMode().then(mode => (this.toolbarMode = mode))\n }\n\n if (this.active) {\n this.boardId = lifecycle.resourceId\n } else {\n this.boardId = null\n this.board = null\n this.model = null\n this.preparing = false\n this.modeller?.close()\n this._unsubscribeBoardPatches()\n this.updateContext()\n }\n }\n\n render() {\n const oops = !this.preparing && !this.model && this.oopsNote\n\n return html`\n <div class=\"modeller-area\">\n ${oops\n ? html`<ox-oops-note icon=${oops.icon} title=${oops.title} description=${oops.description}></ox-oops-note>`\n : html`\n <ox-board-modeller\n .boardName=${this.boardName || ''}\n .contextualToolbar=${this.toolbarMode !== 'toolbar'}\n .contextualToolbarPlacement=${this.toolbarMode === 'docked' ? 'docked' : 'floating'}\n .mode=${this.mode}\n .loadTracker=${this._loadTracker}\n @mode-changed=${e => {\n this.mode = e.detail.value\n }}\n .model=${this.model}\n @model-changed=${e => {\n this.model = e.detail.value\n }}\n .scene=${this.scene}\n @scene-changed=${e => {\n this.scene = e.detail.value\n }}\n .selected=${this.selected}\n @selected-changed=${e => {\n this.selected = e.detail.value\n }}\n .provider=${provider}\n @save-model=${e => this.saveBoard()}\n .componentGroupList=${this.componentGroupList}\n .fonts=${this._fontCtrl.fonts}\n .hideProperty=${this.hideProperty}\n >\n </ox-board-modeller>\n `}\n ${this.scene && boardPlacementProvider()\n ? html`<board-placement-tray .boardId=${this.boardId} .scene=${this.scene}></board-placement-tray>`\n : nothing}\n ${this.boardId\n ? html`\n <button\n class=\"ai-toggle ${this.aiPanelOpen ? 'open' : ''}\"\n title=\"${i18next.t('text.ai_assistant') || 'AI Assistant'}\"\n @click=${this.toggleAIPanel}>\n <md-icon>${this.aiPanelOpen ? 'close' : 'auto_awesome'}</md-icon>AI\n </button>\n `\n : nothing}\n </div>\n ${this.aiPanelOpen\n ? html`\n <div class=\"ai-panel\">\n <ox-assistant-chat\n chat-endpoint=\"boardAIChat\"\n subject=\"board\"\n .mode=${this.aiMode}\n @assistant-mode-change=${this.onAssistantModeChange}\n .sessionId=${this.chatSessionId}\n .sessions=${this.chatSessions}\n .currentBoard=${this.model}\n .boardProvider=${() => this.getLiveBoard()}\n .searchProvider=${this.searchSceneForMention}\n .userProvider=${this.fetchDomainUsersForMention}\n .knownTypes=${this.knownTypes}\n .categories=${this.knownCategories}\n .componentSchemas=${this.componentSchemas}\n .selectedRefids=${this.extractSelectedRefids()}\n @session-switch=${this.onChatSessionSwitch}\n @session-create=${this.onChatSessionCreate}\n @scene-edit-patch=${this.onSceneEditPatch}\n @board-edit-revert=${this.onBoardEditRevert}\n @scene-action-execute=${this.onSceneActionExecute}>\n </ox-assistant-chat>\n </div>\n `\n : nothing}\n `\n }\n\n async updateBoard() {\n try {\n this.preparing = true\n\n const { id, name, description, groupId } = this.board\n const model = JSON.stringify(this.scene.model)\n\n await client.mutate({\n mutation: gql`\n mutation UpdateBoard($id: String!, $patch: BoardPatch!) {\n updateBoard(id: $id, patch: $patch) {\n id\n }\n }\n `,\n variables: {\n id,\n patch: { name, description, model, groupId }\n },\n context: gqlContext()\n })\n\n notify('info', i18next.t('text.saved'))\n } catch (ex) {\n notifyError(ex)\n } finally {\n this.preparing = false\n }\n\n this.updateContext()\n }\n\n async saveBoard() {\n await this.updateBoard()\n this.modeller?.preserve()\n // C3: 저장 후(이산적·사용자 의도) 직접편집을 ops 로 캡처해 방송. best-effort —\n // 실패해도 저장 자체엔 영향 없음(이미 완료). (라이브 per-edit 동기화는 C3c 후보.)\n this._captureDirectEdits()\n }\n\n /**\n * C3: 마지막 동기 모델 → 현재 모델 diff 를 recordDirectPatch 로 기록(=같은 board 구독자 방송).\n * 반환된 patchId 를 게이트에 claim → 자기발신 echo skip. baseline 갱신.\n * sessionId 없으면(AI 세션 미연결) skip — 협업 비활성, 편집은 정상.\n */\n private async _captureDirectEdits() {\n try {\n if (!this.chatSessionId) return\n const current = this.getLiveBoard()\n if (!current) return\n if (!this._syncedModel) {\n this._syncedModel = current // 첫 저장 = baseline 확립 (이전 상태 미상이라 방송 안 함)\n return\n }\n const ops = diffBoardModel(this._syncedModel, current)\n this._syncedModel = current\n if (ops.length === 0) return\n\n const res = await client.mutate({\n mutation: gql`\n mutation RecordDirectPatch($sessionId: String!, $ops: JSON!, $summary: String) {\n recordDirectPatch(sessionId: $sessionId, ops: $ops, summary: $summary) {\n id\n }\n }\n `,\n variables: { sessionId: this.chatSessionId, ops, summary: `직접 편집 ${ops.length}건` },\n context: gqlContext()\n })\n const id = res?.data?.recordDirectPatch?.id\n if (id) this._patchGate.tryClaim(id) // 내 직접편집의 broadcast echo 차단\n } catch (ex) {\n notifyError(ex)\n }\n }\n\n async canDeactivate(): Promise<boolean> {\n if (this.modeller?.hasUnpreservedChanges()) {\n return await OxPrompt.open({\n title: i18next.t('text.are_you_sure'),\n text: i18next.t('prompt.sure to navigate away?'),\n confirmButton: { text: i18next.t('button.confirm') },\n cancelButton: { text: i18next.t('button.cancel') }\n })\n }\n\n return true\n }\n}\n"]}
|
|
@@ -113,7 +113,7 @@ let BoardTemplateListPage = class BoardTemplateListPage extends BoardTemplateLis
|
|
|
113
113
|
name: 'info',
|
|
114
114
|
icon: 'edit',
|
|
115
115
|
quiet: true,
|
|
116
|
-
title: i18next.t('
|
|
116
|
+
title: i18next.t('button.edit'),
|
|
117
117
|
handlers: {
|
|
118
118
|
click: (_columns, _data, _column, record) => this.onShowInfo(record)
|
|
119
119
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-template-list-page.js","sourceRoot":"","sources":["../../../client/pages/board-template/board-template-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@operato/board/ox-board-template-viewer.js'\nimport '@material/web/icon/icon.js'\nimport '../../board-list/board-thumb.js'\nimport '../../viewparts/board-template-info.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\n\nimport { BoardCardStyles } from '../../styles/board-card-styles.js'\nimport { timeAgo } from '../../utils/board-meta.js'\n\nconst BoardTemplateListPageBase = localize(i18next)(PageView) as typeof PageView\n\n/**\n * The template catalog - the same card as board-list-page.ts and play-list-page.ts (shared through\n * styles/board-card-styles.ts), because a template *is* a board, only one you start from rather\n * than one you run. Clicking a card previews it; the one gutter action opens the info overlay.\n *\n * A template is made from inside the modeller (\"save as template\"), never from here, so there is\n * no create FAB on this page.\n */\n@customElement('board-template-list-page')\nexport class BoardTemplateListPage extends BoardTemplateListPageBase {\n static styles = [\n /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */\n BoardCardStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @state() visibility: string = ''\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n /* A plain name, no icon - the rail already carries the icon for this screen. */\n title: i18next.t('title.board-template list', { defaultValue: 'Board Template List' }),\n search: {\n placeholder: i18next.t('text.search templates by name', { defaultValue: 'Search templates by name' }),\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n board_topmenu: true\n }\n }\n\n render() {\n return html`\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized() {\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n /* name, then a quieter \"public · who · when\" line - the same two-line rhythm as board-list. */\n fields: ['name', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: {\n editable: false,\n align: 'center',\n renderEmpty: true,\n /* board-thumb.ts draws the picture; badge=\"\" because a template has no draft state.\n * The description rides along as the picture's tooltip - a template's one-line\n * purpose is worth having on hover without spending a third line on every card. */\n renderer: (_value, _column, record) =>\n html`<board-thumb .board=${record} badge=\"\" title=${record.description || ''}></board-thumb>`\n }\n },\n {\n type: 'string',\n name: 'name',\n record: { editable: false },\n filter: 'search',\n sortable: true\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false }\n },\n {\n type: 'string',\n name: 'description',\n hidden: true,\n record: { editable: false },\n filter: 'search'\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'info',\n icon: 'edit',\n quiet: true,\n title: i18next.t('label.edit', { defaultValue: 'Edit' }),\n handlers: {\n click: (_columns, _data, _column, record) => this.onShowInfo(record)\n }\n },\n /* Visibility is a chip facet, the way board-list's type/state are. Nothing pressed means\n * all three - the server only narrows when the filter carries a value. */\n {\n type: 'select-buttons',\n name: 'visibility',\n header: i18next.t('field.visibility', { defaultValue: 'Visibility' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: [],\n label: '',\n options: [\n { display: this.visibilityLabel('private'), value: 'private' },\n { display: this.visibilityLabel('domain'), value: 'domain' },\n { display: this.visibilityLabel('public'), value: 'public' }\n ]\n }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n handlers: {\n click: (_columns, _data, _column, record) => this.onPreview(record)\n }\n },\n sorters: [{ name: 'name' }]\n }\n }\n\n async pageUpdated() {\n if (this.active) {\n this.grist?.fetch()\n }\n }\n\n async fetchHandler({ page = 1, limit = 24, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n model\n thumbnail\n visibility\n tags\n mine\n creator {\n id\n username\n name\n }\n createdAt\n updatedAt\n }\n total\n }\n }\n `,\n variables: {\n /* An empty chip strip would otherwise be sent as `in []` and match nothing. */\n filters: filters.filter(f => !(Array.isArray(f.value) && f.value.length === 0)),\n pagination: { page, limit },\n sortings\n }\n })\n\n const records = (response.data.responses.items || []).map(template => ({\n ...template,\n meta: this.templateMeta(template)\n }))\n\n return {\n total: response.data.responses.total || 0,\n records\n }\n }\n\n /** \"public · Hearty · 3 days ago\" - who can see it, who made it, how fresh. */\n private templateMeta(template: any): string {\n return [this.visibilityLabel(template.visibility), template.creator?.name, timeAgo(template.updatedAt || template.createdAt)]\n .filter(part => !!part)\n .join(' · ')\n }\n\n private visibilityLabel(visibility: string): string {\n return i18next.t(`label.visibility-${visibility}`, { defaultValue: visibility })\n }\n\n private onPreview(record: any) {\n const boardTemplate = {\n ...record,\n model: JSON.parse(record.model)\n }\n\n openPopup(html` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, {\n backdrop: true,\n size: 'large',\n title: record.name\n })\n }\n\n private onShowInfo(template: any) {\n openPopup(\n html`\n <board-template-info\n .template=${{ ...template }}\n @updated=${() => this.grist.fetch()}\n @deleted=${() => this.grist.fetch()}\n ></board-template-info>\n `,\n { backdrop: true, size: 'small', closable: true, title: template.name }\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"board-template-list-page.js","sourceRoot":"","sources":["../../../client/pages/board-template/board-template-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@operato/board/ox-board-template-viewer.js'\nimport '@material/web/icon/icon.js'\nimport '../../board-list/board-thumb.js'\nimport '../../viewparts/board-template-info.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\n\nimport { BoardCardStyles } from '../../styles/board-card-styles.js'\nimport { timeAgo } from '../../utils/board-meta.js'\n\nconst BoardTemplateListPageBase = localize(i18next)(PageView) as typeof PageView\n\n/**\n * The template catalog - the same card as board-list-page.ts and play-list-page.ts (shared through\n * styles/board-card-styles.ts), because a template *is* a board, only one you start from rather\n * than one you run. Clicking a card previews it; the one gutter action opens the info overlay.\n *\n * A template is made from inside the modeller (\"save as template\"), never from here, so there is\n * no create FAB on this page.\n */\n@customElement('board-template-list-page')\nexport class BoardTemplateListPage extends BoardTemplateListPageBase {\n static styles = [\n /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */\n BoardCardStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @state() visibility: string = ''\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n /* A plain name, no icon - the rail already carries the icon for this screen. */\n title: i18next.t('title.board-template list', { defaultValue: 'Board Template List' }),\n search: {\n placeholder: i18next.t('text.search templates by name', { defaultValue: 'Search templates by name' }),\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n board_topmenu: true\n }\n }\n\n render() {\n return html`\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized() {\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n /* name, then a quieter \"public · who · when\" line - the same two-line rhythm as board-list. */\n fields: ['name', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: {\n editable: false,\n align: 'center',\n renderEmpty: true,\n /* board-thumb.ts draws the picture; badge=\"\" because a template has no draft state.\n * The description rides along as the picture's tooltip - a template's one-line\n * purpose is worth having on hover without spending a third line on every card. */\n renderer: (_value, _column, record) =>\n html`<board-thumb .board=${record} badge=\"\" title=${record.description || ''}></board-thumb>`\n }\n },\n {\n type: 'string',\n name: 'name',\n record: { editable: false },\n filter: 'search',\n sortable: true\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false }\n },\n {\n type: 'string',\n name: 'description',\n hidden: true,\n record: { editable: false },\n filter: 'search'\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'info',\n icon: 'edit',\n quiet: true,\n title: i18next.t('button.edit'),\n handlers: {\n click: (_columns, _data, _column, record) => this.onShowInfo(record)\n }\n },\n /* Visibility is a chip facet, the way board-list's type/state are. Nothing pressed means\n * all three - the server only narrows when the filter carries a value. */\n {\n type: 'select-buttons',\n name: 'visibility',\n header: i18next.t('field.visibility', { defaultValue: 'Visibility' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: [],\n label: '',\n options: [\n { display: this.visibilityLabel('private'), value: 'private' },\n { display: this.visibilityLabel('domain'), value: 'domain' },\n { display: this.visibilityLabel('public'), value: 'public' }\n ]\n }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n handlers: {\n click: (_columns, _data, _column, record) => this.onPreview(record)\n }\n },\n sorters: [{ name: 'name' }]\n }\n }\n\n async pageUpdated() {\n if (this.active) {\n this.grist?.fetch()\n }\n }\n\n async fetchHandler({ page = 1, limit = 24, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n model\n thumbnail\n visibility\n tags\n mine\n creator {\n id\n username\n name\n }\n createdAt\n updatedAt\n }\n total\n }\n }\n `,\n variables: {\n /* An empty chip strip would otherwise be sent as `in []` and match nothing. */\n filters: filters.filter(f => !(Array.isArray(f.value) && f.value.length === 0)),\n pagination: { page, limit },\n sortings\n }\n })\n\n const records = (response.data.responses.items || []).map(template => ({\n ...template,\n meta: this.templateMeta(template)\n }))\n\n return {\n total: response.data.responses.total || 0,\n records\n }\n }\n\n /** \"public · Hearty · 3 days ago\" - who can see it, who made it, how fresh. */\n private templateMeta(template: any): string {\n return [this.visibilityLabel(template.visibility), template.creator?.name, timeAgo(template.updatedAt || template.createdAt)]\n .filter(part => !!part)\n .join(' · ')\n }\n\n private visibilityLabel(visibility: string): string {\n return i18next.t(`label.visibility-${visibility}`, { defaultValue: visibility })\n }\n\n private onPreview(record: any) {\n const boardTemplate = {\n ...record,\n model: JSON.parse(record.model)\n }\n\n openPopup(html` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, {\n backdrop: true,\n size: 'large',\n title: record.name\n })\n }\n\n private onShowInfo(template: any) {\n openPopup(\n html`\n <board-template-info\n .template=${{ ...template }}\n @updated=${() => this.grist.fetch()}\n @deleted=${() => this.grist.fetch()}\n ></board-template-info>\n `,\n { backdrop: true, size: 'small', closable: true, title: template.name }\n )\n }\n}\n"]}
|
|
@@ -133,7 +133,7 @@ let PlayListPage = class PlayListPage extends localize(i18next)(PageView) {
|
|
|
133
133
|
/* Edit first, the star last - same order as board-list-page.ts. */
|
|
134
134
|
icon: 'edit',
|
|
135
135
|
quiet: true,
|
|
136
|
-
title: i18next.t('
|
|
136
|
+
title: i18next.t('button.edit'),
|
|
137
137
|
handlers: {
|
|
138
138
|
click: (_columns, _data, _column, record) => this.onInfoBoard(record)
|
|
139
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"play-list-page.js","sourceRoot":"","sources":["../../client/pages/play-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@material/web/icon/icon.js'\nimport '@material/web/button/text-button.js'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport '../board-list/board-thumb.js'\nimport '../viewparts/play-group-info.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client'\nimport { openPopup } from '@operato/layout'\nimport { navigate, PageView, store } from '@operato/shell'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { pulltorefresh } from '@operato/pull-to-refresh'\nimport { notify } from '../utils/notify-helper.js'\nimport { boardMeta } from '../utils/board-meta.js'\nimport { BoardCardStyles } from '../styles/board-card-styles.js'\n\nimport {\n createPlayGroup,\n deletePlayGroup,\n fetchPlayGroup,\n fetchPlayGroupList,\n updateBoard,\n updatePlayGroup\n} from '../graphql'\n\n/*\n * Same board-card look as board-list-page (ox-grist CARD mode, drag-reorder — see\n * `data-grist`'s `rows.reorderable`, ADR: shared component over a board-only fork).\n * A play group's board set is small and its own array *is* the order, so there is no pagination or\n * server-side sort here - `fetchHandler` always hands back the whole thing.\n */\n@customElement('play-list-page')\nexport class PlayListPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */\n BoardCardStyles,\n css`\n /*\n The play groups are chips, not a tab strip - the same select-buttons the list's own\n facets use, so this page and board-list read as one product. One is always pressed:\n a play list is *of* a group, there is no \"all groups\" view here.\n */\n ox-input-select-buttons {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) groupId?: string\n @property({ type: Array }) groups: any[] = []\n @property({ type: Array }) boards: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) gristConfig: any\n\n @query('ox-grist') private grist!: DataGrist\n\n private page?: string\n\n get context() {\n /* The pressed chip already names the group; the title names the screen, as board-list's does. */\n return {\n title: i18next.t('title.play list', { defaultValue: 'Play List' }),\n board_topmenu: true\n }\n }\n\n render() {\n const current = (this.groups || []).find(group => group.id === this.groupId)\n\n return html`\n <ox-grist\n class=\"page-fill\"\n mode=\"CARD\"\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n @reorder=${e => this.onReorder(e.detail)}\n >\n <div slot=\"headroom\">\n <ox-input-select-buttons\n .value=${this.groupId || ''}\n .options=${(this.groups || []).map(group => ({ display: group.name, value: group.id }))}\n @change=${(e: CustomEvent) => {\n const id = e.detail\n /* The URL stays the source of truth - same round trip a deep link takes. */\n if (id && id !== this.groupId) navigate(`${this.page || 'play-list'}/${id}`)\n }}\n ></ox-input-select-buttons>\n ${current\n ? html`\n <md-text-button @click=${() => this.onInfoPlayGroup(current)}>\n <md-icon slot=\"icon\">edit</md-icon>\n ${i18next.t('text.edit play-group', { defaultValue: 'Edit' })}\n </md-text-button>\n `\n : ''}\n <md-text-button @click=${() => this.onInfoPlayGroup(undefined)}>\n <md-icon slot=\"icon\">playlist_add</md-icon>\n ${i18next.t('text.new play-group', { defaultValue: 'New Play Group' })}\n </md-text-button>\n </div>\n </ox-grist>\n\n ${this.groupId\n ? html`\n <button fab title=${i18next.t('label.play', { defaultValue: 'Play' })} @click=${() => navigate(`board-player/${this.groupId}`)}>\n <md-icon>play_arrow</md-icon>${i18next.t('label.play', { defaultValue: 'Play' })}\n </button>\n `\n : ''}\n `\n }\n\n async pageInitialized() {\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n fields: ['name', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: {\n editable: false,\n align: 'center',\n renderEmpty: true,\n /* board-thumb.ts owns the picture and draft badge; info/favorite are gutter columns\n * below - see board-list-page.ts's identical setup and board-thumb.ts's own comment. */\n renderer: (value, column, record) => html`<board-thumb .board=${record}></board-thumb>`\n }\n },\n { type: 'string', name: 'name', record: { editable: false } },\n { type: 'string', name: 'meta', record: { editable: false } },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'edit',\n /* Edit first, the star last - same order as board-list-page.ts. */\n icon: 'edit',\n quiet: true,\n title: i18next.t('label.edit', { defaultValue: 'Edit' }),\n handlers: {\n click: (_columns, _data, _column, record) => this.onInfoBoard(record)\n }\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'favorite',\n icon: (record?: any) => (record?.favorited ? 'star' : 'star_border'),\n quiet: (record?: any) => !record?.favorited,\n title: (record?: any) =>\n i18next.t(record?.favorited ? 'label.unfavorite' : 'label.favorite', {\n defaultValue: record?.favorited ? 'Remove from favorites' : 'Add to favorites'\n }),\n handlers: {\n click: (_columns, _data, _column, record) => this.toggleFavorite(record)\n }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n reorderable: true,\n handlers: {\n click: (_columns, _data, _column, record) => navigate(`board-viewer/${record.id}`)\n }\n },\n sorters: []\n }\n\n this.refresh()\n }\n\n async fetchHandler(_option: FetchOption) {\n const favorites = this.favorites || []\n const records = (this.boards || []).map(board => ({\n ...board,\n favorited: favorites.includes(board.id),\n meta: boardMeta(board)\n }))\n\n return { total: records.length, records }\n }\n\n async refresh() {\n this.groups = (await fetchPlayGroupList()).playGroups.items\n\n this.groups && (await this.refreshBoards())\n }\n\n async refreshBoards() {\n if (!this.groups) {\n await this.refresh()\n return\n }\n\n if (!this.groupId) {\n const groupId = this.groups && this.groups[0] && this.groups[0].id\n\n /*\n * Build the address from the page name, not by appending to window.location: re-entering\n * this page from the rail while a play-list/<id> URL is still current appended a second\n * id (play-list/<id>/<id>), the route stopped matching and groupId came back empty - no chip\n * pressed, no Edit button (seen live 2026-09-23).\n */\n if (groupId) {\n navigate(`${this.page || 'play-list'}/${groupId}`, true)\n }\n return\n }\n\n if (this.groupId) {\n const playGroup = (await fetchPlayGroup(this.groupId)).playGroup\n this.boards = playGroup ? playGroup.boards : []\n } else {\n this.boards = []\n }\n\n this.updateContext()\n this.grist?.fetch()\n\n if (this.grist) {\n this.grist.style.transition = ''\n this.grist.style.transform = `translate3d(0, 0, 0)`\n }\n }\n\n async pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.page = lifecycle.page\n /*\n * On a full page load the router can deliver the bare /play-list lifecycle *after* this\n * page has already redirected itself to /play-list/<first group> - the id would be wiped\n * while the URL still shows it (no chip pressed, no Edit button; seen live 2026-09-23).\n * The address bar is the source of truth, so read the id back from it in that case.\n */\n this.groupId = lifecycle.resourceId || this.groupIdFromLocation()\n\n await this.updateComplete\n\n this.refreshBoards()\n }\n }\n\n private groupIdFromLocation(): string {\n const segments = location.pathname.split('/').filter(Boolean)\n const at = segments.lastIndexOf(this.page || 'play-list')\n\n return at >= 0 ? segments[at + 1] || '' : ''\n }\n\n private _unsubscribe?: () => void\n\n connectedCallback() {\n super.connectedCallback()\n\n this._applyState()\n\n this._unsubscribe = store.subscribe(() => this._applyState())\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this._unsubscribe?.()\n }\n\n private _applyState() {\n const __state__ = store.getState() as any\n const favorites = __state__.favorite.favorites\n\n /*\n * `store.subscribe` fires on every dispatch anywhere in the app, not just favorite changes - an\n * unconditional fetch() here risks a loop if fetch() completing itself dispatches through this\n * same store (board-list-page.ts hit exactly this).\n */\n const changed = JSON.stringify(favorites) !== JSON.stringify(this.favorites)\n this.favorites = favorites\n\n if (changed) {\n this.grist?.fetch()\n }\n }\n\n firstUpdated() {\n /* Groups are chips now, one tap each - the swipe-between-routes gesture the tab strip needed\n * no longer has a job here. */\n pulltorefresh({\n container: this.shadowRoot,\n scrollable: this.grist,\n refresh: () => {\n return this.refresh()\n }\n })\n }\n\n async onInfoBoard(board) {\n openPopup(\n html`\n <board-info\n .board=${board}\n .groupId=${this.groupId}\n @update-board=${e => this.onUpdateBoard(e.detail)}\n @delete-board=${e => this.onDeleteBoard(e.detail)}\n @join-playgroup=${e => this.onJoinPlayGroup(e.detail)}\n @leave-playgroup=${e => this.onLeavePlayGroup(e.detail)}\n ></board-info>\n `,\n { backdrop: true, size: 'medium', closable: true, title: board.name }\n )\n }\n\n async onInfoPlayGroup(group) {\n openPopup(\n html`\n <play-group-info\n .playGroup=${group}\n @update-play-group=${e => this.onUpdatePlayGroup(e.detail)}\n @delete-play-group=${e => this.onDeletePlayGroup(e.detail)}\n @create-play-group=${e => this.onCreatePlayGroup(e.detail)}\n ></play-group-info>\n `,\n {\n backdrop: true,\n size: 'small',\n closable: true,\n title: group?.name || i18next.t('text.new play-group', { defaultValue: 'New Play Group' })\n }\n )\n }\n\n async onCreatePlayGroup(playGroup) {\n try {\n await createPlayGroup(playGroup)\n notify('info', i18next.t('text.play-group created', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdatePlayGroup(playGroup) {\n try {\n await updatePlayGroup(playGroup)\n notify('info', i18next.t('text.play-group updated', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onDeletePlayGroup(playGroup) {\n try {\n await deletePlayGroup(playGroup.id)\n notify('info', i18next.t('text.play-group deleted', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdateBoard(board) {\n try {\n await updateBoard(board)\n notify('info', i18next.t('text.board updated', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onDeleteBoard(board) {\n const playGroup = this.groups && this.groups.find(group => group.id === this.groupId)\n await this.onLeavePlayGroup({ board, playGroup })\n }\n\n async onJoinPlayGroup({ board, playGroup }) {\n try {\n await client.mutate({\n mutation: gql`\n mutation JoinPlayGroup($id: String!, $boardIds: [String!]!) {\n joinPlayGroup(id: $id, boardIds: $boardIds) {\n id\n }\n }\n `,\n variables: {\n id: playGroup.id,\n boardIds: [board.id]\n }\n })\n\n notify('info', i18next.t('text.joined into play-group', { board: board.name, playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onLeavePlayGroup({ board, playGroup }) {\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $boardIds: [String!]!) {\n leavePlayGroup(id: $id, boardIds: $boardIds) {\n id\n }\n }\n `,\n variables: {\n id: playGroup.id,\n boardIds: [board.id]\n }\n })\n\n notify('info', i18next.t('text.leaved from play-group', { board: board.name, playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onReorder({ ids, movedId }: { ids: string[]; movedId: string }) {\n const groupId = this.groupId\n\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $boardIds: [String!]!) {\n reorderPlayGroup(id: $id, boardIds: $boardIds) {\n id\n name\n }\n }\n `,\n variables: {\n id: groupId,\n boardIds: ids\n }\n })\n\n const playGroup = response.data.reorderPlayGroup\n\n notify('info', i18next.t('text.reorder play-group', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n /* 실패 시에만 서버 데이터로 복원 */\n this.refresh()\n }\n }\n\n async toggleFavorite(board) {\n const wasFavorite = (this.favorites || []).includes(board.id)\n\n /*\n * The star answers the click at once; the server round trip only confirms it. Before, nothing\n * moved until the mutation, the favorites re-query, the store dispatch and a full refetch had\n * all come back - a click with no reaction reads as a click that did not land.\n *\n * `favorites` is set locally too, so the store update that follows carries the same list and\n * `_applyState` does not trigger the refetch that would repaint every card.\n */\n this.favorites = wasFavorite\n ? (this.favorites || []).filter(id => id !== board.id)\n : [...(this.favorites || []), board.id]\n this.patchRecord(board.id, { favorited: !wasFavorite })\n\n try {\n if (wasFavorite) {\n await this.removeFavorite(board.id)\n } else {\n await this.addFavorite(board.id)\n }\n } catch (ex) {\n /* Put it back the way it was and say why. */\n this.favorites = wasFavorite\n ? [...(this.favorites || []), board.id]\n : (this.favorites || []).filter(id => id !== board.id)\n this.patchRecord(board.id, { favorited: wasFavorite })\n notify('error', (ex as any)?.message || String(ex))\n }\n }\n\n /** Replaces one record in the grist in place, so only that card re-renders. */\n private patchRecord(id: string, patch: Record<string, unknown>) {\n const grist = this.grist\n const data = grist?.data\n\n if (!data?.records) {\n return\n }\n\n grist.data = {\n ...data,\n records: data.records.map(record => (record.id === id ? { ...record, ...patch } : record))\n }\n }\n\n async removeFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n deleteFavorite(routing: \"${boardId}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${boardId}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async refreshFavorites() {\n const response = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: response.data.myFavorites.map(favorite => favorite.routing)\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"play-list-page.js","sourceRoot":"","sources":["../../client/pages/play-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@material/web/icon/icon.js'\nimport '@material/web/button/text-button.js'\nimport '@operato/input/ox-input-select-buttons.js'\n\nimport '../board-list/board-thumb.js'\nimport '../viewparts/play-group-info.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client'\nimport { openPopup } from '@operato/layout'\nimport { navigate, PageView, store } from '@operato/shell'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { pulltorefresh } from '@operato/pull-to-refresh'\nimport { notify } from '../utils/notify-helper.js'\nimport { boardMeta } from '../utils/board-meta.js'\nimport { BoardCardStyles } from '../styles/board-card-styles.js'\n\nimport {\n createPlayGroup,\n deletePlayGroup,\n fetchPlayGroup,\n fetchPlayGroupList,\n updateBoard,\n updatePlayGroup\n} from '../graphql'\n\n/*\n * Same board-card look as board-list-page (ox-grist CARD mode, drag-reorder — see\n * `data-grist`'s `rows.reorderable`, ADR: shared component over a board-only fork).\n * A play group's board set is small and its own array *is* the order, so there is no pagination or\n * server-side sort here - `fetchHandler` always hands back the whole thing.\n */\n@customElement('play-list-page')\nexport class PlayListPage extends localize(i18next)(PageView) {\n static styles = [\n /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */\n BoardCardStyles,\n css`\n /*\n The play groups are chips, not a tab strip - the same select-buttons the list's own\n facets use, so this page and board-list read as one product. One is always pressed:\n a play list is *of* a group, there is no \"all groups\" view here.\n */\n ox-input-select-buttons {\n flex: 1;\n }\n `\n ]\n\n @property({ type: String }) groupId?: string\n @property({ type: Array }) groups: any[] = []\n @property({ type: Array }) boards: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) gristConfig: any\n\n @query('ox-grist') private grist!: DataGrist\n\n private page?: string\n\n get context() {\n /* The pressed chip already names the group; the title names the screen, as board-list's does. */\n return {\n title: i18next.t('title.play list', { defaultValue: 'Play List' }),\n board_topmenu: true\n }\n }\n\n render() {\n const current = (this.groups || []).find(group => group.id === this.groupId)\n\n return html`\n <ox-grist\n class=\"page-fill\"\n mode=\"CARD\"\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n @reorder=${e => this.onReorder(e.detail)}\n >\n <div slot=\"headroom\">\n <ox-input-select-buttons\n .value=${this.groupId || ''}\n .options=${(this.groups || []).map(group => ({ display: group.name, value: group.id }))}\n @change=${(e: CustomEvent) => {\n const id = e.detail\n /* The URL stays the source of truth - same round trip a deep link takes. */\n if (id && id !== this.groupId) navigate(`${this.page || 'play-list'}/${id}`)\n }}\n ></ox-input-select-buttons>\n ${current\n ? html`\n <md-text-button @click=${() => this.onInfoPlayGroup(current)}>\n <md-icon slot=\"icon\">edit</md-icon>\n ${i18next.t('text.edit play-group', { defaultValue: 'Edit' })}\n </md-text-button>\n `\n : ''}\n <md-text-button @click=${() => this.onInfoPlayGroup(undefined)}>\n <md-icon slot=\"icon\">playlist_add</md-icon>\n ${i18next.t('text.new play-group', { defaultValue: 'New Play Group' })}\n </md-text-button>\n </div>\n </ox-grist>\n\n ${this.groupId\n ? html`\n <button fab title=${i18next.t('label.play', { defaultValue: 'Play' })} @click=${() => navigate(`board-player/${this.groupId}`)}>\n <md-icon>play_arrow</md-icon>${i18next.t('label.play', { defaultValue: 'Play' })}\n </button>\n `\n : ''}\n `\n }\n\n async pageInitialized() {\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n fields: ['name', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: {\n editable: false,\n align: 'center',\n renderEmpty: true,\n /* board-thumb.ts owns the picture and draft badge; info/favorite are gutter columns\n * below - see board-list-page.ts's identical setup and board-thumb.ts's own comment. */\n renderer: (value, column, record) => html`<board-thumb .board=${record}></board-thumb>`\n }\n },\n { type: 'string', name: 'name', record: { editable: false } },\n { type: 'string', name: 'meta', record: { editable: false } },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'edit',\n /* Edit first, the star last - same order as board-list-page.ts. */\n icon: 'edit',\n quiet: true,\n title: i18next.t('button.edit'),\n handlers: {\n click: (_columns, _data, _column, record) => this.onInfoBoard(record)\n }\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'favorite',\n icon: (record?: any) => (record?.favorited ? 'star' : 'star_border'),\n quiet: (record?: any) => !record?.favorited,\n title: (record?: any) =>\n i18next.t(record?.favorited ? 'label.unfavorite' : 'label.favorite', {\n defaultValue: record?.favorited ? 'Remove from favorites' : 'Add to favorites'\n }),\n handlers: {\n click: (_columns, _data, _column, record) => this.toggleFavorite(record)\n }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n reorderable: true,\n handlers: {\n click: (_columns, _data, _column, record) => navigate(`board-viewer/${record.id}`)\n }\n },\n sorters: []\n }\n\n this.refresh()\n }\n\n async fetchHandler(_option: FetchOption) {\n const favorites = this.favorites || []\n const records = (this.boards || []).map(board => ({\n ...board,\n favorited: favorites.includes(board.id),\n meta: boardMeta(board)\n }))\n\n return { total: records.length, records }\n }\n\n async refresh() {\n this.groups = (await fetchPlayGroupList()).playGroups.items\n\n this.groups && (await this.refreshBoards())\n }\n\n async refreshBoards() {\n if (!this.groups) {\n await this.refresh()\n return\n }\n\n if (!this.groupId) {\n const groupId = this.groups && this.groups[0] && this.groups[0].id\n\n /*\n * Build the address from the page name, not by appending to window.location: re-entering\n * this page from the rail while a play-list/<id> URL is still current appended a second\n * id (play-list/<id>/<id>), the route stopped matching and groupId came back empty - no chip\n * pressed, no Edit button (seen live 2026-09-23).\n */\n if (groupId) {\n navigate(`${this.page || 'play-list'}/${groupId}`, true)\n }\n return\n }\n\n if (this.groupId) {\n const playGroup = (await fetchPlayGroup(this.groupId)).playGroup\n this.boards = playGroup ? playGroup.boards : []\n } else {\n this.boards = []\n }\n\n this.updateContext()\n this.grist?.fetch()\n\n if (this.grist) {\n this.grist.style.transition = ''\n this.grist.style.transform = `translate3d(0, 0, 0)`\n }\n }\n\n async pageUpdated(changes, lifecycle) {\n if (this.active) {\n this.page = lifecycle.page\n /*\n * On a full page load the router can deliver the bare /play-list lifecycle *after* this\n * page has already redirected itself to /play-list/<first group> - the id would be wiped\n * while the URL still shows it (no chip pressed, no Edit button; seen live 2026-09-23).\n * The address bar is the source of truth, so read the id back from it in that case.\n */\n this.groupId = lifecycle.resourceId || this.groupIdFromLocation()\n\n await this.updateComplete\n\n this.refreshBoards()\n }\n }\n\n private groupIdFromLocation(): string {\n const segments = location.pathname.split('/').filter(Boolean)\n const at = segments.lastIndexOf(this.page || 'play-list')\n\n return at >= 0 ? segments[at + 1] || '' : ''\n }\n\n private _unsubscribe?: () => void\n\n connectedCallback() {\n super.connectedCallback()\n\n this._applyState()\n\n this._unsubscribe = store.subscribe(() => this._applyState())\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n\n this._unsubscribe?.()\n }\n\n private _applyState() {\n const __state__ = store.getState() as any\n const favorites = __state__.favorite.favorites\n\n /*\n * `store.subscribe` fires on every dispatch anywhere in the app, not just favorite changes - an\n * unconditional fetch() here risks a loop if fetch() completing itself dispatches through this\n * same store (board-list-page.ts hit exactly this).\n */\n const changed = JSON.stringify(favorites) !== JSON.stringify(this.favorites)\n this.favorites = favorites\n\n if (changed) {\n this.grist?.fetch()\n }\n }\n\n firstUpdated() {\n /* Groups are chips now, one tap each - the swipe-between-routes gesture the tab strip needed\n * no longer has a job here. */\n pulltorefresh({\n container: this.shadowRoot,\n scrollable: this.grist,\n refresh: () => {\n return this.refresh()\n }\n })\n }\n\n async onInfoBoard(board) {\n openPopup(\n html`\n <board-info\n .board=${board}\n .groupId=${this.groupId}\n @update-board=${e => this.onUpdateBoard(e.detail)}\n @delete-board=${e => this.onDeleteBoard(e.detail)}\n @join-playgroup=${e => this.onJoinPlayGroup(e.detail)}\n @leave-playgroup=${e => this.onLeavePlayGroup(e.detail)}\n ></board-info>\n `,\n { backdrop: true, size: 'medium', closable: true, title: board.name }\n )\n }\n\n async onInfoPlayGroup(group) {\n openPopup(\n html`\n <play-group-info\n .playGroup=${group}\n @update-play-group=${e => this.onUpdatePlayGroup(e.detail)}\n @delete-play-group=${e => this.onDeletePlayGroup(e.detail)}\n @create-play-group=${e => this.onCreatePlayGroup(e.detail)}\n ></play-group-info>\n `,\n {\n backdrop: true,\n size: 'small',\n closable: true,\n title: group?.name || i18next.t('text.new play-group', { defaultValue: 'New Play Group' })\n }\n )\n }\n\n async onCreatePlayGroup(playGroup) {\n try {\n await createPlayGroup(playGroup)\n notify('info', i18next.t('text.play-group created', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdatePlayGroup(playGroup) {\n try {\n await updatePlayGroup(playGroup)\n notify('info', i18next.t('text.play-group updated', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onDeletePlayGroup(playGroup) {\n try {\n await deletePlayGroup(playGroup.id)\n notify('info', i18next.t('text.play-group deleted', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdateBoard(board) {\n try {\n await updateBoard(board)\n notify('info', i18next.t('text.board updated', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onDeleteBoard(board) {\n const playGroup = this.groups && this.groups.find(group => group.id === this.groupId)\n await this.onLeavePlayGroup({ board, playGroup })\n }\n\n async onJoinPlayGroup({ board, playGroup }) {\n try {\n await client.mutate({\n mutation: gql`\n mutation JoinPlayGroup($id: String!, $boardIds: [String!]!) {\n joinPlayGroup(id: $id, boardIds: $boardIds) {\n id\n }\n }\n `,\n variables: {\n id: playGroup.id,\n boardIds: [board.id]\n }\n })\n\n notify('info', i18next.t('text.joined into play-group', { board: board.name, playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onLeavePlayGroup({ board, playGroup }) {\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $boardIds: [String!]!) {\n leavePlayGroup(id: $id, boardIds: $boardIds) {\n id\n }\n }\n `,\n variables: {\n id: playGroup.id,\n boardIds: [board.id]\n }\n })\n\n notify('info', i18next.t('text.leaved from play-group', { board: board.name, playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onReorder({ ids, movedId }: { ids: string[]; movedId: string }) {\n const groupId = this.groupId\n\n try {\n const response = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $boardIds: [String!]!) {\n reorderPlayGroup(id: $id, boardIds: $boardIds) {\n id\n name\n }\n }\n `,\n variables: {\n id: groupId,\n boardIds: ids\n }\n })\n\n const playGroup = response.data.reorderPlayGroup\n\n notify('info', i18next.t('text.reorder play-group', { playGroup: playGroup.name }))\n } catch (ex) {\n notify('error', ex, ex)\n /* 실패 시에만 서버 데이터로 복원 */\n this.refresh()\n }\n }\n\n async toggleFavorite(board) {\n const wasFavorite = (this.favorites || []).includes(board.id)\n\n /*\n * The star answers the click at once; the server round trip only confirms it. Before, nothing\n * moved until the mutation, the favorites re-query, the store dispatch and a full refetch had\n * all come back - a click with no reaction reads as a click that did not land.\n *\n * `favorites` is set locally too, so the store update that follows carries the same list and\n * `_applyState` does not trigger the refetch that would repaint every card.\n */\n this.favorites = wasFavorite\n ? (this.favorites || []).filter(id => id !== board.id)\n : [...(this.favorites || []), board.id]\n this.patchRecord(board.id, { favorited: !wasFavorite })\n\n try {\n if (wasFavorite) {\n await this.removeFavorite(board.id)\n } else {\n await this.addFavorite(board.id)\n }\n } catch (ex) {\n /* Put it back the way it was and say why. */\n this.favorites = wasFavorite\n ? [...(this.favorites || []), board.id]\n : (this.favorites || []).filter(id => id !== board.id)\n this.patchRecord(board.id, { favorited: wasFavorite })\n notify('error', (ex as any)?.message || String(ex))\n }\n }\n\n /** Replaces one record in the grist in place, so only that card re-renders. */\n private patchRecord(id: string, patch: Record<string, unknown>) {\n const grist = this.grist\n const data = grist?.data\n\n if (!data?.records) {\n return\n }\n\n grist.data = {\n ...data,\n records: data.records.map(record => (record.id === id ? { ...record, ...patch } : record))\n }\n }\n\n async removeFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n deleteFavorite(routing: \"${boardId}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${boardId}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async refreshFavorites() {\n const response = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: response.data.myFavorites.map(favorite => favorite.routing)\n })\n }\n}\n"]}
|