@operato/dataset 1.0.0-alpha.36 → 1.0.0-alpha.39
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/CHANGELOG.md +37 -0
- package/demo/index.html +2 -0
- package/demo/ox-data-item-spec.html +43 -39
- package/demo/ox-data-ooc-view.html +184 -0
- package/demo/ox-data-sample-view.html +150 -0
- package/demo/ox-grist-editor-data-item-spec.html +43 -39
- package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js +5 -5
- package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/ox-data-entry-form.js +4 -9
- package/dist/src/ox-data-entry-form.js.map +1 -1
- package/dist/src/ox-data-item-spec.d.ts +1 -7
- package/dist/src/ox-data-item-spec.js +5 -15
- package/dist/src/ox-data-item-spec.js.map +1 -1
- package/dist/src/ox-data-ooc-view.d.ts +10 -0
- package/dist/src/ox-data-ooc-view.js +58 -0
- package/dist/src/ox-data-ooc-view.js.map +1 -0
- package/dist/src/ox-data-sample-view copy.d.ts +13 -0
- package/dist/src/ox-data-sample-view copy.js +214 -0
- package/dist/src/ox-data-sample-view copy.js.map +1 -0
- package/dist/src/ox-data-sample-view.d.ts +13 -0
- package/dist/src/ox-data-sample-view.js +165 -0
- package/dist/src/ox-data-sample-view.js.map +1 -0
- package/dist/src/ox-data-use-case.d.ts +16 -0
- package/dist/src/ox-data-use-case.js +111 -0
- package/dist/src/ox-data-use-case.js.map +1 -0
- package/dist/src/types.d.ts +36 -2
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -11
- package/src/grist-editor/ox-grist-editor-data-item-spec.ts +5 -5
- package/src/index.ts +3 -0
- package/src/ox-data-entry-form.ts +4 -9
- package/src/ox-data-item-spec.ts +5 -17
- package/src/ox-data-ooc-view.ts +56 -0
- package/src/ox-data-sample-view.ts +171 -0
- package/src/ox-data-use-case.ts +147 -0
- package/src/types.ts +30 -2
package/src/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@operato/input/ox-input-file.js'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { css, html, LitElement } from 'lit'
|
|
4
4
|
import { customElement, property } from 'lit/decorators.js'
|
|
5
5
|
|
|
6
6
|
import { DataSet } from './types.js'
|
|
@@ -95,7 +95,7 @@ export class OxDataEntryForm extends LitElement {
|
|
|
95
95
|
const value = this.value && this.value[tag]
|
|
96
96
|
|
|
97
97
|
const elements = samples.map((_, idx) => {
|
|
98
|
-
const v =
|
|
98
|
+
const v = value instanceof Array ? value[idx] : idx === 0 ? value : undefined
|
|
99
99
|
|
|
100
100
|
switch (type) {
|
|
101
101
|
case 'select':
|
|
@@ -141,19 +141,14 @@ export class OxDataEntryForm extends LitElement {
|
|
|
141
141
|
const dataItems = this.dataSet!.dataItems
|
|
142
142
|
|
|
143
143
|
return (dataItems || []).reduce((sum, dataItem) => {
|
|
144
|
-
const { tag,
|
|
144
|
+
const { tag, type } = dataItem
|
|
145
145
|
|
|
146
146
|
const editors = Array.prototype.slice.call(
|
|
147
147
|
this.renderRoot.querySelectorAll(`[name=${tag}]`) as NodeListOf<HTMLInputElement>
|
|
148
148
|
) as HTMLInputElement[]
|
|
149
149
|
|
|
150
150
|
if (editors.length > 0) {
|
|
151
|
-
sum[tag] =
|
|
152
|
-
editors.length > 1
|
|
153
|
-
? editors.map(editor => (type === 'boolean' ? editor.checked : editor.value))
|
|
154
|
-
: type === 'boolean'
|
|
155
|
-
? editors[0].checked
|
|
156
|
-
: editors[0].value
|
|
151
|
+
sum[tag] = editors.map(editor => (type === 'boolean' ? editor.checked : editor.value))
|
|
157
152
|
}
|
|
158
153
|
|
|
159
154
|
return sum
|
package/src/ox-data-item-spec.ts
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
1
|
import '@operato/property-editor/ox-properties-dynamic-view.js'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { LitElement, PropertyValues, css, html } from 'lit'
|
|
3
|
+
import { css, html, LitElement, PropertyValues } from 'lit'
|
|
5
4
|
import { customElement, property, queryAll, state } from 'lit/decorators.js'
|
|
6
5
|
|
|
6
|
+
import { OxDataUseCase } from './ox-data-use-case.js'
|
|
7
|
+
import { DataItem, DataItemSpecSet } from './types.js'
|
|
8
|
+
|
|
7
9
|
@customElement('ox-data-item-spec')
|
|
8
10
|
export class OxDataItemSpec extends LitElement {
|
|
9
|
-
static registry: { [name: string]: DataItemSpecSetProvider } = {}
|
|
10
|
-
|
|
11
|
-
public static registerProvider(name: string, provider: DataItemSpecSetProvider) {
|
|
12
|
-
OxDataItemSpec.registry[name] = provider
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public static getProviderNames() {
|
|
16
|
-
return Object.keys(OxDataItemSpec.registry)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public static getProvider(name: string): DataItemSpecSetProvider | undefined {
|
|
20
|
-
return OxDataItemSpec.registry[name]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
11
|
static styles = css`
|
|
24
12
|
:host {
|
|
25
13
|
display: flex;
|
|
@@ -61,7 +49,7 @@ export class OxDataItemSpec extends LitElement {
|
|
|
61
49
|
|
|
62
50
|
updated(changes: PropertyValues<this>) {
|
|
63
51
|
if (changes.has('dataItem')) {
|
|
64
|
-
this.dataItemSpecSets =
|
|
52
|
+
this.dataItemSpecSets = OxDataUseCase.getUseCases().map(useCase => useCase.getSpecification(this.dataItem!))
|
|
65
53
|
}
|
|
66
54
|
}
|
|
67
55
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import '@operato/input/ox-input-file.js'
|
|
2
|
+
import './ox-data-sample-view'
|
|
3
|
+
|
|
4
|
+
import { DataOoc, DataSet } from './types.js'
|
|
5
|
+
import { LitElement, css, html } from 'lit'
|
|
6
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
7
|
+
|
|
8
|
+
@customElement('ox-data-ooc-view')
|
|
9
|
+
export class OxDataOocView extends LitElement {
|
|
10
|
+
static styles = css`
|
|
11
|
+
:host {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
background-color: var(--main-section-background-color);
|
|
15
|
+
padding: var(--padding-wide);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
h3 {
|
|
19
|
+
margin: var(--title-margin);
|
|
20
|
+
padding-top: 12px;
|
|
21
|
+
font: var(--title-font);
|
|
22
|
+
color: var(--title-text-color);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
[page-description] {
|
|
26
|
+
margin: var(--page-description-margin);
|
|
27
|
+
font: var(--page-description-font);
|
|
28
|
+
color: var(--page-description-color);
|
|
29
|
+
}
|
|
30
|
+
`
|
|
31
|
+
|
|
32
|
+
@property({ type: Object }) dataSet?: DataSet
|
|
33
|
+
@property({ type: Object }) dataOoc?: DataOoc
|
|
34
|
+
|
|
35
|
+
render() {
|
|
36
|
+
const history = this.dataOoc?.history || []
|
|
37
|
+
const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
|
|
38
|
+
|
|
39
|
+
return html`
|
|
40
|
+
<ox-data-sample-view .dataSample=${this.dataOoc} .dataSet=${this.dataSet}></ox-data-sample-view>
|
|
41
|
+
|
|
42
|
+
<h3>history</h3>
|
|
43
|
+
${history.map(
|
|
44
|
+
({ user, state, comment, timestamp }) => html`
|
|
45
|
+
<p page-description>
|
|
46
|
+
${formatter.format(new Date(timestamp))}
|
|
47
|
+
<br />
|
|
48
|
+
${state} by ${user.name}
|
|
49
|
+
<br />
|
|
50
|
+
${comment}
|
|
51
|
+
</p>
|
|
52
|
+
`
|
|
53
|
+
)}
|
|
54
|
+
`
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import '@operato/input/ox-input-file.js'
|
|
2
|
+
|
|
3
|
+
import { DataItem, DataSample, DataSet } from './types.js'
|
|
4
|
+
import { LitElement, css, html } from 'lit'
|
|
5
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
6
|
+
|
|
7
|
+
import { OxDataUseCase } from './ox-data-use-case.js'
|
|
8
|
+
|
|
9
|
+
@customElement('ox-data-sample-view')
|
|
10
|
+
export class OxDataSampleView extends LitElement {
|
|
11
|
+
static styles = css`
|
|
12
|
+
:host {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
background-color: var(--main-section-background-color);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
form {
|
|
19
|
+
flex: 1;
|
|
20
|
+
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
h2 {
|
|
26
|
+
margin: var(--title-margin);
|
|
27
|
+
padding-top: 25px;
|
|
28
|
+
font: var(--title-font);
|
|
29
|
+
color: var(--title-text-color);
|
|
30
|
+
}
|
|
31
|
+
[page-description] {
|
|
32
|
+
margin: var(--page-description-margin);
|
|
33
|
+
font: var(--page-description-font);
|
|
34
|
+
color: var(--page-description-color);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
table {
|
|
38
|
+
border-collapse: collapse;
|
|
39
|
+
margin-bottom: var(--margin-default);
|
|
40
|
+
}
|
|
41
|
+
th {
|
|
42
|
+
padding: var(--th-padding);
|
|
43
|
+
border-top: var(--th-border-top);
|
|
44
|
+
border-bottom: var(--td-border-bottom);
|
|
45
|
+
text-transform: var(--th-text-transform);
|
|
46
|
+
font: var(--th-font);
|
|
47
|
+
color: var(--th-color);
|
|
48
|
+
text-align: left;
|
|
49
|
+
}
|
|
50
|
+
th[item] {
|
|
51
|
+
min-width: 100px;
|
|
52
|
+
}
|
|
53
|
+
th[value] {
|
|
54
|
+
min-width: 100px;
|
|
55
|
+
}
|
|
56
|
+
tr {
|
|
57
|
+
background-color: var(--tr-background-color);
|
|
58
|
+
}
|
|
59
|
+
tr:nth-child(odd) {
|
|
60
|
+
background-color: var(--tr-background-odd-color);
|
|
61
|
+
}
|
|
62
|
+
tr:hover {
|
|
63
|
+
background-color: var(--tr-background-hover-color);
|
|
64
|
+
}
|
|
65
|
+
tr[ooc],
|
|
66
|
+
tr[oos] {
|
|
67
|
+
background-color: #fefbdf;
|
|
68
|
+
}
|
|
69
|
+
td {
|
|
70
|
+
border-bottom: var(--td-border-bottom);
|
|
71
|
+
padding: var(--td-padding);
|
|
72
|
+
font: var(--td-font);
|
|
73
|
+
color: var(--td-color);
|
|
74
|
+
}
|
|
75
|
+
td[name] {
|
|
76
|
+
font-weight: bold;
|
|
77
|
+
}
|
|
78
|
+
td mwc-icon {
|
|
79
|
+
color: var(--status-danger-color);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pre {
|
|
83
|
+
tab-size: 2;
|
|
84
|
+
}
|
|
85
|
+
`
|
|
86
|
+
|
|
87
|
+
@property({ type: Object }) dataSet?: DataSet
|
|
88
|
+
@property({ type: Object }) dataSample?: DataSample
|
|
89
|
+
|
|
90
|
+
render() {
|
|
91
|
+
const dataItems = this.dataSet?.dataItems.filter(item => item.active) || []
|
|
92
|
+
const data = this.dataSample?.data || {}
|
|
93
|
+
const formatter = new Intl.DateTimeFormat(navigator.language, { dateStyle: 'full', timeStyle: 'short' })
|
|
94
|
+
|
|
95
|
+
return html` <h2>${this.dataSample?.name}</h2>
|
|
96
|
+
<p page-description>
|
|
97
|
+
${this.dataSample?.description}<br /><br />
|
|
98
|
+
collected at: ${this.dataSample && formatter.format(new Date(this.dataSample?.collectedAt!))}
|
|
99
|
+
</p>
|
|
100
|
+
|
|
101
|
+
<form @change=${(e: Event) => this.onChange(e)}>
|
|
102
|
+
<table>
|
|
103
|
+
<tr>
|
|
104
|
+
<th item>item</th>
|
|
105
|
+
<th>description</th>
|
|
106
|
+
<th>unit</th>
|
|
107
|
+
<th value>value</th>
|
|
108
|
+
<th>specification</th>
|
|
109
|
+
<th>OOC</th>
|
|
110
|
+
<th>OOS</th>
|
|
111
|
+
</tr>
|
|
112
|
+
${dataItems.map(dataItem => {
|
|
113
|
+
const { ooc, oos } = this.evaluateOOC(dataItem, data?.[dataItem.tag]) || {}
|
|
114
|
+
return html`
|
|
115
|
+
<tr ?ooc=${ooc} ?oos=${oos}>
|
|
116
|
+
<td name>${dataItem.name}</td>
|
|
117
|
+
<td>${dataItem.description}</td>
|
|
118
|
+
<td>${dataItem.unit}</td>
|
|
119
|
+
<td>${this.buildValue(dataItem)}</td>
|
|
120
|
+
<td><pre>${this.buildSpec(dataItem)}</pre></td>
|
|
121
|
+
<td>${ooc ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
|
|
122
|
+
<td>${oos ? html`<mwc-icon>done</mwc-icon>` : ''}</td>
|
|
123
|
+
</tr>
|
|
124
|
+
`
|
|
125
|
+
})}
|
|
126
|
+
</table>
|
|
127
|
+
</form>`
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private onChange(e: Event) {}
|
|
131
|
+
|
|
132
|
+
private buildSpec(dataItem: DataItem) {
|
|
133
|
+
return OxDataUseCase.elaborateDataItemSpec(this.dataSet!, dataItem)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private buildValue(dataItem: DataItem) {
|
|
137
|
+
const { tag, type } = dataItem
|
|
138
|
+
|
|
139
|
+
if (!this.dataSample) {
|
|
140
|
+
return ''
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const value = this.dataSample?.data[dataItem.tag]
|
|
144
|
+
if (value === undefined) {
|
|
145
|
+
return ''
|
|
146
|
+
}
|
|
147
|
+
const values = value instanceof Array ? value : [value]
|
|
148
|
+
|
|
149
|
+
const elements = values.map((_: any, idx) => {
|
|
150
|
+
const v = value[idx]
|
|
151
|
+
|
|
152
|
+
switch (type) {
|
|
153
|
+
case 'boolean':
|
|
154
|
+
return html` <input type="checkbox" name=${tag} .checked=${v} disabled />`
|
|
155
|
+
break
|
|
156
|
+
|
|
157
|
+
case 'select':
|
|
158
|
+
case 'number':
|
|
159
|
+
case 'string':
|
|
160
|
+
default:
|
|
161
|
+
return String(v === undefined ? '' : v)
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
return type === 'boolean' ? elements : elements.join(', ')
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private evaluateOOC(dataItem: DataItem, value: any) {
|
|
169
|
+
return OxDataUseCase.evaluateItem(this.dataSet!, dataItem, value)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { DataItem, DataItemSpecSet, DataSet, EvaluationResult } from './types'
|
|
2
|
+
|
|
3
|
+
export abstract class OxDataUseCase {
|
|
4
|
+
static registry: { [name: string]: OxDataUseCase } = {}
|
|
5
|
+
|
|
6
|
+
public static registerUseCase(name: string, useCase: OxDataUseCase) {
|
|
7
|
+
OxDataUseCase.registry[name] = useCase
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
public static getUseCaseNames() {
|
|
11
|
+
return Object.keys(OxDataUseCase.registry)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public static getUseCases(): OxDataUseCase[] {
|
|
15
|
+
return Object.values(OxDataUseCase.registry)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public static getUseCase(name: string): OxDataUseCase | undefined {
|
|
19
|
+
return OxDataUseCase.registry[name]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public static elaborateDataItemSpec(dataSet: DataSet, dataItem: DataItem): string {
|
|
23
|
+
if (!dataSet.useCase) {
|
|
24
|
+
return ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const useCaseNames = dataSet.useCase.split(',').map(useCaseName => useCaseName.trim())
|
|
28
|
+
const useCases = useCaseNames.map(useCaseName => OxDataUseCase.getUseCase(useCaseName)).filter(useCase => !!useCase)
|
|
29
|
+
|
|
30
|
+
var texts = []
|
|
31
|
+
|
|
32
|
+
for (let j = 0; j < useCases.length; j++) {
|
|
33
|
+
const useCase = useCases[j]
|
|
34
|
+
if (!useCase) {
|
|
35
|
+
continue
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const specs = dataItem.spec?.[dataSet.useCase]
|
|
39
|
+
if (!specs) {
|
|
40
|
+
continue
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const result = useCase.elaborateUseCaseSpec(dataItem.spec)
|
|
44
|
+
if (!result) {
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
texts.push(result)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return texts.join('\n')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public static evaluate(dataSet: DataSet, dataItems: DataItem[], data: any): EvaluationResult | undefined {
|
|
55
|
+
var ooc = false
|
|
56
|
+
var oos = false
|
|
57
|
+
|
|
58
|
+
if (!dataSet.useCase) {
|
|
59
|
+
return { ooc, oos }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const useCaseNames = dataSet.useCase.split(',').map(useCaseName => useCaseName.trim())
|
|
63
|
+
const useCases = useCaseNames.map(useCaseName => OxDataUseCase.getUseCase(useCaseName)).filter(useCase => !!useCase)
|
|
64
|
+
|
|
65
|
+
for (let i = 0; i < dataItems.length; i++) {
|
|
66
|
+
const dataItem = dataItems[i]
|
|
67
|
+
const { active, tag } = dataItem
|
|
68
|
+
if (!active || !tag) {
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let values: any | any[] = data[tag]
|
|
73
|
+
if (typeof values === 'undefined') {
|
|
74
|
+
continue // TODO what if in case no value ?
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (!(values instanceof Array)) {
|
|
78
|
+
values = [values]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
for (let j = 0; j < useCases.length; j++) {
|
|
82
|
+
const useCase = useCases[j]
|
|
83
|
+
|
|
84
|
+
const specs = dataItem.spec?.[dataSet.useCase]
|
|
85
|
+
if (!specs) {
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const result = useCase?.evaluate(specs, values)
|
|
90
|
+
|
|
91
|
+
if (result) {
|
|
92
|
+
ooc ||= result.ooc
|
|
93
|
+
oos ||= result.oos
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return { ooc, oos }
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public static evaluateItem(dataSet: DataSet, dataItem: DataItem, values: any | any[]): EvaluationResult | undefined {
|
|
102
|
+
var ooc = false
|
|
103
|
+
var oos = false
|
|
104
|
+
|
|
105
|
+
if (!dataSet.useCase) {
|
|
106
|
+
return { ooc, oos }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const useCaseNames = dataSet.useCase.split(',').map(useCaseName => useCaseName.trim())
|
|
110
|
+
const useCases = useCaseNames.map(useCaseName => OxDataUseCase.getUseCase(useCaseName)).filter(useCase => !!useCase)
|
|
111
|
+
|
|
112
|
+
const { active, tag } = dataItem
|
|
113
|
+
if (!active || !tag) {
|
|
114
|
+
return
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (typeof values === 'undefined') {
|
|
118
|
+
return // TODO what if in case no value ?
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!(values instanceof Array)) {
|
|
122
|
+
values = [values]
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (let j = 0; j < useCases.length; j++) {
|
|
126
|
+
const useCase = useCases[j]
|
|
127
|
+
|
|
128
|
+
const specs = dataItem.spec?.[dataSet.useCase]
|
|
129
|
+
if (!specs) {
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const result = useCase?.evaluate(specs, values)
|
|
134
|
+
|
|
135
|
+
if (result) {
|
|
136
|
+
ooc ||= result.ooc
|
|
137
|
+
oos ||= result.oos
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return { ooc, oos }
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public abstract evaluate(specs: any, values: any[]): EvaluationResult | undefined
|
|
145
|
+
public abstract elaborateUseCaseSpec(spec: any): string | undefined
|
|
146
|
+
public abstract getSpecification(dataItem: DataItem): DataItemSpecSet
|
|
147
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ export type DataItem = {
|
|
|
15
15
|
options: TypeOptions
|
|
16
16
|
unit: string
|
|
17
17
|
quota: number
|
|
18
|
+
spec: { [useCase: string]: any }
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export type DataSet = {
|
|
@@ -24,19 +25,46 @@ export type DataSet = {
|
|
|
24
25
|
useCase: string
|
|
25
26
|
active: boolean
|
|
26
27
|
dataItems: DataItem[]
|
|
28
|
+
spec: { [dataItem: string]: { [useCase: string]: any } }
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
export type DataItemSpec = {
|
|
30
32
|
type: string
|
|
31
33
|
label: string
|
|
32
34
|
name: string
|
|
33
|
-
property
|
|
35
|
+
property?: { [option: string]: any }
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export type DataItemSpecSet = {
|
|
37
39
|
name: string
|
|
38
40
|
description: string
|
|
41
|
+
help: string
|
|
39
42
|
specs: DataItemSpec[]
|
|
40
43
|
}
|
|
41
44
|
|
|
42
|
-
export type
|
|
45
|
+
export type DataSample = {
|
|
46
|
+
name: string
|
|
47
|
+
description: string
|
|
48
|
+
data: any
|
|
49
|
+
spec: any
|
|
50
|
+
quota: number
|
|
51
|
+
collectedAt: Date
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type DataOocState = 'CREATED' | 'REVIEWED' | 'CORRECTED'
|
|
55
|
+
|
|
56
|
+
export type DataOoc = DataSample & {
|
|
57
|
+
state: DataOocState
|
|
58
|
+
correctiveAction: string
|
|
59
|
+
history: {
|
|
60
|
+
user: {
|
|
61
|
+
id: string
|
|
62
|
+
name: string
|
|
63
|
+
}
|
|
64
|
+
state: DataOocState
|
|
65
|
+
comment: string
|
|
66
|
+
timestamp: number
|
|
67
|
+
}[]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type EvaluationResult = { oos: boolean; ooc: boolean }
|