@operato/dataset 1.0.0-alpha.9 → 1.0.0-beta.10

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 (59) hide show
  1. package/CHANGELOG.md +735 -0
  2. package/demo/index.html +8 -90
  3. package/demo/ox-data-entry-form.html +118 -0
  4. package/demo/ox-data-item-spec.html +152 -0
  5. package/demo/ox-data-ooc-view.html +185 -0
  6. package/demo/ox-data-sample-view.html +150 -0
  7. package/demo/ox-grist-editor-data-item-spec.html +476 -0
  8. package/dist/src/grist-editor/index.d.ts +1 -0
  9. package/dist/src/grist-editor/index.js +7 -0
  10. package/dist/src/grist-editor/index.js.map +1 -0
  11. package/dist/src/grist-editor/ox-grist-editor-data-item-spec.d.ts +11 -0
  12. package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js +77 -0
  13. package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js.map +1 -0
  14. package/dist/src/grist-editor/ox-popup-data-item-spec.d.ts +13 -0
  15. package/dist/src/grist-editor/ox-popup-data-item-spec.js +91 -0
  16. package/dist/src/grist-editor/ox-popup-data-item-spec.js.map +1 -0
  17. package/dist/src/index.d.ts +6 -1
  18. package/dist/src/index.js +6 -1
  19. package/dist/src/index.js.map +1 -1
  20. package/dist/src/ox-data-entry-form.d.ts +1 -24
  21. package/dist/src/ox-data-entry-form.js +52 -26
  22. package/dist/src/ox-data-entry-form.js.map +1 -1
  23. package/dist/src/ox-data-item-spec.d.ts +18 -0
  24. package/dist/src/ox-data-item-spec.js +77 -0
  25. package/dist/src/ox-data-item-spec.js.map +1 -0
  26. package/dist/src/ox-data-ooc-view.d.ts +11 -0
  27. package/dist/src/ox-data-ooc-view.js +75 -0
  28. package/dist/src/ox-data-ooc-view.js.map +1 -0
  29. package/dist/src/ox-data-sample-view copy.d.ts +13 -0
  30. package/dist/src/ox-data-sample-view copy.js +214 -0
  31. package/dist/src/ox-data-sample-view copy.js.map +1 -0
  32. package/dist/src/ox-data-sample-view.d.ts +13 -0
  33. package/dist/src/ox-data-sample-view.js +169 -0
  34. package/dist/src/ox-data-sample-view.js.map +1 -0
  35. package/dist/src/ox-data-use-case.d.ts +16 -0
  36. package/dist/src/ox-data-use-case.js +111 -0
  37. package/dist/src/ox-data-use-case.js.map +1 -0
  38. package/dist/src/types.d.ts +78 -0
  39. package/dist/src/types.js +2 -0
  40. package/dist/src/types.js.map +1 -0
  41. package/dist/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +20 -12
  43. package/src/grist-editor/index.ts +10 -0
  44. package/src/grist-editor/ox-grist-editor-data-item-spec.ts +92 -0
  45. package/src/grist-editor/ox-popup-data-item-spec.ts +92 -0
  46. package/src/index.ts +6 -1
  47. package/src/ox-data-entry-form.ts +52 -47
  48. package/src/ox-data-item-spec.ts +74 -0
  49. package/src/ox-data-ooc-view.ts +75 -0
  50. package/src/ox-data-sample-view.ts +177 -0
  51. package/src/ox-data-use-case.ts +147 -0
  52. package/src/types.ts +72 -0
  53. package/themes/grist-theme.css +194 -0
  54. package/themes/oops-theme.css +26 -0
  55. package/themes/report-theme.css +47 -0
  56. package/translations/en.json +57 -0
  57. package/translations/ko.json +56 -0
  58. package/translations/ms.json +56 -0
  59. package/translations/zh.json +56 -0
@@ -0,0 +1,92 @@
1
+ import '../ox-data-item-spec.js'
2
+
3
+ import { css, html, LitElement } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+
6
+ import { i18next } from '@operato/i18n'
7
+ import { ScrollbarStyles } from '@operato/styles'
8
+
9
+ import { DataItem } from '../types.js'
10
+
11
+ @customElement('ox-popup-data-item-spec')
12
+ export class OxPopupDataItemSpec extends LitElement {
13
+ static styles = [
14
+ ScrollbarStyles,
15
+ css`
16
+ :host {
17
+ display: flex;
18
+ flex-direction: column;
19
+
20
+ background-color: #fff;
21
+
22
+ width: var(--overlay-center-normal-width, 50%);
23
+ height: var(--overlay-center-normal-height, 50%);
24
+ }
25
+
26
+ ox-data-item-spec {
27
+ flex: 1;
28
+ overflow-y: auto;
29
+ padding: var(--padding-wide);
30
+ }
31
+
32
+ span {
33
+ flex: 1;
34
+
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: center;
38
+
39
+ color: var(--primary-color);
40
+ }
41
+
42
+ .button-container {
43
+ display: flex;
44
+ margin-left: auto;
45
+ }
46
+ `
47
+ ]
48
+
49
+ @property({ type: Object }) value: any
50
+ @property({ type: Object }) dataItem?: DataItem
51
+ @property({ type: Object }) confirmCallback!: (newval: any) => void
52
+
53
+ render() {
54
+ var dataItem = this.dataItem || {}
55
+
56
+ return html`
57
+ <ox-data-item-spec .value=${this.value} .dataItem=${dataItem} @change=${this.onChange.bind(this)}>
58
+ </ox-data-item-spec>
59
+
60
+ <div class="button-container">
61
+ <mwc-button @click=${this.onCancel.bind(this)}>${i18next.t('button.cancel')}</mwc-button>
62
+ <mwc-button @click=${this.onConfirm.bind(this)}>${i18next.t('button.confirm')}</mwc-button>
63
+ </div>
64
+ `
65
+ }
66
+
67
+ private onChange(e: CustomEvent) {
68
+ e.stopPropagation()
69
+
70
+ /*
71
+ 주의 : 이 팝업 템플릿은 layout 모듈에 의해서 render 되므로,
72
+ layout의 구성에 변화가 발생하면, 다시 render된다.
73
+ 이 팝업이 떠 있는 상태에서, 또 다른 팝업이 뜨는 경우도 layout 구성의 변화를 야기한다. (overlay의 갯수의 증가)
74
+ 이 경우 value, options, confirmCallback 등 클로져를 사용한 것들이 초기 바인딩된 값으로 다시 바인딩되게 되는데,
75
+ 만약, 템플릿 내부에서 이들 속성의 레퍼런스가 변화했다면, 원래 상태로 되돌아가는 현상이 발생하게 된다.
76
+ 따라서, 가급적 이들 속성의 레퍼런스를 변화시키지 않는 것이 좋다.
77
+ (이 팝업 클래스를 템플릿으로 사용한 곳의 코드를 참조하세요.)
78
+ =>
79
+ 이런 이유로, Object.assign(...)을 사용하였다.
80
+ */
81
+ this.value = e.detail
82
+ }
83
+
84
+ private onCancel(e: Event) {
85
+ history.back()
86
+ }
87
+
88
+ private onConfirm(e: Event) {
89
+ this.confirmCallback && this.confirmCallback(this.value)
90
+ history.back()
91
+ }
92
+ }
package/src/index.ts CHANGED
@@ -1 +1,6 @@
1
- export * from './ox-data-entry-form'
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
+ export * from './types.js'
@@ -1,30 +1,9 @@
1
1
  import '@operato/input/ox-input-file.js'
2
2
 
3
- import { LitElement, css, html } from 'lit'
3
+ import { css, html, LitElement } from 'lit'
4
4
  import { customElement, property } from 'lit/decorators.js'
5
5
 
6
- type SelectOption = { text: string; value: string }
7
- type SelectOptions = SelectOption[]
8
- type TypeOptions = {
9
- options?: SelectOptions
10
- [prop: string]: any
11
- }
12
-
13
- export type DataItem = {
14
- name: string
15
- description: string
16
- sequence: number
17
- tag: string
18
- type: string
19
- options: TypeOptions
20
- quota: number
21
- }
22
-
23
- export type DataSet = {
24
- name: string
25
- description: string
26
- dataItems: DataItem[]
27
- }
6
+ import { DataSet } from './types.js'
28
7
 
29
8
  @customElement('ox-data-entry-form')
30
9
  export class OxDataEntryForm extends LitElement {
@@ -34,6 +13,11 @@ export class OxDataEntryForm extends LitElement {
34
13
  flex-direction: row;
35
14
  }
36
15
 
16
+ h2,
17
+ h3 {
18
+ text-align: center;
19
+ }
20
+
37
21
  form {
38
22
  flex: 1;
39
23
 
@@ -42,23 +26,34 @@ export class OxDataEntryForm extends LitElement {
42
26
  }
43
27
  label {
44
28
  display: grid;
45
- grid-template-columns: repeat(12, 1fr);
46
- gap: 9px;
29
+
30
+ grid-template-rows: auto 1fr;
31
+ grid-template-columns: 1fr 5fr;
32
+ grid-template-areas: 'name description' 'empty inputs';
33
+
34
+ grid-gap: 9px;
47
35
  align-items: center;
48
36
  margin-bottom: var(--margin-default);
49
37
  }
50
- label:nth-child(even) {
38
+ label:nth-child(odd) {
51
39
  background-color: var(--main-section-background-color);
52
40
  padding: var(--padding-default) 0;
53
41
  }
42
+
54
43
  div[name] {
55
- grid-column: span 2 / auto;
44
+ grid-area: name;
56
45
  font: var(--label-font);
57
46
  color: var(--label-color);
58
47
  text-align: right;
59
48
  }
49
+ div[description] {
50
+ grid-area: description;
51
+ font: var(--page-description-font);
52
+ color: var(--page-description-color);
53
+ text-align: left;
54
+ }
60
55
  div[elements] {
61
- grid-column: span 10 / auto;
56
+ grid-area: inputs;
62
57
  display: flex;
63
58
  flex-direction: row;
64
59
  flex-wrap: wrap;
@@ -75,12 +70,22 @@ export class OxDataEntryForm extends LitElement {
75
70
  padding: var(--input-field-padding);
76
71
  font: var(--input-field-font);
77
72
  }
73
+
78
74
  @media only screen and (max-width: 460px) {
79
- div[name] {
80
- grid-column: span 3 / auto;
75
+ label {
76
+ display: grid;
77
+
78
+ grid-template-rows: auto auto 1fr;
79
+ grid-template-columns: 1fr;
80
+ grid-template-areas: 'name' 'description' 'inputs';
81
+
82
+ grid-gap: 9px;
83
+ align-items: center;
84
+ margin-bottom: var(--margin-default);
81
85
  }
82
- div[elements] {
83
- grid-column: span 9 / auto;
86
+
87
+ div[name] {
88
+ text-align: left;
84
89
  }
85
90
  }
86
91
  `
@@ -89,32 +94,36 @@ export class OxDataEntryForm extends LitElement {
89
94
  @property({ type: Object }) value?: { [tag: string]: any }
90
95
 
91
96
  render() {
92
- return html`<form @change=${(e: Event) => this.onChange(e)}>${this.buildInputs()}</form>`
97
+ return html` <form @change=${(e: Event) => this.onChange(e)}>
98
+ <h2>${this.dataSet?.name || ''}</h2>
99
+ <h3>${this.dataSet?.description || ''}</h3>
100
+ ${this.buildInputs()}
101
+ </form>`
93
102
  }
94
103
 
95
104
  private onChange(e: Event) {
96
- const value = this.buildValue()
105
+ this.value = this.buildValue()
97
106
 
98
107
  this.dispatchEvent(
99
108
  new CustomEvent('change', {
100
109
  bubbles: true,
101
110
  composed: true,
102
- detail: value
111
+ detail: this.value
103
112
  })
104
113
  )
105
114
  }
106
115
 
107
116
  private buildInputs() {
108
- const dataItems = this.dataSet!.dataItems
117
+ const dataItems = this.dataSet!.dataItems.filter(item => item.active)
109
118
 
110
119
  return (dataItems || []).map(dataItem => {
111
- const { name, description, tag, type, quota = 1, options = {} } = dataItem
120
+ const { name, description, tag, type, quota = 1, options = {}, unit } = dataItem
112
121
 
113
122
  const samples = new Array(quota).fill(0)
114
- const value = this.value?.[tag]
123
+ const value = this.value && this.value[tag]
115
124
 
116
125
  const elements = samples.map((_, idx) => {
117
- const v = quota <= 1 ? value : value instanceof Array && value[idx]
126
+ const v = value instanceof Array ? value[idx] : idx === 0 ? value : undefined
118
127
 
119
128
  switch (type) {
120
129
  case 'select':
@@ -150,7 +159,8 @@ export class OxDataEntryForm extends LitElement {
150
159
  })
151
160
 
152
161
  return html` <label .title=${description}>
153
- <div name>${name}</div>
162
+ <div name>${name}${unit ? `(${unit})` : ''}</div>
163
+ <div description>${description}</div>
154
164
  <div elements>${elements}</div>
155
165
  </label>`
156
166
  })
@@ -160,19 +170,14 @@ export class OxDataEntryForm extends LitElement {
160
170
  const dataItems = this.dataSet!.dataItems
161
171
 
162
172
  return (dataItems || []).reduce((sum, dataItem) => {
163
- const { tag, quota, type } = dataItem
173
+ const { tag, type } = dataItem
164
174
 
165
175
  const editors = Array.prototype.slice.call(
166
176
  this.renderRoot.querySelectorAll(`[name=${tag}]`) as NodeListOf<HTMLInputElement>
167
177
  ) as HTMLInputElement[]
168
178
 
169
179
  if (editors.length > 0) {
170
- sum[tag] =
171
- editors.length > 1
172
- ? editors.map(editor => (type === 'boolean' ? editor.checked : editor.value))
173
- : type === 'boolean'
174
- ? editors[0].checked
175
- : editors[0].value
180
+ sum[tag] = editors.map(editor => (type === 'boolean' ? editor.checked : editor.value))
176
181
  }
177
182
 
178
183
  return sum
@@ -0,0 +1,74 @@
1
+ import '@operato/property-editor/ox-properties-dynamic-view.js'
2
+
3
+ import { css, html, LitElement, PropertyValues } from 'lit'
4
+ import { customElement, property, queryAll, state } from 'lit/decorators.js'
5
+
6
+ import { OxDataUseCase } from './ox-data-use-case.js'
7
+ import { DataItem, DataItemSpecSet } from './types.js'
8
+
9
+ @customElement('ox-data-item-spec')
10
+ export class OxDataItemSpec extends LitElement {
11
+ static styles = css`
12
+ :host {
13
+ display: flex;
14
+ flex-direction: row;
15
+ border-bottom: var(--border-dark-color);
16
+ padding: var(--margin-default) 0;
17
+ }
18
+ [specName] {
19
+ font: var(--legend-font);
20
+ color: var(--legend-text-color);
21
+ }
22
+ [description] {
23
+ font: var(--form-sublabel-font);
24
+ opacity: 0.8;
25
+ }
26
+
27
+ form {
28
+ flex: 1;
29
+ }
30
+ `
31
+
32
+ @property({ type: Object }) value?: { [specSetName: string]: any }
33
+ @property({ type: Object }) dataItem?: DataItem
34
+
35
+ @state() dataItemSpecSets: DataItemSpecSet[] = []
36
+
37
+ @queryAll('ox-properties-dynamic-view') specSetViews!: NodeListOf<HTMLElement & { value: any }>
38
+
39
+ render() {
40
+ return html`<form @property-change=${(e: Event) => this.onChange(e)}>
41
+ ${this.dataItemSpecSets.map(
42
+ ({ name, description, specs }) => html` <div specName>${name}</div>
43
+ <div description>${description}</div>
44
+ <ox-properties-dynamic-view data-name=${name} .props=${specs} .value=${this.value?.[name]}>
45
+ </ox-properties-dynamic-view>`
46
+ )}
47
+ </form>`
48
+ }
49
+
50
+ updated(changes: PropertyValues<this>) {
51
+ if (changes.has('dataItem')) {
52
+ this.dataItemSpecSets = OxDataUseCase.getUseCases().map(useCase => useCase.getSpecification(this.dataItem!))
53
+ }
54
+ }
55
+
56
+ private onChange(e: Event) {
57
+ this.value = this.buildValue()
58
+
59
+ this.dispatchEvent(
60
+ new CustomEvent('change', {
61
+ bubbles: true,
62
+ composed: true,
63
+ detail: { ...this.value }
64
+ })
65
+ )
66
+ }
67
+
68
+ private buildValue() {
69
+ var value = {} as any
70
+ this.specSetViews.forEach(view => (value[view.getAttribute('data-name')!] = view.value))
71
+
72
+ return value
73
+ }
74
+ }
@@ -0,0 +1,75 @@
1
+ import '@operato/input/ox-input-file.js'
2
+ import './ox-data-sample-view'
3
+ import '@material/mwc-icon'
4
+
5
+ import { css, html, LitElement } from 'lit'
6
+ import { customElement, property } from 'lit/decorators.js'
7
+
8
+ import { i18next } from '@operato/i18n'
9
+
10
+ import { DataOoc, DataSet } from './types.js'
11
+
12
+ @customElement('ox-data-ooc-view')
13
+ export class OxDataOocView extends LitElement {
14
+ static styles = css`
15
+ :host {
16
+ display: flex;
17
+ flex-direction: column;
18
+ background-color: var(--main-section-background-color);
19
+ padding: var(--padding-wide);
20
+
21
+ position: relative;
22
+ }
23
+
24
+ h3 {
25
+ margin: var(--title-margin);
26
+ padding-top: 12px;
27
+ font: var(--title-font);
28
+ color: var(--title-text-color);
29
+ }
30
+
31
+ h3[state] {
32
+ position: absolute;
33
+
34
+ right: 20px;
35
+ top: 25px;
36
+ }
37
+
38
+ mwc-icon {
39
+ font-size: 16px;
40
+ }
41
+
42
+ [page-description] {
43
+ margin: var(--page-description-margin);
44
+ font: var(--page-description-font);
45
+ color: var(--page-description-color);
46
+ }
47
+ `
48
+
49
+ @property({ type: Object }) dataSet?: DataSet
50
+ @property({ type: Object }) dataOoc?: DataOoc
51
+
52
+ render() {
53
+ const history = this.dataOoc?.history || []
54
+ const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
55
+
56
+ return html`
57
+ <ox-data-sample-view .dataSample=${this.dataOoc} .dataSet=${this.dataSet}></ox-data-sample-view>
58
+
59
+ <h3 state>${this.dataOoc?.state || ''}</h3>
60
+
61
+ <h3>${i18next.t('title.history')}</h3>
62
+ ${history.map(
63
+ ({ user, state, comment, timestamp }) => html`
64
+ <p page-description>
65
+ ${formatter.format(new Date(timestamp))}
66
+ <br />
67
+ ${state} <mwc-icon>account_circle</mwc-icon> ${user.name}
68
+ <br />
69
+ ${comment}
70
+ </p>
71
+ `
72
+ )}
73
+ `
74
+ }
75
+ }
@@ -0,0 +1,177 @@
1
+ import '@operato/input/ox-input-file.js'
2
+
3
+ import { css, html, LitElement } from 'lit'
4
+ import { customElement, property } from 'lit/decorators.js'
5
+
6
+ import { i18next } from '@operato/i18n'
7
+
8
+ import { OxDataUseCase } from './ox-data-use-case.js'
9
+ import { DataItem, DataSample, DataSet } from './types.js'
10
+
11
+ @customElement('ox-data-sample-view')
12
+ export class OxDataSampleView extends LitElement {
13
+ static styles = css`
14
+ :host {
15
+ display: flex;
16
+ flex-direction: column;
17
+ background-color: var(--main-section-background-color);
18
+ }
19
+
20
+ form {
21
+ flex: 1;
22
+
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+
27
+ h2 {
28
+ margin: var(--title-margin);
29
+ padding-top: 25px;
30
+ font: var(--title-font);
31
+ color: var(--title-text-color);
32
+ }
33
+ [page-description] {
34
+ margin: var(--page-description-margin);
35
+ font: var(--page-description-font);
36
+ color: var(--page-description-color);
37
+ }
38
+
39
+ table {
40
+ border-collapse: collapse;
41
+ margin-bottom: var(--margin-default);
42
+ }
43
+ th {
44
+ padding: var(--th-padding);
45
+ border-top: var(--th-border-top);
46
+ border-bottom: var(--td-border-bottom);
47
+ text-transform: var(--th-text-transform);
48
+ font: var(--th-font);
49
+ color: var(--th-color);
50
+ text-align: left;
51
+ }
52
+ th[item] {
53
+ min-width: 100px;
54
+ }
55
+ th[value] {
56
+ min-width: 100px;
57
+ }
58
+ tr {
59
+ background-color: var(--tr-background-color);
60
+ }
61
+ tr:nth-child(odd) {
62
+ background-color: var(--tr-background-odd-color);
63
+ }
64
+ tr:hover {
65
+ background-color: var(--tr-background-hover-color);
66
+ }
67
+ tr[ooc],
68
+ tr[oos] {
69
+ background-color: #fefbdf;
70
+ }
71
+ td {
72
+ border-bottom: var(--td-border-bottom);
73
+ padding: var(--td-padding);
74
+ font: var(--td-font);
75
+ color: var(--td-color);
76
+ }
77
+ td[name] {
78
+ font-weight: bold;
79
+ }
80
+ td mwc-icon {
81
+ color: var(--status-danger-color);
82
+ }
83
+
84
+ pre {
85
+ tab-size: 2;
86
+ }
87
+ `
88
+
89
+ @property({ type: Object }) dataSet?: DataSet
90
+ @property({ type: Object }) dataSample?: DataSample
91
+
92
+ render() {
93
+ const dataItems = this.dataSet?.dataItems.filter(item => item.active) || []
94
+ const data = this.dataSample?.data || {}
95
+ const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
96
+
97
+ const { name, description, collectedAt, workDate, workShift } = this.dataSample || {}
98
+
99
+ return html` <h2>${i18next.t('field.name')}</h2>
100
+ <p page-description>
101
+ ${i18next.t('field.description')}<br /><br />
102
+ ${i18next.t('field.work-date')}: ${workDate} ${workShift}<br />
103
+ ${i18next.t('field.collected-at')}: ${formatter.format(new Date(collectedAt!))}
104
+ </p>
105
+
106
+ <form @change=${(e: Event) => this.onChange(e)}>
107
+ <table>
108
+ <tr>
109
+ <th item>${i18next.t('field.item')}</th>
110
+ <th>${i18next.t('field.description')}</th>
111
+ <th>${i18next.t('field.unit')}</th>
112
+ <th value>${i18next.t('field.value')}</th>
113
+ <th>${i18next.t('field.spec')}</th>
114
+ <th>${i18next.t('field.ooc')}</th>
115
+ <th>${i18next.t('field.oos')}</th>
116
+ </tr>
117
+ ${dataItems.map(dataItem => {
118
+ const { ooc, oos } = this.evaluateOOC(dataItem, data?.[dataItem.tag]) || {}
119
+ const { name, description, unit } = dataItem
120
+ return html`
121
+ <tr ?ooc=${ooc} ?oos=${oos}>
122
+ <td name>${name}</td>
123
+ <td>${description}</td>
124
+ <td>${unit}</td>
125
+ <td>${this.buildValue(dataItem)}</td>
126
+ <td><pre>${this.buildSpec(dataItem)}</pre></td>
127
+ <td>${ooc ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
128
+ <td>${oos ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
129
+ </tr>
130
+ `
131
+ })}
132
+ </table>
133
+ </form>`
134
+ }
135
+
136
+ private onChange(e: Event) {}
137
+
138
+ private buildSpec(dataItem: DataItem) {
139
+ return OxDataUseCase.elaborateDataItemSpec(this.dataSet!, dataItem)
140
+ }
141
+
142
+ private buildValue(dataItem: DataItem) {
143
+ const { tag, type } = dataItem
144
+
145
+ if (!this.dataSample) {
146
+ return ''
147
+ }
148
+
149
+ const value = this.dataSample?.data[dataItem.tag]
150
+ if (value === undefined) {
151
+ return ''
152
+ }
153
+ const values = value instanceof Array ? value : [value]
154
+
155
+ const elements = values.map((_: any, idx) => {
156
+ const v = value[idx]
157
+
158
+ switch (type) {
159
+ case 'boolean':
160
+ return html` <input type="checkbox" name=${tag} .checked=${v} disabled />`
161
+ break
162
+
163
+ case 'select':
164
+ case 'number':
165
+ case 'string':
166
+ default:
167
+ return String(v === undefined ? '' : v)
168
+ }
169
+ })
170
+
171
+ return type === 'boolean' ? elements : elements.join(', ')
172
+ }
173
+
174
+ private evaluateOOC(dataItem: DataItem, value: any) {
175
+ return OxDataUseCase.evaluateItem(this.dataSet!, dataItem, value)
176
+ }
177
+ }