From e2b7aab32716b8ffcc9f04e6c34b815e52260bb9 Mon Sep 17 00:00:00 2001 From: ipula Date: Mon, 12 Aug 2024 23:46:12 +0200 Subject: [PATCH] invitation table view and api integration --- public/globals.js | 6 +- src/components/Container/PageOJS.vue | 2 - .../InvitationManager/InvitationManager.mdx} | 4 +- .../InvitationManager.stories.js | 42 +++++++ .../InvitationManager/InvitationManager.vue | 108 ++++++++++++++++++ .../InvitationManagerStore.js} | 62 ++++++---- .../InvitationManager/mocks/invitationMock.js | 89 +++++++++++++++ .../AcceptInvitationPage.stories.js | 14 +-- .../acceptInvitation/AcceptInvitationPage.vue | 5 +- .../AcceptInvitationPageStore.js | 25 ++-- .../AcceptInvitationReview.vue | 2 +- .../AcceptInvitationUserAccountDetails.vue | 2 +- .../AcceptInvitationUserDetailsForms.vue | 2 +- .../AcceptInvitationUserRoles.vue | 2 +- .../mocks/invitationNewUserMock.js | 84 ++++++++++---- .../invitationUserNotVerifiedOrcidMock.js | 84 ++++++++++---- .../mocks/invitationUserVerifiedOrcidMock.js | 84 ++++++++++---- .../acceptInvitation/mocks/pageInitConfig.js | 16 +-- .../pageInitConfigUserNotVerifiedOrcid.js | 8 +- .../invitation/InvitationPage.stories.js | 34 ------ src/pages/invitation/InvitationPage.vue | 103 ----------------- src/pages/invitation/mocks/invitationMock.js | 92 --------------- .../UserInvitationDetailsFormStep.vue | 16 ++- .../UserInvitationPage.stories.js | 34 +++--- .../userInvitation/UserInvitationPage.vue | 18 ++- .../userInvitation/UserInvitationPageStore.js | 100 ++++++++++++++-- .../UserInvitationSearchFormStep.vue | 10 +- .../UserInvitationUserGroupsTable.vue | 17 ++- .../userInvitation/mocks/pageInitConfig.js | 33 +++--- 29 files changed, 682 insertions(+), 416 deletions(-) rename src/{pages/invitation/InvitationPage.mdx => managers/InvitationManager/InvitationManager.mdx} (52%) create mode 100644 src/managers/InvitationManager/InvitationManager.stories.js create mode 100755 src/managers/InvitationManager/InvitationManager.vue rename src/{pages/invitation/InvitationPageStore.js => managers/InvitationManager/InvitationManagerStore.js} (60%) create mode 100644 src/managers/InvitationManager/mocks/invitationMock.js delete mode 100644 src/pages/invitation/InvitationPage.stories.js delete mode 100755 src/pages/invitation/InvitationPage.vue delete mode 100644 src/pages/invitation/mocks/invitationMock.js diff --git a/public/globals.js b/public/globals.js index fdf576b44..f9faaffa1 100644 --- a/public/globals.js +++ b/public/globals.js @@ -527,8 +527,8 @@ window.pkp = { 'submissions.declined': 'Declined', 'submissions.incomplete': 'Incomplete', todo: '##todo##', - 'user.email': 'Email', - 'user.emailAddress': 'Email Address', + 'about.contact.email': 'Email', + 'user.email': 'Email Address', 'user.orcid': 'ORCID iD', 'user.username': 'Username', 'user.password': 'Password', @@ -563,6 +563,8 @@ window.pkp = { 'invitation.cancel': 'Cancel Invite', 'invitation.inviteToRole.btn': 'Invite to a role', 'invitation.header': 'Invitation', + 'invitation.tableHeader.name': 'Name', + 'invitation.searchForm.emptyError': 'At least provide one search criteria.', }, diff --git a/src/components/Container/PageOJS.vue b/src/components/Container/PageOJS.vue index 11c56e4dc..4e6c19acc 100644 --- a/src/components/Container/PageOJS.vue +++ b/src/components/Container/PageOJS.vue @@ -3,14 +3,12 @@ import Page from '@/components/Container/Page.vue'; import DashboardPage from '@/pages/dashboard/DashboardPage.vue'; import UserInvitationPage from '@/pages/userInvitation/UserInvitationPage.vue'; import AcceptInvitationPage from '@/pages/acceptInvitation/AcceptInvitationPage.vue'; -import InvitationPage from '@/pages/invitation/InvitationPage.vue'; export default { components: { DashboardPage, UserInvitationPage, AcceptInvitationPage, - InvitationPage, }, extends: Page, }; diff --git a/src/pages/invitation/InvitationPage.mdx b/src/managers/InvitationManager/InvitationManager.mdx similarity index 52% rename from src/pages/invitation/InvitationPage.mdx rename to src/managers/InvitationManager/InvitationManager.mdx index 1a3eb6fdd..062fa58bc 100644 --- a/src/pages/invitation/InvitationPage.mdx +++ b/src/managers/InvitationManager/InvitationManager.mdx @@ -1,8 +1,8 @@ import {Primary, Controls, Stories, Meta, ArgTypes} from '@storybook/blocks'; -import * as InvitationPage from './InvitationPage.stories.js'; +import * as InvitationManager from './InvitationManager.stories.js'; - + # Invitation page diff --git a/src/managers/InvitationManager/InvitationManager.stories.js b/src/managers/InvitationManager/InvitationManager.stories.js new file mode 100644 index 000000000..cca93b69d --- /dev/null +++ b/src/managers/InvitationManager/InvitationManager.stories.js @@ -0,0 +1,42 @@ +import InvitationManager from './InvitationManager.vue'; +import {http, HttpResponse} from 'msw'; +import invitationMock from './mocks/invitationMock.js'; + +export default { + title: 'Managers/InvitationManager', + component: InvitationManager, +}; + +export const Init = { + render: (args) => ({ + components: {InvitationManager}, + setup() { + return {args}; + }, + template: '', + }), + parameters: { + msw: { + handlers: [ + http.get( + 'https://mock/index.php/publicknowledge/api/v1/invitations', + async ({request}) => { + const url = new URL(request.url); + const offset = parseInt(url.searchParams.get('offset') || 0); + const count = parseInt(url.searchParams.get('count')); + const invitations = invitationMock.items.slice( + offset, + offset + count, + ); + + return HttpResponse.json({ + itemsMax: invitationMock.itemsMax, + items: invitations, + }); + }, + ), + ], + }, + }, + args: [], +}; diff --git a/src/managers/InvitationManager/InvitationManager.vue b/src/managers/InvitationManager/InvitationManager.vue new file mode 100755 index 000000000..d50baf209 --- /dev/null +++ b/src/managers/InvitationManager/InvitationManager.vue @@ -0,0 +1,108 @@ + + + diff --git a/src/pages/invitation/InvitationPageStore.js b/src/managers/InvitationManager/InvitationManagerStore.js similarity index 60% rename from src/pages/invitation/InvitationPageStore.js rename to src/managers/InvitationManager/InvitationManagerStore.js index 709d9acd2..b58d05951 100755 --- a/src/pages/invitation/InvitationPageStore.js +++ b/src/managers/InvitationManager/InvitationManagerStore.js @@ -1,26 +1,35 @@ -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 {useUrl} from '@/composables/useUrl'; +import {useLocalize} from '@/composables/useLocalize'; +import {useFetchPaginated} from '@/composables/useFetchPaginated'; import {computed, ref, watch} from 'vue'; -export const useInvitationsPageStore = defineComponentStore( +export const useInvitationManagerStore = defineComponentStore( 'invitationsPage', () => { - /** - * Translation - */ - - const {t} = useTranslation(); - + const {t} = useLocalize(); /** Announcer */ const {announce} = useAnnouncer(); - const pageTitle = ref(null); + /** + * redirect to send invitation page + */ + const {pageUrl} = useUrl('invitation/invite'); + const sendInvitationPageUrl = computed(() => { + return pageUrl.value; + }); + function sendInvitation() { + window.location = sendInvitationPageUrl.value; + } + + /** + * get invitations twith paginations + */ const invitationCount = ref(0); + const countPerPage = ref(2); const currentPage = ref(1); function setCurrentPage(_currentPage) { currentPage.value = _currentPage; @@ -30,21 +39,14 @@ export const useInvitationsPageStore = defineComponentStore( 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, + items: invitations, + pagination: invitationsPagination, isLoading: isInvitationLoading, fetch: fetchInvitation, - } = useFetch(getInvitationApiUrl, { - query: {page: currentPage}, + } = useFetchPaginated(getInvitationApiUrl, { + currentPage, + pageSize: countPerPage, }); watch( [currentPage], @@ -57,15 +59,27 @@ export const useInvitationsPageStore = defineComponentStore( {immediate: true}, ); + /** + * create user full name + * @param String givenName + * @param String familyName + * @returns String + */ + function getFullName(givenName, familyName) { + return givenName + ' ' + familyName; + } + return { - pageTitle, invitationCount, setCurrentPage, sendInvitation, currentPage, + invitationsPagination, + pageUrl, // invitation table data invitations, isInvitationLoading, + getFullName, }; }, ); diff --git a/src/managers/InvitationManager/mocks/invitationMock.js b/src/managers/InvitationManager/mocks/invitationMock.js new file mode 100644 index 000000000..aae3a7ffb --- /dev/null +++ b/src/managers/InvitationManager/mocks/invitationMock.js @@ -0,0 +1,89 @@ +export default { + itemsMax: 3, + items: [ + { + invitationModel: { + invitation_id: 44, + user_id: null, + expiry_date: '2024-08-29T14:10:26.000000Z', + status: 'PENDING', + email: 'ipula2@mailinator.com', + context_id: 1, + }, + orcid: null, + givenName: 'asd', + familyName: 'ads', + affiliation: null, + country: null, + username: null, + password: null, + emailSubject: null, + emailBody: null, + existingUser: null, + userGroupsToAdd: [ + { + masthead: true, + dateStart: '2024-07-26', + userGroup: 2, + }, + ], + userGroupsToRemove: [], + }, + { + invitationModel: { + invitation_id: 45, + user_id: null, + expiry_date: '2024-08-29T14:26:09.000000Z', + status: 'PENDING', + email: 'ipula3@mailinator.com', + context_id: 1, + }, + orcid: null, + givenName: 'asd', + familyName: 'asd', + affiliation: null, + country: null, + username: null, + password: null, + emailSubject: null, + emailBody: null, + existingUser: null, + userGroupsToAdd: [ + { + masthead: true, + dateStart: '2024-07-26', + userGroup: 10, + }, + ], + userGroupsToRemove: [], + }, + { + invitationModel: { + invitation_id: 46, + user_id: null, + expiry_date: '2024-08-29T15:46:56.000000Z', + status: 'PENDING', + email: 'ipula4@mailinator.com', + context_id: 1, + }, + orcid: null, + givenName: 'zxc', + familyName: 'sdf', + affiliation: null, + country: null, + username: null, + password: null, + emailSubject: null, + emailBody: null, + existingUser: null, + userGroupsToAdd: [ + { + masthead: true, + dateStart: '2024-07-26', + userGroup: 2, + }, + ], + userGroupsToRemove: [], + }, + ], +}; diff --git a/src/pages/acceptInvitation/AcceptInvitationPage.stories.js b/src/pages/acceptInvitation/AcceptInvitationPage.stories.js index b76cb54bb..8b70a5b49 100644 --- a/src/pages/acceptInvitation/AcceptInvitationPage.stories.js +++ b/src/pages/acceptInvitation/AcceptInvitationPage.stories.js @@ -35,24 +35,24 @@ export const NewUser = { const postBody = await request.json(); let errors = {}; - if (!Object.keys(postBody).includes('username')) { + if (!Object.keys(postBody.invitationData).includes('username')) { errors['username'] = ['This field is required']; } - if (!Object.keys(postBody).includes('password')) { + if (!Object.keys(postBody.invitationData).includes('password')) { errors['password'] = ['This field is required']; } - if (!Object.keys(postBody).includes('affiliation')) { + if (!Object.keys(postBody.invitationData).includes('affiliation')) { errors['affiliation'] = ['This field is required']; } - if (!Object.keys(postBody).includes('familyName')) { + if (!Object.keys(postBody.invitationData).includes('familyName')) { errors['familyName'] = ['This field is required']; } - if (!Object.keys(postBody).includes('country')) { + if (!Object.keys(postBody.invitationData).includes('country')) { errors['country'] = ['This field is required']; } - Object.keys(postBody).forEach((element) => { + Object.keys(postBody.invitationData).forEach((element) => { if (element !== 'orcid') { - if (postBody[element] === '') { + if (postBody.invitationData[element] === '') { errors[element] = ['This field is required']; } } diff --git a/src/pages/acceptInvitation/AcceptInvitationPage.vue b/src/pages/acceptInvitation/AcceptInvitationPage.vue index af7d15907..1015fa3d2 100644 --- a/src/pages/acceptInvitation/AcceptInvitationPage.vue +++ b/src/pages/acceptInvitation/AcceptInvitationPage.vue @@ -1,7 +1,7 @@