@operato/board 8.0.0-alpha.3 → 8.0.0-alpha.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.
- package/CHANGELOG.md +164 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/ox-board-player.js +2 -1
- package/dist/src/ox-board-player.js.map +1 -1
- package/dist/src/ox-board-template-viewer.d.ts +27 -0
- package/dist/src/ox-board-template-viewer.js +178 -0
- package/dist/src/ox-board-template-viewer.js.map +1 -0
- package/dist/src/player/ox-board-wrapper.js +3 -1
- package/dist/src/player/ox-board-wrapper.js.map +1 -1
- package/dist/src/selector/ox-board-selector.d.ts +2 -0
- package/dist/src/selector/ox-board-selector.js +40 -8
- package/dist/src/selector/ox-board-selector.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -16
- package/src/index.ts +1 -0
- package/src/ox-board-player.ts +3 -1
- package/src/ox-board-template-viewer.ts +198 -0
- package/src/player/ox-board-wrapper.ts +3 -1
- package/src/selector/ox-board-selector.ts +41 -8
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@operato/board",
|
3
|
-
"version": "8.0.0-alpha.
|
3
|
+
"version": "8.0.0-alpha.33",
|
4
4
|
"description": "Webcomponent for board following open-wc recommendations",
|
5
5
|
"author": "heartyoh",
|
6
6
|
"main": "dist/src/index.js",
|
@@ -26,6 +26,7 @@
|
|
26
26
|
"./ox-board-list.js": "./dist/src/ox-board-list.js",
|
27
27
|
"./ox-board-template-list.js": "./dist/src/ox-board-template-list.js",
|
28
28
|
"./ox-board-viewer.js": "./dist/src/ox-board-viewer.js",
|
29
|
+
"./ox-board-template-viewer.js": "./dist/src/ox-board-template-viewer.js",
|
29
30
|
"./ox-board-player.js": "./dist/src/ox-board-player.js",
|
30
31
|
"./ox-board-modeller.js": "./dist/src/ox-board-modeller.js",
|
31
32
|
"./ox-editor-board-selector.js": "./dist/src/ox-editor-board-selector.js",
|
@@ -57,6 +58,9 @@
|
|
57
58
|
"ox-board-viewer.js": [
|
58
59
|
"./dist/src/ox-board-viewer.d.ts"
|
59
60
|
],
|
61
|
+
"ox-board-template-viewer.js": [
|
62
|
+
"./dist/src/ox-board-template-viewer.d.ts"
|
63
|
+
],
|
60
64
|
"ox-board-player.js": [
|
61
65
|
"./dist/src/ox-board-player.d.ts"
|
62
66
|
],
|
@@ -95,18 +99,18 @@
|
|
95
99
|
"dependencies": {
|
96
100
|
"@material/web": "^2.0.0",
|
97
101
|
"@open-wc/scoped-elements": "^2.1.3",
|
98
|
-
"@operato/app": "^8.0.0-alpha.
|
99
|
-
"@operato/data-grist": "^8.0.0-alpha.
|
100
|
-
"@operato/font": "^8.0.0-alpha.
|
101
|
-
"@operato/graphql": "^8.0.0-alpha.
|
102
|
-
"@operato/i18n": "^8.0.0-alpha.
|
103
|
-
"@operato/input": "^8.0.0-alpha.
|
104
|
-
"@operato/layout": "^8.0.0-alpha.
|
105
|
-
"@operato/markdown": "^8.0.0-alpha.
|
106
|
-
"@operato/popup": "^8.0.0-alpha.
|
107
|
-
"@operato/property-editor": "^8.0.0-alpha.
|
108
|
-
"@operato/styles": "^8.0.0-alpha.
|
109
|
-
"@operato/utils": "^8.0.0-alpha.
|
102
|
+
"@operato/app": "^8.0.0-alpha.33",
|
103
|
+
"@operato/data-grist": "^8.0.0-alpha.33",
|
104
|
+
"@operato/font": "^8.0.0-alpha.33",
|
105
|
+
"@operato/graphql": "^8.0.0-alpha.33",
|
106
|
+
"@operato/i18n": "^8.0.0-alpha.33",
|
107
|
+
"@operato/input": "^8.0.0-alpha.33",
|
108
|
+
"@operato/layout": "^8.0.0-alpha.33",
|
109
|
+
"@operato/markdown": "^8.0.0-alpha.33",
|
110
|
+
"@operato/popup": "^8.0.0-alpha.33",
|
111
|
+
"@operato/property-editor": "^8.0.0-alpha.33",
|
112
|
+
"@operato/styles": "^8.0.0-alpha.33",
|
113
|
+
"@operato/utils": "^8.0.0-alpha.33",
|
110
114
|
"@polymer/paper-dropdown-menu": "^3.2.0",
|
111
115
|
"@types/file-saver": "^2.0.4",
|
112
116
|
"@types/sortablejs": "^1.10.7",
|
@@ -123,8 +127,8 @@
|
|
123
127
|
"@hatiolab/things-scene": "^8.0.0-alpha",
|
124
128
|
"@open-wc/eslint-config": "^12.0.3",
|
125
129
|
"@open-wc/testing": "^3.1.6",
|
126
|
-
"@rollup/plugin-image": "^
|
127
|
-
"@rollup/plugin-json": "^
|
130
|
+
"@rollup/plugin-image": "^3.0.3",
|
131
|
+
"@rollup/plugin-json": "^6.1.0",
|
128
132
|
"@types/lodash-es": "^4.17.6",
|
129
133
|
"@types/w3c-web-usb": "^1.0.5",
|
130
134
|
"@typescript-eslint/eslint-plugin": "^7.0.1",
|
@@ -155,5 +159,5 @@
|
|
155
159
|
"prettier --write"
|
156
160
|
]
|
157
161
|
},
|
158
|
-
"gitHead": "
|
162
|
+
"gitHead": "f5fb8cd2bf7aed9781b75e9fa2e3cf53181641c9"
|
159
163
|
}
|
package/src/index.ts
CHANGED
package/src/ox-board-player.ts
CHANGED
@@ -301,7 +301,9 @@ export class BoardPlayer extends LitElement {
|
|
301
301
|
}
|
302
302
|
|
303
303
|
async start() {
|
304
|
-
if (!this.boards || this.boards.length == 0)
|
304
|
+
if (!this.boards || this.boards.length == 0) {
|
305
|
+
return
|
306
|
+
}
|
305
307
|
|
306
308
|
this.started = true
|
307
309
|
this.playing = true
|
@@ -0,0 +1,198 @@
|
|
1
|
+
import '@material/web/icon/icon.js'
|
2
|
+
import '@material/web/fab/fab.js'
|
3
|
+
|
4
|
+
import { css, html, LitElement, PropertyValues } from 'lit'
|
5
|
+
import { customElement, property, query, state } from 'lit/decorators.js'
|
6
|
+
|
7
|
+
import { create, SCENE_MODE } from '@hatiolab/things-scene'
|
8
|
+
import { ScrollbarStyles } from '@operato/styles'
|
9
|
+
|
10
|
+
@customElement('ox-board-template-viewer')
|
11
|
+
export class BoardTemplateViewer extends LitElement {
|
12
|
+
static styles = [
|
13
|
+
ScrollbarStyles,
|
14
|
+
css`
|
15
|
+
:host {
|
16
|
+
display: flex;
|
17
|
+
flex-direction: column;
|
18
|
+
|
19
|
+
position: relative;
|
20
|
+
|
21
|
+
width: 100%; /* 전체화면보기를 위해서 필요함. */
|
22
|
+
overflow: hidden;
|
23
|
+
}
|
24
|
+
|
25
|
+
#target {
|
26
|
+
flex: 1;
|
27
|
+
|
28
|
+
width: 100%; /* 전체화면보기를 위해서 필요함. */
|
29
|
+
height: 100%;
|
30
|
+
|
31
|
+
outline: 0;
|
32
|
+
}
|
33
|
+
|
34
|
+
@media print {
|
35
|
+
md-fab,
|
36
|
+
md-icon {
|
37
|
+
display: none;
|
38
|
+
}
|
39
|
+
}
|
40
|
+
`
|
41
|
+
]
|
42
|
+
|
43
|
+
@property({ type: Object }) boardTemplate: any = {}
|
44
|
+
|
45
|
+
@state() _scene: any = null
|
46
|
+
|
47
|
+
@query('#target') _target!: HTMLElement
|
48
|
+
|
49
|
+
render() {
|
50
|
+
return html` <div id="target"></div> `
|
51
|
+
}
|
52
|
+
|
53
|
+
private resizeHandler = () => {
|
54
|
+
this._scene && this._scene.fit()
|
55
|
+
}
|
56
|
+
|
57
|
+
connectedCallback() {
|
58
|
+
super.connectedCallback()
|
59
|
+
|
60
|
+
window.addEventListener('resize', this.resizeHandler)
|
61
|
+
|
62
|
+
window.addEventListener('orientationchange', this.resizeHandler)
|
63
|
+
}
|
64
|
+
|
65
|
+
disconnectedCallback() {
|
66
|
+
window.removeEventListener('resize', this.resizeHandler)
|
67
|
+
window.removeEventListener('orientationchange', this.resizeHandler)
|
68
|
+
|
69
|
+
super.disconnectedCallback()
|
70
|
+
|
71
|
+
this.closeScene()
|
72
|
+
}
|
73
|
+
|
74
|
+
updated(changes: PropertyValues<this>) {
|
75
|
+
if (changes.has('boardTemplate')) {
|
76
|
+
this.closeScene()
|
77
|
+
|
78
|
+
if (this.boardTemplate && this.boardTemplate.id) {
|
79
|
+
this.initScene()
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
initScene() {
|
85
|
+
if (!this.boardTemplate || !this.boardTemplate.id) return
|
86
|
+
|
87
|
+
this._scene = create({
|
88
|
+
model: {
|
89
|
+
...this.boardTemplate.model
|
90
|
+
},
|
91
|
+
mode: SCENE_MODE.VIEW
|
92
|
+
})
|
93
|
+
|
94
|
+
this.setupScene({ id: this.boardTemplate.id, scene: this._scene })
|
95
|
+
}
|
96
|
+
|
97
|
+
closeScene() {
|
98
|
+
if (this._scene) {
|
99
|
+
this._scene.target = null
|
100
|
+
this._scene.release && this._scene.release()
|
101
|
+
|
102
|
+
this._scene = null
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
releaseScene() {
|
107
|
+
this.closeScene()
|
108
|
+
}
|
109
|
+
|
110
|
+
setupScene({ id, scene }: { id: string; scene: any }) {
|
111
|
+
this._scene = scene
|
112
|
+
|
113
|
+
const backgroundColor = this._scene?.root.state.fillStyle
|
114
|
+
if (typeof backgroundColor === 'string') {
|
115
|
+
this.style.backgroundColor = backgroundColor
|
116
|
+
} else {
|
117
|
+
this.style.backgroundColor = 'initial'
|
118
|
+
}
|
119
|
+
|
120
|
+
/* scene의 기존 target을 보관한다. */
|
121
|
+
|
122
|
+
this._scene.fit(this._scene.fitMode)
|
123
|
+
this._scene.target = this._target
|
124
|
+
}
|
125
|
+
|
126
|
+
/* event handlers */
|
127
|
+
async getSceneImageData(base64 = false) {
|
128
|
+
if (!this._scene) {
|
129
|
+
return
|
130
|
+
}
|
131
|
+
|
132
|
+
var { width, height } = this._scene.model
|
133
|
+
var pixelRatio = window.devicePixelRatio
|
134
|
+
|
135
|
+
// 1. Scene의 바운드에 근거하여, 오프스크린 캔바스를 만든다.
|
136
|
+
var canvas = document.createElement('canvas')
|
137
|
+
canvas.width = Number(width)
|
138
|
+
canvas.height = Number(height)
|
139
|
+
|
140
|
+
var root = this._scene.root
|
141
|
+
// 2. 모델레이어의 원래 위치와 스케일을 저장한다.
|
142
|
+
var translate = root.get('translate')
|
143
|
+
var scale = root.get('scale')
|
144
|
+
|
145
|
+
// 3. 위치와 스케일 기본 설정.
|
146
|
+
root.set('translate', { x: 0, y: 0 })
|
147
|
+
root.set('scale', { x: 1 / pixelRatio, y: 1 / pixelRatio })
|
148
|
+
|
149
|
+
// 4. 오프스크린 캔바스의 Context2D를 구한뒤, 모델레이어를 그 위에 그린다.
|
150
|
+
var context = canvas.getContext('2d')
|
151
|
+
|
152
|
+
root.draw(context)
|
153
|
+
|
154
|
+
root.set('translate', translate)
|
155
|
+
root.set('scale', scale)
|
156
|
+
|
157
|
+
var data = base64 ? canvas.toDataURL() : context!.getImageData(0, 0, width, height).data
|
158
|
+
|
159
|
+
return {
|
160
|
+
width,
|
161
|
+
height,
|
162
|
+
data
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
async printTrick(image: string) {
|
167
|
+
var viewTarget: HTMLElement | null = null
|
168
|
+
var printTarget: HTMLImageElement | null = null
|
169
|
+
|
170
|
+
if (!image) {
|
171
|
+
image = (await this.getSceneImageData(true))?.data as string
|
172
|
+
}
|
173
|
+
|
174
|
+
printTarget = document.createElement('img')
|
175
|
+
printTarget.id = 'target'
|
176
|
+
printTarget.src = image
|
177
|
+
printTarget.style.width = '100%'
|
178
|
+
printTarget.style.height = '100%'
|
179
|
+
|
180
|
+
const x = (mql: MediaQueryListEvent) => {
|
181
|
+
if (mql.matches) {
|
182
|
+
if (!viewTarget) {
|
183
|
+
viewTarget = (this.renderRoot as ShadowRoot)!.getElementById('target')
|
184
|
+
this.renderRoot.replaceChild(printTarget!, viewTarget!)
|
185
|
+
}
|
186
|
+
} else {
|
187
|
+
this.renderRoot.replaceChild(viewTarget!, printTarget!)
|
188
|
+
printTarget!.remove()
|
189
|
+
mediaQueryList.removeEventListener('change', x)
|
190
|
+
}
|
191
|
+
}
|
192
|
+
|
193
|
+
if (window.matchMedia) {
|
194
|
+
var mediaQueryList = window.matchMedia('print')
|
195
|
+
mediaQueryList.addEventListener('change', x)
|
196
|
+
}
|
197
|
+
}
|
198
|
+
}
|
@@ -81,6 +81,8 @@ class BoardWrapper extends LitElement {
|
|
81
81
|
}
|
82
82
|
|
83
83
|
_onBoardChanged() {
|
84
|
+
this.closeScene()
|
85
|
+
|
84
86
|
this.initScene()
|
85
87
|
}
|
86
88
|
|
@@ -138,7 +140,7 @@ class BoardWrapper extends LitElement {
|
|
138
140
|
this._scene.target = this._targetEl
|
139
141
|
|
140
142
|
requestAnimationFrame(() => {
|
141
|
-
if (this._scene
|
143
|
+
if (this._scene?.target.offsetWidth) {
|
142
144
|
this._scene.fit()
|
143
145
|
}
|
144
146
|
})
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import '@operato/input/ox-input-search.js'
|
1
2
|
import './ox-board-creation-card'
|
2
3
|
|
3
4
|
import gql from 'graphql-tag'
|
@@ -9,6 +10,7 @@ import { i18next, localize } from '@operato/i18n'
|
|
9
10
|
import { ScrollbarStyles } from '@operato/styles'
|
10
11
|
import InfiniteScrollable from '@operato/utils/mixins/infinite-scrollable.js'
|
11
12
|
import { InheritedValueType } from '@operato/shell'
|
13
|
+
import { adjustFilters } from '@operato/utils'
|
12
14
|
|
13
15
|
const FETCH_BOARD_LIST_GQL = gql`
|
14
16
|
query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!], $inherited: InheritedValueType) {
|
@@ -97,7 +99,7 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
97
99
|
.card > .name {
|
98
100
|
color: var(--md-sys-color-on-secondary);
|
99
101
|
background-color: var(--md-sys-color-secondary);
|
100
|
-
opacity: 0.
|
102
|
+
opacity: 0.9;
|
101
103
|
margin-top: -35px;
|
102
104
|
width: 100%;
|
103
105
|
font-weight: bolder;
|
@@ -106,12 +108,11 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
106
108
|
}
|
107
109
|
|
108
110
|
.card > .description {
|
109
|
-
color: var(--md-sys-color-on-
|
110
|
-
background-color: var(--md-sys-color-
|
111
|
+
color: var(--md-sys-color-on-secondary);
|
112
|
+
background-color: var(--md-sys-color-secondary);
|
111
113
|
width: 100%;
|
112
|
-
min-height:
|
114
|
+
min-height: 16px;
|
113
115
|
font-size: 0.6rem;
|
114
|
-
color: #fff;
|
115
116
|
text-indent: 7px;
|
116
117
|
}
|
117
118
|
.card img {
|
@@ -120,12 +121,22 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
120
121
|
}
|
121
122
|
|
122
123
|
#filter {
|
124
|
+
display: flex;
|
125
|
+
align-items: center;
|
123
126
|
padding: var(--popup-content-padding);
|
124
127
|
color: var(--md-sys-color-on-surface-variant);
|
125
128
|
background-color: var(--md-sys-color-surface-variant);
|
126
129
|
box-shadow: var(--box-shadow);
|
127
130
|
}
|
128
131
|
|
132
|
+
#filter > ox-input-search {
|
133
|
+
margin-right: auto;
|
134
|
+
border: var(--md-sys-color-primary) 1px solid;
|
135
|
+
padding: var(--spacing-small) var(--spacing-small);
|
136
|
+
border-radius: 999px;
|
137
|
+
color: var(--md-sys-color-primary);
|
138
|
+
}
|
139
|
+
|
129
140
|
#filter > div {
|
130
141
|
float: right;
|
131
142
|
margin-left: 10px;
|
@@ -145,6 +156,7 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
145
156
|
@property({ type: Array }) groups: { id: string; name: string; description: string }[] = []
|
146
157
|
@property({ type: Array }) boards: any[] = []
|
147
158
|
@property({ type: String }) group?: string
|
159
|
+
@property({ type: String }) search?: string
|
148
160
|
@property({ type: String }) inherited?: InheritedValueType = InheritedValueType.Include
|
149
161
|
@property({ type: Boolean }) creatable: boolean = false
|
150
162
|
@property({ type: String }) value?: string
|
@@ -161,6 +173,11 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
161
173
|
render() {
|
162
174
|
return html`
|
163
175
|
<div id="filter">
|
176
|
+
<ox-input-search
|
177
|
+
@change=${(e: Event) => {
|
178
|
+
this.search = (e.currentTarget as any)?.value
|
179
|
+
}}
|
180
|
+
></ox-input-search>
|
164
181
|
<div>
|
165
182
|
<label for="group">Group</label>
|
166
183
|
<select
|
@@ -233,7 +250,7 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
233
250
|
}
|
234
251
|
|
235
252
|
async updated(changed: PropertyValues<this>) {
|
236
|
-
if (changed.has('group') || changed.has('inherited')) {
|
253
|
+
if (changed.has('group') || changed.has('inherited') || changed.has('search')) {
|
237
254
|
this.refreshBoards()
|
238
255
|
}
|
239
256
|
}
|
@@ -294,12 +311,29 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
294
311
|
page
|
295
312
|
}
|
296
313
|
|
297
|
-
if (this.group)
|
314
|
+
if (this.group) {
|
298
315
|
filters.push({
|
299
316
|
name: 'groupId',
|
300
317
|
operator: 'eq',
|
301
318
|
value: this.group
|
302
319
|
})
|
320
|
+
}
|
321
|
+
|
322
|
+
if (this.search) {
|
323
|
+
const value = `%${this.search.trim()}%`
|
324
|
+
|
325
|
+
filters.push({
|
326
|
+
name: 'name',
|
327
|
+
operator: 'search',
|
328
|
+
value: this.search
|
329
|
+
})
|
330
|
+
|
331
|
+
filters.push({
|
332
|
+
name: 'description',
|
333
|
+
operator: 'search',
|
334
|
+
value: this.search
|
335
|
+
})
|
336
|
+
}
|
303
337
|
|
304
338
|
var variables = {
|
305
339
|
filters,
|
@@ -310,7 +344,6 @@ export class BoardSelector extends InfiniteScrollable(localize(i18next)(LitEleme
|
|
310
344
|
|
311
345
|
var boardListResponse = await client.query({
|
312
346
|
query: FETCH_BOARD_LIST_GQL,
|
313
|
-
context: gqlContext(),
|
314
347
|
variables
|
315
348
|
})
|
316
349
|
|