mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: UI/UX improvements (#3319)
* chore: add proper message for cycle/ module having start & end date but isn't active yet. * fix: infinite loader after updating workspace settings. * fix: user profile icon dropdown doesn't closes automatically. * style: fix inconsistent padding in cycle empty state. * chore: remove multiple `empty state` in labels settings and improve add label logic. * style: fix inconsistent padding in project label, integration and estimates empty state. * style: fix integrations settings breadcrumb title. * style: add proper `disabled` styles for email field in profile settings. * style: fix cycle layout height.
This commit is contained in:
parent
d98b688342
commit
9dd8c8ba14
@ -43,7 +43,7 @@ export const NewEmptyState: React.FC<Props> = ({
|
||||
return (
|
||||
<div className="flex items-center justify-center overflow-y-auto">
|
||||
<div className=" flex h-full w-full flex-col items-center justify-center ">
|
||||
<div className="m-5 flex max-w-6xl flex-col gap-5 rounded-xl border border-custom-border-200 px-10 py-7 shadow-sm md:m-16">
|
||||
<div className="m-5 flex max-w-6xl flex-col gap-5 rounded-xl border border-custom-border-200 px-10 py-7 shadow-sm md:m-8">
|
||||
<h3 className="text-2xl font-semibold">{title}</h3>
|
||||
{description && <p className=" text-lg">{description}</p>}
|
||||
<div className="relative w-full max-w-6xl">
|
||||
|
@ -539,7 +539,9 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
<div className="flex items-center gap-1">
|
||||
<AlertCircle height={14} width={14} className="text-custom-text-200" />
|
||||
<span className="text-xs italic text-custom-text-200">
|
||||
Invalid date. Please enter valid date.
|
||||
{cycleDetails?.start_date && cycleDetails?.end_date
|
||||
? "This cycle isn't active yet."
|
||||
: "Invalid date. Please enter valid date."}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
@ -102,7 +102,7 @@ export const EstimatesList: React.FC = observer(() => {
|
||||
))}
|
||||
</section>
|
||||
) : (
|
||||
<div className="h-full w-full overflow-y-auto">
|
||||
<div className="w-full py-8">
|
||||
<EmptyState
|
||||
title="No estimates yet"
|
||||
description="Estimates help you communicate the complexity of an issue."
|
||||
|
@ -96,9 +96,9 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
||||
Add label
|
||||
</Button>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<div className="w-full py-8">
|
||||
{showLabelForm && (
|
||||
<div className="w-full rounded border border-custom-border-200 px-3.5 py-2">
|
||||
<div className="w-full rounded border border-custom-border-200 px-3.5 py-2 my-2">
|
||||
<CreateUpdateLabelInline
|
||||
labelForm={showLabelForm}
|
||||
setLabelForm={setLabelForm}
|
||||
@ -112,7 +112,7 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
||||
</div>
|
||||
)}
|
||||
{projectLabels ? (
|
||||
projectLabels.length === 0 ? (
|
||||
projectLabels.length === 0 && !showLabelForm ? (
|
||||
<EmptyState
|
||||
title="No labels yet"
|
||||
description="Create labels to help organize and filter issues in you project"
|
||||
@ -203,25 +203,14 @@ export const ProjectSettingsLabelList: React.FC = observer(() => {
|
||||
)
|
||||
)
|
||||
) : (
|
||||
!showLabelForm && (
|
||||
<Loader className="space-y-5">
|
||||
<Loader.Item height="42px" />
|
||||
<Loader.Item height="42px" />
|
||||
<Loader.Item height="42px" />
|
||||
<Loader.Item height="42px" />
|
||||
</Loader>
|
||||
)}
|
||||
|
||||
{/* empty state */}
|
||||
{projectLabels && projectLabels.length === 0 && (
|
||||
<EmptyState
|
||||
title="No labels yet"
|
||||
description="Create labels to help organize and filter issues in your project."
|
||||
image={emptyLabel}
|
||||
primaryButton={{
|
||||
text: "Add label",
|
||||
onClick: () => newLabel(),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
|
@ -550,7 +550,9 @@ export const ModuleDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
<div className="flex items-center gap-1">
|
||||
<AlertCircle height={14} width={14} className="text-custom-text-200" />
|
||||
<span className="text-xs italic text-custom-text-200">
|
||||
Invalid date. Please enter valid date.
|
||||
{moduleDetails?.start_date && moduleDetails?.target_date
|
||||
? "This module isn't active yet."
|
||||
: "Invalid date. Please enter valid date."}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
@ -278,14 +278,14 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
||||
<div className="flex flex-col gap-2.5 pb-2">
|
||||
<span className="px-2 text-custom-sidebar-text-200">{currentUser?.email}</span>
|
||||
{profileLinks(workspaceSlug?.toString() ?? "", currentUser?.id ?? "").map((link, index) => (
|
||||
<Menu.Item key={index} as="button" type="button">
|
||||
<Link href={link.link}>
|
||||
<Link key={index} href={link.link}>
|
||||
<Menu.Item key={index} as="div">
|
||||
<span className="flex w-full items-center gap-2 rounded px-2 py-1 hover:bg-custom-sidebar-background-80">
|
||||
<link.icon className="h-4 w-4 stroke-[1.5]" />
|
||||
{link.name}
|
||||
</span>
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
<div className={`pt-2 ${isUserInstanceAdmin ? "pb-2" : ""}`}>
|
||||
@ -301,13 +301,13 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
||||
</div>
|
||||
{isUserInstanceAdmin && (
|
||||
<div className="p-2 pb-0">
|
||||
<Menu.Item as="button" type="button" className="w-full">
|
||||
<Link href="/god-mode">
|
||||
<Menu.Item as="button" type="button" className="w-full">
|
||||
<span className="flex w-full items-center justify-center rounded bg-custom-primary-100/20 px-2 py-1 text-sm font-medium text-custom-primary-100 hover:bg-custom-primary-100/30 hover:text-custom-primary-200">
|
||||
Enter God Mode
|
||||
</span>
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</Menu.Items>
|
||||
|
@ -59,7 +59,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
||||
if (!workspaceSlug || !projectId) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-full">
|
||||
<CycleCreateUpdateModal
|
||||
workspaceSlug={workspaceSlug.toString()}
|
||||
projectId={projectId.toString()}
|
||||
@ -67,7 +67,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
||||
handleClose={() => setCreateModal(false)}
|
||||
/>
|
||||
{totalCycles === 0 ? (
|
||||
<div className="grid h-full place-items-center">
|
||||
<div className="h-full place-items-center">
|
||||
<NewEmptyState
|
||||
title="Group and timebox your work in Cycles."
|
||||
description="Break work down by timeboxed chunks, work backwards from your project deadline to set dates, and make tangible progress as a team."
|
||||
@ -194,7 +194,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
||||
</Tab.Panels>
|
||||
</Tab.Group>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -54,6 +54,7 @@ const ProjectIntegrationsPage: NextPageWithLayout = () => {
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full py-8">
|
||||
<EmptyState
|
||||
title="You haven't configured integrations"
|
||||
description="Configure GitHub and other integrations to sync your project issues."
|
||||
@ -64,6 +65,7 @@ const ProjectIntegrationsPage: NextPageWithLayout = () => {
|
||||
}}
|
||||
disabled={!isAdmin}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<Loader className="space-y-5">
|
||||
|
@ -65,7 +65,7 @@ const WorkspaceIntegrationsPage: NextPageWithLayout = observer(() => {
|
||||
|
||||
WorkspaceIntegrationsPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return (
|
||||
<AppLayout header={<WorkspaceSettingHeader title="Export Settings" />}>
|
||||
<AppLayout header={<WorkspaceSettingHeader title="Integrations Settings" />}>
|
||||
<WorkspaceSettingLayout>{page}</WorkspaceSettingLayout>
|
||||
</AppLayout>
|
||||
);
|
||||
|
@ -218,7 +218,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => {
|
||||
<div className="grid grid-cols-1 gap-6 px-8 lg:grid-cols-2 2xl:grid-cols-3">
|
||||
<div className="flex flex-col gap-1">
|
||||
<h4 className="text-sm">
|
||||
First name <span className="text-red-500">*</span>
|
||||
First name<span className="text-red-500">*</span>
|
||||
</h4>
|
||||
<Controller
|
||||
control={control}
|
||||
@ -275,17 +275,16 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => {
|
||||
rules={{
|
||||
required: "Email is required.",
|
||||
}}
|
||||
render={({ field: { value, onChange, ref } }) => (
|
||||
render={({ field: { value, ref } }) => (
|
||||
<Input
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
ref={ref}
|
||||
hasError={Boolean(errors.email)}
|
||||
placeholder="Enter your email"
|
||||
className={`w-full rounded-md ${errors.email ? "border-red-500" : ""}`}
|
||||
className={`w-full rounded-md cursor-not-allowed !bg-custom-background-80 ${errors.email ? "border-red-500" : ""}`}
|
||||
disabled
|
||||
/>
|
||||
)}
|
||||
|
@ -14,10 +14,9 @@ import {
|
||||
IWorkspaceBulkInviteFormData,
|
||||
IWorkspaceViewProps,
|
||||
IUserProjectsRole,
|
||||
TIssueMap,
|
||||
TIssue,
|
||||
IWorkspaceView,
|
||||
} from "@plane/types";
|
||||
import { IWorkspaceView } from "@plane/types";
|
||||
|
||||
export class WorkspaceService extends APIService {
|
||||
constructor() {
|
||||
|
@ -135,7 +135,7 @@ export class WorkspaceRootStore implements IWorkspaceRootStore {
|
||||
updateWorkspace = async (workspaceSlug: string, data: Partial<IWorkspace>) =>
|
||||
await this.workspaceService.updateWorkspace(workspaceSlug, data).then((response) => {
|
||||
runInAction(() => {
|
||||
set(this.workspaces, response.id, data);
|
||||
set(this.workspaces, response.id, response);
|
||||
});
|
||||
return response;
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user