diff --git a/web/components/core/sidebar/sidebar-menu-hamburger-toggle.tsx b/web/components/core/sidebar/sidebar-menu-hamburger-toggle.tsx index b732d8f95..cb433de05 100644 --- a/web/components/core/sidebar/sidebar-menu-hamburger-toggle.tsx +++ b/web/components/core/sidebar/sidebar-menu-hamburger-toggle.tsx @@ -3,12 +3,20 @@ import { Menu } from "lucide-react"; import { useApplication } from "hooks/store"; import { observer } from "mobx-react"; -export const SidebarHamburgerToggle: FC = observer(() => { - const { theme: themStore } = useApplication(); +type Props = { + onClick?: () => void; +} + +export const SidebarHamburgerToggle: FC = observer((props) => { + const { onClick } = props + const { theme: themeStore } = useApplication(); return (
themStore.toggleMobileSidebar()} + onClick={() => { + if (onClick) onClick() + else themeStore.toggleMobileSidebar() + }} >
diff --git a/web/components/cycles/cycles-board-card.tsx b/web/components/cycles/cycles-board-card.tsx index 07e946c80..e96b01858 100644 --- a/web/components/cycles/cycles-board-card.tsx +++ b/web/components/cycles/cycles-board-card.tsx @@ -1,6 +1,7 @@ import { FC, MouseEvent, useState } from "react"; import { useRouter } from "next/router"; import Link from "next/link"; +import { observer } from "mobx-react"; // hooks import { useEventTracker, useCycle, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; @@ -26,7 +27,7 @@ export interface ICyclesBoardCard { cycleId: string; } -export const CyclesBoardCard: FC = (props) => { +export const CyclesBoardCard: FC = observer((props) => { const { cycleId, workspaceSlug, projectId } = props; // states const [updateModal, setUpdateModal] = useState(false); @@ -69,8 +70,8 @@ export const CyclesBoardCard: FC = (props) => { ? cycleTotalIssues === 0 ? "0 Issue" : cycleTotalIssues === cycleDetails.completed_issues - ? `${cycleTotalIssues} Issue${cycleTotalIssues > 1 ? "s" : ""}` - : `${cycleDetails.completed_issues}/${cycleTotalIssues} Issues` + ? `${cycleTotalIssues} Issue${cycleTotalIssues > 1 ? "s" : ""}` + : `${cycleDetails.completed_issues}/${cycleTotalIssues} Issues` : "0 Issue"; const handleCopyText = (e: MouseEvent) => { @@ -295,4 +296,4 @@ export const CyclesBoardCard: FC = (props) => { ); -}; +}); diff --git a/web/components/cycles/cycles-list-item.tsx b/web/components/cycles/cycles-list-item.tsx index da2654aaf..ed2b26c53 100644 --- a/web/components/cycles/cycles-list-item.tsx +++ b/web/components/cycles/cycles-list-item.tsx @@ -1,6 +1,7 @@ import { FC, MouseEvent, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/router"; +import { observer } from "mobx-react"; // hooks import { useEventTracker, useCycle, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; @@ -30,7 +31,7 @@ type TCyclesListItem = { projectId: string; }; -export const CyclesListItem: FC = (props) => { +export const CyclesListItem: FC = observer((props) => { const { cycleId, workspaceSlug, projectId } = props; // states const [updateModal, setUpdateModal] = useState(false); @@ -289,4 +290,4 @@ export const CyclesListItem: FC = (props) => { ); -}; +}); diff --git a/web/components/issues/issue-detail/sidebar.tsx b/web/components/issues/issue-detail/sidebar.tsx index c78bbe942..1c93385c0 100644 --- a/web/components/issues/issue-detail/sidebar.tsx +++ b/web/components/issues/issue-detail/sidebar.tsx @@ -15,7 +15,7 @@ import { CalendarCheck2, } from "lucide-react"; // hooks -import { useEstimate, useIssueDetail, useProject, useProjectState, useUser } from "hooks/store"; +import { useEstimate, useIssueDetail, useProject, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components import { @@ -56,11 +56,9 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { const { workspaceSlug, projectId, issueId, issueOperations, is_archived, is_editable } = props; // router const router = useRouter(); - const { inboxIssueId } = router.query; // store hooks const { getProjectById } = useProject(); const { currentUser } = useUser(); - const { projectStates } = useProjectState(); const { areEstimatesEnabledForCurrentProject } = useEstimate(); const { setToastAlert } = useToast(); const { @@ -91,8 +89,6 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { const maxDate = issue.target_date ? new Date(issue.target_date) : null; maxDate?.setDate(maxDate.getDate()); - const currentIssueState = projectStates?.find((s) => s.id === issue.state_id); - return ( <> {workspaceSlug && projectId && issue && ( @@ -108,22 +104,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { )}
-
-
- {currentIssueState ? ( - - ) : inboxIssueId ? ( - - ) : null} -

- {projectDetails?.identifier}-{issue?.sequence_id} -

-
- +
{currentUser && !is_archived && ( @@ -187,8 +168,9 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"} className="w-3/5 flex-grow group" buttonContainerClassName="w-full text-left" - buttonClassName={`text-sm justify-between ${issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400" - }`} + buttonClassName={`text-sm justify-between ${ + issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400" + }`} hideIcon={issue.assignee_ids?.length === 0} dropdownArrow dropdownArrowClassName="h-3.5 w-3.5 hidden group-hover:inline" @@ -232,8 +214,8 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`} hideIcon clearIconClassName="h-3 w-3 hidden group-hover:inline" - // TODO: add this logic - // showPlaceholderIcon + // TODO: add this logic + // showPlaceholderIcon />
@@ -258,8 +240,8 @@ export const IssueDetailsSidebar: React.FC = observer((props) => { buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`} hideIcon clearIconClassName="h-3 w-3 hidden group-hover:inline" - // TODO: add this logic - // showPlaceholderIcon + // TODO: add this logic + // showPlaceholderIcon />
diff --git a/web/components/issues/issue-layouts/empty-states/cycle.tsx b/web/components/issues/issue-layouts/empty-states/cycle.tsx index baf2abb70..69c2279dd 100644 --- a/web/components/issues/issue-layouts/empty-states/cycle.tsx +++ b/web/components/issues/issue-layouts/empty-states/cycle.tsx @@ -1,29 +1,42 @@ import { useState } from "react"; import { observer } from "mobx-react-lite"; import { PlusIcon } from "lucide-react"; +import { useTheme } from "next-themes"; // hooks import { useApplication, useEventTracker, useIssueDetail, useIssues, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components import { ExistingIssuesListModal } from "components/core"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // types import { ISearchIssueResponse, TIssueLayouts } from "@plane/types"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssuesStoreType } from "constants/issue"; -import { CYCLE_EMPTY_STATE_DETAILS } from "constants/empty-state"; -import { useTheme } from "next-themes"; -import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; +import { CYCLE_EMPTY_STATE_DETAILS, EMPTY_FILTER_STATE_DETAILS } from "constants/empty-state"; type Props = { workspaceSlug: string | undefined; projectId: string | undefined; cycleId: string | undefined; activeLayout: TIssueLayouts | undefined; + handleClearAllFilters: () => void; + isEmptyFilters?: boolean; }; +interface EmptyStateProps { + title: string; + image: string; + description?: string; + comicBox?: { title: string; description: string }; + primaryButton?: { text: string; icon?: React.ReactNode; onClick: () => void }; + secondaryButton?: { text: string; icon?: React.ReactNode; onClick: () => void }; + size?: "lg" | "sm" | undefined; + disabled?: boolean | undefined; +} + export const CycleEmptyState: React.FC = observer((props) => { - const { workspaceSlug, projectId, cycleId, activeLayout } = props; + const { workspaceSlug, projectId, cycleId, activeLayout, handleClearAllFilters, isEmptyFilters = false } = props; // states const [cycleIssuesListModal, setCycleIssuesListModal] = useState(false); // theme @@ -65,10 +78,41 @@ export const CycleEmptyState: React.FC = observer((props) => { const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS["no-issues"]; const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; + const currentLayoutEmptyStateImagePath = getEmptyStateImagePath("empty-filters", activeLayout ?? "list", isLightMode); const emptyStateImage = getEmptyStateImagePath("cycle-issues", activeLayout ?? "list", isLightMode); const isEditingAllowed = !!userRole && userRole >= EUserProjectRoles.MEMBER; + const emptyStateProps: EmptyStateProps = isEmptyFilters + ? { + title: EMPTY_FILTER_STATE_DETAILS["project"].title, + image: currentLayoutEmptyStateImagePath, + secondaryButton: { + text: EMPTY_FILTER_STATE_DETAILS["project"].secondaryButton.text, + onClick: handleClearAllFilters, + }, + } + : { + title: emptyStateDetail.title, + description: emptyStateDetail.description, + image: emptyStateImage, + primaryButton: { + text: emptyStateDetail.primaryButton.text, + icon: , + onClick: () => { + setTrackElement("Cycle issue empty state"); + toggleCreateIssueModal(true, EIssuesStoreType.CYCLE); + }, + }, + secondaryButton: { + text: emptyStateDetail.secondaryButton.text, + icon: , + onClick: () => setCycleIssuesListModal(true), + }, + size: "sm", + disabled: !isEditingAllowed, + }; + return ( <> = observer((props) => { handleOnSubmit={handleAddIssuesToCycle} />
- , - onClick: () => { - setTrackElement("Cycle issue empty state"); - toggleCreateIssueModal(true, EIssuesStoreType.CYCLE); - }, - }} - secondaryButton={{ - text: emptyStateDetail.secondaryButton.text, - icon: , - onClick: () => setCycleIssuesListModal(true), - }} - size="sm" - disabled={!isEditingAllowed} - /> +
); diff --git a/web/components/issues/issue-layouts/empty-states/module.tsx b/web/components/issues/issue-layouts/empty-states/module.tsx index 4285368e9..ef7ec729c 100644 --- a/web/components/issues/issue-layouts/empty-states/module.tsx +++ b/web/components/issues/issue-layouts/empty-states/module.tsx @@ -1,29 +1,42 @@ import { useState } from "react"; import { observer } from "mobx-react-lite"; import { PlusIcon } from "lucide-react"; +import { useTheme } from "next-themes"; // hooks import { useApplication, useEventTracker, useIssues, useUser } from "hooks/store"; import useToast from "hooks/use-toast"; // components import { ExistingIssuesListModal } from "components/core"; +import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; // types import { ISearchIssueResponse, TIssueLayouts } from "@plane/types"; // constants import { EUserProjectRoles } from "constants/project"; import { EIssuesStoreType } from "constants/issue"; -import { MODULE_EMPTY_STATE_DETAILS } from "constants/empty-state"; -import { useTheme } from "next-themes"; -import { EmptyState, getEmptyStateImagePath } from "components/empty-state"; +import { EMPTY_FILTER_STATE_DETAILS, MODULE_EMPTY_STATE_DETAILS } from "constants/empty-state"; type Props = { workspaceSlug: string | undefined; projectId: string | undefined; moduleId: string | undefined; activeLayout: TIssueLayouts | undefined; + handleClearAllFilters: () => void; + isEmptyFilters?: boolean; }; +interface EmptyStateProps { + title: string; + image: string; + description?: string; + comicBox?: { title: string; description: string }; + primaryButton?: { text: string; icon?: React.ReactNode; onClick: () => void }; + secondaryButton?: { text: string; icon?: React.ReactNode; onClick: () => void }; + size?: "lg" | "sm" | undefined; + disabled?: boolean | undefined; +} + export const ModuleEmptyState: React.FC = observer((props) => { - const { workspaceSlug, projectId, moduleId, activeLayout } = props; + const { workspaceSlug, projectId, moduleId, activeLayout, handleClearAllFilters, isEmptyFilters = false } = props; // states const [moduleIssuesListModal, setModuleIssuesListModal] = useState(false); // theme @@ -59,10 +72,40 @@ export const ModuleEmptyState: React.FC = observer((props) => { const emptyStateDetail = MODULE_EMPTY_STATE_DETAILS["no-issues"]; const isLightMode = resolvedTheme ? resolvedTheme === "light" : currentUser?.theme.theme === "light"; - const emptyStateImage = getEmptyStateImagePath("cycle-issues", activeLayout ?? "list", isLightMode); + const currentLayoutEmptyStateImagePath = getEmptyStateImagePath("empty-filters", activeLayout ?? "list", isLightMode); + const emptyStateImage = getEmptyStateImagePath("module-issues", activeLayout ?? "list", isLightMode); const isEditingAllowed = !!userRole && userRole >= EUserProjectRoles.MEMBER; + const emptyStateProps: EmptyStateProps = isEmptyFilters + ? { + title: EMPTY_FILTER_STATE_DETAILS["project"].title, + image: currentLayoutEmptyStateImagePath, + secondaryButton: { + text: EMPTY_FILTER_STATE_DETAILS["project"].secondaryButton.text, + onClick: handleClearAllFilters, + }, + } + : { + title: emptyStateDetail.title, + description: emptyStateDetail.description, + image: emptyStateImage, + primaryButton: { + text: emptyStateDetail.primaryButton.text, + icon: , + onClick: () => { + setTrackElement("Module issue empty state"); + toggleCreateIssueModal(true, EIssuesStoreType.MODULE); + }, + }, + secondaryButton: { + text: emptyStateDetail.secondaryButton.text, + icon: , + onClick: () => setModuleIssuesListModal(true), + }, + disabled: !isEditingAllowed, + }; + return ( <> = observer((props) => { handleOnSubmit={handleAddIssuesToModule} />
- , - onClick: () => { - setTrackElement("Module issue empty state"); - toggleCreateIssueModal(true, EIssuesStoreType.MODULE); - }, - }} - secondaryButton={{ - text: emptyStateDetail.secondaryButton.text, - icon: , - onClick: () => setModuleIssuesListModal(true), - }} - disabled={!isEditingAllowed} - /> +
); diff --git a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx index 402103072..4f7088c38 100644 --- a/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/cycle-layout-root.tsx @@ -2,6 +2,7 @@ import React, { Fragment, useState } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import useSWR from "swr"; +import size from "lodash/size"; // hooks import { useCycle, useIssues } from "hooks/store"; // components @@ -18,7 +19,9 @@ import { import { TransferIssues, TransferIssuesModal } from "components/cycles"; import { ActiveLoader } from "components/ui"; // constants -import { EIssuesStoreType } from "constants/issue"; +import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +// types +import { IIssueFilterOptions } from "@plane/types"; export const CycleLayoutRoot: React.FC = observer(() => { const router = useRouter(); @@ -51,6 +54,31 @@ export const CycleLayoutRoot: React.FC = observer(() => { const cycleDetails = cycleId ? getCycleById(cycleId.toString()) : undefined; const cycleStatus = cycleDetails?.status?.toLocaleLowerCase() ?? "draft"; + const userFilters = issuesFilter?.issueFilters?.filters; + + const issueFilterCount = size( + Object.fromEntries( + Object.entries(userFilters ?? {}).filter(([, value]) => value && Array.isArray(value) && value.length > 0) + ) + ); + + const handleClearAllFilters = () => { + if (!workspaceSlug || !projectId || !cycleId) return; + const newFilters: IIssueFilterOptions = {}; + Object.keys(userFilters ?? {}).forEach((key) => { + newFilters[key as keyof IIssueFilterOptions] = null; + }); + issuesFilter.updateFilters( + workspaceSlug.toString(), + projectId.toString(), + EIssueFilterType.FILTERS, + { + ...newFilters, + }, + cycleId.toString() + ); + }; + if (!workspaceSlug || !projectId || !cycleId) return <>; if (issues?.loader === "init-loader" || !issues?.groupedIssueIds) { @@ -71,6 +99,8 @@ export const CycleLayoutRoot: React.FC = observer(() => { projectId={projectId.toString()} cycleId={cycleId.toString()} activeLayout={activeLayout} + handleClearAllFilters={handleClearAllFilters} + isEmptyFilters={issueFilterCount > 0} />
) : ( diff --git a/web/components/issues/issue-layouts/roots/module-layout-root.tsx b/web/components/issues/issue-layouts/roots/module-layout-root.tsx index dfce3022f..b7978c7bc 100644 --- a/web/components/issues/issue-layouts/roots/module-layout-root.tsx +++ b/web/components/issues/issue-layouts/roots/module-layout-root.tsx @@ -2,6 +2,7 @@ import React, { Fragment } from "react"; import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import useSWR from "swr"; +import size from "lodash/size"; // mobx store import { useIssues } from "hooks/store"; // components @@ -17,7 +18,9 @@ import { } from "components/issues"; import { ActiveLoader } from "components/ui"; // constants -import { EIssuesStoreType } from "constants/issue"; +import { EIssueFilterType, EIssuesStoreType } from "constants/issue"; +// types +import { IIssueFilterOptions } from "@plane/types"; export const ModuleLayoutRoot: React.FC = observer(() => { // router @@ -43,6 +46,31 @@ export const ModuleLayoutRoot: React.FC = observer(() => { } ); + const userFilters = issuesFilter?.issueFilters?.filters; + + const issueFilterCount = size( + Object.fromEntries( + Object.entries(userFilters ?? {}).filter(([, value]) => value && Array.isArray(value) && value.length > 0) + ) + ); + + const handleClearAllFilters = () => { + if (!workspaceSlug || !projectId || !moduleId) return; + const newFilters: IIssueFilterOptions = {}; + Object.keys(userFilters ?? {}).forEach((key) => { + newFilters[key as keyof IIssueFilterOptions] = null; + }); + issuesFilter.updateFilters( + workspaceSlug.toString(), + projectId.toString(), + EIssueFilterType.FILTERS, + { + ...newFilters, + }, + moduleId.toString() + ); + }; + if (!workspaceSlug || !projectId || !moduleId) return <>; const activeLayout = issuesFilter?.issueFilters?.displayFilters?.layout || undefined; @@ -62,6 +90,8 @@ export const ModuleLayoutRoot: React.FC = observer(() => { projectId={projectId.toString()} moduleId={moduleId.toString()} activeLayout={activeLayout} + handleClearAllFilters={handleClearAllFilters} + isEmptyFilters={issueFilterCount > 0} />
) : ( diff --git a/web/components/project/sidebar-list-item.tsx b/web/components/project/sidebar-list-item.tsx index d9cd81d5f..64134b242 100644 --- a/web/components/project/sidebar-list-item.tsx +++ b/web/components/project/sidebar-list-item.tsx @@ -18,7 +18,7 @@ import { MoreHorizontal, } from "lucide-react"; // hooks -import { useApplication,useEventTracker, useProject } from "hooks/store"; +import { useApplication, useEventTracker, useProject } from "hooks/store"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; import useToast from "hooks/use-toast"; // helpers @@ -131,7 +131,7 @@ export const ProjectSidebarListItem: React.FC = observer((props) => { const handleProjectClick = () => { if (window.innerWidth < 768) { - themeStore.toggleSidebar(); + themeStore.toggleMobileSidebar(); } }; @@ -147,9 +147,8 @@ export const ProjectSidebarListItem: React.FC = observer((props) => { {({ open }) => ( <>
{provided && ( = observer((props) => { > @@ -101,10 +101,9 @@ export const WorkspaceHelpSection: React.FC = observe @@ -122,9 +121,8 @@ export const WorkspaceHelpSection: React.FC = observe leaveTo="transform opacity-0 scale-95" >
diff --git a/web/components/workspace/sidebar-dropdown.tsx b/web/components/workspace/sidebar-dropdown.tsx index 87bb4c868..7d4c6adec 100644 --- a/web/components/workspace/sidebar-dropdown.tsx +++ b/web/components/workspace/sidebar-dropdown.tsx @@ -54,7 +54,7 @@ export const WorkspaceSidebarDropdown = observer(() => { const { workspaceSlug } = router.query; // store hooks const { - theme: { sidebarCollapsed, toggleSidebar }, + theme: { sidebarCollapsed, toggleMobileSidebar }, } = useApplication(); const { setTrackElement } = useEventTracker(); const { currentUser, updateCurrentUser, isUserInstanceAdmin, signOut } = useUser(); @@ -98,7 +98,7 @@ export const WorkspaceSidebarDropdown = observer(() => { }; const handleItemClick = () => { if (window.innerWidth < 768) { - toggleSidebar(); + toggleMobileSidebar(); } }; const workspacesList = Object.values(workspaces ?? {}); @@ -110,15 +110,13 @@ export const WorkspaceSidebarDropdown = observer(() => { <>
{activeWorkspace?.logo && activeWorkspace.logo !== "" ? ( {
{!sidebarCollapsed && (
@@ -179,9 +176,8 @@ export const WorkspaceSidebarDropdown = observer(() => { >
{workspace?.logo && workspace.logo !== "" ? ( { )}
{workspace.name}
diff --git a/web/components/workspace/sidebar-menu.tsx b/web/components/workspace/sidebar-menu.tsx index 774a231db..9f3f5e1d6 100644 --- a/web/components/workspace/sidebar-menu.tsx +++ b/web/components/workspace/sidebar-menu.tsx @@ -31,7 +31,7 @@ export const WorkspaceSidebarMenu = observer(() => { const handleLinkClick = (itemKey: string) => { if (window.innerWidth < 768) { - themeStore.toggleSidebar(); + themeStore.toggleMobileSidebar(); } captureEvent(SIDEBAR_CLICKED, { destination: itemKey, @@ -52,11 +52,10 @@ export const WorkspaceSidebarMenu = observer(() => { disabled={!themeStore?.sidebarCollapsed} >
{ = (props) => { const { children, header } = props; const router = useRouter(); + const { theme: themeStore } = useApplication(); const showMenuItem = () => { const item = router.asPath.split('/'); @@ -42,7 +44,7 @@ export const ProfilePreferenceSettingsLayout: FC - + themeStore.toggleSidebar()} /> { const { setToastAlert } = useToast(); // store hooks const { - theme: { sidebarCollapsed, toggleSidebar }, + theme: { sidebarCollapsed, toggleSidebar, toggleMobileSidebar }, } = useApplication(); const { currentUser, currentUserSettings, signOut } = useUser(); const { workspaces } = useWorkspace(); @@ -78,7 +78,7 @@ export const ProfileLayoutSidebar = observer(() => { const handleItemClick = () => { if (window.innerWidth < 768) { - toggleSidebar(); + toggleMobileSidebar(); } }; @@ -111,7 +111,7 @@ export const ProfileLayoutSidebar = observer(() => { `} >
- +
{ const { data: userActivity } = useSWR(USER_ACTIVITY, () => userService.getUserActivity()); // store hooks const { currentUser } = useUser(); + const { theme: themeStore } = useApplication(); return (
- + themeStore.toggleSidebar()} />

Activity

{userActivity ? ( @@ -96,12 +97,12 @@ const ProfileActivityPage: NextPageWithLayout = observer(() => { const message = activityItem.verb === "created" && - activityItem.field !== "cycles" && - activityItem.field !== "modules" && - activityItem.field !== "attachment" && - activityItem.field !== "link" && - activityItem.field !== "estimate" && - !activityItem.field ? ( + activityItem.field !== "cycles" && + activityItem.field !== "modules" && + activityItem.field !== "attachment" && + activityItem.field !== "link" && + activityItem.field !== "estimate" && + !activityItem.field ? ( created diff --git a/web/pages/profile/change-password.tsx b/web/pages/profile/change-password.tsx index 4641837fd..15cb946ed 100644 --- a/web/pages/profile/change-password.tsx +++ b/web/pages/profile/change-password.tsx @@ -3,7 +3,7 @@ import { useRouter } from "next/router"; import { observer } from "mobx-react-lite"; import { Controller, useForm } from "react-hook-form"; // hooks -import { useUser } from "hooks/store"; +import { useApplication, useUser } from "hooks/store"; // services import { UserService } from "services/user.service"; // hooks @@ -32,7 +32,8 @@ const userService = new UserService(); const ChangePasswordPage: NextPageWithLayout = observer(() => { const [isPageLoading, setIsPageLoading] = useState(true); - + // hooks + const { theme: themeStore } = useApplication(); const { currentUser } = useUser(); const router = useRouter(); @@ -89,90 +90,90 @@ const ChangePasswordPage: NextPageWithLayout = observer(() => { return (
- + themeStore.toggleSidebar()} />
-
-

Change password

-
-
-

Current password

- ( - - )} - /> - {errors.old_password && {errors.old_password.message}} + +

Change password

+
+
+

Current password

+ ( + + )} + /> + {errors.old_password && {errors.old_password.message}} +
+ +
+

New password

+ ( + + )} + /> + {errors.new_password && {errors.new_password.message}} +
+ +
+

Confirm password

+ ( + + )} + /> + {errors.confirm_password && {errors.confirm_password.message}} +
-
-

New password

- ( - - )} - /> - {errors.new_password && {errors.new_password.message}} +
+
- -
-

Confirm password

- ( - - )} - /> - {errors.confirm_password && {errors.confirm_password.message}} -
-
- -
- -
- +
); }); diff --git a/web/pages/profile/index.tsx b/web/pages/profile/index.tsx index 655d6a4bd..da8626dd1 100644 --- a/web/pages/profile/index.tsx +++ b/web/pages/profile/index.tsx @@ -5,7 +5,7 @@ import { observer } from "mobx-react-lite"; // services import { FileService } from "services/file.service"; // hooks -import { useUser } from "hooks/store"; +import { useApplication, useUser } from "hooks/store"; import useUserAuth from "hooks/use-user-auth"; import useToast from "hooks/use-toast"; // layouts @@ -58,6 +58,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => { const { currentUser: myProfile, updateCurrentUser, currentUserLoader } = useUser(); // custom hooks const { } = useUserAuth({ user: myProfile, isLoading: currentUserLoader }); + const { theme: themeStore } = useApplication(); useEffect(() => { reset({ ...defaultValues, ...myProfile }); @@ -139,7 +140,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => { <>
- + themeStore.toggleSidebar()} />