@operato/board 8.0.0-beta.0 → 8.0.0-beta.1

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 (82) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/package.json +14 -14
  3. package/.storybook/main.js +0 -3
  4. package/.storybook/server.mjs +0 -8
  5. package/src/component/3d.ts +0 -29
  6. package/src/component/chart-and-gauge.ts +0 -28
  7. package/src/component/container.ts +0 -63
  8. package/src/component/data-source.ts +0 -30
  9. package/src/component/etc.ts +0 -88
  10. package/src/component/form.ts +0 -42
  11. package/src/component/index.ts +0 -12
  12. package/src/component/iot.ts +0 -52
  13. package/src/component/line.ts +0 -156
  14. package/src/component/register-default-groups.ts +0 -28
  15. package/src/component/shape.ts +0 -156
  16. package/src/component/table.ts +0 -28
  17. package/src/component/text-and-media.ts +0 -125
  18. package/src/component/warehouse.ts +0 -26
  19. package/src/data-storage/data-storage.ts +0 -76
  20. package/src/graphql/board.ts +0 -144
  21. package/src/graphql/data-subscription.ts +0 -30
  22. package/src/graphql/favorite-board.ts +0 -25
  23. package/src/graphql/group.ts +0 -138
  24. package/src/graphql/index.ts +0 -4
  25. package/src/graphql/play-group.ts +0 -225
  26. package/src/graphql/scenario.ts +0 -79
  27. package/src/index.ts +0 -10
  28. package/src/modeller/component-toolbar/component-detail.ts +0 -52
  29. package/src/modeller/component-toolbar/component-menu.ts +0 -196
  30. package/src/modeller/component-toolbar/component-toolbar.ts +0 -196
  31. package/src/modeller/component-toolbar/mode-icons.ts +0 -88
  32. package/src/modeller/edit-toolbar-style.ts +0 -232
  33. package/src/modeller/edit-toolbar.ts +0 -587
  34. package/src/modeller/property-sidebar/abstract-property.ts +0 -69
  35. package/src/modeller/property-sidebar/data-binding/data-binding-mapper.ts +0 -475
  36. package/src/modeller/property-sidebar/data-binding/data-binding-value-map.ts +0 -19
  37. package/src/modeller/property-sidebar/data-binding/data-binding-value-range.ts +0 -19
  38. package/src/modeller/property-sidebar/data-binding/data-binding.ts +0 -480
  39. package/src/modeller/property-sidebar/effects/effects-shared-style.ts +0 -62
  40. package/src/modeller/property-sidebar/effects/effects.ts +0 -69
  41. package/src/modeller/property-sidebar/effects/property-animation.ts +0 -146
  42. package/src/modeller/property-sidebar/effects/property-animations.ts +0 -93
  43. package/src/modeller/property-sidebar/effects/property-event-hover.ts +0 -200
  44. package/src/modeller/property-sidebar/effects/property-event-tap.ts +0 -251
  45. package/src/modeller/property-sidebar/effects/property-event.ts +0 -73
  46. package/src/modeller/property-sidebar/effects/property-shadow.ts +0 -114
  47. package/src/modeller/property-sidebar/effects/value-converter.ts +0 -23
  48. package/src/modeller/property-sidebar/inspector/inspector.ts +0 -404
  49. package/src/modeller/property-sidebar/property-shared-style.ts +0 -136
  50. package/src/modeller/property-sidebar/property-sidebar.ts +0 -326
  51. package/src/modeller/property-sidebar/shapes/box-padding-editor-styles.ts +0 -94
  52. package/src/modeller/property-sidebar/shapes/shapes.ts +0 -432
  53. package/src/modeller/property-sidebar/specifics/specific-properties-builder.ts +0 -152
  54. package/src/modeller/property-sidebar/specifics/specifics.ts +0 -81
  55. package/src/modeller/property-sidebar/styles/styles.ts +0 -577
  56. package/src/modeller/scene-viewer/confidential-overlay.ts +0 -18
  57. package/src/modeller/scene-viewer/ox-scene-handler.ts +0 -40
  58. package/src/modeller/scene-viewer/ox-scene-layer.ts +0 -42
  59. package/src/modeller/scene-viewer/ox-scene-property.ts +0 -10
  60. package/src/modeller/scene-viewer/ox-scene-viewer.ts +0 -263
  61. package/src/ox-board-component-info.ts +0 -236
  62. package/src/ox-board-list.ts +0 -401
  63. package/src/ox-board-modeller.ts +0 -408
  64. package/src/ox-board-player-style.ts +0 -200
  65. package/src/ox-board-player.ts +0 -333
  66. package/src/ox-board-template-list.ts +0 -267
  67. package/src/ox-board-template-viewer.ts +0 -198
  68. package/src/ox-board-viewer.ts +0 -727
  69. package/src/ox-editor-board-selector.ts +0 -91
  70. package/src/ox-property-editor-board-selector.ts +0 -23
  71. package/src/player/ox-board-player-carousel.ts +0 -197
  72. package/src/player/ox-board-player-grid.ts +0 -78
  73. package/src/player/ox-board-wrapper.ts +0 -152
  74. package/src/selector/board-creation-popup.ts +0 -151
  75. package/src/selector/board-thumbnail-card.ts +0 -175
  76. package/src/selector/ox-board-creation-card.ts +0 -98
  77. package/src/selector/ox-board-selector.ts +0 -382
  78. package/src/types.ts +0 -63
  79. package/stories/property-data-binding.stories.ts +0 -34
  80. package/tsconfig.json +0 -24
  81. package/web-dev-server.config.mjs +0 -30
  82. 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
- }