Skip to content

Commit bed14c2

Browse files
pkp/pkp-lib#10820 Add FormErrorSummary component
1 parent 64a811e commit bed14c2

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

src/components/Form/Form.stories.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Form from './Form.vue';
2+
import FormErrorSummary from './FormErrorSummary.vue';
23
import {useContainerStateManager} from '@/composables/useContainerStateManager';
34
import FormBase from './mocks/form-base';
45
import FormMultilingual from './mocks/form-multilingual';
@@ -126,3 +127,42 @@ export const WithErrors = {
126127

127128
args: {},
128129
};
130+
131+
export const WithErrorSummary = {
132+
render: (args) => ({
133+
components: {PkpForm: Form, FormErrorSummary},
134+
setup() {
135+
const {get, set, components} = useContainerStateManager();
136+
const errors = {
137+
email: ['Please provide a valid email address'],
138+
affiliation: {
139+
en: ['You must enter your affiliation in English.'],
140+
fr_CA: ['You must enter your affiliation in French.'],
141+
ar: ['You must enter your affiliation in Arabic.'],
142+
},
143+
'user-locales': ['You must select at least two options.'],
144+
bio: {
145+
en: ['Please provide a bio statement to accompany your publication.'],
146+
},
147+
country: ['Please select your country.'],
148+
'mailing-address': [
149+
'You must enter a mailing address where you can receive post.',
150+
],
151+
};
152+
set('errorSummary', {
153+
...FormUser,
154+
...args,
155+
errors,
156+
});
157+
return {args, errors, get, set, components};
158+
},
159+
template: `
160+
<FormErrorSummary :errors="errors"/>
161+
<PkpForm v-bind="components.errorSummary" @set="set" />
162+
`,
163+
}),
164+
165+
args: {
166+
showErrorFooter: false,
167+
},
168+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<template>
2+
<div
3+
v-if="errorsCount"
4+
class="inline-flex w-full gap-x-1 rounded border border-s-4 border-attention p-2"
5+
>
6+
<div class="leading-none">
7+
<Icon icon="Error" class="h-5 w-5" :inline="true" />
8+
</div>
9+
<span class="text-lg-normal">
10+
{{ message }}
11+
</span>
12+
</div>
13+
</template>
14+
15+
<script setup>
16+
import {computed} from 'vue';
17+
import Icon from '@/components/Icon/Icon.vue';
18+
19+
const props = defineProps({
20+
errors: {
21+
type: Object,
22+
default: () => {},
23+
},
24+
});
25+
26+
const errorsCount = computed(() => Object.keys(props.errors).length);
27+
28+
const message = computed(() => {
29+
const error = errorsCount.value > 1 ? 'errors' : 'error';
30+
return `${errorsCount.value} ${error} detected! Please correct the following ${error} before proceeding.`;
31+
});
32+
</script>

0 commit comments

Comments
 (0)