@things-factory/board-ui 10.0.0-beta.8 → 10.0.0-beta.80

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.
Files changed (104) hide show
  1. package/dist-client/apptools/favorite-tool.js +5 -5
  2. package/dist-client/apptools/favorite-tool.js.map +1 -1
  3. package/dist-client/board-list/board-tile-list.d.ts +6 -3
  4. package/dist-client/board-list/board-tile-list.js +316 -62
  5. package/dist-client/board-list/board-tile-list.js.map +1 -1
  6. package/dist-client/board-list/group-bar.js +3 -3
  7. package/dist-client/board-list/group-bar.js.map +1 -1
  8. package/dist-client/board-list/play-group-bar.d.ts +0 -1
  9. package/dist-client/board-list/play-group-bar.js +3 -6
  10. package/dist-client/board-list/play-group-bar.js.map +1 -1
  11. package/dist-client/board-provider.js +20 -8
  12. package/dist-client/board-provider.js.map +1 -1
  13. package/dist-client/data-grist/board-editor.js +4 -4
  14. package/dist-client/data-grist/board-editor.js.map +1 -1
  15. package/dist-client/data-grist/board-renderer.js +4 -4
  16. package/dist-client/data-grist/board-renderer.js.map +1 -1
  17. package/dist-client/graphql/attachment.d.ts +33 -0
  18. package/dist-client/graphql/attachment.js +87 -0
  19. package/dist-client/graphql/attachment.js.map +1 -0
  20. package/dist-client/graphql/board-import.d.ts +45 -0
  21. package/dist-client/graphql/board-import.js +104 -0
  22. package/dist-client/graphql/board-import.js.map +1 -0
  23. package/dist-client/graphql/board-template.js +1 -1
  24. package/dist-client/graphql/board-template.js.map +1 -1
  25. package/dist-client/graphql/board.d.ts +1 -0
  26. package/dist-client/graphql/board.js +28 -2
  27. package/dist-client/graphql/board.js.map +1 -1
  28. package/dist-client/graphql/group.js +1 -1
  29. package/dist-client/graphql/group.js.map +1 -1
  30. package/dist-client/graphql/play-group.js +3 -3
  31. package/dist-client/graphql/play-group.js.map +1 -1
  32. package/dist-client/pages/attachment-list-page.d.ts +16 -0
  33. package/dist-client/pages/attachment-list-page.js +63 -2
  34. package/dist-client/pages/attachment-list-page.js.map +1 -1
  35. package/dist-client/pages/board-action-dispatch.d.ts +31 -0
  36. package/dist-client/pages/board-action-dispatch.js +80 -0
  37. package/dist-client/pages/board-action-dispatch.js.map +1 -0
  38. package/dist-client/pages/board-action-dispatch.test.d.ts +1 -0
  39. package/dist-client/pages/board-action-dispatch.test.js +235 -0
  40. package/dist-client/pages/board-action-dispatch.test.js.map +1 -0
  41. package/dist-client/pages/board-create-wizard-page.d.ts +157 -0
  42. package/dist-client/pages/board-create-wizard-page.js +2176 -0
  43. package/dist-client/pages/board-create-wizard-page.js.map +1 -0
  44. package/dist-client/pages/board-edit-dispatch.d.ts +74 -0
  45. package/dist-client/pages/board-edit-dispatch.js +299 -0
  46. package/dist-client/pages/board-edit-dispatch.js.map +1 -0
  47. package/dist-client/pages/board-edit-dispatch.test.d.ts +1 -0
  48. package/dist-client/pages/board-edit-dispatch.test.js +858 -0
  49. package/dist-client/pages/board-edit-dispatch.test.js.map +1 -0
  50. package/dist-client/pages/board-list-page.d.ts +23 -3
  51. package/dist-client/pages/board-list-page.js +165 -77
  52. package/dist-client/pages/board-list-page.js.map +1 -1
  53. package/dist-client/pages/board-modeller-page.d.ts +134 -0
  54. package/dist-client/pages/board-modeller-page.js +725 -54
  55. package/dist-client/pages/board-modeller-page.js.map +1 -1
  56. package/dist-client/pages/board-player-by-name-page.js.map +1 -1
  57. package/dist-client/pages/board-player-page.js +14 -26
  58. package/dist-client/pages/board-player-page.js.map +1 -1
  59. package/dist-client/pages/board-viewer-by-name-page.d.ts +8 -1
  60. package/dist-client/pages/board-viewer-by-name-page.js +9 -1
  61. package/dist-client/pages/board-viewer-by-name-page.js.map +1 -1
  62. package/dist-client/pages/board-viewer-page.d.ts +2 -1
  63. package/dist-client/pages/board-viewer-page.js +52 -48
  64. package/dist-client/pages/board-viewer-page.js.map +1 -1
  65. package/dist-client/pages/play-list-page.d.ts +0 -1
  66. package/dist-client/pages/play-list-page.js +26 -33
  67. package/dist-client/pages/play-list-page.js.map +1 -1
  68. package/dist-client/pages/printable-board-viewer-page.js +2 -2
  69. package/dist-client/pages/printable-board-viewer-page.js.map +1 -1
  70. package/dist-client/route.d.ts +1 -1
  71. package/dist-client/route.js +3 -0
  72. package/dist-client/route.js.map +1 -1
  73. package/dist-client/setting-let/board-view-setting-let.js +1 -1
  74. package/dist-client/setting-let/board-view-setting-let.js.map +1 -1
  75. package/dist-client/tsconfig.tsbuildinfo +1 -1
  76. package/dist-client/utils/notify-helper.d.ts +7 -0
  77. package/dist-client/utils/notify-helper.js +28 -0
  78. package/dist-client/utils/notify-helper.js.map +1 -0
  79. package/dist-client/utils/query-utils.d.ts +1 -0
  80. package/dist-client/utils/query-utils.js +20 -0
  81. package/dist-client/utils/query-utils.js.map +1 -0
  82. package/dist-client/viewparts/board-basic-info.js +9 -13
  83. package/dist-client/viewparts/board-basic-info.js.map +1 -1
  84. package/dist-client/viewparts/board-template-info.d.ts +0 -1
  85. package/dist-client/viewparts/board-template-info.js +5 -13
  86. package/dist-client/viewparts/board-template-info.js.map +1 -1
  87. package/dist-client/viewparts/board-versions.js +1 -1
  88. package/dist-client/viewparts/board-versions.js.map +1 -1
  89. package/dist-client/viewparts/group-info-basic.js +2 -2
  90. package/dist-client/viewparts/group-info-basic.js.map +1 -1
  91. package/dist-client/viewparts/group-info-import.js +2 -2
  92. package/dist-client/viewparts/group-info-import.js.map +1 -1
  93. package/dist-client/viewparts/link-builder.js +1 -1
  94. package/dist-client/viewparts/link-builder.js.map +1 -1
  95. package/dist-client/viewparts/play-group-info-basic.js +2 -2
  96. package/dist-client/viewparts/play-group-info-basic.js.map +1 -1
  97. package/dist-server/tsconfig.tsbuildinfo +1 -1
  98. package/package.json +5 -4
  99. package/things-factory.config.js +1 -0
  100. package/translations/en.json +71 -30
  101. package/translations/ja.json +3 -29
  102. package/translations/ko.json +71 -30
  103. package/translations/ms.json +3 -29
  104. package/translations/zh.json +3 -29
@@ -60,7 +60,7 @@ let GroupBar = class GroupBar extends LitElement {
60
60
  }));
61
61
  }
62
62
  onWheelEvent(e) {
63
- var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
63
+ const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
64
64
  this.scrollLeft -= delta * 40;
65
65
  e.preventDefault();
66
66
  }
@@ -76,12 +76,12 @@ let GroupBar = class GroupBar extends LitElement {
76
76
  this.__sb && this.__sb.updateMetrics();
77
77
  }
78
78
  if (change.has('groupId')) {
79
- var active = this.renderRoot.querySelector('li[active]');
79
+ const active = this.renderRoot.querySelector('li[active]');
80
80
  active && active.scrollIntoView();
81
81
  }
82
82
  }
83
83
  firstUpdated() {
84
- var scrollTarget = this.renderRoot.querySelector('ul');
84
+ const scrollTarget = this.renderRoot.querySelector('ul');
85
85
  /* long-press */
86
86
  longpressable(scrollTarget);
87
87
  scrollTarget.addEventListener('mousewheel', this.onWheelEvent.bind(this), false);
@@ -1 +1 @@
1
- {"version":3,"file":"group-bar.js","sourceRoot":"","sources":["../../client/board-list/group-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport i18next from 'i18next'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable, isMobileDevice } from '@operato/utils'\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\nimport { GroupBarStyles } from './group-bar-styles'\n@customElement('group-bar')\nexport default class GroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups?: any[]\n @property({ type: String }) groupId?: string\n @property({ type: String }) targetPage?: string\n\n @state() showAll?: boolean = false\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n <li ?active=${!this.groupId}>\n <a href=${this.targetPage || ''}><md-icon>dashboard</md-icon></a>\n </li>\n\n <li ?active=${this.groupId === 'favor'}>\n <a href=\"${this.targetPage}/favor\"><md-icon>star</md-icon></a>\n </li>\n\n ${privileged(\n { privilege: 'mutation', category: 'board' },\n html`<li ?active=${this.groupId === 'mywork'}>\n <a href=\"${this.targetPage}/mywork\"><md-icon>engineering</md-icon></a>\n </li>`\n )}\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this.infoGroup(group.id)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding></li>\n\n ${isMobileDevice()\n ? nothing\n : html`\n <li>\n <label for=\"show-all\">${i18next.t('label.show-all-board-type')}&nbsp;</label>\n <md-checkbox\n id=\"show-all\"\n ?checked=${this.showAll}\n @change=${e => this.showAllBoardType(e)}\n ></md-checkbox>\n </li>\n `}\n\n <li add>\n <md-icon @click=${e => this.infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n infoGroup(groupId?: string) {\n this.dispatchEvent(\n new CustomEvent('info-group', {\n detail: groupId\n })\n )\n }\n\n onWheelEvent(e) {\n var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n showAllBoardType(e) {\n this.showAll = e.target.checked\n\n this.dispatchEvent(\n new CustomEvent('show-all-board-type', {\n detail: this.showAll\n })\n )\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n var active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n var scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this.onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"group-bar.js","sourceRoot":"","sources":["../../client/board-list/group-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport i18next from 'i18next'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable, isMobileDevice } from '@operato/utils'\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\nimport { GroupBarStyles } from './group-bar-styles'\n@customElement('group-bar')\nexport default class GroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups?: any[]\n @property({ type: String }) groupId?: string\n @property({ type: String }) targetPage?: string\n\n @state() showAll?: boolean = false\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n <li ?active=${!this.groupId}>\n <a href=${this.targetPage || ''}><md-icon>dashboard</md-icon></a>\n </li>\n\n <li ?active=${this.groupId === 'favor'}>\n <a href=\"${this.targetPage}/favor\"><md-icon>star</md-icon></a>\n </li>\n\n ${privileged(\n { privilege: 'mutation', category: 'board' },\n html`<li ?active=${this.groupId === 'mywork'}>\n <a href=\"${this.targetPage}/mywork\"><md-icon>engineering</md-icon></a>\n </li>`\n )}\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this.infoGroup(group.id)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding></li>\n\n ${isMobileDevice()\n ? nothing\n : html`\n <li>\n <label for=\"show-all\">${i18next.t('label.show-all-board-type')}&nbsp;</label>\n <md-checkbox\n id=\"show-all\"\n ?checked=${this.showAll}\n @change=${e => this.showAllBoardType(e)}\n ></md-checkbox>\n </li>\n `}\n\n <li add>\n <md-icon @click=${e => this.infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n infoGroup(groupId?: string) {\n this.dispatchEvent(\n new CustomEvent('info-group', {\n detail: groupId\n })\n )\n }\n\n onWheelEvent(e) {\n const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n showAllBoardType(e) {\n this.showAll = e.target.checked\n\n this.dispatchEvent(\n new CustomEvent('show-all-board-type', {\n detail: this.showAll\n })\n )\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n const active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n const scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this.onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}
@@ -15,7 +15,6 @@ export default class PlayGroupBar extends LitElement {
15
15
  name: string;
16
16
  }): void;
17
17
  _onWheelEvent(e: any): void;
18
- _onClickAdd(e: any): void;
19
18
  updated(change: any): void;
20
19
  firstUpdated(): void;
21
20
  }
@@ -36,25 +36,22 @@ let PlayGroupBar = class PlayGroupBar extends LitElement {
36
36
  }));
37
37
  }
38
38
  _onWheelEvent(e) {
39
- var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
39
+ const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
40
40
  this.scrollLeft -= delta * 40;
41
41
  e.preventDefault();
42
42
  }
43
- _onClickAdd(e) {
44
- // TODO Implements
45
- }
46
43
  updated(change) {
47
44
  if (change.has('groups')) {
48
45
  /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */
49
46
  this.__sb && this.__sb.updateMetrics();
50
47
  }
51
48
  if (change.has('groupId')) {
52
- var active = this.renderRoot.querySelector('li[active]');
49
+ const active = this.renderRoot.querySelector('li[active]');
53
50
  active && active.scrollIntoView();
54
51
  }
55
52
  }
56
53
  firstUpdated() {
57
- var scrollTarget = this.renderRoot.querySelector('ul');
54
+ const scrollTarget = this.renderRoot.querySelector('ul');
58
55
  /* long-press */
59
56
  longpressable(scrollTarget);
60
57
  scrollTarget.addEventListener('mousewheel', this._onWheelEvent.bind(this), false);
@@ -1 +1 @@
1
- {"version":3,"file":"play-group-bar.js","sourceRoot":"","sources":["../../client/board-list/play-group-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable } from '@operato/utils'\nimport { GroupBarStyles } from './group-bar-styles.js'\n\n@customElement('play-group-bar')\nexport default class PlayGroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups: { id: string; name: string }[] = []\n @property({ type: String }) groupId: string = ''\n @property({ type: String, attribute: 'target-page' }) targetPage: string = ''\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this._infoGroup(group)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding>&nbsp;</li>\n\n <li add>\n <md-icon @click=${e => this._infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n _infoGroup(group?: { id: string; name: string }) {\n this.dispatchEvent(\n new CustomEvent('info-play-group', {\n detail: group\n })\n )\n }\n\n _onWheelEvent(e) {\n var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n _onClickAdd(e) {\n // TODO Implements\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n var active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n var scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this._onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"play-group-bar.js","sourceRoot":"","sources":["../../client/board-list/play-group-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable } from '@operato/utils'\nimport { GroupBarStyles } from './group-bar-styles.js'\n\n@customElement('play-group-bar')\nexport default class PlayGroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups: { id: string; name: string }[] = []\n @property({ type: String }) groupId: string = ''\n @property({ type: String, attribute: 'target-page' }) targetPage: string = ''\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this._infoGroup(group)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding>&nbsp;</li>\n\n <li add>\n <md-icon @click=${e => this._infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n _infoGroup(group?: { id: string; name: string }) {\n this.dispatchEvent(\n new CustomEvent('info-play-group', {\n detail: group\n })\n )\n }\n\n _onWheelEvent(e) {\n const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n const active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n const scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this._onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}
@@ -1,19 +1,22 @@
1
1
  import gql from 'graphql-tag';
2
2
  import { create, error, ReferenceMap } from '@hatiolab/things-scene';
3
- import { BoardDataStorage } from '@operato/board';
3
+ import { BoardDataStorage, BoardModelCache } from '@operato/board';
4
4
  import { client, gqlContext, subscribe } from '@operato/graphql';
5
5
  export function createBoardProvider() {
6
- var _provider = new ReferenceMap(async (boardId, resolve, reject) => {
6
+ const _provider = new ReferenceMap(async (boardId, resolve, reject) => {
7
+ const startTime = performance.now();
7
8
  try {
9
+ const cached = await BoardModelCache.get(boardId);
8
10
  const response = await client.query({
9
11
  query: gql `
10
- query FetchBoardById($id: String!) {
11
- board(id: $id) {
12
+ query FetchBoardById($id: String!, $cachedUpdatedAt: String) {
13
+ board(id: $id, cachedUpdatedAt: $cachedUpdatedAt) {
12
14
  model
15
+ updatedAt
13
16
  }
14
17
  }
15
18
  `,
16
- variables: { id: boardId },
19
+ variables: { id: boardId, cachedUpdatedAt: cached?.updatedAt },
17
20
  context: gqlContext()
18
21
  });
19
22
  const board = response.data?.board;
@@ -21,11 +24,19 @@ export function createBoardProvider() {
21
24
  reject(new Error('Failed to get the requested board.'));
22
25
  return;
23
26
  }
24
- var model = JSON.parse(board.model);
25
- var scene;
27
+ let model;
28
+ if (board.model === null && cached) {
29
+ // 캐시 유효
30
+ model = cached.model;
31
+ }
32
+ else {
33
+ // 새 모델
34
+ model = JSON.parse(board.model);
35
+ await BoardModelCache.put(boardId, '', board.model, board.updatedAt);
36
+ }
37
+ let scene;
26
38
  try {
27
39
  scene = await provider.get(boardId);
28
- console.warn('Board fetched more than twice.', boardId);
29
40
  }
30
41
  catch (e) {
31
42
  scene = create({
@@ -33,6 +44,7 @@ export function createBoardProvider() {
33
44
  mode: 0,
34
45
  refProvider: provider,
35
46
  dataStorage: new BoardDataStorage(boardId),
47
+ loading: { startTime },
36
48
  dataSubscriptionProvider: {
37
49
  subscribe: async (tag, component) => {
38
50
  return await subscribe({
@@ -1 +1 @@
1
- {"version":3,"file":"board-provider.js","sourceRoot":"","sources":["../client/board-provider.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAS,MAAM,wBAAwB,CAAA;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEhE,MAAM,UAAU,mBAAmB;IACjC,IAAI,SAAS,GAAG,IAAI,YAAY,CAC9B,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAgB,EAAE;QAC/C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;gBAClC,KAAK,EAAE,GAAG,CAAA;;;;;;WAMT;gBACD,SAAS,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE;gBAC1B,OAAO,EAAE,UAAU,EAAE;aACtB,CAAC,CAAA;YAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;YAElC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAA;gBACvD,OAAM;YACR,CAAC;YAED,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YAEnC,IAAI,KAAY,CAAA;YAEhB,IAAI,CAAC;gBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACnC,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,OAAO,CAAC,CAAA;YACzD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,GAAG,MAAM,CAAC;oBACb,KAAK;oBACL,IAAI,EAAE,CAAC;oBACP,WAAW,EAAE,QAAe;oBAC5B,WAAW,EAAE,IAAI,gBAAgB,CAAC,OAAO,CAAC;oBAC1C,wBAAwB,EAAE;wBACxB,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE;4BAClC,OAAO,MAAM,SAAS,CACpB;gCACE,KAAK,EAAE,GAAG,CAAA;;6CAEe,GAAG;;;;;6BAKnB;6BACV,EACD;gCACE,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;oCACvB,IAAI,IAAI,EAAE,CAAC;wCACT,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAA;oCACjC,CAAC;gCACH,CAAC;6BACF,CACF,CAAA;wBACH,CAAC;wBAED,OAAO,KAAI,CAAC;qBACb;iBACK,CAAC,CAAA;gBAET,6BAA6B;YAC/B,CAAC;YAED,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,KAAK,CAAC,CAAC,CAAC,CAAA;YACR,MAAM,CAAC,CAAC,CAAC,CAAA;QACX,CAAC;IACH,CAAC,EACD,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;QAChB,GAAG,CAAC,OAAO,EAAE,CAAA;IACf,CAAC,CACF,CAAA;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAA","sourcesContent":["import gql from 'graphql-tag'\n\nimport { create, error, ReferenceMap, Scene } from '@hatiolab/things-scene'\nimport { BoardDataStorage } from '@operato/board'\nimport { client, gqlContext, subscribe } from '@operato/graphql'\n\nexport function createBoardProvider() {\n var _provider = new ReferenceMap(\n async (boardId, resolve, reject): Promise<any> => {\n try {\n const response = await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n model\n }\n }\n `,\n variables: { id: boardId },\n context: gqlContext()\n })\n\n const board = response.data?.board\n\n if (!board) {\n reject(new Error('Failed to get the requested board.'))\n return\n }\n\n var model = JSON.parse(board.model)\n\n var scene: Scene\n\n try {\n scene = await provider.get(boardId)\n console.warn('Board fetched more than twice.', boardId)\n } catch (e) {\n scene = create({\n model,\n mode: 0,\n refProvider: provider as any,\n dataStorage: new BoardDataStorage(boardId),\n dataSubscriptionProvider: {\n subscribe: async (tag, component) => {\n return await subscribe(\n {\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n }\n }\n `\n },\n {\n next: async ({ data }) => {\n if (data) {\n component.data = data.data.data\n }\n }\n }\n )\n },\n\n dispose() {}\n }\n } as any)\n\n // s.app.baseUrl = undefined;\n }\n\n resolve(scene)\n } catch (e) {\n error(e)\n reject(e)\n }\n },\n async (id, ref) => {\n ref.dispose()\n }\n )\n\n return _provider\n}\n\nexport const provider = createBoardProvider()\n"]}
1
+ {"version":3,"file":"board-provider.js","sourceRoot":"","sources":["../client/board-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import gql from 'graphql-tag'\n\nimport { create, error, ReferenceMap, Scene } from '@hatiolab/things-scene'\nimport { BoardDataStorage, BoardModelCache } from '@operato/board'\nimport { client, gqlContext, subscribe } from '@operato/graphql'\n\nexport function createBoardProvider() {\n const _provider = new ReferenceMap(\n async (boardId, resolve, reject): Promise<any> => {\n const startTime = performance.now()\n try {\n const cached = await BoardModelCache.get(boardId)\n\n const response = await client.query({\n query: gql`\n query FetchBoardById($id: String!, $cachedUpdatedAt: String) {\n board(id: $id, cachedUpdatedAt: $cachedUpdatedAt) {\n model\n updatedAt\n }\n }\n `,\n variables: { id: boardId, cachedUpdatedAt: cached?.updatedAt },\n context: gqlContext()\n })\n\n const board = response.data?.board\n\n if (!board) {\n reject(new Error('Failed to get the requested board.'))\n return\n }\n\n let model: any\n if (board.model === null && cached) {\n // 캐시 유효\n model = cached.model\n } else {\n // 새 모델\n model = JSON.parse(board.model)\n await BoardModelCache.put(boardId, '', board.model, board.updatedAt)\n }\n\n let scene: Scene\n\n try {\n scene = await provider.get(boardId)\n } catch (e) {\n scene = create({\n model,\n mode: 0,\n refProvider: provider as any,\n dataStorage: new BoardDataStorage(boardId),\n loading: { startTime },\n dataSubscriptionProvider: {\n subscribe: async (tag, component) => {\n return await subscribe(\n {\n query: gql`\n subscription {\n data(tag: \"${tag}\") {\n tag\n data\n }\n }\n `\n },\n {\n next: async ({ data }) => {\n if (data) {\n component.data = data.data.data\n }\n }\n }\n )\n },\n\n dispose() {}\n }\n } as any)\n\n // s.app.baseUrl = undefined;\n }\n\n resolve(scene)\n } catch (e) {\n error(e)\n reject(e)\n }\n },\n async (id, ref) => {\n ref.dispose()\n }\n )\n\n return _provider\n}\n\nexport const provider = createBoardProvider()\n"]}
@@ -37,7 +37,7 @@ let BoardEditor = class BoardEditor extends OxGristEditor {
37
37
  `
38
38
  ]; }
39
39
  render() {
40
- var { boardViewerPage } = this.column.record.options || {};
40
+ const { boardViewerPage } = this.column.record.options || {};
41
41
  return html `
42
42
  <board-renderer
43
43
  .value=${this.value}
@@ -60,13 +60,13 @@ let BoardEditor = class BoardEditor extends OxGristEditor {
60
60
  * 주의. value는 object일 수도 있고, string일 수도 있다.
61
61
  * string인 경우에는 해당 보드의 id로 해석한다.
62
62
  */
63
- var value = this.value || {};
64
- var template = html `
63
+ const value = this.value || {};
64
+ const template = html `
65
65
  <ox-board-selector
66
66
  .creatable=${true}
67
67
  .value=${this.value}
68
68
  @board-selected=${async (e) => {
69
- var board = e.detail.board;
69
+ const board = e.detail.board;
70
70
  this.dispatchEvent(new CustomEvent('field-change', {
71
71
  bubbles: true,
72
72
  composed: true,
@@ -1 +1 @@
1
- {"version":3,"file":"board-editor.js","sourceRoot":"","sources":["../../client/data-grist/board-editor.ts"],"names":[],"mappings":";AAAA,OAAO,qCAAqC,CAAA;AAC5C,OAAO,qBAAqB,CAAA;AAE5B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAS,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGpC,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,aAAa;aACrC,WAAM,GAAG;QACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BF;KACF,AA5BY,CA4BZ;IASD,MAAM;QACJ,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;QAC1D,OAAO,IAAI,CAAA;;iBAEE,IAAI,CAAC,KAAK;2BACA,eAAe;iBACzB,IAAI,CAAC,YAAY;;KAE7B,CAAA;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE1C,4BAA4B;QAE5B,sBAAsB;IACxB,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;QAED;;;;WAIG;QACH,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE5B,IAAI,QAAQ,GAAG,IAAI,CAAA;;qBAEF,IAAI;iBACR,IAAI,CAAC,KAAK;0BACD,KAAK,EAAC,CAAC,EAAC,EAAE;YAC1B,IAAI,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAE1B,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,cAAc,EAAE;gBAC9B,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE;oBACN,MAAM,EAAE,IAAI,CAAC,KAAK;oBAClB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE;oBAC3D,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,GAAG,EAAE,IAAI,CAAC,GAAG;iBACd;aACF,CAAC,CACH,CAAA;YAED,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAClC,CAAC;;KAEJ,CAAA;QAED,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE;YAC/B,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;SACvC,CAAC,CAAA;IACJ,CAAC;;AArE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0CAAW;AACV;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CAAY;AACX;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CAAY;AACX;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;wCAAa;AAlC7B,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CAqGvB","sourcesContent":["import '@operato/board/ox-board-selector.js'\nimport './board-renderer.js'\n\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { OxGristEditor } from '@operato/data-grist'\nimport { i18next } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\n\n@customElement('board-editor')\nexport class BoardEditor extends OxGristEditor {\n static styles = [\n css`\n :host {\n display: flex;\n flex-flow: row nowrap;\n align-items: center;\n\n box-sizing: border-box;\n\n width: 100%;\n height: 100%;\n\n border: 0;\n background-color: transparent;\n\n font: var(--grist-object-editor-font);\n color: var(--grist-object-editor-color);\n\n justify-content: inherit;\n }\n\n board-renderer {\n display: flex;\n flex: auto;\n\n justify-content: inherit;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) column: any\n @property({ type: Object }) record: any\n @property({ type: Number }) row?: number\n\n popup\n\n render() {\n var { boardViewerPage } = this.column.record.options || {}\n return html`\n <board-renderer\n .value=${this.value}\n .boardViewerPage=${boardViewerPage}\n @click=${this.openSelector}\n ></board-renderer>\n `\n }\n\n async firstUpdated() {\n this.value = this.record[this.column.name]\n\n // await this.updateComplete\n\n // this.openSelector()\n }\n\n openSelector() {\n if (this.popup) {\n delete this.popup\n }\n\n /*\n * 기존 설정된 보드가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.\n * 주의. value는 object일 수도 있고, string일 수도 있다.\n * string인 경우에는 해당 보드의 id로 해석한다.\n */\n var value = this.value || {}\n\n var template = html`\n <ox-board-selector\n .creatable=${true}\n .value=${this.value}\n @board-selected=${async e => {\n var board = e.detail.board\n\n this.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: {\n before: this.value,\n after: this.column.type == 'board' ? board : board.id || '',\n record: this.record,\n column: this.column,\n row: this.row\n }\n })\n )\n\n this.popup && this.popup.close()\n }}\n ></ox-board-selector>\n `\n\n this.popup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('title.select board')\n })\n }\n}\n"]}
1
+ {"version":3,"file":"board-editor.js","sourceRoot":"","sources":["../../client/data-grist/board-editor.ts"],"names":[],"mappings":";AAAA,OAAO,qCAAqC,CAAA;AAC5C,OAAO,qBAAqB,CAAA;AAE5B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAS,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAGpC,IAAM,WAAW,GAAjB,MAAM,WAAY,SAAQ,aAAa;aACrC,WAAM,GAAG;QACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;KA0BF;KACF,AA5BY,CA4BZ;IASD,MAAM;QACJ,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;QAC5D,OAAO,IAAI,CAAA;;iBAEE,IAAI,CAAC,KAAK;2BACA,eAAe;iBACzB,IAAI,CAAC,YAAY;;KAE7B,CAAA;IACH,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAE1C,4BAA4B;QAE5B,sBAAsB;IACxB,CAAC;IAED,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;QAED;;;;WAIG;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAE9B,MAAM,QAAQ,GAAG,IAAI,CAAA;;qBAEJ,IAAI;iBACR,IAAI,CAAC,KAAK;0BACD,KAAK,EAAC,CAAC,EAAC,EAAE;YAC1B,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;YAE5B,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,cAAc,EAAE;gBAC9B,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE;oBACN,MAAM,EAAE,IAAI,CAAC,KAAK;oBAClB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE;oBAC3D,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,GAAG,EAAE,IAAI,CAAC,GAAG;iBACd;aACF,CAAC,CACH,CAAA;YAED,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAClC,CAAC;;KAEJ,CAAA;QAED,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,QAAQ,EAAE;YAC/B,QAAQ,EAAE,IAAI;YACd,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC;SACvC,CAAC,CAAA;IACJ,CAAC;;AArE2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0CAAW;AACV;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CAAY;AACX;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;2CAAY;AACX;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;wCAAa;AAlC7B,WAAW;IADvB,aAAa,CAAC,cAAc,CAAC;GACjB,WAAW,CAqGvB","sourcesContent":["import '@operato/board/ox-board-selector.js'\nimport './board-renderer.js'\n\nimport { css, html } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { OxGristEditor } from '@operato/data-grist'\nimport { i18next } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\n\n@customElement('board-editor')\nexport class BoardEditor extends OxGristEditor {\n static styles = [\n css`\n :host {\n display: flex;\n flex-flow: row nowrap;\n align-items: center;\n\n box-sizing: border-box;\n\n width: 100%;\n height: 100%;\n\n border: 0;\n background-color: transparent;\n\n font: var(--grist-object-editor-font);\n color: var(--grist-object-editor-color);\n\n justify-content: inherit;\n }\n\n board-renderer {\n display: flex;\n flex: auto;\n\n justify-content: inherit;\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: Object }) column: any\n @property({ type: Object }) record: any\n @property({ type: Number }) row?: number\n\n popup\n\n render() {\n const { boardViewerPage } = this.column.record.options || {}\n return html`\n <board-renderer\n .value=${this.value}\n .boardViewerPage=${boardViewerPage}\n @click=${this.openSelector}\n ></board-renderer>\n `\n }\n\n async firstUpdated() {\n this.value = this.record[this.column.name]\n\n // await this.updateComplete\n\n // this.openSelector()\n }\n\n openSelector() {\n if (this.popup) {\n delete this.popup\n }\n\n /*\n * 기존 설정된 보드가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.\n * 주의. value는 object일 수도 있고, string일 수도 있다.\n * string인 경우에는 해당 보드의 id로 해석한다.\n */\n const value = this.value || {}\n\n const template = html`\n <ox-board-selector\n .creatable=${true}\n .value=${this.value}\n @board-selected=${async e => {\n const board = e.detail.board\n\n this.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: {\n before: this.value,\n after: this.column.type == 'board' ? board : board.id || '',\n record: this.record,\n column: this.column,\n row: this.row\n }\n })\n )\n\n this.popup && this.popup.close()\n }}\n ></ox-board-selector>\n `\n\n this.popup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('title.select board')\n })\n }\n}\n"]}
@@ -81,7 +81,7 @@ let BoardRendererElement = class BoardRendererElement extends LitElement {
81
81
  if (typeof this.value == 'string' && this.value) {
82
82
  /* fetchBoard..., */
83
83
  try {
84
- var response = await client.query({
84
+ const response = await client.query({
85
85
  query: FETCH_BOARD_GQL(this.value),
86
86
  context: gqlContext()
87
87
  });
@@ -97,7 +97,7 @@ let BoardRendererElement = class BoardRendererElement extends LitElement {
97
97
  }
98
98
  }
99
99
  render() {
100
- var { id, name = '', thumbnail = 'image/gif' } = this._value || {};
100
+ const { id, name = '', thumbnail = 'image/gif' } = this._value || {};
101
101
  return id
102
102
  ? html `
103
103
  <span>${name}</span>
@@ -111,7 +111,7 @@ let BoardRendererElement = class BoardRendererElement extends LitElement {
111
111
  onClickViewer(e, id) {
112
112
  e.preventDefault();
113
113
  e.stopPropagation();
114
- var boardViewerPage = this.boardViewerPage || 'board-viewer';
114
+ const boardViewerPage = this.boardViewerPage || 'board-viewer';
115
115
  navigate(`${boardViewerPage}/${id}${window.location.search}`);
116
116
  }
117
117
  onClickModeler(e, id) {
@@ -136,7 +136,7 @@ BoardRendererElement = __decorate([
136
136
  customElement('board-renderer')
137
137
  ], BoardRendererElement);
138
138
  export const BoardRenderer = (value, column, record) => {
139
- var { boardViewerPage = '' } = column.record.options || {};
139
+ const { boardViewerPage = '' } = column.record.options || {};
140
140
  return html ` <board-renderer .value=${value} .boardViewerPage=${boardViewerPage}></board-renderer> `;
141
141
  };
142
142
  //# sourceMappingURL=board-renderer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"board-renderer.js","sourceRoot":"","sources":["../../client/data-grist/board-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { navigate } from '@operato/shell'\nimport { client, gqlContext } from '@operato/graphql'\n\nconst FETCH_BOARD_GQL = id => {\n return gql`\n {\n board(id:\"${id}\") {\n id\n name\n description\n thumbnail\n }\n }\n`\n}\n\n@customElement('board-renderer')\nclass BoardRendererElement extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n justify-content: center;\n position: relative;\n\n max-width: var(--board-renderer-max-width);\n border: var(--board-renderer-border);\n\n width: 100%;\n }\n span {\n position: absolute;\n bottom: 0;\n width: 100%;\n text-indent: 5px;\n\n font: var(--board-renderer-name-font);\n color: var(--md-sys-color-on-primary);\n background-color: var(--md-sys-color-primary);\n }\n img {\n object-fit: contain;\n max-width: 100%;\n max-height: 100%;\n }\n md-icon {\n position: absolute;\n top: 0;\n text-align: center;\n color: var(--md-sys-color-on-primary);\n background-color: var(--md-sys-color-primary);\n\n width: var(--board-renderer-icon-size);\n height: var(--board-renderer-icon-size);\n font: var(--board-renderer-font);\n }\n\n md-icon:hover {\n background-color: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n cursor: pointer;\n }\n\n md-icon[edit] {\n right: 0;\n\n border-bottom-left-radius: var(--board-renderer-icon-border-radius);\n }\n\n md-icon[view] {\n left: 0;\n\n border-bottom-right-radius: var(--board-renderer-icon-border-radius);\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: String }) boardViewerPage?: string\n @property({ type: Object }) _value: any\n\n async updated(changes) {\n if (changes.has('value')) {\n if (typeof this.value == 'string' && this.value) {\n /* fetchBoard..., */\n try {\n var response = await client.query({\n query: FETCH_BOARD_GQL(this.value),\n context: gqlContext()\n })\n\n this._value = (response && response.data && response.data.board) || {}\n } catch (e) {\n console.error(e)\n }\n } else {\n this._value = this.value || {}\n }\n }\n }\n\n render() {\n var { id, name = '', thumbnail = 'image/gif' } = this._value || {}\n\n return id\n ? html`\n <span>${name}</span>\n <img src=${thumbnail} alt=\"no thumbnail!\" />\n\n <md-icon view @click=${e => this.onClickViewer(e, id)}>search</md-icon>\n <md-icon edit @click=${e => this.onClickModeler(e, id)}>edit</md-icon>\n `\n : html` choose board.. `\n }\n\n onClickViewer(e, id) {\n e.preventDefault()\n e.stopPropagation()\n\n var boardViewerPage = this.boardViewerPage || 'board-viewer'\n\n navigate(`${boardViewerPage}/${id}${window.location.search}`)\n }\n\n onClickModeler(e, id) {\n e.preventDefault()\n e.stopPropagation()\n\n navigate(`board-modeller/${id}${window.location.search}`)\n }\n}\n\nexport const BoardRenderer = (value, column, record) => {\n var { boardViewerPage = '' } = column.record.options || {}\n\n return html` <board-renderer .value=${value} .boardViewerPage=${boardViewerPage}></board-renderer> `\n}\n"]}
1
+ {"version":3,"file":"board-renderer.js","sourceRoot":"","sources":["../../client/data-grist/board-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { navigate } from '@operato/shell'\nimport { client, gqlContext } from '@operato/graphql'\n\nconst FETCH_BOARD_GQL = id => {\n return gql`\n {\n board(id:\"${id}\") {\n id\n name\n description\n thumbnail\n }\n }\n`\n}\n\n@customElement('board-renderer')\nclass BoardRendererElement extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n justify-content: center;\n position: relative;\n\n max-width: var(--board-renderer-max-width);\n border: var(--board-renderer-border);\n\n width: 100%;\n }\n span {\n position: absolute;\n bottom: 0;\n width: 100%;\n text-indent: 5px;\n\n font: var(--board-renderer-name-font);\n color: var(--md-sys-color-on-primary);\n background-color: var(--md-sys-color-primary);\n }\n img {\n object-fit: contain;\n max-width: 100%;\n max-height: 100%;\n }\n md-icon {\n position: absolute;\n top: 0;\n text-align: center;\n color: var(--md-sys-color-on-primary);\n background-color: var(--md-sys-color-primary);\n\n width: var(--board-renderer-icon-size);\n height: var(--board-renderer-icon-size);\n font: var(--board-renderer-font);\n }\n\n md-icon:hover {\n background-color: var(--md-sys-color-secondary-container);\n color: var(--md-sys-color-on-secondary-container);\n cursor: pointer;\n }\n\n md-icon[edit] {\n right: 0;\n\n border-bottom-left-radius: var(--board-renderer-icon-border-radius);\n }\n\n md-icon[view] {\n left: 0;\n\n border-bottom-right-radius: var(--board-renderer-icon-border-radius);\n }\n `\n ]\n\n @property({ type: Object }) value: any\n @property({ type: String }) boardViewerPage?: string\n @property({ type: Object }) _value: any\n\n async updated(changes) {\n if (changes.has('value')) {\n if (typeof this.value == 'string' && this.value) {\n /* fetchBoard..., */\n try {\n const response = await client.query({\n query: FETCH_BOARD_GQL(this.value),\n context: gqlContext()\n })\n\n this._value = (response && response.data && response.data.board) || {}\n } catch (e) {\n console.error(e)\n }\n } else {\n this._value = this.value || {}\n }\n }\n }\n\n render() {\n const { id, name = '', thumbnail = 'image/gif' } = this._value || {}\n\n return id\n ? html`\n <span>${name}</span>\n <img src=${thumbnail} alt=\"no thumbnail!\" />\n\n <md-icon view @click=${e => this.onClickViewer(e, id)}>search</md-icon>\n <md-icon edit @click=${e => this.onClickModeler(e, id)}>edit</md-icon>\n `\n : html` choose board.. `\n }\n\n onClickViewer(e, id) {\n e.preventDefault()\n e.stopPropagation()\n\n const boardViewerPage = this.boardViewerPage || 'board-viewer'\n\n navigate(`${boardViewerPage}/${id}${window.location.search}`)\n }\n\n onClickModeler(e, id) {\n e.preventDefault()\n e.stopPropagation()\n\n navigate(`board-modeller/${id}${window.location.search}`)\n }\n}\n\nexport const BoardRenderer = (value, column, record) => {\n const { boardViewerPage = '' } = column.record.options || {}\n\n return html` <board-renderer .value=${value} .boardViewerPage=${boardViewerPage}></board-renderer> `\n}\n"]}
@@ -0,0 +1,33 @@
1
+ export interface AttachmentResult {
2
+ id: string;
3
+ name: string;
4
+ mimetype?: string;
5
+ size?: number;
6
+ path?: string;
7
+ category?: string;
8
+ createdAt?: string;
9
+ }
10
+ /**
11
+ * 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.
12
+ * file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.
13
+ *
14
+ * board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.
15
+ */
16
+ export declare function createAttachmentForImport(file: File): Promise<AttachmentResult>;
17
+ /**
18
+ * 기존 attachment 목록 조회 — wizard upload 스텝의 "기존 파일 선택" 탭에서 사용.
19
+ * 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.
20
+ *
21
+ * @param search 파일명 부분 일치 (선택)
22
+ * @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용
23
+ * @param page / limit 페이지네이션 (기본 1, 50)
24
+ */
25
+ export declare function fetchAttachmentsForImport(options: {
26
+ search?: string;
27
+ mimetypePrefix?: string;
28
+ page?: number;
29
+ limit?: number;
30
+ }): Promise<{
31
+ items: AttachmentResult[];
32
+ total: number;
33
+ }>;
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Attachment GraphQL operations — board-import wizard 가 도면 파일 업로드 시 사용.
3
+ *
4
+ * 백엔드: @things-factory/attachment-base 의 createAttachment mutation.
5
+ * 별도 ox-attachment-list 의 흐름과 독립 — wizard 는 단순 file input → createAttachment
6
+ * → attachmentId 획득 → importBoardAsync 로 전달하는 짧은 흐름만 필요.
7
+ */
8
+ import gql from 'graphql-tag';
9
+ import { client } from '@operato/graphql';
10
+ /**
11
+ * 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.
12
+ * file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.
13
+ *
14
+ * board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.
15
+ */
16
+ export async function createAttachmentForImport(file) {
17
+ const response = await client.mutate({
18
+ mutation: gql `
19
+ mutation CreateAttachmentForImport($attachment: NewAttachment!) {
20
+ createAttachment(attachment: $attachment) {
21
+ id
22
+ name
23
+ mimetype
24
+ size
25
+ path
26
+ category
27
+ }
28
+ }
29
+ `,
30
+ variables: {
31
+ attachment: {
32
+ file,
33
+ category: 'import',
34
+ refType: 'board-import',
35
+ description: 'board-import wizard upload'
36
+ }
37
+ },
38
+ // multipart 업로드는 Apollo upload-link 가 처리. fetchPolicy 강제 무관.
39
+ context: {
40
+ hasUpload: true
41
+ }
42
+ });
43
+ return response.data.createAttachment;
44
+ }
45
+ /**
46
+ * 기존 attachment 목록 조회 — wizard upload 스텝의 "기존 파일 선택" 탭에서 사용.
47
+ * 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.
48
+ *
49
+ * @param search 파일명 부분 일치 (선택)
50
+ * @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용
51
+ * @param page / limit 페이지네이션 (기본 1, 50)
52
+ */
53
+ export async function fetchAttachmentsForImport(options) {
54
+ const filters = [];
55
+ if (options.search) {
56
+ filters.push({ name: 'name', operator: 'i_like', value: `%${options.search}%` });
57
+ }
58
+ if (options.mimetypePrefix) {
59
+ filters.push({ name: 'mimetype', operator: 'i_like', value: `${options.mimetypePrefix}%` });
60
+ }
61
+ const response = await client.query({
62
+ query: gql `
63
+ query AttachmentsForImport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
64
+ attachments(filters: $filters, pagination: $pagination, sortings: $sortings) {
65
+ items {
66
+ id
67
+ name
68
+ mimetype
69
+ size
70
+ path
71
+ category
72
+ createdAt
73
+ }
74
+ total
75
+ }
76
+ }
77
+ `,
78
+ variables: {
79
+ filters,
80
+ pagination: { page: options.page ?? 1, limit: options.limit ?? 50 },
81
+ sortings: [{ name: 'createdAt', desc: true }]
82
+ },
83
+ fetchPolicy: 'no-cache'
84
+ });
85
+ return response.data.attachments;
86
+ }
87
+ //# sourceMappingURL=attachment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../client/graphql/attachment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAYzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,IAAU;IACxD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;KAWZ;QACD,SAAS,EAAE;YACT,UAAU,EAAE;gBACV,IAAI;gBACJ,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,cAAc;gBACvB,WAAW,EAAE,4BAA4B;aAC1C;SACF;QACD,6DAA6D;QAC7D,OAAO,EAAE;YACP,SAAS,EAAE,IAAI;SAChB;KACF,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAA;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAK/C;IACC,MAAM,OAAO,GAA6D,EAAE,CAAA;IAC5E,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAClF,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,cAAc,GAAG,EAAE,CAAC,CAAA;IAC7F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;KAeT;QACD,SAAS,EAAE;YACT,OAAO;YACP,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE;YACnE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;SAC9C;QACD,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAA;AAClC,CAAC","sourcesContent":["/**\n * Attachment GraphQL operations — board-import wizard 가 도면 파일 업로드 시 사용.\n *\n * 백엔드: @things-factory/attachment-base 의 createAttachment mutation.\n * 별도 ox-attachment-list 의 흐름과 독립 — wizard 는 단순 file input → createAttachment\n * → attachmentId 획득 → importBoardAsync 로 전달하는 짧은 흐름만 필요.\n */\nimport gql from 'graphql-tag'\n\nimport { client } from '@operato/graphql'\n\nexport interface AttachmentResult {\n id: string\n name: string\n mimetype?: string\n size?: number\n path?: string\n category?: string\n createdAt?: string\n}\n\n/**\n * 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.\n * file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.\n *\n * board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.\n */\nexport async function createAttachmentForImport(file: File): Promise<AttachmentResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation CreateAttachmentForImport($attachment: NewAttachment!) {\n createAttachment(attachment: $attachment) {\n id\n name\n mimetype\n size\n path\n category\n }\n }\n `,\n variables: {\n attachment: {\n file,\n category: 'import',\n refType: 'board-import',\n description: 'board-import wizard upload'\n }\n },\n // multipart 업로드는 Apollo upload-link 가 처리. fetchPolicy 강제 무관.\n context: {\n hasUpload: true\n }\n })\n return response.data.createAttachment\n}\n\n/**\n * 기존 attachment 목록 조회 — wizard upload 스텝의 \"기존 파일 선택\" 탭에서 사용.\n * 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.\n *\n * @param search 파일명 부분 일치 (선택)\n * @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용\n * @param page / limit 페이지네이션 (기본 1, 50)\n */\nexport async function fetchAttachmentsForImport(options: {\n search?: string\n mimetypePrefix?: string\n page?: number\n limit?: number\n}): Promise<{ items: AttachmentResult[]; total: number }> {\n const filters: Array<{ name: string; operator: string; value: string }> = []\n if (options.search) {\n filters.push({ name: 'name', operator: 'i_like', value: `%${options.search}%` })\n }\n if (options.mimetypePrefix) {\n filters.push({ name: 'mimetype', operator: 'i_like', value: `${options.mimetypePrefix}%` })\n }\n const response = await client.query({\n query: gql`\n query AttachmentsForImport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n attachments(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n mimetype\n size\n path\n category\n createdAt\n }\n total\n }\n }\n `,\n variables: {\n filters,\n pagination: { page: options.page ?? 1, limit: options.limit ?? 50 },\n sortings: [{ name: 'createdAt', desc: true }]\n },\n fetchPolicy: 'no-cache'\n })\n return response.data.attachments\n}\n"]}
@@ -0,0 +1,45 @@
1
+ export interface ImportBoardAsyncInput {
2
+ attachmentId: string;
3
+ chatSessionId?: string;
4
+ scopes?: string[];
5
+ normalizeOrigin?: boolean;
6
+ flipY?: boolean;
7
+ scale?: number;
8
+ applyBinding?: boolean;
9
+ parseOptions?: any;
10
+ /**
11
+ * 사용자 자유서술 hint — 도면 설명 / 강조 부분 / 카테고리 가이드 등.
12
+ * VLM 의 view type 분류 + entity 추출에 추가 컨텍스트로 합류.
13
+ */
14
+ userPrompt?: string;
15
+ }
16
+ export declare function importBoardAsync(input: ImportBoardAsyncInput): Promise<any>;
17
+ export declare function fetchImportSession(id: string): Promise<any>;
18
+ export interface MaterializeImportSessionInput {
19
+ sessionId: string;
20
+ name: string;
21
+ description?: string;
22
+ groupId?: string;
23
+ type?: 'main' | 'sub' | 'popup';
24
+ thumbnail?: string;
25
+ /** 선택한 시안 id ('as-is' / 'scene' / 'auto-fit' 등). 미지정 시 default. */
26
+ variantId?: string;
27
+ }
28
+ /**
29
+ * 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.
30
+ * 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해
31
+ * 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.
32
+ */
33
+ export declare function suggestBoardMeta(input: {
34
+ sessionId?: string;
35
+ hint?: string;
36
+ }): Promise<{
37
+ name: string;
38
+ description: string;
39
+ }>;
40
+ /** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */
41
+ export declare function suggestBoardName(input: {
42
+ sessionId?: string;
43
+ hint?: string;
44
+ }): Promise<string>;
45
+ export declare function materializeImportSession(input: MaterializeImportSessionInput): Promise<any>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * board-import GraphQL operation client — wizard page 가 사용.
3
+ *
4
+ * 백엔드 정의: @things-factory/board-import 의 ImportSessionResolver.
5
+ * - importBoardAsync(input: ImportBoardAsyncInput!): ImportSession
6
+ * - importSession(id: String!): ImportSession
7
+ * - materializeImportSession(input: MaterializeImportSessionInput!): Board
8
+ */
9
+ import gql from 'graphql-tag';
10
+ import { client } from '@operato/graphql';
11
+ const IMPORT_SESSION_FIELDS = `
12
+ id
13
+ status
14
+ progress
15
+ message
16
+ totalEntities
17
+ options
18
+ result
19
+ attachmentId
20
+ chatSessionId
21
+ createdAt
22
+ updatedAt
23
+ completedAt
24
+ `;
25
+ export async function importBoardAsync(input) {
26
+ const response = await client.mutate({
27
+ mutation: gql `
28
+ mutation ImportBoardAsync($input: ImportBoardAsyncInput!) {
29
+ importBoardAsync(input: $input) {
30
+ ${IMPORT_SESSION_FIELDS}
31
+ }
32
+ }
33
+ `,
34
+ variables: { input }
35
+ });
36
+ return response.data?.importBoardAsync;
37
+ }
38
+ export async function fetchImportSession(id) {
39
+ const response = await client.query({
40
+ query: gql `
41
+ query ImportSession($id: String!) {
42
+ importSession(id: $id) {
43
+ ${IMPORT_SESSION_FIELDS}
44
+ }
45
+ }
46
+ `,
47
+ variables: { id },
48
+ // polling 시 cache 우회 — 매 호출마다 server fresh.
49
+ fetchPolicy: 'no-cache'
50
+ });
51
+ return response.data?.importSession;
52
+ }
53
+ /**
54
+ * 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.
55
+ * 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해
56
+ * 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.
57
+ */
58
+ export async function suggestBoardMeta(input) {
59
+ const response = await client.query({
60
+ query: gql `
61
+ query SuggestBoardMeta($input: SuggestBoardNameInput!) {
62
+ suggestBoardMeta(input: $input) {
63
+ name
64
+ description
65
+ }
66
+ }
67
+ `,
68
+ variables: { input },
69
+ fetchPolicy: 'no-cache'
70
+ });
71
+ return response.data?.suggestBoardMeta ?? { name: '', description: '' };
72
+ }
73
+ /** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */
74
+ export async function suggestBoardName(input) {
75
+ const response = await client.query({
76
+ query: gql `
77
+ query SuggestBoardName($input: SuggestBoardNameInput!) {
78
+ suggestBoardName(input: $input)
79
+ }
80
+ `,
81
+ variables: { input },
82
+ fetchPolicy: 'no-cache'
83
+ });
84
+ return response.data?.suggestBoardName ?? '';
85
+ }
86
+ export async function materializeImportSession(input) {
87
+ const response = await client.mutate({
88
+ mutation: gql `
89
+ mutation MaterializeImportSession($input: MaterializeImportSessionInput!) {
90
+ materializeImportSession(input: $input) {
91
+ id
92
+ name
93
+ description
94
+ state
95
+ sourceImportSessionId
96
+ createdAt
97
+ }
98
+ }
99
+ `,
100
+ variables: { input }
101
+ });
102
+ return response.data?.materializeImportSession;
103
+ }
104
+ //# sourceMappingURL=board-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-import.js","sourceRoot":"","sources":["../../client/graphql/board-import.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;CAa7B,CAAA;AAkBD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAA4B;IACjE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;YAGL,qBAAqB;;;KAG5B;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;KACrB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAU;IACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;YAGF,qBAAqB;;;KAG5B;QACD,SAAS,EAAE,EAAE,EAAE,EAAE;QACjB,4CAA4C;QAC5C,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;AACrC,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAGtC;IACC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;KAOT;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;QACpB,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAA;AACzE,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAGtC;IACC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;KAIT;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;QACpB,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,IAAI,EAAE,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,KAAoC;IACjF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;KAWZ;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;KACrB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAA;AAChD,CAAC","sourcesContent":["/**\n * board-import GraphQL operation client — wizard page 가 사용.\n *\n * 백엔드 정의: @things-factory/board-import 의 ImportSessionResolver.\n * - importBoardAsync(input: ImportBoardAsyncInput!): ImportSession\n * - importSession(id: String!): ImportSession\n * - materializeImportSession(input: MaterializeImportSessionInput!): Board\n */\nimport gql from 'graphql-tag'\n\nimport { client } from '@operato/graphql'\n\nconst IMPORT_SESSION_FIELDS = `\n id\n status\n progress\n message\n totalEntities\n options\n result\n attachmentId\n chatSessionId\n createdAt\n updatedAt\n completedAt\n`\n\nexport interface ImportBoardAsyncInput {\n attachmentId: string\n chatSessionId?: string\n scopes?: string[]\n normalizeOrigin?: boolean\n flipY?: boolean\n scale?: number\n applyBinding?: boolean\n parseOptions?: any\n /**\n * 사용자 자유서술 hint — 도면 설명 / 강조 부분 / 카테고리 가이드 등.\n * VLM 의 view type 분류 + entity 추출에 추가 컨텍스트로 합류.\n */\n userPrompt?: string\n}\n\nexport async function importBoardAsync(input: ImportBoardAsyncInput) {\n const response = await client.mutate({\n mutation: gql`\n mutation ImportBoardAsync($input: ImportBoardAsyncInput!) {\n importBoardAsync(input: $input) {\n ${IMPORT_SESSION_FIELDS}\n }\n }\n `,\n variables: { input }\n })\n return response.data?.importBoardAsync\n}\n\nexport async function fetchImportSession(id: string) {\n const response = await client.query({\n query: gql`\n query ImportSession($id: String!) {\n importSession(id: $id) {\n ${IMPORT_SESSION_FIELDS}\n }\n }\n `,\n variables: { id },\n // polling 시 cache 우회 — 매 호출마다 server fresh.\n fetchPolicy: 'no-cache'\n })\n return response.data?.importSession\n}\n\nexport interface MaterializeImportSessionInput {\n sessionId: string\n name: string\n description?: string\n groupId?: string\n type?: 'main' | 'sub' | 'popup'\n thumbnail?: string\n /** 선택한 시안 id ('as-is' / 'scene' / 'auto-fit' 등). 미지정 시 default. */\n variantId?: string\n}\n\n/**\n * 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.\n * 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해\n * 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.\n */\nexport async function suggestBoardMeta(input: {\n sessionId?: string\n hint?: string\n}): Promise<{ name: string; description: string }> {\n const response = await client.query({\n query: gql`\n query SuggestBoardMeta($input: SuggestBoardNameInput!) {\n suggestBoardMeta(input: $input) {\n name\n description\n }\n }\n `,\n variables: { input },\n fetchPolicy: 'no-cache'\n })\n return response.data?.suggestBoardMeta ?? { name: '', description: '' }\n}\n\n/** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */\nexport async function suggestBoardName(input: {\n sessionId?: string\n hint?: string\n}): Promise<string> {\n const response = await client.query({\n query: gql`\n query SuggestBoardName($input: SuggestBoardNameInput!) {\n suggestBoardName(input: $input)\n }\n `,\n variables: { input },\n fetchPolicy: 'no-cache'\n })\n return response.data?.suggestBoardName ?? ''\n}\n\nexport async function materializeImportSession(input: MaterializeImportSessionInput) {\n const response = await client.mutate({\n mutation: gql`\n mutation MaterializeImportSession($input: MaterializeImportSessionInput!) {\n materializeImportSession(input: $input) {\n id\n name\n description\n state\n sourceImportSessionId\n createdAt\n }\n }\n `,\n variables: { input }\n })\n return response.data?.materializeImportSession\n}\n"]}