diff --git a/web/ee/components/projects/create/root.tsx b/web/ee/components/projects/create/root.tsx index d90e4c68c7..25dbfce78b 100644 --- a/web/ee/components/projects/create/root.tsx +++ b/web/ee/components/projects/create/root.tsx @@ -15,7 +15,7 @@ import { getRandomEmoji } from "@/helpers/emoji.helper"; // hooks import { useEventTracker, useMember, useProject, useUser, useWorkspace } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; -import { useWorkspaceFeatures } from "@/plane-web/hooks/store"; +import { E_FEATURE_FLAGS, useFlag, useWorkspaceFeatures } from "@/plane-web/hooks/store"; import { TProject } from "@/plane-web/types/projects"; import { EWorkspaceFeatures } from "@/plane-web/types/workspace-feature"; import ProjectAttributes from "./attributes"; @@ -58,7 +58,9 @@ export const CreateProjectForm: FC = observer((props) => { const { data: currentUser } = useUser(); const { isWorkspaceFeatureEnabled } = useWorkspaceFeatures(); - const isProjectGroupingEnabled = isWorkspaceFeatureEnabled(EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED); + const isProjectGroupingEnabled = + isWorkspaceFeatureEnabled(EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED) && + useFlag(workspaceSlug.toString(), E_FEATURE_FLAGS.PROJECT_GROUPING); // form info const methods = useForm({ diff --git a/web/ee/components/projects/dropdowns/scope-dropdown.tsx b/web/ee/components/projects/dropdowns/scope-dropdown.tsx index 764aca3645..13043e886e 100644 --- a/web/ee/components/projects/dropdowns/scope-dropdown.tsx +++ b/web/ee/components/projects/dropdowns/scope-dropdown.tsx @@ -10,7 +10,7 @@ import { PROJECT_SCOPES } from "@/plane-web/constants/project"; // plane web hooks import { useProjectFilter } from "@/plane-web/hooks/store"; // plane web types -import { EProjectScope } from "@/plane-web/types/workspace-project-filters"; +import { EProjectLayouts, EProjectScope } from "@/plane-web/types/workspace-project-filters"; export type TProjectScopeDropdown = { workspaceSlug: string; @@ -20,7 +20,7 @@ export type TProjectScopeDropdown = { export const ProjectScopeDropdown: FC = observer((props) => { const { workspaceSlug, className } = props; // hooks - const { scopeProjectsCount, filters, updateScope } = useProjectFilter(); + const { scopeProjectsCount, filters, updateScope, updateLayout } = useProjectFilter(); // derived values const selectedScope = filters?.scope || EProjectScope.ALL_PROJECTS; @@ -28,13 +28,17 @@ export const ProjectScopeDropdown: FC = observer((props) const DropdownLabel = () => ( <> -
-
- {(PROJECT_SCOPES || []).find((scope) => selectedScope === scope.key)?.label} -
-
- {selectedScopeCount} +
+
+ {" "} +
+ {(PROJECT_SCOPES || []).find((scope) => selectedScope === scope.key)?.label} +
+
+ {selectedScopeCount} +
+
{(PROJECT_SCOPES || []).find((scope) => selectedScope === scope.key)?.label} @@ -48,7 +52,15 @@ export const ProjectScopeDropdown: FC = observer((props) updateScope(workspaceSlug, scope.key)} + onClick={() => { + updateScope(workspaceSlug, scope.key); + if ( + scope.key === EProjectScope.ALL_PROJECTS && + filters?.layout && + ![EProjectLayouts.GALLERY, EProjectLayouts.TABLE].includes(filters?.layout) + ) + updateLayout(workspaceSlug, EProjectLayouts.GALLERY); + }} >
{scope?.label}
diff --git a/web/ee/components/projects/header/layout-selection.tsx b/web/ee/components/projects/header/layout-selection.tsx index 0d2a74cd49..8aa05cbbcf 100644 --- a/web/ee/components/projects/header/layout-selection.tsx +++ b/web/ee/components/projects/header/layout-selection.tsx @@ -10,7 +10,7 @@ import { PROJECT_LAYOUTS } from "@/plane-web/constants/project"; // plane web hooks import { useProjectFilter } from "@/plane-web/hooks/store"; // plane web types -import { EProjectLayouts } from "@/plane-web/types/workspace-project-filters"; +import { EProjectLayouts, EProjectScope } from "@/plane-web/types/workspace-project-filters"; type TProjectLayoutSelection = { workspaceSlug: string; @@ -48,7 +48,9 @@ export const ProjectLayoutSelection: FC = observer((pro ))}
- {PROJECT_LAYOUTS.map((layout) => ( + {PROJECT_LAYOUTS.filter( + (layout) => !layout.selectivelyHide || filters?.scope === EProjectScope.MY_PROJECTS + ).map((layout) => (
); }); diff --git a/web/ee/components/projects/layouts/gantt/blocks.tsx b/web/ee/components/projects/layouts/gantt/blocks.tsx index 56f22e28aa..fb0bb0680f 100644 --- a/web/ee/components/projects/layouts/gantt/blocks.tsx +++ b/web/ee/components/projects/layouts/gantt/blocks.tsx @@ -11,8 +11,9 @@ import { IGanttBlock } from "@/components/gantt-chart"; import { findTotalDaysInRange, renderFormattedDate } from "@/helpers/date-time.helper"; import { useProject } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; -import { useWorkspaceProjectStates } from "@/plane-web/hooks/store"; +import { useProjectFilter, useWorkspaceProjectStates } from "@/plane-web/hooks/store"; import { TProject } from "@/plane-web/types/projects"; +import { EProjectScope } from "@/plane-web/types/workspace-project-filters"; import JoinButton from "../../common/join-button"; type Props = { @@ -68,6 +69,7 @@ export const ProjectGanttBlock: React.FC = observer((props) => { // rendering projects on gantt sidebar export const ProjectGanttSidebarBlock: React.FC = observer((props) => { const { block } = props; + const { filters } = useProjectFilter(); // router const { workspaceSlug: routerWorkspaceSlug } = useParams(); @@ -89,7 +91,7 @@ export const ProjectGanttSidebarBlock: React.FC = observer((props) {projectDetails?.name}
- + {filters?.scope === EProjectScope.ALL_PROJECTS && }
{duration} day{duration > 1 ? "s" : ""}
diff --git a/web/ee/components/projects/layouts/list/block.tsx b/web/ee/components/projects/layouts/list/block.tsx index 8623efc750..ad14e66901 100644 --- a/web/ee/components/projects/layouts/list/block.tsx +++ b/web/ee/components/projects/layouts/list/block.tsx @@ -11,7 +11,9 @@ import { cn } from "@/helpers/common.helper"; // hooks import { useAppTheme, useProject, useWorkspace } from "@/hooks/store"; import { usePlatformOS } from "@/hooks/use-platform-os"; +import { useProjectFilter } from "@/plane-web/hooks/store"; import { TProject } from "@/plane-web/types/projects"; +import { EProjectScope } from "@/plane-web/types/workspace-project-filters"; import JoinButton from "../../common/join-button"; import QuickActions from "../../quick-actions"; import Attributes from "../attributes"; @@ -35,7 +37,7 @@ export const ProjectBlock = observer((props: ProjectBlockProps) => { const { sidebarCollapsed: isSidebarCollapsed } = useAppTheme(); const { getProjectById, updateProject } = useProject(); const { currentWorkspace } = useWorkspace(); - + const { filters } = useProjectFilter(); const { isMobile } = usePlatformOS(); const projectDetails = getProjectById(projectId); @@ -112,7 +114,7 @@ export const ProjectBlock = observer((props: ProjectBlockProps) => { handleUpdateProject={(data) => updateProject(workspaceSlug.toString(), projectDetails.id, data)} workspaceSlug={workspaceSlug.toString()} currentWorkspace={currentWorkspace} - cta={} + cta={filters?.scope === EProjectScope.ALL_PROJECTS && } />
{ // derived values const pageTitle = currentWorkspace?.name ? `${currentWorkspace?.name} - Projects` : undefined; const currentWorkspaceId = currentWorkspace?.id; - const isProjectGroupingEnabled = isWorkspaceFeatureEnabled(EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED); + const isProjectGroupingEnabled = + isWorkspaceFeatureEnabled(EWorkspaceFeatures.IS_PROJECT_GROUPING_ENABLED) && + useFlag(workspaceSlug.toString(), E_FEATURE_FLAGS.PROJECT_GROUPING); useEffect(() => { if (pathname.includes("/archives")) { diff --git a/web/ee/constants/project/default-root.ts b/web/ee/constants/project/default-root.ts index 0e249fc5dd..5562add7d9 100644 --- a/web/ee/constants/project/default-root.ts +++ b/web/ee/constants/project/default-root.ts @@ -27,7 +27,7 @@ export const PROJECT_SCOPE_MAP: TProjectScopeMap = { export const PROJECT_SCOPES = Object.values(PROJECT_SCOPE_MAP); // layout constants -type TProjectLayoutMapObject = { key: T; title: string; label: string; icon: LucideIcon }; +type TProjectLayoutMapObject = { key: T; title: string; label: string; icon: LucideIcon; selectivelyHide: boolean }; type TProjectLayoutMap = { [key in EProjectLayouts]: TProjectLayoutMapObject; }; @@ -37,14 +37,28 @@ export const PROJECT_LAYOUT_MAP: TProjectLayoutMap = { title: "Gallery Layout", label: "Gallery", icon: GalleryVertical, + selectivelyHide: false, + }, + [EProjectLayouts.BOARD]: { + key: EProjectLayouts.BOARD, + title: "Board Layout", + label: "Board", + icon: Kanban, + selectivelyHide: true, + }, + [EProjectLayouts.TABLE]: { + key: EProjectLayouts.TABLE, + title: "Table Layout", + label: "Table", + icon: List, + selectivelyHide: false, }, - [EProjectLayouts.BOARD]: { key: EProjectLayouts.BOARD, title: "Board Layout", label: "Board", icon: Kanban }, - [EProjectLayouts.TABLE]: { key: EProjectLayouts.TABLE, title: "Table Layout", label: "Table", icon: List }, [EProjectLayouts.TIMELINE]: { key: EProjectLayouts.TIMELINE, title: "Timeline Layout", label: "Timeline", icon: GanttChartSquare, + selectivelyHide: true, }, }; export const PROJECT_LAYOUTS = Object.values(PROJECT_LAYOUT_MAP); diff --git a/web/ee/store/workspace-project-states/filters/filters.ts b/web/ee/store/workspace-project-states/filters/filters.ts index a556ef6075..b9eec92cda 100644 --- a/web/ee/store/workspace-project-states/filters/filters.ts +++ b/web/ee/store/workspace-project-states/filters/filters.ts @@ -207,10 +207,11 @@ export class ProjectFilterStore extends ProjectFilterHelper implements IProjectF if (!this.scopeMap[workspaceSlug]) { this.updateScope(workspaceSlug, EProjectScope.ALL_PROJECTS); } + const savedLayout = this.handleProjectLocalFilters.get(workspaceSlug)?.layout; if (!this.layoutMap[workspaceSlug]) { this.updateLayout( workspaceSlug, - this.handleProjectLocalFilters.get(workspaceSlug)?.layout || EProjectLayouts.GALLERY + [EProjectLayouts.GALLERY, EProjectLayouts.TABLE].includes(savedLayout) ? savedLayout : EProjectLayouts.GALLERY ); } if (!this.attributesMap[workspaceSlug]) {