From d40b93486616b01ad97a17f1c54767c7c45d1c8f Mon Sep 17 00:00:00 2001 From: Alex van Andel Date: Wed, 8 Mar 2023 22:04:33 +0000 Subject: [PATCH] Bugfix/improved assignment page (#7165) * Refactor Assignment hosts components * Addressed NIT * Remove switch in favour of render object --------- Co-authored-by: zomars --- .../web/components/eventtype/EventTeamTab.tsx | 256 ++++++++++-------- apps/web/pages/event-types/[type]/index.tsx | 24 +- apps/web/pages/event-types/index.tsx | 2 +- .../schedules/components/Schedule.tsx | 7 +- .../migration.sql | 11 + packages/prisma/schema.prisma | 3 +- packages/trpc/server/routers/viewer.tsx | 2 +- .../trpc/server/routers/viewer/eventTypes.ts | 13 +- 8 files changed, 173 insertions(+), 145 deletions(-) create mode 100644 packages/prisma/migrations/20230216171757_host_user_id_event_type_id/migration.sql diff --git a/apps/web/components/eventtype/EventTeamTab.tsx b/apps/web/components/eventtype/EventTeamTab.tsx index 1014ac0d0c..97409da13d 100644 --- a/apps/web/components/eventtype/EventTeamTab.tsx +++ b/apps/web/components/eventtype/EventTeamTab.tsx @@ -1,7 +1,7 @@ -import { SchedulingType } from "@prisma/client"; +import type { SchedulingType } from "@prisma/client"; import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]"; +import { useEffect, useRef } from "react"; import type { ComponentProps } from "react"; -import type { Control } from "react-hook-form"; import { Controller, useFormContext, useWatch } from "react-hook-form"; import type { Options } from "react-select"; @@ -35,65 +35,169 @@ const sortByLabel = (a: ReturnType, b: ReturnType; labelText: string; placeholder: string; + isFixed: boolean; + value: { isFixed: boolean; userId: number }[]; + onChange?: (options: { isFixed: boolean; userId: number }[]) => void; options?: Options; -} & Partial>) => { +} & Omit>, "onChange" | "value">) => { return (
- { - return ( - { - onChange( - options.map((option) => ({ - isFixed: true, - userId: parseInt(option.value, 10), - })) - ); - }} - value={value - .map( - (host) => - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - options.find((member) => member.value === host.userId.toString())! - ) - .filter(Boolean)} - controlShouldRenderValue={false} - options={options} - placeholder={placeholder} - {...rest} - /> - ); + !!value.find((host) => host.userId.toString() === option.value)} + onChange={(options) => { + onChange && + onChange( + options.map((option) => ({ + isFixed, + userId: parseInt(option.value, 10), + })) + ); }} + value={(value || []) + .filter(({ isFixed: _isFixed }) => isFixed === _isFixed) + .map( + (host) => + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + options.find((member) => member.value === host.userId.toString())! + ) + .filter(Boolean)} + controlShouldRenderValue={false} + options={options} + placeholder={placeholder} + {...rest} />
); }; -export const EventTeamTab = ({ team, teamMembers }: Pick) => { - const formMethods = useFormContext(); +const RoundRobinHosts = ({ + teamMembers, + value, + onChange, +}: { + value: { isFixed: boolean; userId: number }[]; + onChange: (hosts: { isFixed: boolean; userId: number }[]) => void; + teamMembers: { + value: string; + label: string; + avatar: string; + email: string; + }[]; +}) => { const { t } = useLocale(); + return ( + <> + { + onChange([...value.filter(({ isFixed }) => !isFixed), ...changeValue]); + }} + value={value} + placeholder={t("add_fixed_hosts")} + labelText={t("fixed_hosts")} + /> + onChange([...value.filter(({ isFixed }) => isFixed), ...changeValue])} + value={value} + isFixed={false} + placeholder={t("add_attendees")} + labelText={t("round_robin_hosts")} + /> + + ); +}; +const Hosts = ({ + teamMembers, +}: { + teamMembers: { + value: string; + label: string; + avatar: string; + email: string; + }[]; +}) => { + const { t } = useLocale(); + const { + control, + resetField, + getValues, + formState: { submitCount }, + } = useFormContext(); const schedulingType = useWatch({ - control: formMethods.control, + control, name: "schedulingType", }); + const initialValue = useRef<{ + hosts: FormValues["hosts"]; + schedulingType: SchedulingType | null; + submitCount: number; + } | null>(null); + + useEffect(() => { + // Handles init & out of date initial value after submission. + if (!initialValue.current || initialValue.current?.submitCount !== submitCount) { + initialValue.current = { hosts: getValues("hosts"), schedulingType, submitCount }; + return; + } + resetField("hosts", { + defaultValue: initialValue.current.schedulingType === schedulingType ? initialValue.current.hosts : [], + }); + }, [schedulingType, resetField, getValues, submitCount]); + + return ( + + name="hosts" + render={({ field: { onChange, value } }) => { + const schedulingTypeRender = { + COLLECTIVE: ( + + ), + ROUND_ROBIN: ( + <> + + {/*{t("hosts")}} + />*/} + + ), + }; + return !!schedulingType ? schedulingTypeRender[schedulingType] : <>; + }} + /> + ); +}; + +export const EventTeamTab = ({ team, teamMembers }: Pick) => { + const { t } = useLocale(); const schedulingTypeOptions: { value: SchedulingType; @@ -101,17 +205,16 @@ export const EventTeamTab = ({ team, teamMembers }: Pick @@ -119,9 +222,8 @@ export const EventTeamTab = ({ team, teamMembers }: Pick
- name="schedulingType" - control={formMethods.control} render={({ field: { value, onChange } }) => (