@drax/crud-vue 3.1.0 → 3.2.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/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "3.1
|
|
6
|
+
"version": "3.2.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./src/index.ts",
|
|
9
9
|
"module": "./src/index.ts",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@drax/common-front": "^3.0.0",
|
|
28
28
|
"@drax/crud-front": "^3.0.0",
|
|
29
|
-
"@drax/crud-share": "^3.
|
|
30
|
-
"@drax/media-vue": "^3.1
|
|
29
|
+
"@drax/crud-share": "^3.2.0",
|
|
30
|
+
"@drax/media-vue": "^3.2.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"pinia": "^3.0.4",
|
|
@@ -50,5 +50,5 @@
|
|
|
50
50
|
"vue-tsc": "^3.2.4",
|
|
51
51
|
"vuetify": "^3.11.8"
|
|
52
52
|
},
|
|
53
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "f6c0a2464fdd61b2434d85a097ad23bdbb1d7954"
|
|
54
54
|
}
|
package/src/EntityCrud.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
IEntityCrud, IEntityCrudForm, IEntityCrudHeader, IEntityCrudRefs,
|
|
3
3
|
IEntityCrudRules, IEntityCrudField, IEntityCrudPermissions,
|
|
4
|
-
IDraxCrudProvider, IEntityCrudFilter, IEntityCrudFieldVariant, IDraxFieldFilter
|
|
4
|
+
IDraxCrudProvider, IEntityCrudFilter, IEntityCrudFieldVariant, IDraxFieldFilter,
|
|
5
|
+
IEntityCrudOnInput
|
|
5
6
|
} from "@drax/crud-share";
|
|
6
7
|
|
|
7
8
|
|
|
@@ -149,10 +150,20 @@ class EntityCrud implements IEntityCrud {
|
|
|
149
150
|
return {}
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
|
|
154
|
+
|
|
152
155
|
getRule(field: string | undefined): Array<Function> | undefined {
|
|
153
156
|
return field && this.rules[field] && this.rules[field].length > 0 ? this.rules[field] : undefined
|
|
154
157
|
}
|
|
155
158
|
|
|
159
|
+
get onInputs(): IEntityCrudOnInput {
|
|
160
|
+
return {}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
getOnInput(field: string | undefined): Function | undefined {
|
|
164
|
+
return (field && this.onInputs[field] && typeof this.onInputs[field] === 'function') ? this.onInputs[field] : undefined
|
|
165
|
+
}
|
|
166
|
+
|
|
156
167
|
get isViewable() {
|
|
157
168
|
return true
|
|
158
169
|
}
|
|
@@ -27,6 +27,7 @@ const {entity, multiple} = defineProps({
|
|
|
27
27
|
hint: {type: String},
|
|
28
28
|
persistentHint: {type: Boolean, default: false},
|
|
29
29
|
rules: {type: Array as PropType<any>, default: () => []},
|
|
30
|
+
onInput: {type: Function as PropType<Function>, required: false},
|
|
30
31
|
errorMessages: {type: Array as PropType<string[]>, default: () => []},
|
|
31
32
|
hideDetails: {type: Boolean, default: false},
|
|
32
33
|
singleLine: {type: Boolean, default: false},
|
|
@@ -128,11 +129,17 @@ defineEmits(['updateValue'])
|
|
|
128
129
|
:single-line="singleLine"
|
|
129
130
|
:clearable="clearable"
|
|
130
131
|
:error-messages="errorMessages"
|
|
131
|
-
@update:modelValue="
|
|
132
|
+
@update:modelValue="v => {
|
|
133
|
+
if(onInput && typeof onInput === 'function'){
|
|
134
|
+
onInput(v)
|
|
135
|
+
}
|
|
136
|
+
$emit('updateValue')
|
|
137
|
+
}"
|
|
132
138
|
:prepend-icon="prependIcon"
|
|
133
139
|
:append-icon="appendIcon"
|
|
134
140
|
:prepend-inner-icon="prependInnerIcon"
|
|
135
141
|
:append-inner-icon="appendInnerIcon"
|
|
142
|
+
@input="onInput"
|
|
136
143
|
>
|
|
137
144
|
|
|
138
145
|
<template v-if="addOnTheFly" v-slot:append>
|
|
@@ -185,11 +192,17 @@ defineEmits(['updateValue'])
|
|
|
185
192
|
:clearable="clearable"
|
|
186
193
|
:error-messages="errorMessages"
|
|
187
194
|
@update:search="debouncedSearch"
|
|
188
|
-
@update:modelValue="
|
|
195
|
+
@update:modelValue="v => {
|
|
196
|
+
if(onInput && typeof onInput === 'function'){
|
|
197
|
+
onInput(v)
|
|
198
|
+
}
|
|
199
|
+
$emit('updateValue')
|
|
200
|
+
}"
|
|
189
201
|
:prepend-icon="prependIcon"
|
|
190
202
|
:append-icon="appendIcon"
|
|
191
203
|
:prepend-inner-icon="prependInnerIcon"
|
|
192
204
|
:append-inner-icon="appendInnerIcon"
|
|
205
|
+
@input="onInput"
|
|
193
206
|
>
|
|
194
207
|
|
|
195
208
|
<template v-if="addOnTheFly" v-slot:append>
|
|
@@ -132,6 +132,12 @@ const rules = computed(() => {
|
|
|
132
132
|
}
|
|
133
133
|
})
|
|
134
134
|
|
|
135
|
+
const onInput = computed(() => {
|
|
136
|
+
return (fieldName: string) => {
|
|
137
|
+
return entity?.getOnInput(fieldName) as Function || undefined
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
|
|
135
141
|
const onlyView = computed(()=> {
|
|
136
142
|
return ['delete','view'].includes(operation?.value)
|
|
137
143
|
})
|
|
@@ -177,6 +183,7 @@ const onlyView = computed(()=> {
|
|
|
177
183
|
:preview="field?.preview"
|
|
178
184
|
:previewHeight="field?.previewHeight"
|
|
179
185
|
:rules="rules(field.name)"
|
|
186
|
+
:on-input="onInput(field.name)"
|
|
180
187
|
:hint="field.hint"
|
|
181
188
|
:persistent-hint="field.persistentHint"
|
|
182
189
|
:placeholder="field.placeholder"
|
|
@@ -226,6 +233,7 @@ const onlyView = computed(()=> {
|
|
|
226
233
|
:append-icon="field?.appendIcon"
|
|
227
234
|
:append-inner-icon="field?.appendInnerIcon"
|
|
228
235
|
:rules="rules(field.name)"
|
|
236
|
+
:on-input="onInput(field.name)"
|
|
229
237
|
:hint="field.hint"
|
|
230
238
|
:persistent-hint="field.persistentHint"
|
|
231
239
|
:placeholder="field.placeholder"
|
|
@@ -284,6 +292,7 @@ const onlyView = computed(()=> {
|
|
|
284
292
|
:append-icon="field?.appendIcon"
|
|
285
293
|
:append-inner-icon="field?.appendInnerIcon"
|
|
286
294
|
:rules="rules(field.name)"
|
|
295
|
+
:on-input="onInput(field.name)"
|
|
287
296
|
:hint="field.hint"
|
|
288
297
|
:persistent-hint="field.persistentHint"
|
|
289
298
|
:placeholder="field.placeholder"
|
|
@@ -16,14 +16,13 @@ import MediaField from "@drax/media-vue/src/components/MediaField.vue";
|
|
|
16
16
|
import MediaFullField from "@drax/media-vue/src/components/MediaFullField.vue";
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
const {t, te} = useI18n()
|
|
21
20
|
|
|
22
21
|
const {hasPermission} = useAuth()
|
|
23
22
|
|
|
24
23
|
const valueModel = defineModel<any>({type: [String, Number, Boolean, Object, Array], default: false})
|
|
25
24
|
|
|
26
|
-
const {index, entity, field, parentField, errorMessages, rules, readonly, hideDetails} = defineProps({
|
|
25
|
+
const {index, entity, field, parentField, errorMessages, rules, onInput, readonly, hideDetails} = defineProps({
|
|
27
26
|
entity: {type: Object as PropType<IEntityCrud>, required: true},
|
|
28
27
|
field: {type: Object as PropType<IEntityCrudField | IEntityCrudFilter | undefined>, required: true},
|
|
29
28
|
prependIcon: {type: String, default: ''},
|
|
@@ -43,6 +42,7 @@ const {index, entity, field, parentField, errorMessages, rules, readonly, hideDe
|
|
|
43
42
|
previewHeight: {type: String, default: '100px'},
|
|
44
43
|
parentField: {type: String, default: null, required: false},
|
|
45
44
|
errorMessages: {type: Array as PropType<string[]>, default: null, required: false},
|
|
45
|
+
onInput: {type: Function as PropType<Function>, required: false},
|
|
46
46
|
rules: {type: Array as PropType<ValidationRule[]>, required: false},
|
|
47
47
|
index: {type: Number, default: null, required: false},
|
|
48
48
|
density: {type: String as PropType<'comfortable' | 'compact' | 'default'>, default: 'default'},
|
|
@@ -69,11 +69,10 @@ const label = computed(() => {
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
|
|
73
72
|
const storeErrorMessages = computed(() => {
|
|
74
73
|
let sIndex = (index != null && index >= 0) ? `${index}.` : ''
|
|
75
74
|
let name = parentField ? `${parentField}.${sIndex}${field.name}` : field.name
|
|
76
|
-
return store.getFieldInputErrors(name).map((error: string) =>te(error) ? t(error) : error)
|
|
75
|
+
return store.getFieldInputErrors(name).map((error: string) => te(error) ? t(error) : error)
|
|
77
76
|
}
|
|
78
77
|
)
|
|
79
78
|
|
|
@@ -84,10 +83,10 @@ const inputErrors = computed(() => {
|
|
|
84
83
|
defineEmits(['updateValue'])
|
|
85
84
|
|
|
86
85
|
|
|
87
|
-
const hasHideDetails = computed(()=>{
|
|
88
|
-
if(readonly){
|
|
86
|
+
const hasHideDetails = computed(() => {
|
|
87
|
+
if (readonly) {
|
|
89
88
|
return true
|
|
90
|
-
}else{
|
|
89
|
+
} else {
|
|
91
90
|
return hideDetails ?? field.hideDetails
|
|
92
91
|
}
|
|
93
92
|
|
|
@@ -120,6 +119,7 @@ const hasHideDetails = computed(()=>{
|
|
|
120
119
|
:append-icon="appendIcon"
|
|
121
120
|
:prepend-inner-icon="prependInnerIcon"
|
|
122
121
|
:append-inner-icon="appendInnerIcon"
|
|
122
|
+
@input="onInput"
|
|
123
123
|
@update:modelValue="$emit('updateValue')"
|
|
124
124
|
/>
|
|
125
125
|
|
|
@@ -147,6 +147,7 @@ const hasHideDetails = computed(()=>{
|
|
|
147
147
|
:prepend-inner-icon="prependInnerIcon"
|
|
148
148
|
:append-inner-icon="appendInnerIcon"
|
|
149
149
|
@update:modelValue="$emit('updateValue')"
|
|
150
|
+
@input="onInput"
|
|
150
151
|
/>
|
|
151
152
|
|
|
152
153
|
<v-text-field
|
|
@@ -169,10 +170,11 @@ const hasHideDetails = computed(()=>{
|
|
|
169
170
|
:prepend-icon="prependIcon"
|
|
170
171
|
:append-icon="appendIcon"
|
|
171
172
|
:prepend-inner-icon="prependInnerIcon"
|
|
172
|
-
@update:modelValue="$emit('updateValue')"
|
|
173
173
|
:type="show ? 'text' : 'password'"
|
|
174
174
|
:append-inner-icon="show ? 'mdi-eye' : 'mdi-eye-off'"
|
|
175
175
|
@click:append-inner="show = !show"
|
|
176
|
+
@update:modelValue="$emit('updateValue')"
|
|
177
|
+
@input="onInput"
|
|
176
178
|
/>
|
|
177
179
|
|
|
178
180
|
|
|
@@ -194,12 +196,17 @@ const hasHideDetails = computed(()=>{
|
|
|
194
196
|
:hide-details="hasHideDetails"
|
|
195
197
|
:single-line="singleLine"
|
|
196
198
|
:rules="rules"
|
|
197
|
-
@update:modelValue="
|
|
199
|
+
@update:modelValue="v => {
|
|
200
|
+
if(onInput && typeof onInput === 'function'){
|
|
201
|
+
onInput(v)
|
|
202
|
+
}
|
|
203
|
+
$emit('updateValue')
|
|
204
|
+
}"
|
|
198
205
|
:prepend-icon="prependIcon"
|
|
199
206
|
:append-icon="appendIcon"
|
|
200
207
|
:prepend-inner-icon="prependInnerIcon"
|
|
201
208
|
:append-inner-icon="appendInnerIcon"
|
|
202
|
-
|
|
209
|
+
@input="onInput"
|
|
203
210
|
>
|
|
204
211
|
</v-combobox>
|
|
205
212
|
|
|
@@ -223,12 +230,17 @@ const hasHideDetails = computed(()=>{
|
|
|
223
230
|
:hide-details="hasHideDetails"
|
|
224
231
|
:single-line="singleLine"
|
|
225
232
|
:rules="rules"
|
|
226
|
-
@update:modelValue="
|
|
233
|
+
@update:modelValue="v => {
|
|
234
|
+
if(onInput && typeof onInput === 'function'){
|
|
235
|
+
onInput(v)
|
|
236
|
+
}
|
|
237
|
+
$emit('updateValue')
|
|
238
|
+
}"
|
|
227
239
|
:prepend-icon="prependIcon"
|
|
228
240
|
:append-icon="appendIcon"
|
|
229
241
|
:prepend-inner-icon="prependInnerIcon"
|
|
230
242
|
:append-inner-icon="appendInnerIcon"
|
|
231
|
-
|
|
243
|
+
@input="onInput"
|
|
232
244
|
>
|
|
233
245
|
<template v-slot:item="{ props: itemProps, item }">
|
|
234
246
|
<v-list-item
|
|
@@ -242,7 +254,10 @@ const hasHideDetails = computed(()=>{
|
|
|
242
254
|
</template>
|
|
243
255
|
|
|
244
256
|
<template v-slot:selection="{item}">
|
|
245
|
-
<v-chip tile density="compact" :color="item.raw.color" :prepend-icon="item.raw.icon">{{
|
|
257
|
+
<v-chip tile density="compact" :color="item.raw.color" :prepend-icon="item.raw.icon">{{
|
|
258
|
+
item.raw.title
|
|
259
|
+
}}
|
|
260
|
+
</v-chip>
|
|
246
261
|
</template>
|
|
247
262
|
</v-select>
|
|
248
263
|
|
|
@@ -270,11 +285,11 @@ const hasHideDetails = computed(()=>{
|
|
|
270
285
|
:append-icon="appendIcon"
|
|
271
286
|
:prepend-inner-icon="prependInnerIcon"
|
|
272
287
|
:append-inner-icon="appendInnerIcon"
|
|
288
|
+
@input="onInput"
|
|
273
289
|
>
|
|
274
290
|
</v-select>
|
|
275
291
|
|
|
276
292
|
|
|
277
|
-
|
|
278
293
|
<v-text-field
|
|
279
294
|
v-if="field.type === 'number'"
|
|
280
295
|
type="number"
|
|
@@ -298,6 +313,7 @@ const hasHideDetails = computed(()=>{
|
|
|
298
313
|
:append-icon="appendIcon"
|
|
299
314
|
:prepend-inner-icon="prependInnerIcon"
|
|
300
315
|
:append-inner-icon="appendInnerIcon"
|
|
316
|
+
@input="onInput"
|
|
301
317
|
/>
|
|
302
318
|
|
|
303
319
|
<media-field
|
|
@@ -367,6 +383,7 @@ const hasHideDetails = computed(()=>{
|
|
|
367
383
|
:prepend-inner-icon="prependInnerIcon"
|
|
368
384
|
:append-inner-icon="appendInnerIcon"
|
|
369
385
|
color="primary"
|
|
386
|
+
@input="onInput"
|
|
370
387
|
/>
|
|
371
388
|
|
|
372
389
|
|
|
@@ -375,7 +392,8 @@ const hasHideDetails = computed(()=>{
|
|
|
375
392
|
:name="name"
|
|
376
393
|
:label="label"
|
|
377
394
|
:hint="hint ?? field.hint"
|
|
378
|
-
:persistent-hint="persistentHint ?? field.persistentHint" :placeholder="placeholder ?? field.placeholder"
|
|
395
|
+
:persistent-hint="persistentHint ?? field.persistentHint" :placeholder="placeholder ?? field.placeholder"
|
|
396
|
+
:persistent-placeholder="persistentPlaceholder ?? field.persistentPlaceholder"
|
|
379
397
|
v-model="valueModel"
|
|
380
398
|
:readonly="readonly"
|
|
381
399
|
:error-messages="inputErrors"
|
|
@@ -391,6 +409,9 @@ const hasHideDetails = computed(()=>{
|
|
|
391
409
|
date.setHours(23, 59, 59, 0)
|
|
392
410
|
valueModel = date
|
|
393
411
|
}
|
|
412
|
+
if(onInput && typeof onInput === 'function'){
|
|
413
|
+
onInput(v)
|
|
414
|
+
}
|
|
394
415
|
$emit('updateValue')
|
|
395
416
|
}"
|
|
396
417
|
@click:clear="() => {valueModel = null; $emit('updateValue');} "
|
|
@@ -399,6 +420,7 @@ const hasHideDetails = computed(()=>{
|
|
|
399
420
|
:prepend-inner-icon="prependInnerIcon"
|
|
400
421
|
:append-inner-icon="appendInnerIcon"
|
|
401
422
|
:max="field.max"
|
|
423
|
+
@input="onInput"
|
|
402
424
|
>
|
|
403
425
|
<template v-if="field.endOfDay && field.showEndOfDayChip !== false" v-slot:append-inner>
|
|
404
426
|
<v-chip size="small">23:59</v-chip>
|
|
@@ -431,6 +453,7 @@ const hasHideDetails = computed(()=>{
|
|
|
431
453
|
:prepend-inner-icon="prependInnerIcon"
|
|
432
454
|
:append-inner-icon="appendInnerIcon"
|
|
433
455
|
:add-on-the-fly="field?.addOnTheFly"
|
|
456
|
+
:on-input="onInput"
|
|
434
457
|
/>
|
|
435
458
|
|
|
436
459
|
<v-card v-if="field.type === 'object'" class="mt-3" variant="flat" border>
|
|
@@ -439,7 +462,7 @@ const hasHideDetails = computed(()=>{
|
|
|
439
462
|
<v-card-text>
|
|
440
463
|
|
|
441
464
|
<v-row dense>
|
|
442
|
-
<v-col cols="12"
|
|
465
|
+
<v-col cols="12" v-for="oField in field.objectFields">
|
|
443
466
|
<crud-form-field
|
|
444
467
|
|
|
445
468
|
:entity="entity"
|
|
@@ -487,11 +510,17 @@ const hasHideDetails = computed(()=>{
|
|
|
487
510
|
:hide-details="hasHideDetails"
|
|
488
511
|
:single-line="singleLine"
|
|
489
512
|
:rules="rules"
|
|
490
|
-
@update:modelValue="
|
|
513
|
+
@update:modelValue="v => {
|
|
514
|
+
if(onInput && typeof onInput === 'function'){
|
|
515
|
+
onInput(v)
|
|
516
|
+
}
|
|
517
|
+
$emit('updateValue')
|
|
518
|
+
}"
|
|
491
519
|
:prepend-icon="prependIcon"
|
|
492
520
|
:append-icon="appendIcon"
|
|
493
521
|
:prepend-inner-icon="prependInnerIcon"
|
|
494
522
|
:append-inner-icon="appendInnerIcon"
|
|
523
|
+
@input="onInput"
|
|
495
524
|
>
|
|
496
525
|
</v-combobox>
|
|
497
526
|
|
|
@@ -517,11 +546,17 @@ const hasHideDetails = computed(()=>{
|
|
|
517
546
|
:hide-details="hasHideDetails"
|
|
518
547
|
:single-line="singleLine"
|
|
519
548
|
:rules="rules"
|
|
520
|
-
@update:modelValue="
|
|
549
|
+
@update:modelValue="v => {
|
|
550
|
+
if(onInput && typeof onInput === 'function'){
|
|
551
|
+
onInput(v)
|
|
552
|
+
}
|
|
553
|
+
$emit('updateValue')
|
|
554
|
+
}"
|
|
521
555
|
:prepend-icon="prependIcon"
|
|
522
556
|
:append-icon="appendIcon"
|
|
523
557
|
:prepend-inner-icon="prependInnerIcon"
|
|
524
558
|
:append-inner-icon="appendInnerIcon"
|
|
559
|
+
@input="onInput"
|
|
525
560
|
>
|
|
526
561
|
</v-combobox>
|
|
527
562
|
|
|
@@ -553,6 +588,7 @@ const hasHideDetails = computed(()=>{
|
|
|
553
588
|
:prepend-inner-icon="prependInnerIcon"
|
|
554
589
|
:append-inner-icon="appendInnerIcon"
|
|
555
590
|
:add-on-the-fly="field?.addOnTheFly"
|
|
591
|
+
:on-input="onInput"
|
|
556
592
|
/>
|
|
557
593
|
|
|
558
594
|
|
|
@@ -565,7 +601,7 @@ const hasHideDetails = computed(()=>{
|
|
|
565
601
|
:persistent-hint="persistentHint ?? field.persistentHint"
|
|
566
602
|
:placeholder="placeholder ?? field.placeholder"
|
|
567
603
|
:persistent-placeholder="persistentPlaceholder ?? field.persistentPlaceholder"
|
|
568
|
-
v-model
|
|
604
|
+
v-model="valueModel"
|
|
569
605
|
:multiple="true"
|
|
570
606
|
:chips="true"
|
|
571
607
|
:readonly="readonly"
|
|
@@ -576,11 +612,17 @@ const hasHideDetails = computed(()=>{
|
|
|
576
612
|
:hide-details="hasHideDetails"
|
|
577
613
|
:single-line="singleLine"
|
|
578
614
|
:rules="rules"
|
|
579
|
-
@update:modelValue="
|
|
615
|
+
@update:modelValue="v => {
|
|
616
|
+
if(onInput && typeof onInput === 'function'){
|
|
617
|
+
onInput(v)
|
|
618
|
+
}
|
|
619
|
+
$emit('updateValue')
|
|
620
|
+
}"
|
|
580
621
|
:prepend-icon="prependIcon"
|
|
581
622
|
:append-icon="appendIcon"
|
|
582
623
|
:prepend-inner-icon="prependInnerIcon"
|
|
583
624
|
:append-inner-icon="appendInnerIcon"
|
|
625
|
+
@input="onInput"
|
|
584
626
|
>
|
|
585
627
|
</v-combobox>
|
|
586
628
|
|
|
@@ -39,6 +39,14 @@ export const useCrudStore = (id: string = 'entity') => defineStore('CrudStore'+i
|
|
|
39
39
|
}
|
|
40
40
|
),
|
|
41
41
|
getters: {
|
|
42
|
+
getFieldValue(state: any) {
|
|
43
|
+
return (fieldName: string) => {
|
|
44
|
+
if (fieldName && state.form[fieldName]) {
|
|
45
|
+
return state.form[fieldName]
|
|
46
|
+
}
|
|
47
|
+
return undefined
|
|
48
|
+
}
|
|
49
|
+
},
|
|
42
50
|
getFieldInputErrors(state: any) {
|
|
43
51
|
return (fieldName: string) => {
|
|
44
52
|
if (state.inputErrors && state.inputErrors[fieldName]) {
|