mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: ui improvement (#214)
* fix: help option ui fix * feat: auth toast added * fix: copy shortcut command fix * feat: card title ellipsis added --------- Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia1001@gmail.com>
This commit is contained in:
parent
28d4f4c876
commit
27e3364a1f
@ -5,6 +5,7 @@ import { CheckCircleIcon } from "@heroicons/react/20/solid";
|
|||||||
import { Button, Input } from "components/ui";
|
import { Button, Input } from "components/ui";
|
||||||
// services
|
// services
|
||||||
import authenticationService from "services/authentication.service";
|
import authenticationService from "services/authentication.service";
|
||||||
|
import useToast from "hooks/use-toast";
|
||||||
// icons
|
// icons
|
||||||
|
|
||||||
// types
|
// types
|
||||||
@ -16,6 +17,7 @@ type EmailCodeFormValues = {
|
|||||||
|
|
||||||
export const EmailCodeForm = ({ onSuccess }: any) => {
|
export const EmailCodeForm = ({ onSuccess }: any) => {
|
||||||
const [codeSent, setCodeSent] = useState(false);
|
const [codeSent, setCodeSent] = useState(false);
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -53,6 +55,11 @@ export const EmailCodeForm = ({ onSuccess }: any) => {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
setToastAlert({
|
||||||
|
title: "Oops!",
|
||||||
|
type: "error",
|
||||||
|
message: "Enter the correct code to sign in",
|
||||||
|
});
|
||||||
setError("token" as keyof EmailCodeFormValues, {
|
setError("token" as keyof EmailCodeFormValues, {
|
||||||
type: "manual",
|
type: "manual",
|
||||||
message: error.error,
|
message: error.error,
|
||||||
|
@ -6,6 +6,7 @@ import { useForm } from "react-hook-form";
|
|||||||
// ui
|
// ui
|
||||||
import { Button, Input } from "components/ui";
|
import { Button, Input } from "components/ui";
|
||||||
import authenticationService from "services/authentication.service";
|
import authenticationService from "services/authentication.service";
|
||||||
|
import useToast from "hooks/use-toast";
|
||||||
|
|
||||||
// types
|
// types
|
||||||
type EmailPasswordFormValues = {
|
type EmailPasswordFormValues = {
|
||||||
@ -15,6 +16,7 @@ type EmailPasswordFormValues = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const EmailPasswordForm = ({ onSuccess }: any) => {
|
export const EmailPasswordForm = ({ onSuccess }: any) => {
|
||||||
|
const { setToastAlert } = useToast();
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -38,6 +40,11 @@ export const EmailPasswordForm = ({ onSuccess }: any) => {
|
|||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
setToastAlert({
|
||||||
|
title: "Oops!",
|
||||||
|
type: "error",
|
||||||
|
message: "Enter the correct email address and password to sign in",
|
||||||
|
});
|
||||||
if (!error?.response?.data) return;
|
if (!error?.response?.data) return;
|
||||||
Object.keys(error.response.data).forEach((key) => {
|
Object.keys(error.response.data).forEach((key) => {
|
||||||
const err = error.response.data[key];
|
const err = error.response.data[key];
|
||||||
|
@ -105,6 +105,8 @@ const CommandPalette: React.FC = () => {
|
|||||||
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
|
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsPaletteOpen(true);
|
setIsPaletteOpen(true);
|
||||||
|
} else if (e.ctrlKey && e.key === "c") {
|
||||||
|
console.log("Text copied");
|
||||||
} else if (e.key === "c") {
|
} else if (e.key === "c") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setIsIssueModalOpen(true);
|
setIsIssueModalOpen(true);
|
||||||
@ -128,24 +130,23 @@ const CommandPalette: React.FC = () => {
|
|||||||
setIsBulkDeleteIssuesModalOpen(true);
|
setIsBulkDeleteIssuesModalOpen(true);
|
||||||
} else if ((e.ctrlKey || e.metaKey) && e.altKey && e.key === "c") {
|
} else if ((e.ctrlKey || e.metaKey) && e.altKey && e.key === "c") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
if (!router.query.issueId) return;
|
||||||
|
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
copyTextToClipboard(url.href)
|
||||||
|
.then(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "success",
|
||||||
|
title: "Copied to clipboard",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setToastAlert({
|
||||||
|
type: "error",
|
||||||
|
title: "Some error occurred",
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!router.query.issueId) return;
|
|
||||||
|
|
||||||
const url = new URL(window.location.href);
|
|
||||||
copyTextToClipboard(url.href)
|
|
||||||
.then(() => {
|
|
||||||
setToastAlert({
|
|
||||||
type: "success",
|
|
||||||
title: "Copied to clipboard",
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setToastAlert({
|
|
||||||
type: "error",
|
|
||||||
title: "Some error occurred",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[toggleCollapsed, setToastAlert, router]
|
[toggleCollapsed, setToastAlert, router]
|
||||||
|
@ -46,14 +46,16 @@ export const ProjectCard: React.FC<ProjectCardProps> = (props) => {
|
|||||||
<>
|
<>
|
||||||
<div className="flex h-full w-full flex-col rounded-md border bg-white px-4 py-3">
|
<div className="flex h-full w-full flex-col rounded-md border bg-white px-4 py-3">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex gap-2 text-lg font-medium">
|
<div className="flex gap-2 text-lg font-medium">
|
||||||
<Link href={`/${workspaceSlug}/projects/${project.id}/issues`}>
|
<Link href={`/${workspaceSlug}/projects/${project.id}/issues`}>
|
||||||
<a className="flex items-center gap-x-3">
|
<a className="flex items-center gap-x-3">
|
||||||
{project.icon && (
|
{project.icon && (
|
||||||
<span className="text-base">{String.fromCodePoint(parseInt(project.icon))}</span>
|
<span className="text-base">{String.fromCodePoint(parseInt(project.icon))}</span>
|
||||||
)}
|
)}
|
||||||
<span>{project.name}</span>
|
<span className="w-3/4 max-w-[225px] md:max-w-[140px] xl:max-w-[225px] text-ellipsis overflow-hidden">
|
||||||
<span className="text-xs text-gray-500">{project.identifier}</span>
|
{project.name}
|
||||||
|
</span>
|
||||||
|
<span className="text-xs text-gray-500 ">{project.identifier}</span>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,7 +71,9 @@ const SingleStat: React.FC<TSingleStatProps> = (props) => {
|
|||||||
<div className="flex items-center justify-between gap-2">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectId as string}/cycles/${cycle.id}`}>
|
<Link href={`/${workspaceSlug}/projects/${projectId as string}/cycles/${cycle.id}`}>
|
||||||
<a>
|
<a>
|
||||||
<h2 className="font-medium">{cycle.name}</h2>
|
<h2 className="font-medium w-full max-w-[175px] lg:max-w-[225px] xl:max-w-[300px] text-ellipsis overflow-hidden">
|
||||||
|
{cycle.name}
|
||||||
|
</h2>
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
<CustomMenu width="auto" ellipsis>
|
<CustomMenu width="auto" ellipsis>
|
||||||
|
@ -30,7 +30,7 @@ const SingleModuleCard: React.FC<Props> = ({ module }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="group/card relative select-none p-2">
|
<div className="group/card h-full w-full relative select-none p-2">
|
||||||
<div className="absolute top-4 right-4 z-50 bg-red-200 opacity-0 group-hover/card:opacity-100">
|
<div className="absolute top-4 right-4 z-50 bg-red-200 opacity-0 group-hover/card:opacity-100">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -50,8 +50,8 @@ const SingleModuleCard: React.FC<Props> = ({ module }) => {
|
|||||||
data={selectedModuleForDelete}
|
data={selectedModuleForDelete}
|
||||||
/>
|
/>
|
||||||
<Link href={`/${workspaceSlug}/projects/${module.project}/modules/${module.id}`}>
|
<Link href={`/${workspaceSlug}/projects/${module.project}/modules/${module.id}`}>
|
||||||
<a className="block cursor-pointer rounded-md border bg-white p-3">
|
<a className="flex flex-col cursor-pointer rounded-md border bg-white p-3 ">
|
||||||
{module.name}
|
<span className="w-3/4 text-ellipsis overflow-hidden">{module.name}</span>
|
||||||
<div className="mt-4 grid grid-cols-2 gap-2 text-xs md:grid-cols-4">
|
<div className="mt-4 grid grid-cols-2 gap-2 text-xs md:grid-cols-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h6 className="text-gray-500">LEAD</h6>
|
<h6 className="text-gray-500">LEAD</h6>
|
||||||
|
@ -53,6 +53,8 @@ export const WorkspaceHelpSection: FC<WorkspaceHelpSectionProps> = (props) => {
|
|||||||
// hooks
|
// hooks
|
||||||
useOutsideClickDetector(helpOptionsRef, () => setIsNeedHelpOpen(false));
|
useOutsideClickDetector(helpOptionsRef, () => setIsNeedHelpOpen(false));
|
||||||
|
|
||||||
|
const helpOptionMode = sidebarCollapse ? "left-full" : "left-[-75px]";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`flex w-full items-center self-baseline bg-primary px-2 py-2 ${
|
className={`flex w-full items-center self-baseline bg-primary px-2 py-2 ${
|
||||||
@ -107,14 +109,14 @@ export const WorkspaceHelpSection: FC<WorkspaceHelpSectionProps> = (props) => {
|
|||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="absolute bottom-0 left-full space-y-2 rounded-sm bg-white py-3 shadow-md"
|
className={`absolute bottom-2 ${helpOptionMode} space-y-2 rounded-sm bg-white py-3 shadow-md`}
|
||||||
ref={helpOptionsRef}
|
ref={helpOptionsRef}
|
||||||
>
|
>
|
||||||
{helpOptions.map(({ name, Icon, href }) => (
|
{helpOptions.map(({ name, Icon, href }) => (
|
||||||
<Link href={href} key={name}>
|
<Link href={href} key={name}>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="mx-3 flex items-center gap-x-2 rounded-md px-2 py-2 text-xs hover:bg-gray-100"
|
className="mx-3 flex items-center gap-x-2 rounded-md whitespace-nowrap px-2 py-2 text-xs hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
<Icon className="h-5 w-5 text-gray-500" />
|
<Icon className="h-5 w-5 text-gray-500" />
|
||||||
<span className="text-sm">{name}</span>
|
<span className="text-sm">{name}</span>
|
||||||
|
@ -84,6 +84,8 @@ const Sidebar: React.FC<Props> = ({ toggleSidebar, setToggleSidebar }) => {
|
|||||||
|
|
||||||
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
const [isNeedHelpOpen, setIsNeedHelpOpen] = useState(false);
|
||||||
|
|
||||||
|
const helpOptionMode = sidebarCollapse ? "left-full" : "left-[-75px]";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="relative z-20 h-screen">
|
<nav className="relative z-20 h-screen">
|
||||||
<div
|
<div
|
||||||
@ -148,14 +150,14 @@ const Sidebar: React.FC<Props> = ({ toggleSidebar, setToggleSidebar }) => {
|
|||||||
leaveTo="transform opacity-0 scale-95"
|
leaveTo="transform opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="absolute bottom-0 left-full space-y-2 rounded-sm bg-white py-3 shadow-md"
|
className={`absolute bottom-2 ${helpOptionMode} space-y-2 rounded-sm bg-white py-3 shadow-md`}
|
||||||
ref={helpOptionsRef}
|
ref={helpOptionsRef}
|
||||||
>
|
>
|
||||||
{helpOptions.map(({ name, Icon, href }) => (
|
{helpOptions.map(({ name, Icon, href }) => (
|
||||||
<Link href={href} key={name}>
|
<Link href={href} key={name}>
|
||||||
<a
|
<a
|
||||||
target="_blank"
|
target="_blank"
|
||||||
className="mx-3 flex items-center gap-x-2 rounded-md px-2 py-2 text-xs hover:bg-gray-100"
|
className="mx-3 flex items-center gap-x-2 rounded-md whitespace-nowrap px-2 py-2 text-xs hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
<Icon className="h-5 w-5 text-gray-500" />
|
<Icon className="h-5 w-5 text-gray-500" />
|
||||||
<span className="text-sm">{name}</span>
|
<span className="text-sm">{name}</span>
|
||||||
|
@ -75,6 +75,11 @@ const SignInPage: NextPage = () => {
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
setToastAlert({
|
||||||
|
title: "Error signing in!",
|
||||||
|
type: "error",
|
||||||
|
message: "Something went wrong. Please try again later or contact the support team.",
|
||||||
|
});
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user