Skip to content

Commit aa76018

Browse files
authored
Merge pull request #529 from citation-file-format/filter-errors
Filter errors with standard JS and Vue3 lifecycle hooks
2 parents 1c30f04 + d29975f commit aa76018

20 files changed

Lines changed: 547 additions & 96 deletions

src/components/AuthorCardEditing.vue

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@
105105
title="The person's email address."
106106
type="email"
107107
v-bind:model-value="email"
108-
v-bind:error="false"
109-
v-bind:error-message="''"
108+
v-bind:class="emailErrors.length > 0 ? 'has-error' : ''"
109+
v-bind:error="emailErrors.length > 0"
110+
v-bind:error-message="emailErrors.join(', ')"
110111
v-on:update:modelValue="$emit('update', 'email', $event)"
111112
/>
112113
</div>
@@ -143,9 +144,10 @@
143144
outlined
144145
standout
145146
title="The person's ORCID identifier."
147+
v-bind:class="orcidErrors.length > 0 ? 'has-error' : ''"
146148
v-bind:model-value="orcid"
147-
v-bind:error="false"
148-
v-bind:error-message="''"
149+
v-bind:error="orcidErrors.length > 0"
150+
v-bind:error-message="orcidErrors.join(', ')"
149151
v-on:update:modelValue="$emit('update', 'orcid', $event)"
150152
/>
151153
</div>
@@ -185,9 +187,11 @@
185187
</template>
186188

187189
<script lang="ts">
188-
/* eslint-disable @typescript-eslint/restrict-template-expressions */
189-
import { defineComponent, ref } from 'vue'
190+
import { computed, defineComponent, onUpdated } from 'vue'
190191
import SchemaGuideLink from './SchemaGuideLink.vue'
192+
import { useValidation } from 'src/store/validation'
193+
import { byError, emailQueries, orcidQueries } from 'src/error-filtering'
194+
import { useStepperErrors } from 'src/store/stepper-errors'
191195
192196
export default defineComponent({
193197
name: 'AuthorCardEditing',
@@ -229,10 +233,25 @@ export default defineComponent({
229233
default: 0
230234
}
231235
},
232-
setup () {
233-
const givenNamesRef = ref<HTMLElement | null>(null)
236+
setup (props) {
237+
onUpdated(() => {
238+
const { setErrorStateScreenAuthors } = useStepperErrors()
239+
setErrorStateScreenAuthors(document.getElementsByClassName('has-error').length > 0)
240+
})
241+
const { errors } = useValidation()
242+
const orcidErrors = computed(() => {
243+
return orcidQueries(props.index)
244+
.filter(byError(errors.value))
245+
.map(query => query.replace.message)
246+
})
247+
const emailErrors = computed(() => {
248+
return emailQueries(props.index)
249+
.filter(byError(errors.value))
250+
.map(query => query.replace.message)
251+
})
234252
return {
235-
givenNamesRef
253+
emailErrors,
254+
orcidErrors
236255
}
237256
},
238257
emits: ['closePressed', 'removePressed', 'update', 'moveUp', 'moveDown'],

src/components/AuthorCardViewing.vue

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<q-card
33
bordered
4-
v-bind:class="['bg-formcard', false ? 'red-border' : '']"
4+
v-bind:class="['bg-formcard', authorErrors.length > 0 ? 'red-border has-error' : '']"
55
flat
66
style="display: flex; flex-direction: row"
77
>
@@ -43,8 +43,11 @@
4343
</template>
4444

4545
<script lang="ts">
46-
import { defineComponent, PropType } from 'vue'
46+
import { computed, defineComponent, onUpdated, PropType } from 'vue'
4747
import { AuthorType } from 'src/types'
48+
import { useStepperErrors } from 'src/store/stepper-errors'
49+
import { useValidation } from 'src/store/validation'
50+
import { byError, emailQueries, orcidQueries } from 'src/error-filtering'
4851
4952
export default defineComponent({
5053
name: 'AuthorCardViewing',
@@ -62,6 +65,27 @@ export default defineComponent({
6265
default: 0
6366
}
6467
},
68+
setup (props) {
69+
onUpdated(() => {
70+
const { setErrorStateScreenAuthors } = useStepperErrors()
71+
setErrorStateScreenAuthors(document.getElementsByClassName('has-error').length > 0)
72+
})
73+
const { errors } = useValidation()
74+
const emailErrors = computed(() => {
75+
return emailQueries(props.index)
76+
.filter(byError(errors.value))
77+
.map(query => query.replace.message)
78+
})
79+
const orcidErrors = computed(() => {
80+
return orcidQueries(props.index)
81+
.filter(byError(errors.value))
82+
.map(query => query.replace.message)
83+
})
84+
const authorErrors = [...emailErrors.value, ...orcidErrors.value]
85+
return {
86+
authorErrors
87+
}
88+
},
6589
emits: ['editPressed', 'moveDown', 'moveUp']
6690
})
6791
</script>

src/components/IdentifierCardEditing.vue

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
<q-option-group
1010
inline
1111
type="radio"
12-
v-bind:error="false"
13-
v-bind:error-message="''"
1412
v-bind:model-value="type"
1513
v-bind:options="typeOptions"
1614
v-on:update:modelValue="$emit('updateType', 'type', $event)"
@@ -30,8 +28,9 @@
3028
outlined
3129
standout
3230
dense
33-
v-bind:error="false"
34-
v-bind:error-message="''"
31+
v-bind:class="identifierValueErrors.length > 0 ? 'has-error' : ''"
32+
v-bind:error="identifierValueErrors.length > 0"
33+
v-bind:error-message="identifierValueErrors.join(', ')"
3534
v-bind:model-value="value"
3635
v-on:update:modelValue="$emit('updateValue', 'value', $event)"
3736
ref="valueRef"
@@ -50,8 +49,6 @@
5049
outlined
5150
standout
5251
dense
53-
v-bind:error="false"
54-
v-bind:error-message="''"
5552
v-bind:model-value="description"
5653
v-on:update:modelValue="$emit('updateDescription', 'description', $event)"
5754
/>
@@ -93,8 +90,10 @@
9390

9491
<script lang="ts">
9592
import { IdentifierTypeType } from '../types'
96-
import { computed, defineComponent, PropType, ref } from 'vue'
93+
import { computed, defineComponent, PropType } from 'vue'
9794
import SchemaGuideLink from 'src/components/SchemaGuideLink.vue'
95+
import { byError, identifierValueQueries } from 'src/error-filtering'
96+
import { useValidation } from 'src/store/validation'
9897
9998
export default defineComponent({
10099
name: 'IdentifierCardEditing',
@@ -124,6 +123,7 @@ export default defineComponent({
124123
SchemaGuideLink
125124
},
126125
setup (props) {
126+
const { errors } = useValidation()
127127
const linkInfo = {
128128
doi: { label: 'DOI', anchor: '#definitionsdoi' },
129129
url: { label: 'URL', anchor: '#definitionsurl' },
@@ -133,17 +133,21 @@ export default defineComponent({
133133
},
134134
other: { label: 'identifier', anchor: '#definitionsidentifier' }
135135
}
136-
const valueRef = ref<HTMLElement | null>(null)
136+
const identifierValueErrors = computed(() => {
137+
return identifierValueQueries(props.index, ['doi', 'url', 'swh', 'other'].indexOf(props.type))
138+
.filter(byError(errors.value))
139+
.map(query => query.replace.message)
140+
})
137141
return {
138-
valueRef,
139142
typeOptions: [
140143
{ label: 'DOI', value: 'doi' },
141144
{ label: 'URL', value: 'url' },
142145
{ label: 'Software Heritage', value: 'swh' },
143146
{ label: 'Other', value: 'other' }
144147
],
145148
label: computed(() => linkInfo[props.type].label),
146-
anchor: computed(() => linkInfo[props.type].anchor)
149+
anchor: computed(() => linkInfo[props.type].anchor),
150+
identifierValueErrors
147151
}
148152
},
149153
emits: [

src/components/IdentifierCardViewing.vue

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<q-card
33
bordered
4-
v-bind:class="['bg-formcard', false ? 'red-border' : '']"
4+
v-bind:class="['bg-formcard', identifierValueErrors.length > 0 ? 'red-border has-error' : '']"
55
flat
66
style="display: flex; flex-direction: row"
77
>
@@ -42,8 +42,10 @@
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 { useValidation } from 'src/store/validation'
48+
import { byError, identifierValueQueries } from 'src/error-filtering'
4749
4850
export default defineComponent({
4951
name: 'IdentifierCardViewing',
@@ -61,6 +63,17 @@ export default defineComponent({
6163
default: 0
6264
}
6365
},
66+
setup (props) {
67+
const { errors } = useValidation()
68+
const identifierValueErrors = computed(() => {
69+
return identifierValueQueries(props.index, ['doi', 'url', 'swh', 'other'].indexOf(props.identifier.type))
70+
.filter(byError(errors.value))
71+
.map(query => query.replace.message)
72+
})
73+
return {
74+
identifierValueErrors
75+
}
76+
},
6477
emits: ['editPressed', 'moveDown', 'moveUp']
6578
})
6679
</script>

src/components/Keyword.vue

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
dense
88
outlined
99
placeholder="Type a keyword"
10+
v-bind:class="keywordErrors.length > 0 ? 'has-error' : ''"
1011
v-bind:model-value="keyword"
11-
v-bind:error="false"
12-
v-bind:error-message="''"
12+
v-bind:error="keywordErrors.length > 0"
13+
v-bind:error-message="keywordErrors.join(', ')"
1314
v-on:update:modelValue="$emit('update', $event)"
1415
ref="keywordRef"
1516
/>
@@ -43,10 +44,12 @@
4344
</template>
4445

4546
<script lang="ts">
46-
import { defineComponent, ref } from 'vue'
47+
import { computed, defineComponent } from 'vue'
48+
import { useValidation } from 'src/store/validation'
49+
import { byError, keywordQueries } from 'src/error-filtering'
4750
4851
export default defineComponent({
49-
name: 'KeywordCard',
52+
name: 'Keyword',
5053
props: {
5154
keyword: {
5255
type: String,
@@ -61,10 +64,15 @@ export default defineComponent({
6164
default: 0
6265
}
6366
},
64-
setup () {
65-
const keywordRef = ref<HTMLElement | null>(null)
67+
setup (props) {
68+
const { errors } = useValidation()
69+
const keywordErrors = computed(() => {
70+
return keywordQueries(props.index)
71+
.filter(byError(errors.value))
72+
.map(query => query.replace.message)
73+
})
6674
return {
67-
keywordRef
75+
keywordErrors
6876
}
6977
},
7078
emits: ['moveDown', 'moveUp', 'removePressed', 'update']

src/components/Preview.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,30 @@
3030
</q-btn>
3131
</div>
3232
<textarea
33-
v-bind:class="['cffstr', true ? '' : 'error']"
33+
v-bind:class="['cffstr', isValidCFF ? '' : 'error']"
3434
readonly="true"
3535
v-bind:value="cffstr"
3636
wrap="hard"
3737
/>
3838
<div class="validation-msg">
39-
<p v-bind:class="true ? '' : 'invalid'">
40-
Your CITATION.cff is {{ true ? "valid" : "not valid" }}
39+
<p v-bind:class="isValidCFF ? '' : 'invalid'">
40+
Your CITATION.cff is {{ isValidCFF ? "valid" : "not valid" }}
4141
</p>
4242
</div>
4343
</template>
4444

4545
<script lang="ts">
46-
import { defineComponent, ref } from 'vue'
46+
import { computed, defineComponent, ref } from 'vue'
4747
import { useCffstr } from 'src/store/cffstr'
48+
import { useValidation } from 'src/store/validation'
4849
4950
export default defineComponent({
5051
name: 'Preview',
5152
components: {
5253
},
5354
setup () {
5455
const { cffstr } = useCffstr()
56+
const { errors } = useValidation()
5557
const showTooltip = ref(false)
5658
5759
const copyToClipboard = async () => {
@@ -64,6 +66,7 @@ export default defineComponent({
6466
return {
6567
cffstr,
6668
copyToClipboard,
69+
isValidCFF: computed(() => errors.value.length === 0),
6770
showTooltip
6871
}
6972
}

src/components/ScreenAbstract.vue

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
standout
2525
type="textarea"
2626
v-bind:model-value="abstract"
27-
v-bind:error="false"
28-
v-bind:error-message="''"
2927
v-on:update:modelValue="setAbstract"
3028
/>
3129
</div>

0 commit comments

Comments
 (0)