diff --git a/src/components/Container/PageOJS.vue b/src/components/Container/PageOJS.vue index f13455ad5..dd798b54e 100644 --- a/src/components/Container/PageOJS.vue +++ b/src/components/Container/PageOJS.vue @@ -2,13 +2,11 @@ import Page from '@/components/Container/Page.vue'; import SubmissionsPage from '@/pages/submissions/SubmissionsPage.vue'; import UserInvitationPage from '@/pages/userInvitation/UserInvitationPage.vue'; -import AcceptInvitationPage from '@/pages/acceptInvitation/AcceptInvitationPage.vue'; export default { components: { SubmissionsPage, UserInvitationPage, - AcceptInvitationPage, }, extends: Page, }; diff --git a/src/composables/useForm.js b/src/composables/useForm.js index 0cdd654cb..6f20cb74b 100644 --- a/src/composables/useForm.js +++ b/src/composables/useForm.js @@ -32,6 +32,7 @@ function mapFromSelectedToValue(selected) { export function useForm(_form) { const form = ref(_form); + console.log(form.value); function connectWithPayload(payload) { watch( @@ -49,6 +50,20 @@ export function useForm(_form) { ); } + function setErrors(errors, validateFields) { + watch( + errors, + (newErrors) => { + Object.keys(newErrors).forEach((key) => { + if (validateFields.includes(key)) { + form.value.errors[key] = newErrors[key]; + } + }); + }, + {immediate: true}, + ); + } + function set(key, data) { Object.keys(data).forEach(function (dataKey) { form.value[dataKey] = data[dataKey]; @@ -109,5 +124,6 @@ export function useForm(_form) { clearForm, form, connectWithPayload, + setErrors, }; } diff --git a/src/pages/acceptInvitation/AcceptInvitationCreateUserAccount.vue b/src/pages/acceptInvitation/AcceptInvitationCreateUserAccount.vue deleted file mode 100644 index 03de14e38..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationCreateUserAccount.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationCreateUserForms.vue b/src/pages/acceptInvitation/AcceptInvitationCreateUserForms.vue deleted file mode 100644 index a96b44ede..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationCreateUserForms.vue +++ /dev/null @@ -1,20 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationHeader.vue b/src/pages/acceptInvitation/AcceptInvitationHeader.vue deleted file mode 100644 index f67629358..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationHeader.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationPage.mdx b/src/pages/acceptInvitation/AcceptInvitationPage.mdx deleted file mode 100644 index 6e6766ee3..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationPage.mdx +++ /dev/null @@ -1,9 +0,0 @@ -import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks'; - -import * as AcceptInvitationPage from './AcceptInvitationPage.stories.js'; - - - -# User Invitation page - - diff --git a/src/pages/acceptInvitation/AcceptInvitationPage.stories.js b/src/pages/acceptInvitation/AcceptInvitationPage.stories.js deleted file mode 100644 index 5a5662db4..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationPage.stories.js +++ /dev/null @@ -1,28 +0,0 @@ -import AcceptInvitationPage from './AcceptInvitationPage.vue'; -import {http, HttpResponse} from 'msw'; -import PageInitConfigMock from './mocks/pageInitConfig'; - -export default { - title: 'Pages/AcceptInvitation', - component: AcceptInvitationPage, -}; - -export const Init = { - render: (args) => ({ - components: {AcceptInvitationPage}, - setup() { - return {args}; - }, - template: '', - }), - parameters: { - msw: { - handlers: [ - http.post('https://mock/index.php/publicknowledge/api/v1/users', () => { - return HttpResponse.json('accept invitation successfully'); - }), - ], - }, - }, - args: PageInitConfigMock, -}; diff --git a/src/pages/acceptInvitation/AcceptInvitationPage.vue b/src/pages/acceptInvitation/AcceptInvitationPage.vue deleted file mode 100644 index 6b09ed46a..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationPage.vue +++ /dev/null @@ -1,407 +0,0 @@ - - - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationPageStore.js b/src/pages/acceptInvitation/AcceptInvitationPageStore.js deleted file mode 100644 index bb641edee..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationPageStore.js +++ /dev/null @@ -1,519 +0,0 @@ -import {useTranslation} from '@/composables/useTranslation'; - -import {defineComponentStore} from '@/utils/defineComponentStore'; -import {useFetch} from '@/composables/useFetch'; -import {computed, onMounted, ref, watch} from 'vue'; -//let pageInitConfig = null; - -/*export function initSubmissionsPageStore(_pageInitConfig) { - pageInitConfig = _pageInitConfig; -} - -export function disposeSubmissionsPageStore() { - const store = useSubmissionsPageStore(); - store.$dispose(); - pageInitConfig = null; - delete getActivePinia().state.value[store.$id]; -}*/ - -export const useAcceptInvitationPageStore = defineComponentStore( - 'userInvitationPage', - (pageInitConfig) => { - /** - * Translation - */ - - const {t} = useTranslation(); - - const currentStepId = ref(pageInitConfig.steps[0].id); - const steps = ref(pageInitConfig.steps); - const pageTitleDescription = ref(pageInitConfig.pageTitleDescription); - const errors = ref({}); - const startedSteps = ref([]); - const isModalOpened = ref(false); - const reviewSteps = ref([]); - - const emailField = ref({ - label: t('user.email'), - name: 'email', - size: 'large', - value: '', - allErrors: {}, - }); - - const usernameField = ref({ - label: t('user.username'), - name: 'username', - size: 'large', - value: '', - allErrors: {}, - }); - const passwordField = ref({ - label: t('user.password'), - name: 'password', - size: 'large', - value: '', - inputType: 'password', - allErrors: {}, - }); - const password = ref(''); - const username = ref(''); - const user = ref(''); - const email = ref(pageInitConfig.userEmail); - emailField.value.value = email; - - /** - * The currently active step - */ - const currentStep = computed(() => { - return steps.value.find((step) => step.id === currentStepId.value); - }); - - /** - * The index of the currently active step - * in the steps array - */ - const currentStepIndex = computed(() => { - return steps.value.findIndex((step) => step.id === currentStepId.value); - }); - - /** - * Is the current step the first step? - */ - const isOnFirstStep = computed(() => { - return !currentStepIndex.value; - }); - - /** - * Is the current step the last step? - */ - const isOnLastStep = computed(() => { - return currentStepIndex.value === steps.value.length - 1; - }); - - /** - * Are there any validation errors? - */ - const isValid = computed(() => { - return Object.keys(errors.value).length === 0; - }); - /** - * The title to show at the top of the page - */ - const pageTitle = computed(() => { - if (!currentStep.value) { - return ''; - } - return currentStep.value.name.replace('{$step}', currentStep.value); - }); - - /** - * The step title to show at the top of the step - */ - const stepTitle = computed(() => { - if (!currentStep.value) { - return ''; - } - return currentStep.value.stepName.replace( - '{$step}', - 'STEP ' + (1 + currentStepIndex.value), - ); - }); - - /** - * The step next button name - */ - const stepButtonTitle = computed(() => { - if (!currentStep.value) { - return ''; - } - return currentStep.value.stepButtonName; - }); - - /** - * accept invitation request - */ - const updateUserRequestBody = computed(() => { - const reqBody = { - username: username.value, - password: password.value, - email: email.value, - invitationId: pageInitConfig.invitationId, - invitationKey: pageInitConfig.invitationKey, - }; - steps.value.forEach((step) => { - step.sections.forEach((section) => { - if (section.type === 'form' || section.length > 0) { - section.form.fields.forEach((field) => { - reqBody[field.name] = field.value; - }); - } - }); - }); - - return reqBody; - }); - - /** - * Update when the step changes - */ - watch(currentStepIndex, async (newVal, oldVal) => { - if (newVal === oldVal) { - return; - } - - // Update the list of steps that have been started - steps.value.forEach((step, i) => { - if ( - !startedSteps.value.includes(step.id) && - i <= currentStepIndex.value - ) { - startedSteps.value.push(step.id); - } - }); - - // Track step changes in the title and browser history - const step = steps.value[newVal]; - // document.title = this.getPageTitle(step); - if (step.id !== window.location.hash.replace('#', '')) { - addHistory(step); - } - - // Trigger validation on the review step - if (newVal === steps.value.length - 1) { - validateOnServer(steps.value[currentStepIndex.value].id); - } - }); - - /** - * Set form data when validation errors are changed - */ - watch(errors, async (newVal, oldVal) => { - const keys = Object.keys(newVal); - steps.value.forEach((step, stepIndex) => { - step.sections.forEach((section, sectionIndex) => { - if (section.type === 'form') { - section.form.fields.forEach((field) => { - if (keys.includes(field.name)) { - steps.value[stepIndex].sections[sectionIndex].form.errors = { - ...steps.value[stepIndex].sections[sectionIndex].form.errors, - ...{[field.name]: newVal[field.name]}, - }; - } - }); - } - }); - }); - }); - - onMounted(() => { - /** - * Open the correct step when the page is loaded - */ - if (!window.location.hash) { - openStep(steps.value[0].id); - } - }); - - function passwordChange(fieldName, propName, newValue, localeKey) { - password.value = newValue; - passwordField.value.value = newValue; - passwordField.value.allErrors = {}; - } - function usernameChange(fieldName, propName, newValue, localeKey) { - username.value = newValue; - usernameField.value.value = newValue; - usernameField.value.allErrors = {}; - } - - function emailChange(fieldName, propName, newValue, localeKey) { - email.value = newValue; - email.value.value = newValue; - email.value.allErrors = {}; - } - /** - * Add a step change to the browser history so the - * user can use the browser's back button - * - * @param {Object} step The step to add - */ - function addHistory(step) { - window.history.pushState({}, step.name, '#' + step.id); - } - - /** - * Go to the next step or submit if this is the last step - */ - function nextStep() { - if (!validateOnClient(steps.value[currentStepIndex.value].id)) { - return; - } - if (isOnLastStep.value) { - submit(); - } else { - openStep(steps.value[1 + currentStepIndex.value].id); - } - } - - /** - * Go to a step in the wizard - * - * @param {String} stepId - */ - function openStep(stepId) { - const newStep = steps.value.find((step) => step.id === stepId); - if (!newStep) { - return; - } - currentStepId.value = stepId; - } - - /** - * Go to the previous step in the wizard - */ - function previousStep() { - const previousIndex = currentStepIndex.value - 1; - if (previousIndex >= 0) { - openStep(steps.value[previousIndex].id); - } - } - - /** - * Validate the user details - * - * Always wait for autosaves to complete before - * trying to validate - */ - function validateOnClient(stepId) { - let isValidate = true; - usernameField.value.allErrors = {}; - passwordField.value.allErrors = {}; - emailField.value.allErrors = {}; - if (stepId === 'userCreate') { - if (username.value === '') { - usernameField.value.allErrors.username = [t('validator.required')]; - isValidate = false; - } - if (password.value === '') { - passwordField.value.allErrors.password = [t('validator.required')]; - isValidate = false; - } - if (email.value === '') { - emailField.value.allErrors.email = [t('validator.required')]; - isValidate = false; - } - } - if (stepId === 'userDetails') { - const formErrors = {}; - steps.value.forEach((step, stepIndex) => { - step.sections.forEach((section, sectionIndex) => { - if (section.type === 'form') { - section.form.fields.forEach((field) => { - if ( - (field.value === '' || field.value === null) && - field.isRequired - ) { - formErrors[field.name] = [t('validator.required')]; - isValidate = false; - } - }); - } - }); - }); - errors.value = formErrors; - } - - return isValidate; - } - /** - * Validate the user details - * - * Always wait for autosaves to complete before - * trying to validate - */ - async function validateOnServer(stepId) { - let isValidate = true; - updateUserRequestBody.value['_validateOnly'] = true; - const { - data: res, - validationError, - fetch, - } = useFetch(pageInitConfig.userApiUrl + '/' + user.value.id, { - expectValidationError: true, - method: 'PUT', - body: updateUserRequestBody.value, - }); - await fetch(); - steps.value.forEach((step) => { - if (step.id !== 'userCreate') { - return; - } - step.reviewData[0] = { - username: username.value, - password: password.value, - email: email.value, - }; - }); - if (validationError.value) { - isValidate = false; - errors.value = validationError.value; - } else if (res.value && !validationError.value) { - errors.value = {}; - } - return isValidate; - } - - /** - * Update an autosave form - * - * @param {String} formId - * @param {Object} data - */ - function updateAutosaveForm(formId, data) { - updateForm(formId, data); - } - - /** - * Complete the submission - * - * Opens a confirmation dialog and then makes the submission - * request with any required confirmation fields - */ - async function submit() { - if (pageInitConfig.userId) { - const { - data: res, - validationError, - fetch, - } = useFetch(pageInitConfig.acceptInvitationApiUrl, { - expectValidationError: true, - method: 'PUT', - body: {invitationKey: pageInitConfig.invitationKey}, - }); - await fetch(); - if (validationError.value) { - errors.value = validationError.value; - } else if (res.value && !validationError.value) { - errors.value = {}; - isModalOpened.value = true; - } - } else { - delete updateUserRequestBody.value._validateOnly; - const { - data: res, - validationError, - fetch, - } = useFetch(pageInitConfig.userApiUrl + '/' + user.value.id, { - expectValidationError: true, - method: 'PUT', - body: updateUserRequestBody.value, - }); - await fetch(); - if (validationError.value) { - errors.value = validationError.value; - } else if (res.value && !validationError.value) { - errors.value = {}; - isModalOpened.value = true; - } - } - } - - /** - * Update a form with new data - * - * This is fired every time a form field changes, so - * resource-intensive code should not be run every - * time this method is called. - * - * @param {String} formId - * @param {Object} data - */ - function updateForm(formId, data) { - steps.value.forEach((step, stepIndex) => { - step.sections.forEach((section, sectionIndex) => { - if (section.type !== 'form' || section.form.id !== formId) { - return; - } - steps.value[stepIndex].sections[sectionIndex].form = { - ...steps.value[stepIndex].sections[sectionIndex].form, - ...data, - }; - }); - }); - } - /** - * Complete the submission - * - * Opens a confirmation dialog and then makes the submission - * request with any required confirmation fields - */ - // async function searchUser() { - // } - - /** - * Update the data attached to a step - * - * @param {String} stepId The id of the step to update - * @param {Object} data The data to update in the step - */ - function updateStep(stepId, data) { - steps.value.forEach((step, stepIndex) => { - step.sections.forEach((section, sectionIndex) => { - if (section.type !== 'email') { - return; - } - let errors = {...step.sections.errors}; - Object.keys(data).forEach((key) => delete errors[key]); - steps.value[stepIndex].sections[sectionIndex].email = { - ...steps.value[stepIndex].sections[sectionIndex].email, - ...data, - errors: errors, - }; - }); - }); - } - - /** - * Close modal popup - */ - function isModalClosed() { - isModalOpened.value = false; - } - - return { - //computed - currentStep, - currentStepIndex, - isOnFirstStep, - isOnLastStep, - isValid, - pageTitle, - startedSteps, - stepTitle, - openStep, - steps, - pageTitleDescription, - errors, - reviewSteps, - stepButtonTitle, - - //form feilds - passwordField, - usernameField, - passwordChange, - usernameChange, - emailField, - emailChange, - - //methods - nextStep, - previousStep, - updateStep, - updateAutosaveForm, - - //modal - isModalOpened, - isModalClosed, - }; - }, -); diff --git a/src/pages/acceptInvitation/AcceptInvitationReview.vue b/src/pages/acceptInvitation/AcceptInvitationReview.vue deleted file mode 100644 index f4db20d59..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationReview.vue +++ /dev/null @@ -1,212 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationUserRoles.vue b/src/pages/acceptInvitation/AcceptInvitationUserRoles.vue deleted file mode 100644 index 085faf365..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationUserRoles.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/AcceptInvitationVerifyOrcid.vue b/src/pages/acceptInvitation/AcceptInvitationVerifyOrcid.vue deleted file mode 100644 index 2a7cf97d3..000000000 --- a/src/pages/acceptInvitation/AcceptInvitationVerifyOrcid.vue +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/src/pages/acceptInvitation/mocks/pageInitConfig.js b/src/pages/acceptInvitation/mocks/pageInitConfig.js deleted file mode 100644 index ab2b0f14e..000000000 --- a/src/pages/acceptInvitation/mocks/pageInitConfig.js +++ /dev/null @@ -1,204 +0,0 @@ -export default { - acceptInvitationApiUrl: 'https://mock/index.php/publicknowledge/api/v1/users', - primaryLocale: 'en', - pageTitle: 'Invite user to take a role', - pageTitleDescription: - 'You are inviting a user to take a role in OJS along with appearing in the journal masthead', - csrfToken: '3e964b3403ec2daf5d595121b888ab4c', - invitationId: 65, - invitationKey: '8aqc3W', - steps: [ - { - id: 'verifyOrcid', - name: 'Verify ORCID iD', - reviewName: '', - stepName: '{$step} - Verify ORCID iD', - type: 'popup', - description: 'Please verify orcid iD', - sections: [ - { - id: 'userVerifyOrcid', - sectionComponent: 'AcceptInvitationVerifyOrcid', - }, - ], - }, - { - id: 'userCreate', - name: 'Create OJS account', - reviewName: 'Account details', - stepName: '{$step} - Create OJS account', - type: 'form', - description: - 'To get started with OJS and accept the new role, you will need to create an account with us. For this purpose please enter a username and password.', - sections: [ - { - id: 'userCreateForm', - sectionComponent: 'AcceptInvitationCreateUserAccount', - }, - ], - reviewData: [], - }, - { - id: 'userDetails', - name: 'Enter details', - reviewName: 'User Details', - stepName: '{$step} - Enter details', - type: 'form', - description: - 'Enter your details like email ID, affiliation ect. As per the GDPR compliance, this information can only modified by you. You can also choose if you want this information to be visible on your profile to the editor. ', - sections: [ - { - id: 'userCreateDetailsForm', - type: 'form', - description: - '

Please provide the following details to help us manage your submission in our system.

', - form: { - id: 'userDetails', - method: 'POST', - action: - 'http://localhost/ojs/index.php/publicknowledge/api/v1/users', - fields: [ - { - name: 'email', - component: 'field-text', - label: 'Email address', - groupId: 'default', - isRequired: true, - isMultilingual: false, - value: 'test@mailinator.com', - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - { - name: 'orcid', - component: 'field-text', - label: 'ORCID iD', - groupId: 'default', - isRequired: false, - isMultilingual: false, - value: null, - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - { - name: 'givenName', - component: 'field-text', - label: 'Given Name', - groupId: 'default', - isRequired: true, - isMultilingual: false, - value: null, - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - { - name: 'familyName', - component: 'field-text', - label: 'Family Name', - groupId: 'default', - isRequired: true, - isMultilingual: false, - value: null, - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - { - name: 'affiliation', - component: 'field-text', - label: 'Affiliation', - groupId: 'default', - isRequired: true, - isMultilingual: false, - value: null, - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - { - name: 'country', - component: 'field-text', - label: 'County of affiliation', - groupId: 'default', - isRequired: true, - isMultilingual: false, - value: null, - inputType: 'text', - optIntoEdit: false, - optIntoEditLabel: '', - size: 'large', - prefix: '', - }, - ], - groups: [ - { - id: 'default', - pageId: 'default', - }, - ], - hiddenFields: {}, - pages: [ - { - id: 'default', - submitButton: { - label: 'Save', - }, - }, - ], - primaryLocale: 'en', - visibleLocales: ['en'], - supportedFormLocales: [ - { - key: 'en', - label: 'English', - }, - { - key: 'fr_CA', - label: 'French', - }, - ], - errors: {}, - }, - sectionComponent: 'AcceptInvitationCreateUserForms', - }, - ], - }, - { - id: 'userCreateReview', - name: 'Review & create account', - reviewName: 'Roles', - stepName: '{$step} - Review & create account', - type: 'review', - description: 'Review details to start your new roles in OJS', - sections: [ - { - id: 'userCreateRoles', - sectionComponent: 'AcceptInvitationReview', - type: 'table', - description: '', - rows: [ - { - date_start: '2024-03-01', - date_end: '2025-01-01', - user_group_id: 3, - setting_value: 'test', - }, - ], - }, - ], - }, - ], -}; diff --git a/src/pages/invitations/InvitationsPage.vue b/src/pages/invitations/InvitationsPage.vue deleted file mode 100755 index 5e64544ad..000000000 --- a/src/pages/invitations/InvitationsPage.vue +++ /dev/null @@ -1,89 +0,0 @@ - - - - diff --git a/src/pages/invitations/InvitationsPageStore.js b/src/pages/invitations/InvitationsPageStore.js deleted file mode 100755 index efcb96d73..000000000 --- a/src/pages/invitations/InvitationsPageStore.js +++ /dev/null @@ -1,84 +0,0 @@ -import {useTranslation} from '@/composables/useTranslation'; -import {defineComponentStore} from '@/utils/defineComponentStore'; -import {useApiUrl} from '@/composables/useApiUrl'; -import {useUrl} from '@/composables/useUrl'; -import {useFetch} from '@/composables/useFetch'; -import {useAnnouncer} from '@/composables/useAnnouncer'; -import {computed, ref, watch} from 'vue'; -//let pageInitConfig = null; - -/*export function initSubmissionsPageStore(_pageInitConfig) { - pageInitConfig = _pageInitConfig; -} - -export function disposeSubmissionsPageStore() { - const store = useSubmissionsPageStore(); - store.$dispose(); - pageInitConfig = null; - delete getActivePinia().state.value[store.$id]; -}*/ - -export const useInvitationsPageStore = defineComponentStore( - 'invitationsPage', - (pageInitConfig) => { - /** - * Translation - */ - - const {t} = useTranslation(); - - /** Announcer */ - - const {announce} = useAnnouncer(); - const pageTitle = ref(null); - const invitationCount = ref(0); - - const currentPage = ref(1); - function setCurrentPage(_currentPage) { - currentPage.value = _currentPage; - } - - const {apiUrl} = useApiUrl('invitations'); - const getInvitationApiUrl = computed(() => { - return apiUrl.value; - }); - - const {pageUrl} = useUrl('management/settings/invitations'); - const sendInvitationPageUrl = computed(() => { - return pageUrl.value; - }); - - function sendInvitation() { - window.location = sendInvitationPageUrl.value; - } - const { - data: invitations, - isLoading: isInvitationLoading, - fetch: fetchInvitation, - } = useFetch(getInvitationApiUrl, { - query: {page: currentPage}, - }); - watch( - [currentPage], - async () => { - announce(t('common.loading')); - - await fetchInvitation(); - announce(t('common.loaded')); - console.log(invitations.value); - }, - {immediate: true}, - ); - - return { - pageTitle, - invitationCount, - setCurrentPage, - sendInvitation, - currentPage, - // invitation table data - invitations, - isInvitationLoading, - }; - }, -); diff --git a/src/pages/userInvitation/UserInvitationDetailsFormStep.vue b/src/pages/userInvitation/UserInvitationDetailsFormStep.vue index e2f806240..4cb17773a 100644 --- a/src/pages/userInvitation/UserInvitationDetailsFormStep.vue +++ b/src/pages/userInvitation/UserInvitationDetailsFormStep.vue @@ -1,44 +1,46 @@