@operato/dataset 7.1.30 → 7.1.32

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 (50) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/tsconfig.tsbuildinfo +1 -1
  3. package/package.json +12 -12
  4. package/.editorconfig +0 -29
  5. package/.storybook/main.js +0 -3
  6. package/.storybook/preview.js +0 -52
  7. package/.storybook/server.mjs +0 -8
  8. package/demo/favicon.ico +0 -0
  9. package/demo/index.html +0 -349
  10. package/demo/ox-data-ooc-brief-view-test.html +0 -349
  11. package/src/grist-editor/index.ts +0 -10
  12. package/src/grist-editor/ox-grist-editor-data-item-spec.ts +0 -93
  13. package/src/grist-editor/ox-popup-data-item-spec.ts +0 -93
  14. package/src/index.ts +0 -2
  15. package/src/ox-data-entry-form.ts +0 -303
  16. package/src/ox-data-entry-subgroup-form.ts +0 -157
  17. package/src/ox-data-entry-subgroup-view.ts +0 -221
  18. package/src/ox-data-entry-view.ts +0 -241
  19. package/src/ox-data-item-spec.ts +0 -131
  20. package/src/ox-data-ooc-badge.ts +0 -73
  21. package/src/ox-data-ooc-brief-view.ts +0 -43
  22. package/src/ox-data-ooc-correction-part.ts +0 -107
  23. package/src/ox-data-ooc-history.ts +0 -74
  24. package/src/ox-data-ooc-view.ts +0 -51
  25. package/src/ox-data-sample-subgroup-view.ts +0 -210
  26. package/src/ox-data-sample-view.ts +0 -271
  27. package/src/ox-data-summary-view.ts +0 -198
  28. package/src/types.ts +0 -178
  29. package/src/usecase/ccp/index.ts +0 -10
  30. package/src/usecase/ccp/ox-data-use-case-ccp.ts +0 -147
  31. package/src/usecase/ccp/ox-input-ccp-limits.ts +0 -184
  32. package/src/usecase/ccp/ox-property-editor-ccp-limits.ts +0 -23
  33. package/src/usecase/ox-data-use-case.ts +0 -178
  34. package/src/usecase/qc/index.ts +0 -10
  35. package/src/usecase/qc/ox-data-use-case-qc.ts +0 -76
  36. package/src/usecase/qc/ox-input-qc-limits.ts +0 -183
  37. package/src/usecase/qc/ox-property-editor-qc-limits.ts +0 -23
  38. package/src/usecase/spc/index.ts +0 -10
  39. package/src/usecase/spc/ox-data-use-case-spc.ts +0 -147
  40. package/src/usecase/spc/ox-input-spc-limits.ts +0 -184
  41. package/src/usecase/spc/ox-property-editor-spc-limits.ts +0 -23
  42. package/stories/ox-data-entry-form.stories.ts +0 -253
  43. package/stories/ox-data-item-spec.stories.ts +0 -257
  44. package/stories/ox-data-ooc-brief-view.stories.ts +0 -333
  45. package/stories/ox-data-ooc-view.stories.ts +0 -327
  46. package/stories/ox-data-sample-view.stories.ts +0 -313
  47. package/stories/ox-grist-editor-data-item-spec.stories.ts +0 -412
  48. package/tsconfig.json +0 -24
  49. package/web-dev-server.config.mjs +0 -27
  50. package/web-test-runner.config.mjs +0 -41
@@ -1,51 +0,0 @@
1
- import '@operato/input/ox-input-file.js'
2
- import './ox-data-sample-view'
3
- import './ox-data-ooc-history'
4
- import '@material/web/icon/icon.js'
5
-
6
- import { css, html, LitElement } from 'lit'
7
- import { customElement, property } from 'lit/decorators.js'
8
-
9
- import { i18next } from '@operato/i18n'
10
-
11
- import { DataOoc, DataSet } from './types.js'
12
-
13
- /**
14
- * @deprecated by ox-data-ooc-brief-view
15
- */
16
- @customElement('ox-data-ooc-view')
17
- export class OxDataOocView extends LitElement {
18
- static styles = css`
19
- :host {
20
- display: flex;
21
- flex-direction: column;
22
-
23
- position: relative;
24
- }
25
-
26
- ox-data-ooc-badge {
27
- position: absolute;
28
-
29
- margin: 0;
30
- padding: 0;
31
- right: 10px;
32
- width: 90px;
33
- }
34
- `
35
-
36
- @property({ type: Object }) dataSet?: DataSet
37
- @property({ type: Object }) dataOoc?: DataOoc
38
-
39
- render() {
40
- const { state } = this.dataOoc || {}
41
-
42
- return html`
43
- <ox-data-sample-view .dataSample=${this.dataOoc}></ox-data-sample-view>
44
-
45
- <ox-data-ooc-badge .state=${state}></ox-data-ooc-badge>
46
-
47
- <h3>${i18next.t('title.history')}</h3>
48
- <ox-data-ooc-history .dataOoc=${this.dataOoc}></ox-data-ooc-history>
49
- `
50
- }
51
- }
@@ -1,210 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/input/ox-input-file.js'
3
- import '@operato/input/ox-input-signature.js'
4
-
5
- import { css, html, LitElement, nothing } from 'lit'
6
- import { customElement, property } from 'lit/decorators.js'
7
-
8
- import { i18next } from '@operato/i18n'
9
-
10
- import { DataSample, DataSpecLimitSet } from './types.js'
11
- import { OxDataUseCase } from './usecase/ox-data-use-case.js'
12
-
13
- @customElement('ox-data-sample-subgroup-view')
14
- export class OxDataSampleSubgroupView extends LitElement {
15
- static styles = css`
16
- :host {
17
- display: flex;
18
- flex-direction: column;
19
- }
20
-
21
- h3 {
22
- margin: var(--title-margin);
23
- font: var(--title-font);
24
- font-size: 20px;
25
- color: var(--title-text-color);
26
- text-transform: capitalize;
27
- }
28
-
29
- table {
30
- border-collapse: collapse;
31
- margin-bottom: var(--spacing-medium);
32
- }
33
-
34
- th {
35
- padding: var(--th-padding);
36
- border-top: var(--th-border-top);
37
- border-left: var(--td-border-line, 1px solid rgba(0, 0, 0, 0.05));
38
- border-bottom: var(--td-border-bottom);
39
- text-transform: var(--th-text-transform);
40
- font: var(--th-font);
41
- font-weight: bold;
42
- color: var(--th-color);
43
- text-align: center;
44
- white-space: nowrap;
45
- }
46
-
47
- th.label,
48
- td.label {
49
- background-color: var(--label-cell-background-color, #f6f6f6);
50
- width: 120px;
51
- text-transform: var(--th-text-transform);
52
- }
53
-
54
- tr {
55
- background-color: var(--tr-background-color);
56
- }
57
-
58
- tr:hover {
59
- background-color: var(--tr-background-hover-color);
60
- }
61
-
62
- td {
63
- border-left: var(--td-border-line, 1px solid rgba(0, 0, 0, 0.05));
64
- border-bottom: var(--td-border-bottom);
65
- padding: var(--td-padding);
66
- font: var(--td-font);
67
- color: var(--td-color);
68
- text-align: center;
69
- }
70
- tr th:first-child,
71
- tr td:first-child {
72
- border-left: none;
73
- }
74
-
75
- td md-icon {
76
- color: var(--md-sys-color-error);
77
- }
78
-
79
- pre {
80
- tab-size: 2;
81
- text-align: left;
82
- }
83
-
84
- a[file] {
85
- display: flex;
86
- align-items: center;
87
- gap: var(--spacing-small);
88
- }
89
-
90
- a[file] md-icon {
91
- --md-icon-size: 16px;
92
- color: var(--md-sys-color-primary);
93
- }
94
- `
95
-
96
- @property({ type: Object }) dataSample?: DataSample
97
- @property({ type: String }) subgroup?: string
98
-
99
- render() {
100
- if (!this.dataSample) {
101
- return html``
102
- }
103
-
104
- const { useCase, data = {}, judgment, dataItems = [] } = this.dataSample
105
- const useCaseNames = useCase?.split(',').filter(useCase => useCase.trim()) || []
106
- const subgroupDataItems = dataItems.filter(dataItem => dataItem.group == this.subgroup && !dataItem.hidden)
107
- const records = subgroupDataItems.reduce((max, dataItem) => {
108
- const value = data[dataItem.tag]
109
- return Math.max(max, Array.isArray(value) ? value.length : 1)
110
- }, 0)
111
-
112
- return html` <h3>${this.subgroup}</h3>
113
- <table>
114
- <tr>
115
- <th class="label">${i18next.t('field.name')}</th>
116
- ${subgroupDataItems.map(
117
- dataItem => html` <th>${dataItem.name} ${dataItem.unit ? `(${dataItem.unit})` : ''}</th> `
118
- )}
119
- </tr>
120
- <tr>
121
- <td class="label">${i18next.t('field.description')}</td>
122
- ${subgroupDataItems.map(dataItem => html` <td>${dataItem.description}</td> `)}
123
- </tr>
124
- ${Array.from({ length: records }, (_, index) => index).map(
125
- index => html`
126
- <tr>
127
- <td class="label">${records > 1 ? index + 1 : i18next.t('field.value')}</td>
128
- ${subgroupDataItems.map(dataItem => {
129
- const { tag = '', type } = dataItem
130
- const valueArray = data[tag]
131
- const value = Array.isArray(valueArray) ? valueArray[index] : index == 0 ? valueArray : undefined
132
-
133
- return html` <td>${this.buildValue(type, value)}</td> `
134
- })}
135
- </tr>
136
- `
137
- )}
138
- <tr>
139
- <td class="label">${i18next.t('field.spec')}</td>
140
- ${subgroupDataItems.map(
141
- dataItem => html` <td><pre>${this.buildSpec(useCaseNames, dataItem.spec)}</pre></td> `
142
- )}
143
- </tr>
144
- <tr>
145
- <td class="label">${i18next.t('field.ooc')}</td>
146
- ${subgroupDataItems.map(
147
- dataItem => html` <td>${judgment?.[dataItem.tag]?.ooc ? html`<md-icon>done</md-icon>` : nothing}</td> `
148
- )}
149
- </tr>
150
- <tr>
151
- <td class="label">${i18next.t('field.oos')}</td>
152
- ${subgroupDataItems.map(
153
- dataItem => html` <td>${judgment?.[dataItem.tag]?.oos ? html`<md-icon>done</md-icon>` : nothing}</td> `
154
- )}
155
- </tr>
156
- </table>`
157
- }
158
-
159
- private buildSpec(useCaseNames: string[], spec: DataSpecLimitSet): string {
160
- return OxDataUseCase.elaborateDataItemSpec(useCaseNames, spec)
161
- }
162
-
163
- private download(file: { mimetype: string; name: string; fullpath: string }) {
164
- const element = document.createElement('a')
165
- element.setAttribute('href', file.fullpath)
166
- element.setAttribute('download', file.name!)
167
- document.body.appendChild(element)
168
- element.click()
169
- }
170
-
171
- private buildValue(type: string, value: any | any[]) {
172
- if (value === undefined) {
173
- return ''
174
- }
175
- const values = value instanceof Array ? value : [value]
176
-
177
- if (type == 'file') {
178
- const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
179
-
180
- return files.filter(Boolean).map(
181
- (file, idx) => html`
182
- <a @click=${() => this.download(file)} file><md-icon>description</md-icon>${file.name}</a>
183
- ${files.length - 1 == idx ? html`</br>` : nothing}
184
- `
185
- )
186
- }
187
-
188
- if (type == 'signature') {
189
- return html` <ox-input-signature .value=${value} disabled></ox-input-signature>`
190
- }
191
-
192
- const elements = values.map((v: any, idx) => {
193
- switch (typeof v) {
194
- case 'boolean':
195
- return html` <input type="checkbox" .checked=${v} disabled />`
196
- break
197
-
198
- default:
199
- if (type == 'date') {
200
- return v ? new Date(v).toLocaleDateString() : ''
201
- } else if (type == 'datetime') {
202
- return v ? new Date(v).toLocaleString() : ''
203
- }
204
- return v ?? ''
205
- }
206
- })
207
-
208
- return typeof values[0] === 'boolean' ? elements : elements.join(', ')
209
- }
210
- }
@@ -1,271 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/input/ox-input-file.js'
3
- import '@operato/input/ox-input-signature.js'
4
- import './ox-data-sample-subgroup-view.js'
5
-
6
- import { css, html, LitElement, nothing } from 'lit'
7
- import { customElement, property } from 'lit/decorators.js'
8
-
9
- import { i18next } from '@operato/i18n'
10
-
11
- import { DataItem, DataSample, DataSpecLimitSet } from './types.js'
12
- import { OxDataUseCase } from './usecase/ox-data-use-case.js'
13
-
14
- @customElement('ox-data-sample-view')
15
- export class OxDataSampleView extends LitElement {
16
- static styles = css`
17
- :host {
18
- display: flex;
19
- flex-direction: column;
20
-
21
- --signature-min-width: 100px;
22
- --signature-min-height: 60px;
23
- }
24
-
25
- form {
26
- flex: 1;
27
-
28
- display: flex;
29
- flex-direction: column;
30
- }
31
-
32
- h2 {
33
- margin: var(--title-margin);
34
- font: var(--title-font);
35
- color: var(--title-text-color);
36
- text-transform: capitalize;
37
- }
38
- [page-description] {
39
- margin: var(--page-description-margin);
40
- opacity: 0.7;
41
- font: var(--page-description-font);
42
- color: var(--md-sys-color-on-secondary-container);
43
- text-transform: capitalize;
44
- }
45
- [page-description] * {
46
- vertical-align: middle;
47
- }
48
- [page-description] md-icon {
49
- margin-top: -2px;
50
- font-size: 0.9rem;
51
- color: var(--page-description-color);
52
- }
53
-
54
- table {
55
- border-collapse: collapse;
56
- margin-bottom: var(--spacing-medium);
57
- }
58
- th {
59
- padding: var(--th-padding);
60
- border-top: var(--th-border-top);
61
- border-bottom: var(--td-border-bottom);
62
- text-transform: var(--th-text-transform);
63
- font: var(--th-font);
64
- color: var(--th-color);
65
- text-align: left;
66
- white-space: nowrap;
67
- }
68
- th[item] {
69
- min-width: 100px;
70
- }
71
- th[value] {
72
- min-width: 100px;
73
- }
74
- tr {
75
- background-color: var(--tr-background-color);
76
- }
77
- tr:nth-child(odd) {
78
- background-color: var(--tr-background-odd-color);
79
- }
80
- tr:hover {
81
- background-color: var(--tr-background-hover-color);
82
- }
83
- tr[ooc],
84
- tr[oos] {
85
- background-color: #fefbdf;
86
- }
87
- td {
88
- border-bottom: var(--td-border-bottom);
89
- padding: var(--td-padding);
90
- font: var(--td-font);
91
- color: var(--td-color);
92
- }
93
- td[name] {
94
- font-weight: bold;
95
- }
96
- td md-icon {
97
- color: var(--md-sys-color-error);
98
- }
99
-
100
- pre {
101
- tab-size: 2;
102
- }
103
-
104
- a[file] {
105
- display: flex;
106
- align-items: center;
107
- gap: var(--spacing-small);
108
- }
109
-
110
- a[file] md-icon {
111
- --md-icon-size: 16px;
112
- color: var(--md-sys-color-primary);
113
- }
114
-
115
- @media print {
116
- :host {
117
- display: block;
118
- }
119
- }
120
-
121
- @media screen and (max-width: 480px) {
122
- th {
123
- min-width: 50px;
124
- }
125
- }
126
- `
127
-
128
- @property({ type: Object }) dataSample?: DataSample
129
-
130
- render() {
131
- if (!this.dataSample) {
132
- return html``
133
- }
134
-
135
- const {
136
- name,
137
- description,
138
- collectedAt,
139
- workDate,
140
- workShift,
141
- useCase,
142
- data = {},
143
- judgment,
144
- dataItems = []
145
- } = this.dataSample
146
- const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
147
- const useCaseNames = useCase?.split(',').filter(useCase => useCase.trim()) || []
148
- const nonGroupDataItems = dataItems.filter(dataItem => !dataItem.group && !dataItem.hidden)
149
- const dataItemSubgroups = this.groupDataItemsByGroup(dataItems)
150
-
151
- return html` <h2>${name}</h2>
152
- <p page-description>
153
- <md-icon>info</md-icon> ${description}<br />
154
- <md-icon>alarm</md-icon> ${i18next.t('field.work-date')}: ${workDate} ${workShift} |
155
- <md-icon>pending_actions</md-icon> ${i18next.t('field.collected-at')}:
156
- ${formatter.format(new Date(collectedAt!))}
157
- </p>
158
-
159
- <form>
160
- ${nonGroupDataItems.length > 0
161
- ? html`
162
- <table>
163
- <tr>
164
- <th item>${i18next.t('field.item')}</th>
165
- <th>${i18next.t('field.description')}</th>
166
- <th>${i18next.t('field.finalizing-function')}</th>
167
- <th>${i18next.t('field.unit')}</th>
168
- <th value>${i18next.t('field.value')}</th>
169
- <th>${i18next.t('field.spec')}</th>
170
- <th>${i18next.t('field.ooc')}</th>
171
- <th>${i18next.t('field.oos')}</th>
172
- </tr>
173
- ${nonGroupDataItems.map(dataItem => {
174
- const { name = '', tag = '', description = '', stat, unit = '', spec = {}, type } = dataItem
175
- const value = data[tag]
176
- const { ooc, oos } = judgment?.[tag] || {}
177
-
178
- return html`
179
- <tr ?ooc=${ooc} ?oos=${oos}>
180
- <td name>${name}</td>
181
- <td>${description}</td>
182
- <td>${stat}</td>
183
- <td>${unit}</td>
184
- <td>${this.buildValue(type, value)}</td>
185
- <td><pre>${this.buildSpec(useCaseNames, spec)}</pre></td>
186
- <td>${ooc ? html`<md-icon>done</md-icon>` : ''}</td>
187
- <td>${oos ? html`<md-icon>done</md-icon>` : ''}</td>
188
- </tr>
189
- `
190
- })}
191
- </table>
192
- `
193
- : nothing}
194
- ${Object.keys(dataItemSubgroups).map(subgroup => {
195
- return html`
196
- <ox-data-sample-subgroup-view
197
- .subgroup=${subgroup}
198
- .dataSample=${this.dataSample}
199
- ></ox-data-sample-subgroup-view>
200
- `
201
- })}
202
- </form>`
203
- }
204
-
205
- private groupDataItemsByGroup(dataItems: DataItem[]): { [group: string]: DataItem[] } {
206
- const groupedDataItems: { [group: string]: DataItem[] } = {}
207
-
208
- for (const dataItem of dataItems) {
209
- const { group, hidden } = dataItem
210
-
211
- if (group && !hidden) {
212
- if (!groupedDataItems[group]) {
213
- groupedDataItems[group] = []
214
- }
215
-
216
- groupedDataItems[group].push(dataItem)
217
- }
218
- }
219
-
220
- return groupedDataItems
221
- }
222
-
223
- private buildSpec(useCaseNames: string[], spec: DataSpecLimitSet): string {
224
- return OxDataUseCase.elaborateDataItemSpec(useCaseNames, spec)
225
- }
226
-
227
- private download(file: { mimetype: string; name: string; fullpath: string }) {
228
- const element = document.createElement('a')
229
- element.setAttribute('href', file.fullpath)
230
- element.setAttribute('download', file.name!)
231
- document.body.appendChild(element)
232
- element.click()
233
- }
234
-
235
- private buildValue(type: string, value: any | any[]) {
236
- if (value === undefined) {
237
- return ''
238
- }
239
- const values = value instanceof Array ? value : [value]
240
-
241
- if (type == 'file') {
242
- const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
243
-
244
- return files
245
- .filter(Boolean)
246
- .map(file => html`<a @click=${() => this.download(file)} file><md-icon>description</md-icon>${file.name}</a>`)
247
- }
248
-
249
- if (type == 'signature') {
250
- return html` <ox-input-signature .value=${value} disabled></ox-input-signature>`
251
- }
252
-
253
- const elements = values.map((v: any, idx) => {
254
- switch (typeof v) {
255
- case 'boolean':
256
- return html` <input type="checkbox" .checked=${v} disabled />`
257
- break
258
-
259
- default:
260
- if (type == 'date') {
261
- return v ? new Date(v).toLocaleDateString() : ''
262
- } else if (type == 'datetime') {
263
- return v ? new Date(v).toLocaleString() : ''
264
- }
265
- return v ?? ''
266
- }
267
- })
268
-
269
- return typeof values[0] === 'boolean' ? elements : elements.join(', ')
270
- }
271
- }