@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.
- package/CHANGELOG.md +20 -0
- package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js +1 -1
- package/dist/src/grist-editor/ox-grist-editor-data-item-spec.js.map +1 -1
- package/dist/src/grist-editor/ox-popup-data-item-spec.js +3 -2
- package/dist/src/grist-editor/ox-popup-data-item-spec.js.map +1 -1
- package/dist/src/index.d.ts +1 -5
- package/dist/src/index.js +1 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/ox-data-item-spec.d.ts +2 -2
- package/dist/src/ox-data-item-spec.js +1 -1
- package/dist/src/ox-data-item-spec.js.map +1 -1
- package/dist/src/ox-data-ooc-view.js +1 -1
- package/dist/src/ox-data-ooc-view.js.map +1 -1
- package/dist/src/ox-data-sample-view.d.ts +1 -2
- package/dist/src/ox-data-sample-view.js +25 -31
- package/dist/src/ox-data-sample-view.js.map +1 -1
- package/dist/src/types.d.ts +18 -6
- package/dist/src/types.js.map +1 -1
- package/dist/src/usecase/ccp/index.d.ts +1 -0
- package/dist/src/usecase/ccp/index.js +8 -0
- package/dist/src/usecase/ccp/index.js.map +1 -0
- package/dist/src/usecase/ccp/ox-data-use-case-ccp.d.ts +7 -0
- package/dist/src/usecase/ccp/ox-data-use-case-ccp.js +102 -0
- package/dist/src/usecase/ccp/ox-data-use-case-ccp.js.map +1 -0
- package/dist/src/usecase/ccp/ox-input-ccp-limits.d.ts +44 -0
- package/dist/src/usecase/ccp/ox-input-ccp-limits.js +171 -0
- package/dist/src/usecase/ccp/ox-input-ccp-limits.js.map +1 -0
- package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.d.ts +5 -0
- package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.js +24 -0
- package/dist/src/usecase/ccp/ox-property-editor-ccp-limits.js.map +1 -0
- package/dist/src/{ox-data-use-case.d.ts → usecase/ox-data-use-case.d.ts} +5 -5
- package/dist/src/{ox-data-use-case.js → usecase/ox-data-use-case.js} +23 -34
- package/dist/src/usecase/ox-data-use-case.js.map +1 -0
- package/dist/src/usecase/qc/index.d.ts +1 -0
- package/dist/src/usecase/qc/index.js +8 -0
- package/dist/src/usecase/qc/index.js.map +1 -0
- package/dist/src/usecase/qc/ox-data-use-case-qc.d.ts +7 -0
- package/dist/src/usecase/qc/ox-data-use-case-qc.js +55 -0
- package/dist/src/usecase/qc/ox-data-use-case-qc.js.map +1 -0
- package/dist/src/usecase/qc/ox-input-qc-limits.d.ts +44 -0
- package/dist/src/usecase/qc/ox-input-qc-limits.js +171 -0
- package/dist/src/usecase/qc/ox-input-qc-limits.js.map +1 -0
- package/dist/src/usecase/qc/ox-property-editor-qc-limits.d.ts +5 -0
- package/dist/src/usecase/qc/ox-property-editor-qc-limits.js +24 -0
- package/dist/src/usecase/qc/ox-property-editor-qc-limits.js.map +1 -0
- package/dist/stories/ox-data-entry-form.stories.d.ts +19 -0
- package/dist/stories/ox-data-entry-form.stories.js +152 -0
- package/dist/stories/ox-data-entry-form.stories.js.map +1 -0
- package/dist/stories/ox-data-item-spec.stories.d.ts +26 -0
- package/dist/stories/ox-data-item-spec.stories.js +102 -0
- package/dist/stories/ox-data-item-spec.stories.js.map +1 -0
- package/dist/stories/ox-data-ooc-view.stories.d.ts +19 -0
- package/dist/stories/ox-data-ooc-view.stories.js +242 -0
- package/dist/stories/ox-data-ooc-view.stories.js.map +1 -0
- package/dist/stories/ox-data-sample-view.stories.d.ts +19 -0
- package/dist/stories/ox-data-sample-view.stories.js +213 -0
- package/dist/stories/ox-data-sample-view.stories.js.map +1 -0
- package/dist/stories/ox-grist-editor-data-item-spec.stories.d.ts +27 -0
- package/dist/stories/ox-grist-editor-data-item-spec.stories.js +389 -0
- package/dist/stories/ox-grist-editor-data-item-spec.stories.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +18 -12
- package/src/grist-editor/ox-grist-editor-data-item-spec.ts +1 -1
- package/src/grist-editor/ox-popup-data-item-spec.ts +3 -2
- package/src/index.ts +1 -5
- package/src/ox-data-item-spec.ts +3 -3
- package/src/ox-data-ooc-view.ts +1 -1
- package/src/ox-data-sample-view.ts +28 -31
- package/src/types.ts +23 -6
- package/src/usecase/ccp/index.ts +10 -0
- package/src/usecase/ccp/ox-data-use-case-ccp.ts +147 -0
- package/src/usecase/ccp/ox-input-ccp-limits.ts +161 -0
- package/src/usecase/ccp/ox-property-editor-ccp-limits.ts +23 -0
- package/src/{ox-data-use-case.ts → usecase/ox-data-use-case.ts} +28 -40
- package/src/usecase/qc/index.ts +10 -0
- package/src/usecase/qc/ox-data-use-case-qc.ts +72 -0
- package/src/usecase/qc/ox-input-qc-limits.ts +161 -0
- package/src/usecase/qc/ox-property-editor-qc-limits.ts +23 -0
- package/stories/ox-data-entry-form.stories.ts +165 -0
- package/stories/ox-data-item-spec.stories.ts +121 -0
- package/stories/ox-data-ooc-view.stories.ts +256 -0
- package/stories/ox-data-sample-view.stories.ts +227 -0
- package/stories/ox-grist-editor-data-item-spec.stories.ts +409 -0
- package/translations/en.json +26 -8
- package/translations/ko.json +25 -7
- package/translations/ms.json +26 -8
- package/translations/zh.json +25 -7
- package/demo/index.html +0 -28
- package/demo/ox-data-entry-form.html +0 -118
- package/demo/ox-data-item-spec.html +0 -152
- package/demo/ox-data-ooc-view.html +0 -185
- package/demo/ox-data-sample-view.html +0 -150
- package/demo/ox-grist-editor-data-item-spec.html +0 -476
- package/dist/src/ox-data-use-case.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataItem,
|
|
1
|
+
import { DataItem, DataSet, DataSpecLimitSet, EvaluationResult, UseCaseDefinition } from '../types'
|
|
2
2
|
|
|
3
3
|
export abstract class OxDataUseCase {
|
|
4
4
|
static registry: { [name: string]: OxDataUseCase } = {}
|
|
@@ -19,39 +19,35 @@ export abstract class OxDataUseCase {
|
|
|
19
19
|
return OxDataUseCase.registry[name]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
public static elaborateDataItemSpec(
|
|
23
|
-
|
|
24
|
-
return ''
|
|
25
|
-
}
|
|
22
|
+
public static elaborateDataItemSpec(spec: DataSpecLimitSet): string {
|
|
23
|
+
const useCaseNames = Object.keys(spec || {})
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
const useCases = useCaseNames.map(useCaseName => OxDataUseCase.getUseCase(useCaseName)).filter(useCase => !!useCase)
|
|
25
|
+
var texts: string[] = []
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
for (let j = 0; j < useCases.length; j++) {
|
|
33
|
-
const useCase = useCases[j]
|
|
27
|
+
useCaseNames.forEach(useCaseName => {
|
|
28
|
+
const useCase = OxDataUseCase.getUseCase(useCaseName)
|
|
34
29
|
if (!useCase) {
|
|
35
|
-
|
|
30
|
+
return
|
|
36
31
|
}
|
|
37
32
|
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
40
|
-
|
|
33
|
+
const limits = spec?.[useCaseName]
|
|
34
|
+
if (!limits) {
|
|
35
|
+
return
|
|
41
36
|
}
|
|
42
37
|
|
|
43
|
-
const result = useCase.elaborateUseCaseSpec(
|
|
38
|
+
const result = useCase.elaborateUseCaseSpec(limits)
|
|
44
39
|
if (!result) {
|
|
45
|
-
|
|
40
|
+
return
|
|
46
41
|
}
|
|
47
42
|
|
|
43
|
+
texts.push(`[ ${useCaseName} ]`)
|
|
48
44
|
texts.push(result)
|
|
49
|
-
}
|
|
45
|
+
})
|
|
50
46
|
|
|
51
47
|
return texts.join('\n')
|
|
52
48
|
}
|
|
53
49
|
|
|
54
|
-
public static evaluate(dataSet: DataSet, dataItems: DataItem[], data: any): EvaluationResult
|
|
50
|
+
public static evaluate(dataSet: DataSet, dataItems: DataItem[], data: any): EvaluationResult {
|
|
55
51
|
var ooc = false
|
|
56
52
|
var oos = false
|
|
57
53
|
|
|
@@ -86,7 +82,7 @@ export abstract class OxDataUseCase {
|
|
|
86
82
|
continue
|
|
87
83
|
}
|
|
88
84
|
|
|
89
|
-
const result = useCase
|
|
85
|
+
const result = useCase!.evaluate(specs, values)
|
|
90
86
|
|
|
91
87
|
if (result) {
|
|
92
88
|
ooc ||= result.ooc
|
|
@@ -98,22 +94,10 @@ export abstract class OxDataUseCase {
|
|
|
98
94
|
return { ooc, oos }
|
|
99
95
|
}
|
|
100
96
|
|
|
101
|
-
public static evaluateItem(
|
|
97
|
+
public static evaluateItem(spec: DataSpecLimitSet, values: any | any[]): EvaluationResult | undefined {
|
|
102
98
|
var ooc = false
|
|
103
99
|
var oos = false
|
|
104
100
|
|
|
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
101
|
if (typeof values === 'undefined') {
|
|
118
102
|
return // TODO what if in case no value ?
|
|
119
103
|
}
|
|
@@ -122,26 +106,30 @@ export abstract class OxDataUseCase {
|
|
|
122
106
|
values = [values]
|
|
123
107
|
}
|
|
124
108
|
|
|
125
|
-
|
|
126
|
-
|
|
109
|
+
const useCaseNames = Object.keys(spec || {})
|
|
110
|
+
|
|
111
|
+
if (useCaseNames.length === 0) {
|
|
112
|
+
return { ooc, oos }
|
|
113
|
+
}
|
|
127
114
|
|
|
128
|
-
|
|
129
|
-
|
|
115
|
+
useCaseNames.forEach(useCaseName => {
|
|
116
|
+
const useCase = OxDataUseCase.getUseCase(useCaseName)
|
|
117
|
+
if (!useCase) {
|
|
130
118
|
return
|
|
131
119
|
}
|
|
132
120
|
|
|
133
|
-
const result = useCase?.evaluate(
|
|
121
|
+
const result = useCase?.evaluate(spec[useCaseName], values)
|
|
134
122
|
|
|
135
123
|
if (result) {
|
|
136
124
|
ooc ||= result.ooc
|
|
137
125
|
oos ||= result.oos
|
|
138
126
|
}
|
|
139
|
-
}
|
|
127
|
+
})
|
|
140
128
|
|
|
141
129
|
return { ooc, oos }
|
|
142
130
|
}
|
|
143
131
|
|
|
144
132
|
public abstract evaluate(specs: any, values: any[]): EvaluationResult | undefined
|
|
145
133
|
public abstract elaborateUseCaseSpec(spec: any): string | undefined
|
|
146
|
-
public abstract getSpecification(dataItem: DataItem):
|
|
134
|
+
public abstract getSpecification(dataItem: DataItem): UseCaseDefinition
|
|
147
135
|
}
|
|
@@ -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.js'
|
|
4
|
+
import { OxDataUseCaseQC } from './ox-data-use-case-qc.js'
|
|
5
|
+
|
|
6
|
+
// OxPropertyEditor.register({
|
|
7
|
+
// 'qc-limits': 'ox-property-editor-qc-limits'
|
|
8
|
+
// })
|
|
9
|
+
|
|
10
|
+
OxDataUseCase.registerUseCase('QC', new OxDataUseCaseQC())
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import i18next from 'i18next' // Since this is a common module, @operato/i18n was deliberately avoided.
|
|
2
|
+
|
|
3
|
+
import { DataItem, EvaluationResult, UseCaseDefinition } from '../../types.js'
|
|
4
|
+
import { OxDataUseCase } from '../ox-data-use-case.js'
|
|
5
|
+
|
|
6
|
+
export class OxDataUseCaseQC implements OxDataUseCase {
|
|
7
|
+
getSpecification(dataItem: DataItem): UseCaseDefinition {
|
|
8
|
+
return {
|
|
9
|
+
name: 'QC',
|
|
10
|
+
description: 'Quality Control Data Spec',
|
|
11
|
+
help: '',
|
|
12
|
+
specs: [
|
|
13
|
+
{
|
|
14
|
+
type: 'qc-limits' /* 'A value which seperates acceptability from unacceptability' */,
|
|
15
|
+
label: 'pass-limits',
|
|
16
|
+
name: 'passLimits',
|
|
17
|
+
property: dataItem
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
evaluate(spec: any, values: any[]): EvaluationResult {
|
|
24
|
+
const { minimum, maximum, acceptables } = spec['passLimits']
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < values.length; i++) {
|
|
27
|
+
const value = values[i]
|
|
28
|
+
|
|
29
|
+
if (typeof minimum !== 'undefined' && value < minimum) {
|
|
30
|
+
return { oos: true, ooc: true }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof maximum !== 'undefined' && value > maximum) {
|
|
34
|
+
return { oos: true, ooc: true }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (typeof acceptables !== 'undefined' && !acceptables.includes(value)) {
|
|
38
|
+
return { oos: true, ooc: true }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return { oos: false, ooc: false }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
elaborateUseCaseSpec(limits: any): string | undefined {
|
|
46
|
+
if (!limits) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var text = ''
|
|
51
|
+
|
|
52
|
+
const { minimum, maximum, acceptables } = limits['passLimits'] || {}
|
|
53
|
+
|
|
54
|
+
if (minimum !== undefined || maximum !== undefined || acceptables !== undefined) {
|
|
55
|
+
text += `${i18next.t('label.pass-limits')}\n`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (minimum !== undefined) {
|
|
59
|
+
text += `\t${i18next.t('label.minimum value')} : ${minimum}\n`
|
|
60
|
+
}
|
|
61
|
+
if (maximum !== undefined) {
|
|
62
|
+
text += `\t${i18next.t('label.maximum value')} : ${maximum}\n`
|
|
63
|
+
}
|
|
64
|
+
if (acceptables !== undefined) {
|
|
65
|
+
text += `\t${i18next.t('label.acceptables')} : ${
|
|
66
|
+
acceptables instanceof Array ? acceptables.join(', ') : acceptables
|
|
67
|
+
}\n`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return text
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -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 QcLimitValue = {
|
|
19
|
+
minimum?: number
|
|
20
|
+
maximum?: number
|
|
21
|
+
acceptables?: string[]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
element for QC limits
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
|
|
29
|
+
<ox-input-qc-limits
|
|
30
|
+
.value=${value}
|
|
31
|
+
.type=${type}>
|
|
32
|
+
</ox-input-qc-limits>
|
|
33
|
+
*/
|
|
34
|
+
@customElement('ox-input-qc-limits')
|
|
35
|
+
export class OxInputQcLimits 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: QcLimitValue = {}
|
|
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-qc-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-qc-limits')
|
|
9
|
+
export class OxPropertyEditorQcLimits extends OxPropertyEditor {
|
|
10
|
+
editorTemplate() {
|
|
11
|
+
const { type, options, unit } = this.property || {}
|
|
12
|
+
|
|
13
|
+
return html`
|
|
14
|
+
<ox-input-qc-limits
|
|
15
|
+
id="editor"
|
|
16
|
+
.value=${this.value}
|
|
17
|
+
.type=${type}
|
|
18
|
+
.unit=${unit}
|
|
19
|
+
.options=${options}
|
|
20
|
+
></ox-input-qc-limits>
|
|
21
|
+
`
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import '@operato/i18n'
|
|
2
|
+
import '../src/ox-data-entry-form.js'
|
|
3
|
+
import '../src/usecase/ccp' /* register usecase CCP */
|
|
4
|
+
import '@material/mwc-icon'
|
|
5
|
+
|
|
6
|
+
import { html, TemplateResult } from 'lit'
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
title: 'ox-data-entry-form',
|
|
10
|
+
component: 'ox-data-entry-form',
|
|
11
|
+
argTypes: {}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface Story<T> {
|
|
15
|
+
(args: T): TemplateResult
|
|
16
|
+
args?: Partial<T>
|
|
17
|
+
argTypes?: Record<string, unknown>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ArgTypes {}
|
|
21
|
+
|
|
22
|
+
const dataSet = {
|
|
23
|
+
name: 'sample',
|
|
24
|
+
description: 'sample description',
|
|
25
|
+
useCase: 'CCP',
|
|
26
|
+
dataItems: [
|
|
27
|
+
{
|
|
28
|
+
name: '창고 온도',
|
|
29
|
+
description: '창고 온도는 섭씨 0도 이하로 유지되어야 합니다.',
|
|
30
|
+
sequence: 1,
|
|
31
|
+
tag: 'temp',
|
|
32
|
+
type: 'number',
|
|
33
|
+
quota: 1,
|
|
34
|
+
active: true,
|
|
35
|
+
unit: '℃',
|
|
36
|
+
spec: {
|
|
37
|
+
CCP: {
|
|
38
|
+
criticalLimits: {
|
|
39
|
+
minimum: 100,
|
|
40
|
+
maximum: 200
|
|
41
|
+
},
|
|
42
|
+
targetLimits: {
|
|
43
|
+
minimum: 120,
|
|
44
|
+
maximum: 180
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: '창고 습도',
|
|
51
|
+
description: '창고 습도는 30% 이하로 유지되어야 합니다.',
|
|
52
|
+
sequence: 2,
|
|
53
|
+
tag: 'humid',
|
|
54
|
+
type: 'number',
|
|
55
|
+
quota: 5,
|
|
56
|
+
active: true,
|
|
57
|
+
unit: '%',
|
|
58
|
+
spec: {
|
|
59
|
+
CCP: {
|
|
60
|
+
criticalLimits: {
|
|
61
|
+
minimum: 10,
|
|
62
|
+
maximum: 50
|
|
63
|
+
},
|
|
64
|
+
targetLimits: {
|
|
65
|
+
minimum: 20,
|
|
66
|
+
maximum: 40
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: '육안 검사',
|
|
73
|
+
description: '육안 검사는 포장전 30분 내로 실행되어야 합니다.',
|
|
74
|
+
sequence: 3,
|
|
75
|
+
tag: 'inspection',
|
|
76
|
+
type: 'boolean',
|
|
77
|
+
quota: 3,
|
|
78
|
+
active: true,
|
|
79
|
+
spec: {
|
|
80
|
+
CCP: {
|
|
81
|
+
criticalLimits: {
|
|
82
|
+
acceptables: true
|
|
83
|
+
},
|
|
84
|
+
targetLimits: {
|
|
85
|
+
acceptables: true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: '품평',
|
|
92
|
+
description: '품평은 최우수/우수/보통/미달을 포함하여 간단히 평가.',
|
|
93
|
+
sequence: 4,
|
|
94
|
+
tag: 'evaluation',
|
|
95
|
+
type: 'select',
|
|
96
|
+
options: {
|
|
97
|
+
options: [
|
|
98
|
+
{ text: '최우수', value: '최우수' },
|
|
99
|
+
{ text: '우수', value: '우수' },
|
|
100
|
+
{ text: '보통', value: '보통' },
|
|
101
|
+
{ text: '미달', value: '미달' }
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
quota: 3,
|
|
105
|
+
active: true,
|
|
106
|
+
spec: {
|
|
107
|
+
CCP: {
|
|
108
|
+
criticalLimits: {
|
|
109
|
+
acceptables: ['최우수', '우수', '보통']
|
|
110
|
+
},
|
|
111
|
+
targetLimits: {
|
|
112
|
+
acceptables: ['최우수', '우수']
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: '코멘트',
|
|
119
|
+
description: '특이사항을 기록함.',
|
|
120
|
+
sequence: 4,
|
|
121
|
+
tag: 'comment',
|
|
122
|
+
type: 'string',
|
|
123
|
+
quota: 1,
|
|
124
|
+
active: true
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: '첨부파일',
|
|
128
|
+
description: '참조 첨부 파일.',
|
|
129
|
+
sequence: 4,
|
|
130
|
+
tag: 'attachment',
|
|
131
|
+
type: 'file',
|
|
132
|
+
quota: 1,
|
|
133
|
+
active: true
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
var value = {
|
|
138
|
+
temp: 1000,
|
|
139
|
+
humid: [20, 23, 21, 26, 27],
|
|
140
|
+
inspection: [true, false, true],
|
|
141
|
+
evaluation: ['최우수', '보통', '우수'],
|
|
142
|
+
comment: '이것이 코멘트입니다.'
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const Template: Story<ArgTypes> = ({}: ArgTypes) =>
|
|
146
|
+
html`
|
|
147
|
+
<link href="/themes/app-theme.css" rel="stylesheet" />
|
|
148
|
+
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
|
|
149
|
+
<style>
|
|
150
|
+
body {
|
|
151
|
+
}
|
|
152
|
+
</style>
|
|
153
|
+
|
|
154
|
+
<ox-data-entry-form
|
|
155
|
+
.dataSet=${dataSet}
|
|
156
|
+
.value=${value}
|
|
157
|
+
@change=${(e: CustomEvent) => {
|
|
158
|
+
value = e.detail
|
|
159
|
+
console.log('change', value)
|
|
160
|
+
}}
|
|
161
|
+
></ox-data-entry-form>
|
|
162
|
+
`
|
|
163
|
+
|
|
164
|
+
export const Regular = Template.bind({})
|
|
165
|
+
Regular.args = {}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import '@operato/i18n'
|
|
2
|
+
import '@material/mwc-icon'
|
|
3
|
+
import '@operato/property-editor/ox-property-editor-checkbox.js'
|
|
4
|
+
import '@operato/property-editor/ox-property-editor-number.js'
|
|
5
|
+
import '@operato/property-editor/ox-property-editor-string.js'
|
|
6
|
+
import '@operato/property-editor/ox-properties-dynamic-view.js'
|
|
7
|
+
import '../src/ox-data-item-spec.js'
|
|
8
|
+
import '../src/usecase/ccp' /* register usecase CCP */
|
|
9
|
+
import '../src/usecase/qc' /* register usecase QC */
|
|
10
|
+
import '../src/usecase/ccp/ox-property-editor-ccp-limits.js'
|
|
11
|
+
import '../src/usecase/qc/ox-property-editor-qc-limits.js'
|
|
12
|
+
|
|
13
|
+
import { html, TemplateResult } from 'lit'
|
|
14
|
+
|
|
15
|
+
import { OxPropertyEditor } from '@operato/property-editor'
|
|
16
|
+
|
|
17
|
+
OxPropertyEditor.register({
|
|
18
|
+
number: 'ox-property-editor-number',
|
|
19
|
+
string: 'ox-property-editor-string',
|
|
20
|
+
boolean: 'ox-property-editor-checkbox',
|
|
21
|
+
'ccp-limits': 'ox-property-editor-ccp-limits',
|
|
22
|
+
'qc-limits': 'ox-property-editor-qc-limits'
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export default {
|
|
26
|
+
title: 'ox-data-item-spec',
|
|
27
|
+
component: 'ox-data-item-spec',
|
|
28
|
+
argTypes: {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface Story<T> {
|
|
32
|
+
(args: T): TemplateResult
|
|
33
|
+
args?: Partial<T>
|
|
34
|
+
argTypes?: Record<string, unknown>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface ArgTypes {}
|
|
38
|
+
|
|
39
|
+
const dataItemA = {
|
|
40
|
+
name: '창고 온도',
|
|
41
|
+
description: '창고 온도는 섭씨 0도 이하로 유지되어야 합니다.',
|
|
42
|
+
sequence: 1,
|
|
43
|
+
tag: 'temp',
|
|
44
|
+
unit: '℃',
|
|
45
|
+
type: 'number',
|
|
46
|
+
quota: 1
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const dataItemB = {
|
|
50
|
+
name: '품평',
|
|
51
|
+
description: '품평은 최우수/우수/보통/미달을 포함하여 간단히 평가.',
|
|
52
|
+
sequence: 4,
|
|
53
|
+
tag: 'evaluation',
|
|
54
|
+
type: 'select',
|
|
55
|
+
options: {
|
|
56
|
+
options: [
|
|
57
|
+
{ text: '최우수', value: '최우수' },
|
|
58
|
+
{ text: '우수', value: '우수' },
|
|
59
|
+
{ text: '보통', value: '보통' },
|
|
60
|
+
{ text: '미달', value: '미달' }
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
quota: 3
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const dataItemC = {
|
|
67
|
+
name: '코멘트',
|
|
68
|
+
description: '특이사항을 기록함.',
|
|
69
|
+
sequence: 4,
|
|
70
|
+
tag: 'comment',
|
|
71
|
+
type: 'string',
|
|
72
|
+
quota: 1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var specA = {
|
|
76
|
+
CCP: {
|
|
77
|
+
criticalLimits: {
|
|
78
|
+
minimum: 100,
|
|
79
|
+
maximum: 200
|
|
80
|
+
},
|
|
81
|
+
targetLimits: {
|
|
82
|
+
minimum: 120,
|
|
83
|
+
maximum: 180
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
QC: {
|
|
87
|
+
passLimits: {
|
|
88
|
+
minimum: 320,
|
|
89
|
+
maximum: 440
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var specB = {
|
|
95
|
+
CCP: { accpetables: ['최우수', '우수'] },
|
|
96
|
+
QC: { accpetables: ['최우수', '우수'] }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const Template: Story<ArgTypes> = ({}: ArgTypes) =>
|
|
100
|
+
html`
|
|
101
|
+
<link href="/themes/app-theme.css" rel="stylesheet" />
|
|
102
|
+
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
|
|
103
|
+
<style>
|
|
104
|
+
body {
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
107
|
+
|
|
108
|
+
<script type="module"></script>
|
|
109
|
+
|
|
110
|
+
<ox-data-item-spec
|
|
111
|
+
.dataItem=${dataItemA}
|
|
112
|
+
.value=${specA}
|
|
113
|
+
@change=${(e: CustomEvent) => {
|
|
114
|
+
specA = e.detail
|
|
115
|
+
console.log('change', specA)
|
|
116
|
+
}}
|
|
117
|
+
></ox-data-item-spec>
|
|
118
|
+
`
|
|
119
|
+
|
|
120
|
+
export const Regular = Template.bind({})
|
|
121
|
+
Regular.args = {}
|