@operato/dataset 7.1.4 → 7.1.6
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 +18 -0
- package/dist/src/ox-data-entry-form.js +3 -7
- package/dist/src/ox-data-entry-form.js.map +1 -1
- package/dist/src/ox-data-entry-subgroup-form.d.ts +1 -0
- package/dist/src/ox-data-entry-subgroup-form.js +5 -0
- package/dist/src/ox-data-entry-subgroup-form.js.map +1 -1
- package/dist/src/ox-data-entry-subgroup-view.d.ts +15 -0
- package/dist/src/ox-data-entry-subgroup-view.js +198 -0
- package/dist/src/ox-data-entry-subgroup-view.js.map +1 -0
- package/dist/src/ox-data-entry-view.d.ts +4 -3
- package/dist/src/ox-data-entry-view.js +61 -79
- package/dist/src/ox-data-entry-view.js.map +1 -1
- package/dist/src/ox-data-sample-subgroup-view.js +1 -1
- package/dist/src/ox-data-sample-subgroup-view.js.map +1 -1
- package/dist/src/ox-data-sample-view.js +3 -1
- package/dist/src/ox-data-sample-view.js.map +1 -1
- package/dist/src/ox-data-summary-view.js +1 -1
- package/dist/src/ox-data-summary-view.js.map +1 -1
- package/dist/src/usecase/ccp/ox-input-ccp-limits.d.ts +2 -1
- package/dist/src/usecase/ccp/ox-input-ccp-limits.js +1 -0
- package/dist/src/usecase/ccp/ox-input-ccp-limits.js.map +1 -1
- package/dist/src/usecase/qc/ox-input-qc-limits.d.ts +2 -1
- package/dist/src/usecase/qc/ox-input-qc-limits.js +1 -0
- package/dist/src/usecase/qc/ox-input-qc-limits.js.map +1 -1
- package/dist/src/usecase/spc/ox-input-spc-limits.d.ts +2 -1
- package/dist/src/usecase/spc/ox-input-spc-limits.js +1 -0
- package/dist/src/usecase/spc/ox-input-spc-limits.js.map +1 -1
- package/dist/stories/ox-grist-editor-data-item-spec.stories.js +1 -1
- package/dist/stories/ox-grist-editor-data-item-spec.stories.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/ox-data-entry-form.ts +3 -7
- package/src/ox-data-entry-subgroup-form.ts +6 -0
- package/src/ox-data-entry-subgroup-view.ts +221 -0
- package/src/ox-data-entry-view.ts +70 -93
- package/src/ox-data-sample-subgroup-view.ts +1 -1
- package/src/ox-data-sample-view.ts +3 -3
- package/src/ox-data-summary-view.ts +1 -1
- package/src/usecase/ccp/ox-input-ccp-limits.ts +2 -1
- package/src/usecase/qc/ox-input-qc-limits.ts +2 -1
- package/src/usecase/spc/ox-input-spc-limits.ts +2 -1
- package/stories/ox-grist-editor-data-item-spec.stories.ts +1 -1
- package/themes/form-theme.css +0 -1
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/dataset",
|
|
3
3
|
"description": "WebApplication dataset supporting components following open-wc recommendations",
|
|
4
4
|
"author": "heartyoh",
|
|
5
|
-
"version": "7.1.
|
|
5
|
+
"version": "7.1.6",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
7
7
|
"module": "dist/src/index.js",
|
|
8
8
|
"exports": {
|
|
@@ -108,15 +108,15 @@
|
|
|
108
108
|
},
|
|
109
109
|
"dependencies": {
|
|
110
110
|
"@material/web": "^2.0.0",
|
|
111
|
-
"@operato/data-grist": "^7.1.
|
|
111
|
+
"@operato/data-grist": "^7.1.6",
|
|
112
112
|
"@operato/graphql": "^7.1.1",
|
|
113
|
-
"@operato/grist-editor": "^7.1.
|
|
113
|
+
"@operato/grist-editor": "^7.1.6",
|
|
114
114
|
"@operato/i18n": "^7.1.1",
|
|
115
|
-
"@operato/input": "^7.1.
|
|
116
|
-
"@operato/popup": "^7.1.
|
|
117
|
-
"@operato/property-editor": "^7.1.
|
|
118
|
-
"@operato/shell": "^7.1.
|
|
119
|
-
"@operato/styles": "^7.1.
|
|
115
|
+
"@operato/input": "^7.1.6",
|
|
116
|
+
"@operato/popup": "^7.1.6",
|
|
117
|
+
"@operato/property-editor": "^7.1.6",
|
|
118
|
+
"@operato/shell": "^7.1.6",
|
|
119
|
+
"@operato/styles": "^7.1.6",
|
|
120
120
|
"@operato/utils": "^7.1.1",
|
|
121
121
|
"lit": "^3.1.2"
|
|
122
122
|
},
|
|
@@ -152,5 +152,5 @@
|
|
|
152
152
|
"prettier --write"
|
|
153
153
|
]
|
|
154
154
|
},
|
|
155
|
-
"gitHead": "
|
|
155
|
+
"gitHead": "6f754b46ee6e01c930e71073611de781da4e7bf5"
|
|
156
156
|
}
|
|
@@ -172,6 +172,7 @@ export class OxDataEntryForm extends LitElement {
|
|
|
172
172
|
.subgroup=${subgroup}
|
|
173
173
|
.dataItems=${dataItems}
|
|
174
174
|
.value=${value}
|
|
175
|
+
@change=${(e: Event) => this.onChange(e)}
|
|
175
176
|
></ox-data-entry-subgroup-form>
|
|
176
177
|
</div>
|
|
177
178
|
</div>
|
|
@@ -234,15 +235,10 @@ export class OxDataEntryForm extends LitElement {
|
|
|
234
235
|
return html` <input type="datetime-local" name=${tag} value=${v} />`
|
|
235
236
|
|
|
236
237
|
case 'file':
|
|
237
|
-
return html`<ox-input-file name=${tag}></ox-input-file>`
|
|
238
|
+
return html`<ox-input-file name=${tag} multiple .value=${v}></ox-input-file>`
|
|
238
239
|
|
|
239
240
|
case 'signature':
|
|
240
|
-
return html`<ox-input-signature
|
|
241
|
-
name=${tag}
|
|
242
|
-
label="Attach Files"
|
|
243
|
-
accept="*/*"
|
|
244
|
-
multiple="true"
|
|
245
|
-
></ox-input-signature>`
|
|
241
|
+
return html`<ox-input-signature name=${tag} value=${v}></ox-input-signature>`
|
|
246
242
|
|
|
247
243
|
case 'string':
|
|
248
244
|
default:
|
|
@@ -38,6 +38,7 @@ export class OxDataEntrySubgroupForm extends LitElement {
|
|
|
38
38
|
.mode=${isMobileDevice() ? 'LIST' : 'GRID'}
|
|
39
39
|
.config=${this.buildGristConfiguration()}
|
|
40
40
|
.fetchHandler=${this.fetchHandler.bind(this)}
|
|
41
|
+
@field-change=${this.onFieldChange.bind(this)}
|
|
41
42
|
>
|
|
42
43
|
</ox-grist>
|
|
43
44
|
`
|
|
@@ -91,6 +92,7 @@ export class OxDataEntrySubgroupForm extends LitElement {
|
|
|
91
92
|
return columnConfig
|
|
92
93
|
|
|
93
94
|
case 'file':
|
|
95
|
+
columnConfig.record.multiple = true
|
|
94
96
|
return columnConfig
|
|
95
97
|
|
|
96
98
|
case 'signature':
|
|
@@ -148,4 +150,8 @@ export class OxDataEntrySubgroupForm extends LitElement {
|
|
|
148
150
|
return partial
|
|
149
151
|
}, {} as any)
|
|
150
152
|
}
|
|
153
|
+
|
|
154
|
+
onFieldChange(e: CustomEvent) {
|
|
155
|
+
this.dispatchEvent(new CustomEvent('change', { detail: this.grist.dirtyData }))
|
|
156
|
+
}
|
|
151
157
|
}
|
|
@@ -0,0 +1,221 @@
|
|
|
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, DataSet, DataSpecLimitSet } from './types.js'
|
|
11
|
+
import { OxDataUseCase } from './usecase/ox-data-use-case.js'
|
|
12
|
+
|
|
13
|
+
@customElement('ox-data-entry-subgroup-view')
|
|
14
|
+
export class OxDataEntrySubgroupView 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 }) dataSet?: DataSet
|
|
97
|
+
@property({ type: Object }) data?: any
|
|
98
|
+
@property({ type: String }) subgroup?: string
|
|
99
|
+
|
|
100
|
+
render() {
|
|
101
|
+
if (!this.data || !this.dataSet) {
|
|
102
|
+
return html``
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const { useCase, dataItems = [] } = this.dataSet
|
|
106
|
+
|
|
107
|
+
const { data } = this
|
|
108
|
+
const useCaseNames = useCase?.split(',').filter(useCase => useCase.trim()) || []
|
|
109
|
+
const subgroupDataItems = dataItems.filter(dataItem => dataItem.group == this.subgroup && !dataItem.hidden)
|
|
110
|
+
const records = subgroupDataItems.reduce((max, dataItem) => {
|
|
111
|
+
const value = data[dataItem.tag]
|
|
112
|
+
return Math.max(max, Array.isArray(value) ? value.length : 1)
|
|
113
|
+
}, 0)
|
|
114
|
+
const judgment = subgroupDataItems.reduce(
|
|
115
|
+
(judgment, dataItem) => {
|
|
116
|
+
const tag = dataItem.tag
|
|
117
|
+
judgment[tag] = OxDataUseCase.evaluateTag(this.dataSet!, dataItems, data, tag) || {}
|
|
118
|
+
return judgment
|
|
119
|
+
},
|
|
120
|
+
{} as { [tag: string]: { ooc: boolean; oos: boolean } }
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
return html` <h3>${this.subgroup}</h3>
|
|
124
|
+
<table>
|
|
125
|
+
<tr>
|
|
126
|
+
<th class="label">${i18next.t('field.name')}</th>
|
|
127
|
+
${subgroupDataItems.map(
|
|
128
|
+
dataItem => html` <th>${dataItem.name} ${dataItem.unit ? `(${dataItem.unit})` : ''}</th> `
|
|
129
|
+
)}
|
|
130
|
+
</tr>
|
|
131
|
+
<tr>
|
|
132
|
+
<td class="label">${i18next.t('field.description')}</td>
|
|
133
|
+
${subgroupDataItems.map(dataItem => html` <td>${dataItem.description}</td> `)}
|
|
134
|
+
</tr>
|
|
135
|
+
${Array.from({ length: records }, (_, index) => index).map(
|
|
136
|
+
index => html`
|
|
137
|
+
<tr>
|
|
138
|
+
<td class="label">${records > 1 ? index + 1 : i18next.t('field.value')}</td>
|
|
139
|
+
${subgroupDataItems.map(dataItem => {
|
|
140
|
+
const { tag = '', type } = dataItem
|
|
141
|
+
const valueArray = data[tag]
|
|
142
|
+
const value = Array.isArray(valueArray) ? valueArray[index] : index == 0 ? valueArray : undefined
|
|
143
|
+
|
|
144
|
+
return html` <td>${this.buildValue(type, value)}</td> `
|
|
145
|
+
})}
|
|
146
|
+
</tr>
|
|
147
|
+
`
|
|
148
|
+
)}
|
|
149
|
+
<tr>
|
|
150
|
+
<td class="label">${i18next.t('field.spec')}</td>
|
|
151
|
+
${subgroupDataItems.map(
|
|
152
|
+
dataItem => html` <td><pre>${this.buildSpec(useCaseNames, dataItem.spec)}</pre></td> `
|
|
153
|
+
)}
|
|
154
|
+
</tr>
|
|
155
|
+
<tr>
|
|
156
|
+
<td class="label">${i18next.t('field.ooc')}</td>
|
|
157
|
+
${subgroupDataItems.map(
|
|
158
|
+
dataItem => html` <td>${judgment?.[dataItem.tag]?.ooc ? html`<md-icon>done</md-icon>` : nothing}</td> `
|
|
159
|
+
)}
|
|
160
|
+
</tr>
|
|
161
|
+
<tr>
|
|
162
|
+
<td class="label">${i18next.t('field.oos')}</td>
|
|
163
|
+
${subgroupDataItems.map(
|
|
164
|
+
dataItem => html` <td>${judgment?.[dataItem.tag]?.oos ? html`<md-icon>done</md-icon>` : nothing}</td> `
|
|
165
|
+
)}
|
|
166
|
+
</tr>
|
|
167
|
+
</table>`
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private buildSpec(useCaseNames: string[], spec: DataSpecLimitSet): string {
|
|
171
|
+
return OxDataUseCase.elaborateDataItemSpec(useCaseNames, spec)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private download(file: { mimetype: string; name: string; fullpath: string }) {
|
|
175
|
+
const element = document.createElement('a')
|
|
176
|
+
element.setAttribute('href', file.fullpath)
|
|
177
|
+
element.setAttribute('download', file.name!)
|
|
178
|
+
document.body.appendChild(element)
|
|
179
|
+
element.click()
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private buildValue(type: string, value: any | any[]) {
|
|
183
|
+
if (value === undefined) {
|
|
184
|
+
return ''
|
|
185
|
+
}
|
|
186
|
+
const values = value instanceof Array ? value : [value]
|
|
187
|
+
|
|
188
|
+
if (type == 'file') {
|
|
189
|
+
const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
|
|
190
|
+
|
|
191
|
+
return files.filter(Boolean).map(
|
|
192
|
+
(file, idx) => html`
|
|
193
|
+
<a @click=${() => this.download(file)} file><md-icon>description</md-icon>${file.name}</a>
|
|
194
|
+
${files.length - 1 == idx ? html`</br>` : nothing}
|
|
195
|
+
`
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (type == 'signature') {
|
|
200
|
+
return html` <ox-input-signature .value=${value} disabled></ox-input-signature>`
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const elements = values.map((v: any, idx) => {
|
|
204
|
+
switch (typeof v) {
|
|
205
|
+
case 'boolean':
|
|
206
|
+
return html` <input type="checkbox" .checked=${v} disabled />`
|
|
207
|
+
break
|
|
208
|
+
|
|
209
|
+
default:
|
|
210
|
+
if (type == 'date') {
|
|
211
|
+
return v ? new Date(v).toLocaleDateString() : ''
|
|
212
|
+
} else if (type == 'datetime') {
|
|
213
|
+
return v ? new Date(v).toLocaleString() : ''
|
|
214
|
+
}
|
|
215
|
+
return v ?? ''
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
return typeof values[0] === 'boolean' ? elements : elements.join(', ')
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js'
|
|
1
2
|
import '@operato/input/ox-input-file.js'
|
|
2
3
|
import '@operato/input/ox-input-signature.js'
|
|
4
|
+
import './ox-data-entry-subgroup-view.js'
|
|
3
5
|
|
|
4
6
|
import { css, html, LitElement, nothing } from 'lit'
|
|
5
7
|
import { customElement, property } from 'lit/decorators.js'
|
|
6
8
|
|
|
7
9
|
import { i18next } from '@operato/i18n'
|
|
8
10
|
|
|
9
|
-
import { DataSet, DataSpecLimitSet } from './types.js'
|
|
11
|
+
import { DataItem, DataSet, DataSpecLimitSet } from './types.js'
|
|
10
12
|
import { OxDataUseCase } from './usecase/ox-data-use-case.js'
|
|
11
13
|
|
|
12
14
|
@customElement('ox-data-entry-view')
|
|
@@ -15,6 +17,9 @@ export class OxDataEntryView extends LitElement {
|
|
|
15
17
|
:host {
|
|
16
18
|
display: flex;
|
|
17
19
|
flex-direction: column;
|
|
20
|
+
|
|
21
|
+
--signature-min-width: 100px;
|
|
22
|
+
--signature-min-height: 60px;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
form {
|
|
@@ -106,68 +111,6 @@ export class OxDataEntryView extends LitElement {
|
|
|
106
111
|
@property({ type: Object }) dataSet?: DataSet
|
|
107
112
|
@property({ type: Object }) value?: { [tag: string]: any }
|
|
108
113
|
|
|
109
|
-
__render() {
|
|
110
|
-
return html`<form>
|
|
111
|
-
<h2>${this.dataSet?.name || ''}</h2>
|
|
112
|
-
<h3>${this.dataSet?.description || ''}</h3>
|
|
113
|
-
${this.buildEntryViews()}
|
|
114
|
-
</form> `
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private buildEntryViews() {
|
|
118
|
-
const dataItems = this.dataSet?.dataItems.filter(item => item.active)
|
|
119
|
-
|
|
120
|
-
return (dataItems || []).map(dataItem => {
|
|
121
|
-
const { name, description, tag, type, quota = 1, options = {}, unit } = dataItem
|
|
122
|
-
|
|
123
|
-
const samples = new Array(quota).fill(0)
|
|
124
|
-
const value = this.value && this.value[tag]
|
|
125
|
-
|
|
126
|
-
const elements = samples.map((_, idx) => {
|
|
127
|
-
const v = value instanceof Array ? value[idx] : idx === 0 ? value : undefined
|
|
128
|
-
|
|
129
|
-
switch (type) {
|
|
130
|
-
case 'select':
|
|
131
|
-
return html` <select .name=${tag} disabled>
|
|
132
|
-
<option value=""></option>
|
|
133
|
-
${(options.options || []).map(
|
|
134
|
-
option => html`<option value=${option.value} ?selected=${option.value === v}>${option.text}</option>`
|
|
135
|
-
)}
|
|
136
|
-
</select>`
|
|
137
|
-
break
|
|
138
|
-
|
|
139
|
-
case 'boolean':
|
|
140
|
-
return html` <input type="checkbox" name=${tag} .checked=${v} disabled />`
|
|
141
|
-
break
|
|
142
|
-
|
|
143
|
-
case 'number':
|
|
144
|
-
return html` <input type="number" name=${tag} value=${v} disabled />`
|
|
145
|
-
break
|
|
146
|
-
|
|
147
|
-
case 'file':
|
|
148
|
-
return html`<ox-input-file
|
|
149
|
-
name=${tag}
|
|
150
|
-
label="Attach Files"
|
|
151
|
-
accept="*/*"
|
|
152
|
-
multiple="true"
|
|
153
|
-
hide-filelist
|
|
154
|
-
disabled
|
|
155
|
-
></ox-input-file>`
|
|
156
|
-
|
|
157
|
-
case 'string':
|
|
158
|
-
default:
|
|
159
|
-
return html` <input type="text" name=${tag} value=${v} disabled />`
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
return html` <label .title=${description}>
|
|
164
|
-
<div name>${name}${unit ? `(${unit})` : ''}</div>
|
|
165
|
-
<div description><md-icon>info</md-icon> ${description}</div>
|
|
166
|
-
<div elements>${elements}</div>
|
|
167
|
-
</label>`
|
|
168
|
-
})
|
|
169
|
-
}
|
|
170
|
-
|
|
171
114
|
render() {
|
|
172
115
|
if (!this.dataSet) {
|
|
173
116
|
return nothing
|
|
@@ -176,45 +119,79 @@ export class OxDataEntryView extends LitElement {
|
|
|
176
119
|
const { name, description, useCase, dataItems = [] } = this.dataSet!
|
|
177
120
|
|
|
178
121
|
const data = this.value || {}
|
|
122
|
+
|
|
179
123
|
const useCaseNames = useCase?.split(',').filter(useCase => useCase.trim()) || []
|
|
124
|
+
const nonGroupDataItems = dataItems.filter(dataItem => !dataItem.group && !dataItem.hidden)
|
|
125
|
+
const dataItemSubgroups = this.groupDataItemsByGroup(dataItems)
|
|
180
126
|
|
|
181
127
|
return html` <h2>${name}</h2>
|
|
182
128
|
<p page-description><md-icon>info</md-icon> ${description}<br /></p>
|
|
183
129
|
|
|
184
130
|
<form>
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
131
|
+
${nonGroupDataItems.length > 0
|
|
132
|
+
? html`
|
|
133
|
+
<table>
|
|
134
|
+
<tr>
|
|
135
|
+
<th item>${i18next.t('field.item')}</th>
|
|
136
|
+
<th>${i18next.t('field.description')}</th>
|
|
137
|
+
<th>${i18next.t('field.finalizing-function')}</th>
|
|
138
|
+
<th>${i18next.t('field.unit')}</th>
|
|
139
|
+
<th value>${i18next.t('field.value')}</th>
|
|
140
|
+
<th>${i18next.t('field.spec')}</th>
|
|
141
|
+
<th>${i18next.t('field.ooc')}</th>
|
|
142
|
+
<th>${i18next.t('field.oos')}</th>
|
|
143
|
+
</tr>
|
|
144
|
+
${nonGroupDataItems.map(dataItem => {
|
|
145
|
+
const { name = '', tag = '', description = '', stat, unit = '', spec = {}, type } = dataItem
|
|
146
|
+
const value = data[tag]
|
|
147
|
+
const { ooc, oos } = OxDataUseCase.evaluateTag(this.dataSet!, dataItems, data, tag) || {}
|
|
148
|
+
|
|
149
|
+
return html`
|
|
150
|
+
<tr ?ooc=${ooc} ?oos=${oos}>
|
|
151
|
+
<td name>${name}</td>
|
|
152
|
+
<td>${description}</td>
|
|
153
|
+
<td>${stat}</td>
|
|
154
|
+
<td>${unit}</td>
|
|
155
|
+
<td>${this.buildValue(type, value)}</td>
|
|
156
|
+
<td><pre>${this.buildSpec(useCaseNames, spec)}</pre></td>
|
|
157
|
+
<td>${ooc ? html`<md-icon>done</md-icon>` : ''}</td>
|
|
158
|
+
<td>${oos ? html`<md-icon>done</md-icon>` : ''}</td>
|
|
159
|
+
</tr>
|
|
160
|
+
`
|
|
161
|
+
})}
|
|
162
|
+
</table>
|
|
212
163
|
`
|
|
213
|
-
}
|
|
214
|
-
|
|
164
|
+
: nothing}
|
|
165
|
+
${Object.keys(dataItemSubgroups).map(subgroup => {
|
|
166
|
+
return html`
|
|
167
|
+
<ox-data-entry-subgroup-view
|
|
168
|
+
.subgroup=${subgroup}
|
|
169
|
+
.dataSet=${this.dataSet}
|
|
170
|
+
.data=${this.value}
|
|
171
|
+
></ox-data-entry-subgroup-view>
|
|
172
|
+
`
|
|
173
|
+
})}
|
|
215
174
|
</form>`
|
|
216
175
|
}
|
|
217
176
|
|
|
177
|
+
private groupDataItemsByGroup(dataItems: DataItem[]): { [group: string]: DataItem[] } {
|
|
178
|
+
const groupedDataItems: { [group: string]: DataItem[] } = {}
|
|
179
|
+
|
|
180
|
+
for (const dataItem of dataItems) {
|
|
181
|
+
const { group, hidden } = dataItem
|
|
182
|
+
|
|
183
|
+
if (group && !hidden) {
|
|
184
|
+
if (!groupedDataItems[group]) {
|
|
185
|
+
groupedDataItems[group] = []
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
groupedDataItems[group].push(dataItem)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return groupedDataItems
|
|
193
|
+
}
|
|
194
|
+
|
|
218
195
|
private buildSpec(useCaseNames: string[], spec: DataSpecLimitSet): string {
|
|
219
196
|
return OxDataUseCase.elaborateDataItemSpec(useCaseNames, spec)
|
|
220
197
|
}
|
|
@@ -236,7 +213,7 @@ export class OxDataEntryView extends LitElement {
|
|
|
236
213
|
if (type == 'file') {
|
|
237
214
|
const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
|
|
238
215
|
|
|
239
|
-
return files.map(file => html`<a @click=${() => this.download(file)}>${file.name}</a></br>`)
|
|
216
|
+
return files.filter(Boolean).map(file => html`<a @click=${() => this.download(file)}>${file.name}</a></br>`)
|
|
240
217
|
}
|
|
241
218
|
|
|
242
219
|
if (type == 'signature') {
|
|
@@ -177,7 +177,7 @@ export class OxDataSampleSubgroupView extends LitElement {
|
|
|
177
177
|
if (type == 'file') {
|
|
178
178
|
const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
|
|
179
179
|
|
|
180
|
-
return files.map(
|
|
180
|
+
return files.filter(Boolean).map(
|
|
181
181
|
(file, idx) => html`
|
|
182
182
|
<a @click=${() => this.download(file)} file><md-icon>description</md-icon>${file.name}</a>
|
|
183
183
|
${files.length - 1 == idx ? html`</br>` : nothing}
|
|
@@ -241,9 +241,9 @@ export class OxDataSampleView extends LitElement {
|
|
|
241
241
|
if (type == 'file') {
|
|
242
242
|
const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
|
|
243
243
|
|
|
244
|
-
return files
|
|
245
|
-
|
|
246
|
-
|
|
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
247
|
}
|
|
248
248
|
|
|
249
249
|
if (type == 'signature') {
|
|
@@ -170,7 +170,7 @@ export class OxDataSummaryView extends LitElement {
|
|
|
170
170
|
if (type == 'file') {
|
|
171
171
|
const files = values.flat() as { mimetype: string; name: string; fullpath: string }[]
|
|
172
172
|
|
|
173
|
-
return files.map(file => html`<a @click=${() => this.download(file)}>${file.name}</a></br>`)
|
|
173
|
+
return files.filter(Boolean).map(file => html`<a @click=${() => this.download(file)}>${file.name}</a></br>`)
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
if (type == 'signature') {
|
|
@@ -191,7 +191,7 @@ class GristDemo extends LitElement {
|
|
|
191
191
|
name: 'type',
|
|
192
192
|
header: i18next.t('field.type'),
|
|
193
193
|
record: {
|
|
194
|
-
options: ['', 'number', 'text', 'select', 'boolean', 'file'],
|
|
194
|
+
options: ['', 'number', 'text', 'select', 'boolean', 'file', 'signature'],
|
|
195
195
|
editable: true
|
|
196
196
|
},
|
|
197
197
|
width: 120
|
package/themes/form-theme.css
CHANGED
|
@@ -39,7 +39,6 @@ body {
|
|
|
39
39
|
--file-uploader-label-color: #fff;
|
|
40
40
|
--file-uploader-li-padding: 2px 5px 0px 5px;
|
|
41
41
|
--file-uploader-li-border-bottom: 1px dotted rgba(0, 0, 0, 0.1);
|
|
42
|
-
--file-uploader-li-icon-margin: 2px 0 2px 5px;
|
|
43
42
|
--file-uploader-li-icon-font: normal 15px var(--md-icon-font, 'Material Symbols Outlined');
|
|
44
43
|
--file-uploader-li-icon-focus-color: var(--md-sys-color-primary);
|
|
45
44
|
}
|