@operato/process 1.1.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 (197) hide show
  1. package/.storybook/main.js +3 -0
  2. package/.storybook/server.mjs +8 -0
  3. package/CHANGELOG.md +1824 -0
  4. package/LICENSE +21 -0
  5. package/README.md +95 -0
  6. package/demo/index-modeller.html +101 -0
  7. package/demo/index-viewer.html +101 -0
  8. package/demo/index.html +101 -0
  9. package/dist/src/data-storage/data-storage.d.ts +8 -0
  10. package/dist/src/data-storage/data-storage.js +28 -0
  11. package/dist/src/data-storage/data-storage.js.map +1 -0
  12. package/dist/src/graphql/data-subscription.d.ts +5 -0
  13. package/dist/src/graphql/data-subscription.js +24 -0
  14. package/dist/src/graphql/data-subscription.js.map +1 -0
  15. package/dist/src/graphql/favorite-process.d.ts +1 -0
  16. package/dist/src/graphql/favorite-process.js +23 -0
  17. package/dist/src/graphql/favorite-process.js.map +1 -0
  18. package/dist/src/graphql/index.d.ts +3 -0
  19. package/dist/src/graphql/index.js +4 -0
  20. package/dist/src/graphql/index.js.map +1 -0
  21. package/dist/src/graphql/process-group.d.ts +7 -0
  22. package/dist/src/graphql/process-group.js +125 -0
  23. package/dist/src/graphql/process-group.js.map +1 -0
  24. package/dist/src/graphql/process.d.ts +6 -0
  25. package/dist/src/graphql/process.js +130 -0
  26. package/dist/src/graphql/process.js.map +1 -0
  27. package/dist/src/graphql/scenario.d.ts +6 -0
  28. package/dist/src/graphql/scenario.js +69 -0
  29. package/dist/src/graphql/scenario.js.map +1 -0
  30. package/dist/src/index.d.ts +5 -0
  31. package/dist/src/index.js +6 -0
  32. package/dist/src/index.js.map +1 -0
  33. package/dist/src/modeller/component-toolbar/component-detail.d.ts +12 -0
  34. package/dist/src/modeller/component-toolbar/component-detail.js +58 -0
  35. package/dist/src/modeller/component-toolbar/component-detail.js.map +1 -0
  36. package/dist/src/modeller/component-toolbar/component-menu.d.ts +24 -0
  37. package/dist/src/modeller/component-toolbar/component-menu.js +190 -0
  38. package/dist/src/modeller/component-toolbar/component-menu.js.map +1 -0
  39. package/dist/src/modeller/component-toolbar/component-toolbar.d.ts +28 -0
  40. package/dist/src/modeller/component-toolbar/component-toolbar.js +168 -0
  41. package/dist/src/modeller/component-toolbar/component-toolbar.js.map +1 -0
  42. package/dist/src/modeller/component-toolbar/mode-icons.d.ts +2 -0
  43. package/dist/src/modeller/component-toolbar/mode-icons.js +86 -0
  44. package/dist/src/modeller/component-toolbar/mode-icons.js.map +1 -0
  45. package/dist/src/modeller/edit-toolbar-style.d.ts +4 -0
  46. package/dist/src/modeller/edit-toolbar-style.js +227 -0
  47. package/dist/src/modeller/edit-toolbar-style.js.map +1 -0
  48. package/dist/src/modeller/edit-toolbar.d.ts +61 -0
  49. package/dist/src/modeller/edit-toolbar.js +641 -0
  50. package/dist/src/modeller/edit-toolbar.js.map +1 -0
  51. package/dist/src/modeller/property-sidebar/abstract-property.d.ts +10 -0
  52. package/dist/src/modeller/property-sidebar/abstract-property.js +55 -0
  53. package/dist/src/modeller/property-sidebar/abstract-property.js.map +1 -0
  54. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.d.ts +4 -0
  55. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.js +61 -0
  56. package/dist/src/modeller/property-sidebar/effects/effects-shared-style.js.map +1 -0
  57. package/dist/src/modeller/property-sidebar/effects/effects.d.ts +20 -0
  58. package/dist/src/modeller/property-sidebar/effects/effects.js +42 -0
  59. package/dist/src/modeller/property-sidebar/effects/effects.js.map +1 -0
  60. package/dist/src/modeller/property-sidebar/effects/property-shadow.d.ts +23 -0
  61. package/dist/src/modeller/property-sidebar/effects/property-shadow.js +103 -0
  62. package/dist/src/modeller/property-sidebar/effects/property-shadow.js.map +1 -0
  63. package/dist/src/modeller/property-sidebar/effects/value-converter.d.ts +1 -0
  64. package/dist/src/modeller/property-sidebar/effects/value-converter.js +21 -0
  65. package/dist/src/modeller/property-sidebar/effects/value-converter.js.map +1 -0
  66. package/dist/src/modeller/property-sidebar/inspector/inspector.d.ts +29 -0
  67. package/dist/src/modeller/property-sidebar/inspector/inspector.js +318 -0
  68. package/dist/src/modeller/property-sidebar/inspector/inspector.js.map +1 -0
  69. package/dist/src/modeller/property-sidebar/property-shared-style.d.ts +4 -0
  70. package/dist/src/modeller/property-sidebar/property-shared-style.js +135 -0
  71. package/dist/src/modeller/property-sidebar/property-shared-style.js.map +1 -0
  72. package/dist/src/modeller/property-sidebar/property-sidebar.d.ts +43 -0
  73. package/dist/src/modeller/property-sidebar/property-sidebar.js +309 -0
  74. package/dist/src/modeller/property-sidebar/property-sidebar.js.map +1 -0
  75. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.d.ts +1 -0
  76. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.js +94 -0
  77. package/dist/src/modeller/property-sidebar/shapes/box-padding-editor-styles.js.map +1 -0
  78. package/dist/src/modeller/property-sidebar/shapes/shapes.d.ts +28 -0
  79. package/dist/src/modeller/property-sidebar/shapes/shapes.js +321 -0
  80. package/dist/src/modeller/property-sidebar/shapes/shapes.js.map +1 -0
  81. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.d.ts +16 -0
  82. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.js +132 -0
  83. package/dist/src/modeller/property-sidebar/specifics/specific-properties-builder.js.map +1 -0
  84. package/dist/src/modeller/property-sidebar/specifics/specifics.d.ts +25 -0
  85. package/dist/src/modeller/property-sidebar/specifics/specifics.js +81 -0
  86. package/dist/src/modeller/property-sidebar/specifics/specifics.js.map +1 -0
  87. package/dist/src/modeller/property-sidebar/styles/styles.d.ts +21 -0
  88. package/dist/src/modeller/property-sidebar/styles/styles.js +559 -0
  89. package/dist/src/modeller/property-sidebar/styles/styles.js.map +1 -0
  90. package/dist/src/modeller/scene-viewer/scene-handler.d.ts +11 -0
  91. package/dist/src/modeller/scene-viewer/scene-handler.js +32 -0
  92. package/dist/src/modeller/scene-viewer/scene-handler.js.map +1 -0
  93. package/dist/src/modeller/scene-viewer/scene-layer.d.ts +10 -0
  94. package/dist/src/modeller/scene-viewer/scene-layer.js +38 -0
  95. package/dist/src/modeller/scene-viewer/scene-layer.js.map +1 -0
  96. package/dist/src/modeller/scene-viewer/scene-property.d.ts +6 -0
  97. package/dist/src/modeller/scene-viewer/scene-property.js +15 -0
  98. package/dist/src/modeller/scene-viewer/scene-property.js.map +1 -0
  99. package/dist/src/modeller/scene-viewer/scene-viewer.d.ts +38 -0
  100. package/dist/src/modeller/scene-viewer/scene-viewer.js +243 -0
  101. package/dist/src/modeller/scene-viewer/scene-viewer.js.map +1 -0
  102. package/dist/src/ox-process-list.d.ts +2 -0
  103. package/dist/src/ox-process-list.js +427 -0
  104. package/dist/src/ox-process-list.js.map +1 -0
  105. package/dist/src/ox-process-modeller.d.ts +58 -0
  106. package/dist/src/ox-process-modeller.js +396 -0
  107. package/dist/src/ox-process-modeller.js.map +1 -0
  108. package/dist/src/ox-process-viewer.d.ts +51 -0
  109. package/dist/src/ox-process-viewer.js +512 -0
  110. package/dist/src/ox-process-viewer.js.map +1 -0
  111. package/dist/src/types.d.ts +37 -0
  112. package/dist/src/types.js +2 -0
  113. package/dist/src/types.js.map +1 -0
  114. package/dist/stories/index.stories.d.ts +33 -0
  115. package/dist/stories/index.stories.js +33 -0
  116. package/dist/stories/index.stories.js.map +1 -0
  117. package/dist/tsconfig.tsbuildinfo +1 -0
  118. package/icons/components/audio.png +0 -0
  119. package/icons/components/both-arrow.png +0 -0
  120. package/icons/components/color-image.png +0 -0
  121. package/icons/components/container.png +0 -0
  122. package/icons/components/dash.png +0 -0
  123. package/icons/components/donut.png +0 -0
  124. package/icons/components/ellipse.png +0 -0
  125. package/icons/components/forklift.png +0 -0
  126. package/icons/components/gif-image.png +0 -0
  127. package/icons/components/global-reference.png +0 -0
  128. package/icons/components/gray-image.png +0 -0
  129. package/icons/components/humidity-sensor.png +0 -0
  130. package/icons/components/info-window.png +0 -0
  131. package/icons/components/line.png +0 -0
  132. package/icons/components/local-reference.png +0 -0
  133. package/icons/components/no-image.png +0 -0
  134. package/icons/components/ortholine.png +0 -0
  135. package/icons/components/person.png +0 -0
  136. package/icons/components/polygon.png +0 -0
  137. package/icons/components/polyline.png +0 -0
  138. package/icons/components/popup.png +0 -0
  139. package/icons/components/rect.png +0 -0
  140. package/icons/components/single-arrow.png +0 -0
  141. package/icons/components/star.png +0 -0
  142. package/icons/components/streamline.png +0 -0
  143. package/icons/components/text.png +0 -0
  144. package/icons/components/triangle.png +0 -0
  145. package/icons/icon-collapse-active.png +0 -0
  146. package/icons/icon-collapse.png +0 -0
  147. package/icons/icon-fullscreen.png +0 -0
  148. package/icons/icon-htoolbar.png +0 -0
  149. package/icons/icon-properties-arrow-type.png +0 -0
  150. package/icons/icon-properties-gradient-direction.png +0 -0
  151. package/icons/icon-properties-label.png +0 -0
  152. package/icons/icon-properties-line-type.png +0 -0
  153. package/icons/icon-properties-padding.png +0 -0
  154. package/icons/icon-properties-ratio.png +0 -0
  155. package/icons/icon-properties-table.png +0 -0
  156. package/icons/icon-properties.png +0 -0
  157. package/icons/icon-shell-inspector.png +0 -0
  158. package/package.json +115 -0
  159. package/src/data-storage/data-storage.ts +47 -0
  160. package/src/graphql/data-subscription.ts +30 -0
  161. package/src/graphql/favorite-process.ts +25 -0
  162. package/src/graphql/index.ts +3 -0
  163. package/src/graphql/process-group.ts +138 -0
  164. package/src/graphql/process.ts +144 -0
  165. package/src/graphql/scenario.ts +79 -0
  166. package/src/index.ts +7 -0
  167. package/src/modeller/component-toolbar/component-detail.ts +58 -0
  168. package/src/modeller/component-toolbar/component-menu.ts +187 -0
  169. package/src/modeller/component-toolbar/component-toolbar.ts +173 -0
  170. package/src/modeller/component-toolbar/mode-icons.ts +86 -0
  171. package/src/modeller/edit-toolbar-style.ts +228 -0
  172. package/src/modeller/edit-toolbar.ts +641 -0
  173. package/src/modeller/property-sidebar/abstract-property.ts +69 -0
  174. package/src/modeller/property-sidebar/effects/effects-shared-style.ts +62 -0
  175. package/src/modeller/property-sidebar/effects/effects.ts +47 -0
  176. package/src/modeller/property-sidebar/effects/property-shadow.ts +114 -0
  177. package/src/modeller/property-sidebar/effects/value-converter.ts +23 -0
  178. package/src/modeller/property-sidebar/inspector/inspector.ts +361 -0
  179. package/src/modeller/property-sidebar/property-shared-style.ts +136 -0
  180. package/src/modeller/property-sidebar/property-sidebar.ts +308 -0
  181. package/src/modeller/property-sidebar/shapes/box-padding-editor-styles.ts +94 -0
  182. package/src/modeller/property-sidebar/shapes/shapes.ts +326 -0
  183. package/src/modeller/property-sidebar/specifics/specific-properties-builder.ts +144 -0
  184. package/src/modeller/property-sidebar/specifics/specifics.ts +77 -0
  185. package/src/modeller/property-sidebar/styles/styles.ts +577 -0
  186. package/src/modeller/scene-viewer/scene-handler.ts +39 -0
  187. package/src/modeller/scene-viewer/scene-layer.ts +41 -0
  188. package/src/modeller/scene-viewer/scene-property.ts +9 -0
  189. package/src/modeller/scene-viewer/scene-viewer.ts +249 -0
  190. package/src/ox-process-list.ts +459 -0
  191. package/src/ox-process-modeller.ts +396 -0
  192. package/src/ox-process-viewer.ts +555 -0
  193. package/src/types.ts +68 -0
  194. package/stories/index.stories.ts +52 -0
  195. package/tsconfig.json +23 -0
  196. package/web-dev-server.config.mjs +30 -0
  197. package/web-test-runner.config.mjs +29 -0
@@ -0,0 +1,555 @@
1
+ import '@material/mwc-fab'
2
+ import '@material/mwc-icon'
3
+
4
+ import { css, html, LitElement, PropertyValues } from 'lit'
5
+ import { customElement, property, query, state } from 'lit/decorators.js'
6
+
7
+ import { Component, create, ReferenceProvider, SCENE_MODE } from '@hatiolab/things-scene'
8
+ import { isIOS, togglefullscreen } from '@operato/utils'
9
+
10
+ import { DataStorage } from './data-storage/data-storage.js'
11
+ import { DataSubscriptionProviderImpl } from './graphql/data-subscription.js'
12
+ import { runScenario, startScenario } from './graphql/scenario.js'
13
+
14
+ @customElement('ox-process-viewer')
15
+ export class OxProcessViewer extends LitElement {
16
+ static styles = css`
17
+ :host {
18
+ display: flex;
19
+ flex-direction: column;
20
+
21
+ position: relative;
22
+
23
+ width: 100%; /* 전체화면보기를 위해서 필요함. */
24
+ overflow: hidden;
25
+ }
26
+
27
+ #target {
28
+ flex: 1;
29
+
30
+ width: 100%; /* 전체화면보기를 위해서 필요함. */
31
+ height: 100%;
32
+
33
+ outline: 0;
34
+ }
35
+
36
+ /* navigation buttons */
37
+ mwc-icon {
38
+ z-index: 10;
39
+ position: absolute;
40
+ top: 45%;
41
+ min-width: 50px;
42
+ width: 50px;
43
+ height: 50px;
44
+ margin: 0;
45
+ padding: 0;
46
+ color: #fff;
47
+ user-select: none;
48
+
49
+ --mdc-icon-size: 3em;
50
+ }
51
+
52
+ mwc-icon[hidden] {
53
+ display: none;
54
+ }
55
+
56
+ mwc-icon:hover {
57
+ background-color: rgba(0, 0, 0, 0.2);
58
+ border-radius: 50%;
59
+ }
60
+
61
+ #prev {
62
+ left: 5px;
63
+ }
64
+
65
+ #next {
66
+ right: 5px;
67
+ }
68
+
69
+ #fullscreen {
70
+ position: absolute;
71
+ bottom: 15px;
72
+ right: 16px;
73
+ }
74
+
75
+ /* for scroller */
76
+ ::-webkit-scrollbar {
77
+ width: 5px;
78
+ height: 5px;
79
+ }
80
+ ::-webkit-scrollbar-track {
81
+ background-color: transparent;
82
+ }
83
+ ::-webkit-scrollbar-thumb {
84
+ background-color: rgba(0, 0, 0, 0.2);
85
+ }
86
+ ::-webkit-scrollbar-thumb:hover {
87
+ background-color: #aa866a;
88
+ }
89
+
90
+ [hidden] {
91
+ display: none;
92
+ }
93
+
94
+ @media print {
95
+ mwc-fab,
96
+ mwc-icon {
97
+ display: none;
98
+ }
99
+ }
100
+ `
101
+
102
+ @property({ type: String }) baseUrl: string = ''
103
+ @property({ type: Object }) process: any = {}
104
+ @property({ type: Object }) provider: ReferenceProvider | null = null
105
+ @property({ type: Object }) data: any
106
+
107
+ @property({ type: Boolean, reflect: true, attribute: 'hide-fullscreen' }) hideFullscreen = false
108
+ @property({ type: Boolean, reflect: true, attribute: 'hide-navigation' }) hideNavigation = false
109
+
110
+ @state() _scene: any = null
111
+ @state() _forward: Array<any> = []
112
+ @state() _backward: Array<any> = []
113
+
114
+ @state() _oldtarget?: HTMLElement
115
+ @state() _fade_animations?: Array<Animation>
116
+
117
+ @query('#target') _target!: HTMLElement
118
+ @query('#prev') _prev!: HTMLElement
119
+ @query('#next') _next!: HTMLElement
120
+ @query('#fullscreen') _fullscreen!: HTMLElement
121
+
122
+ render() {
123
+ var fullscreen =
124
+ !isIOS() && !this.hideFullscreen
125
+ ? html`
126
+ <mwc-fab
127
+ id="fullscreen"
128
+ .icon=${document.fullscreenElement ? 'fullscreen_exit' : 'fullscreen'}
129
+ @click=${(e: Event) => this.onTapFullscreen()}
130
+ @mouseover=${(e: Event) => this.transientShowButtons(true)}
131
+ @mouseout=${(e: Event) => this.transientShowButtons()}
132
+ title="fullscreen"
133
+ ></mwc-fab>
134
+ `
135
+ : html``
136
+
137
+ var prev = !this.hideNavigation
138
+ ? html`
139
+ <mwc-icon
140
+ id="prev"
141
+ @click=${(e: Event) => this.onTapPrev()}
142
+ @mouseover=${(e: Event) => this.transientShowButtons(true)}
143
+ @mouseout=${(e: Event) => this.transientShowButtons()}
144
+ hidden
145
+ >keyboard_arrow_left</mwc-icon
146
+ >
147
+ `
148
+ : html``
149
+
150
+ var next = !this.hideNavigation
151
+ ? html`
152
+ <mwc-icon
153
+ id="next"
154
+ @click=${(e: Event) => this.onTapNext()}
155
+ @mouseover=${(e: Event) => this.transientShowButtons(true)}
156
+ @mouseout=${(e: Event) => this.transientShowButtons()}
157
+ hidden
158
+ >keyboard_arrow_right</mwc-icon
159
+ >
160
+ `
161
+ : html``
162
+
163
+ return html`
164
+ ${prev}
165
+
166
+ <div
167
+ id="target"
168
+ @touchstart=${(e: Event) => this.transientShowButtons()}
169
+ @mousemove=${(e: Event) => this.transientShowButtons()}
170
+ ></div>
171
+
172
+ ${next} ${fullscreen}
173
+ `
174
+ }
175
+
176
+ connectedCallback() {
177
+ super.connectedCallback()
178
+
179
+ window.addEventListener('resize', () => {
180
+ this._scene && this._scene.fit()
181
+ })
182
+
183
+ this.renderRoot.addEventListener(
184
+ 'close-scene',
185
+ e => {
186
+ e.preventDefault()
187
+ this.onTapPrev()
188
+ },
189
+ false
190
+ )
191
+ }
192
+
193
+ disconnectedCallback() {
194
+ super.disconnectedCallback()
195
+
196
+ this.closeScene()
197
+ }
198
+
199
+ updated(changes: PropertyValues<this>) {
200
+ if (changes.has('process')) {
201
+ this.closeScene()
202
+
203
+ if (this.process && this.process.id) {
204
+ if (this.process.model) {
205
+ this.initScene()
206
+ } else {
207
+ this.initSceneAsync()
208
+ }
209
+ }
210
+ }
211
+
212
+ if (changes.has('data') && this._scene && this.data) {
213
+ this._scene.data = this.data
214
+ }
215
+ }
216
+
217
+ async initSceneAsync() {
218
+ if (!this.process || !this.process.id) return
219
+
220
+ this._scene = await this.provider!.get(this.process.id, true)
221
+ this.setupScene(this._scene)
222
+ }
223
+
224
+ initScene() {
225
+ if (!this.process || !this.process.id) return
226
+
227
+ this._scene = create({
228
+ model: {
229
+ ...this.process.model
230
+ },
231
+ mode: SCENE_MODE.VIEW,
232
+ refProvider: this.provider!,
233
+ dataStorage: this.process.id !== 'preview' ? new DataStorage(this.process.id) : undefined,
234
+ dataSubscriptionProvider: new DataSubscriptionProviderImpl()
235
+ })
236
+
237
+ if (this.baseUrl) {
238
+ this._scene.baseUrl = this.baseUrl
239
+ }
240
+
241
+ this.provider!.add(this.process.id, this._scene)
242
+
243
+ this.setupScene(this._scene)
244
+ }
245
+
246
+ closeScene() {
247
+ if (this._scene) {
248
+ this.unbindSceneEvents(this._scene)
249
+
250
+ this._scene.target = null
251
+ this._scene.release && this._scene.release()
252
+
253
+ this._scene = null
254
+ }
255
+
256
+ // delete queued scenes
257
+ this._forward.forEach(scene => scene.release && scene.release())
258
+ this._forward = []
259
+
260
+ this._backward.forEach(scene => scene.release && scene.release())
261
+ this._backward = []
262
+ }
263
+
264
+ releaseScene() {
265
+ this.closeScene()
266
+ this.transientShowButtons()
267
+ }
268
+
269
+ setupScene(scene: any) {
270
+ this._scene = scene
271
+
272
+ /* scene의 기존 target을 보관한다. */
273
+ this._oldtarget = this._scene.target
274
+
275
+ this._scene.fit(this._scene.fitMode)
276
+ this._scene.target = this._target
277
+
278
+ if (this.data) {
279
+ this._scene.data = this.data
280
+ }
281
+
282
+ this.bindSceneEvents()
283
+
284
+ this.transientShowButtons()
285
+ }
286
+
287
+ async showScene(processId: string, bindingData?: any) {
288
+ if (!processId) return
289
+
290
+ try {
291
+ var scene = await this.provider!.get(processId, true)
292
+
293
+ if (scene === this._scene) {
294
+ scene.release && scene.release()
295
+ return
296
+ }
297
+
298
+ if (this._scene) {
299
+ /* old scene을 _backward에 보관한다. */
300
+ this.unbindSceneEvents(this._scene)
301
+ /* 원래의 target에 되돌린다. */
302
+ this._scene.target = this._oldtarget
303
+ this._backward.push(this._scene)
304
+ }
305
+
306
+ this._scene = scene
307
+
308
+ this._forward.forEach(scene => scene.release && scene.release())
309
+
310
+ /* forward를 비운다. */
311
+ this._forward = []
312
+
313
+ this.setupScene(scene)
314
+
315
+ if (bindingData) {
316
+ scene.data = bindingData
317
+ }
318
+ } catch (e) {
319
+ console.error(e)
320
+ }
321
+ }
322
+
323
+ bindSceneEvents() {
324
+ this._scene.on('goto', this.onLinkGoto, this)
325
+ this._scene.on('link-open', this.onLinkOpen, this)
326
+ this._scene.on('link-move', this.onLinkMove, this)
327
+ this._scene.on('route-page', this.onRoutePage, this)
328
+ this._scene.on('start-scenario', this.onStartScenario, this)
329
+ this._scene.on('run-scenario', this.onRunScenario, this)
330
+ }
331
+
332
+ unbindSceneEvents(scene: any) {
333
+ scene.off('goto', this.onLinkGoto, this)
334
+ scene.off('link-open', this.onLinkOpen, this)
335
+ scene.off('link-move', this.onLinkMove, this)
336
+ scene.off('route-page', this.onRoutePage, this)
337
+ scene.off('start-scenario', this.onStartScenario, this)
338
+ scene.off('run-scenario', this.onRunScenario, this)
339
+ }
340
+
341
+ transientShowButtons(stop?: boolean) {
342
+ var buttons = []
343
+ !this.hideNavigation && buttons.push(this._next, this._prev)
344
+ !this.hideFullscreen && buttons.push(this._fullscreen)
345
+
346
+ if (buttons.length == 0) {
347
+ return
348
+ }
349
+
350
+ if (!this._fade_animations) {
351
+ this._fade_animations = buttons
352
+ .filter(button => button)
353
+ .map(button => {
354
+ let animation = button.animate(
355
+ [
356
+ {
357
+ opacity: 1,
358
+ easing: 'ease-in'
359
+ },
360
+ { opacity: 0 }
361
+ ],
362
+ { delay: 1000, duration: 2000 }
363
+ )
364
+
365
+ animation.onfinish = () => {
366
+ button.setAttribute('hidden', '')
367
+ }
368
+
369
+ return animation
370
+ })
371
+ }
372
+
373
+ this._forward.length <= 0 ? this._next.setAttribute('hidden', '') : this._next.removeAttribute('hidden')
374
+ this._backward.length <= 0 ? this._prev.setAttribute('hidden', '') : this._prev.removeAttribute('hidden')
375
+ this._fullscreen && this._fullscreen.removeAttribute('hidden')
376
+
377
+ this._fade_animations.forEach(animation => {
378
+ animation.cancel()
379
+ if (stop) return
380
+
381
+ animation.play()
382
+ })
383
+ }
384
+
385
+ /* event handlers */
386
+
387
+ onTapNext() {
388
+ var scene = this._forward.pop()
389
+ if (!scene) return
390
+
391
+ if (this._scene) {
392
+ this._scene.target = null
393
+ /* 원래의 target에 되돌린다. */
394
+ this._scene.target = this._oldtarget
395
+ this.unbindSceneEvents(this._scene)
396
+ this._backward.push(this._scene)
397
+ }
398
+
399
+ this.setupScene(scene)
400
+ }
401
+
402
+ onTapPrev() {
403
+ var scene = this._backward.pop()
404
+ if (!scene) return
405
+
406
+ if (this._scene) {
407
+ this._scene.target = null
408
+ /* 원래의 target에 되돌린다. */
409
+ this._scene.target = this._oldtarget
410
+ this.unbindSceneEvents(this._scene)
411
+ this._forward.push(this._scene)
412
+ }
413
+
414
+ this.setupScene(scene)
415
+ }
416
+
417
+ onTapFullscreen() {
418
+ togglefullscreen(
419
+ this,
420
+ () => this.requestUpdate(),
421
+ () => this.requestUpdate()
422
+ )
423
+ }
424
+
425
+ onLinkGoto(targetProcessId: string, options: any, fromComponent: any) {
426
+ const { input, output } = options || { input: '(self)' }
427
+ const data = input && fromComponent.root.findFirst(input, fromComponent)?.data
428
+ this.showScene(targetProcessId, data)
429
+ }
430
+
431
+ onLinkOpen(url: string, value: any, fromComponent: Component) {
432
+ if (!url) return
433
+
434
+ try {
435
+ window.open(url)
436
+ } catch (ex) {
437
+ document.dispatchEvent(
438
+ new CustomEvent('notify', {
439
+ detail: {
440
+ level: 'error',
441
+ message: ex,
442
+ ex
443
+ }
444
+ })
445
+ )
446
+ }
447
+ }
448
+
449
+ onLinkMove(url: string, value: any, fromComponent: Component) {
450
+ if (!url) return
451
+
452
+ location.href = url
453
+ }
454
+
455
+ onRoutePage(page: string) {
456
+ if (!page) {
457
+ return
458
+ }
459
+
460
+ history.pushState({}, '', page)
461
+ window.dispatchEvent(new Event('popstate'))
462
+ }
463
+
464
+ async onStartScenario(scenario: string, value: string | number | object, component: Component) {
465
+ try {
466
+ await startScenario(scenario, scenario, value)
467
+ } catch (e) {
468
+ console.error(e)
469
+ }
470
+ }
471
+
472
+ async onRunScenario(scenario: string, value: string | number | object, component: Component) {
473
+ try {
474
+ component.data = await runScenario(scenario, value)
475
+ } catch (e) {
476
+ console.error(e)
477
+ }
478
+ }
479
+
480
+ getSceneData() {
481
+ return this._scene?.data
482
+ }
483
+
484
+ async getSceneImageData(base64 = false) {
485
+ if (!this._scene) {
486
+ return
487
+ }
488
+
489
+ var { width, height } = this._scene.model
490
+ var pixelRatio = window.devicePixelRatio
491
+
492
+ // 1. Scene의 바운드에 근거하여, 오프스크린 캔바스를 만든다.
493
+ var canvas = document.createElement('canvas')
494
+ canvas.width = Number(width)
495
+ canvas.height = Number(height)
496
+
497
+ var root = this._scene.root
498
+ // 2. 모델레이어의 원래 위치와 스케일을 저장한다.
499
+ var translate = root.get('translate')
500
+ var scale = root.get('scale')
501
+
502
+ // 3. 위치와 스케일 기본 설정.
503
+ root.set('translate', { x: 0, y: 0 })
504
+ root.set('scale', { x: 1 / pixelRatio, y: 1 / pixelRatio })
505
+
506
+ // 4. 오프스크린 캔바스의 Context2D를 구한뒤, 모델레이어를 그 위에 그린다.
507
+ var context = canvas.getContext('2d')
508
+
509
+ root.draw(context)
510
+
511
+ root.set('translate', translate)
512
+ root.set('scale', scale)
513
+
514
+ var data = base64 ? canvas.toDataURL() : context!.getImageData(0, 0, width, height).data
515
+
516
+ return {
517
+ width,
518
+ height,
519
+ data
520
+ }
521
+ }
522
+
523
+ async printTrick(image: string) {
524
+ var viewTarget: HTMLElement | null = null
525
+ var printTarget: HTMLImageElement | null = null
526
+
527
+ if (!image) {
528
+ image = (await this.getSceneImageData(true))?.data as string
529
+ }
530
+
531
+ printTarget = document.createElement('img')
532
+ printTarget.id = 'target'
533
+ printTarget.src = image
534
+ printTarget.style.width = '100%'
535
+ printTarget.style.height = '100%'
536
+
537
+ const x = (mql: MediaQueryListEvent) => {
538
+ if (mql.matches) {
539
+ if (!viewTarget) {
540
+ viewTarget = (this.renderRoot as ShadowRoot)!.getElementById('target')
541
+ this.renderRoot.replaceChild(printTarget!, viewTarget!)
542
+ }
543
+ } else {
544
+ this.renderRoot.replaceChild(viewTarget!, printTarget!)
545
+ printTarget!.remove()
546
+ mediaQueryList.removeEventListener('change', x)
547
+ }
548
+ }
549
+
550
+ if (window.matchMedia) {
551
+ var mediaQueryList = window.matchMedia('print')
552
+ mediaQueryList.addEventListener('change', x)
553
+ }
554
+ }
555
+ }
package/src/types.ts ADDED
@@ -0,0 +1,68 @@
1
+ import { Model } from '@hatiolab/things-scene'
2
+
3
+ export interface PalletItem {
4
+ type: string
5
+ description: string
6
+ icon: HTMLImageElement
7
+ group:
8
+ | 'line'
9
+ | 'shape'
10
+ | 'textAndMedio'
11
+ | 'chartAndGauge'
12
+ | 'table'
13
+ | 'container'
14
+ | 'IoT'
15
+ | '3D'
16
+ | 'warehouse'
17
+ | 'form'
18
+ | 'etc'
19
+ | string
20
+ model: Model
21
+ }
22
+
23
+ export interface Pallet {
24
+ name: string
25
+ templates: PalletItem[]
26
+ }
27
+
28
+ export type ComponentTemplate = {
29
+ type: string
30
+ description: string
31
+ group:
32
+ | 'line'
33
+ | 'shape'
34
+ | 'textAndMedia'
35
+ | 'chartAndGauge'
36
+ | 'table'
37
+ | 'container'
38
+ | 'dataSource'
39
+ | 'IoT'
40
+ | '3D'
41
+ | 'warehouse'
42
+ | 'form'
43
+ | 'etc'
44
+ | string
45
+ icon: any
46
+ model: Model
47
+ }
48
+
49
+ export type ComponentGroup = {
50
+ name: string
51
+ description: string
52
+ icon: string
53
+ templates: ComponentTemplate[]
54
+ }
55
+
56
+ export type Process = {
57
+ id?: string
58
+ name?: string
59
+ description?: string
60
+ model?: any
61
+ groupId?: string
62
+ }
63
+
64
+ export type ProcessGroup = {
65
+ id?: string
66
+ name?: string
67
+ description?: string
68
+ }
@@ -0,0 +1,52 @@
1
+ import '../index.js.js'
2
+
3
+ import { TemplateResult, html } from 'lit'
4
+
5
+ export default {
6
+ title: 'ProcessViewer',
7
+ component: 'process-viewer',
8
+ argTypes: {
9
+ title: { control: 'text' },
10
+ counter: { control: 'number' },
11
+ textColor: { control: 'color' }
12
+ }
13
+ }
14
+
15
+ interface Story<T> {
16
+ (args: T): TemplateResult
17
+ args?: Partial<T>
18
+ argTypes?: Record<string, unknown>
19
+ }
20
+
21
+ interface ArgTypes {
22
+ title?: string
23
+ counter?: number
24
+ textColor?: string
25
+ slot?: TemplateResult
26
+ }
27
+
28
+ const Template: Story<ArgTypes> = ({ title = 'Hello world', counter = 5, textColor, slot }: ArgTypes) => html`
29
+ <ox-process-viewer style="--process-viewer-text-color: ${textColor || 'black'}" .title=${title} .counter=${counter}>
30
+ ${slot}
31
+ </ox-process-viewer>
32
+ `
33
+
34
+ export const Regular = Template.bind({})
35
+
36
+ export const CustomTitle = Template.bind({})
37
+ CustomTitle.args = {
38
+ title: 'My title'
39
+ }
40
+
41
+ export const CustomCounter = Template.bind({})
42
+ CustomCounter.args = {
43
+ counter: 123456
44
+ }
45
+
46
+ export const SlottedContent = Template.bind({})
47
+ SlottedContent.args = {
48
+ slot: html`<p>Slotted content</p>`
49
+ }
50
+ SlottedContent.argTypes = {
51
+ slot: { table: { disable: true } }
52
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2018",
4
+ "module": "esnext",
5
+ "moduleResolution": "node",
6
+ "noEmitOnError": true,
7
+ "lib": ["es2017", "dom"],
8
+ "strict": true,
9
+ "esModuleInterop": false,
10
+ "allowSyntheticDefaultImports": true,
11
+ "experimentalDecorators": true,
12
+ "useDefineForClassFields": false,
13
+ "importHelpers": true,
14
+ "outDir": "dist",
15
+ "sourceMap": true,
16
+ "inlineSources": true,
17
+ "rootDir": "./",
18
+ "declaration": true,
19
+ "incremental": true,
20
+ "types": ["node", "mocha"]
21
+ },
22
+ "include": ["**/*.ts", "*.d.ts"]
23
+ }