diff --git a/src/components/MenuDropdownButton/MenuDropdownButton.tsx b/src/components/MenuDropdownButton/MenuDropdownButton.tsx index 9d6cc46c9..12427ef6a 100644 --- a/src/components/MenuDropdownButton/MenuDropdownButton.tsx +++ b/src/components/MenuDropdownButton/MenuDropdownButton.tsx @@ -15,6 +15,16 @@ interface MenuDropdownButtonProps extends ButtonProps { mainButtonText: string } +// NOTE: For icon buttons where the bg is clear, icon.default won't clash with the background +// However, for solid background, return icon.inverse so that the chevron is clear. +const computeIconFill = (variant: ButtonProps["variant"]): string => { + if (variant === "solid") { + return "icon.inverse" + } + + return "icon.default" +} + /** * The button props and mainButtonText props are passed to the main button. * The children props are passed to the context menu and should be a list of @@ -55,11 +65,12 @@ export const MenuDropdownButton = forwardRef( borderLeftRadius={0} aria-label="Select options" variant={buttonVariant} + colorScheme={props.colorScheme} icon={ } /> diff --git a/src/layouts/ReviewRequest/Dashboard.stories.tsx b/src/layouts/ReviewRequest/Dashboard.stories.tsx new file mode 100644 index 000000000..34562cf40 --- /dev/null +++ b/src/layouts/ReviewRequest/Dashboard.stories.tsx @@ -0,0 +1,27 @@ +import { ComponentMeta, Story } from "@storybook/react" + +import { MOCK_ITEMS } from "mocks/constants" + +import { + ReviewRequestDashboard, + ReviewRequestDashboardProps, +} from "./Dashboard" + +const dashboardMeta = { + title: "Components/ReviewRequest/Dashboard", + component: ReviewRequestDashboard, +} as ComponentMeta + +const Template = ReviewRequestDashboard + +export const Playground: Story = Template.bind({}) +Playground.args = { + reviewRequestedTime: new Date(), + reviewUrl: "Copied to your clipboard kekw", + title: "Update STCCED hyperlink, customs duty", + requestor: "seaerchin", + reviewers: ["nat mae tan", "jiachin er"], + changedItems: MOCK_ITEMS, +} + +export default dashboardMeta diff --git a/src/layouts/ReviewRequest/Dashboard.tsx b/src/layouts/ReviewRequest/Dashboard.tsx new file mode 100644 index 000000000..43a9041d8 --- /dev/null +++ b/src/layouts/ReviewRequest/Dashboard.tsx @@ -0,0 +1,177 @@ +import { + HStack, + VStack, + Text, + Box, + Avatar, + Flex, + Spacer, + useClipboard, + Popover, + PopoverTrigger, + PopoverContent, + PopoverBody, + PopoverArrow, + IconButton, +} from "@chakra-ui/react" +import { + MenuDropdownButton, + MenuDropdownItem, +} from "components/MenuDropdownButton" +import { useState } from "react" +import { BiLink, BiPlus } from "react-icons/bi" + +import { extractInitials, getDateTimeFromUnixTime } from "utils" + +import { RequestOverview, EditedItemProps } from "./components/RequestOverview" + +export interface ReviewRequestDashboardProps { + reviewUrl: string + title: string + requestor: string + reviewers: string[] + reviewRequestedTime: Date + changedItems: EditedItemProps[] +} +export const ReviewRequestDashboard = ({ + reviewRequestedTime, + reviewUrl, + title, + requestor, + reviewers, + changedItems, +}: ReviewRequestDashboardProps): JSX.Element => { + const { onCopy, hasCopied } = useClipboard(reviewUrl) + + return ( + + + + + {title} + {/* Closes after 1.5s and does not refocus on the button to avoid the outline */} + + + } + variant="clear" + aria-label="link to pull request" + onClick={onCopy} + /> + + + + + + Link copied! + + + + + + + + + + + + + + + ) +} + +// NOTE: Utility component exists to soothe over state management +const ApprovalButton = (): JSX.Element => { + const [isApproved, setIsApproved] = useState(false) + + return ( + + setIsApproved(false)}> + + In review + + + setIsApproved(true)}> + + Approved + + + + ) +} + +interface SecondaryDetailsProps { + requestor: string + reviewers: string[] + reviewRequestedTime: Date +} +const SecondaryDetails = ({ + requestor, + reviewers, + reviewRequestedTime, +}: SecondaryDetailsProps) => { + const { date, time } = getDateTimeFromUnixTime(reviewRequestedTime.getTime()) + return ( + + + {`Review requested by ${requestor} on ${date} ${time}`} + + + + Reviewers + + + {reviewers.map((name, index) => { + const initials = extractInitials(name) + return ( + + ) + })} + {/* NOTE: Not using design system IconButton as we require sm size */} + } + aria-label="Add Reviewer" + variant="outline" + borderRadius="50%" + fontSize="1rem" + size="sm" + ml="-0.25rem" + bg="blue.50" + /> + + + + ) +} diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.stories.tsx b/src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.stories.tsx similarity index 98% rename from src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.stories.tsx rename to src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.stories.tsx index 30846e8eb..8f8fa9f58 100644 --- a/src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.stories.tsx +++ b/src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.stories.tsx @@ -23,7 +23,7 @@ import { MOCK_ITEMS } from "mocks/constants" import { RequestOverview, RequestOverviewProps } from "./RequestOverview" const overviewMeta = { - title: "Components/ReviewRequestModal/Overview", + title: "Components/ReviewRequest/Modal Overview", component: RequestOverview, } as ComponentMeta diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.tsx b/src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.tsx similarity index 95% rename from src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.tsx rename to src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.tsx index de60c4141..70862e6af 100644 --- a/src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/RequestOverview.tsx +++ b/src/layouts/ReviewRequest/components/RequestOverview/RequestOverview.tsx @@ -55,6 +55,7 @@ import { BiChevronDown, BiCompass, BiCheck, + BiEditAlt, } from "react-icons/bi" import { TableVirtuoso } from "react-virtuoso" @@ -164,10 +165,15 @@ const LastEditedMeta = ({ export interface RequestOverviewProps { items: EditedItemProps[] + // NOTE: An alternative way to do this would be to allow consumers to pass in the header + // and let it have the same shape as react-table's header. + // However, this component seems limited in scope so the easier way out was chosen. + allowEditing?: boolean } export const RequestOverview = ({ items, + allowEditing, }: RequestOverviewProps): JSX.Element => { const { isExpanded, @@ -335,6 +341,15 @@ export const RequestOverview = ({ header: () => null, cell: ({ row }) => ( + {allowEditing && ( + + } + aria-label="edit file" + variant="link" + /> + + )} } diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/index.ts b/src/layouts/ReviewRequest/components/RequestOverview/index.ts similarity index 100% rename from src/layouts/Dashboard/components/ReviewRequestModal/RequestOverview/index.ts rename to src/layouts/ReviewRequest/components/RequestOverview/index.ts diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/ReviewRequestForm.stories.tsx b/src/layouts/ReviewRequest/components/ReviewRequestForm/ReviewRequestForm.stories.tsx similarity index 98% rename from src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/ReviewRequestForm.stories.tsx rename to src/layouts/ReviewRequest/components/ReviewRequestForm/ReviewRequestForm.stories.tsx index 3ed65c9ee..ce4c1c804 100644 --- a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/ReviewRequestForm.stories.tsx +++ b/src/layouts/ReviewRequest/components/ReviewRequestForm/ReviewRequestForm.stories.tsx @@ -23,7 +23,7 @@ import { MOCK_ADMINS } from "mocks/constants" import { ReviewRequestForm, ReviewRequestFormProps } from "./ReviewRequestForm" const formMeta = { - title: "Components/ReviewRequestModal/Form", + title: "Components/ReviewRequest/Modal Form", component: ReviewRequestForm, } as ComponentMeta diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/ReviewRequestForm.tsx b/src/layouts/ReviewRequest/components/ReviewRequestForm/ReviewRequestForm.tsx similarity index 100% rename from src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/ReviewRequestForm.tsx rename to src/layouts/ReviewRequest/components/ReviewRequestForm/ReviewRequestForm.tsx diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/index.ts b/src/layouts/ReviewRequest/components/ReviewRequestForm/index.ts similarity index 100% rename from src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestForm/index.ts rename to src/layouts/ReviewRequest/components/ReviewRequestForm/index.ts diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.stories.tsx b/src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.stories.tsx similarity index 91% rename from src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.stories.tsx rename to src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.stories.tsx index b36b8c06e..7a70e4d73 100644 --- a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.stories.tsx +++ b/src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.stories.tsx @@ -3,14 +3,13 @@ import { Story, ComponentMeta } from "@storybook/react" import { MOCK_ITEMS, MOCK_ADMINS } from "mocks/constants" -import { EditedItemProps } from "./RequestOverview" import { ReviewRequestModal, ReviewRequestModalProps, } from "./ReviewRequestModal" const modalMeta = { - title: "Components/ReviewRequestModal/Modal", + title: "Components/ReviewRequest/Modal", component: ReviewRequestModal, } as ComponentMeta type TemplateProps = Pick diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.tsx b/src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.tsx similarity index 95% rename from src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.tsx rename to src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.tsx index 21d3eb457..4a2897e02 100644 --- a/src/layouts/Dashboard/components/ReviewRequestModal/ReviewRequestModal.tsx +++ b/src/layouts/ReviewRequest/components/ReviewRequestModal/ReviewRequestModal.tsx @@ -16,8 +16,8 @@ import { } from "@chakra-ui/react" import { Button, ModalCloseButton, Tab } from "@opengovsg/design-system-react" -import { EditedItemProps, RequestOverview } from "./RequestOverview" -import { ReviewRequestForm, ReviewRequestFormProps } from "./ReviewRequestForm" +import { EditedItemProps, RequestOverview } from "../RequestOverview" +import { ReviewRequestForm, ReviewRequestFormProps } from "../ReviewRequestForm" export type ReviewRequestModalProps = ModalProps & ReviewRequestFormProps & { items: EditedItemProps[] } diff --git a/src/layouts/Dashboard/components/ReviewRequestModal/index.ts b/src/layouts/ReviewRequest/components/ReviewRequestModal/index.ts similarity index 100% rename from src/layouts/Dashboard/components/ReviewRequestModal/index.ts rename to src/layouts/ReviewRequest/components/ReviewRequestModal/index.ts diff --git a/src/layouts/Dashboard/components/index.ts b/src/layouts/ReviewRequest/components/index.ts similarity index 100% rename from src/layouts/Dashboard/components/index.ts rename to src/layouts/ReviewRequest/components/index.ts diff --git a/src/layouts/Dashboard/index.ts b/src/layouts/ReviewRequest/index.ts similarity index 100% rename from src/layouts/Dashboard/index.ts rename to src/layouts/ReviewRequest/index.ts diff --git a/src/mocks/constants.ts b/src/mocks/constants.ts index 272fd80fb..b809bdb74 100644 --- a/src/mocks/constants.ts +++ b/src/mocks/constants.ts @@ -1,4 +1,4 @@ -import { EditedItemProps } from "layouts/Dashboard/components/ReviewRequestModal/RequestOverview" +import { EditedItemProps } from "layouts/ReviewRequest/components/RequestOverview" import { DirectoryData, diff --git a/src/theme/foundations/colours.ts b/src/theme/foundations/colours.ts index 36bd23de5..c2b1cfe9e 100644 --- a/src/theme/foundations/colours.ts +++ b/src/theme/foundations/colours.ts @@ -45,6 +45,8 @@ export const colours: { [k in IsomerColorScheme]: NestedRecord } = { helper: "#848484", placeholder: "#A0A0A0", description: "#474747", + success: "#00774E", + inverse: "#FFFFFF", title: { brand: "#2164DA", brandSecondary: "#3C4764", @@ -62,7 +64,10 @@ export const colours: { [k in IsomerColorScheme]: NestedRecord } = { }, background: { action: { + default: "#2164DA", + success: "#00774E", defaultInverse: "#FFFFFF", + alt: "#5D6785", altInverse: "#F8F9FA", infoInverse: "#F7F9FE", },