From ce9157698b9c927bbd9d0972d8ab85c3206a30a3 Mon Sep 17 00:00:00 2001 From: Preston Lim Date: Thu, 11 Aug 2022 13:46:39 +0800 Subject: [PATCH] feat(storybook): add stories for CollaboratorModal --- .../CollaboratorModal.stories.tsx | 118 ++++++++++++++++++ src/mocks/constants.ts | 71 +++++++++++ src/mocks/utils.ts | 21 ++++ src/types/collaborators.ts | 48 +++++++ 4 files changed, 258 insertions(+) create mode 100644 src/components/CollaboratorModal/CollaboratorModal.stories.tsx create mode 100644 src/types/collaborators.ts diff --git a/src/components/CollaboratorModal/CollaboratorModal.stories.tsx b/src/components/CollaboratorModal/CollaboratorModal.stories.tsx new file mode 100644 index 0000000000..6541ea88d4 --- /dev/null +++ b/src/components/CollaboratorModal/CollaboratorModal.stories.tsx @@ -0,0 +1,118 @@ +import { ComponentMeta, ComponentStory } from "@storybook/react" +import { CollaboratorModal } from "components/CollaboratorModal/index" +import { MemoryRouter, Route } from "react-router-dom" + +import { MOCK_COLLABORATORS, MOCK_USER } from "mocks/constants" +import { handlers } from "mocks/handlers" +import { + addContributorCollaborator, + buildCollaboratorData, + buildCollaboratorRoleData, + buildLoginData, +} from "mocks/utils" +import { CollaboratorData } from "types/collaborators" + +const collaboratorModalMeta = { + title: "Components/CollaboratorModal", + component: CollaboratorModal, + parameters: { + // Set delay so mock API requests will get resolved and the UI will render properly + chromatic: { delay: 500 }, + msw: { + handlers, + }, + }, + decorators: [ + (Story) => { + return ( + + + + + + ) + }, + ], +} as ComponentMeta + +const Template: ComponentStory = CollaboratorModal + +export const AdminMain = Template.bind({}) +AdminMain.parameters = { + msw: { + handlers: [ + ...handlers, + buildLoginData(MOCK_USER), + buildCollaboratorData(({ + collaborators: [ + // Email override so that the modal can display the "(You)" text depending on + // the LoggedInUser + { ...MOCK_COLLABORATORS.ADMIN_2, email: MOCK_USER.email }, + MOCK_COLLABORATORS.ADMIN_1, + MOCK_COLLABORATORS.CONTRIBUTOR_1, + MOCK_COLLABORATORS.CONTRIBUTOR_2, + ], + } as unknown) as CollaboratorData), + buildCollaboratorRoleData({ role: "ADMIN" }), + ], + }, +} +AdminMain.args = { + siteName: "default", +} + +export const ContributorMain = Template.bind({}) +ContributorMain.parameters = { + msw: { + handlers: [ + ...handlers, + buildLoginData(MOCK_USER), + buildCollaboratorData(({ + collaborators: [ + MOCK_COLLABORATORS.ADMIN_2, + MOCK_COLLABORATORS.ADMIN_1, + // Email override so that the modal can display the "(You)" text depending on + // the LoggedInUser + { + ...MOCK_COLLABORATORS.CONTRIBUTOR_1, + email: MOCK_USER.email, + // Setting lastLoggedIn as now since that must be true + // because the user is seeing this modal + lastLoggedIn: new Date(), + }, + MOCK_COLLABORATORS.CONTRIBUTOR_2, + ], + } as unknown) as CollaboratorData), + buildCollaboratorRoleData({ role: "CONTRIBUTOR" }), + ], + }, +} +ContributorMain.args = { + siteName: "default", +} + +export const AdminAddContributor = Template.bind({}) +AdminAddContributor.parameters = { + msw: { + handlers: [ + ...handlers, + buildLoginData(MOCK_USER), + buildCollaboratorData(({ + collaborators: [ + // Email override so that the modal can display the "(You)" text depending on + // the LoggedInUser + { ...MOCK_COLLABORATORS.ADMIN_2, email: MOCK_USER.email }, + MOCK_COLLABORATORS.ADMIN_1, + MOCK_COLLABORATORS.CONTRIBUTOR_1, + MOCK_COLLABORATORS.CONTRIBUTOR_2, + ], + } as unknown) as CollaboratorData), + buildCollaboratorRoleData({ role: "ADMIN" }), + addContributorCollaborator(), + ], + }, +} +AdminAddContributor.args = { + siteName: "default", +} +export default collaboratorModalMeta diff --git a/src/mocks/constants.ts b/src/mocks/constants.ts index f68f40db5c..56b5560846 100644 --- a/src/mocks/constants.ts +++ b/src/mocks/constants.ts @@ -136,3 +136,74 @@ export const MOCK_SUBFOLDER_NAME = "mock-subfolder" export const MOCK_RESOURCE_ROOM_NAME = "mock-resource-room" export const MOCK_RESOURCE_CATEGORY_NAME = "mock-resource-category" + +export const MOCK_COLLABORATORS = { + CONTRIBUTOR_1: { + id: "1", + email: "test1@vendor.sg", + githubId: "test1", + contactNumber: "12331231", + lastLoggedIn: "2022-03-20T07:41:09.661Z", + createdAt: "2022-04-04T07:25:41.013Z", + updatedAt: "2022-07-30T07:41:09.662Z", + deletedAt: null, + SiteMember: { + userId: "1", + siteId: "16", + role: "CONTRIBUTOR", + createdAt: "2022-07-29T03:50:49.145Z", + updatedAt: "2022-07-29T03:50:49.145Z", + }, + }, + CONTRIBUTOR_2: { + id: "4", + email: "test4@vendor.sg", + githubId: "test4", + contactNumber: "12331234", + lastLoggedIn: "2022-04-30T07:41:09.661Z", + createdAt: "2022-04-04T07:25:41.013Z", + updatedAt: "2022-07-30T07:41:09.662Z", + deletedAt: null, + SiteMember: { + userId: "4", + siteId: "16", + role: "CONTRIBUTOR", + createdAt: "2022-07-29T03:50:49.145Z", + updatedAt: "2022-07-29T03:50:49.145Z", + }, + }, + ADMIN_1: { + id: "2", + email: "test2@test.gov.sg", + githubId: "test2", + contactNumber: "12331232", + lastLoggedIn: "2022-07-30T07:41:09.661Z", + createdAt: "2022-04-04T07:25:41.013Z", + updatedAt: "2022-07-30T07:41:09.662Z", + deletedAt: null, + SiteMember: { + userId: "2", + siteId: "16", + role: "ADMIN", + createdAt: "2022-07-29T03:50:49.145Z", + updatedAt: "2022-07-29T03:50:49.145Z", + }, + }, + ADMIN_2: { + id: "3", + email: "test3@test.gov.sg", + githubId: "test3", + contactNumber: "12331233", + lastLoggedIn: "2022-06-30T07:41:09.661Z", + createdAt: "2022-04-04T07:25:41.013Z", + updatedAt: "2022-07-30T07:41:09.662Z", + deletedAt: null, + SiteMember: { + userId: "3", + siteId: "16", + role: "ADMIN", + createdAt: "2022-07-29T03:50:49.145Z", + updatedAt: "2022-07-29T03:50:49.145Z", + }, + }, +} diff --git a/src/mocks/utils.ts b/src/mocks/utils.ts index cec65d4d9d..3c62c93ed9 100644 --- a/src/mocks/utils.ts +++ b/src/mocks/utils.ts @@ -2,6 +2,11 @@ import { DefaultBodyType, rest } from "msw" import { DirectoryData, PageData, ResourcePageData } from "types/directory" import { BackendSiteSettings } from "types/settings" +import { + CollaboratorData, + CollaboratorRoleData, + SiteMemberModel, +} from "types/collaborators" import { LoggedInUser } from "types/user" const apiDataBuilder = ( @@ -43,6 +48,14 @@ export const buildSubfolderData = apiDataBuilder<(PageData | DirectoryData)[]>( "*/sites/:siteName/collections/:collectionName/subcollections/:subCollectionName" ) +export const buildCollaboratorRoleData = apiDataBuilder( + "*/sites/:siteName/collaborators/role" +) + +export const buildCollaboratorData = apiDataBuilder( + "*/sites/:siteName/collaborators" +) + export const buildLoginData = apiDataBuilder("*/auth/whoami") export const buildLastUpdated = apiDataBuilder<{ lastUpdated: string }>( @@ -52,3 +65,11 @@ export const buildLastUpdated = apiDataBuilder<{ lastUpdated: string }>( export const buildResourceCategoryData = apiDataBuilder( "/*sites/:siteName/resourceRoom/:resourceRoomName/resources/:resourceCategoryName" ) + +export const addContributorCollaborator = () => + rest.post("*/sites/:siteName/collaborators", (req, res, ctx) => { + return res( + ctx.status(422), + ctx.json({ error: { message: "Acknowledgement required" } }) + ) + }) diff --git a/src/types/collaborators.ts b/src/types/collaborators.ts new file mode 100644 index 0000000000..a75e1f58de --- /dev/null +++ b/src/types/collaborators.ts @@ -0,0 +1,48 @@ +import { string } from "prop-types" + +// TODO: Replace with actual model types in backend + +export interface SiteModel { + id: number + name: string + apiTokenName: string + siteStatus: string // TODO: This is really a SiteStatus enum but I didn't want to replicate this in the frontend + jobStatus: string // TODO: This is also an enum + createdAt: Date + updatedAt: Date + deletedAt?: Date + /* eslint-disable-next-line */ + site_members: Array + repo?: any // TODO: Repo + deployment?: any // TODO: Deployment + creatorId: number + /* eslint-disable-next-line */ + site_creator: UserModel +} + +export interface SiteMemberModel { + userId: number + siteId: string + role: string + createdAt: Date + updatedAt: Date +} +export interface UserModel { + id: number + email: string | null + githubId: string + contactNumber: string | null + lastLoggedIn: Date + createdAt: Date + updatedAt: Date + deletedAt?: Date + sites: Array + sitesCreated?: SiteModel[] +} + +export type CollaboratorData = { + collaborators: Array +} +export type CollaboratorRoleData = { + role: SiteMemberModel["role"] +}