@operato/board 7.1.31 → 7.1.33

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 (87) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/package.json +14 -14
  4. package/.storybook/main.js +0 -3
  5. package/.storybook/server.mjs +0 -8
  6. package/demo/index-modeller.html +0 -112
  7. package/demo/index-player.html +0 -112
  8. package/demo/index-viewer.html +0 -112
  9. package/demo/index.html +0 -112
  10. package/src/component/3d.ts +0 -29
  11. package/src/component/chart-and-gauge.ts +0 -28
  12. package/src/component/container.ts +0 -63
  13. package/src/component/data-source.ts +0 -30
  14. package/src/component/etc.ts +0 -88
  15. package/src/component/form.ts +0 -42
  16. package/src/component/index.ts +0 -12
  17. package/src/component/iot.ts +0 -52
  18. package/src/component/line.ts +0 -156
  19. package/src/component/register-default-groups.ts +0 -28
  20. package/src/component/shape.ts +0 -156
  21. package/src/component/table.ts +0 -28
  22. package/src/component/text-and-media.ts +0 -125
  23. package/src/component/warehouse.ts +0 -26
  24. package/src/data-storage/data-storage.ts +0 -76
  25. package/src/graphql/board.ts +0 -144
  26. package/src/graphql/data-subscription.ts +0 -30
  27. package/src/graphql/favorite-board.ts +0 -25
  28. package/src/graphql/group.ts +0 -138
  29. package/src/graphql/index.ts +0 -4
  30. package/src/graphql/play-group.ts +0 -225
  31. package/src/graphql/scenario.ts +0 -79
  32. package/src/index.ts +0 -10
  33. package/src/modeller/component-toolbar/component-detail.ts +0 -52
  34. package/src/modeller/component-toolbar/component-menu.ts +0 -196
  35. package/src/modeller/component-toolbar/component-toolbar.ts +0 -196
  36. package/src/modeller/component-toolbar/mode-icons.ts +0 -88
  37. package/src/modeller/edit-toolbar-style.ts +0 -232
  38. package/src/modeller/edit-toolbar.ts +0 -587
  39. package/src/modeller/property-sidebar/abstract-property.ts +0 -69
  40. package/src/modeller/property-sidebar/data-binding/data-binding-mapper.ts +0 -475
  41. package/src/modeller/property-sidebar/data-binding/data-binding-value-map.ts +0 -19
  42. package/src/modeller/property-sidebar/data-binding/data-binding-value-range.ts +0 -19
  43. package/src/modeller/property-sidebar/data-binding/data-binding.ts +0 -480
  44. package/src/modeller/property-sidebar/effects/effects-shared-style.ts +0 -62
  45. package/src/modeller/property-sidebar/effects/effects.ts +0 -69
  46. package/src/modeller/property-sidebar/effects/property-animation.ts +0 -146
  47. package/src/modeller/property-sidebar/effects/property-animations.ts +0 -93
  48. package/src/modeller/property-sidebar/effects/property-event-hover.ts +0 -200
  49. package/src/modeller/property-sidebar/effects/property-event-tap.ts +0 -251
  50. package/src/modeller/property-sidebar/effects/property-event.ts +0 -73
  51. package/src/modeller/property-sidebar/effects/property-shadow.ts +0 -114
  52. package/src/modeller/property-sidebar/effects/value-converter.ts +0 -23
  53. package/src/modeller/property-sidebar/inspector/inspector.ts +0 -404
  54. package/src/modeller/property-sidebar/property-shared-style.ts +0 -136
  55. package/src/modeller/property-sidebar/property-sidebar.ts +0 -326
  56. package/src/modeller/property-sidebar/shapes/box-padding-editor-styles.ts +0 -94
  57. package/src/modeller/property-sidebar/shapes/shapes.ts +0 -432
  58. package/src/modeller/property-sidebar/specifics/specific-properties-builder.ts +0 -152
  59. package/src/modeller/property-sidebar/specifics/specifics.ts +0 -81
  60. package/src/modeller/property-sidebar/styles/styles.ts +0 -577
  61. package/src/modeller/scene-viewer/confidential-overlay.ts +0 -18
  62. package/src/modeller/scene-viewer/ox-scene-handler.ts +0 -40
  63. package/src/modeller/scene-viewer/ox-scene-layer.ts +0 -42
  64. package/src/modeller/scene-viewer/ox-scene-property.ts +0 -10
  65. package/src/modeller/scene-viewer/ox-scene-viewer.ts +0 -263
  66. package/src/ox-board-component-info.ts +0 -236
  67. package/src/ox-board-list.ts +0 -401
  68. package/src/ox-board-modeller.ts +0 -408
  69. package/src/ox-board-player-style.ts +0 -200
  70. package/src/ox-board-player.ts +0 -333
  71. package/src/ox-board-template-list.ts +0 -267
  72. package/src/ox-board-template-viewer.ts +0 -198
  73. package/src/ox-board-viewer.ts +0 -727
  74. package/src/ox-editor-board-selector.ts +0 -91
  75. package/src/ox-property-editor-board-selector.ts +0 -23
  76. package/src/player/ox-board-player-carousel.ts +0 -197
  77. package/src/player/ox-board-player-grid.ts +0 -78
  78. package/src/player/ox-board-wrapper.ts +0 -152
  79. package/src/selector/board-creation-popup.ts +0 -151
  80. package/src/selector/board-thumbnail-card.ts +0 -175
  81. package/src/selector/ox-board-creation-card.ts +0 -98
  82. package/src/selector/ox-board-selector.ts +0 -382
  83. package/src/types.ts +0 -63
  84. package/stories/property-data-binding.stories.ts +0 -34
  85. package/tsconfig.json +0 -24
  86. package/web-dev-server.config.mjs +0 -30
  87. package/web-test-runner.config.mjs +0 -29
@@ -1,91 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import '@material/web/icon/icon.js'
6
- import './selector/ox-board-selector'
7
-
8
- import { css, html, LitElement } from 'lit'
9
- import { customElement, property } from 'lit/decorators.js'
10
-
11
- import { i18next } from '@operato/i18n'
12
- import { openPopup } from '@operato/layout'
13
-
14
- @customElement('ox-editor-board-selector')
15
- export class BoardSelector extends LitElement {
16
- static get styles() {
17
- return [
18
- css`
19
- :host {
20
- position: relative;
21
- display: inline-block;
22
- }
23
-
24
- input[type='text'] {
25
- box-sizing: border-box;
26
- width: 100%;
27
- height: 100%;
28
- border: 1px solid rgba(0, 0, 0, 0.2);
29
- }
30
-
31
- md-icon {
32
- position: absolute;
33
- top: 0;
34
- right: 0;
35
- }
36
- `
37
- ]
38
- }
39
-
40
- @property({ type: String }) value?: string
41
- @property({ type: Object }) properties?: any
42
-
43
- private popup: any
44
-
45
- render() {
46
- return html`
47
- <input id="text" type="text" .value=${this.value || ''} @change=${(e: Event) => this._onInputChanged(e)} />
48
-
49
- <md-icon @click=${(e: MouseEvent) => this.openSelector()}>dashboard</md-icon>
50
- `
51
- }
52
-
53
- _onInputChanged(e: Event) {
54
- this.value = (e.target as any)?.value
55
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
56
- }
57
-
58
- openSelector() {
59
- if (this.popup) {
60
- delete this.popup
61
- }
62
-
63
- /*
64
- * 기존 설정된 보드가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.
65
- * 주의. value는 object일 수도 있고, string일 수도 있다.
66
- * string인 경우에는 해당 보드의 id로 해석한다.
67
- */
68
- var value = this.value || {}
69
-
70
- var template = html`
71
- <ox-board-selector
72
- .creatable=${true}
73
- .value=${value}
74
- @board-selected=${async (e: CustomEvent) => {
75
- var board = e.detail.board
76
- this.value = board.id
77
-
78
- this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))
79
-
80
- this.popup && this.popup.close()
81
- }}
82
- ></ox-board-selector>
83
- `
84
-
85
- this.popup = openPopup(template, {
86
- backdrop: true,
87
- size: 'large',
88
- title: i18next.t('title.select board')
89
- })
90
- }
91
- }
@@ -1,23 +0,0 @@
1
- /**
2
- * @license Copyright © HatioLab Inc. All rights reserved.
3
- */
4
-
5
- import './ox-editor-board-selector'
6
-
7
- import { html, TemplateResult } from 'lit'
8
- import { customElement } from 'lit/decorators.js'
9
-
10
- import { OxPropertyEditor, PropertySpec } from '@operato/property-editor'
11
-
12
- @customElement('ox-property-editor-board-selector')
13
- class PropertyEditorBoardSelector extends OxPropertyEditor {
14
- static get styles() {
15
- return [...OxPropertyEditor.styles]
16
- }
17
-
18
- editorTemplate(value: any, spec: PropertySpec): TemplateResult {
19
- return html`
20
- <ox-editor-board-selector id="editor" .value=${value} .properties=${spec.property}></ox-editor-board-selector>
21
- `
22
- }
23
- }
@@ -1,197 +0,0 @@
1
- import './ox-board-player-grid'
2
-
3
- import { LitElement, PropertyValues, css, html } from 'lit'
4
- import { customElement, property, query, state } from 'lit/decorators.js'
5
-
6
- @customElement('ox-board-player-carousel')
7
- class BoardPlayerCarousel extends LitElement {
8
- static styles = [
9
- css`
10
- :host {
11
- display: block;
12
- width: 100%;
13
- height: 100%;
14
- position: relative;
15
- margin: 0 auto 0px;
16
- -webkit-perspective: 1200px;
17
- -moz-perspective: 1200px;
18
- -o-perspective: 1200px;
19
- perspective: 1200px;
20
- }
21
-
22
- #carousel {
23
- width: 100%;
24
- height: 100%;
25
- margin: 0px auto 0px;
26
-
27
- position: absolute;
28
- -webkit-transform-style: preserve-3d;
29
- -moz-transform-style: preserve-3d;
30
- -o-transform-style: preserve-3d;
31
- transform-style: preserve-3d;
32
- -webkit-transition: -webkit-transform 1.5s;
33
- -moz-transition: -moz-transform 1.5s;
34
- -o-transition: -o-transform 1.5s;
35
- transition: transform 1.5s;
36
- }
37
-
38
- #carousel > * {
39
- position: absolute;
40
- width: 100%;
41
- height: 100%;
42
- font-weight: bold;
43
- -webkit-transition: opacity 1.5s, -webkit-transform 1.5s;
44
- -moz-transition: opacity 1.5s, -moz-transform 1.5s;
45
- -o-transition: opacity 1.5s, -o-transform 1.5s;
46
- transition: opacity 1.5s, transform 1.5s;
47
-
48
- -webkit-backface-visibility: hidden;
49
- -moz-backface-visibility: hidden;
50
- -o-backface-visibility: hidden;
51
- backface-visibility: hidden;
52
- }
53
- `
54
- ]
55
-
56
- @property({ type: String }) axis: string = 'y'
57
- @property({ type: Number }) rows: number = 1
58
- @property({ type: Number }) columns: number = 1
59
-
60
- @state() _slotObserver?: MutationObserver
61
- @state() _boundResize?: () => void
62
- @state() _rotation: number = 0
63
- @state() _theta: number = 0
64
- @state() _radius: number = 0
65
- @state() _rotateFn?: string
66
-
67
- @state() _panelCount: number = 0
68
- @state() _panelSize: number = 0
69
- @state() _isHorizontal: boolean = true
70
-
71
- @query('#slot') _slot!: HTMLSlotElement
72
- @query('#carousel') _carousel!: HTMLElement
73
-
74
- render() {
75
- return html`
76
- <slot id="slot" select="[page]"></slot>
77
-
78
- <div id="carousel"></div>
79
- `
80
- }
81
-
82
- async connectedCallback() {
83
- await super.connectedCallback()
84
-
85
- this._boundResize = this.build.bind(this)
86
- window.addEventListener('resize', this._boundResize)
87
-
88
- this._slotObserver = new MutationObserver(mutations => {
89
- this.build()
90
- })
91
-
92
- await this.updateComplete
93
-
94
- this._slotObserver?.observe(this._slot, { childList: true })
95
- this.build()
96
- }
97
-
98
- disconnectedCallback() {
99
- super.disconnectedCallback()
100
-
101
- this._slotObserver?.disconnect()
102
- delete this._slotObserver
103
-
104
- if (this._boundResize) {
105
- window.removeEventListener('resize', this._boundResize)
106
- delete this._boundResize
107
- }
108
- }
109
-
110
- firstUpdated() {
111
- this._rotation = 0
112
- }
113
-
114
- updated(changes: PropertyValues<this>) {
115
- changes.has('axis') && this._onAxisChanged()
116
- }
117
-
118
- build() {
119
- var pages = Array.from(this.querySelectorAll('[page]'))
120
- var panel = Array.from(this._carousel.querySelectorAll('ox-board-player-grid')).pop()
121
-
122
- var rows = this.rows || 1
123
- var columns = this.columns || 1
124
-
125
- var i = panel ? panel.querySelectorAll('[page]').length : 0
126
- var page = pages.shift()
127
-
128
- while (page) {
129
- if (!(i++ % (rows * columns))) {
130
- panel = document.createElement('ox-board-player-grid')
131
- ;(panel as any).rows = rows
132
- ;(panel as any).columns = columns
133
-
134
- this._carousel.appendChild(panel)
135
- }
136
- panel?.appendChild(page)
137
-
138
- page = pages.shift()
139
- }
140
-
141
- this.start()
142
- }
143
-
144
- start() {
145
- var panels = this._carousel.querySelectorAll('ox-board-player-grid')
146
-
147
- this._isHorizontal = this.axis === 'y'
148
-
149
- this._panelCount = panels.length
150
-
151
- this._panelSize = this._carousel[this._isHorizontal ? 'offsetWidth' : 'offsetHeight'] || 640
152
- this._rotateFn = this._isHorizontal ? 'rotateY' : 'rotateX'
153
- this._theta = 360 / (this._panelCount || 1)
154
-
155
- // do some trig to figure out how big the carousel is in 3D space
156
- this._radius = Math.round(this._panelSize / 2 / Math.tan(Math.PI / (this._panelCount < 2 ? 2 : this._panelCount)))
157
-
158
- for (let i = 0; i < this._panelCount; i++) {
159
- let panel = panels[i] as HTMLElement
160
- let angle = this._theta * i
161
- panel.style.opacity = '1'
162
-
163
- panel.style.backgroundColor = 'white'
164
-
165
- panel.style.transform = this._rotateFn + '(' + angle + 'deg) translateZ(' + this._radius + 'px)'
166
- }
167
-
168
- // adjust rotation so panels are always flat
169
- this._rotation = Math.round(this._rotation / this._theta) * this._theta
170
- this._transform()
171
- }
172
-
173
- stop() {
174
- this._carousel.innerHTML = ''
175
- }
176
-
177
- _onAxisChanged() {
178
- this.start()
179
- }
180
-
181
- _transform() {
182
- // push the carousel back in 3D space, and rotate it
183
- this._carousel.style.transform =
184
- 'translateZ(-' + this._radius + 'px) ' + this._rotateFn + '(' + this._rotation + 'deg)'
185
- this.dispatchEvent(new CustomEvent('transform', { bubbles: true, composed: true }))
186
- }
187
-
188
- previous() {
189
- this._rotation += this._theta
190
- this._transform()
191
- }
192
-
193
- next() {
194
- this._rotation -= this._theta
195
- this._transform()
196
- }
197
- }
@@ -1,78 +0,0 @@
1
- import { LitElement, PropertyValues, css, html } from 'lit'
2
- import { customElement, property, query, state } from 'lit/decorators.js'
3
-
4
- /**
5
- * 자식 컴포넌트들을 그리드형태로 화면에 배치하여 한꺼번에 디스플레이해주는 컴포넌트.
6
- * Example:
7
- <ox-board-player-grid rows="3" columns="3" tabindex="0" focus>
8
- <div page>A</div>
9
- <div page>B</div>
10
- <div page>C</div>
11
- <div page>D</div>
12
- </ox-board-player-grid>
13
- */
14
-
15
- @customElement('ox-board-player-grid')
16
- class BoardPlayerGrid extends LitElement {
17
- static styles = [
18
- css`
19
- :host {
20
- width: 100%;
21
- height: 100%;
22
- position: relative;
23
-
24
- display: grid;
25
- grid-gap: 0px;
26
- grid-auto-flow: dense;
27
- }
28
- `
29
- ]
30
-
31
- @property({ type: Number }) rows: number = 1
32
- @property({ type: Number }) columns: number = 1
33
-
34
- @state() _slotObserver?: MutationObserver
35
-
36
- @query('#slot') _slot!: HTMLSlotElement
37
-
38
- render() {
39
- return html` <slot id="slot" select="[page]"></slot> `
40
- }
41
-
42
- async connectedCallback() {
43
- await super.connectedCallback()
44
-
45
- this._slotObserver = new MutationObserver(mutations => {
46
- var columns = this.columns || 1
47
- var rows = this.rows || 1
48
-
49
- ;(this.style as any)['grid-template-columns'] = `repeat(${columns}, 1fr)`
50
- ;(this.style as any)['grid-template-rows'] = `repeat(${rows}, 1fr)`
51
- })
52
-
53
- await this.updateComplete
54
-
55
- var columns = this.columns || 1
56
- var rows = this.rows || 1
57
-
58
- ;(this.style as any)['grid-template-columns'] = `repeat(${columns}, 1fr)`
59
- ;(this.style as any)['grid-template-rows'] = `repeat(${rows}, 1fr)`
60
-
61
- this._slotObserver?.observe(this._slot, { childList: true })
62
- }
63
-
64
- disconnectedCallback() {
65
- super.disconnectedCallback()
66
-
67
- this._slotObserver?.disconnect()
68
- delete this._slotObserver
69
- }
70
-
71
- start() {}
72
-
73
- stop() {}
74
-
75
- next() {}
76
-
77
- previous() {}
78
- }
@@ -1,152 +0,0 @@
1
- import { css, html, LitElement, PropertyValues } from 'lit'
2
- import { customElement, property, query, state } from 'lit/decorators.js'
3
-
4
- import { BoardDataStorage } from '../data-storage/data-storage.js'
5
- import { DataSubscriptionProviderImpl } from '../graphql/data-subscription.js'
6
-
7
- import { create, SCENE_MODE } from '@hatiolab/things-scene'
8
-
9
- /**
10
- * @class BoardWrapper
11
- *
12
- * @description scene provider로부터 제공받은 scene의 reference count control을 담당하며, resize 이벤트 발생시 scene의 사이즈를 fit 시키는 역할을 담당한다.
13
- */
14
- @customElement('ox-board-wrapper')
15
- class BoardWrapper extends LitElement {
16
- static styles = [
17
- css`
18
- :host {
19
- display: flex;
20
- flex-direction: column;
21
- position: relative;
22
- }
23
-
24
- #target {
25
- flex: 1;
26
-
27
- width: 100%;
28
- height: 100%;
29
- outline: 0;
30
- }
31
- `
32
- ]
33
-
34
- @property({ type: Object }) provider!: any
35
- @property({ type: Object }) data: any
36
- @property({ type: Object }) board?: any
37
- @property({ type: String }) baseUrl?: string
38
-
39
- private _scene: any
40
- private connected: boolean = false
41
-
42
- @query('#target') _targetEl!: HTMLElement
43
-
44
- render() {
45
- return html` <div id="target"></div> `
46
- }
47
-
48
- connectedCallback() {
49
- super.connectedCallback()
50
-
51
- this.connected = true
52
-
53
- window.addEventListener('resize', () => {
54
- requestAnimationFrame(() => {
55
- if (this._scene) {
56
- this._scene.resize()
57
-
58
- if (this.offsetWidth) {
59
- this._scene.fit()
60
- }
61
- }
62
- })
63
- })
64
- }
65
-
66
- disconnectedCallback() {
67
- super.disconnectedCallback()
68
- this.connected = false
69
-
70
- /* ox-board-player-carousel에 의해서 mutation 되면서, 잠깐 disconnected되므로,
71
- 최종적으로 disconnected 여부를 확인하여야 한다. */
72
- requestAnimationFrame(() => {
73
- if (!this.connected) {
74
- this.closeScene()
75
- }
76
- })
77
- }
78
-
79
- updated(changes: PropertyValues<this>) {
80
- changes.has('board') && this._onBoardChanged()
81
- }
82
-
83
- _onBoardChanged() {
84
- this.closeScene()
85
-
86
- this.initScene()
87
- }
88
-
89
- initScene() {
90
- if (!this.board || !this.board.id) {
91
- return
92
- }
93
-
94
- var { model } = this.board
95
-
96
- try {
97
- if (typeof model == 'string') {
98
- model = JSON.parse(model)
99
- } else {
100
- model = JSON.parse(JSON.stringify(model))
101
- }
102
- } catch (err) {
103
- console.error(err)
104
- }
105
-
106
- this._scene = create({
107
- model,
108
- mode: SCENE_MODE.VIEW,
109
- refProvider: this.provider!,
110
- dataStorage: new BoardDataStorage(this.board.id),
111
- dataSubscriptionProvider: new DataSubscriptionProviderImpl()
112
- })
113
-
114
- if (this.baseUrl) {
115
- this._scene.baseUrl = this.baseUrl
116
- }
117
-
118
- this.setupScene({ id: this.board.id, scene: this._scene })
119
- }
120
-
121
- closeScene() {
122
- if (this._scene) {
123
- this._scene.target = null
124
- this._scene.release && this._scene.release()
125
-
126
- this._scene = null
127
- }
128
- }
129
-
130
- setupScene({ id, scene }: { id: string; scene: any }) {
131
- this._scene = scene
132
-
133
- const backgroundColor = this._scene?.root.state.fillStyle
134
- if (typeof backgroundColor === 'string') {
135
- this.style.backgroundColor = backgroundColor
136
- } else {
137
- this.style.backgroundColor = 'initial'
138
- }
139
-
140
- this._scene.target = this._targetEl
141
-
142
- requestAnimationFrame(() => {
143
- if (this._scene?.target.offsetWidth) {
144
- this._scene.fit()
145
- }
146
- })
147
-
148
- if (this.data) {
149
- this._scene.data = this.data
150
- }
151
- }
152
- }
@@ -1,151 +0,0 @@
1
- import '@material/web/textfield/filled-text-field.js'
2
- import '@material/web/button/text-button.js'
3
- import '@material/web/select/filled-select.js'
4
- import '@material/web/select/select-option.js'
5
- import '../ox-board-template-list'
6
-
7
- import { css, html, LitElement } from 'lit'
8
- import { customElement, property, query } from 'lit/decorators.js'
9
-
10
- import { i18next, localize } from '@operato/i18n'
11
- import { OxBoardTemplateList } from '../ox-board-template-list'
12
-
13
- @customElement('board-creation-popup')
14
- export class BoardCreationPopup extends localize(i18next)(LitElement) {
15
- static get styles() {
16
- return [
17
- css`
18
- :host {
19
- display: flex;
20
- flex-direction: column;
21
- gap: 10px;
22
- padding: 10px;
23
-
24
- background-color: var(--md-sys-color-surface);
25
- }
26
-
27
- [body] {
28
- flex: 1;
29
-
30
- display: flex;
31
- flex-direction: row;
32
- gap: 10px;
33
-
34
- overflow: hidden;
35
- }
36
-
37
- [content] {
38
- flex: 1;
39
-
40
- display: flex;
41
- flex-direction: column;
42
- gap: 10px;
43
-
44
- overflow: auto;
45
- }
46
-
47
- [content] > md-filled-text-field[type='textarea'] {
48
- flex: 1;
49
- resize: none;
50
- }
51
-
52
- [templates] {
53
- flex: 2;
54
- display: flex;
55
- flex-direction: column;
56
- overflow: hidden;
57
- }
58
-
59
- [templates] > ox-board-template-list {
60
- flex: 1;
61
- overflow: hidden;
62
- }
63
-
64
- md-text-button {
65
- --_container-color: var(--md-sys-color-primary);
66
- --_label-text-color: var(--md-sys-color-on-primary);
67
- }
68
- `
69
- ]
70
- }
71
-
72
- @property({ type: String }) defaultGroup?: string
73
- @property({ type: Array }) groups?: { id: string; name: string }[]
74
-
75
- @query('ox-board-template-list') boardTemplateList!: OxBoardTemplateList
76
-
77
- render() {
78
- var groups = this.groups || []
79
-
80
- return html`
81
- <div body>
82
- <div content>
83
- <md-filled-text-field
84
- label=${String(i18next.t('label.name'))}
85
- name="name"
86
- required
87
- field-name
88
- ></md-filled-text-field>
89
- <md-filled-text-field
90
- type="textarea"
91
- label=${String(i18next.t('label.description'))}
92
- name="description"
93
- field-description
94
- ></md-filled-text-field>
95
- <md-filled-select
96
- label=${String(i18next.t('label.group'))}
97
- field-group
98
- helper="If there is no group to choose, you can leave it empty."
99
- >
100
- ${groups.map(
101
- group => html`
102
- <md-select-option value=${group.id} ?selected=${this.defaultGroup == group.id}
103
- >${group.name}</md-select-option
104
- >
105
- `
106
- )}
107
- </md-filled-select>
108
- </div>
109
-
110
- <div templates>
111
- <div>${i18next.t('label.board-template')}</div>
112
- <ox-board-template-list></ox-board-template-list>
113
- </div>
114
- </div>
115
-
116
- <md-text-button @click=${(e: MouseEvent) => this.onClickSubmit()}
117
- >${String(i18next.t('button.create'))}</md-text-button
118
- >
119
- `
120
- }
121
-
122
- firstUpdated() {
123
- setTimeout(() => {
124
- ;(this.renderRoot.querySelector('md-filled-text-field') as any)?.focus()
125
- }, 100)
126
- }
127
-
128
- async onClickSubmit() {
129
- var [name, description, groupId] = ['name', 'description', 'group'].map(attr => {
130
- return (this.renderRoot.querySelector(`[field-${attr}]`) as any)?.value
131
- })
132
-
133
- if (!name) {
134
- return
135
- }
136
-
137
- const template = await this.boardTemplateList.getSelected()
138
-
139
- this.dispatchEvent(
140
- new CustomEvent('create-board', {
141
- detail: {
142
- name,
143
- description,
144
- groupId,
145
- model: template?.model,
146
- thumbnail: template?.thumbnail
147
- }
148
- })
149
- )
150
- }
151
- }