chore: empty state theme improvement (#3501)

This commit is contained in:
Anmol Singh Bhatia 2024-01-29 20:38:32 +05:30 committed by GitHub
parent 483fc57601
commit c7616fda11
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 96 additions and 40 deletions

View File

@ -2,6 +2,7 @@ import { MouseEvent } from "react";
import Link from "next/link";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import { useTheme } from "next-themes";
// hooks
import { useCycle, useIssues, useProject, useUser } from "hooks/store";
import useToast from "hooks/use-toast";
@ -43,6 +44,7 @@ interface IActiveCycleDetails {
export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = observer((props) => {
// props
const { workspaceSlug, projectId } = props;
const { resolvedTheme } = useTheme();
// store hooks
const { currentUser } = useUser();
const {
@ -76,7 +78,9 @@ export const ActiveCycleDetails: React.FC<IActiveCycleDetails> = observer((props
);
const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS["active"];
const emptyStateImage = getEmptyStateImagePath("cycle", "active", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("cycle", "active", isLightMode);
if (!activeCycle && isLoading)
return (

View File

@ -1,5 +1,6 @@
import { FC } from "react";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useUser } from "hooks/store";
// components
@ -18,11 +19,15 @@ export interface ICyclesBoard {
export const CyclesBoard: FC<ICyclesBoard> = observer((props) => {
const { cycleIds, filter, workspaceSlug, projectId, peekCycle } = props;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const { currentUser } = useUser();
const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS[filter as keyof typeof CYCLE_EMPTY_STATE_DETAILS];
const emptyStateImage = getEmptyStateImagePath("cycle", filter, currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("cycle", filter, isLightMode);
return (
<>

View File

@ -1,5 +1,6 @@
import { FC } from "react";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useUser } from "hooks/store";
// components
@ -19,11 +20,15 @@ export interface ICyclesList {
export const CyclesList: FC<ICyclesList> = observer((props) => {
const { cycleIds, filter, workspaceSlug, projectId } = props;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const { currentUser } = useUser();
const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS[filter as keyof typeof CYCLE_EMPTY_STATE_DETAILS];
const emptyStateImage = getEmptyStateImagePath("cycle", filter, currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("cycle", filter, isLightMode);
return (
<>

View File

@ -1,6 +1,7 @@
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import size from "lodash/size";
import { useTheme } from "next-themes";
// hooks
import { useIssues, useUser } from "hooks/store";
// components
@ -26,6 +27,9 @@ export const ProjectArchivedEmptyState: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
membership: { currentProjectRole },
currentUser,
@ -35,12 +39,9 @@ export const ProjectArchivedEmptyState: React.FC = observer(() => {
const userFilters = issuesFilter?.issueFilters?.filters;
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath(
"empty-filters",
activeLayout ?? "list",
currentUser?.theme.theme === "light"
);
const EmptyStateImagePath = getEmptyStateImagePath("archived", "empty-issues", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath("empty-filters", activeLayout ?? "list", isLightMode);
const EmptyStateImagePath = getEmptyStateImagePath("archived", "empty-issues", isLightMode);
const issueFilterCount = size(
Object.fromEntries(

View File

@ -1,6 +1,7 @@
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import size from "lodash/size";
import { useTheme } from "next-themes";
// hooks
import { useIssues, useUser } from "hooks/store";
// components
@ -26,6 +27,9 @@ export const ProjectDraftEmptyState: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
membership: { currentProjectRole },
currentUser,
@ -35,12 +39,9 @@ export const ProjectDraftEmptyState: React.FC = observer(() => {
const userFilters = issuesFilter?.issueFilters?.filters;
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath(
"empty-filters",
activeLayout ?? "list",
currentUser?.theme.theme === "light"
);
const EmptyStateImagePath = getEmptyStateImagePath("draft", "empty-issues", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath("empty-filters", activeLayout ?? "list", isLightMode);
const EmptyStateImagePath = getEmptyStateImagePath("draft", "empty-issues", isLightMode);
const issueFilterCount = size(
Object.fromEntries(

View File

@ -1,6 +1,7 @@
import { observer } from "mobx-react-lite";
import { useRouter } from "next/router";
import size from "lodash/size";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useIssues, useUser } from "hooks/store";
// components
@ -26,6 +27,8 @@ export const ProjectEmptyState: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: commandPaletteStore,
@ -40,12 +43,9 @@ export const ProjectEmptyState: React.FC = observer(() => {
const userFilters = issuesFilter?.issueFilters?.filters;
const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout;
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath(
"empty-filters",
activeLayout ?? "list",
currentUser?.theme.theme === "light"
);
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "issues", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const currentLayoutEmptyStateImagePath = getEmptyStateImagePath("empty-filters", activeLayout ?? "list", isLightMode);
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "issues", isLightMode);
const issueFilterCount = size(
Object.fromEntries(

View File

@ -3,6 +3,7 @@ import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import isEmpty from "lodash/isEmpty";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useGlobalView, useIssues, useProject, useUser } from "hooks/store";
import { useWorkspaceIssueProperties } from "hooks/use-workspace-issue-properties";
@ -25,6 +26,8 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, globalViewId } = router.query;
// theme
const { resolvedTheme } = useTheme();
//swr hook for fetching issue properties
useWorkspaceIssueProperties(workspaceSlug);
// store
@ -46,7 +49,8 @@ export const AllIssueLayoutRoot: React.FC = observer(() => {
const currentView = isDefaultView ? groupedIssueIds.dataViewId : "custom-view";
const currentViewDetails = ALL_ISSUES_EMPTY_STATE_DETAILS[currentView as keyof typeof ALL_ISSUES_EMPTY_STATE_DETAILS];
const emptyStateImage = getEmptyStateImagePath("all-issues", currentView, currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("all-issues", currentView, isLightMode);
// filter init from the query params

View File

@ -1,5 +1,6 @@
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useModule, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage";
@ -15,6 +16,8 @@ export const ModulesListView: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, projectId, peekModule } = router.query;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const { commandPalette: commandPaletteStore } = useApplication();
const {
@ -25,7 +28,8 @@ export const ModulesListView: React.FC = observer(() => {
const { storedValue: modulesView } = useLocalStorage("modules_view", "grid");
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "modules", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "modules", isLightMode);
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;

View File

@ -1,4 +1,5 @@
import { useEffect } from "react";
import { useTheme } from "next-themes";
import { observer } from "mobx-react-lite";
// hooks
import { useApplication, useDashboard, useProject, useUser } from "hooks/store";
@ -14,6 +15,8 @@ import { Spinner } from "@plane/ui";
import { EUserWorkspaceRoles } from "constants/workspace";
export const WorkspaceDashboardView = observer(() => {
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: { toggleCreateProjectModal },
@ -28,7 +31,8 @@ export const WorkspaceDashboardView = observer(() => {
const { homeDashboardId, fetchHomeDashboardWidgets } = useDashboard();
const { joinedProjectIds } = useProject();
const emptyStateImage = getEmptyStateImagePath("onboarding", "dashboard", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("onboarding", "dashboard", isLightMode);
const handleTourCompleted = () => {
updateTourCompleted()

View File

@ -1,5 +1,6 @@
import { FC } from "react";
import { useRouter } from "next/router";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage";
@ -18,7 +19,9 @@ type IPagesListView = {
export const PagesListView: FC<IPagesListView> = (props) => {
const { pageIds: projectPageIds } = props;
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: { toggleCreatePageModal },
} = useApplication();
@ -36,11 +39,8 @@ export const PagesListView: FC<IPagesListView> = (props) => {
? PAGE_EMPTY_STATE_DETAILS[pageTab as keyof typeof PAGE_EMPTY_STATE_DETAILS]
: PAGE_EMPTY_STATE_DETAILS["All"];
const emptyStateImage = getEmptyStateImagePath(
"pages",
currentPageTabDetails.key,
currentUser?.theme.theme === "light"
);
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("pages", currentPageTabDetails.key, isLightMode);
const isButtonVisible = currentPageTabDetails.key !== "archived" && currentPageTabDetails.key !== "favorites";

View File

@ -1,5 +1,6 @@
import React, { FC } from "react";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useUser } from "hooks/store";
import { useProjectPages } from "hooks/store/use-project-specific-pages";
@ -14,6 +15,8 @@ import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
import { EUserProjectRoles } from "constants/project";
export const RecentPagesList: FC = observer(() => {
// theme
const { resolvedTheme } = useTheme();
// store hooks
const { commandPalette: commandPaletteStore } = useApplication();
const {
@ -22,7 +25,8 @@ export const RecentPagesList: FC = observer(() => {
} = useUser();
const { recentProjectPages } = useProjectPages();
const EmptyStateImagePath = getEmptyStateImagePath("pages", "recent", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("pages", "recent", isLightMode);
// FIXME: replace any with proper type
const isEmpty = recentProjectPages && Object.values(recentProjectPages).every((value: any) => value.length === 0);

View File

@ -2,6 +2,7 @@ import React from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// components
import { ProfileIssuesListLayout } from "components/issues/issue-layouts/list/roots/profile-issues-root";
import { ProfileIssuesKanBanLayout } from "components/issues/issue-layouts/kanban/roots/profile-issues-root";
@ -27,6 +28,9 @@ export const ProfileIssuesPage = observer((props: IProfileIssuesPage) => {
workspaceSlug: string;
userId: string;
};
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
membership: { currentWorkspaceRole },
currentUser,
@ -46,7 +50,8 @@ export const ProfileIssuesPage = observer((props: IProfileIssuesPage) => {
}
);
const emptyStateImage = getEmptyStateImagePath("profile", type, currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("profile", type, isLightMode);
const activeLayout = issueFilters?.displayFilters?.layout || undefined;

View File

@ -1,16 +1,17 @@
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useProject, useUser } from "hooks/store";
// components
import { ProjectCard } from "components/project";
import { Loader } from "@plane/ui";
import { EmptyState, getEmptyStateImagePath } from "components/empty-state";
// icons
import { Plus } from "lucide-react";
// constants
import { EUserWorkspaceRoles } from "constants/workspace";
export const ProjectCardList = observer(() => {
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: commandPaletteStore,
@ -22,7 +23,8 @@ export const ProjectCardList = observer(() => {
} = useUser();
const { workspaceProjectIds, searchedProjects, getProjectById } = useProject();
const emptyStateImage = getEmptyStateImagePath("onboarding", "projects", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const emptyStateImage = getEmptyStateImagePath("onboarding", "projects", isLightMode);
const isEditingAllowed = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;

View File

@ -1,6 +1,7 @@
import { useState } from "react";
import { observer } from "mobx-react-lite";
import { Search } from "lucide-react";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useProjectView, useUser } from "hooks/store";
// components
@ -14,6 +15,8 @@ import { EUserProjectRoles } from "constants/project";
export const ProjectViewsList = observer(() => {
// states
const [query, setQuery] = useState("");
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: { toggleCreateViewModal },
@ -43,7 +46,8 @@ export const ProjectViewsList = observer(() => {
const viewsList = projectViewIds.map((viewId) => getViewById(viewId));
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "views", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "views", isLightMode);
const filteredViewsList = viewsList.filter((v) => v?.name.toLowerCase().includes(query.toLowerCase()));

View File

@ -1,6 +1,7 @@
import React, { Fragment, ReactElement } from "react";
import { observer } from "mobx-react-lite";
import { Tab } from "@headlessui/react";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useProject, useUser } from "hooks/store";
// layouts
@ -16,6 +17,8 @@ import { EUserWorkspaceRoles } from "constants/workspace";
import { NextPageWithLayout } from "lib/types";
const AnalyticsPage: NextPageWithLayout = observer(() => {
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
commandPalette: { toggleCreateProjectModal },
@ -27,7 +30,8 @@ const AnalyticsPage: NextPageWithLayout = observer(() => {
} = useUser();
const { workspaceProjectIds } = useProject();
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "analytics", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "analytics", isLightMode);
const isEditingAllowed = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
return (

View File

@ -2,6 +2,7 @@ import { Fragment, useCallback, useState, ReactElement } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import { Tab } from "@headlessui/react";
import { useTheme } from "next-themes";
// hooks
import { useCycle, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage";
@ -22,6 +23,8 @@ import { EUserWorkspaceRoles } from "constants/workspace";
const ProjectCyclesPage: NextPageWithLayout = observer(() => {
const [createModal, setCreateModal] = useState(false);
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
membership: { currentProjectRole },
@ -49,7 +52,9 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
},
[handleCurrentLayout, setCycleTab]
);
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "cycles", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "cycles", isLightMode);
const totalCycles = currentProjectCycleIds?.length ?? 0;

View File

@ -4,6 +4,7 @@ import dynamic from "next/dynamic";
import { Tab } from "@headlessui/react";
import useSWR from "swr";
import { observer } from "mobx-react-lite";
import { useTheme } from "next-themes";
// hooks
import { useApplication, useUser } from "hooks/store";
import useLocalStorage from "hooks/use-local-storage";
@ -48,7 +49,9 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
const { workspaceSlug, projectId } = router.query;
// states
const [createUpdatePageModal, setCreateUpdatePageModal] = useState(false);
// store
// theme
const { resolvedTheme } = useTheme();
// store hooks
const {
currentUser,
currentUserLoader,
@ -94,7 +97,8 @@ const ProjectPagesPage: NextPageWithLayout = observer(() => {
}
};
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "pages", currentUser?.theme.theme === "light");
const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light";
const EmptyStateImagePath = getEmptyStateImagePath("onboarding", "pages", isLightMode);
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserWorkspaceRoles.MEMBER;