@operato/board 8.0.0-alpha.9 → 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 (93) hide show
  1. package/CHANGELOG.md +256 -0
  2. package/demo/index-viewer.html +1 -1
  3. package/demo/index.html +1 -1
  4. package/dist/src/ox-board-player.js +2 -1
  5. package/dist/src/ox-board-player.js.map +1 -1
  6. package/dist/src/ox-board-template-viewer.d.ts +1 -1
  7. package/dist/src/ox-board-viewer.d.ts +3 -2
  8. package/dist/src/ox-board-viewer.js +16 -6
  9. package/dist/src/ox-board-viewer.js.map +1 -1
  10. package/dist/src/player/ox-board-wrapper.js +3 -1
  11. package/dist/src/player/ox-board-wrapper.js.map +1 -1
  12. package/dist/tsconfig.tsbuildinfo +1 -1
  13. package/package.json +25 -25
  14. package/.storybook/main.js +0 -3
  15. package/.storybook/server.mjs +0 -8
  16. package/src/component/3d.ts +0 -29
  17. package/src/component/chart-and-gauge.ts +0 -28
  18. package/src/component/container.ts +0 -63
  19. package/src/component/data-source.ts +0 -30
  20. package/src/component/etc.ts +0 -88
  21. package/src/component/form.ts +0 -42
  22. package/src/component/index.ts +0 -12
  23. package/src/component/iot.ts +0 -52
  24. package/src/component/line.ts +0 -156
  25. package/src/component/register-default-groups.ts +0 -28
  26. package/src/component/shape.ts +0 -156
  27. package/src/component/table.ts +0 -28
  28. package/src/component/text-and-media.ts +0 -125
  29. package/src/component/warehouse.ts +0 -26
  30. package/src/data-storage/data-storage.ts +0 -76
  31. package/src/graphql/board.ts +0 -144
  32. package/src/graphql/data-subscription.ts +0 -30
  33. package/src/graphql/favorite-board.ts +0 -25
  34. package/src/graphql/group.ts +0 -138
  35. package/src/graphql/index.ts +0 -4
  36. package/src/graphql/play-group.ts +0 -225
  37. package/src/graphql/scenario.ts +0 -79
  38. package/src/index.ts +0 -10
  39. package/src/modeller/component-toolbar/component-detail.ts +0 -52
  40. package/src/modeller/component-toolbar/component-menu.ts +0 -196
  41. package/src/modeller/component-toolbar/component-toolbar.ts +0 -196
  42. package/src/modeller/component-toolbar/mode-icons.ts +0 -88
  43. package/src/modeller/edit-toolbar-style.ts +0 -232
  44. package/src/modeller/edit-toolbar.ts +0 -587
  45. package/src/modeller/property-sidebar/abstract-property.ts +0 -69
  46. package/src/modeller/property-sidebar/data-binding/data-binding-mapper.ts +0 -475
  47. package/src/modeller/property-sidebar/data-binding/data-binding-value-map.ts +0 -19
  48. package/src/modeller/property-sidebar/data-binding/data-binding-value-range.ts +0 -19
  49. package/src/modeller/property-sidebar/data-binding/data-binding.ts +0 -480
  50. package/src/modeller/property-sidebar/effects/effects-shared-style.ts +0 -62
  51. package/src/modeller/property-sidebar/effects/effects.ts +0 -69
  52. package/src/modeller/property-sidebar/effects/property-animation.ts +0 -146
  53. package/src/modeller/property-sidebar/effects/property-animations.ts +0 -93
  54. package/src/modeller/property-sidebar/effects/property-event-hover.ts +0 -200
  55. package/src/modeller/property-sidebar/effects/property-event-tap.ts +0 -251
  56. package/src/modeller/property-sidebar/effects/property-event.ts +0 -73
  57. package/src/modeller/property-sidebar/effects/property-shadow.ts +0 -114
  58. package/src/modeller/property-sidebar/effects/value-converter.ts +0 -23
  59. package/src/modeller/property-sidebar/inspector/inspector.ts +0 -404
  60. package/src/modeller/property-sidebar/property-shared-style.ts +0 -136
  61. package/src/modeller/property-sidebar/property-sidebar.ts +0 -326
  62. package/src/modeller/property-sidebar/shapes/box-padding-editor-styles.ts +0 -94
  63. package/src/modeller/property-sidebar/shapes/shapes.ts +0 -432
  64. package/src/modeller/property-sidebar/specifics/specific-properties-builder.ts +0 -152
  65. package/src/modeller/property-sidebar/specifics/specifics.ts +0 -81
  66. package/src/modeller/property-sidebar/styles/styles.ts +0 -577
  67. package/src/modeller/scene-viewer/confidential-overlay.ts +0 -18
  68. package/src/modeller/scene-viewer/ox-scene-handler.ts +0 -40
  69. package/src/modeller/scene-viewer/ox-scene-layer.ts +0 -42
  70. package/src/modeller/scene-viewer/ox-scene-property.ts +0 -10
  71. package/src/modeller/scene-viewer/ox-scene-viewer.ts +0 -263
  72. package/src/ox-board-component-info.ts +0 -236
  73. package/src/ox-board-list.ts +0 -401
  74. package/src/ox-board-modeller.ts +0 -408
  75. package/src/ox-board-player-style.ts +0 -200
  76. package/src/ox-board-player.ts +0 -331
  77. package/src/ox-board-template-list.ts +0 -267
  78. package/src/ox-board-template-viewer.ts +0 -198
  79. package/src/ox-board-viewer.ts +0 -718
  80. package/src/ox-editor-board-selector.ts +0 -91
  81. package/src/ox-property-editor-board-selector.ts +0 -23
  82. package/src/player/ox-board-player-carousel.ts +0 -197
  83. package/src/player/ox-board-player-grid.ts +0 -78
  84. package/src/player/ox-board-wrapper.ts +0 -150
  85. package/src/selector/board-creation-popup.ts +0 -151
  86. package/src/selector/board-thumbnail-card.ts +0 -175
  87. package/src/selector/ox-board-creation-card.ts +0 -98
  88. package/src/selector/ox-board-selector.ts +0 -382
  89. package/src/types.ts +0 -63
  90. package/stories/property-data-binding.stories.ts +0 -34
  91. package/tsconfig.json +0 -24
  92. package/web-dev-server.config.mjs +0 -30
  93. 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,150 +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.initScene()
85
- }
86
-
87
- initScene() {
88
- if (!this.board || !this.board.id) {
89
- return
90
- }
91
-
92
- var { model } = this.board
93
-
94
- try {
95
- if (typeof model == 'string') {
96
- model = JSON.parse(model)
97
- } else {
98
- model = JSON.parse(JSON.stringify(model))
99
- }
100
- } catch (err) {
101
- console.error(err)
102
- }
103
-
104
- this._scene = create({
105
- model,
106
- mode: SCENE_MODE.VIEW,
107
- refProvider: this.provider!,
108
- dataStorage: new BoardDataStorage(this.board.id),
109
- dataSubscriptionProvider: new DataSubscriptionProviderImpl()
110
- })
111
-
112
- if (this.baseUrl) {
113
- this._scene.baseUrl = this.baseUrl
114
- }
115
-
116
- this.setupScene({ id: this.board.id, scene: this._scene })
117
- }
118
-
119
- closeScene() {
120
- if (this._scene) {
121
- this._scene.target = null
122
- this._scene.release && this._scene.release()
123
-
124
- this._scene = null
125
- }
126
- }
127
-
128
- setupScene({ id, scene }: { id: string; scene: any }) {
129
- this._scene = scene
130
-
131
- const backgroundColor = this._scene?.root.state.fillStyle
132
- if (typeof backgroundColor === 'string') {
133
- this.style.backgroundColor = backgroundColor
134
- } else {
135
- this.style.backgroundColor = 'initial'
136
- }
137
-
138
- this._scene.target = this._targetEl
139
-
140
- requestAnimationFrame(() => {
141
- if (this._scene.target.offsetWidth) {
142
- this._scene.fit()
143
- }
144
- })
145
-
146
- if (this.data) {
147
- this._scene.data = this.data
148
- }
149
- }
150
- }
@@ -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
- }