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>
This commit is contained in:
Syed Ali Shahbaz 2022-05-23 16:47:00 +05:30 committed by GitHub
parent c5ad74f61c
commit 27422c351c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 66 deletions

View File

@ -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>

View File

@ -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

View File

@ -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}>