chore: empty state revamp and loader improvement (#3448)

* chore: empty state asset added

* chore: empty state asset updated and image path helper function added

* chore: empty state asset updated

* chore: empty state asset updated and empty state details constant added

* chore: empty state component, helper function and comicbox button added

* chore: draft, archived and project issue empty state

* chore: cycle, module and issue layout empty state

* chore: analytics, dashboard, all issues, pages and project view empty state

* chore:projects empty state

* chore:projects empty state improvement

* chore: cycle, module, view and page loader improvement

* chore: code refactor
This commit is contained in:
Anmol Singh Bhatia 2024-01-24 19:12:54 +05:30 committed by GitHub
parent 1a1594e818
commit 87f39d7372
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
105 changed files with 897 additions and 285 deletions

View file

@ -2,7 +2,6 @@ import { Fragment, useCallback, useState, ReactElement } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { Tab } from "@headlessui/react";
import { Plus } from "lucide-react";
// hooks
import { useCycle, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage";
@ -11,11 +10,9 @@ import { AppLayout } from "layouts/app-layout";
// components
import { CyclesHeader } from "components/headers";
import { CyclesView, ActiveCycleDetails, CycleCreateUpdateModal } from "components/cycles";
import { NewEmptyState } from "components/common/new-empty-state";
import { EmptyState, getEmptyStateImagePath } from "components/empty-state";
// ui
import { Tooltip } from "@plane/ui";
// images
import emptyCycle from "public/empty-state/empty_cycles.webp";
import { Spinner, Tooltip } from "@plane/ui";
// types
import { TCycleView, TCycleLayout } from "@plane/types";
import { NextPageWithLayout } from "lib/types";
@ -28,8 +25,9 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
// store hooks
const {
membership: { currentProjectRole },
currentUser,
} = useUser();
const { currentProjectCycleIds } = useCycle();
const { currentProjectCycleIds, loader } = useCycle();
// router
const router = useRouter();
const { workspaceSlug, projectId, peekCycle } = router.query;
@ -51,6 +49,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
},
[handleCurrentLayout, setCycleTab]
);
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "cycles", currentUser?.theme.theme === "light");
const totalCycles = currentProjectCycleIds?.length ?? 0;
@ -58,6 +57,13 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
if (!workspaceSlug || !projectId) return null;
if (loader)
return (
<div className="flex items-center justify-center h-full w-full">
<Spinner />
</div>
);
return (
<div className="w-full h-full">
<CycleCreateUpdateModal
@ -68,23 +74,22 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
/>
{totalCycles === 0 ? (
<div className="h-full place-items-center">
<NewEmptyState
<EmptyState
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."
image={emptyCycle}
image={EmptyStateImagePath}
comicBox={{
title: "Cycles are repetitive time-boxes.",
direction: "right",
description:
"A sprint, an iteration, and or any other term you use for weekly or fortnightly tracking of work is a cycle.",
}}
primaryButton={{
icon: <Plus className="h-4 w-4" />,
text: "Set your first cycle",
onClick: () => {
setCreateModal(true);
},
}}
size="lg"
disabled={!isEditingAllowed}
/>
</div>

View file

@ -13,6 +13,7 @@ import { AppLayout } from "layouts/app-layout";
// components
import { RecentPagesList, CreateUpdatePageModal } from "components/pages";
import { PagesHeader } from "components/headers";
import { Spinner } from "@plane/ui";
// types
import { NextPageWithLayout } from "lib/types";
// constants
@ -48,7 +49,7 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
// store
const { currentUser, currentUserLoader } = useUser();
const { fetchProjectPages, fetchArchivedProjectPages } = useProjectPages();
const { fetchProjectPages, fetchArchivedProjectPages, loader } = useProjectPages();
// hooks
const {} = useUserAuth({ user: currentUser, isLoading: currentUserLoader });
// local storage
@ -83,6 +84,13 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
}
};
if (loader)
return (
<div className="flex items-center justify-center h-full w-full">
<Spinner />
</div>
);
return (
<>
{workspaceSlug && projectId && (