@operato/form 8.0.0-alpha.6 → 8.0.0-beta.1
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 +156 -0
- package/dist/src/filters/ox-filters-form-base.js +2 -1
- package/dist/src/filters/ox-filters-form-base.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
- package/themes/calendar-theme.css +3 -1
- package/.editorconfig +0 -29
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/src/components/ox-custom-input.ts +0 -102
- package/src/components/ox-custom-select.ts +0 -91
- package/src/components/ox-file-uploader.ts +0 -164
- package/src/components/ox-form-master.ts +0 -246
- package/src/components/ox-form-paginator.ts +0 -60
- package/src/components/ox-search-form-paginator.ts +0 -46
- package/src/components/ox-search-form.ts +0 -467
- package/src/filters/filter-checkbox.ts +0 -34
- package/src/filters/filter-input-barcode.ts +0 -35
- package/src/filters/filter-input.ts +0 -30
- package/src/filters/filter-range-date.ts +0 -81
- package/src/filters/filter-range-number.ts +0 -64
- package/src/filters/filter-select.ts +0 -56
- package/src/filters/filter-styles.ts +0 -127
- package/src/filters/index.ts +0 -10
- package/src/filters/ox-filter-personalizer.ts +0 -188
- package/src/filters/ox-filters-form-base.ts +0 -436
- package/src/filters/registry.ts +0 -54
- package/src/index.ts +0 -4
- package/src/styles/index.ts +0 -3
- package/src/styles/multi-column-form-styles.ts +0 -192
- package/src/styles/search-form-styles.ts +0 -160
- package/src/styles/single-column-form-styles.ts +0 -114
- package/src/types.ts +0 -106
- package/stories/ox-filters-form-barcode.stories.ts +0 -140
- package/stories/ox-filters-form-base-bounded.stories.ts +0 -208
- package/stories/ox-filters-form-base-change-handler.stories.ts +0 -220
- package/stories/ox-filters-form-base-page-preference.stories.ts +0 -177
- package/stories/ox-filters-form-base.stories.ts +0 -179
- package/stories/ox-search-form-change-handler.stories.ts +0 -253
- package/stories/ox-search-form.stories.ts +0 -258
- package/tsconfig.json +0 -24
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -41
|
@@ -1,467 +0,0 @@
|
|
|
1
|
-
import '@material/web/icon/icon.js'
|
|
2
|
-
import './ox-custom-input.js'
|
|
3
|
-
import './ox-custom-select.js'
|
|
4
|
-
|
|
5
|
-
import gql from 'graphql-tag'
|
|
6
|
-
import { css, html, LitElement, nothing, PropertyValues } from 'lit'
|
|
7
|
-
import { customElement, property, query, queryAll, queryAsync } from 'lit/decorators.js'
|
|
8
|
-
import { ifDefined } from 'lit/directives/if-defined.js'
|
|
9
|
-
import { until } from 'lit/directives/until.js'
|
|
10
|
-
import { styles as MDTypeScaleStyles } from '@material/web/typography/md-typescale-styles'
|
|
11
|
-
|
|
12
|
-
import { buildArgs, client } from '@operato/graphql'
|
|
13
|
-
|
|
14
|
-
import { SearchFormStyles } from '../styles/search-form-styles.js'
|
|
15
|
-
import { SearchFormField, SelectOption, SelectOptionObject } from '../types.js'
|
|
16
|
-
|
|
17
|
-
function buildOptions(field: SearchFormField, options: SelectOption[]) {
|
|
18
|
-
const selectOptionObjects = options.map(option => {
|
|
19
|
-
switch (typeof option) {
|
|
20
|
-
case 'string':
|
|
21
|
-
return {
|
|
22
|
-
name: option,
|
|
23
|
-
value: option
|
|
24
|
-
}
|
|
25
|
-
case 'object':
|
|
26
|
-
return {
|
|
27
|
-
name: option.name || option.display,
|
|
28
|
-
value: option.value
|
|
29
|
-
}
|
|
30
|
-
default:
|
|
31
|
-
return option
|
|
32
|
-
}
|
|
33
|
-
}) as SelectOptionObject[]
|
|
34
|
-
|
|
35
|
-
return html`
|
|
36
|
-
${selectOptionObjects?.map(
|
|
37
|
-
({ value, display, name }) => html`
|
|
38
|
-
<option ?selected=${value == field.value} value=${value}>${name || display}</option>
|
|
39
|
-
`
|
|
40
|
-
)}
|
|
41
|
-
`
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
@customElement('ox-search-form')
|
|
45
|
-
export class OxSearchForm extends LitElement {
|
|
46
|
-
static styles = [
|
|
47
|
-
MDTypeScaleStyles,
|
|
48
|
-
SearchFormStyles,
|
|
49
|
-
css`
|
|
50
|
-
:host {
|
|
51
|
-
display: flex;
|
|
52
|
-
flex-direction: column;
|
|
53
|
-
padding: var(--spacing-small);
|
|
54
|
-
|
|
55
|
-
position: relative;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
::placeholder {
|
|
59
|
-
text-transform: capitalize;
|
|
60
|
-
color: rgba(var(--secondary-color-rgb), 0.5);
|
|
61
|
-
}
|
|
62
|
-
label {
|
|
63
|
-
font-size: var(--md-sys-typescale-label-large-size, 0.875rem);
|
|
64
|
-
color: var(--md-sys-color-primary);
|
|
65
|
-
}
|
|
66
|
-
select,
|
|
67
|
-
input {
|
|
68
|
-
border: none;
|
|
69
|
-
border-bottom: var(--ox-filters-input-border, 1px solid var(--md-sys-color-outline));
|
|
70
|
-
font: var(--ox-filters-input-font);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
select:focus,
|
|
74
|
-
input:focus {
|
|
75
|
-
outline: none;
|
|
76
|
-
border-bottom: var(--ox-filters-input-focus-border, 1px solid var(--md-sys-color-primary));
|
|
77
|
-
color: var(--ox-filters-input-focus-color, var(--md-sys-color-primary));
|
|
78
|
-
}
|
|
79
|
-
`
|
|
80
|
-
]
|
|
81
|
-
|
|
82
|
-
@property({ type: Array }) fields?: SearchFormField[]
|
|
83
|
-
@property({ type: Boolean }) hideSearchButton: boolean = false
|
|
84
|
-
@property({ type: Boolean, attribute: true }) autofocus: boolean = false
|
|
85
|
-
|
|
86
|
-
@queryAsync('form') form!: HTMLFormElement
|
|
87
|
-
@query('input[autofocus]') autofocused?: HTMLInputElement
|
|
88
|
-
@queryAll('input, select') formFields!: ((HTMLInputElement | HTMLSelectElement) & { field: string; _value: any })[]
|
|
89
|
-
|
|
90
|
-
private autoUpdateTargetsOnChange: { [name: string]: string[] } = {}
|
|
91
|
-
|
|
92
|
-
render() {
|
|
93
|
-
var autofocusConsumed = 0
|
|
94
|
-
|
|
95
|
-
return html`
|
|
96
|
-
<form
|
|
97
|
-
class="search-form md-typescale-body-medium-prominent"
|
|
98
|
-
@submit=${(e: Event) => {
|
|
99
|
-
e.preventDefault() // input="text" 가 한개만 있을경우에 엔터를 치면 강제 submit되는 증상 방지
|
|
100
|
-
}}
|
|
101
|
-
@change=${async (e: Event) => {
|
|
102
|
-
const field = e.target as HTMLInputElement
|
|
103
|
-
const name = field?.getAttribute('name')
|
|
104
|
-
const value = field.value
|
|
105
|
-
|
|
106
|
-
if (name && this.autoUpdateTargetsOnChange[name]) {
|
|
107
|
-
;(this.autoUpdateTargetsOnChange[name] || []).forEach(name => {
|
|
108
|
-
const target = this.renderRoot.querySelector(`[name='${name}']`)
|
|
109
|
-
if (target) {
|
|
110
|
-
;(target as HTMLInputElement).value = ''
|
|
111
|
-
}
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
this.requestUpdate()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const { onchange } = this.fields?.find(field => field.name == name) || {}
|
|
118
|
-
|
|
119
|
-
const keepGoing = onchange ? await onchange.call(null, value, this) : true
|
|
120
|
-
|
|
121
|
-
if (keepGoing) {
|
|
122
|
-
this.dispatchEvent(new CustomEvent('change', { detail: value }))
|
|
123
|
-
this.submit()
|
|
124
|
-
}
|
|
125
|
-
}}
|
|
126
|
-
>
|
|
127
|
-
${(this.fields || []).map(
|
|
128
|
-
field => html`
|
|
129
|
-
${field.type === 'select'
|
|
130
|
-
? this.renderSelect(field)
|
|
131
|
-
: field.type === 'checkbox'
|
|
132
|
-
? this.renderCheckbox(field)
|
|
133
|
-
: field.type === 'object'
|
|
134
|
-
? this.renderObject(field, autofocusConsumed++)
|
|
135
|
-
: this.renderElse(field, autofocusConsumed++)}
|
|
136
|
-
`
|
|
137
|
-
)}
|
|
138
|
-
${!!this.hideSearchButton
|
|
139
|
-
? nothing
|
|
140
|
-
: html`<md-icon @click=${(e: MouseEvent) => this.submit()} search>search</md-icon>`}
|
|
141
|
-
</form>
|
|
142
|
-
`
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
renderSelect(field: SearchFormField) {
|
|
146
|
-
var { id, options, readonly, label, name, value, placeholder, hidden } = field
|
|
147
|
-
|
|
148
|
-
if (typeof options === 'function') {
|
|
149
|
-
options = (options as Function).call(field, this)
|
|
150
|
-
|
|
151
|
-
if (options instanceof Promise) {
|
|
152
|
-
var optionsTemplate = html`${until(options.then(options => buildOptions(field, options)))}`
|
|
153
|
-
} else {
|
|
154
|
-
var optionsTemplate = buildOptions(field, (options || []) as SelectOption[])
|
|
155
|
-
}
|
|
156
|
-
} else {
|
|
157
|
-
var optionsTemplate = buildOptions(field, (options || []) as SelectOption[])
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return html`
|
|
161
|
-
<label ?hidden=${hidden}>${label || name || id}</label>
|
|
162
|
-
<select
|
|
163
|
-
.value=${value}
|
|
164
|
-
name=${ifDefined(name)}
|
|
165
|
-
placeholder=${ifDefined(placeholder)}
|
|
166
|
-
?hidden=${hidden}
|
|
167
|
-
?readonly=${readonly}
|
|
168
|
-
>
|
|
169
|
-
${optionsTemplate!}
|
|
170
|
-
</select>
|
|
171
|
-
`
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
renderCheckbox(field: SearchFormField) {
|
|
175
|
-
return html`
|
|
176
|
-
<input
|
|
177
|
-
id="ckbx_${field.name}"
|
|
178
|
-
type="checkbox"
|
|
179
|
-
name=${ifDefined(field.name)}
|
|
180
|
-
?checked=${field.value}
|
|
181
|
-
?hidden=${field.hidden}
|
|
182
|
-
?readonly=${field.readonly}
|
|
183
|
-
@click=${(e: MouseEvent) => {
|
|
184
|
-
const checkbox = e.currentTarget as HTMLInputElement & { _value: any }
|
|
185
|
-
if (checkbox.hasAttribute('indeterminate')) {
|
|
186
|
-
const values = [undefined, 'on', 'off']
|
|
187
|
-
const currentValue = checkbox._value
|
|
188
|
-
const newValue =
|
|
189
|
-
values.indexOf(currentValue) + 1 > values.length - 1
|
|
190
|
-
? values[0]
|
|
191
|
-
: values[values.indexOf(currentValue) + 1]
|
|
192
|
-
|
|
193
|
-
if (newValue === 'on') {
|
|
194
|
-
checkbox.checked = true
|
|
195
|
-
} else if (newValue === 'off') {
|
|
196
|
-
checkbox.checked = false
|
|
197
|
-
} else {
|
|
198
|
-
checkbox.indeterminate = true
|
|
199
|
-
}
|
|
200
|
-
checkbox._value = newValue
|
|
201
|
-
}
|
|
202
|
-
}}
|
|
203
|
-
/>
|
|
204
|
-
<label for="ckbx_${field.name}" ?hidden=${field.hidden}>${field.label || field.name || field.id}</label>
|
|
205
|
-
`
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
renderObject(field: SearchFormField, autofocusConsumed: number) {
|
|
209
|
-
return html`
|
|
210
|
-
<label ?hidden=${field.hidden}>${field.label || field.name || field.id}</label>
|
|
211
|
-
<input
|
|
212
|
-
.type=${field.type}
|
|
213
|
-
name=${ifDefined(field.name)}
|
|
214
|
-
placeholder=${ifDefined(field.placeholder)}
|
|
215
|
-
.value=${field.value || ''}
|
|
216
|
-
.field=${field.field}
|
|
217
|
-
.queryName=${field.queryName}
|
|
218
|
-
?hidden=${field.hidden}
|
|
219
|
-
?readonly=${field.readonly}
|
|
220
|
-
?autofocus=${!field.hidden && 0 === autofocusConsumed}
|
|
221
|
-
/>
|
|
222
|
-
`
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
renderElse(field: SearchFormField, autofocusConsumed: number) {
|
|
226
|
-
return html`
|
|
227
|
-
<label ?hidden=${field.hidden}>${field.label || field.name || field.id}</label>
|
|
228
|
-
<input
|
|
229
|
-
.type=${field.type}
|
|
230
|
-
.value=${field.value || ''}
|
|
231
|
-
name=${ifDefined(field.name)}
|
|
232
|
-
placeholder=${ifDefined(field.placeholder)}
|
|
233
|
-
?hidden=${field.hidden}
|
|
234
|
-
?readonly=${field.readonly}
|
|
235
|
-
?autofocus=${!field.hidden && 0 === autofocusConsumed++}
|
|
236
|
-
/>
|
|
237
|
-
`
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async updated(changes: PropertyValues<this>) {
|
|
241
|
-
if (changes.has('fields')) {
|
|
242
|
-
this._checkInputValidity()
|
|
243
|
-
|
|
244
|
-
var formFields = Array.from(this.formFields)
|
|
245
|
-
this.fields &&
|
|
246
|
-
this.fields.forEach(field => {
|
|
247
|
-
var formField = formFields.find(f => f.name == field.name)
|
|
248
|
-
if (field.props instanceof Object && !Array.isArray(field.props)) {
|
|
249
|
-
for (let prop in field.props) {
|
|
250
|
-
if (field.props[prop]) {
|
|
251
|
-
formField!.setAttribute(prop, field.props[prop])
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
if (field.attrs && Array.isArray(field.attrs)) {
|
|
257
|
-
field.attrs.forEach(attr => {
|
|
258
|
-
if (attr === 'indeterminate') {
|
|
259
|
-
;(formField as HTMLInputElement).indeterminate = true
|
|
260
|
-
} else {
|
|
261
|
-
formField!.setAttribute(attr, '')
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (field.handlers instanceof Object && !Array.isArray(field.handlers)) {
|
|
267
|
-
for (let eventName in field.handlers) {
|
|
268
|
-
formField!.addEventListener(eventName, field.handlers[eventName])
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
if (this.autofocus) {
|
|
274
|
-
await this.requestUpdate()
|
|
275
|
-
this.autofocused?.focus()
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
this.autoUpdateTargetsOnChange = {}
|
|
279
|
-
this.fields
|
|
280
|
-
?.filter(filter => filter.boundTo && filter.boundTo.length > 0)
|
|
281
|
-
.map(({ name, boundTo }) => {
|
|
282
|
-
boundTo!.forEach(to => {
|
|
283
|
-
const origin = this.autoUpdateTargetsOnChange[to] || []
|
|
284
|
-
if (name && !origin.includes(name)) {
|
|
285
|
-
this.autoUpdateTargetsOnChange[to] = [...origin, name]
|
|
286
|
-
}
|
|
287
|
-
})
|
|
288
|
-
})
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
getFieldByName(name: string) {
|
|
293
|
-
return this.renderRoot.querySelector(`[name=${name}]`)
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
_checkInputValidity() {
|
|
297
|
-
const names = this.fields?.map(i => i.name) || []
|
|
298
|
-
const result = names.every(name => {
|
|
299
|
-
return names.indexOf(name) === names.lastIndexOf(name)
|
|
300
|
-
})
|
|
301
|
-
if (!result) {
|
|
302
|
-
throw new Error('Field name is duplicated.')
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
get searchParams() {
|
|
307
|
-
let searchParam = new URLSearchParams()
|
|
308
|
-
const fields = Array.from(this.formFields)
|
|
309
|
-
fields.forEach(field => searchParam.append(field.name, field.value))
|
|
310
|
-
|
|
311
|
-
return decodeURI(searchParam.toString())
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
get queryFilters() {
|
|
315
|
-
return Array.from(this.formFields)
|
|
316
|
-
.filter(
|
|
317
|
-
field =>
|
|
318
|
-
(field.type !== 'checkbox' && field.value && field.value !== '') ||
|
|
319
|
-
(field.type === 'checkbox' && !field.hasAttribute('indeterminate')) ||
|
|
320
|
-
(field.type === 'checkbox' && field.hasAttribute('indeterminate') && field._value)
|
|
321
|
-
)
|
|
322
|
-
.map(field => {
|
|
323
|
-
const operator = field.getAttribute('searchOper') || ''
|
|
324
|
-
let value = operator.indexOf('like') >= 0 ? `%${field.value}%` : field.value
|
|
325
|
-
return {
|
|
326
|
-
name: field.name,
|
|
327
|
-
value:
|
|
328
|
-
field.type === 'text'
|
|
329
|
-
? value
|
|
330
|
-
: field.type === 'checkbox'
|
|
331
|
-
? field.hasAttribute('indeterminate')
|
|
332
|
-
? field._value === 'on'
|
|
333
|
-
? true
|
|
334
|
-
: false
|
|
335
|
-
: (field as HTMLInputElement).checked
|
|
336
|
-
: field.type === 'number'
|
|
337
|
-
? parseFloat(value)
|
|
338
|
-
: value,
|
|
339
|
-
operator
|
|
340
|
-
}
|
|
341
|
-
})
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
public async getQueryFilters() {
|
|
345
|
-
return await Promise.all(
|
|
346
|
-
Array.from(this.formFields)
|
|
347
|
-
.filter(
|
|
348
|
-
field =>
|
|
349
|
-
(field.type !== 'checkbox' && field.value && field.value !== '') ||
|
|
350
|
-
(field.type === 'checkbox' && !field.hasAttribute('indeterminate')) ||
|
|
351
|
-
(field.type === 'checkbox' && field.hasAttribute('indeterminate') && field._value)
|
|
352
|
-
)
|
|
353
|
-
.map(async field => {
|
|
354
|
-
const name = field.name
|
|
355
|
-
const operator = (field.type === 'text' && field.field ? 'in' : field.getAttribute('searchOper')) || ''
|
|
356
|
-
const value = operator.indexOf('like') >= 0 ? `%${field.value}%` : field.value
|
|
357
|
-
const filter = {
|
|
358
|
-
name,
|
|
359
|
-
operator,
|
|
360
|
-
value:
|
|
361
|
-
field.type === 'text' && field.getAttribute('type') === 'object'
|
|
362
|
-
? await this._getResourceIds(field)
|
|
363
|
-
: field.type === 'text'
|
|
364
|
-
? value
|
|
365
|
-
: field.type === 'checkbox'
|
|
366
|
-
? field.hasAttribute('indeterminate')
|
|
367
|
-
? field._value === 'on'
|
|
368
|
-
? true
|
|
369
|
-
: false
|
|
370
|
-
: (field as HTMLInputElement).checked
|
|
371
|
-
: field.type === 'number'
|
|
372
|
-
? parseFloat(value)
|
|
373
|
-
: value,
|
|
374
|
-
relation: field.type === 'text' && field.getAttribute('type') === 'object'
|
|
375
|
-
}
|
|
376
|
-
return filter
|
|
377
|
-
})
|
|
378
|
-
)
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
private async _getResourceIds(inputField: HTMLInputElement | HTMLSelectElement) {
|
|
382
|
-
const {
|
|
383
|
-
field = 'name',
|
|
384
|
-
value,
|
|
385
|
-
queryName
|
|
386
|
-
} = inputField as (HTMLInputElement | HTMLSelectElement) & { field: string; queryName: string }
|
|
387
|
-
|
|
388
|
-
const response = await client.query({
|
|
389
|
-
query: gql`
|
|
390
|
-
query {
|
|
391
|
-
fetch: ${queryName}(${buildArgs({
|
|
392
|
-
filters: [
|
|
393
|
-
{
|
|
394
|
-
name: field,
|
|
395
|
-
operator: 'i_like',
|
|
396
|
-
value: `%${value}%`
|
|
397
|
-
}
|
|
398
|
-
]
|
|
399
|
-
})}) {
|
|
400
|
-
items {
|
|
401
|
-
id
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
`
|
|
406
|
-
})
|
|
407
|
-
|
|
408
|
-
if (!response.errors) {
|
|
409
|
-
const items = response.data.fetch.items as { id: string }[]
|
|
410
|
-
return (items && items.map(item => item.id)) || []
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
serialize() {
|
|
415
|
-
let data: { [name: string]: any } = {}
|
|
416
|
-
|
|
417
|
-
Array.from(this.formFields).forEach(field => {
|
|
418
|
-
const name = field.name
|
|
419
|
-
if (field.type === 'number') {
|
|
420
|
-
data[name] = parseFloat(field.value)
|
|
421
|
-
} else if (field.type === 'checkbox') {
|
|
422
|
-
data[name] = (field as HTMLInputElement).checked
|
|
423
|
-
} else {
|
|
424
|
-
data[name] = field.value
|
|
425
|
-
}
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
return data
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
reset(value?: string[] | { [field: string]: any }) {
|
|
432
|
-
this.form
|
|
433
|
-
.then((form: HTMLFormElement) => {
|
|
434
|
-
if (value) {
|
|
435
|
-
if (value instanceof Array) {
|
|
436
|
-
value
|
|
437
|
-
.filter(item => typeof item == 'string')
|
|
438
|
-
.forEach(item => {
|
|
439
|
-
const field = this.getFieldByName(item)
|
|
440
|
-
if (field) {
|
|
441
|
-
;(field as HTMLInputElement).value = ''
|
|
442
|
-
}
|
|
443
|
-
})
|
|
444
|
-
} else {
|
|
445
|
-
const keys = Object.keys(value)
|
|
446
|
-
keys
|
|
447
|
-
.filter(key => typeof key == 'string')
|
|
448
|
-
.forEach(key => {
|
|
449
|
-
const field = this.getFieldByName(key)
|
|
450
|
-
if (field) {
|
|
451
|
-
;(field as HTMLInputElement).value = value[key]
|
|
452
|
-
}
|
|
453
|
-
})
|
|
454
|
-
}
|
|
455
|
-
} else {
|
|
456
|
-
form.reset()
|
|
457
|
-
}
|
|
458
|
-
})
|
|
459
|
-
.catch((error: any) => {
|
|
460
|
-
console.error('Error resetting the form:', error)
|
|
461
|
-
})
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
submit() {
|
|
465
|
-
this.dispatchEvent(new CustomEvent('submit'))
|
|
466
|
-
}
|
|
467
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import '@operato/input/ox-checkbox.js'
|
|
2
|
-
|
|
3
|
-
import { html } from 'lit-html'
|
|
4
|
-
|
|
5
|
-
import { FilterSelectRenderer } from '../types.js'
|
|
6
|
-
|
|
7
|
-
export const FilterCheckbox: FilterSelectRenderer = (filter, value, owner) => {
|
|
8
|
-
const { name, label, readonly } = filter
|
|
9
|
-
|
|
10
|
-
return html`
|
|
11
|
-
<ox-checkbox
|
|
12
|
-
name=${name}
|
|
13
|
-
?checked=${value}
|
|
14
|
-
indeterminatable
|
|
15
|
-
?indeterminate=${value === undefined}
|
|
16
|
-
left-label
|
|
17
|
-
@change=${(e: CustomEvent) => {
|
|
18
|
-
;(e.target as HTMLElement).dispatchEvent(
|
|
19
|
-
new CustomEvent('filter-change', {
|
|
20
|
-
bubbles: true,
|
|
21
|
-
composed: true,
|
|
22
|
-
detail: {
|
|
23
|
-
name: name,
|
|
24
|
-
operator: filter.operator,
|
|
25
|
-
value: (e.target as Element & { checked: boolean | undefined }).checked
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
)
|
|
29
|
-
}}
|
|
30
|
-
?readonly=${readonly}
|
|
31
|
-
><label><span>${label}</span></label></ox-checkbox
|
|
32
|
-
>
|
|
33
|
-
`
|
|
34
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import '@operato/input/ox-input-barcode.js'
|
|
2
|
-
|
|
3
|
-
import { html } from 'lit-html'
|
|
4
|
-
|
|
5
|
-
import { FilterSelectRenderer } from '../types.js'
|
|
6
|
-
|
|
7
|
-
export const FilterInputBarcode: FilterSelectRenderer = (filter, value, owner) => {
|
|
8
|
-
const { name, readonly, options } = filter
|
|
9
|
-
const { englishOnly, selectAfterChange } = (options || {}) as { [key: string]: any }
|
|
10
|
-
|
|
11
|
-
return html`
|
|
12
|
-
<ox-input-barcode
|
|
13
|
-
name=${name}
|
|
14
|
-
?english-only=${englishOnly}
|
|
15
|
-
?select-after-change=${selectAfterChange}
|
|
16
|
-
.value=${value === undefined ? '' : value}
|
|
17
|
-
@change=${(e: CustomEvent) => {
|
|
18
|
-
const input = e.target as HTMLInputElement
|
|
19
|
-
input.dispatchEvent(
|
|
20
|
-
new CustomEvent('filter-change', {
|
|
21
|
-
bubbles: true,
|
|
22
|
-
composed: true,
|
|
23
|
-
detail: {
|
|
24
|
-
name,
|
|
25
|
-
operator: filter.operator,
|
|
26
|
-
value: input.value
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
)
|
|
30
|
-
}}
|
|
31
|
-
filter-input
|
|
32
|
-
?readonly=${readonly}
|
|
33
|
-
></ox-input-barcode>
|
|
34
|
-
`
|
|
35
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { html } from 'lit-html'
|
|
2
|
-
|
|
3
|
-
import { FilterSelectRenderer } from '../types.js'
|
|
4
|
-
|
|
5
|
-
export const FilterInput: FilterSelectRenderer = (filter, value, owner) => {
|
|
6
|
-
const { name, type, readonly } = filter
|
|
7
|
-
|
|
8
|
-
return html`
|
|
9
|
-
<input
|
|
10
|
-
type=${type}
|
|
11
|
-
name=${name}
|
|
12
|
-
.value=${value === undefined ? '' : value}
|
|
13
|
-
@change=${(e: CustomEvent) => {
|
|
14
|
-
const input = e.target as HTMLInputElement
|
|
15
|
-
input.dispatchEvent(
|
|
16
|
-
new CustomEvent('filter-change', {
|
|
17
|
-
bubbles: true,
|
|
18
|
-
composed: true,
|
|
19
|
-
detail: {
|
|
20
|
-
name: name,
|
|
21
|
-
operator: filter.operator,
|
|
22
|
-
value: input.value
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
)
|
|
26
|
-
}}
|
|
27
|
-
?readonly=${readonly}
|
|
28
|
-
/>
|
|
29
|
-
`
|
|
30
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { html } from 'lit-html'
|
|
2
|
-
|
|
3
|
-
import { FilterSelectRenderer } from '../types.js'
|
|
4
|
-
|
|
5
|
-
function formatDate(type: string, date: Date) {
|
|
6
|
-
var year = date.getFullYear()
|
|
7
|
-
var month = ('0' + (date.getMonth() + 1)).slice(-2)
|
|
8
|
-
var day = ('0' + date.getDate()).slice(-2)
|
|
9
|
-
var hours = ('0' + date.getHours()).slice(-2)
|
|
10
|
-
var minutes = ('0' + date.getMinutes()).slice(-2)
|
|
11
|
-
|
|
12
|
-
var formatDate = year + '-' + month + '-' + day
|
|
13
|
-
|
|
14
|
-
return type == 'date' ? formatDate : formatDate + 'T' + hours + ':' + minutes
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const FilterRangeDate: FilterSelectRenderer = (filter, value, owner) => {
|
|
18
|
-
var { name, type, operator, readonly } = filter
|
|
19
|
-
var [from, to] = value instanceof Array ? value : []
|
|
20
|
-
|
|
21
|
-
if (type === 'datetime') {
|
|
22
|
-
type = 'datetime-local'
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
from = formatDate(type, new Date(from))
|
|
26
|
-
to = formatDate(type, new Date(to))
|
|
27
|
-
|
|
28
|
-
return html`
|
|
29
|
-
<input
|
|
30
|
-
name=${name}
|
|
31
|
-
type=${type as 'date' | 'datetime-local'}
|
|
32
|
-
value=${from}
|
|
33
|
-
from
|
|
34
|
-
@keyup=${(e: KeyboardEvent) => {
|
|
35
|
-
if (e.key !== 'Enter') {
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
;(e.target as HTMLElement).dispatchEvent(
|
|
39
|
-
new CustomEvent('filter-change', {
|
|
40
|
-
bubbles: true,
|
|
41
|
-
composed: true,
|
|
42
|
-
detail: {
|
|
43
|
-
name,
|
|
44
|
-
operator,
|
|
45
|
-
value: Array.from(
|
|
46
|
-
(e.target as HTMLElement).parentElement!.querySelectorAll('input[from], input[to]')
|
|
47
|
-
).map(input => (input as HTMLInputElement).value)
|
|
48
|
-
}
|
|
49
|
-
})
|
|
50
|
-
)
|
|
51
|
-
}}
|
|
52
|
-
?readonly=${readonly}
|
|
53
|
-
/>
|
|
54
|
-
~
|
|
55
|
-
<input
|
|
56
|
-
name=${name}
|
|
57
|
-
type=${type as 'date' | 'datetime-local'}
|
|
58
|
-
value=${to}
|
|
59
|
-
to
|
|
60
|
-
@keyup=${(e: KeyboardEvent) => {
|
|
61
|
-
if (e.key !== 'Enter') {
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
;(e.target as HTMLElement).dispatchEvent(
|
|
65
|
-
new CustomEvent('filter-change', {
|
|
66
|
-
bubbles: true,
|
|
67
|
-
composed: true,
|
|
68
|
-
detail: {
|
|
69
|
-
name,
|
|
70
|
-
operator,
|
|
71
|
-
value: Array.from(
|
|
72
|
-
(e.target as HTMLElement).parentElement!.querySelectorAll('input[from], input[to]')
|
|
73
|
-
).map(input => (input as HTMLInputElement).value)
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
)
|
|
77
|
-
}}
|
|
78
|
-
?readonly=${readonly}
|
|
79
|
-
/>
|
|
80
|
-
`
|
|
81
|
-
}
|