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

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