@things-factory/board-ui 8.0.0-beta.0 → 8.0.0-beta.2

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 (53) hide show
  1. package/package.json +5 -5
  2. package/client/apptools/favorite-tool.ts +0 -124
  3. package/client/board-list/board-tile-list.ts +0 -272
  4. package/client/board-list/group-bar-styles.ts +0 -63
  5. package/client/board-list/group-bar.ts +0 -99
  6. package/client/board-list/play-group-bar.ts +0 -88
  7. package/client/board-provider.ts +0 -92
  8. package/client/bootstrap.ts +0 -39
  9. package/client/data-grist/board-editor.ts +0 -113
  10. package/client/data-grist/board-renderer.ts +0 -134
  11. package/client/data-grist/color-map-editor.ts +0 -17
  12. package/client/data-grist/color-ranges-editor.ts +0 -17
  13. package/client/graphql/board-template.ts +0 -141
  14. package/client/graphql/board.ts +0 -273
  15. package/client/graphql/favorite-board.ts +0 -25
  16. package/client/graphql/group.ts +0 -138
  17. package/client/graphql/index.ts +0 -6
  18. package/client/graphql/my-board.ts +0 -25
  19. package/client/graphql/play-group.ts +0 -189
  20. package/client/index.ts +0 -10
  21. package/client/pages/attachment-list-page.ts +0 -142
  22. package/client/pages/board-list-page.ts +0 -603
  23. package/client/pages/board-modeller-page.ts +0 -288
  24. package/client/pages/board-player-by-name-page.ts +0 -29
  25. package/client/pages/board-player-page.ts +0 -241
  26. package/client/pages/board-template/board-template-list-page.ts +0 -248
  27. package/client/pages/board-viewer-by-name-page.ts +0 -24
  28. package/client/pages/board-viewer-page.ts +0 -271
  29. package/client/pages/font-list-page.ts +0 -31
  30. package/client/pages/play-list-page.ts +0 -400
  31. package/client/pages/printable-board-viewer-page.ts +0 -54
  32. package/client/pages/theme/theme-editors.ts +0 -56
  33. package/client/pages/theme/theme-list-page.ts +0 -313
  34. package/client/pages/things-scene-components-with-tools.import +0 -0
  35. package/client/pages/things-scene-components.import +0 -0
  36. package/client/route.ts +0 -51
  37. package/client/setting-let/board-view-setting-let.ts +0 -68
  38. package/client/themes/board-theme.css +0 -77
  39. package/client/things-scene-import.d.ts +0 -4
  40. package/client/viewparts/board-basic-info.ts +0 -646
  41. package/client/viewparts/board-info-link.ts +0 -56
  42. package/client/viewparts/board-info.ts +0 -85
  43. package/client/viewparts/board-template-builder.ts +0 -134
  44. package/client/viewparts/board-versions.ts +0 -172
  45. package/client/viewparts/group-info-basic.ts +0 -267
  46. package/client/viewparts/group-info-import.ts +0 -132
  47. package/client/viewparts/group-info.ts +0 -87
  48. package/client/viewparts/index.ts +0 -3
  49. package/client/viewparts/link-builder.ts +0 -210
  50. package/client/viewparts/play-group-info-basic.ts +0 -268
  51. package/client/viewparts/play-group-info-link.ts +0 -46
  52. package/client/viewparts/play-group-info.ts +0 -81
  53. package/server/index.ts +0 -0
@@ -1,85 +0,0 @@
1
- import { css, html, LitElement } from 'lit'
2
- import { customElement, property, state } from 'lit/decorators.js'
3
- import { ifDefined } from 'lit/directives/if-defined.js'
4
-
5
- import { ScrollbarStyles } from '@operato/styles'
6
-
7
- import './board-basic-info'
8
- import './board-versions'
9
- import './board-info-link'
10
-
11
- @customElement('board-info')
12
- export class BoardInfo extends LitElement {
13
- static styles = [
14
- ScrollbarStyles,
15
- css`
16
- :host {
17
- height: 100%;
18
- min-width: 360px;
19
-
20
- display: flex;
21
- flex-direction: column;
22
- position: relative;
23
- background-color: var(--md-sys-color-surface);
24
- }
25
-
26
- [tab] {
27
- width: 100%;
28
- display: flex;
29
- }
30
-
31
- [tab] > * {
32
- flex: 1;
33
- }
34
-
35
- [content] {
36
- flex: 1;
37
- overflow-y: auto;
38
- }
39
-
40
- span {
41
- padding: 5px 4px 1px;
42
- font: var(--group-bar-textbutton);
43
- background-color: var(--md-sys-color-secondary);
44
- color: rgba(255, 255, 255, 0.8);
45
- text-align: center;
46
- text-transform: uppercase;
47
- }
48
-
49
- span[active] {
50
- background-color: var(--md-sys-color-primary);
51
- }
52
-
53
- @media screen and (max-width: 460px) {
54
- :host {
55
- width: 100vw;
56
- }
57
- }
58
- `
59
- ]
60
-
61
- @property({ type: Object }) board?: { id: string; name: string }
62
-
63
- @state() tab: string = 'basic'
64
-
65
- render() {
66
- return html`
67
- <div tab>
68
- <span @click=${() => (this.tab = 'basic')} ?active=${this.tab == 'basic'}>basic</span>
69
- <span @click=${() => (this.tab = 'versions')} ?active=${this.tab == 'versions'}>versions</span>
70
- <span @click=${() => (this.tab = 'link')} ?active=${this.tab == 'link'}>link</span>
71
- </div>
72
- <div content>
73
- ${this.tab == 'basic'
74
- ? html`<board-basic-info boardId=${ifDefined(this.board?.id)}></board-basic-info>`
75
- : this.tab == 'versions'
76
- ? html`<board-versions boardId=${ifDefined(this.board?.id)}></board-versions>`
77
- : html`<board-info-link .board=${this.board}></board-info-link>`}
78
- </div>
79
- `
80
- }
81
-
82
- close() {
83
- history.back()
84
- }
85
- }
@@ -1,134 +0,0 @@
1
- import '@operato/i18n/ox-i18n.js'
2
-
3
- import { css, html, LitElement, nothing } from 'lit'
4
- import { customElement, property, state } from 'lit/decorators.js'
5
-
6
- import { ScrollbarStyles } from '@operato/styles'
7
- import { i18next } from '@operato/i18n'
8
- import { OxPrompt } from '@operato/popup/ox-prompt.js'
9
-
10
- @customElement('board-template-builder')
11
- export class BoardTemplateBuilder extends LitElement {
12
- static styles = [
13
- ScrollbarStyles,
14
- css`
15
- :host {
16
- display: flex;
17
- padding: var(--spacing-large);
18
-
19
- /* for narrow mode */
20
- flex-direction: column;
21
- }
22
-
23
- div[template] {
24
- display: grid;
25
- position: relative;
26
- }
27
-
28
- label {
29
- font: var(--label-font);
30
- color: var(--label-color, var(--md-sys-color-on-surface));
31
- text-transform: capitalize;
32
- }
33
-
34
- input,
35
- select,
36
- textarea {
37
- border: var(--border-dim-color);
38
- border-radius: var(--border-radius);
39
- margin: var(--input-margin);
40
- padding: var(--input-padding);
41
- font: var(--input-font);
42
- flex: 1 1 0%;
43
- }
44
-
45
- textarea {
46
- min-height: 132px;
47
- resize: none;
48
- }
49
-
50
- select:focus,
51
- input:focus,
52
- textarea:focus,
53
- button {
54
- outline: none;
55
- }
56
-
57
- button:hover {
58
- border: var(--button-activ-border);
59
- box-shadow: var(--button-active-box-shadow);
60
- }
61
- `
62
- ]
63
-
64
- @property({ type: Object }) board?: { id: string; name: string; description: string }
65
-
66
- @state() visibility?: string = 'private'
67
- @state() name?: string = ''
68
- @state() description?: string = ''
69
-
70
- render() {
71
- const name = this.name || this.board?.name || ''
72
- const description = this.description || this.board?.description || ''
73
-
74
- return html`
75
- <div template>
76
- <h3>
77
- <ox-title-with-help topic="board-service/board-template" msgid="label.board-template"
78
- >board template</ox-title-with-help
79
- >
80
- </h3>
81
- <label for="name">${i18next.t('field.name')}</label>
82
- <input id="name" type="text" .value=${name} @change=${e => (this.name = e.target.value)} />
83
-
84
- <label for="description">${i18next.t('field.description')}</label>
85
- <textarea
86
- id="description"
87
- .value=${this.description}
88
- @change=${e => (this.description = e.target.value)}
89
- ></textarea>
90
-
91
- <label>${i18next.t('field.visibility')}</label>
92
- <select
93
- @change=${e => (this.visibility = e.target.value)}
94
- placeholder="choose visibility ..."
95
- .value=${this.visibility}
96
- >
97
- <option value="private">${i18next.t('label.visibility-private')}</option>
98
- ${window.location.pathname.startsWith('/domain/')
99
- ? html` <option value="domain">${i18next.t('label.visibility-domain')}</option> `
100
- : nothing}
101
- <option value="public">${i18next.t('label.visibility-public')}</option>
102
- </select>
103
-
104
- <button @click=${this.registerBoardAsTemplate}>${i18next.t('text.register-template')}</button>
105
- </div>
106
- `
107
- }
108
-
109
- async registerBoardAsTemplate() {
110
- if (
111
- await OxPrompt.open({
112
- title: i18next.t('text.are_you_sure'),
113
- text: i18next.t('text.sure_to_x', { x: i18next.t('text.register-template') }),
114
- confirmButton: { text: i18next.t('button.confirm') },
115
- cancelButton: { text: i18next.t('button.cancel') }
116
- })
117
- ) {
118
- const { id } = this.board || {}
119
-
120
- this.dispatchEvent(
121
- new CustomEvent('register-template', {
122
- detail: {
123
- id,
124
- name: this.name || this.board?.name,
125
- description: this.description || this.board?.description,
126
- visibility: this.visibility
127
- },
128
- bubbles: true,
129
- composed: true
130
- })
131
- )
132
- }
133
- }
134
- }
@@ -1,172 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@material/web/chips/assist-chip.js'
3
-
4
- import gql from 'graphql-tag'
5
- import { css, html, LitElement } from 'lit'
6
- import { customElement, property, state } from 'lit/decorators.js'
7
-
8
- import { i18next } from '@operato/i18n'
9
- import { client } from '@operato/graphql'
10
-
11
- import { privileged } from '@things-factory/auth-base/dist-client'
12
-
13
- @customElement('board-versions')
14
- export class BoardVersions extends LitElement {
15
- static styles = [
16
- css`
17
- :host {
18
- display: block;
19
- background-color: var(--md-sys-color-surface);
20
- position: relative;
21
- text-align: center;
22
- color: var(--label-color, var(--md-sys-color-on-surface));
23
- font: var(--label-font);
24
- }
25
-
26
- img {
27
- display: block;
28
-
29
- margin: auto;
30
- max-width: 100%;
31
- max-height: 100%;
32
- border-bottom: 2px solid rgba(0, 0, 0, 0.1);
33
- }
34
-
35
- div[card] {
36
- position: relative;
37
- margin: var(--spacing-medium);
38
- text-align: start;
39
- border-bottom: var(--border-dim-color);
40
- }
41
-
42
- div[info] {
43
- display: flex;
44
- align-items: center;
45
- gap: var(--spacing-medium);
46
- }
47
-
48
- span {
49
- margin-left: auto;
50
- font: var(--input-field-font);
51
- display: flex;
52
- align-items: center;
53
- gap: 5px;
54
- }
55
-
56
- span md-icon {
57
- font-variation-settings: 'FILL' 1;
58
-
59
- vertical-align: middle;
60
- font-size: var(--fontsize-large);
61
- color: var(--md-sys-color-primary);
62
- }
63
-
64
- md-assist-chip {
65
- position: absolute;
66
- right: 3px;
67
- top: 3px;
68
- opacity: 0.8;
69
-
70
- --md-assist-chip-elevated-container-color: var(--md-sys-color-primary);
71
- --md-assist-chip-label-text-color: var(--md-sys-color-on-primary);
72
- --md-assist-chip-leading-icon-color: var(--md-sys-color-on-primary);
73
- }
74
-
75
- @media screen and (max-width: 460px) {
76
- :host {
77
- width: 100vw;
78
- }
79
- }
80
- `
81
- ]
82
-
83
- @property({ type: String }) boardId?: string
84
-
85
- @state() versions: any[] = []
86
-
87
- render() {
88
- return html`
89
- ${this.versions.length == 0
90
- ? html` ${i18next.t('text.no released version information available')} `
91
- : html`
92
- ${this.versions.map(
93
- version => html`
94
- <div card>
95
- <img src=${version.thumbnail} />
96
- <div info>
97
- <md-icon>pin</md-icon> ${version.version}
98
- <span>
99
- <md-icon>person</md-icon> ${(version.updater && version.updater.name) || 'anonymouse'}
100
- <md-icon>schedule</md-icon> ${new Date(version.updatedAt).toLocaleString()}
101
- </span>
102
- </div>
103
-
104
- ${privileged(
105
- { privilege: 'mutation', category: 'board' },
106
- html`
107
- <md-assist-chip
108
- elevated
109
- label=${String(i18next.t('button.revert-board-version'))}
110
- @click=${() => this.revertBoardVersion(version.version)}
111
- >
112
- <md-icon slot="icon">recycling</md-icon>
113
- </md-assist-chip>
114
- `
115
- )}
116
- </div>
117
- `
118
- )}
119
- `}
120
- `
121
- }
122
-
123
- firstUpdated() {
124
- this.refresh()
125
- }
126
-
127
- async refresh() {
128
- if (!this.boardId) {
129
- return
130
- }
131
-
132
- var response = (
133
- await client.query({
134
- query: gql`
135
- query FetchBoardVersionsById($id: String!) {
136
- boardVersions(id: $id) {
137
- id
138
- version
139
- thumbnail
140
- updater {
141
- name
142
- }
143
- updatedAt
144
- }
145
- }
146
- `,
147
- variables: { id: this.boardId }
148
- })
149
- ).data
150
-
151
- this.versions = response.boardVersions
152
- }
153
-
154
- revertBoardVersion(version: number) {
155
- this.dispatchEvent(
156
- new CustomEvent('revert-board-version', {
157
- detail: {
158
- id: this.boardId,
159
- version
160
- },
161
- bubbles: true,
162
- composed: true
163
- })
164
- )
165
-
166
- this.close()
167
- }
168
-
169
- close() {
170
- history.back()
171
- }
172
- }
@@ -1,267 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@material/web/textfield/filled-text-field.js'
3
- import '@material/web/button/elevated-button.js'
4
- import '@operato/input/ox-input-file.js'
5
-
6
- import { css, html, LitElement } from 'lit'
7
- import { customElement, property, query, state } from 'lit/decorators.js'
8
-
9
- import { i18next } from '@operato/i18n'
10
-
11
- import { fetchGroup } from '../graphql/group.js'
12
-
13
- @customElement('group-info-basic')
14
- export class GroupInfo extends LitElement {
15
- static styles = [
16
- css`
17
- :host {
18
- display: block;
19
- color: var(--md-sys-color-on-surface);
20
- background-color: var(--md-sys-color-surface);
21
- height: 100%;
22
- min-width: 360px;
23
- overflow: auto;
24
- position: relative;
25
-
26
- --form-grid-gap: 2px 0;
27
-
28
- --input-field-padding: var(--spacing-medium);
29
- --legend-padding: var(--spacing-medium) 0 var(--spacing-small) 0;
30
- }
31
-
32
- form {
33
- display: grid;
34
- grid-template-columns: repeat(12, 1fr);
35
- grid-gap: var(--form-grid-gap);
36
- grid-auto-rows: minmax(24px, auto);
37
- padding: var(--spacing-large);
38
- align-items: center;
39
- }
40
-
41
- md-filled-text-field {
42
- grid-column: span 12;
43
- padding: 10px 0;
44
- }
45
-
46
- [buttons] {
47
- grid-column: span 12;
48
- padding: var(--spacing-medium) 0;
49
- text-align: right;
50
-
51
- display: flex;
52
- gap: var(--spacing-small);
53
- align-items: center;
54
- }
55
-
56
- [buttons] * {
57
- margin: 0 0 0 auto;
58
- }
59
-
60
- [danger] {
61
- float: left;
62
- margin: 0;
63
- --md-elevated-button-icon-color: var(--md-sys-color-on-error);
64
- --md-elevated-button-label-text-color: var(--md-sys-color-on-error);
65
- --md-elevated-button-container-color: var(--md-sys-color-error);
66
- }
67
-
68
- fieldset {
69
- display: contents;
70
- }
71
-
72
- legend {
73
- grid-column: span 12;
74
- padding: var(--legend-padding);
75
- font: var(--legend-font);
76
- color: var(--md-sys-color-primary);
77
- text-transform: capitalize;
78
- }
79
-
80
- label {
81
- grid-column: span 12;
82
- text-transform: capitalize;
83
- color: var(--md-sys-color-primary);
84
- font: var(--label-font);
85
- }
86
-
87
- span {
88
- grid-column: span 12;
89
- border-bottom: var(--border-dim-color);
90
- margin-bottom: var(--spacing-medium);
91
- padding-bottom: var(--spacing-small);
92
- font: var(--input-field-font);
93
- }
94
- span md-icon {
95
- font-variation-settings: 'FILL' 1;
96
-
97
- vertical-align: middle;
98
- font-size: var(--fontsize-large);
99
- color: var(--md-sys-color-primary);
100
- }
101
-
102
- input,
103
- table,
104
- select,
105
- textarea,
106
- [custom-input] {
107
- grid-column: span 12;
108
-
109
- border: var(--input-field-border);
110
- border-radius: var(--input-field-border-radius);
111
- margin-bottom: var(--spacing-medium);
112
- padding: var(--input-field-padding);
113
- font: var(--input-field-font);
114
- }
115
-
116
- input[type='checkbox'],
117
- input[type='radio'] {
118
- place-self: center;
119
- margin: 0;
120
- grid-column: 1;
121
- }
122
-
123
- input[type='checkbox'] + label,
124
- input[type='radio'] + label {
125
- text-align: left;
126
- grid-column: span 11 / auto;
127
-
128
- font: var(--form-sublabel-font);
129
- color: var(--md-sys-color-secondary);
130
- }
131
-
132
- input:focus {
133
- outline: none;
134
- border: 1px solid var(--focus-background-color);
135
- }
136
-
137
- @media screen and (max-width: 460px) {
138
- :host {
139
- width: 100vw;
140
- }
141
- }
142
- `
143
- ]
144
-
145
- @property({ type: String }) groupId?: string
146
-
147
- @state() group: any = { name: '', description: '' }
148
-
149
- render() {
150
- var group = this.group || { name: '', description: '' }
151
-
152
- return html`
153
- <form>
154
- <fieldset>
155
- <legend>group information</legend>
156
-
157
- <md-filled-text-field
158
- type="text"
159
- label=${String(i18next.t('label.name'))}
160
- .value=${group.name}
161
- @change=${e => (this.group.name = e.target.value)}
162
- ></md-filled-text-field>
163
-
164
- <md-filled-text-field
165
- type="text"
166
- label=${String(i18next.t('label.description'))}
167
- .value=${group.description}
168
- @change=${e => (this.group.description = e.target.value)}
169
- ></md-filled-text-field>
170
-
171
- <label>${i18next.t('label.creator')}</label>
172
- <span>
173
- <md-icon>person</md-icon> ${group.creator && group.creator.name} <md-icon>schedule</md-icon> ${new Date(
174
- group.createdAt
175
- ).toLocaleString()}
176
- </span>
177
-
178
- <label>${i18next.t('label.updater')}</label>
179
- <span>
180
- <md-icon>person</md-icon> ${group.updater && group.updater.name} <md-icon>schedule</md-icon> ${new Date(
181
- group.updatedAt
182
- ).toLocaleString()}
183
- </span>
184
-
185
- <div buttons>
186
- ${this.groupId
187
- ? html`
188
- <md-elevated-button danger @click=${this.deleteGroup.bind(this)}
189
- ><md-icon slot="icon">delete_outline</md-icon>${i18next.t('button.delete')}</md-elevated-button
190
- >
191
- <md-elevated-button @click=${this.updateGroup.bind(this)}
192
- ><md-icon slot="icon">save</md-icon>${i18next.t('button.save')}</md-elevated-button
193
- >
194
- `
195
- : html`
196
- <md-elevated-button @click=${this.createGroup.bind(this)}
197
- ><md-icon slot="icon">create_new_folder</md-icon>${i18next.t('button.create')}</md-elevated-button
198
- >
199
- `}
200
- </div>
201
- </fieldset>
202
- </form>
203
- `
204
- }
205
-
206
- updated(changes) {
207
- if (changes.has('groupId')) {
208
- this.refresh()
209
- }
210
- }
211
-
212
- firstUpdated() {
213
- setTimeout(() => {
214
- ;(this.renderRoot.querySelector('[type=text]') as any).focus()
215
- }, 100)
216
- }
217
-
218
- async refresh() {
219
- if (!this.groupId) {
220
- /* model이 없으므로, 기본 모델을 제공함. */
221
- this.group = { name: '', description: '' }
222
- } else {
223
- var response = await fetchGroup(this.groupId)
224
- this.group = response.group
225
- }
226
- }
227
-
228
- async createGroup() {
229
- this.dispatchEvent(
230
- new CustomEvent('create-group', {
231
- detail: this.group,
232
- bubbles: true,
233
- composed: true
234
- })
235
- )
236
-
237
- this.close()
238
- }
239
-
240
- async updateGroup() {
241
- this.dispatchEvent(
242
- new CustomEvent('update-group', {
243
- detail: this.group,
244
- bubbles: true,
245
- composed: true
246
- })
247
- )
248
-
249
- this.close()
250
- }
251
-
252
- async deleteGroup() {
253
- this.dispatchEvent(
254
- new CustomEvent('delete-group', {
255
- detail: this.group,
256
- bubbles: true,
257
- composed: true
258
- })
259
- )
260
-
261
- this.close()
262
- }
263
-
264
- close() {
265
- history.back()
266
- }
267
- }