Skip to content

Commit ae24b8f

Browse files
authored
Merge pull request #364 from citation-file-format/208-identifiers-validation
implement validation for identifiers screen
2 parents 36d8797 + 27b1b24 commit ae24b8f

6 files changed

Lines changed: 82 additions & 20 deletions

File tree

src/components/IdentifierCardEditing.vue

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
<q-card
33
flat
44
bordered
5-
class="bg-formcard"
5+
v-bind:class="['bg-formcard', 'q-pa-md', identifierErrors.hasError ? 'red-border' : '']"
66
>
77
<q-card-section>
88
<div class="row items-center no-wrap">
99
<q-option-group
1010
inline
1111
type="radio"
12+
v-bind:error="typeError.hasError"
13+
v-bind:error-message="typeError.messages.join(', ')"
1214
v-bind:model-value="type"
1315
v-bind:options="typeOptions"
1416
v-on:update:modelValue="
@@ -23,6 +25,8 @@
2325
outlined
2426
standout
2527
dense
28+
v-bind:error="valueError.hasError"
29+
v-bind:error-message="valueError.messages.join(', ')"
2630
v-bind:model-value="value"
2731
v-on:update:modelValue="
2832
$emit('updateValue', 'value', $event)
@@ -36,6 +40,8 @@
3640
outlined
3741
standout
3842
dense
43+
v-bind:error="descriptionError.hasError"
44+
v-bind:error-message="descriptionError.messages.join(', ')"
3945
v-bind:model-value="description"
4046
v-on:update:modelValue="
4147
$emit('updateDescription', 'description', $event)
@@ -79,7 +85,9 @@
7985

8086
<script lang="ts">
8187
import { IdentifierTypeType } from '../types'
82-
import { defineComponent, PropType } from 'vue'
88+
import { computed, defineComponent, PropType } from 'vue'
89+
import { getMyErrors } from 'src/store/validator'
90+
import { identifierErrors } from 'src/identifier-errors'
8391
8492
export default defineComponent({
8593
name: 'IdentifierCardEditing',
@@ -105,23 +113,18 @@ export default defineComponent({
105113
default: 0
106114
}
107115
},
108-
setup () {
109-
// validating of value depends on type
110-
// const valueValidators: Record<IdentifierTypeType, (val: unknown) => true | string > = {
111-
// doi: makeFieldValidator('/definitions/identifier/anyOf/0/properties/value'),
112-
// url: makeFieldValidator('/definitions/identifier/anyOf/1/properties/value'),
113-
// swh: makeFieldValidator('/definitions/identifier/anyOf/2/properties/value'),
114-
// other: makeFieldValidator('/definitions/identifier/anyOf/3/properties/value')
115-
// }
116+
setup (props) {
116117
return {
117-
// validateValue: (val: string) => valueValidators[props.type as IdentifierTypeType](val),
118-
// validateDescription: makeOptionalFieldValidator('/definitions/identifier-description'),
119118
typeOptions: [
120119
{ label: 'DOI', value: 'doi' },
121120
{ label: 'URL', value: 'url' },
122121
{ label: 'Software Heritage', value: 'swh' },
123122
{ label: 'Other', value: 'other' }
124-
]
123+
],
124+
typeError: computed(() => getMyErrors(`/identifiers/${props.index}/type`)),
125+
valueError: computed(() => getMyErrors(`/identifiers/${props.index}/value`)),
126+
descriptionError: computed(() => getMyErrors(`/identifiers/${props.index}/description`)),
127+
identifierErrors: computed(() => identifierErrors(props.index))
125128
}
126129
},
127130
emits: ['closePressed', 'removePressed', 'updateType', 'updateValue', 'updateDescription', 'moveUp', 'moveDown']

src/components/IdentifierCardViewing.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<q-card
33
bordered
4-
class="bg-formcard"
4+
v-bind:class="['bg-formcard', identifierErrors.hasError ? 'red-border' : '']"
55
flat
66
style="display: flex; flex-direction: row"
77
>
@@ -42,8 +42,9 @@
4242
</template>
4343

4444
<script lang="ts">
45-
import { defineComponent, PropType } from 'vue'
45+
import { computed, defineComponent, PropType } from 'vue'
4646
import { IdentifierType } from 'src/types'
47+
import { identifierErrors } from 'src/identifier-errors'
4748
4849
export default defineComponent({
4950
name: 'IdentifierCardViewing',
@@ -61,6 +62,11 @@ export default defineComponent({
6162
default: 0
6263
}
6364
},
65+
setup (props) {
66+
return {
67+
identifierErrors: computed(() => identifierErrors(props.index))
68+
}
69+
},
6470
emits: ['editPressed', 'moveDown', 'moveUp']
6571
})
6672
</script>

src/components/ScreenIdentifiers.vue

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,26 @@
6363
</q-btn>
6464
</div>
6565

66+
<q-banner
67+
v-if="identifiersErrors.hasError"
68+
class="bg-warning text-negative"
69+
>
70+
<div
71+
v-bind:key="index"
72+
v-for="(screenMessage, index) in identifiersErrors.messages"
73+
>
74+
{{ screenMessage }}
75+
</div>
76+
</q-banner>
77+
6678
<div id="form-button-bar">
6779
<StepperActions />
6880
</div>
6981
</div>
7082
</template>
7183

7284
<script lang="ts">
73-
import { defineComponent, nextTick, ref } from 'vue'
85+
import { computed, defineComponent, nextTick, ref } from 'vue'
7486
import Stepper from 'components/Stepper.vue'
7587
import StepperActions from 'components/StepperActions.vue'
7688
import IdentifierCardEditing from 'components/IdentifierCardEditing.vue'
@@ -79,6 +91,7 @@ import { IdentifierType, IdentifierTypeType } from 'src/types'
7991
import { useCff } from 'src/store/cff'
8092
import { scrollToBottom } from '../scroll-to-bottom'
8193
import { moveDown, moveUp } from '../updown'
94+
import { identifiersErrors } from 'src/identifiers-errors'
8295
8396
export default defineComponent({
8497
name: 'ScreenIdentifiers',
@@ -172,7 +185,8 @@ export default defineComponent({
172185
removeIdentifier,
173186
setIdentifierDescriptionField,
174187
setIdentifierTypeField,
175-
setIdentifierValueField
188+
setIdentifierValueField,
189+
identifiersErrors: computed(() => identifiersErrors(identifiers.value))
176190
}
177191
}
178192
})

src/components/Stepper.vue

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,14 @@
4747
/>
4848

4949
<q-step
50-
color="primary"
50+
error-color="negative"
51+
error-icon="warning"
5152
icon=""
5253
name="identifiers"
5354
title="Identifiers"
55+
v-bind:active-icon="isValidScreenIdentifiers.hasError ? 'warning' : 'edit'"
56+
v-bind:color="isValidScreenIdentifiers.hasError ? 'negative' : 'primary'"
57+
v-bind:error="isValidScreenIdentifiers.hasError"
5458
v-bind:order="3"
5559
v-if="showAdvanced"
5660
v-on:click="setStepName('identifiers')"
@@ -137,18 +141,20 @@ import { computed } from 'vue'
137141
import { useCff } from 'src/store/cff'
138142
import { authorsErrors } from 'src/authors-errors'
139143
import { relatedResourcesErrors } from 'src/related-resources-errors'
144+
import { identifiersErrors } from 'src/identifiers-errors'
140145
import { keywordsErrors } from 'src/keywords-errors'
141146
142147
export default {
143148
setup () {
144149
const { showAdvanced, stepName, setStepName } = useApp()
145-
const { authors, keywords } = useCff()
150+
const { authors, identifiers, keywords } = useCff()
146151
return {
147152
isValidScreenAuthors: computed(() => authorsErrors(authors.value)),
153+
isValidScreenIdentifiers: computed(() => identifiersErrors(identifiers.value)),
154+
isValidScreenRelatedResources: computed(relatedResourcesErrors),
148155
isValidScreenStart: computed(() => getMyErrors('', ['message', 'title'])),
149156
isValidScreenKeywords: computed(() => keywordsErrors(keywords.value)),
150157
isValidScreenVersionSpecific: computed(() => getMyErrors('/date-released')),
151-
isValidScreenRelatedResources: computed(relatedResourcesErrors),
152158
setStepName,
153159
showAdvanced,
154160
stepName

src/identifier-errors.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { getMyErrors } from 'src/store/validator'
2+
3+
export const identifierErrors = (index:number) => {
4+
const myErrors = [
5+
getMyErrors(`/identifiers/${index}`)
6+
]
7+
const myChildrenErrors = [
8+
getMyErrors(`/identifiers/${index}/type`),
9+
getMyErrors(`/identifiers/${index}/value`),
10+
getMyErrors(`/identifiers/${index}/description`)
11+
]
12+
const errors = [...myErrors, ...myChildrenErrors]
13+
return {
14+
hasError: errors.some(result => result.hasError),
15+
messages: errors[0].hasError ? errors[0].messages : []
16+
}
17+
}

src/identifiers-errors.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { IdentifiersType } from 'src/types'
2+
import { getMyErrors } from 'src/store/validator'
3+
import { identifierErrors } from 'src/identifier-errors'
4+
5+
export const identifiersErrors = (identifiers: IdentifiersType) => {
6+
const myErrors = [
7+
getMyErrors('', ['identifiers']),
8+
getMyErrors('/identifiers')
9+
]
10+
const myChildrenErrors = identifiers?.map((_, index) => identifierErrors(index))
11+
const errors = myChildrenErrors === undefined ? myErrors : [...myErrors, ...myChildrenErrors]
12+
return {
13+
hasError: errors.some(result => result.hasError),
14+
messages: errors.map(result => result.messages.join(', '))
15+
}
16+
}

0 commit comments

Comments
 (0)