Skip to content

Commit

Permalink
feat: added custom classnames to event-assignment tab atom (calcom#17527
Browse files Browse the repository at this point in the history
)

* added classNames to common types

* Update types.ts

* feat: added custom classnames to event-assignment tab atom

* Update EventTypePlatformWrapper.tsx

* update: better classnames

* added example clasnames for demo

* fix: classnames

* fix: type check

* fixed classnames

* fix: better calssnames

assingAllTeamMembersToggle -> assingAllTeamMembers
enableWeightsToggle -> enableWeights
assingAllTeamMembersToggle -> assingAllTeamMembers
  • Loading branch information
SomayChauhan authored Nov 25, 2024
1 parent 5af10a2 commit 9e9dd60
Show file tree
Hide file tree
Showing 9 changed files with 511 additions and 65 deletions.
21 changes: 19 additions & 2 deletions packages/features/eventtypes/components/AddMembersWithSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import {
AddMembersWithSwitchPlatformWrapper,
} from "@calcom/atoms/monorepo";
import { Segment } from "@calcom/features/Segment";
import type { FormValues, Host, TeamMember } from "@calcom/features/eventtypes/lib/types";
import type {
FormValues,
Host,
SettingsToggleClassNames,
TeamMember,
} from "@calcom/features/eventtypes/lib/types";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { AttributesQueryValue } from "@calcom/lib/raqb/types";
import { Label, SettingsToggle } from "@calcom/ui";

import AssignAllTeamMembers from "./AssignAllTeamMembers";
import CheckedTeamSelect from "./CheckedTeamSelect";
import type { CheckedSelectOption } from "./CheckedTeamSelect";
import type { CheckedSelectOption, CheckedTeamSelectCustomClassNames } from "./CheckedTeamSelect";

interface IUserToValue {
id: number | null;
Expand Down Expand Up @@ -57,6 +62,7 @@ const CheckedHostField = ({
onChange,
helperText,
isRRWeightsEnabled,
customClassNames,
...rest
}: {
labelText?: string;
Expand Down Expand Up @@ -100,6 +106,7 @@ const CheckedHostField = ({
options={options}
placeholder={placeholder}
isRRWeightsEnabled={isRRWeightsEnabled}
customClassNames={customClassNames}
{...rest}
/>
</div>
Expand Down Expand Up @@ -154,6 +161,11 @@ function MembersSegmentWithToggle({
);
}

export type AddMembersWithSwitchCustomClassNames = {
assingAllTeamMembers?: SettingsToggleClassNames;
teamMemberSelect?: CheckedTeamSelectCustomClassNames;
};

export type AddMembersWithSwitchProps = {
teamMembers: TeamMember[];
value: Host[];
Expand All @@ -168,6 +180,7 @@ export type AddMembersWithSwitchProps = {
teamId: number;
isSegmentApplicable?: boolean;
"data-testid"?: string;
customClassNames?: AddMembersWithSwitchCustomClassNames;
};

const enum AssignmentState {
Expand Down Expand Up @@ -232,6 +245,7 @@ export function AddMembersWithSwitch({
isRRWeightsEnabled,
teamId,
isSegmentApplicable,
customClassNames,
...rest
}: AddMembersWithSwitchProps) {
const { t } = useLocale();
Expand Down Expand Up @@ -267,6 +281,7 @@ export function AddMembersWithSwitch({
onActive();
}}
onInactive={onAssignAllTeamMembersInactive}
customClassNames={customClassNames?.assingAllTeamMembers}
/>
{assignmentState !== AssignmentState.ALL_TEAM_MEMBERS_ENABLED_AND_SEGMENT_NOT_APPLICABLE && (
<div className="mt-2">
Expand All @@ -293,6 +308,7 @@ export function AddMembersWithSwitch({
setAssignAllTeamMembers={setAssignAllTeamMembers}
onActive={onActive}
onInactive={onAssignAllTeamMembersInactive}
customClassNames={customClassNames?.assingAllTeamMembers}
/>
)}
</div>
Expand All @@ -306,6 +322,7 @@ export function AddMembersWithSwitch({
options={teamMembers.sort(sortByLabel)}
placeholder={placeholder ?? t("add_attendees")}
isRRWeightsEnabled={isRRWeightsEnabled}
customClassNames={customClassNames?.teamMemberSelect}
/>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Dispatch, SetStateAction } from "react";
import { Controller, useFormContext } from "react-hook-form";

import type { FormValues } from "@calcom/features/eventtypes/lib/types";
import type { FormValues, SettingsToggleClassNames } from "@calcom/features/eventtypes/lib/types";
import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { SettingsToggle } from "@calcom/ui";

Expand All @@ -10,11 +11,13 @@ const AssignAllTeamMembers = ({
setAssignAllTeamMembers,
onActive,
onInactive,
customClassNames,
}: {
assignAllTeamMembers: boolean;
setAssignAllTeamMembers: Dispatch<SetStateAction<boolean>>;
onActive: () => void;
onInactive?: () => void;
customClassNames?: SettingsToggleClassNames;
}) => {
const { t } = useLocale();
const { setValue } = useFormContext<FormValues>();
Expand All @@ -26,7 +29,8 @@ const AssignAllTeamMembers = ({
<SettingsToggle
data-testid="assign-all-team-members-toggle"
title={t("automatically_add_all_team_members")}
labelClassName="mt-0.5 font-normal"
labelClassName={classNames("mt-0.5 font-normal", customClassNames?.label)}
switchContainerClassName={customClassNames?.container}
checked={assignAllTeamMembers}
onCheckedChange={(active) => {
setValue("assignAllTeamMembers", active, { shouldDirty: true });
Expand Down
66 changes: 59 additions & 7 deletions packages/features/eventtypes/components/CheckedTeamSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { useState } from "react";
import type { Props } from "react-select";

import { useIsPlatform } from "@calcom/atoms/monorepo";
import type { SelectClassNames } from "@calcom/features/eventtypes/lib/types";
import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Avatar, Button, Icon, Select, Tooltip } from "@calcom/ui";

import type { PriorityDialogCustomClassNames, WeightDialogCustomClassNames } from "./HostEditDialogs";
import { PriorityDialog, WeightDialog } from "./HostEditDialogs";

export type CheckedSelectOption = {
Expand All @@ -22,15 +24,33 @@ export type CheckedSelectOption = {
defaultScheduleId?: number | null;
};

export type CheckedTeamSelectCustomClassNames = {
hostsSelect?: SelectClassNames;
selectedHostList?: {
container?: string;
listItem?: {
container?: string;
avatar?: string;
name?: string;
changePriorityButton?: string;
changeWeightButton?: string;
removeButton?: string;
};
};
priorityDialog?: PriorityDialogCustomClassNames;
weightDialog?: WeightDialogCustomClassNames;
};
export const CheckedTeamSelect = ({
options = [],
value = [],
isRRWeightsEnabled,
customClassNames,
...props
}: Omit<Props<CheckedSelectOption, true>, "value" | "onChange"> & {
value?: readonly CheckedSelectOption[];
onChange: (value: readonly CheckedSelectOption[]) => void;
isRRWeightsEnabled?: boolean;
customClassNames?: CheckedTeamSelectCustomClassNames;
}) => {
const isPlatform = useIsPlatform();
const [priorityDialogOpen, setPriorityDialogOpen] = useState(false);
Expand All @@ -50,21 +70,44 @@ export const CheckedTeamSelect = ({
options={options}
value={value}
isMulti
className={customClassNames?.hostsSelect?.select}
innerClassNames={customClassNames?.hostsSelect?.innerClassNames}
{...props}
/>
{/* This class name conditional looks a bit odd but it allows a seemless transition when using autoanimate
- Slides down from the top instead of just teleporting in from nowhere*/}
<ul
className={classNames("mb-4 mt-3 rounded-md", value.length >= 1 && "border-subtle border")}
className={classNames(
"mb-4 mt-3 rounded-md",
value.length >= 1 && "border-subtle border",
customClassNames?.selectedHostList?.container
)}
ref={animationRef}>
{value.map((option, index) => (
<>
<li
key={option.value}
className={`flex px-3 py-2 ${index === value.length - 1 ? "" : "border-subtle border-b"}`}>
className={classNames(
`flex px-3 py-2 ${index === value.length - 1 ? "" : "border-subtle border-b"}`,
customClassNames?.selectedHostList?.listItem?.container
)}>
{!isPlatform && <Avatar size="sm" imageSrc={option.avatar} alt={option.label} />}
{isPlatform && <Icon name="user" className="mt-0.5 h-4 w-4" />}
<p className="text-emphasis my-auto ms-3 text-sm">{option.label}</p>
{isPlatform && (
<Icon
name="user"
className={classNames(
"mt-0.5 h-4 w-4",
customClassNames?.selectedHostList?.listItem?.avatar
)}
/>
)}
<p
className={classNames(
"text-emphasis my-auto ms-3 text-sm",
customClassNames?.selectedHostList?.listItem?.name
)}>
{option.label}
</p>
<div className="ml-auto flex items-center">
{option && !option.isFixed ? (
<>
Expand All @@ -77,15 +120,19 @@ export const CheckedTeamSelect = ({
}}
className={classNames(
"mr-6 h-2 p-0 text-sm hover:bg-transparent",
getPriorityTextAndColor(option.priority).color
getPriorityTextAndColor(option.priority).color,
customClassNames?.selectedHostList?.listItem?.changePriorityButton
)}>
{t(getPriorityTextAndColor(option.priority).text)}
</Button>
</Tooltip>
{isRRWeightsEnabled ? (
<Button
color="minimal"
className="mr-6 h-2 w-4 p-0 text-sm hover:bg-transparent"
className={classNames(
"mr-6 h-2 w-4 p-0 text-sm hover:bg-transparent",
customClassNames?.selectedHostList?.listItem?.changeWeightButton
)}
onClick={() => {
setWeightDialogOpen(true);
setCurrentOption(option);
Expand All @@ -103,7 +150,10 @@ export const CheckedTeamSelect = ({
<Icon
name="x"
onClick={() => props.onChange(value.filter((item) => item.value !== option.value))}
className="my-auto ml-2 h-4 w-4"
className={classNames(
"my-auto ml-2 h-4 w-4",
customClassNames?.selectedHostList?.listItem?.removeButton
)}
/>
</div>
</li>
Expand All @@ -117,12 +167,14 @@ export const CheckedTeamSelect = ({
setIsOpenDialog={setPriorityDialogOpen}
option={currentOption}
onChange={props.onChange}
customClassNames={customClassNames?.priorityDialog}
/>
<WeightDialog
isOpenDialog={weightDialogOpen}
setIsOpenDialog={setWeightDialogOpen}
option={currentOption}
onChange={props.onChange}
customClassNames={customClassNames?.weightDialog}
/>
</>
) : (
Expand Down
Loading

0 comments on commit 9e9dd60

Please sign in to comment.