* WIP * Locked fields manager * Leftovers * Bad merge fix * Type import fix * Moving away from classes * Progress refactoring locked logic * Covering apps, webhooks and workflows * Supporting webhooks and workflows (TBT) * Restoring yarn.lock * Progress * Refactoring code, adding default values * Fixing CRUD for children * Connect app link and case-sensitive lib renaming * Translation missing * Locked indicators, empty screens, locations * Member card and hidden status + missing i18n * Missing existent children shown * Showing preview for already created children * Email notification almost in place * Making progress over notif email * Fixing nodemailer by mixed FE/BE mixup * Delete dialog * Adding tests * New test * Reverting unneeded change * Removed console.log * Tweaking email * Reverting not applicable webhook changes * Reverting dev email api * Fixing last changes due to tests * Changing user-evType relationship * Availability and slug replacement tweaks * Fixing event type delete * Sometimes slug is not there... * Removing old webhooks references Changed slug hint * Fixing types * Fixing hiding event types actions * Changing delete dialog text * Removing unneeded code * Applying feedback * Update yarn.lock * Making sure locked fields values are static * Applying feedback * Feedback + relying on children list, not users * Removing console.log * PR Feedback * Telemetry for slug replacement action * More unit tests * Relying on schedule and editor tweaks * Fixing conteiner classname * PR Feedback * PR Feedback * Updating unit tests * Moving stuff to ee, added feature flag * type fix * Including e2e * Reverting unneeded changes in EmptyScreen * Fixing some UI issues after merging tokens * Fixing missing disabled locked fields * Theme fixes + e2e potential fix * Fixing e2e * Fixing login relying on network * Tweaking e2e * Removing unneeded code --------- Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import classNames from "@calcom/lib/classNames";
|
|
|
|
import { Avatar } from "./Avatar";
|
|
|
|
export type AvatarGroupProps = {
|
|
size: "sm" | "lg";
|
|
items: {
|
|
image: string;
|
|
title?: string;
|
|
alt?: string;
|
|
href?: string;
|
|
}[];
|
|
className?: string;
|
|
accepted?: boolean;
|
|
truncateAfter?: number;
|
|
};
|
|
|
|
export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
|
|
const LENGTH = props.items.length;
|
|
const truncateAfter = props.truncateAfter || 4;
|
|
/**
|
|
* First, filter all the avatars object that have image
|
|
* Then, slice it until before `truncateAfter` index
|
|
*/
|
|
const displayedAvatars = props.items.filter((avatar) => avatar.image).slice(0, truncateAfter);
|
|
const numTruncatedAvatars = LENGTH - displayedAvatars.length;
|
|
|
|
if (!displayedAvatars.length) return <></>;
|
|
|
|
return (
|
|
<ul className={classNames("flex items-center", props.className)}>
|
|
{displayedAvatars.map((item, idx) => (
|
|
<li key={idx} className="-mr-[4px] inline-block">
|
|
<Avatar
|
|
className="border-subtle"
|
|
imageSrc={item.image}
|
|
title={item.title}
|
|
alt={item.alt || ""}
|
|
accepted={props.accepted}
|
|
size={props.size}
|
|
href={item.href}
|
|
/>
|
|
</li>
|
|
))}
|
|
{numTruncatedAvatars > 0 && (
|
|
<li
|
|
className={classNames(
|
|
"bg-darkgray-300 relative -mr-[4px] mb-1 inline-flex justify-center overflow-hidden rounded-full",
|
|
props.size === "sm" ? "min-w-6 h-6" : "min-w-16 h-16"
|
|
)}>
|
|
<span
|
|
className={classNames(
|
|
"text-inverted m-auto px-1 text-center",
|
|
props.size === "sm" ? "text-[12px]" : "text-2xl"
|
|
)}>
|
|
+{numTruncatedAvatars}
|
|
</span>
|
|
</li>
|
|
)}
|
|
</ul>
|
|
);
|
|
};
|