@operato/board 1.0.0-beta.0 → 1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@operato/board",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "Webcomponent for board following open-wc recommendations",
5
5
  "author": "heartyoh",
6
6
  "license": "MIT",
@@ -49,17 +49,17 @@
49
49
  "storybook:build": "tsc && npm run analyze -- --exclude dist && build-storybook"
50
50
  },
51
51
  "dependencies": {
52
- "@operato/app": "^1.0.0-beta.0",
53
- "@operato/data-grist": "^1.0.0-beta.0",
54
- "@operato/font": "^1.0.0-beta.0",
55
- "@operato/graphql": "^1.0.0-beta.0",
56
- "@operato/i18n": "^1.0.0-beta.0",
57
- "@operato/input": "^1.0.0-beta.0",
58
- "@operato/markdown": "^1.0.0-beta.0",
59
- "@operato/popup": "^1.0.0-beta.0",
60
- "@operato/property-editor": "^1.0.0-beta.0",
61
- "@operato/styles": "^1.0.0-beta.0",
62
- "@operato/utils": "^1.0.0-beta.0",
52
+ "@operato/app": "^1.0.0-beta.1",
53
+ "@operato/data-grist": "^1.0.0-beta.1",
54
+ "@operato/font": "^1.0.0-beta.1",
55
+ "@operato/graphql": "^1.0.0-beta.1",
56
+ "@operato/i18n": "^1.0.0-beta.1",
57
+ "@operato/input": "^1.0.0-beta.1",
58
+ "@operato/markdown": "^1.0.0-beta.1",
59
+ "@operato/popup": "^1.0.0-beta.1",
60
+ "@operato/property-editor": "^1.0.0-beta.1",
61
+ "@operato/styles": "^1.0.0-beta.1",
62
+ "@operato/utils": "^1.0.0-beta.1",
63
63
  "@polymer/paper-dropdown-menu": "^3.2.0",
64
64
  "@types/file-saver": "^2.0.4",
65
65
  "@types/sortablejs": "^1.10.7",
@@ -107,5 +107,5 @@
107
107
  "prettier --write"
108
108
  ]
109
109
  },
110
- "gitHead": "06b7a224872643b4dfdd95efc83770ce96057bdf"
110
+ "gitHead": "cfa0be4c72d93b2bf3f851c09b5c62c6025edf0f"
111
111
  }
@@ -0,0 +1,79 @@
1
+ import gql from 'graphql-tag'
2
+
3
+ import { client } from '@operato/graphql'
4
+
5
+ export const scenarios = async (): Promise<{ name: string; description: string }[]> => {
6
+ var response = await client.query({
7
+ query: gql`
8
+ query {
9
+ scenarios {
10
+ items {
11
+ name
12
+ description
13
+ }
14
+ }
15
+ }
16
+ `
17
+ })
18
+
19
+ if (response.errors) {
20
+ return []
21
+ }
22
+
23
+ return response.data.scenarios.items
24
+ }
25
+
26
+ export const startScenario = async (
27
+ scenarioName: string,
28
+ instanceName: string,
29
+ variables: string | number | object
30
+ ) => {
31
+ if (!scenarioName) {
32
+ return
33
+ }
34
+
35
+ if (client) {
36
+ var response = await client.query({
37
+ query: gql`
38
+ mutation ($instanceName: String, $scenarioName: String!, $variables: Object) {
39
+ startScenario(instanceName: $instanceName, scenarioName: $scenarioName, variables: $variables) {
40
+ state
41
+ message
42
+ data
43
+ }
44
+ }
45
+ `,
46
+ variables: {
47
+ instanceName: instanceName,
48
+ scenarioName: scenarioName,
49
+ variables
50
+ }
51
+ })
52
+
53
+ return response?.data?.startScenario?.data
54
+ }
55
+ }
56
+
57
+ export const runScenario = async (scenarioName: string, variables: string | number | object) => {
58
+ if (!scenarioName) return
59
+
60
+ if (client) {
61
+ var response = await client.query({
62
+ query: gql`
63
+ mutation ($scenarioName: String!, $variables: Object) {
64
+ runScenario(scenarioName: $scenarioName, variables: $variables) {
65
+ state
66
+ message
67
+ data
68
+ }
69
+ }
70
+ `,
71
+ variables: {
72
+ scenarioName: scenarioName,
73
+ variables
74
+ }
75
+ })
76
+
77
+ return response?.data?.runScenario?.data
78
+ }
79
+ }
@@ -8,10 +8,11 @@ import '@operato/input/ox-buttons-radio.js'
8
8
  import '@operato/input/ox-input-code.js'
9
9
  import '@operato/i18n/ox-i18n.js'
10
10
 
11
- import { LitElement, PropertyValues, css, html } from 'lit'
12
- import { Properties, Scene } from '@hatiolab/things-scene'
11
+ import { css, html, LitElement, PropertyValues } from 'lit'
13
12
  import { customElement, property, query, state } from 'lit/decorators.js'
14
13
 
14
+ import { Properties, Scene } from '@hatiolab/things-scene'
15
+
15
16
  export type Rule =
16
17
  | {
17
18
  map?: Properties
@@ -155,7 +156,7 @@ export default class DataBindingMapper extends LitElement {
155
156
  text: 'string',
156
157
  ref: 'string'
157
158
  }
158
- @state() _componentIds: any[] = []
159
+ @state() _componentIds: { value: string; description: string }[] = []
159
160
 
160
161
  @query('#eval-editor') editor!: HTMLInputElement
161
162
  @query('#target-input') target!: HTMLInputElement
@@ -191,15 +192,24 @@ export default class DataBindingMapper extends LitElement {
191
192
  list="target-list"
192
193
  .value=${mapping.target || ''}
193
194
  @focusin=${() => {
194
- if (!this.scene) this._componentIds = []
195
- this._componentIds = this.scene!.ids.map(info => info.key).filter(id => !!id)
195
+ this._componentIds =
196
+ (this.scene &&
197
+ this.scene.ids.map(i => {
198
+ const id = i.key
199
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
200
+ })) ||
201
+ []
196
202
  }}
197
203
  />
198
204
  <datalist id="target-list">
199
205
  <option value="(self)"></option>
200
206
  <option value="(key)"></option>
201
207
  ${this._componentIds.length
202
- ? html` ${this._componentIds.map(id => html` <option value=${id}></option> `)} `
208
+ ? html`
209
+ ${this._componentIds.map(
210
+ ({ value, description }) => html` <option value=${value}>${description}</option> `
211
+ )}
212
+ `
203
213
  : html``}
204
214
  </datalist>
205
215
 
@@ -63,7 +63,9 @@ class PropertyEventHover extends LitElement {
63
63
  />
64
64
 
65
65
  <datalist id="target-list">
66
- ${this._getTargetList(action).map(item => html` <option .value=${item}></option> `)}
66
+ ${this._getTargetList(action).map(
67
+ ({ value, description }) => html` <option .value=${value}>${description}</option> `
68
+ )}
67
69
  </datalist>
68
70
  `}
69
71
  ${action == 'data-set' || action == 'value-set'
@@ -93,14 +95,20 @@ class PropertyEventHover extends LitElement {
93
95
  }
94
96
  }
95
97
 
96
- _getTargetList(action: string) {
98
+ _getTargetList(action: string): { value: string; description: string }[] {
97
99
  switch (action) {
98
100
  case 'data-toggle':
99
101
  case 'data-tristate':
100
102
  case 'data-set':
101
103
  case 'value-set':
102
- let ids = (this.scene && this.scene.ids.map(i => `#${i.key}`)) || []
103
- ids.unshift('(self)')
104
+ let ids =
105
+ (this.scene &&
106
+ this.scene.ids.map(i => {
107
+ const id = i.key
108
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
109
+ })) ||
110
+ []
111
+ ids.unshift({ value: '(self)', description: 'self component' })
104
112
  return ids
105
113
  case 'infoWindow':
106
114
  return (
@@ -109,7 +117,10 @@ class PropertyEventHover extends LitElement {
109
117
  .filter(i => {
110
118
  return this.scene!.findById(i.key).get('type') == 'info-window'
111
119
  })
112
- .map(i => `${i.key}`)) ||
120
+ .map(i => {
121
+ const id = i.key
122
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
123
+ })) ||
113
124
  []
114
125
  )
115
126
  default:
@@ -6,10 +6,11 @@ import '@operato/input/ox-input-data.js'
6
6
  import '@operato/i18n/ox-i18n.js'
7
7
 
8
8
  import { html, LitElement } from 'lit'
9
- import { customElement, property } from 'lit/decorators.js'
9
+ import { customElement, property, state } from 'lit/decorators.js'
10
10
 
11
11
  import { Properties, Scene } from '@hatiolab/things-scene'
12
12
 
13
+ import { scenarios } from '../../../graphql/scenario'
13
14
  import { EffectsSharedStyle } from './effects-shared-style'
14
15
  import { convert } from './value-converter'
15
16
 
@@ -20,7 +21,10 @@ class PropertyEventTap extends LitElement {
20
21
  @property({ type: Object }) value?: Properties
21
22
  @property({ type: Object }) scene?: Scene
22
23
 
23
- firstUpdated() {
24
+ @state() scenarios: { value: string; description: string }[] = []
25
+ @state() targetList: { value: string; description: string }[] = []
26
+
27
+ async firstUpdated() {
24
28
  this.renderRoot.addEventListener('change', this._onValueChange.bind(this))
25
29
  }
26
30
 
@@ -32,7 +36,18 @@ class PropertyEventTap extends LitElement {
32
36
  <label for="checkbox-pressed" class="checkbox-label"> <ox-i18n msgid="label.pressed">pressed</ox-i18n> </label>
33
37
 
34
38
  <label> <ox-i18n msgid="label.action">action</ox-i18n> </label>
35
- <select id="tap-select" value-key="action" .value=${action || ''}>
39
+ <select
40
+ id="tap-select"
41
+ value-key="action"
42
+ .value=${action || ''}
43
+ @change=${async (e: Event) => {
44
+ if ((e.target as HTMLSelectElement).value === 'start-scenario') {
45
+ this.scenarios = (await scenarios()).map(({ name, description }) => {
46
+ return { value: name, description }
47
+ })
48
+ }
49
+ }}
50
+ >
36
51
  <option value=""></option>
37
52
  <option value="goto">go to target board</option>
38
53
  <option value="link-open">open new window for target link</option>
@@ -47,11 +62,13 @@ class PropertyEventTap extends LitElement {
47
62
  <option value="data-tristate">tristate(0/1/2) target component data</option>
48
63
  <option value="data-set">set value to target component data</option>
49
64
  <option value="value-set">set value to target component value</option>
65
+ <option value="start-scenario">start the given scenario</option>
66
+ <option value="run-scenario">run the given scenario</option>
50
67
  </select>
51
68
 
52
69
  <label> <ox-i18n msgid="label.target">target</ox-i18n> </label>
53
70
 
54
- ${action == 'goto' || action == 'popup'
71
+ ${action === 'goto' || action === 'popup'
55
72
  ? html`
56
73
  <things-editor-board-selector
57
74
  value-key="target"
@@ -60,13 +77,23 @@ class PropertyEventTap extends LitElement {
60
77
  ></things-editor-board-selector>
61
78
  `
62
79
  : html`
63
- <input value-key="target" .value=${target} list="target-list" .placeholder=${this._getPlaceHoder(action)} />
80
+ <input
81
+ value-key="target"
82
+ .value=${target}
83
+ list="target-list"
84
+ .placeholder=${this._getPlaceHoder(action)}
85
+ @focusin=${() => {
86
+ this.targetList = this._getTargetList(action)
87
+ }}
88
+ />
64
89
 
65
90
  <datalist id="target-list">
66
- ${this._getTargetList(action).map(item => html` <option .value=${item}></option> `)}
91
+ ${this.targetList.map(
92
+ ({ value, description }) => html` <option .value=${value}>${description}</option> `
93
+ )}
67
94
  </datalist>
68
95
  `}
69
- ${action == 'data-set' || action == 'value-set'
96
+ ${action === 'data-set' || action === 'value-set' || action === 'start-scenario' || action === 'run-scenario'
70
97
  ? html`
71
98
  <label> <ox-i18n msgid="label.value">value</ox-i18n> </label>
72
99
  <ox-input-data value-key="value" .value=${value} custom-editor fullwidth></ox-input-data>
@@ -88,14 +115,20 @@ class PropertyEventTap extends LitElement {
88
115
  }
89
116
  }
90
117
 
91
- _getTargetList(action: string) {
118
+ _getTargetList(action: string): { value: string; description: string }[] {
92
119
  switch (action) {
93
120
  case 'data-toggle':
94
121
  case 'data-tristate':
95
122
  case 'data-set':
96
123
  case 'value-set':
97
- let ids = (this.scene && this.scene.ids.map(i => `#${i.key}`)) || []
98
- ids.unshift('(self)')
124
+ let ids =
125
+ (this.scene &&
126
+ this.scene.ids.map(i => {
127
+ const id = i.key
128
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
129
+ })) ||
130
+ []
131
+ ids.unshift({ value: '(self)', description: 'self component' })
99
132
  return ids
100
133
  case 'infoWindow':
101
134
  case 'toggle-info-window':
@@ -105,9 +138,15 @@ class PropertyEventTap extends LitElement {
105
138
  .filter(i => {
106
139
  return this.scene!.findById(i.key).get('type') == 'info-window'
107
140
  })
108
- .map(i => `${i.key}`)) ||
141
+ .map(i => {
142
+ const id = i.key
143
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
144
+ })) ||
109
145
  []
110
146
  )
147
+ case 'start-scenario':
148
+ case 'run-scenario':
149
+ return this.scenarios
111
150
  default:
112
151
  return []
113
152
  }
@@ -1,12 +1,14 @@
1
1
  import '@material/mwc-fab'
2
2
  import '@material/mwc-icon'
3
3
 
4
- import { LitElement, PropertyValues, css, html } from 'lit'
5
- import { ReferenceProvider, SCENE_MODE, create } from '@hatiolab/things-scene'
4
+ import { css, html, LitElement, PropertyValues } from 'lit'
6
5
  import { customElement, property, query, state } from 'lit/decorators.js'
6
+
7
+ import { Component, create, ReferenceProvider, SCENE_MODE } from '@hatiolab/things-scene'
7
8
  import { isIOS, togglefullscreen } from '@operato/utils'
8
9
 
9
10
  import { DataSubscriptionProviderImpl } from './graphql/data-subscription'
11
+ import { runScenario, startScenario } from './graphql/scenario'
10
12
 
11
13
  @customElement('ox-board-viewer')
12
14
  export class BoardViewer extends LitElement {
@@ -321,6 +323,8 @@ export class BoardViewer extends LitElement {
321
323
  this._scene.on('link-open', this.onLinkOpen, this)
322
324
  this._scene.on('link-move', this.onLinkMove, this)
323
325
  this._scene.on('route-page', this.onRoutePage, this)
326
+ this._scene.on('start-scenario', this.onStartScenario, this)
327
+ this._scene.on('run-scenario', this.onRunScenario, this)
324
328
  }
325
329
 
326
330
  unbindSceneEvents(scene: any) {
@@ -328,6 +332,8 @@ export class BoardViewer extends LitElement {
328
332
  scene.off('link-open', this.onLinkOpen, this)
329
333
  scene.off('link-move', this.onLinkMove, this)
330
334
  scene.off('route-page', this.onRoutePage, this)
335
+ scene.off('start-scenario', this.onStartScenario, this)
336
+ scene.off('run-scenario', this.onRunScenario, this)
331
337
  }
332
338
 
333
339
  transientShowButtons(stop?: boolean) {
@@ -414,11 +420,11 @@ export class BoardViewer extends LitElement {
414
420
  )
415
421
  }
416
422
 
417
- onLinkGoto(targetBoardId: string, value: any, fromComponent: any) {
423
+ onLinkGoto(targetBoardId: string, value: any, fromComponent: Component) {
418
424
  this.showScene(targetBoardId, fromComponent.data)
419
425
  }
420
426
 
421
- onLinkOpen(url: string, value: any, fromComponent: any) {
427
+ onLinkOpen(url: string, value: any, fromComponent: Component) {
422
428
  if (!url) return
423
429
 
424
430
  try {
@@ -436,7 +442,7 @@ export class BoardViewer extends LitElement {
436
442
  }
437
443
  }
438
444
 
439
- onLinkMove(url: string, value: any, fromComponent: any) {
445
+ onLinkMove(url: string, value: any, fromComponent: Component) {
440
446
  if (!url) return
441
447
 
442
448
  location.href = url
@@ -451,6 +457,22 @@ export class BoardViewer extends LitElement {
451
457
  window.dispatchEvent(new Event('popstate'))
452
458
  }
453
459
 
460
+ async onStartScenario(scenario: string, value: string | number | object, component: Component) {
461
+ try {
462
+ await startScenario(scenario, scenario, value)
463
+ } catch (e) {
464
+ console.error(e)
465
+ }
466
+ }
467
+
468
+ async onRunScenario(scenario: string, value: string | number | object, component: Component) {
469
+ try {
470
+ component.data = await runScenario(scenario, value)
471
+ } catch (e) {
472
+ console.error(e)
473
+ }
474
+ }
475
+
454
476
  async getSceneImageData(base64 = false) {
455
477
  if (!this._scene) {
456
478
  return