@operato/process 1.4.48 → 1.4.49

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/process",
3
- "version": "1.4.48",
3
+ "version": "1.4.49",
4
4
  "description": "Webcomponent for business process modeling following open-wc recommendations",
5
5
  "author": "heartyoh",
6
6
  "main": "dist/src/index.js",
@@ -128,5 +128,5 @@
128
128
  "prettier --write"
129
129
  ]
130
130
  },
131
- "gitHead": "98c601e3a5a8bd67ad66f64746cdeff4d762d747"
131
+ "gitHead": "6ff22981035977f248f2f9ef452c1f14d0284227"
132
132
  }
@@ -0,0 +1,458 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import '@operato/input/ox-buttons-radio.js'
6
+ import '@operato/input/ox-input-code.js'
7
+ import '@operato/i18n/ox-i18n.js'
8
+ import '@operato/help/ox-help-icon.js'
9
+ import './data-binding-value-map.js'
10
+ import './data-binding-value-range.js'
11
+
12
+ import { css, html, LitElement, PropertyValues } from 'lit'
13
+ import { property, query, state } from 'lit/decorators.js'
14
+
15
+ import { Properties, Scene } from '@hatiolab/things-scene'
16
+
17
+ export type Rule =
18
+ | {
19
+ map?: Properties
20
+ range?: Properties[]
21
+ eval?: string
22
+ }
23
+ | any
24
+
25
+ export type Mapping = {
26
+ source?: string
27
+ rule: 'map' | 'range' | 'eval' | 'value'
28
+ accessor?: string
29
+ target?: string
30
+ property?: string
31
+ param?: Rule
32
+ ndnsp?: boolean
33
+ }
34
+
35
+ /**
36
+ element for mapping data value editing
37
+
38
+ Example:
39
+
40
+ <data-binding-mapper mapping=${mapping}>
41
+ </data-binding-mapper>
42
+ */
43
+
44
+ export class DataBindingMapper extends LitElement {
45
+ static styles = [
46
+ css`
47
+ :host {
48
+ background-color: rgba(255, 255, 255, 0.5);
49
+ overflow: hidden;
50
+ padding: 7px 0 0 0;
51
+ border: 1px solid rgba(0, 0, 0, 0.2);
52
+ border-width: 0 1px 1px 1px;
53
+ padding: 4px;
54
+ line-height: 2;
55
+
56
+ display: grid;
57
+ grid-template-columns: repeat(10, 1fr);
58
+ grid-gap: 4px;
59
+ grid-auto-rows: minmax(24px, auto);
60
+
61
+ align-items: center;
62
+ }
63
+
64
+ :host > * {
65
+ align-self: stretch;
66
+ }
67
+
68
+ label {
69
+ grid-column: span 3;
70
+ text-align: right;
71
+ text-transform: capitalize;
72
+ }
73
+
74
+ input,
75
+ select,
76
+ ox-buttons-radio,
77
+ [mapping-rule] {
78
+ grid-column: span 7;
79
+ }
80
+ input,
81
+ select {
82
+ border: var(--property-sidebar-fieldset-border);
83
+ }
84
+
85
+ ox-buttons-radio {
86
+ display: flex;
87
+ padding: 0 4px;
88
+ }
89
+
90
+ ox-buttons-radio > * {
91
+ text-align: center;
92
+ flex: 1;
93
+ margin: 2px;
94
+ border-bottom: 2px solid #fff;
95
+ }
96
+
97
+ ox-buttons-radio div[active] {
98
+ border-color: #f2471c;
99
+ }
100
+
101
+ select {
102
+ height: 22px;
103
+ }
104
+
105
+ [mapping-rule] {
106
+ display: flex;
107
+ }
108
+
109
+ [mapping-rule] * {
110
+ flex: auto;
111
+ margin: 0;
112
+ text-align: left;
113
+ align-self: center;
114
+ }
115
+
116
+ [rule-editors] {
117
+ grid-column: span 10;
118
+
119
+ display: 'flex';
120
+ align-content: auto;
121
+ }
122
+
123
+ [rule-editors] :not([active]) {
124
+ display: none;
125
+ }
126
+
127
+ ox-input-code {
128
+ height: 300px;
129
+ overflow: auto;
130
+ }
131
+
132
+ /* checkbox-row */
133
+ .checkbox-row {
134
+ grid-column: span 10;
135
+
136
+ display: grid;
137
+ grid-template-columns: repeat(10, 1fr);
138
+ grid-gap: 5px;
139
+ grid-auto-rows: minmax(24px, auto);
140
+ align-items: center;
141
+ }
142
+
143
+ .checkbox-row > input {
144
+ grid-column: 4 / 5;
145
+ }
146
+
147
+ .checkbox-row > label {
148
+ grid-column: span 6;
149
+ text-align: left;
150
+ }
151
+ `
152
+ ]
153
+
154
+ @property({ type: Object }) mapping: Mapping = {
155
+ rule: 'value'
156
+ }
157
+ @property({ type: Object }) rule: Rule = {}
158
+ @property({ type: Array }) properties: Properties[] = []
159
+ @property({ type: Object }) scene?: Scene
160
+
161
+ @state() _valueTypes: any = {
162
+ play: 'boolean',
163
+ hidden: 'boolean',
164
+ started: 'boolean',
165
+
166
+ rotation: 'number',
167
+ value: 'number',
168
+
169
+ fillStyle: 'color',
170
+ strokeStyle: 'color',
171
+ fontColor: 'color',
172
+
173
+ data: 'object',
174
+ source: 'attachment',
175
+ location: 'object',
176
+ dimension: 'object',
177
+
178
+ text: 'string',
179
+ ref: 'string'
180
+ }
181
+ @state() _componentIds: { value: string; description: string }[] = []
182
+
183
+ @query('#eval-editor') editor!: HTMLInputElement
184
+ @query('#source-input') source!: HTMLInputElement
185
+ @query('#target-input') target!: HTMLInputElement
186
+
187
+ firstUpdated() {
188
+ this.renderRoot.addEventListener('change', e => this._onChange(e))
189
+ }
190
+
191
+ updated(changes: PropertyValues<this>) {
192
+ changes.has('mapping') && this._onChangedMapping()
193
+ }
194
+
195
+ findComponentIds() {
196
+ return (
197
+ (this.scene &&
198
+ this.scene.ids.map(i => {
199
+ const id = i.key
200
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
201
+ })) ||
202
+ []
203
+ )
204
+ }
205
+
206
+ render() {
207
+ const mapping = this.mapping || {
208
+ rule: 'value'
209
+ }
210
+
211
+ return html`
212
+ <label for="source-input"> <ox-i18n msgid="label.source">source</ox-i18n> </label>
213
+ <input
214
+ id="source-input"
215
+ type="text"
216
+ value-key="source"
217
+ list="source-list"
218
+ .value=${mapping.source || ''}
219
+ @focusin=${() => this.findComponentIds()}
220
+ />
221
+
222
+ <label for="accessor-input">
223
+ <ox-i18n msgid="label.accessor">accessor</ox-i18n><ox-help-icon topic="board-modeller/accessor"></ox-help-icon>
224
+ </label>
225
+ <input
226
+ id="accessor-input"
227
+ value-key="accessor"
228
+ type="text"
229
+ data-mapping-accessor
230
+ .value=${mapping.accessor || ''}
231
+ />
232
+
233
+ <label for="target-input"> <ox-i18n msgid="label.target">target</ox-i18n> </label>
234
+ <input
235
+ id="target-input"
236
+ type="text"
237
+ value-key="target"
238
+ list="target-list"
239
+ .value=${mapping.target || ''}
240
+ @focusin=${() => this.findComponentIds()}
241
+ />
242
+
243
+ <datalist id="source-list">
244
+ <option value="">(self)</option>
245
+ ${this._componentIds.length
246
+ ? html`
247
+ ${this._componentIds.map(
248
+ ({ value, description }) => html` <option value=${value}>${description}</option> `
249
+ )}
250
+ `
251
+ : html``}
252
+ </datalist>
253
+
254
+ <datalist id="target-list">
255
+ <option value="(self)"></option>
256
+ <option value="(children)"></option>
257
+ <option value="(key)"></option>
258
+ <option value="[propkey]"></option>
259
+ ${this._componentIds.length
260
+ ? html`
261
+ ${this._componentIds.map(
262
+ ({ value, description }) => html` <option value=${value}>${description}</option> `
263
+ )}
264
+ `
265
+ : html``}
266
+ </datalist>
267
+
268
+ <label for="property-input"> <ox-i18n msgid="label.property">property</ox-i18n> </label>
269
+ <select id="property-input" value-key="property" .value=${mapping.property || ''}>
270
+ ${this.properties.map(
271
+ item => html` <option .value=${item.name} ?selected=${item.name == mapping.property}>${item.label}</option> `
272
+ )}
273
+ </select>
274
+
275
+ <label> <ox-i18n msgid="label.rule-type">rule type</ox-i18n> </label>
276
+ <ox-buttons-radio .value=${mapping.rule} @change=${(e: Event) => this._onChangeRule(e)}>
277
+ <div data-value="value"><ox-i18n msgid="label.value"></ox-i18n></div>
278
+ <div data-value="map"><ox-i18n msgid="label.map"></ox-i18n></div>
279
+ <div data-value="range"><ox-i18n msgid="label.range"></ox-i18n></div>
280
+ <div data-value="eval"><ox-i18n msgid="label.eval"></ox-i18n></div>
281
+ </ox-buttons-radio>
282
+
283
+ <div rule-editors ?hidden=${mapping.rule == 'value'}>
284
+ <data-binding-value-map
285
+ value-key="map"
286
+ .value=${this.rule.map || {}}
287
+ .valuetype=${this._valuetype(mapping.property!)}
288
+ ?active=${mapping.rule == 'map'}
289
+ >
290
+ </data-binding-value-map>
291
+
292
+ <data-binding-value-range
293
+ value-key="range"
294
+ .value=${this.rule.range || []}
295
+ .valuetype=${this._valuetype(mapping.property!)}
296
+ ?active=${mapping.rule == 'range'}
297
+ >
298
+ </data-binding-value-range>
299
+
300
+ <ox-input-code
301
+ value-key="eval"
302
+ id="eval-editor"
303
+ .value=${this.rule.eval || ''}
304
+ ?active=${mapping.rule == 'eval'}
305
+ >
306
+ </ox-input-code>
307
+ </div>
308
+
309
+ <div class="checkbox-row">
310
+ <input id="checkbox-ndnsp" type="checkbox" value-key="ndnsp" .checked=${mapping.ndnsp === true} />
311
+ <label for="checkbox-ndnsp"> <ox-i18n msgid="label.ndnsp">No Data No Spreading</ox-i18n> </label>
312
+ </div>
313
+ `
314
+ }
315
+
316
+ _valuetype(property: string) {
317
+ return this._valueTypes[property] || 'string'
318
+ }
319
+
320
+ private _keep_saved_rule_params: boolean = false
321
+
322
+ async _onChangedMapping() {
323
+ if (this._keep_saved_rule_params) {
324
+ this._keep_saved_rule_params = false
325
+ } else {
326
+ await this.updateComplete
327
+
328
+ var rule: Rule = {}
329
+
330
+ if (this.mapping) {
331
+ switch (this.mapping.rule) {
332
+ case 'map':
333
+ rule.map = this.mapping.param || {}
334
+ break
335
+ case 'range':
336
+ rule.range = this.mapping.param || []
337
+ break
338
+ case 'eval':
339
+ rule.eval = this.mapping.param || ''
340
+ break
341
+ default:
342
+ this.mapping.rule = 'value'
343
+ break
344
+ }
345
+ }
346
+
347
+ this.rule = rule
348
+ this.requestUpdate()
349
+ }
350
+ }
351
+
352
+ _onChangeRule(e: Event) {
353
+ var element = e.target as HTMLInputElement
354
+ var value = element.value
355
+
356
+ let param
357
+
358
+ switch (value) {
359
+ case 'map':
360
+ param = this.rule.map
361
+ break
362
+ case 'range':
363
+ param = this.rule.range
364
+ break
365
+ case 'eval':
366
+ param = this.rule.eval || ''
367
+
368
+ // rule.eval에 값이 없을 때, ace-editor 내용이 초기화되지 않는 문제때문에 처리함.
369
+ if (!param) {
370
+ this.editor.value = 'return'
371
+ }
372
+ break
373
+ default:
374
+ }
375
+
376
+ this.mapping = {
377
+ ...this.mapping,
378
+ rule: value as 'value' | 'map' | 'range' | 'eval',
379
+ param
380
+ }
381
+
382
+ this._keep_saved_rule_params = true
383
+ this.dispatchEvent(new CustomEvent('value-change', { bubbles: true, composed: true }))
384
+ }
385
+
386
+ _onChange(e: Event) {
387
+ var element = e.target as HTMLInputElement
388
+ var key = element.getAttribute('value-key')
389
+
390
+ if (!key) return
391
+
392
+ var value: string | boolean = element.value
393
+
394
+ if (key === 'source') {
395
+ if (value.length > 0) {
396
+ value = value.trim()
397
+
398
+ this.source.value = value
399
+ }
400
+
401
+ this.mapping = {
402
+ ...this.mapping,
403
+ source: value
404
+ }
405
+ } else if (key === 'target') {
406
+ if (value.length > 0 && !/^[.#(\[]/.test(value)) {
407
+ value = '#' + value.trim()
408
+
409
+ this.target.value = value
410
+ }
411
+
412
+ this.mapping = {
413
+ ...this.mapping,
414
+ target: value
415
+ }
416
+ } else if (key === 'accessor') {
417
+ this.mapping = {
418
+ ...this.mapping,
419
+ accessor: (value || '').trim()
420
+ }
421
+ } else if (key === 'property') {
422
+ this.mapping = {
423
+ ...this.mapping,
424
+ property: (value || '').trim()
425
+ }
426
+ } else if (key === 'map' || key === 'range' || key === 'eval') {
427
+ this.rule[key] = value
428
+ this.mapping = {
429
+ ...this.mapping,
430
+ param: value
431
+ }
432
+ } else if (key === 'ndnsp' /* no data no spreading */) {
433
+ value = element.checked
434
+
435
+ this.mapping = {
436
+ ...this.mapping,
437
+ ndnsp: value
438
+ }
439
+ }
440
+
441
+ if (!this.mapping.rule) {
442
+ this.mapping.rule = 'value'
443
+ }
444
+
445
+ this._keep_saved_rule_params = true
446
+ this.dispatchEvent(
447
+ new CustomEvent('value-change', {
448
+ bubbles: true,
449
+ composed: true,
450
+ detail: {
451
+ changed: {
452
+ [key]: value
453
+ }
454
+ }
455
+ })
456
+ )
457
+ }
458
+ }
@@ -2,12 +2,12 @@
2
2
  * @license Copyright © HatioLab Inc. All rights reserved.
3
3
  */
4
4
 
5
- import '@operato/input/ox-input-value-map.js'
6
- import '@operato/input/ox-input-value-ranges.js'
7
5
  import '@operato/input/ox-buttons-radio.js'
8
6
  import '@operato/input/ox-input-code.js'
9
7
  import '@operato/i18n/ox-i18n.js'
10
8
  import '@operato/help/ox-help-icon.js'
9
+ import './data-binding-value-map.js'
10
+ import './data-binding-value-range.js'
11
11
 
12
12
  import { css, html, LitElement, PropertyValues } from 'lit'
13
13
  import { property, query, state } from 'lit/decorators.js'
@@ -23,6 +23,7 @@ export type Rule =
23
23
  | any
24
24
 
25
25
  export type Mapping = {
26
+ source?: string
26
27
  rule: 'map' | 'range' | 'eval' | 'value'
27
28
  accessor?: string
28
29
  target?: string
@@ -170,7 +171,7 @@ export class DataBindingMapper extends LitElement {
170
171
  fontColor: 'color',
171
172
 
172
173
  data: 'object',
173
- source: 'object',
174
+ source: 'attachment',
174
175
  location: 'object',
175
176
  dimension: 'object',
176
177
 
@@ -180,6 +181,7 @@ export class DataBindingMapper extends LitElement {
180
181
  @state() _componentIds: { value: string; description: string }[] = []
181
182
 
182
183
  @query('#eval-editor') editor!: HTMLInputElement
184
+ @query('#source-input') source!: HTMLInputElement
183
185
  @query('#target-input') target!: HTMLInputElement
184
186
 
185
187
  firstUpdated() {
@@ -190,13 +192,36 @@ export class DataBindingMapper extends LitElement {
190
192
  changes.has('mapping') && this._onChangedMapping()
191
193
  }
192
194
 
195
+ findComponentIds() {
196
+ return (
197
+ (this.scene &&
198
+ this.scene.ids.map(i => {
199
+ const id = i.key
200
+ return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
201
+ })) ||
202
+ []
203
+ )
204
+ }
205
+
193
206
  render() {
194
207
  const mapping = this.mapping || {
195
208
  rule: 'value'
196
209
  }
197
210
 
198
211
  return html`
199
- <label for="accessor-input"> <ox-i18n msgid="label.accessor">accessor</ox-i18n><ox-help-icon topic="board-modeller/accessor"> </label>
212
+ <label for="source-input"> <ox-i18n msgid="label.source">source</ox-i18n> </label>
213
+ <input
214
+ id="source-input"
215
+ type="text"
216
+ value-key="source"
217
+ list="source-list"
218
+ .value=${mapping.source || ''}
219
+ @focusin=${() => this.findComponentIds()}
220
+ />
221
+
222
+ <label for="accessor-input">
223
+ <ox-i18n msgid="label.accessor">accessor</ox-i18n><ox-help-icon topic="board-modeller/accessor"></ox-help-icon>
224
+ </label>
200
225
  <input
201
226
  id="accessor-input"
202
227
  value-key="accessor"
@@ -212,33 +237,36 @@ export class DataBindingMapper extends LitElement {
212
237
  value-key="target"
213
238
  list="target-list"
214
239
  .value=${mapping.target || ''}
215
- @focusin=${() => {
216
- this._componentIds =
217
- (this.scene &&
218
- this.scene.ids.map(i => {
219
- const id = i.key
220
- return { value: `#${id}`, description: this.scene!.findById(id)?.get('type') }
221
- })) ||
222
- []
223
- }}
240
+ @focusin=${() => this.findComponentIds()}
224
241
  />
242
+
243
+ <datalist id="source-list">
244
+ <option value="">(self)</option>
245
+ ${this._componentIds.length
246
+ ? html`
247
+ ${this._componentIds.map(
248
+ ({ value, description }) => html` <option value=${value}>${description}</option> `
249
+ )}
250
+ `
251
+ : html``}
252
+ </datalist>
253
+
225
254
  <datalist id="target-list">
226
255
  <option value="(self)"></option>
256
+ <option value="(children)"></option>
227
257
  <option value="(key)"></option>
228
258
  <option value="[propkey]"></option>
229
- ${
230
- this._componentIds.length
231
- ? html`
232
- ${this._componentIds.map(
233
- ({ value, description }) => html` <option value=${value}>${description}</option> `
234
- )}
235
- `
236
- : html``
237
- }
259
+ ${this._componentIds.length
260
+ ? html`
261
+ ${this._componentIds.map(
262
+ ({ value, description }) => html` <option value=${value}>${description}</option> `
263
+ )}
264
+ `
265
+ : html``}
238
266
  </datalist>
239
267
 
240
268
  <label for="property-input"> <ox-i18n msgid="label.property">property</ox-i18n> </label>
241
- <select id="property-input" value-key="property" .value=${mapping.property}>
269
+ <select id="property-input" value-key="property" .value=${mapping.property || ''}>
242
270
  ${this.properties.map(
243
271
  item => html` <option .value=${item.name} ?selected=${item.name == mapping.property}>${item.label}</option> `
244
272
  )}
@@ -253,21 +281,21 @@ export class DataBindingMapper extends LitElement {
253
281
  </ox-buttons-radio>
254
282
 
255
283
  <div rule-editors ?hidden=${mapping.rule == 'value'}>
256
- <ox-input-value-map
284
+ <data-binding-value-map
257
285
  value-key="map"
258
286
  .value=${this.rule.map || {}}
259
287
  .valuetype=${this._valuetype(mapping.property!)}
260
288
  ?active=${mapping.rule == 'map'}
261
289
  >
262
- </ox-input-value-map>
290
+ </data-binding-value-map>
263
291
 
264
- <ox-input-value-ranges
292
+ <data-binding-value-range
265
293
  value-key="range"
266
294
  .value=${this.rule.range || []}
267
295
  .valuetype=${this._valuetype(mapping.property!)}
268
296
  ?active=${mapping.rule == 'range'}
269
297
  >
270
- </ox-input-value-ranges>
298
+ </data-binding-value-range>
271
299
 
272
300
  <ox-input-code
273
301
  value-key="eval"
@@ -363,7 +391,18 @@ export class DataBindingMapper extends LitElement {
363
391
 
364
392
  var value: string | boolean = element.value
365
393
 
366
- if (key === 'target') {
394
+ if (key === 'source') {
395
+ if (value.length > 0) {
396
+ value = value.trim()
397
+
398
+ this.source.value = value
399
+ }
400
+
401
+ this.mapping = {
402
+ ...this.mapping,
403
+ source: value
404
+ }
405
+ } else if (key === 'target') {
367
406
  if (value.length > 0 && !/^[.#(\[]/.test(value)) {
368
407
  value = '#' + value.trim()
369
408
 
@@ -0,0 +1,19 @@
1
+ import { html } from 'lit'
2
+ import { customElement } from 'lit/decorators.js'
3
+ import { ifDefined } from 'lit/directives/if-defined.js'
4
+
5
+ import { OxInputValueMap } from '@operato/input'
6
+
7
+ import '@operato/attachment/ox-attachment-selector.js'
8
+
9
+ @customElement('data-binding-value-map')
10
+ export class DataBindingValueMap extends OxInputValueMap {
11
+ static styles = OxInputValueMap.styles
12
+
13
+ valueInputTemplate(value?: any) {
14
+ if (this.valuetype == 'attachment') {
15
+ return html`<ox-attachment-selector data-value value=${ifDefined(value)}></ox-attachment-selector>`
16
+ }
17
+ return super.valueInputTemplate(value)
18
+ }
19
+ }