@operato/dataset 1.0.0-beta.38 → 1.0.0-beta.40

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 (94) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js +1 -1
  3. package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js.map +1 -1
  4. package/dist/src/grist-editor/ox-popup-data-item-spec.js +3 -2
  5. package/dist/src/grist-editor/ox-popup-data-item-spec.js.map +1 -1
  6. package/dist/src/index.d.ts +1 -5
  7. package/dist/src/index.js +1 -5
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/ox-data-item-spec.d.ts +2 -2
  10. package/dist/src/ox-data-item-spec.js +1 -1
  11. package/dist/src/ox-data-item-spec.js.map +1 -1
  12. package/dist/src/ox-data-ooc-view.js +1 -1
  13. package/dist/src/ox-data-ooc-view.js.map +1 -1
  14. package/dist/src/ox-data-sample-view.d.ts +1 -2
  15. package/dist/src/ox-data-sample-view.js +25 -31
  16. package/dist/src/ox-data-sample-view.js.map +1 -1
  17. package/dist/src/types.d.ts +18 -6
  18. package/dist/src/types.js.map +1 -1
  19. package/dist/src/usecase/ccp/index.d.ts +1 -0
  20. package/dist/src/usecase/ccp/index.js +8 -0
  21. package/dist/src/usecase/ccp/index.js.map +1 -0
  22. package/dist/src/usecase/ccp/ox-data-use-case-ccp.d.ts +7 -0
  23. package/dist/src/usecase/ccp/ox-data-use-case-ccp.js +102 -0
  24. package/dist/src/usecase/ccp/ox-data-use-case-ccp.js.map +1 -0
  25. package/dist/src/usecase/ccp/ox-input-ccp-limits.d.ts +44 -0
  26. package/dist/src/usecase/ccp/ox-input-ccp-limits.js +171 -0
  27. package/dist/src/usecase/ccp/ox-input-ccp-limits.js.map +1 -0
  28. package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.d.ts +5 -0
  29. package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.js +24 -0
  30. package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.js.map +1 -0
  31. package/dist/src/{ox-data-use-case.d.ts → usecase/ox-data-use-case.d.ts} +5 -5
  32. package/dist/src/{ox-data-use-case.js → usecase/ox-data-use-case.js} +23 -34
  33. package/dist/src/usecase/ox-data-use-case.js.map +1 -0
  34. package/dist/src/usecase/qc/index.d.ts +1 -0
  35. package/dist/src/usecase/qc/index.js +8 -0
  36. package/dist/src/usecase/qc/index.js.map +1 -0
  37. package/dist/src/usecase/qc/ox-data-use-case-qc.d.ts +7 -0
  38. package/dist/src/usecase/qc/ox-data-use-case-qc.js +55 -0
  39. package/dist/src/usecase/qc/ox-data-use-case-qc.js.map +1 -0
  40. package/dist/src/usecase/qc/ox-input-qc-limits.d.ts +44 -0
  41. package/dist/src/usecase/qc/ox-input-qc-limits.js +171 -0
  42. package/dist/src/usecase/qc/ox-input-qc-limits.js.map +1 -0
  43. package/dist/src/usecase/qc/ox-property-editor-qc-limits.d.ts +5 -0
  44. package/dist/src/usecase/qc/ox-property-editor-qc-limits.js +24 -0
  45. package/dist/src/usecase/qc/ox-property-editor-qc-limits.js.map +1 -0
  46. package/dist/stories/ox-data-entry-form.stories.d.ts +19 -0
  47. package/dist/stories/ox-data-entry-form.stories.js +152 -0
  48. package/dist/stories/ox-data-entry-form.stories.js.map +1 -0
  49. package/dist/stories/ox-data-item-spec.stories.d.ts +26 -0
  50. package/dist/stories/ox-data-item-spec.stories.js +102 -0
  51. package/dist/stories/ox-data-item-spec.stories.js.map +1 -0
  52. package/dist/stories/ox-data-ooc-view.stories.d.ts +19 -0
  53. package/dist/stories/ox-data-ooc-view.stories.js +242 -0
  54. package/dist/stories/ox-data-ooc-view.stories.js.map +1 -0
  55. package/dist/stories/ox-data-sample-view.stories.d.ts +19 -0
  56. package/dist/stories/ox-data-sample-view.stories.js +213 -0
  57. package/dist/stories/ox-data-sample-view.stories.js.map +1 -0
  58. package/dist/stories/ox-grist-editor-data-item-spec.stories.d.ts +27 -0
  59. package/dist/stories/ox-grist-editor-data-item-spec.stories.js +389 -0
  60. package/dist/stories/ox-grist-editor-data-item-spec.stories.js.map +1 -0
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +18 -12
  63. package/src/grist-editor/ox-grist-editor-data-item-spec.ts +1 -1
  64. package/src/grist-editor/ox-popup-data-item-spec.ts +3 -2
  65. package/src/index.ts +1 -5
  66. package/src/ox-data-item-spec.ts +3 -3
  67. package/src/ox-data-ooc-view.ts +1 -1
  68. package/src/ox-data-sample-view.ts +28 -31
  69. package/src/types.ts +23 -6
  70. package/src/usecase/ccp/index.ts +10 -0
  71. package/src/usecase/ccp/ox-data-use-case-ccp.ts +147 -0
  72. package/src/usecase/ccp/ox-input-ccp-limits.ts +161 -0
  73. package/src/usecase/ccp/ox-property-editor-ccp-limits.ts +23 -0
  74. package/src/{ox-data-use-case.ts → usecase/ox-data-use-case.ts} +28 -40
  75. package/src/usecase/qc/index.ts +10 -0
  76. package/src/usecase/qc/ox-data-use-case-qc.ts +72 -0
  77. package/src/usecase/qc/ox-input-qc-limits.ts +161 -0
  78. package/src/usecase/qc/ox-property-editor-qc-limits.ts +23 -0
  79. package/stories/ox-data-entry-form.stories.ts +165 -0
  80. package/stories/ox-data-item-spec.stories.ts +121 -0
  81. package/stories/ox-data-ooc-view.stories.ts +256 -0
  82. package/stories/ox-data-sample-view.stories.ts +227 -0
  83. package/stories/ox-grist-editor-data-item-spec.stories.ts +409 -0
  84. package/translations/en.json +26 -8
  85. package/translations/ko.json +25 -7
  86. package/translations/ms.json +26 -8
  87. package/translations/zh.json +25 -7
  88. package/demo/index.html +0 -28
  89. package/demo/ox-data-entry-form.html +0 -118
  90. package/demo/ox-data-item-spec.html +0 -152
  91. package/demo/ox-data-ooc-view.html +0 -185
  92. package/demo/ox-data-sample-view.html +0 -150
  93. package/demo/ox-grist-editor-data-item-spec.html +0 -476
  94. package/dist/src/ox-data-use-case.js.map +0 -1
@@ -4,6 +4,7 @@ import { css, html, LitElement } from 'lit'
4
4
  import { customElement, property } from 'lit/decorators.js'
5
5
 
6
6
  import { i18next } from '@operato/i18n'
7
+ import { closePopup } from '@operato/popup'
7
8
  import { ScrollbarStyles } from '@operato/styles'
8
9
 
9
10
  import { DataItem } from '../types.js'
@@ -82,11 +83,11 @@ export class OxPopupDataItemSpec extends LitElement {
82
83
  }
83
84
 
84
85
  private onCancel(e: Event) {
85
- history.back()
86
+ closePopup(this)
86
87
  }
87
88
 
88
89
  private onConfirm(e: Event) {
89
90
  this.confirmCallback && this.confirmCallback(this.value)
90
- history.back()
91
+ closePopup(this)
91
92
  }
92
93
  }
package/src/index.ts CHANGED
@@ -1,6 +1,2 @@
1
- export * from './ox-data-entry-form.js'
2
- export * from './ox-data-sample-view.js'
3
- export * from './ox-data-ooc-view.js'
4
- export * from './ox-data-item-spec.js'
5
- export * from './ox-data-use-case'
6
1
  export * from './types.js'
2
+ export * from './usecase/ox-data-use-case.js'
@@ -3,8 +3,8 @@ import '@operato/property-editor/ox-properties-dynamic-view.js'
3
3
  import { css, html, LitElement, PropertyValues } from 'lit'
4
4
  import { customElement, property, queryAll, state } from 'lit/decorators.js'
5
5
 
6
- import { OxDataUseCase } from './ox-data-use-case.js'
7
- import { DataItem, DataItemSpecSet } from './types.js'
6
+ import { DataItem, UseCaseDefinition } from './types.js'
7
+ import { OxDataUseCase } from './usecase/ox-data-use-case.js'
8
8
 
9
9
  @customElement('ox-data-item-spec')
10
10
  export class OxDataItemSpec extends LitElement {
@@ -87,7 +87,7 @@ export class OxDataItemSpec extends LitElement {
87
87
  @property({ type: Object }) value?: { [specSetName: string]: any }
88
88
  @property({ type: Object }) dataItem?: DataItem
89
89
 
90
- @state() dataItemSpecSets: DataItemSpecSet[] = []
90
+ @state() dataItemSpecSets: UseCaseDefinition[] = []
91
91
 
92
92
  @queryAll('ox-properties-dynamic-view') specSetViews!: NodeListOf<HTMLElement & { value: any }>
93
93
 
@@ -108,7 +108,7 @@ export class OxDataOocView extends LitElement {
108
108
  const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
109
109
 
110
110
  return html`
111
- <ox-data-sample-view .dataSample=${this.dataOoc} .dataSet=${this.dataSet}></ox-data-sample-view>
111
+ <ox-data-sample-view .dataSample=${this.dataOoc}></ox-data-sample-view>
112
112
 
113
113
  <h3 state>
114
114
  <!--상태에 따라 추가로 danger, complate를 어트리뷰트로 추가시 배경컬러 변경되도록 해두었습니다-->
@@ -5,8 +5,8 @@ import { customElement, property } from 'lit/decorators.js'
5
5
 
6
6
  import { i18next } from '@operato/i18n'
7
7
 
8
- import { OxDataUseCase } from './ox-data-use-case.js'
9
- import { DataItem, DataSample, DataSet } from './types.js'
8
+ import { DataSample, DataSpecLimitSet } from './types.js'
9
+ import { OxDataUseCase } from './usecase/ox-data-use-case.js'
10
10
 
11
11
  @customElement('ox-data-sample-view')
12
12
  export class OxDataSampleView extends LitElement {
@@ -95,16 +95,23 @@ export class OxDataSampleView extends LitElement {
95
95
  }
96
96
  `
97
97
 
98
- @property({ type: Object }) dataSet?: DataSet
99
98
  @property({ type: Object }) dataSample?: DataSample
100
99
 
101
100
  render() {
102
- const dataItems = this.dataSet?.dataItems.filter(item => item.active) || []
103
- const data = this.dataSample?.data || {}
101
+ var { data = {}, spec: dataItems = [] } = this.dataSample || {}
104
102
  const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
105
103
 
106
104
  const { name, description, collectedAt, workDate, workShift } = this.dataSample || {}
107
105
 
106
+ /* TODO below converting logic should be removed after dataset migration */
107
+ if (!(dataItems instanceof Array)) {
108
+ dataItems = Object.keys(dataItems).map(tag => {
109
+ var dataItem = (dataItems as any)[tag]
110
+ dataItem.tag = tag
111
+ return dataItem
112
+ })
113
+ }
114
+
108
115
  return html` <h2>${name}</h2>
109
116
  <p page-description>
110
117
  <mwc-icon>info_outline</mwc-icon> ${description}<br />
@@ -125,15 +132,17 @@ export class OxDataSampleView extends LitElement {
125
132
  <th>${i18next.t('field.oos')}</th>
126
133
  </tr>
127
134
  ${dataItems.map(dataItem => {
128
- const { ooc, oos } = this.evaluateOOC(dataItem, data?.[dataItem.tag]) || {}
129
- const { name, description, unit } = dataItem
135
+ const { name = '', tag = '', description = '', unit = '', spec = {} } = dataItem
136
+ const value = data[tag]
137
+ const { ooc, oos } = this.evaluateOOC(spec, value) || {}
138
+
130
139
  return html`
131
140
  <tr ?ooc=${ooc} ?oos=${oos}>
132
141
  <td name>${name}</td>
133
142
  <td>${description}</td>
134
143
  <td>${unit}</td>
135
- <td>${this.buildValue(dataItem)}</td>
136
- <td><pre>${this.buildSpec(dataItem)}</pre></td>
144
+ <td>${this.buildValue(value)}</td>
145
+ <td><pre>${this.buildSpec(spec)}</pre></td>
137
146
  <td>${ooc ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
138
147
  <td>${oos ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
139
148
  </tr>
@@ -145,43 +154,31 @@ export class OxDataSampleView extends LitElement {
145
154
 
146
155
  private onChange(e: Event) {}
147
156
 
148
- private buildSpec(dataItem: DataItem) {
149
- return OxDataUseCase.elaborateDataItemSpec(this.dataSet!, dataItem)
157
+ private buildSpec(spec: DataSpecLimitSet) {
158
+ return OxDataUseCase.elaborateDataItemSpec(spec)
150
159
  }
151
160
 
152
- private buildValue(dataItem: DataItem) {
153
- const { tag, type } = dataItem
154
-
155
- if (!this.dataSample) {
156
- return ''
157
- }
158
-
159
- const value = this.dataSample?.data[dataItem.tag]
161
+ private buildValue(value: any | any[]) {
160
162
  if (value === undefined) {
161
163
  return ''
162
164
  }
163
165
  const values = value instanceof Array ? value : [value]
164
166
 
165
- const elements = values.map((_: any, idx) => {
166
- const v = value[idx]
167
-
168
- switch (type) {
167
+ const elements = values.map((v: any, idx) => {
168
+ switch (typeof v) {
169
169
  case 'boolean':
170
- return html` <input type="checkbox" name=${tag} .checked=${v} disabled />`
170
+ return html` <input type="checkbox" .checked=${v} disabled />`
171
171
  break
172
172
 
173
- case 'select':
174
- case 'number':
175
- case 'string':
176
173
  default:
177
- return String(v === undefined ? '' : v)
174
+ return v === undefined ? '' : v
178
175
  }
179
176
  })
180
177
 
181
- return type === 'boolean' ? elements : elements.join(', ')
178
+ return typeof values[0] === 'boolean' ? elements : elements.join(', ')
182
179
  }
183
180
 
184
- private evaluateOOC(dataItem: DataItem, value: any) {
185
- return OxDataUseCase.evaluateItem(this.dataSet!, dataItem, value)
181
+ private evaluateOOC(spec: DataSpecLimitSet, value: any) {
182
+ return OxDataUseCase.evaluateItem(spec, value)
186
183
  }
187
184
  }
package/src/types.ts CHANGED
@@ -15,7 +15,11 @@ export type DataItem = {
15
15
  options: TypeOptions
16
16
  unit: string
17
17
  quota: number
18
- spec: { [useCase: string]: any }
18
+ spec: {
19
+ [useCase: string]: {
20
+ [limit: string]: number | string | string[] | boolean
21
+ }
22
+ }
19
23
  }
20
24
 
21
25
  export type DataSet = {
@@ -28,25 +32,38 @@ export type DataSet = {
28
32
  spec: { [dataItem: string]: { [useCase: string]: any } }
29
33
  }
30
34
 
31
- export type DataItemSpec = {
35
+ export type DataSpecDefinition = {
32
36
  type: string
33
37
  label: string
34
38
  name: string
35
39
  property?: { [option: string]: any }
36
40
  }
37
41
 
38
- export type DataItemSpecSet = {
42
+ export type UseCaseDefinition = {
39
43
  name: string
40
44
  description: string
41
45
  help: string
42
- specs: DataItemSpec[]
46
+ specs: DataSpecDefinition[]
47
+ }
48
+
49
+ export type DataSpecLimit = {
50
+ [limit: string]: number | string | string[] | boolean
51
+ }
52
+
53
+ export type DataSpecLimitSet = {
54
+ [useCase: string]: DataSpecLimit
55
+ }
56
+
57
+ export type DataCollection = {
58
+ [tag: string]: any
43
59
  }
44
60
 
45
61
  export type DataSample = {
46
62
  name: string
47
63
  description: string
48
- data: any
49
- spec: any
64
+ useCase: string
65
+ data?: DataCollection
66
+ spec?: DataItem[]
50
67
  quota: number
51
68
  workDate: string
52
69
  workShift: string
@@ -0,0 +1,10 @@
1
+ /* Here, only the common module of client and server is imported/exported. Be careful not to use a module dedicated to client or server. */
2
+
3
+ import { OxDataUseCase } from '../ox-data-use-case'
4
+ import { OxDataUseCaseCCP } from './ox-data-use-case-ccp'
5
+
6
+ // OxPropertyEditor.register({
7
+ // 'ccp-limits': 'ox-property-editor-ccp-limits'
8
+ // })
9
+
10
+ OxDataUseCase.registerUseCase('CCP', new OxDataUseCaseCCP())
@@ -0,0 +1,147 @@
1
+ import i18next from 'i18next' // Since this is a common module, @operato/i18n was deliberately avoided.
2
+
3
+ import { DataItem, EvaluationResult, UseCaseDefinition } from '../../types'
4
+ import { OxDataUseCase } from '../ox-data-use-case.js'
5
+
6
+ export class OxDataUseCaseCCP extends OxDataUseCase {
7
+ getSpecification(dataItem: DataItem): UseCaseDefinition {
8
+ return {
9
+ name: 'CCP',
10
+ description: 'Critical Control Point Data Spec',
11
+ help: '',
12
+ specs: [
13
+ {
14
+ type: 'ccp-limits' /* A value which seperates acceptability from unacceptability */,
15
+ label: 'critical-limits',
16
+ name: 'criticalLimits',
17
+ property: dataItem
18
+ },
19
+ {
20
+ type: 'ccp-limits',
21
+ label: 'target-limits',
22
+ name: 'targetLimits',
23
+ property: dataItem
24
+ }
25
+ ]
26
+ }
27
+ }
28
+
29
+ evaluate(spec: any, values: any | any[]): EvaluationResult | undefined {
30
+ if (!spec || typeof values === 'undefined') {
31
+ return
32
+ }
33
+
34
+ if (!(values instanceof Array)) {
35
+ values = [values]
36
+ }
37
+
38
+ const {
39
+ minimum: criticalMinimum,
40
+ maximum: criticalMaximum,
41
+ acceptables: criticalAcceptables
42
+ } = spec['criticalLimits'] || {}
43
+
44
+ const {
45
+ minimum: targetMinimum,
46
+ maximum: targetMaximum,
47
+ acceptables: targetAcceptables
48
+ } = spec['targetLimits'] || {}
49
+
50
+ var oos = false
51
+ var ooc = false
52
+
53
+ for (let i = 0; i < values.length; i++) {
54
+ const value = values[i]
55
+
56
+ if (typeof criticalMinimum !== 'undefined' && value < criticalMinimum) {
57
+ oos = true
58
+ break
59
+ }
60
+
61
+ if (typeof criticalMaximum !== 'undefined' && value > criticalMaximum) {
62
+ oos = true
63
+ break
64
+ }
65
+
66
+ if (typeof criticalAcceptables !== 'undefined' && !criticalAcceptables.includes(value)) {
67
+ oos = true
68
+ break
69
+ }
70
+ }
71
+
72
+ for (let i = 0; i < values.length; i++) {
73
+ const value = values[i]
74
+
75
+ if (typeof targetMinimum !== 'undefined' && value < targetMinimum) {
76
+ ooc = true
77
+ break
78
+ }
79
+
80
+ if (typeof targetMaximum !== 'undefined' && value > targetMaximum) {
81
+ ooc = true
82
+ break
83
+ }
84
+
85
+ if (typeof targetAcceptables !== 'undefined' && !targetAcceptables.includes(value)) {
86
+ ooc = true
87
+ break
88
+ }
89
+ }
90
+
91
+ return { oos, ooc }
92
+ }
93
+
94
+ elaborateUseCaseSpec(limits: any): string | undefined {
95
+ if (!limits) {
96
+ return
97
+ }
98
+
99
+ var text = ''
100
+
101
+ const {
102
+ minimum: criticalMinimum,
103
+ maximum: criticalMaximum,
104
+ acceptables: criticalAcceptables
105
+ } = limits['criticalLimits'] || {}
106
+
107
+ if (criticalMinimum !== undefined || criticalMaximum !== undefined || criticalAcceptables !== undefined) {
108
+ text += `${i18next.t('label.critical-limits')}\n`
109
+ }
110
+
111
+ if (criticalMinimum !== undefined) {
112
+ text += `\t${i18next.t('label.minimum value')} : ${criticalMinimum}\n`
113
+ }
114
+ if (criticalMaximum !== undefined) {
115
+ text += `\t${i18next.t('label.maximum value')} : ${criticalMaximum}\n`
116
+ }
117
+ if (criticalAcceptables !== undefined) {
118
+ text += `\t${i18next.t('label.acceptables')} : ${
119
+ criticalAcceptables instanceof Array ? criticalAcceptables.join(', ') : criticalAcceptables
120
+ }\n`
121
+ }
122
+
123
+ const {
124
+ minimum: targetMinimum,
125
+ maximum: targetMaximum,
126
+ acceptables: targetAcceptables
127
+ } = limits['targetLimits'] || {}
128
+
129
+ if (targetMinimum !== undefined || targetMaximum !== undefined || targetAcceptables !== undefined) {
130
+ text += `${i18next.t('label.target-limits')}\n`
131
+ }
132
+
133
+ if (targetMinimum !== undefined) {
134
+ text += `\t${i18next.t('label.minimum value')} : ${targetMinimum}\n`
135
+ }
136
+ if (targetMaximum !== undefined) {
137
+ text += `\t${i18next.t('label.maximum value')} : ${targetMaximum}\n`
138
+ }
139
+ if (targetAcceptables !== undefined) {
140
+ text += `\t${i18next.t('label.acceptables')} : ${
141
+ targetAcceptables instanceof Array ? targetAcceptables.join(', ') : targetAcceptables
142
+ }\n`
143
+ }
144
+
145
+ return text
146
+ }
147
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @license Copyright © HatioLab Inc. All rights reserved.
3
+ */
4
+
5
+ import { css, html, LitElement } from 'lit'
6
+ import { customElement, property, query, queryAll } from 'lit/decorators.js'
7
+
8
+ import { i18next } from '@operato/i18n'
9
+
10
+ export enum DataItemType {
11
+ number = 'number',
12
+ text = 'text',
13
+ boolean = 'boolean',
14
+ select = 'select',
15
+ file = 'file'
16
+ }
17
+
18
+ export type CcpLimitValue = {
19
+ minimum?: number
20
+ maximum?: number
21
+ acceptables?: string[]
22
+ }
23
+
24
+ /**
25
+ element for CCP limits
26
+
27
+ Example:
28
+
29
+ <ox-input-ccp-limits
30
+ .value=${value}
31
+ .type=${type}>
32
+ </ox-input-ccp-limits>
33
+ */
34
+ @customElement('ox-input-ccp-limits')
35
+ export class OxInputCcpLimits extends LitElement {
36
+ static styles = css`
37
+ :host {
38
+ display: flex;
39
+ flex-direction: column;
40
+ align-content: center;
41
+ }
42
+
43
+ label {
44
+ margin: 0 var(--margin-default) var(--margin-default) 0;
45
+ }
46
+
47
+ label div > * {
48
+ vertical-align: middle;
49
+ }
50
+
51
+ button {
52
+ width: 20px;
53
+ text-align: center;
54
+ }
55
+
56
+ div[name],
57
+ input[type='checkbox'] + span {
58
+ display: inline-block;
59
+ font: var(--label-font);
60
+ color: var(--label-color);
61
+ text-align: right;
62
+ }
63
+ input,
64
+ select {
65
+ border: var(--input-field-border);
66
+ border-radius: var(--input-field-border-radius);
67
+ padding: var(--input-field-padding);
68
+ font: var(--input-field-font);
69
+ }
70
+
71
+ input[type='checkbox'] {
72
+ width: initial;
73
+ }
74
+ input[checked] + span {
75
+ font-weight: bold;
76
+ }
77
+ [unit],
78
+ [value] {
79
+ display: inline-block;
80
+ opacity: 0.7;
81
+ font: var(--form-sublabel-font);
82
+ }
83
+ [properties] {
84
+ font: var(--input-field-font);
85
+ color: var(--label-color);
86
+ }
87
+ `
88
+
89
+ @property({ type: Object }) value: CcpLimitValue = {}
90
+ @property({ type: String }) type: DataItemType = DataItemType.number
91
+ @property({ type: String }) unit?: string
92
+ @property({ type: Array }) options: { options?: { text: string; value: string }[] } = {}
93
+
94
+ @query('[name=minimum]') minimum!: HTMLInputElement
95
+ @query('[name=maximum]') maximum!: HTMLInputElement
96
+ @queryAll('[type=checkbox]:checked') checkedAll!: NodeListOf<HTMLInputElement>
97
+
98
+ firstUpdated() {
99
+ this.renderRoot.addEventListener('change', this.onChange.bind(this))
100
+ }
101
+
102
+ render() {
103
+ const { minimum, maximum, acceptables = [] } = this.value || {}
104
+
105
+ return html`
106
+ <div>
107
+ ${this.type === DataItemType.number
108
+ ? html`
109
+ <label>
110
+ <div name>${i18next.t('text.minimum value')}</div>
111
+ <input type="number" name="minimum" .value=${minimum} />
112
+ <div unit>${this.unit}</div>
113
+ </select>
114
+ </label>
115
+ <label>
116
+ <div name>${i18next.t('text.maximum value')}</div>
117
+ <input type="number" name="maximum" .value=${maximum} />
118
+ <div unit>${this.unit}</div>
119
+ </label>
120
+ </div>
121
+ `
122
+ : this.type === DataItemType.select
123
+ ? html`
124
+ <!-- <div>Acceptables</div> -->
125
+ ${this.options?.options?.map(
126
+ option => html`
127
+ <div>
128
+ <input type="checkbox" data-value=${option.value} ?checked=${acceptables.includes(option.value)} />
129
+ <span>${option.text}</span>
130
+ <span value>(${option.value})</span>
131
+ </div>
132
+ `
133
+ )}
134
+ </div>
135
+ `
136
+ : html` <div properties>${i18next.t('text.no properties to set')}</div> `}
137
+ </div>
138
+ `
139
+ }
140
+
141
+ private onChange(e: Event) {
142
+ if (this.type === DataItemType.number) {
143
+ this.value = {
144
+ minimum: this.minimum.valueAsNumber,
145
+ maximum: this.maximum.valueAsNumber
146
+ }
147
+ } else if (this.type === DataItemType.select) {
148
+ this.value = {
149
+ acceptables: Array.from(this.checkedAll).map(checked => {
150
+ const x = checked.getAttribute('data-value')!
151
+ console.log(x)
152
+ return x
153
+ })
154
+ }
155
+ } else {
156
+ this.value = {}
157
+ }
158
+
159
+ this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true, detail: this.value }))
160
+ }
161
+ }
@@ -0,0 +1,23 @@
1
+ import './ox-input-ccp-limits.js'
2
+
3
+ import { html } from 'lit'
4
+ import { customElement } from 'lit/decorators.js'
5
+
6
+ import { OxPropertyEditor } from '@operato/property-editor'
7
+
8
+ @customElement('ox-property-editor-ccp-limits')
9
+ export class OxPropertyEditorCcpLimits extends OxPropertyEditor {
10
+ editorTemplate() {
11
+ const { type, options, unit } = this.property || {}
12
+
13
+ return html`
14
+ <ox-input-ccp-limits
15
+ id="editor"
16
+ .value=${this.value}
17
+ .type=${type}
18
+ .unit=${unit}
19
+ .options=${options}
20
+ ></ox-input-ccp-limits>
21
+ `
22
+ }
23
+ }