Fix UI of dialog (#2788)
* removed large mandatory height and scroll * added z index using css * cleanup * fixed TS errors * extract dialog out of dropdown * Adds custom loading text to confirmation dialog * rename update * utilizing mutation loading state Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>pull/2848/head^2
parent
c5ad74f61c
commit
27422c351c
|
@ -12,6 +12,7 @@ export type ConfirmationDialogContentProps = {
|
|||
confirmBtnText?: string;
|
||||
cancelBtnText?: string;
|
||||
isLoading?: boolean;
|
||||
loadingText?: string;
|
||||
onConfirm?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
|
||||
title: string;
|
||||
variety?: "danger" | "warning" | "success";
|
||||
|
@ -25,6 +26,7 @@ export default function ConfirmationDialogContent(props: PropsWithChildren<Confi
|
|||
confirmBtn = null,
|
||||
confirmBtnText = t("confirm"),
|
||||
cancelBtnText = t("cancel"),
|
||||
loadingText = t("loading"),
|
||||
isLoading = false,
|
||||
onConfirm,
|
||||
children,
|
||||
|
@ -63,7 +65,7 @@ export default function ConfirmationDialogContent(props: PropsWithChildren<Confi
|
|||
<DialogClose disabled={isLoading} onClick={onConfirm} asChild>
|
||||
{confirmBtn || (
|
||||
<Button color="primary" loading={isLoading}>
|
||||
{isLoading ? t("loading") : confirmBtnText}
|
||||
{isLoading ? loadingText : confirmBtnText}
|
||||
</Button>
|
||||
)}
|
||||
</DialogClose>
|
||||
|
|
|
@ -87,12 +87,12 @@ const Item = ({ type, group, readOnly }: { type: EventType; group: EventTypeGrou
|
|||
data-testid={"event-type-slug-" + type.id}>{`/${group.profile.slug}/${type.slug}`}</small>
|
||||
{type.hidden && (
|
||||
<span className="rtl:mr-2inline items-center rounded-sm bg-yellow-100 px-1.5 py-0.5 text-xs font-medium text-yellow-800 ltr:ml-2">
|
||||
{t("hidden")}
|
||||
{t("hidden") as string}
|
||||
</span>
|
||||
)}
|
||||
{readOnly && (
|
||||
<span className="rtl:mr-2inline items-center rounded-sm bg-gray-100 px-1.5 py-0.5 text-xs font-medium text-gray-800 ltr:ml-2">
|
||||
{t("readonly")}
|
||||
{t("readonly") as string}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
@ -107,7 +107,8 @@ const MemoizedItem = React.memo(Item);
|
|||
export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeListProps): JSX.Element => {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [deleteDialogTypeId, setDeleteDialogTypeId] = useState(0);
|
||||
const utils = trpc.useContext();
|
||||
const mutation = trpc.useMutation("viewer.eventTypeOrder", {
|
||||
onError: async (err) => {
|
||||
|
@ -182,11 +183,13 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
onSuccess: async () => {
|
||||
await utils.invalidateQueries(["viewer.eventTypes"]);
|
||||
showToast(t("event_type_deleted_successfully"), "success");
|
||||
setDeleteDialogOpen(false);
|
||||
},
|
||||
onError: (err) => {
|
||||
if (err instanceof HttpError) {
|
||||
const message = `${err.statusCode}: ${err.message}`;
|
||||
showToast(message, "error");
|
||||
setDeleteDialogOpen(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
@ -252,7 +255,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
"flex justify-between space-x-2 rtl:space-x-reverse ",
|
||||
type.$disabled && "pointer-events-none cursor-not-allowed"
|
||||
)}>
|
||||
<Tooltip content={t("preview")}>
|
||||
<Tooltip content={t("preview") as string}>
|
||||
<a
|
||||
href={`${process.env.NEXT_PUBLIC_WEBSITE_URL}/${group.profile.slug}/${type.slug}`}
|
||||
target="_blank"
|
||||
|
@ -264,7 +267,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
</a>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content={t("copy_link")}>
|
||||
<Tooltip content={t("copy_link") as string}>
|
||||
<button
|
||||
onClick={() => {
|
||||
showToast(t("link_copied"), "success");
|
||||
|
@ -297,8 +300,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
type.$disabled && " pointer-events-none cursor-not-allowed opacity-30"
|
||||
)}
|
||||
StartIcon={PencilIcon}>
|
||||
{" "}
|
||||
{t("edit")}
|
||||
{t("edit") as string}
|
||||
</Button>
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
|
@ -314,7 +316,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
data-testid={"event-type-duplicate-" + type.id}
|
||||
StartIcon={DuplicateIcon}
|
||||
onClick={() => openModal(group, type)}>
|
||||
{t("duplicate")}
|
||||
{t("duplicate") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
|
@ -328,30 +330,17 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
||||
<DropdownMenuItem>
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
color="warn"
|
||||
size="sm"
|
||||
StartIcon={TrashIcon}
|
||||
className="w-full rounded-none">
|
||||
{t("delete")}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<ConfirmationDialogContent
|
||||
variety="danger"
|
||||
title={t("delete_event_type")}
|
||||
confirmBtnText={t("confirm_delete_event_type")}
|
||||
onConfirm={(e) => {
|
||||
e.preventDefault();
|
||||
deleteEventTypeHandler(type.id);
|
||||
}}>
|
||||
{t("delete_event_type_description")}
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setDeleteDialogOpen(true);
|
||||
setDeleteDialogTypeId(type.id);
|
||||
}}
|
||||
color="warn"
|
||||
size="sm"
|
||||
StartIcon={TrashIcon}
|
||||
className="w-full rounded-none">
|
||||
{t("delete") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</Dropdown>
|
||||
|
@ -373,7 +362,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
size="sm"
|
||||
StartIcon={ExternalLinkIcon}
|
||||
className="w-full rounded-none">
|
||||
{t("preview")}
|
||||
{t("preview") as string}
|
||||
</Button>
|
||||
</a>
|
||||
</Link>
|
||||
|
@ -392,7 +381,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
);
|
||||
showToast(t("link_copied"), "success");
|
||||
}}>
|
||||
{t("copy_link")}
|
||||
{t("copy_link") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
{isNativeShare ? (
|
||||
|
@ -414,7 +403,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
.then(() => showToast(t("link_shared"), "success"))
|
||||
.catch(() => showToast(t("failed"), "error"));
|
||||
}}>
|
||||
{t("share")}
|
||||
{t("share") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
) : null}
|
||||
|
@ -426,8 +415,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
color="minimal"
|
||||
className="w-full rounded-none"
|
||||
StartIcon={PencilIcon}>
|
||||
{" "}
|
||||
{t("edit")}
|
||||
{t("edit") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
|
@ -439,35 +427,22 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
data-testid={"event-type-duplicate-" + type.id}
|
||||
StartIcon={DuplicateIcon}
|
||||
onClick={() => openModal(group, type)}>
|
||||
{t("duplicate")}
|
||||
{t("duplicate") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
||||
<DropdownMenuItem>
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
}}
|
||||
color="warn"
|
||||
size="sm"
|
||||
StartIcon={TrashIcon}
|
||||
className="w-full rounded-none">
|
||||
{t("delete")}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<ConfirmationDialogContent
|
||||
variety="danger"
|
||||
title={t("delete_event_type")}
|
||||
confirmBtnText={t("confirm_delete_event_type")}
|
||||
onConfirm={(e) => {
|
||||
e.preventDefault();
|
||||
deleteEventTypeHandler(type.id);
|
||||
}}>
|
||||
{t("delete_event_type_description")}
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setDeleteDialogOpen(true);
|
||||
setDeleteDialogTypeId(type.id);
|
||||
}}
|
||||
color="warn"
|
||||
size="sm"
|
||||
StartIcon={TrashIcon}
|
||||
className="w-full rounded-none">
|
||||
{t("delete") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</Dropdown>
|
||||
|
@ -476,6 +451,20 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
||||
<ConfirmationDialogContent
|
||||
isLoading={deleteMutation.isLoading}
|
||||
variety="danger"
|
||||
title={t("delete_event_type")}
|
||||
confirmBtnText={t("confirm_delete_event_type")}
|
||||
loadingText={t("confirm_delete_event_type")}
|
||||
onConfirm={(e) => {
|
||||
e.preventDefault();
|
||||
deleteEventTypeHandler(deleteDialogTypeId);
|
||||
}}>
|
||||
{t("delete_event_type_description") as string}
|
||||
</ConfirmationDialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -556,8 +545,8 @@ const EventTypesPage = () => {
|
|||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<Shell
|
||||
heading={t("event_types_page_title")}
|
||||
subtitle={t("event_types_page_subtitle")}
|
||||
heading={t("event_types_page_title") as string}
|
||||
subtitle={t("event_types_page_subtitle") as string}
|
||||
CTA={<CTA />}
|
||||
customLoader={<SkeletonLoader />}>
|
||||
<WithQuery
|
||||
|
|
|
@ -75,7 +75,7 @@ export const DialogContent = React.forwardRef<HTMLDivElement, DialogContentProps
|
|||
: props.size == "lg"
|
||||
? "p-6 sm:max-w-[70rem]"
|
||||
: "p-6 sm:max-w-[35rem]",
|
||||
"h-[80vh] max-h-[560px] overflow-scroll overscroll-auto md:h-auto md:max-h-[inherit]",
|
||||
"max-h-[560px] overflow-auto overscroll-auto md:h-auto md:max-h-[inherit]",
|
||||
`${props.className || ""}`
|
||||
)}
|
||||
ref={forwardedRef}>
|
||||
|
|
Loading…
Reference in New Issue