@things-factory/board-ui 10.1.41 → 10.1.44

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 (81) hide show
  1. package/dist-client/board-list/board-thumb.d.ts +33 -0
  2. package/dist-client/board-list/board-thumb.js +119 -0
  3. package/dist-client/board-list/board-thumb.js.map +1 -0
  4. package/dist-client/graphql/favorite-board.js +3 -0
  5. package/dist-client/graphql/favorite-board.js.map +1 -1
  6. package/dist-client/graphql/my-board.js +3 -0
  7. package/dist-client/graphql/my-board.js.map +1 -1
  8. package/dist-client/graphql/play-group.js +2 -0
  9. package/dist-client/graphql/play-group.js.map +1 -1
  10. package/dist-client/index.d.ts +1 -0
  11. package/dist-client/index.js +1 -0
  12. package/dist-client/index.js.map +1 -1
  13. package/dist-client/pages/board-list-page.d.ts +39 -42
  14. package/dist-client/pages/board-list-page.js +388 -284
  15. package/dist-client/pages/board-list-page.js.map +1 -1
  16. package/dist-client/pages/board-modeller-page.d.ts +2 -0
  17. package/dist-client/pages/board-modeller-page.js +18 -1
  18. package/dist-client/pages/board-modeller-page.js.map +1 -1
  19. package/dist-client/pages/board-template/board-template-list-page.d.ts +21 -10
  20. package/dist-client/pages/board-template/board-template-list-page.js +147 -136
  21. package/dist-client/pages/board-template/board-template-list-page.js.map +1 -1
  22. package/dist-client/pages/play-list-page.d.ts +22 -12
  23. package/dist-client/pages/play-list-page.js +264 -113
  24. package/dist-client/pages/play-list-page.js.map +1 -1
  25. package/dist-client/route.d.ts +1 -1
  26. package/dist-client/setting-let/board-modeller-setting-let.d.ts +21 -0
  27. package/dist-client/setting-let/board-modeller-setting-let.js +144 -0
  28. package/dist-client/setting-let/board-modeller-setting-let.js.map +1 -0
  29. package/dist-client/styles/board-card-styles.d.ts +11 -0
  30. package/dist-client/styles/board-card-styles.js +90 -0
  31. package/dist-client/styles/board-card-styles.js.map +1 -0
  32. package/dist-client/themes/board-theme.css +32 -19
  33. package/dist-client/tsconfig.tsbuildinfo +1 -1
  34. package/dist-client/utils/board-meta.d.ts +10 -0
  35. package/dist-client/utils/board-meta.js +34 -0
  36. package/dist-client/utils/board-meta.js.map +1 -0
  37. package/dist-client/viewparts/board-basic-info.d.ts +38 -7
  38. package/dist-client/viewparts/board-basic-info.js +378 -349
  39. package/dist-client/viewparts/board-basic-info.js.map +1 -1
  40. package/dist-client/viewparts/board-info-link.d.ts +5 -1
  41. package/dist-client/viewparts/board-info-link.js +79 -21
  42. package/dist-client/viewparts/board-info-link.js.map +1 -1
  43. package/dist-client/viewparts/board-info-template.d.ts +15 -0
  44. package/dist-client/viewparts/board-info-template.js +97 -0
  45. package/dist-client/viewparts/board-info-template.js.map +1 -0
  46. package/dist-client/viewparts/board-info.d.ts +5 -0
  47. package/dist-client/viewparts/board-info.js +24 -73
  48. package/dist-client/viewparts/board-info.js.map +1 -1
  49. package/dist-client/viewparts/board-template-builder.d.ts +1 -0
  50. package/dist-client/viewparts/board-template-builder.js +37 -65
  51. package/dist-client/viewparts/board-template-builder.js.map +1 -1
  52. package/dist-client/viewparts/board-template-info.d.ts +3 -0
  53. package/dist-client/viewparts/board-template-info.js +75 -134
  54. package/dist-client/viewparts/board-template-info.js.map +1 -1
  55. package/dist-client/viewparts/group-info-basic.d.ts +8 -3
  56. package/dist-client/viewparts/group-info-basic.js +54 -190
  57. package/dist-client/viewparts/group-info-basic.js.map +1 -1
  58. package/dist-client/viewparts/group-info-import.d.ts +3 -1
  59. package/dist-client/viewparts/group-info-import.js +29 -62
  60. package/dist-client/viewparts/group-info-import.js.map +1 -1
  61. package/dist-client/viewparts/group-info.d.ts +4 -0
  62. package/dist-client/viewparts/group-info.js +21 -55
  63. package/dist-client/viewparts/group-info.js.map +1 -1
  64. package/dist-client/viewparts/info-dialog-styles.d.ts +19 -0
  65. package/dist-client/viewparts/info-dialog-styles.js +194 -0
  66. package/dist-client/viewparts/info-dialog-styles.js.map +1 -0
  67. package/dist-client/viewparts/link-builder.d.ts +3 -0
  68. package/dist-client/viewparts/link-builder.js +87 -81
  69. package/dist-client/viewparts/link-builder.js.map +1 -1
  70. package/dist-client/viewparts/play-group-info-basic.d.ts +4 -3
  71. package/dist-client/viewparts/play-group-info-basic.js +49 -188
  72. package/dist-client/viewparts/play-group-info-basic.js.map +1 -1
  73. package/dist-client/viewparts/play-group-info.d.ts +4 -0
  74. package/dist-client/viewparts/play-group-info.js +22 -53
  75. package/dist-client/viewparts/play-group-info.js.map +1 -1
  76. package/package.json +6 -6
  77. package/translations/en.json +30 -0
  78. package/translations/ja.json +9 -0
  79. package/translations/ko.json +35 -5
  80. package/translations/ms.json +8 -1
  81. package/translations/zh.json +9 -0
@@ -1,181 +1,164 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import '@operato/data-grist';
3
3
  import '@operato/board/ox-board-template-viewer.js';
4
+ import '@material/web/icon/icon.js';
5
+ import '../../board-list/board-thumb.js';
4
6
  import '../../viewparts/board-template-info.js';
5
- import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
6
- import { PageView } from '@operato/shell';
7
+ import gql from 'graphql-tag';
7
8
  import { css, html } from 'lit';
8
9
  import { customElement, property, query, state } from 'lit/decorators.js';
9
- import { ScopedElementsMixin } from '@open-wc/scoped-elements';
10
10
  import { DataGrist } from '@operato/data-grist';
11
11
  import { client } from '@operato/graphql';
12
12
  import { i18next, localize } from '@operato/i18n';
13
- import gql from 'graphql-tag';
14
- import { openPopup, openOverlay } from '@operato/layout';
15
- let BoardTemplateListPage = class BoardTemplateListPage extends localize(i18next)(ScopedElementsMixin(PageView)) {
13
+ import { openPopup } from '@operato/layout';
14
+ import { PageView } from '@operato/shell';
15
+ import { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles';
16
+ import { BoardCardStyles } from '../../styles/board-card-styles.js';
17
+ import { timeAgo } from '../../utils/board-meta.js';
18
+ const BoardTemplateListPageBase = localize(i18next)(PageView);
19
+ /**
20
+ * The template catalog - the same card as board-list-page.ts and play-list-page.ts (shared through
21
+ * styles/board-card-styles.ts), because a template *is* a board, only one you start from rather
22
+ * than one you run. Clicking a card previews it; the one gutter action opens the info overlay.
23
+ *
24
+ * A template is made from inside the modeller ("save as template"), never from here, so there is
25
+ * no create FAB on this page.
26
+ */
27
+ let BoardTemplateListPage = class BoardTemplateListPage extends BoardTemplateListPageBase {
16
28
  constructor() {
17
29
  super(...arguments);
18
30
  this.visibility = '';
19
31
  }
20
32
  static { this.styles = [
21
- /* The work surface frame for a list screen (ADR-0060 decision 8). */
33
+ /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */
22
34
  WorkSurfacePageStyles,
23
35
  ScrollbarStyles,
24
36
  CommonGristStyles,
25
37
  CommonHeaderStyles,
38
+ /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */
39
+ BoardCardStyles,
26
40
  css `
27
- :host {
28
- --grid-record-emphasized-background-color: #8b0000;
29
- --grid-record-emphasized-color: #ff6b6b;
41
+ ox-filters-form {
42
+ flex: 1;
30
43
  }
31
-
32
- ox-filters-form { flex: 1;
33
- }
34
44
  `
35
45
  ]; }
36
46
  get context() {
37
- return { title: i18next.t('title.board-template list'),
38
- search: { handler: (search) => {
47
+ return {
48
+ /* A plain name, no icon - the rail already carries the icon for this screen. */
49
+ title: i18next.t('title.board-template list', { defaultValue: 'Board Template List' }),
50
+ search: {
51
+ placeholder: i18next.t('text.search templates by name', { defaultValue: 'Search templates by name' }),
52
+ handler: (search) => {
39
53
  this.grist.searchText = search;
40
54
  },
41
- value: this.grist?.searchText || '' },
42
- filter: { handler: () => {
43
- this.grist.toggleHeadroom();
44
- }
55
+ value: this.grist?.searchText || ''
45
56
  },
46
- board_topmenu: true,
47
- help: 'board-service/board-template' };
57
+ board_topmenu: true
58
+ };
48
59
  }
49
60
  render() {
50
61
  return html `
51
62
  <ox-grist class="page-fill" mode="CARD" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
52
- <div slot="headroom" class="header">
53
- <div class="filters">
54
- <ox-filters-form autofocus without-search></ox-filters-form>
55
- </div>
63
+ <div slot="headroom">
64
+ <ox-filters-form autofocus without-search></ox-filters-form>
56
65
  </div>
57
66
  </ox-grist>
58
67
  `;
59
68
  }
60
- async pageInitialized(lifecycle) {
61
- this.gristConfig = { list: { thumbnail: 'thumbnail',
62
- fields: ['name', 'description'],
63
- details: ['visibility', 'creator', 'createdAt']
69
+ async pageInitialized() {
70
+ this.gristConfig = {
71
+ list: {
72
+ thumbnail: 'thumbnail',
73
+ /* name, then a quieter "public · who · when" line - the same two-line rhythm as board-list. */
74
+ fields: ['name', 'meta'],
75
+ details: []
64
76
  },
65
77
  columns: [
66
- { type: 'gutter', gutterName: 'sequence' },
67
- { type: 'gutter',
68
- gutterName: 'button',
69
- icon: 'info',
70
- iconOnly: false,
71
- title: '상세정보',
72
- width: 80,
73
- handlers: { click: (columns, data, column, record, rowIndex) => {
74
- this.onShowInfo(record);
75
- }
78
+ {
79
+ type: 'image',
80
+ name: 'thumbnail',
81
+ record: {
82
+ editable: false,
83
+ align: 'center',
84
+ renderEmpty: true,
85
+ /* board-thumb.ts draws the picture; badge="" because a template has no draft state.
86
+ * The description rides along as the picture's tooltip - a template's one-line
87
+ * purpose is worth having on hover without spending a third line on every card. */
88
+ renderer: (_value, _column, record) => html `<board-thumb .board=${record} badge="" title=${record.description || ''}></board-thumb>`
76
89
  }
77
90
  },
78
- { type: 'string',
91
+ {
92
+ type: 'string',
79
93
  name: 'name',
80
- header: i18next.t('field.name'),
81
- record: { editable: false
82
- },
94
+ record: { editable: false },
83
95
  filter: 'search',
84
- sortable: true,
85
- width: 150
96
+ sortable: true
86
97
  },
87
- { type: 'string',
88
- name: 'description',
89
- header: i18next.t('field.description'),
90
- record: { editable: false
91
- },
92
- filter: 'search',
93
- width: 200
98
+ {
99
+ type: 'string',
100
+ name: 'meta',
101
+ record: { editable: false }
94
102
  },
95
- { type: 'boolean',
96
- name: 'mine',
97
- record: { editable: false
98
- },
103
+ {
104
+ type: 'string',
105
+ name: 'description',
99
106
  hidden: true,
100
- width: 0
101
- },
102
- { type: 'select-buttons',
103
- name: 'visibility',
104
- header: i18next.t('field.visibility'),
105
- label: true,
106
- record: { editable: false
107
- },
108
- filter: { operator: 'in',
109
- options: ['private', 'public', 'domain'],
110
- value: this.visibility,
111
- label: '' /* empty intentionally */
112
- },
113
- width: 200
114
- },
115
- { type: 'string',
116
- name: 'tags',
117
- header: i18next.t('field.tags'),
118
- label: true,
119
- record: { renderer: (value, column, record, rowIndex, field) => (value || []).join(', '),
120
- editable: false
121
- },
122
- width: 200
107
+ record: { editable: false },
108
+ filter: 'search'
123
109
  },
124
- { type: 'image',
125
- name: 'thumbnail',
126
- header: i18next.t('field.thumbnail'),
127
- record: { editable: false,
128
- align: 'center',
129
- wide: true
130
- },
131
- width: 200
132
- },
133
- { type: 'resource-object',
134
- name: 'creator',
135
- header: i18next.t('field.creator'),
136
- label: true,
137
- record: { editable: false
138
- },
139
- sortable: true,
140
- width: 120
110
+ {
111
+ type: 'gutter',
112
+ gutterName: 'button',
113
+ name: 'info',
114
+ icon: 'edit',
115
+ quiet: true,
116
+ title: i18next.t('label.edit', { defaultValue: 'Edit' }),
117
+ handlers: {
118
+ click: (_columns, _data, _column, record) => this.onShowInfo(record)
119
+ }
141
120
  },
142
- { type: 'datetime',
143
- name: 'createdAt',
144
- header: i18next.t('field.created_at'),
145
- label: true,
146
- record: { editable: false
147
- },
148
- sortable: true,
149
- width: 180
121
+ /* Visibility is a chip facet, the way board-list's type/state are. Nothing pressed means
122
+ * all three - the server only narrows when the filter carries a value. */
123
+ {
124
+ type: 'select-buttons',
125
+ name: 'visibility',
126
+ header: i18next.t('field.visibility', { defaultValue: 'Visibility' }),
127
+ record: { editable: false },
128
+ filter: {
129
+ operator: 'in',
130
+ value: [],
131
+ label: '',
132
+ options: [
133
+ { display: this.visibilityLabel('private'), value: 'private' },
134
+ { display: this.visibilityLabel('domain'), value: 'domain' },
135
+ { display: this.visibilityLabel('public'), value: 'public' }
136
+ ]
137
+ }
150
138
  }
151
139
  ],
152
- rows: { selectable: false,
140
+ rows: {
141
+ selectable: false,
153
142
  appendable: false,
154
- handlers: { click: (_columns, _data, _column, record, _rowIndex) => {
155
- const boardTemplate = { ...record,
156
- model: JSON.parse(record.model)
157
- };
158
- openPopup(html ` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, { backdrop: true,
159
- size: 'large',
160
- title: i18next.t('label.board-template')
161
- });
162
- }
143
+ handlers: {
144
+ click: (_columns, _data, _column, record) => this.onPreview(record)
163
145
  }
164
146
  },
165
- sorters: [
166
- { name: 'name'
167
- }
168
- ]
147
+ sorters: [{ name: 'name' }]
169
148
  };
170
149
  }
171
- async pageUpdated(changes, lifecycle) {
150
+ async pageUpdated() {
172
151
  if (this.active) {
173
- this.grist.fetch();
152
+ this.grist?.fetch();
174
153
  }
175
154
  }
176
- async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }) {
177
- const response = await client.query({ query: gql `
178
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id
155
+ async fetchHandler({ page = 1, limit = 24, sortings = [], filters = [] }) {
156
+ const response = await client.query({
157
+ query: gql `
158
+ query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
159
+ responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) {
160
+ items {
161
+ id
179
162
  name
180
163
  description
181
164
  model
@@ -183,34 +166,62 @@ let BoardTemplateListPage = class BoardTemplateListPage extends localize(i18next
183
166
  visibility
184
167
  tags
185
168
  mine
186
- creator { id
169
+ creator {
170
+ id
187
171
  username
188
172
  name
189
- }
173
+ }
190
174
  createdAt
191
- }
175
+ updatedAt
176
+ }
192
177
  total
193
- }
194
- }
178
+ }
179
+ }
195
180
  `,
196
- variables: { filters,
181
+ variables: {
182
+ /* An empty chip strip would otherwise be sent as `in []` and match nothing. */
183
+ filters: filters.filter(f => !(Array.isArray(f.value) && f.value.length === 0)),
197
184
  pagination: { page, limit },
198
185
  sortings
199
186
  }
200
187
  });
201
- return { total: response.data.responses.total || 0,
202
- records: response.data.responses.items || []
188
+ const records = (response.data.responses.items || []).map(template => ({
189
+ ...template,
190
+ meta: this.templateMeta(template)
191
+ }));
192
+ return {
193
+ total: response.data.responses.total || 0,
194
+ records
195
+ };
196
+ }
197
+ /** "public · Hearty · 3 days ago" - who can see it, who made it, how fresh. */
198
+ templateMeta(template) {
199
+ return [this.visibilityLabel(template.visibility), template.creator?.name, timeAgo(template.updatedAt || template.createdAt)]
200
+ .filter(part => !!part)
201
+ .join(' · ');
202
+ }
203
+ visibilityLabel(visibility) {
204
+ return i18next.t(`label.visibility-${visibility}`, { defaultValue: visibility });
205
+ }
206
+ onPreview(record) {
207
+ const boardTemplate = {
208
+ ...record,
209
+ model: JSON.parse(record.model)
203
210
  };
211
+ openPopup(html ` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, {
212
+ backdrop: true,
213
+ size: 'large',
214
+ title: record.name
215
+ });
204
216
  }
205
- async onShowInfo(template) {
206
- openOverlay('viewpart-info', { template: html `
217
+ onShowInfo(template) {
218
+ openPopup(html `
207
219
  <board-template-info
208
- .template=${template}
220
+ .template=${{ ...template }}
209
221
  @updated=${() => this.grist.fetch()}
210
222
  @deleted=${() => this.grist.fetch()}
211
223
  ></board-template-info>
212
- `
213
- });
224
+ `, { backdrop: true, size: 'small', closable: true, title: template.name });
214
225
  }
215
226
  };
216
227
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"board-template-list-page.js","sourceRoot":"","sources":["../../../client/pages/board-template/board-template-list-page.ts"],"names":[],"mappings":";AAAA,OAAO,qBAAqB,CAAA;AAC5B,OAAO,4CAA4C,CAAA;AACnD,OAAO,wCAAwC,CAAA;AAE/C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAC/G,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAC/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,SAAS,EAAe,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAEjD,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGjD,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,QAAQ,CAAC,OAAO,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAApF;;QAkBI,eAAU,GAAW,EAAE,CAAA;IAqLlC,CAAC;aAvMsG,WAAM,GAAG;QAC5G,qEAAqE;QACrE,qBAAqB;QACrB,eAAe;QACf,iBAAiB;QACjB,kBAAkB;QAClB,GAAG,CAAA;;;;;;;;KAQF;KACF,AAf0G,CAe1G;IAOD,IAAI,OAAO;QAAS,OAAO,EAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;YAC5E,MAAM,EAAE,EAAU,OAAO,EAAE,CAAC,MAAc,EAAE,EAAE;oBAAa,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,CAAA;gBAC9F,CAAC;gBACM,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,IAAI,EAAE,EACzC;YACI,MAAM,EAAE,EAAU,OAAO,EAAE,GAAG,EAAE;oBAAa,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAA;gBAC7E,CAAC;aACA;YACI,aAAa,EAAE,IAAI;YACnB,IAAI,EAAE,8BAA8B,EACxC,CAAA;IACD,CAAC;IAEA,MAAM;QAAS,OAAO,IAAI,CAAA;wDAC4B,IAAI,CAAC,WAAW,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;KAOjH,CAAA;IACJ,CAAC;IAEA,KAAK,CAAC,eAAe,CAAC,SAAc;QAAQ,IAAI,CAAC,WAAW,GAAG,EAAQ,IAAI,EAAE,EAAU,SAAS,EAAE,WAAW;gBACvG,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC;gBAC/B,OAAO,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,WAAW,CAAC;aACrD;YACI,OAAO,EAAE;gBACP,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE;gBAC1C,EAAY,IAAI,EAAE,QAAQ;oBACxB,UAAU,EAAE,QAAQ;oBACpB,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,KAAK;oBACf,KAAK,EAAE,MAAM;oBACb,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,EAAc,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;4BAAiB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;wBAC5H,CAAC;qBACA;iBACA;gBACM,EAAY,IAAI,EAAE,QAAQ;oBACxB,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,MAAM,EAAE,QAAQ;oBAChB,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,QAAQ;oBACxB,IAAI,EAAE,aAAa;oBACnB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;oBACtC,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,SAAS;oBACzB,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,CAAC;iBAChB;gBACM,EAAY,IAAI,EAAE,gBAAgB;oBAChC,IAAI,EAAE,YAAY;oBAClB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACrC,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,MAAM,EAAE,EAAc,QAAQ,EAAE,IAAI;wBAClC,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;wBACxC,KAAK,EAAE,IAAI,CAAC,UAAU;wBACtB,KAAK,EAAE,EAAE,CAAC,yBAAyB;qBAC7C;oBACQ,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,QAAQ;oBACxB,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,EAAc,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;wBAClG,QAAQ,EAAE,KAAK;qBACzB;oBACQ,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,OAAO;oBACvB,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;oBACpC,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;wBACnC,KAAK,EAAE,QAAQ;wBACf,IAAI,EAAE,IAAI;qBACpB;oBACQ,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,iBAAiB;oBACjC,IAAI,EAAE,SAAS;oBACf,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;oBAClC,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;gBACM,EAAY,IAAI,EAAE,UAAU;oBAC1B,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;oBACrC,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,EAAc,QAAQ,EAAE,KAAK;qBAC7C;oBACQ,QAAQ,EAAE,IAAI;oBACd,KAAK,EAAE,GAAG;iBAClB;aACK;YACD,IAAI,EAAE,EAAU,UAAU,EAAE,KAAK;gBAC/B,UAAU,EAAE,KAAK;gBACjB,QAAQ,EAAE,EAAY,KAAK,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;wBAAe,MAAM,aAAa,GAAG,EAAgB,GAAG,MAAM;4BACrI,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;yBAC3C,CAAA;wBAEU,SAAS,CAAC,IAAI,CAAA,6CAA6C,aAAa,+BAA+B,EAAE,EAAgB,QAAQ,EAAE,IAAI;4BACrI,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;yBACpD,CAAC,CAAA;oBACF,CAAC;iBACA;aACA;YACI,OAAO,EAAE;gBACP,EAAY,IAAI,EAAE,MAAM;iBAC9B;aACK;SACL,CAAA;IACD,CAAC;IAEA,KAAK,CAAC,WAAW,CAAC,OAAY,EAAE,SAAc;QAAQ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAA;QAClG,CAAC;IACD,CAAC;IAEA,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAe;QAAQ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,EAAQ,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;;;;OAkB/I;YACD,SAAS,EAAE,EAAU,OAAO;gBAC1B,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;gBAC3B,QAAQ;aACd;SACA,CAAC,CAAA;QAEC,OAAO,EAAQ,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC;YACtD,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;SAChD,CAAA;IACD,CAAC;IAEA,KAAK,CAAC,UAAU,CAAC,QAAQ;QAAQ,WAAW,CAAC,eAAe,EAAE,EAAQ,QAAQ,EAAE,IAAI,CAAA;;sBAEhE,QAAQ;qBACT,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;qBACxB,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;;OAEtC;SACL,CAAC,CAAA;IACF,CAAC;;AArL4B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0DAAiB;AACnC;IAAR,KAAK,EAAE;;yDAAwB;AAEL;IAA1B,KAAK,CAAC,UAAU,CAAC;8BAAiB,SAAS;oDAAA;AApBjC,qBAAqB;IADjC,aAAa,CAAC,0BAA0B,CAAC;GAC7B,qBAAqB,CAuMjC","sourcesContent":["import '@operato/data-grist'\nimport '@operato/board/ox-board-template-viewer.js'\nimport '../../viewparts/board-template-info.js'\n\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\nimport { PageView } from '@operato/shell'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { ScopedElementsMixin } from '@open-wc/scoped-elements'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\n\nimport gql from 'graphql-tag'\nimport { openPopup, openOverlay } from '@operato/layout'\n\n@customElement('board-template-list-page')\nexport class BoardTemplateListPage extends localize(i18next)(ScopedElementsMixin(PageView)) { static styles = [\n /* The work surface frame for a list screen (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n css`\n :host {\n --grid-record-emphasized-background-color: #8b0000;\n --grid-record-emphasized-color: #ff6b6b;\n }\n\n ox-filters-form { flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @state() visibility: string = ''\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() { return { title: i18next.t('title.board-template list'),\n search: { handler: (search: string) => { this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n filter: { handler: () => { this.grist.toggleHeadroom()\n }\n },\n board_topmenu: true,\n help: 'board-service/board-template'\n }\n }\n\n render() { return html`\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\" class=\"header\">\n <div class=\"filters\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized(lifecycle: any) { this.gristConfig = { list: { thumbnail: 'thumbnail',\n fields: ['name', 'description'],\n details: ['visibility', 'creator', 'createdAt']\n },\n columns: [\n { type: 'gutter', gutterName: 'sequence' },\n { type: 'gutter',\n gutterName: 'button',\n icon: 'info',\n iconOnly: false,\n title: '상세정보',\n width: 80,\n handlers: { click: (columns, data, column, record, rowIndex) => { this.onShowInfo(record)\n }\n }\n },\n { type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n record: { editable: false\n },\n filter: 'search',\n sortable: true,\n width: 150\n },\n { type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n record: { editable: false\n },\n filter: 'search',\n width: 200\n },\n { type: 'boolean',\n name: 'mine',\n record: { editable: false\n },\n hidden: true,\n width: 0\n },\n { type: 'select-buttons',\n name: 'visibility',\n header: i18next.t('field.visibility'),\n label: true,\n record: { editable: false\n },\n filter: { operator: 'in',\n options: ['private', 'public', 'domain'],\n value: this.visibility,\n label: '' /* empty intentionally */\n },\n width: 200\n },\n { type: 'string',\n name: 'tags',\n header: i18next.t('field.tags'),\n label: true,\n record: { renderer: (value, column, record, rowIndex, field) => (value || []).join(', '),\n editable: false\n },\n width: 200\n },\n { type: 'image',\n name: 'thumbnail',\n header: i18next.t('field.thumbnail'),\n record: { editable: false,\n align: 'center',\n wide: true\n },\n width: 200\n },\n { type: 'resource-object',\n name: 'creator',\n header: i18next.t('field.creator'),\n label: true,\n record: { editable: false\n },\n sortable: true,\n width: 120\n },\n { type: 'datetime',\n name: 'createdAt',\n header: i18next.t('field.created_at'),\n label: true,\n record: { editable: false\n },\n sortable: true,\n width: 180\n }\n ],\n rows: { selectable: false,\n appendable: false,\n handlers: { click: (_columns, _data, _column, record, _rowIndex) => { const boardTemplate = { ...record,\n model: JSON.parse(record.model)\n }\n\n openPopup(html` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, { backdrop: true,\n size: 'large',\n title: i18next.t('label.board-template')\n })\n }\n }\n },\n sorters: [\n { name: 'name'\n }\n ]\n }\n }\n\n async pageUpdated(changes: any, lifecycle: any) { if (this.active) { this.grist.fetch()\n }\n }\n\n async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) { const response = await client.query({ query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) { responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) { items { id\n name\n description\n model\n thumbnail\n visibility\n tags\n mine\n creator { id\n username\n name\n }\n createdAt\n }\n total\n }\n }\n `,\n variables: { filters,\n pagination: { page, limit },\n sortings\n }\n })\n\n return { total: response.data.responses.total || 0,\n records: response.data.responses.items || []\n }\n }\n\n async onShowInfo(template) { openOverlay('viewpart-info', { template: html`\n <board-template-info\n .template=${template}\n @updated=${() => this.grist.fetch()}\n @deleted=${() => this.grist.fetch()}\n ></board-template-info>\n `\n })\n }\n}\n"]}
1
+ {"version":3,"file":"board-template-list-page.js","sourceRoot":"","sources":["../../../client/pages/board-template/board-template-list-page.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/data-grist'\nimport '@operato/board/ox-board-template-viewer.js'\nimport '@material/web/icon/icon.js'\nimport '../../board-list/board-thumb.js'\nimport '../../viewparts/board-template-info.js'\n\nimport gql from 'graphql-tag'\nimport { css, html } from 'lit'\nimport { customElement, property, query, state } from 'lit/decorators.js'\nimport { DataGrist, FetchOption } from '@operato/data-grist'\nimport { client } from '@operato/graphql'\nimport { i18next, localize } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\nimport { PageView } from '@operato/shell'\nimport { CommonGristStyles, CommonHeaderStyles, ScrollbarStyles, WorkSurfacePageStyles } from '@operato/styles'\n\nimport { BoardCardStyles } from '../../styles/board-card-styles.js'\nimport { timeAgo } from '../../utils/board-meta.js'\n\nconst BoardTemplateListPageBase = localize(i18next)(PageView) as typeof PageView\n\n/**\n * The template catalog - the same card as board-list-page.ts and play-list-page.ts (shared through\n * styles/board-card-styles.ts), because a template *is* a board, only one you start from rather\n * than one you run. Clicking a card previews it; the one gutter action opens the info overlay.\n *\n * A template is made from inside the modeller (\"save as template\"), never from here, so there is\n * no create FAB on this page.\n */\n@customElement('board-template-list-page')\nexport class BoardTemplateListPage extends BoardTemplateListPageBase {\n static styles = [\n /* The frame owns the page shell; the grist is the content it sizes (ADR-0060 decision 8). */\n WorkSurfacePageStyles,\n ScrollbarStyles,\n CommonGristStyles,\n CommonHeaderStyles,\n /* The card itself - shared with the other catalogs, see styles/board-card-styles.ts. */\n BoardCardStyles,\n css`\n ox-filters-form {\n flex: 1;\n }\n `\n ]\n\n @property({ type: Object }) gristConfig: any\n @state() visibility: string = ''\n\n @query('ox-grist') private grist!: DataGrist\n\n get context() {\n return {\n /* A plain name, no icon - the rail already carries the icon for this screen. */\n title: i18next.t('title.board-template list', { defaultValue: 'Board Template List' }),\n search: {\n placeholder: i18next.t('text.search templates by name', { defaultValue: 'Search templates by name' }),\n handler: (search: string) => {\n this.grist.searchText = search\n },\n value: this.grist?.searchText || ''\n },\n board_topmenu: true\n }\n }\n\n render() {\n return html`\n <ox-grist class=\"page-fill\" mode=\"CARD\" .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>\n <div slot=\"headroom\">\n <ox-filters-form autofocus without-search></ox-filters-form>\n </div>\n </ox-grist>\n `\n }\n\n async pageInitialized() {\n this.gristConfig = {\n list: {\n thumbnail: 'thumbnail',\n /* name, then a quieter \"public · who · when\" line - the same two-line rhythm as board-list. */\n fields: ['name', 'meta'],\n details: []\n },\n columns: [\n {\n type: 'image',\n name: 'thumbnail',\n record: {\n editable: false,\n align: 'center',\n renderEmpty: true,\n /* board-thumb.ts draws the picture; badge=\"\" because a template has no draft state.\n * The description rides along as the picture's tooltip - a template's one-line\n * purpose is worth having on hover without spending a third line on every card. */\n renderer: (_value, _column, record) =>\n html`<board-thumb .board=${record} badge=\"\" title=${record.description || ''}></board-thumb>`\n }\n },\n {\n type: 'string',\n name: 'name',\n record: { editable: false },\n filter: 'search',\n sortable: true\n },\n {\n type: 'string',\n name: 'meta',\n record: { editable: false }\n },\n {\n type: 'string',\n name: 'description',\n hidden: true,\n record: { editable: false },\n filter: 'search'\n },\n {\n type: 'gutter',\n gutterName: 'button',\n name: 'info',\n icon: 'edit',\n quiet: true,\n title: i18next.t('label.edit', { defaultValue: 'Edit' }),\n handlers: {\n click: (_columns, _data, _column, record) => this.onShowInfo(record)\n }\n },\n /* Visibility is a chip facet, the way board-list's type/state are. Nothing pressed means\n * all three - the server only narrows when the filter carries a value. */\n {\n type: 'select-buttons',\n name: 'visibility',\n header: i18next.t('field.visibility', { defaultValue: 'Visibility' }),\n record: { editable: false },\n filter: {\n operator: 'in',\n value: [],\n label: '',\n options: [\n { display: this.visibilityLabel('private'), value: 'private' },\n { display: this.visibilityLabel('domain'), value: 'domain' },\n { display: this.visibilityLabel('public'), value: 'public' }\n ]\n }\n }\n ],\n rows: {\n selectable: false,\n appendable: false,\n handlers: {\n click: (_columns, _data, _column, record) => this.onPreview(record)\n }\n },\n sorters: [{ name: 'name' }]\n }\n }\n\n async pageUpdated() {\n if (this.active) {\n this.grist?.fetch()\n }\n }\n\n async fetchHandler({ page = 1, limit = 24, sortings = [], filters = [] }: FetchOption) {\n const response = await client.query({\n query: gql`\n query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n responses: boardTemplates(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n description\n model\n thumbnail\n visibility\n tags\n mine\n creator {\n id\n username\n name\n }\n createdAt\n updatedAt\n }\n total\n }\n }\n `,\n variables: {\n /* An empty chip strip would otherwise be sent as `in []` and match nothing. */\n filters: filters.filter(f => !(Array.isArray(f.value) && f.value.length === 0)),\n pagination: { page, limit },\n sortings\n }\n })\n\n const records = (response.data.responses.items || []).map(template => ({\n ...template,\n meta: this.templateMeta(template)\n }))\n\n return {\n total: response.data.responses.total || 0,\n records\n }\n }\n\n /** \"public · Hearty · 3 days ago\" - who can see it, who made it, how fresh. */\n private templateMeta(template: any): string {\n return [this.visibilityLabel(template.visibility), template.creator?.name, timeAgo(template.updatedAt || template.createdAt)]\n .filter(part => !!part)\n .join(' · ')\n }\n\n private visibilityLabel(visibility: string): string {\n return i18next.t(`label.visibility-${visibility}`, { defaultValue: visibility })\n }\n\n private onPreview(record: any) {\n const boardTemplate = {\n ...record,\n model: JSON.parse(record.model)\n }\n\n openPopup(html` <ox-board-template-viewer .boardTemplate=${boardTemplate}></ox-board-template-viewer> `, {\n backdrop: true,\n size: 'large',\n title: record.name\n })\n }\n\n private onShowInfo(template: any) {\n openPopup(\n html`\n <board-template-info\n .template=${{ ...template }}\n @updated=${() => this.grist.fetch()}\n @deleted=${() => this.grist.fetch()}\n ></board-template-info>\n `,\n { backdrop: true, size: 'small', closable: true, title: template.name }\n )\n }\n}\n"]}
@@ -1,8 +1,10 @@
1
+ import '@operato/data-grist';
1
2
  import '@material/web/icon/icon.js';
2
- import '@material/web/fab/fab.js';
3
+ import '@material/web/button/text-button.js';
4
+ import '@operato/input/ox-input-select-buttons.js';
5
+ import '../board-list/board-thumb.js';
3
6
  import '../viewparts/play-group-info.js';
4
- import '../board-list/board-tile-list.js';
5
- import '../board-list/play-group-bar.js';
7
+ import { FetchOption } from '@operato/data-grist';
6
8
  import { PageView } from '@operato/shell';
7
9
  declare const PlayListPage_base: (new (...args: any[]) => import("lit").LitElement) & typeof PageView;
8
10
  export declare class PlayListPage extends PlayListPage_base {
@@ -11,20 +13,23 @@ export declare class PlayListPage extends PlayListPage_base {
11
13
  groups: any[];
12
14
  boards: any[];
13
15
  favorites: any[];
14
- boardTileList: HTMLElement;
16
+ gristConfig: any;
17
+ private grist;
15
18
  private page?;
16
19
  get context(): {
17
- title: {
18
- icon: string;
19
- text: any;
20
- };
20
+ title: string;
21
21
  board_topmenu: boolean;
22
22
  };
23
23
  render(): import("lit-html").TemplateResult<1>;
24
+ pageInitialized(): Promise<void>;
25
+ fetchHandler(_option: FetchOption): Promise<{
26
+ total: number;
27
+ records: any[];
28
+ }>;
24
29
  refresh(): Promise<void>;
25
30
  refreshBoards(): Promise<void>;
26
- pageInitialized(): Promise<void>;
27
31
  pageUpdated(changes: any, lifecycle: any): Promise<void>;
32
+ private groupIdFromLocation;
28
33
  private _unsubscribe?;
29
34
  connectedCallback(): void;
30
35
  disconnectedCallback(): void;
@@ -45,10 +50,15 @@ export declare class PlayListPage extends PlayListPage_base {
45
50
  board: any;
46
51
  playGroup: any;
47
52
  }): Promise<void>;
48
- onReorder({ boardIds, groupId }: {
49
- boardIds: any;
50
- groupId: any;
53
+ onReorder({ ids, movedId }: {
54
+ ids: string[];
55
+ movedId: string;
51
56
  }): Promise<void>;
57
+ toggleFavorite(board: any): Promise<void>;
58
+ /** Replaces one record in the grist in place, so only that card re-renders. */
59
+ private patchRecord;
60
+ removeFavorite(boardId: any): Promise<void>;
61
+ addFavorite(boardId: any): Promise<void>;
52
62
  refreshFavorites(): Promise<void>;
53
63
  }
54
64
  export {};