refactor: layout roots (#2517)

This commit is contained in:
Aaryan Khandelwal
2023-10-23 15:06:28 +05:30
committed by GitHub
parent 05a76c5ee3
commit 38421e8106
12 changed files with 205 additions and 269 deletions

View File

@@ -1,11 +1,15 @@
import { useCallback } from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "components/issues";
// ui
import { BreadcrumbItem, Breadcrumbs, CustomMenu, PhotoFilterIcon } from "@plane/ui";
// helpers
import { truncateText } from "helpers/string.helper";
// types
import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions, TIssueLayouts } from "types";
// constants
@@ -19,6 +23,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
issueFilter: issueFilterStore,
projectViewFilters: projectViewFiltersStore,
project: projectStore,
projectViews: projectViewsStore,
} = useMobxStore();
const storedFilters = viewId ? projectViewFiltersStore.storedFilters[viewId.toString()] : undefined;
@@ -82,32 +87,78 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
[issueFilterStore, projectId, workspaceSlug]
);
const projectDetails =
workspaceSlug && projectId
? projectStore.getProjectById(workspaceSlug.toString(), projectId.toString())
: undefined;
const viewsList = projectId ? projectViewsStore.viewsList[projectId.toString()] : undefined;
const viewDetails = viewId ? projectViewsStore.viewDetails[viewId.toString()] : undefined;
return (
<div className="flex items-center gap-2">
<LayoutSelection
layouts={["list", "kanban", "calendar", "spreadsheet", "gantt_chart"]}
onChange={(layout) => handleLayoutChange(layout)}
selectedLayout={activeLayout}
/>
<FiltersDropdown title="Filters">
<FilterSelection
filters={storedFilters ?? {}}
handleFiltersUpdate={handleFiltersUpdate}
layoutDisplayFiltersOptions={activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined}
labels={projectStore.labels?.[projectId?.toString() ?? ""] ?? undefined}
members={projectStore.members?.[projectId?.toString() ?? ""]?.map((m) => m.member)}
states={projectStore.states?.[projectId?.toString() ?? ""] ?? undefined}
<div className="relative w-full flex items-center z-10 justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
<div className="flex items-center gap-2">
<Breadcrumbs onBack={() => router.back()}>
<BreadcrumbItem
link={
<Link href={`/${workspaceSlug}/projects/${projectDetails?.id}/cycles`}>
<a className={`border-r-2 border-custom-sidebar-border-200 px-3 text-sm `}>
<p className="truncate">{`${projectDetails?.name ?? "Project"} Views`}</p>
</a>
</Link>
}
/>
</Breadcrumbs>
<CustomMenu
label={
<>
<PhotoFilterIcon height={12} width={12} />
{viewDetails?.name && truncateText(viewDetails.name, 40)}
</>
}
className="ml-1.5"
placement="bottom-start"
>
{viewsList?.map((view) => (
<CustomMenu.MenuItem
key={view.id}
onClick={() => router.push(`/${workspaceSlug}/projects/${projectId}/views/${view.id}`)}
>
{truncateText(view.name, 40)}
</CustomMenu.MenuItem>
))}
</CustomMenu>
</div>
<div className="flex items-center gap-2">
<LayoutSelection
layouts={["list", "kanban", "calendar", "spreadsheet", "gantt_chart"]}
onChange={(layout) => handleLayoutChange(layout)}
selectedLayout={activeLayout}
/>
</FiltersDropdown>
<FiltersDropdown title="Display">
<DisplayFiltersSelection
displayFilters={issueFilterStore.userDisplayFilters}
displayProperties={issueFilterStore.userDisplayProperties}
handleDisplayFiltersUpdate={handleDisplayFiltersUpdate}
handleDisplayPropertiesUpdate={handleDisplayPropertiesUpdate}
layoutDisplayFiltersOptions={activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined}
/>
</FiltersDropdown>
<FiltersDropdown title="Filters">
<FilterSelection
filters={storedFilters ?? {}}
handleFiltersUpdate={handleFiltersUpdate}
layoutDisplayFiltersOptions={
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
}
labels={projectStore.labels?.[projectId?.toString() ?? ""] ?? undefined}
members={projectStore.members?.[projectId?.toString() ?? ""]?.map((m) => m.member)}
states={projectStore.states?.[projectId?.toString() ?? ""] ?? undefined}
/>
</FiltersDropdown>
<FiltersDropdown title="Display">
<DisplayFiltersSelection
displayFilters={issueFilterStore.userDisplayFilters}
displayProperties={issueFilterStore.userDisplayProperties}
handleDisplayFiltersUpdate={handleDisplayFiltersUpdate}
handleDisplayPropertiesUpdate={handleDisplayPropertiesUpdate}
layoutDisplayFiltersOptions={
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
}
/>
</FiltersDropdown>
</div>
</div>
);
});

View File

@@ -1,7 +1,10 @@
import { FC, useState } from "react";
import { useState } from "react";
import { useRouter } from "next/router";
// icons
import { ArrowLeft, Link, Plus } from "lucide-react";
import Link from "next/link";
import { observer } from "mobx-react-lite";
import { ArrowLeft, Plus } from "lucide-react";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
// components
import { CreateUpdateProjectViewModal } from "components/views";
// components
@@ -11,18 +14,20 @@ import { PrimaryButton } from "components/ui";
// helpers
import { truncateText } from "helpers/string.helper";
interface IProjectViewsHeader {
title: string | undefined;
}
export const ProjectViewsHeader: FC<IProjectViewsHeader> = (props) => {
const { title } = props;
export const ProjectViewsHeader: React.FC = observer(() => {
// router
const router = useRouter();
const { workspaceSlug, projectId } = router.query;
// states
const [createViewModal, setCreateViewModal] = useState(false);
const { project: projectStore } = useMobxStore();
const projectDetails =
workspaceSlug && projectId
? projectStore.getProjectById(workspaceSlug.toString(), projectId.toString())
: undefined;
return (
<>
{workspaceSlug && projectId && (
@@ -43,7 +48,7 @@ export const ProjectViewsHeader: FC<IProjectViewsHeader> = (props) => {
className="grid h-8 w-8 place-items-center rounded border border-custom-border-200"
onClick={() => router.back()}
>
<ArrowLeft fontSize={14} strokeWidth={2} />
<ArrowLeft className="h-3 w-3" strokeWidth={2} />
</button>
</div>
<div>
@@ -57,20 +62,13 @@ export const ProjectViewsHeader: FC<IProjectViewsHeader> = (props) => {
</Link>
}
/>
<BreadcrumbItem title={`${truncateText(title ?? "Project", 32)} Cycles`} />
<BreadcrumbItem title={`${truncateText(projectDetails?.name ?? "Project", 32)} Views`} />
</Breadcrumbs>
</div>
</div>
<div className="flex items-center gap-2">
<div className="flex items-center gap-2 flex-shrink-0">
<div>
<PrimaryButton
type="button"
className="flex items-center gap-2"
onClick={() => {
const e = new KeyboardEvent("keydown", { key: "v" });
document.dispatchEvent(e);
}}
>
<PrimaryButton type="button" className="flex items-center gap-2" onClick={() => setCreateViewModal(true)}>
<Plus size={14} strokeWidth={2} />
Create View
</PrimaryButton>
@@ -79,4 +77,4 @@ export const ProjectViewsHeader: FC<IProjectViewsHeader> = (props) => {
</div>
</>
);
};
});