@things-factory/board-ui 10.1.179 → 10.1.183

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.
@@ -11,9 +11,9 @@ export declare class BoardListPage extends BoardListPageBase {
11
11
  groups: any[];
12
12
  favorites: any[];
13
13
  gristConfig: any;
14
- searchText: string;
14
+ get searchText(): string;
15
15
  private creatable;
16
- private currentGroupId;
16
+ private get currentGroupId();
17
17
  private grist;
18
18
  get context(): {
19
19
  title: string;
@@ -26,37 +26,12 @@ export declare class BoardListPage extends BoardListPageBase {
26
26
  };
27
27
  render(): import("lit-html").TemplateResult<1>;
28
28
  pageInitialized(): Promise<void>;
29
- fetchHandler({ page, limit, filters }: FetchOption): Promise<{
29
+ fetchHandler({ page, limit, filters, search, sorters }: FetchOption): Promise<{
30
30
  total: any;
31
31
  records: any;
32
32
  }>;
33
33
  refresh(): Promise<void>;
34
- getBoards({ page, limit, groupId, types, states }?: {
35
- page?: number | undefined;
36
- limit?: number | undefined;
37
- groupId?: string | undefined;
38
- types?: string[] | undefined;
39
- states?: string[] | undefined;
40
- }): Promise<any>;
41
- /**
42
- * favor/mywork 같이 "search text + pagination"만 받는 간단한 리스트 조회 공용 헬퍼.
43
- * 그룹/타입 필터 등 복합 조건을 쓰는 일반 목록(getBoards)과 구분해 중복 제거.
44
- */
45
- private _fetchSimpleBoardList;
46
- getFavoriteBoards({ page, limit, types, states }?: {
47
- page?: number | undefined;
48
- limit?: number | undefined;
49
- types?: string[] | undefined;
50
- states?: string[] | undefined;
51
- }): Promise<any>;
52
- getMyBoards({ page, limit, types, states }?: {
53
- page?: number | undefined;
54
- limit?: number | undefined;
55
- types?: string[] | undefined;
56
- states?: string[] | undefined;
57
- }): Promise<any>;
58
34
  refreshBoards(): Promise<void>;
59
- pageUpdated(changes: any, lifecycle: any): Promise<void>;
60
35
  private _unsubscribe?;
61
36
  connectedCallback(): void;
62
37
  disconnectedCallback(): void;
@@ -39,11 +39,7 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
39
39
  super(...arguments);
40
40
  this.groups = [];
41
41
  this.favorites = [];
42
- this.searchText = '';
43
42
  this.creatable = false;
44
- /* Kept only to prefill board-info's "which group" context - the filter itself is the source of
45
- * truth for what fetchHandler actually asks the server for. */
46
- this.currentGroupId = '';
47
43
  }
48
44
  static { this.styles = [
49
45
  /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */
@@ -73,6 +69,12 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
73
69
  }
74
70
  `
75
71
  ]; }
72
+ get searchText() { return this.grist?.searchText || ''; }
73
+ /* Prefill board-info from the committed grid filter, never from an unapproved form change. */
74
+ get currentGroupId() {
75
+ const groups = (this.grist?.filters || []).filter(f => f.name === 'group' && f.operator === 'eq');
76
+ return groups.length === 1 && typeof groups[0].value === 'string' ? groups[0].value : '';
77
+ }
76
78
  get context() {
77
79
  return {
78
80
  /* A plain name, no icon - the rail already carries the icon for this screen, and figure's
@@ -80,19 +82,8 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
80
82
  title: i18next.t('title.board list'),
81
83
  search: {
82
84
  placeholder: i18next.t('text.search boards by name', { defaultValue: 'Search boards by name' }),
83
- handler: search => {
84
- this.searchText = search;
85
- this.grist?.fetch();
86
- // URL에 검색어 반영 → 페이지 복귀 시 유지
87
- const url = new URL(window.location.href);
88
- if (search) {
89
- url.searchParams.set('search', search);
90
- }
91
- else {
92
- url.searchParams.delete('search');
93
- }
94
- history.replaceState(null, '', url.href);
95
- },
85
+ handler: search => { if (this.grist)
86
+ this.grist.searchText = search; },
96
87
  value: this.searchText || ''
97
88
  },
98
89
  board_topmenu: true
@@ -103,6 +94,9 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
103
94
  <ox-grist
104
95
  class="page-fill"
105
96
  mode="CARD"
97
+ url-params-sensitive
98
+ search-mode="term"
99
+ @query-state-change=${() => { this.requestUpdate(); this.updateContext(); }}
106
100
  .config=${this.gristConfig}
107
101
  .fetchHandler=${this.fetchHandler.bind(this)}
108
102
  @reorder=${e => this.onReorderBoards(e.detail)}
@@ -209,10 +203,6 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
209
203
  operator: 'eq',
210
204
  value: '',
211
205
  label: i18next.t('field.group', { defaultValue: 'Group' }),
212
- onchange: (value) => {
213
- this.currentGroupId = value;
214
- return true;
215
- },
216
206
  options: () => [
217
207
  { value: '', display: i18next.t('label.all', { defaultValue: 'All' }) },
218
208
  { value: 'favor', display: i18next.t('label.favorite', { defaultValue: 'Favorite' }) },
@@ -271,11 +261,22 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
271
261
  };
272
262
  this.refresh();
273
263
  }
274
- async fetchHandler({ page = 1, limit = 24, filters = [] }) {
275
- const groupId = filters.find(f => f.name === 'group')?.value || '';
276
- const types = filters.find(f => f.name === 'type')?.value || [];
277
- const states = filters.find(f => f.name === 'state')?.value || [];
278
- const { items, total } = await this.getBoards({ page, limit, groupId, types, states });
264
+ async fetchHandler({ page = 1, limit = 24, filters = [], search = '', sorters = [] }) {
265
+ const groups = filters.filter(f => f.name === 'group' && f.operator === 'eq' && typeof f.value === 'string');
266
+ const group = groups.length === 1 ? groups[0] : undefined;
267
+ const special = group?.value === 'favor' || group?.value === 'mywork';
268
+ const query = {
269
+ filters: filters.filter(f => !special || f !== group).map(f => f.name === 'group' ? { ...f, name: 'groupId' } : f),
270
+ search,
271
+ pagination: { page, limit },
272
+ sortings: sorters.length ? sorters : [{ name: 'sortOrder', desc: false }, { name: 'name', desc: false }]
273
+ };
274
+ const result = group?.value === 'favor'
275
+ ? (await fetchFavoriteBoardList(query)).favoriteBoards
276
+ : group?.value === 'mywork'
277
+ ? (await fetchMyBoardList(query)).boardsCreatedByMe
278
+ : (await fetchBoardList(query)).boards;
279
+ const { items, total } = result;
279
280
  const favorites = this.favorites || [];
280
281
  const records = (items || []).map(board => ({
281
282
  ...board,
@@ -293,91 +294,6 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
293
294
  await this.refreshBoards();
294
295
  }
295
296
  }
296
- async getBoards({ page = 1, limit = 24, groupId = '', types = [], states = [] } = {}) {
297
- if (groupId === 'favor') {
298
- return await this.getFavoriteBoards({ page, limit, types, states });
299
- }
300
- else if (groupId === 'mywork') {
301
- return await this.getMyBoards({ page, limit, types, states });
302
- }
303
- const filters = [];
304
- if (groupId) {
305
- filters.push({
306
- name: 'groupId',
307
- operator: 'eq',
308
- value: groupId
309
- });
310
- }
311
- if (this.searchText) {
312
- filters.push({
313
- name: 'name',
314
- operator: 'search',
315
- value: '%' + this.searchText + '%'
316
- });
317
- }
318
- if (types.length) {
319
- filters.push({
320
- name: 'type',
321
- operator: 'in',
322
- value: types
323
- });
324
- }
325
- if (states.length) {
326
- filters.push({
327
- name: 'state',
328
- operator: 'in',
329
- value: states
330
- });
331
- }
332
- const listParam = {
333
- filters,
334
- sortings: [
335
- {
336
- name: 'sortOrder',
337
- desc: false
338
- },
339
- {
340
- name: 'name',
341
- desc: false
342
- }
343
- ],
344
- pagination: {
345
- page,
346
- limit
347
- }
348
- };
349
- return (await fetchBoardList(listParam)).boards;
350
- }
351
- /**
352
- * favor/mywork 같이 "search text + pagination"만 받는 간단한 리스트 조회 공용 헬퍼.
353
- * 그룹/타입 필터 등 복합 조건을 쓰는 일반 목록(getBoards)과 구분해 중복 제거.
354
- */
355
- async _fetchSimpleBoardList(fetcher, resultKey, { page, limit, types = [], states = [] }) {
356
- /* The type and state chips apply here too - the server narrows these lists with the same
357
- * filters as the plain board list, so a pressed chip means the same thing in every view. */
358
- const filters = [];
359
- if (types.length) {
360
- filters.push({ name: 'type', operator: 'in', value: types });
361
- }
362
- if (states.length) {
363
- filters.push({ name: 'state', operator: 'in', value: states });
364
- }
365
- if (this.searchText) {
366
- filters.push({
367
- name: 'name',
368
- operator: 'search',
369
- value: '%' + this.searchText + '%'
370
- });
371
- }
372
- const result = await fetcher({ filters, pagination: { page, limit } });
373
- return result[resultKey];
374
- }
375
- async getFavoriteBoards({ page = 1, limit = 24, types = [], states = [] } = {}) {
376
- return this._fetchSimpleBoardList(fetchFavoriteBoardList, 'favoriteBoards', { page, limit, types, states });
377
- }
378
- async getMyBoards({ page = 1, limit = 24, types = [], states = [] } = {}) {
379
- return this._fetchSimpleBoardList(fetchMyBoardList, 'boardsCreatedByMe', { page, limit, types, states });
380
- }
381
297
  async refreshBoards() {
382
298
  if (!this.groups) {
383
299
  await this.refresh();
@@ -390,16 +306,6 @@ let BoardListPage = class BoardListPage extends BoardListPageBase {
390
306
  this.grist.style.transform = `translate3d(0, 0, 0)`;
391
307
  }
392
308
  }
393
- async pageUpdated(changes, lifecycle) {
394
- if (this.active) {
395
- const searchText = lifecycle.params?.search || '';
396
- if (searchText !== this.searchText) {
397
- this.searchText = searchText;
398
- await this.updateComplete;
399
- this.refreshBoards();
400
- }
401
- }
402
- }
403
309
  connectedCallback() {
404
310
  super.connectedCallback();
405
311
  this._applyState();
@@ -773,18 +679,10 @@ __decorate([
773
679
  property({ type: Object }),
774
680
  __metadata("design:type", Object)
775
681
  ], BoardListPage.prototype, "gristConfig", void 0);
776
- __decorate([
777
- state(),
778
- __metadata("design:type", String)
779
- ], BoardListPage.prototype, "searchText", void 0);
780
682
  __decorate([
781
683
  state(),
782
684
  __metadata("design:type", Object)
783
685
  ], BoardListPage.prototype, "creatable", void 0);
784
- __decorate([
785
- state(),
786
- __metadata("design:type", String)
787
- ], BoardListPage.prototype, "currentGroupId", void 0);
788
686
  __decorate([
789
687
  query('ox-grist'),
790
688
  __metadata("design:type", DataGrist)
@@ -1 +1 @@
1
- {"version":3,"file":"board-list-page.js","sourceRoot":"","sources":["../../client/pages/board-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 '../viewparts/board-info.js'\nimport '../viewparts/group-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 { pulltorefresh } from '@operato/pull-to-refresh'\nimport { navigate, PageView, store } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client/index.js'\nimport { notify } from '../utils/notify-helper.js'\nimport { boardMeta } from '../utils/board-meta.js'\nimport { CardCatalogStyles } from '@operato/styles'\n\nimport { boardCardThumb } from '../board-list/board-card-thumb.js'\n\nimport {\n cloneBoard,\n releaseBoard,\n revertBoardVersion,\n createBoard,\n createGroup,\n deleteBoard,\n deleteGroup,\n fetchBoardList,\n fetchFavoriteBoardList,\n fetchMyBoardList,\n fetchGroupList,\n updateBoard,\n updateGroup,\n importBoards\n} from '../graphql'\n\nconst BoardListPageBase = localize(i18next)(PageView) as typeof PageView\n\n/*\n * ox-grist (CARD mode) like figure-list-page and board-template-list-page, instead of the\n * board-only board-tile-list fork - see ADR on shared-component-over-app-fork. Drag-reorder comes\n * from `rows.reorderable`, a capability added to data-grist for this (2026-09-23); it dispatches a\n * `reorder` event and leaves persisting it to us, same contract board-tile-list's `reordered` used.\n *\n * Traded away in the move: the delta-merge `incrementalRefresh()` that patched only changed boards\n * in place with a highlight-flash animation. ox-grist's own pagination (`attach-page`, handled\n * internally by data-provider.ts) replaces the hand-rolled infinite scroll, but a group/search change\n * now does a plain full refetch rather than an in-place merge. Worth revisiting if the flash-on-update\n * cue turns out to matter in practice.\n */\n@customElement('board-list-page')\nexport class BoardListPage extends BoardListPageBase {\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 - every card catalog's (@operato/styles), the FAB with it. */\n CardCatalogStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n\n /*\n The group actions beside the search read as quiet as the band's buttons above them: outlined icon, muted\n colour. Filled at full ink, \"new group\" stood out against the band (user, 2026-09-25).\n */\n [slot='headroom'] md-text-button {\n --md-text-button-label-text-color: var(--md-sys-color-on-surface-variant);\n --md-text-button-icon-color: var(--md-sys-color-on-surface-variant);\n --md-text-button-icon-size: 18px;\n }\n\n [slot='headroom'] md-text-button md-icon {\n font-variation-settings: 'FILL' 0;\n }\n `\n ]\n\n @property({ type: Array }) groups: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) gristConfig: any\n\n @state() searchText: string = ''\n @state() private creatable = false\n /* Kept only to prefill board-info's \"which group\" context - the filter itself is the source of\n * truth for what fetchHandler actually asks the server for. */\n @state() private currentGroupId: 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, and figure's\n * title bar is bare text too. */\n title: i18next.t('title.board list'),\n search: {\n placeholder: i18next.t('text.search boards by name', { defaultValue: 'Search boards by name' }),\n handler: search => {\n this.searchText = search\n this.grist?.fetch()\n\n // URL에 검색어 반영 → 페이지 복귀 시 유지\n const url = new URL(window.location.href)\n if (search) {\n url.searchParams.set('search', search)\n } else {\n url.searchParams.delete('search')\n }\n history.replaceState(null, '', url.href)\n },\n value: this.searchText || ''\n },\n board_topmenu: true\n }\n }\n\n render() {\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.onReorderBoards(e.detail)}\n >\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n ${this.groups.some(group => group.id === this.currentGroupId)\n ? html`\n <md-text-button @click=${() => this.onInfoGroup(this.currentGroupId)}>\n <md-icon slot=\"icon\">edit</md-icon>\n ${i18next.t('text.edit group', { defaultValue: 'Edit' })}\n </md-text-button>\n `\n : ''}\n <md-text-button @click=${() => this.onInfoGroup(undefined)}>\n <md-icon slot=\"icon\">create_new_folder</md-icon>\n ${i18next.t('text.new group', { defaultValue: 'New Group' })}\n </md-text-button>\n </div>\n </ox-grist>\n\n ${this.creatable\n ? html`\n <button fab title=${i18next.t('text.create board', { defaultValue: 'Create Board' })} @click=${() => navigate('board-create')}>\n <md-icon>add</md-icon>${i18next.t('text.create board', { defaultValue: 'Create Board' })}\n </button>\n `\n : ''}\n `\n }\n\n async pageInitialized() {\n this.creatable = await hasPrivilege({ privilege: 'mutation', category: 'board', domainOwnerGranted: true })\n\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n /* name, then a quieter \"v3 · 2 days ago\" line - the same two-line rhythm as figure's\n * name-over-type, using what a board actually has (utils/board-meta.ts). */\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 /* The picture and the draft badge (board-card-thumb.ts); info/favorite are the two gutter\n * columns below, in the information area rather than over the picture. */\n renderer: (value, column, record) => boardCardThumb(record)\n }\n },\n {\n type: 'string',\n name: 'name',\n record: { editable: false }\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false }\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'edit',\n /* Edit first, the star last: the star is the one that can stay lit at rest, so it takes\n * the corner where the eye lands. */\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 /* A set star is a status and stays; an unset one is an action and waits for hover. */\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 * Group and board-type are filter-only facets - they carry no `list.fields`/`list.details`\n * entry, so record-card.ts never draws them on a card. `filters-form`'s delegated `change`\n * listener (filters-form.ts) turns any change into a `fetch-params-change` event that\n * data-provider.ts already listens for, so no extra wiring is needed to refetch.\n */\n {\n type: 'string',\n name: 'group',\n header: i18next.t('field.group', { defaultValue: 'Group' }),\n record: { editable: false },\n filter: {\n type: 'select',\n operator: 'eq',\n value: '',\n label: i18next.t('field.group', { defaultValue: 'Group' }),\n onchange: (value: string) => {\n this.currentGroupId = value\n return true\n },\n options: () => [\n { value: '', display: i18next.t('label.all', { defaultValue: 'All' }) },\n { value: 'favor', display: i18next.t('label.favorite', { defaultValue: 'Favorite' }) },\n { value: 'mywork', display: i18next.t('label.my-works', { defaultValue: 'My works' }) },\n ...this.groups.map(group => ({ value: group.id, display: group.name }))\n ]\n }\n },\n /*\n * Type and state are chips (select-buttons), the way figure's draft/released facet is - a\n * facet with two or three values is read faster as a row of toggles than as a checkbox\n * or a dropdown. Both are multi-select ('in'), and \"Main\" starts pressed so the default\n * view is the same main-boards-only list as before.\n */\n {\n type: 'select-buttons',\n name: 'type',\n header: i18next.t('field.board-type', { defaultValue: 'Type' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: ['main'],\n label: '',\n options: [\n { display: i18next.t('label.main', { defaultValue: 'Main' }), value: 'main' },\n { display: i18next.t('label.sub', { defaultValue: 'Sub' }), value: 'sub' },\n { display: i18next.t('label.popup', { defaultValue: 'Popup' }), value: 'popup' }\n ]\n }\n },\n {\n type: 'select-buttons',\n name: 'state',\n header: i18next.t('field.state', { defaultValue: 'State' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: [],\n label: '',\n options: [\n { display: i18next.t('label.draft', { defaultValue: 'Draft' }), value: 'draft' },\n { display: i18next.t('label.released', { defaultValue: 'Released' }), value: 'released' }\n ]\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({ page = 1, limit = 24, filters = [] }: FetchOption) {\n const groupId = (filters.find(f => f.name === 'group')?.value as string) || ''\n const types = (filters.find(f => f.name === 'type')?.value as string[]) || []\n const states = (filters.find(f => f.name === 'state')?.value as string[]) || []\n\n const { items, total } = await this.getBoards({ page, limit, groupId, types, states })\n const favorites = this.favorites || []\n const records = (items || []).map(board => ({\n ...board,\n favorited: favorites.includes(board.id),\n meta: boardMeta(board)\n }))\n\n return { total, records }\n }\n\n async refresh() {\n this.groups = (await fetchGroupList()).groups.items\n\n if (this.groups) {\n /* New reference - `options()` on the group filter closes over `this.groups`, but the filter\n * widget only re-reads it if `<ox-grist>`'s own `.config` binding actually changes. */\n this.gristConfig = { ...this.gristConfig }\n await this.refreshBoards()\n }\n }\n\n async getBoards({\n page = 1,\n limit = 24,\n groupId = '',\n types = [] as string[],\n states = [] as string[]\n } = {}) {\n if (groupId === 'favor') {\n return await this.getFavoriteBoards({ page, limit, types, states })\n } else if (groupId === 'mywork') {\n return await this.getMyBoards({ page, limit, types, states })\n }\n\n const filters = [] as any[]\n\n if (groupId) {\n filters.push({\n name: 'groupId',\n operator: 'eq',\n value: groupId\n })\n }\n\n if (this.searchText) {\n filters.push({\n name: 'name',\n operator: 'search',\n value: '%' + this.searchText + '%'\n })\n }\n\n if (types.length) {\n filters.push({\n name: 'type',\n operator: 'in',\n value: types\n })\n }\n\n if (states.length) {\n filters.push({\n name: 'state',\n operator: 'in',\n value: states\n })\n }\n\n const listParam = {\n filters,\n sortings: [\n {\n name: 'sortOrder',\n desc: false\n },\n {\n name: 'name',\n desc: false\n }\n ],\n pagination: {\n page,\n limit\n }\n }\n\n return (await fetchBoardList(listParam)).boards\n }\n\n /**\n * favor/mywork 같이 \"search text + pagination\"만 받는 간단한 리스트 조회 공용 헬퍼.\n * 그룹/타입 필터 등 복합 조건을 쓰는 일반 목록(getBoards)과 구분해 중복 제거.\n */\n private async _fetchSimpleBoardList<K extends string>(\n fetcher: (param: any) => Promise<Record<K, any[]>>,\n resultKey: K,\n { page, limit, types = [], states = [] }: { page: number; limit: number; types?: string[]; states?: string[] }\n ): Promise<any> {\n /* The type and state chips apply here too - the server narrows these lists with the same\n * filters as the plain board list, so a pressed chip means the same thing in every view. */\n const filters: any[] = []\n if (types.length) {\n filters.push({ name: 'type', operator: 'in', value: types })\n }\n if (states.length) {\n filters.push({ name: 'state', operator: 'in', value: states })\n }\n if (this.searchText) {\n filters.push({\n name: 'name',\n operator: 'search',\n value: '%' + this.searchText + '%'\n })\n }\n const result = await fetcher({ filters, pagination: { page, limit } })\n return result[resultKey]\n }\n\n async getFavoriteBoards({ page = 1, limit = 24, types = [] as string[], states = [] as string[] } = {}) {\n return this._fetchSimpleBoardList(fetchFavoriteBoardList, 'favoriteBoards', { page, limit, types, states })\n }\n\n async getMyBoards({ page = 1, limit = 24, types = [] as string[], states = [] as string[] } = {}) {\n return this._fetchSimpleBoardList(fetchMyBoardList, 'boardsCreatedByMe', { page, limit, types, states })\n }\n\n async refreshBoards() {\n if (!this.groups) {\n await this.refresh()\n return\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 const searchText = lifecycle.params?.search || ''\n if (searchText !== this.searchText) {\n this.searchText = searchText\n\n await this.updateComplete\n\n this.refreshBoards()\n }\n }\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 -\n * `favorited` is folded into each record inside `fetchHandler`, so refreshing it means a\n * refetch, and an unconditional one here span a real loop: fetch() completing dispatches through\n * this same store, which re-enters this callback, which calls fetch() again.\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 /* Group used to be a route segment, and swiping moved between routes - now it is one filter\n * among others in the same list, so there is no longer a sequence of screens to swipe between. */\n pulltorefresh({\n container: this.renderRoot,\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.currentGroupId}\n @clone-board=${e => this.onCloneBoard(e.detail)}\n @release-board=${e => this.onReleaseBoard(e.detail)}\n @revert-board-version=${e => this.onRevertBoardVersion(e.detail)}\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 @register-template=${e => this.onRegisterTemplate(e.detail)}\n ></board-info>\n `,\n { backdrop: true, size: 'medium', closable: true, title: board.name }\n )\n }\n\n async onInfoGroup(groupId) {\n const group = this.groups.find(group => group.id == groupId)\n\n openPopup(\n html`\n <group-info\n .groupId=${groupId}\n @update-group=${e => this.onUpdateGroup(e.detail)}\n @delete-group=${e => this.onDeleteGroup(e.detail)}\n @create-group=${e => this.onCreateGroup(e.detail)}\n @import-boards=${e => this.onImportBoards(e.detail)}\n ></group-info>\n `,\n {\n backdrop: true,\n size: 'small',\n closable: true,\n title: group?.name || i18next.t('text.new group', { defaultValue: 'New Group' })\n }\n )\n }\n\n async onCreateGroup(group) {\n try {\n const data = await createGroup(group)\n data && notify('info', i18next.t('text.group created', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdateGroup(group) {\n try {\n const data = await updateGroup(group)\n data && notify('info', i18next.t('text.group updated', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onDeleteGroup(group) {\n try {\n const data = await deleteGroup(group.id)\n data && notify('info', i18next.t('text.group deleted', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onImportBoards({ group, files, overwrite }) {\n try {\n const data = await importBoards({ groupId: group.id, files, overwrite })\n data && notify('info', i18next.t('text.boards imported', { count: files.length, group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onReorderBoards({ ids, movedId }: { ids: string[]; movedId: string }) {\n if (!movedId) return\n\n const newIndex = ids.indexOf(movedId)\n const prevId = newIndex > 0 ? ids[newIndex - 1] : undefined\n const nextId = newIndex < ids.length - 1 ? ids[newIndex + 1] : undefined\n\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $prevId: String, $nextId: String) {\n reorderBoard(id: $id, prevId: $prevId, nextId: $nextId)\n }\n `,\n variables: { id: movedId, prevId, nextId }\n })\n } catch (ex) {\n notify('error', ex, ex)\n this.refreshBoards()\n }\n }\n\n async onCreateBoard(board) {\n try {\n if (!board.model) {\n board.model = {\n width: 800,\n height: 600\n }\n }\n\n const data = await createBoard(board)\n\n data && notify('info', i18next.t('text.board created', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onCloneBoard({ id, name, description, targetSubdomain, targetGroupId }) {\n try {\n const data = await cloneBoard({\n id,\n name,\n description,\n targetSubdomain,\n targetGroupId\n })\n data && notify('info', i18next.t('text.board cloned', { board: name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onReleaseBoard(board) {\n try {\n const data = await releaseBoard(board, board.comment)\n data && notify('info', i18next.t('text.board released', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onRevertBoardVersion({ id, version }) {\n try {\n const board = await revertBoardVersion(id, version)\n board && notify('info', i18next.t('text.board reverted', { board: board.name, version }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onUpdateBoard(board) {\n try {\n const data = await updateBoard(board)\n data && 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 try {\n const data = await deleteBoard(board.id)\n data && notify('info', i18next.t('text.board deleted', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onJoinPlayGroup({ board, playGroup }) {\n try {\n const { data } = 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 data &&\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\n async onLeavePlayGroup({ board, playGroup }) {\n try {\n const { data } = 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 data &&\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\n async onRegisterTemplate({ id, name, description, visibility }) {\n try {\n const { data } = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $name: String!, $description: String!, $visibility: String!) {\n registerBoardAsTemplate(id: $id, name: $name, description: $description, visibility: $visibility) {\n id\n }\n }\n `,\n variables: {\n id,\n name,\n description,\n visibility\n }\n })\n\n data &&\n notify('info', i18next.t('text.info_x_successfully', { x: i18next.t('text.register-template') }), {\n name\n })\n } catch (ex) {\n notify('error', ex, ex)\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\n /* In the Favorite view an unstarred board no longer belongs on the page: refetch so it leaves. */\n if (this.currentGroupId === 'favor') {\n this.grist?.fetch()\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 { data } = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n data &&\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: data.myFavorites.map(favorite => favorite.routing)\n })\n }\n}\n"]}
1
+ {"version":3,"file":"board-list-page.js","sourceRoot":"","sources":["../../client/pages/board-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 '../viewparts/board-info.js'\nimport '../viewparts/group-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 { pulltorefresh } from '@operato/pull-to-refresh'\nimport { navigate, PageView, store } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { hasPrivilege } from '@things-factory/auth-base/dist-client/index.js'\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client/index.js'\nimport { notify } from '../utils/notify-helper.js'\nimport { boardMeta } from '../utils/board-meta.js'\nimport { CardCatalogStyles } from '@operato/styles'\n\nimport { boardCardThumb } from '../board-list/board-card-thumb.js'\n\nimport {\n cloneBoard,\n releaseBoard,\n revertBoardVersion,\n createBoard,\n createGroup,\n deleteBoard,\n deleteGroup,\n fetchBoardList,\n fetchFavoriteBoardList,\n fetchMyBoardList,\n fetchGroupList,\n updateBoard,\n updateGroup,\n importBoards\n} from '../graphql'\n\nconst BoardListPageBase = localize(i18next)(PageView) as typeof PageView\n\n/*\n * ox-grist (CARD mode) like figure-list-page and board-template-list-page, instead of the\n * board-only board-tile-list fork - see ADR on shared-component-over-app-fork. Drag-reorder comes\n * from `rows.reorderable`, a capability added to data-grist for this (2026-09-23); it dispatches a\n * `reorder` event and leaves persisting it to us, same contract board-tile-list's `reordered` used.\n *\n * Traded away in the move: the delta-merge `incrementalRefresh()` that patched only changed boards\n * in place with a highlight-flash animation. ox-grist's own pagination (`attach-page`, handled\n * internally by data-provider.ts) replaces the hand-rolled infinite scroll, but a group/search change\n * now does a plain full refetch rather than an in-place merge. Worth revisiting if the flash-on-update\n * cue turns out to matter in practice.\n */\n@customElement('board-list-page')\nexport class BoardListPage extends BoardListPageBase {\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 - every card catalog's (@operato/styles), the FAB with it. */\n CardCatalogStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n\n /*\n The group actions beside the search read as quiet as the band's buttons above them: outlined icon, muted\n colour. Filled at full ink, \"new group\" stood out against the band (user, 2026-09-25).\n */\n [slot='headroom'] md-text-button {\n --md-text-button-label-text-color: var(--md-sys-color-on-surface-variant);\n --md-text-button-icon-color: var(--md-sys-color-on-surface-variant);\n --md-text-button-icon-size: 18px;\n }\n\n [slot='headroom'] md-text-button md-icon {\n font-variation-settings: 'FILL' 0;\n }\n `\n ]\n\n @property({ type: Array }) groups: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) gristConfig: any\n\n get searchText(): string { return this.grist?.searchText || '' }\n @state() private creatable = false\n /* Prefill board-info from the committed grid filter, never from an unapproved form change. */\n private get currentGroupId(): string {\n const groups = (this.grist?.filters || []).filter(f => f.name === 'group' && f.operator === 'eq')\n return groups.length === 1 && typeof groups[0].value === 'string' ? groups[0].value : ''\n }\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, and figure's\n * title bar is bare text too. */\n title: i18next.t('title.board list'),\n search: {\n placeholder: i18next.t('text.search boards by name', { defaultValue: 'Search boards by name' }),\n handler: search => { if (this.grist) this.grist.searchText = search },\n value: this.searchText || ''\n },\n board_topmenu: true\n }\n }\n\n render() {\n return html`\n <ox-grist\n class=\"page-fill\"\n mode=\"CARD\"\n url-params-sensitive\n search-mode=\"term\"\n @query-state-change=${() => { this.requestUpdate(); this.updateContext() }}\n .config=${this.gristConfig}\n .fetchHandler=${this.fetchHandler.bind(this)}\n @reorder=${e => this.onReorderBoards(e.detail)}\n >\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n ${this.groups.some(group => group.id === this.currentGroupId)\n ? html`\n <md-text-button @click=${() => this.onInfoGroup(this.currentGroupId)}>\n <md-icon slot=\"icon\">edit</md-icon>\n ${i18next.t('text.edit group', { defaultValue: 'Edit' })}\n </md-text-button>\n `\n : ''}\n <md-text-button @click=${() => this.onInfoGroup(undefined)}>\n <md-icon slot=\"icon\">create_new_folder</md-icon>\n ${i18next.t('text.new group', { defaultValue: 'New Group' })}\n </md-text-button>\n </div>\n </ox-grist>\n\n ${this.creatable\n ? html`\n <button fab title=${i18next.t('text.create board', { defaultValue: 'Create Board' })} @click=${() => navigate('board-create')}>\n <md-icon>add</md-icon>${i18next.t('text.create board', { defaultValue: 'Create Board' })}\n </button>\n `\n : ''}\n `\n }\n\n async pageInitialized() {\n this.creatable = await hasPrivilege({ privilege: 'mutation', category: 'board', domainOwnerGranted: true })\n\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n /* name, then a quieter \"v3 · 2 days ago\" line - the same two-line rhythm as figure's\n * name-over-type, using what a board actually has (utils/board-meta.ts). */\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 /* The picture and the draft badge (board-card-thumb.ts); info/favorite are the two gutter\n * columns below, in the information area rather than over the picture. */\n renderer: (value, column, record) => boardCardThumb(record)\n }\n },\n {\n type: 'string',\n name: 'name',\n record: { editable: false }\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false }\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'edit',\n /* Edit first, the star last: the star is the one that can stay lit at rest, so it takes\n * the corner where the eye lands. */\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 /* A set star is a status and stays; an unset one is an action and waits for hover. */\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 * Group and board-type are filter-only facets - they carry no `list.fields`/`list.details`\n * entry, so record-card.ts never draws them on a card. `filters-form`'s delegated `change`\n * listener (filters-form.ts) turns any change into a `fetch-params-change` event that\n * data-provider.ts already listens for, so no extra wiring is needed to refetch.\n */\n {\n type: 'string',\n name: 'group',\n header: i18next.t('field.group', { defaultValue: 'Group' }),\n record: { editable: false },\n filter: {\n type: 'select',\n operator: 'eq',\n value: '',\n label: i18next.t('field.group', { defaultValue: 'Group' }),\n options: () => [\n { value: '', display: i18next.t('label.all', { defaultValue: 'All' }) },\n { value: 'favor', display: i18next.t('label.favorite', { defaultValue: 'Favorite' }) },\n { value: 'mywork', display: i18next.t('label.my-works', { defaultValue: 'My works' }) },\n ...this.groups.map(group => ({ value: group.id, display: group.name }))\n ]\n }\n },\n /*\n * Type and state are chips (select-buttons), the way figure's draft/released facet is - a\n * facet with two or three values is read faster as a row of toggles than as a checkbox\n * or a dropdown. Both are multi-select ('in'), and \"Main\" starts pressed so the default\n * view is the same main-boards-only list as before.\n */\n {\n type: 'select-buttons',\n name: 'type',\n header: i18next.t('field.board-type', { defaultValue: 'Type' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: ['main'],\n label: '',\n options: [\n { display: i18next.t('label.main', { defaultValue: 'Main' }), value: 'main' },\n { display: i18next.t('label.sub', { defaultValue: 'Sub' }), value: 'sub' },\n { display: i18next.t('label.popup', { defaultValue: 'Popup' }), value: 'popup' }\n ]\n }\n },\n {\n type: 'select-buttons',\n name: 'state',\n header: i18next.t('field.state', { defaultValue: 'State' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: [],\n label: '',\n options: [\n { display: i18next.t('label.draft', { defaultValue: 'Draft' }), value: 'draft' },\n { display: i18next.t('label.released', { defaultValue: 'Released' }), value: 'released' }\n ]\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({ page = 1, limit = 24, filters = [], search = '', sorters = [] }: FetchOption) {\n const groups = filters.filter(f => f.name === 'group' && f.operator === 'eq' && typeof f.value === 'string')\n const group = groups.length === 1 ? groups[0] : undefined\n const special = group?.value === 'favor' || group?.value === 'mywork'\n const query = {\n filters: filters.filter(f => !special || f !== group).map(f => f.name === 'group' ? { ...f, name: 'groupId' } : f),\n search,\n pagination: { page, limit },\n sortings: sorters.length ? sorters : [{ name: 'sortOrder', desc: false }, { name: 'name', desc: false }]\n }\n const result = group?.value === 'favor'\n ? (await fetchFavoriteBoardList(query)).favoriteBoards\n : group?.value === 'mywork'\n ? (await fetchMyBoardList(query)).boardsCreatedByMe\n : (await fetchBoardList(query)).boards\n const { items, total } = result\n const favorites = this.favorites || []\n const records = (items || []).map(board => ({\n ...board,\n favorited: favorites.includes(board.id),\n meta: boardMeta(board)\n }))\n\n return { total, records }\n }\n\n async refresh() {\n this.groups = (await fetchGroupList()).groups.items\n\n if (this.groups) {\n /* New reference - `options()` on the group filter closes over `this.groups`, but the filter\n * widget only re-reads it if `<ox-grist>`'s own `.config` binding actually changes. */\n this.gristConfig = { ...this.gristConfig }\n await this.refreshBoards()\n }\n }\n\n async refreshBoards() {\n if (!this.groups) {\n await this.refresh()\n return\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 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 -\n * `favorited` is folded into each record inside `fetchHandler`, so refreshing it means a\n * refetch, and an unconditional one here span a real loop: fetch() completing dispatches through\n * this same store, which re-enters this callback, which calls fetch() again.\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 /* Group used to be a route segment, and swiping moved between routes - now it is one filter\n * among others in the same list, so there is no longer a sequence of screens to swipe between. */\n pulltorefresh({\n container: this.renderRoot,\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.currentGroupId}\n @clone-board=${e => this.onCloneBoard(e.detail)}\n @release-board=${e => this.onReleaseBoard(e.detail)}\n @revert-board-version=${e => this.onRevertBoardVersion(e.detail)}\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 @register-template=${e => this.onRegisterTemplate(e.detail)}\n ></board-info>\n `,\n { backdrop: true, size: 'medium', closable: true, title: board.name }\n )\n }\n\n async onInfoGroup(groupId) {\n const group = this.groups.find(group => group.id == groupId)\n\n openPopup(\n html`\n <group-info\n .groupId=${groupId}\n @update-group=${e => this.onUpdateGroup(e.detail)}\n @delete-group=${e => this.onDeleteGroup(e.detail)}\n @create-group=${e => this.onCreateGroup(e.detail)}\n @import-boards=${e => this.onImportBoards(e.detail)}\n ></group-info>\n `,\n {\n backdrop: true,\n size: 'small',\n closable: true,\n title: group?.name || i18next.t('text.new group', { defaultValue: 'New Group' })\n }\n )\n }\n\n async onCreateGroup(group) {\n try {\n const data = await createGroup(group)\n data && notify('info', i18next.t('text.group created', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onUpdateGroup(group) {\n try {\n const data = await updateGroup(group)\n data && notify('info', i18next.t('text.group updated', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onDeleteGroup(group) {\n try {\n const data = await deleteGroup(group.id)\n data && notify('info', i18next.t('text.group deleted', { group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onImportBoards({ group, files, overwrite }) {\n try {\n const data = await importBoards({ groupId: group.id, files, overwrite })\n data && notify('info', i18next.t('text.boards imported', { count: files.length, group: group.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refresh()\n }\n\n async onReorderBoards({ ids, movedId }: { ids: string[]; movedId: string }) {\n if (!movedId) return\n\n const newIndex = ids.indexOf(movedId)\n const prevId = newIndex > 0 ? ids[newIndex - 1] : undefined\n const nextId = newIndex < ids.length - 1 ? ids[newIndex + 1] : undefined\n\n try {\n await client.mutate({\n mutation: gql`\n mutation ($id: String!, $prevId: String, $nextId: String) {\n reorderBoard(id: $id, prevId: $prevId, nextId: $nextId)\n }\n `,\n variables: { id: movedId, prevId, nextId }\n })\n } catch (ex) {\n notify('error', ex, ex)\n this.refreshBoards()\n }\n }\n\n async onCreateBoard(board) {\n try {\n if (!board.model) {\n board.model = {\n width: 800,\n height: 600\n }\n }\n\n const data = await createBoard(board)\n\n data && notify('info', i18next.t('text.board created', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onCloneBoard({ id, name, description, targetSubdomain, targetGroupId }) {\n try {\n const data = await cloneBoard({\n id,\n name,\n description,\n targetSubdomain,\n targetGroupId\n })\n data && notify('info', i18next.t('text.board cloned', { board: name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onReleaseBoard(board) {\n try {\n const data = await releaseBoard(board, board.comment)\n data && notify('info', i18next.t('text.board released', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onRevertBoardVersion({ id, version }) {\n try {\n const board = await revertBoardVersion(id, version)\n board && notify('info', i18next.t('text.board reverted', { board: board.name, version }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onUpdateBoard(board) {\n try {\n const data = await updateBoard(board)\n data && 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 try {\n const data = await deleteBoard(board.id)\n data && notify('info', i18next.t('text.board deleted', { board: board.name }))\n } catch (ex) {\n notify('error', ex, ex)\n }\n\n this.refreshBoards()\n }\n\n async onJoinPlayGroup({ board, playGroup }) {\n try {\n const { data } = 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 data &&\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\n async onLeavePlayGroup({ board, playGroup }) {\n try {\n const { data } = 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 data &&\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\n async onRegisterTemplate({ id, name, description, visibility }) {\n try {\n const { data } = await client.mutate({\n mutation: gql`\n mutation ($id: String!, $name: String!, $description: String!, $visibility: String!) {\n registerBoardAsTemplate(id: $id, name: $name, description: $description, visibility: $visibility) {\n id\n }\n }\n `,\n variables: {\n id,\n name,\n description,\n visibility\n }\n })\n\n data &&\n notify('info', i18next.t('text.info_x_successfully', { x: i18next.t('text.register-template') }), {\n name\n })\n } catch (ex) {\n notify('error', ex, ex)\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\n /* In the Favorite view an unstarred board no longer belongs on the page: refetch so it leaves. */\n if (this.currentGroupId === 'favor') {\n this.grist?.fetch()\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 { data } = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n data &&\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: data.myFavorites.map(favorite => favorite.routing)\n })\n }\n}\n"]}
@@ -6,6 +6,7 @@ import '@things-factory/board-ai';
6
6
  import { BoardModeller } from '@operato/board/ox-board-modeller.js';
7
7
  import { PageView } from '@operato/shell';
8
8
  import { findSceneComponent } from '@operato/scene-ops';
9
+ import { OxPrompt } from '@operato/popup/ox-prompt.js';
9
10
  import '../board-placement-tray.js';
10
11
  export { findSceneComponent };
11
12
  export declare class BoardModellerPage extends PageView {
@@ -192,5 +193,8 @@ export declare class BoardModellerPage extends PageView {
192
193
  * sessionId 없으면(AI 세션 미연결) skip — 협업 비활성, 편집은 정상.
193
194
  */
194
195
  private _captureDirectEdits;
195
- canDeactivate(): Promise<boolean>;
196
+ get addressDirty(): boolean;
197
+ get addressEditsKept(): boolean;
198
+ get deactivation(): boolean | Parameters<typeof OxPrompt.open>[0];
199
+ discardAddressEdits(): void;
196
200
  }
@@ -18,7 +18,6 @@ import { applyScenePatchVerbose, dispatchSceneAction, dispatchSceneEditOp, findS
18
18
  import { client, gqlContext, subscribe } from '@operato/graphql';
19
19
  import { clearAssistantSurface, provideAssistantSurface } from '@things-factory/ai-assistant/dist-client/index.js';
20
20
  import { i18next } from '@operato/i18n';
21
- import { OxPrompt } from '@operato/popup/ox-prompt.js';
22
21
  import { provider } from '@operato/board/board-provider.js';
23
22
  import '../board-placement-tray.js'; // 배치 팔레트 오버레이(호스트-등록 provider 있을 때만 표시)
24
23
  import { boardPlacementProvider } from '@operato/board/board-placement-palette.js';
@@ -954,20 +953,21 @@ let BoardModellerPage = class BoardModellerPage extends PageView {
954
953
  notifyError(ex);
955
954
  }
956
955
  }
957
- async canDeactivate() {
958
- if (this.unsaved()) {
959
- const leave = await OxPrompt.open({
960
- title: i18next.t('text.are_you_sure'),
961
- text: i18next.t('prompt.sure to navigate away?'),
962
- confirmButton: { text: i18next.t('button.confirm') },
963
- cancelButton: { text: i18next.t('button.cancel') }
964
- });
965
- /* Leaving without saving, chosen: nothing to keep (ADR-0098 decision 3). */
966
- if (leave)
967
- await this.drafts.settled();
968
- return leave;
969
- }
970
- return true;
956
+ get addressDirty() { return this.unsaved(); }
957
+ get addressEditsKept() { return this.drafts.keeps; }
958
+ get deactivation() {
959
+ if (!this.unsaved())
960
+ return true;
961
+ return {
962
+ title: i18next.t('text.are_you_sure'),
963
+ text: i18next.t('prompt.sure to navigate away?'),
964
+ confirmButton: { text: i18next.t('button.confirm') },
965
+ cancelButton: { text: i18next.t('button.cancel') }
966
+ };
967
+ }
968
+ discardAddressEdits() {
969
+ void this.drafts.settled();
970
+ super.discardAddressEdits();
971
971
  }
972
972
  };
973
973
  __decorate([