[WEB-4969] feat: add toggle button for work item filters row visibility (#7865)

* [WEB-4969] feat: add toggle button for work item filters row visibility

* fix: improve error handling in filter update and refine visibility condition check

* chore: correct visibility toggle parameter in filter store
This commit is contained in:
Prateek Shourya 2025-09-30 18:19:43 +05:30 committed by GitHub
parent 992457efd2
commit 7ce21a6488
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 394 additions and 141 deletions

View file

@ -38,6 +38,7 @@ import {
LayoutSelection,
MobileLayoutSelection,
} from "@/components/issues/issue-layouts/filters";
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
// hooks
import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useCycle } from "@/hooks/store/use-cycle";
@ -209,6 +210,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
activeLayout={activeLayout}
/>
</div>
<WorkItemFiltersToggle entityType={EIssuesStoreType.CYCLE} entityId={cycleId} />
<FiltersDropdown
title={t("common.display")}
placement="bottom-end"

View file

@ -35,8 +35,8 @@ import {
LayoutSelection,
MobileLayoutSelection,
} from "@/components/issues/issue-layouts/filters";
// helpers
import { ModuleQuickActions } from "@/components/modules";
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
// hooks
import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useIssues } from "@/hooks/store/use-issues";
@ -57,7 +57,8 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
const [analyticsModal, setAnalyticsModal] = useState(false);
// router
const router = useAppRouter();
const { workspaceSlug, projectId, moduleId } = useParams();
const { workspaceSlug, projectId, moduleId: routerModuleId } = useParams();
const moduleId = routerModuleId ? routerModuleId.toString() : undefined;
// hooks
const { isMobile } = usePlatformOS();
// store hooks
@ -75,7 +76,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
// derived values
const isSidebarCollapsed = storedValue ? (storedValue === "true" ? true : false) : false;
const activeLayout = issueFilters?.displayFilters?.layout;
const moduleDetails = moduleId ? getModuleById(moduleId.toString()) : undefined;
const moduleDetails = moduleId ? getModuleById(moduleId) : undefined;
const canUserCreateIssue = allowPermissions(
[EUserPermissions.ADMIN, EUserPermissions.MEMBER],
EUserPermissionsLevel.PROJECT
@ -197,6 +198,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
activeLayout={activeLayout}
/>
</div>
{moduleId && <WorkItemFiltersToggle entityType={EIssuesStoreType.MODULE} entityId={moduleId} />}
<FiltersDropdown
title="Display"
placement="bottom-end"
@ -251,13 +253,15 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
>
<PanelRight className={cn("h-4 w-4", !isSidebarCollapsed ? "text-[#3E63DD]" : "text-custom-text-200")} />
</button>
<ModuleQuickActions
parentRef={parentRef}
moduleId={moduleId?.toString()}
projectId={projectId.toString()}
workspaceSlug={workspaceSlug.toString()}
customClassName="flex-shrink-0 flex items-center justify-center bg-custom-background-80/70 rounded size-[26px]"
/>
{moduleId && (
<ModuleQuickActions
parentRef={parentRef}
moduleId={moduleId}
projectId={projectId.toString()}
workspaceSlug={workspaceSlug.toString()}
customClassName="flex-shrink-0 flex items-center justify-center bg-custom-background-80/70 rounded size-[26px]"
/>
)}
</Header.RightItem>
</Header>
</>

View file

@ -31,6 +31,7 @@ import { SwitcherIcon, SwitcherLabel } from "@/components/common/switcher-label"
import { DisplayFiltersSelection, FiltersDropdown, LayoutSelection } from "@/components/issues/issue-layouts/filters";
// constants
import { ViewQuickActions } from "@/components/views/quick-actions";
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
// hooks
import { useCommandPalette } from "@/hooks/store/use-command-palette";
import { useIssues } from "@/hooks/store/use-issues";
@ -45,8 +46,9 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
// refs
const parentRef = useRef(null);
// router
const { workspaceSlug, projectId, viewId } = useParams();
const router = useAppRouter();
const { workspaceSlug, projectId, viewId: routerViewId } = useParams();
const viewId = routerViewId ? routerViewId.toString() : undefined;
// store hooks
const {
issuesFilter: { issueFilters, updateFilters },
@ -163,8 +165,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
)}
</Header.LeftItem>
<Header.RightItem className="items-center">
{!viewDetails?.is_locked ? (
<>
<>
{!viewDetails.is_locked && (
<LayoutSelection
layouts={[
EIssueLayoutTypes.LIST,
@ -176,6 +178,9 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
onChange={(layout) => handleLayoutChange(layout)}
selectedLayout={activeLayout}
/>
)}
{viewId && <WorkItemFiltersToggle entityType={EIssuesStoreType.PROJECT_VIEW} entityId={viewId} />}
{!viewDetails.is_locked && (
<FiltersDropdown title="Display" placement="bottom-end">
<DisplayFiltersSelection
layoutDisplayFiltersOptions={
@ -189,10 +194,8 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
moduleViewDisabled={!currentProjectDetails?.module_view}
/>
</FiltersDropdown>
</>
) : (
<></>
)}
)}
</>
{canUserCreateIssue ? (
<Button
onClick={() => {

View file

@ -25,6 +25,7 @@ import { Breadcrumbs, Header, BreadcrumbNavigationSearchDropdown } from "@plane/
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
import { SwitcherLabel } from "@/components/common/switcher-label";
import { DisplayFiltersSelection, FiltersDropdown } from "@/components/issues/issue-layouts/filters";
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
import { DefaultWorkspaceViewQuickActions } from "@/components/workspace/views/default-view-quick-action";
import { CreateUpdateWorkspaceViewModal } from "@/components/workspace/views/modal";
import { WorkspaceViewQuickActions } from "@/components/workspace/views/quick-action";
@ -39,7 +40,8 @@ export const GlobalIssuesHeader = observer(() => {
const [createViewModal, setCreateViewModal] = useState(false);
// router
const router = useAppRouter();
const { workspaceSlug, globalViewId } = useParams();
const { workspaceSlug, globalViewId: routerGlobalViewId } = useParams();
const globalViewId = routerGlobalViewId ? routerGlobalViewId.toString() : undefined;
// store hooks
const {
issuesFilter: { filters, updateFilters },
@ -50,7 +52,7 @@ export const GlobalIssuesHeader = observer(() => {
const issueFilters = globalViewId ? filters[globalViewId.toString()] : undefined;
const activeLayout = issueFilters?.displayFilters?.layout;
const viewDetails = getViewDetailsById(globalViewId.toString());
const viewDetails = globalViewId ? getViewDetailsById(globalViewId) : undefined;
const handleDisplayFilters = useCallback(
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
@ -60,7 +62,7 @@ export const GlobalIssuesHeader = observer(() => {
undefined,
EIssueFilterType.DISPLAY_FILTERS,
updatedDisplayFilter,
globalViewId.toString()
globalViewId
);
},
[workspaceSlug, updateFilters, globalViewId]
@ -69,13 +71,7 @@ export const GlobalIssuesHeader = observer(() => {
const handleDisplayProperties = useCallback(
(property: Partial<IIssueDisplayProperties>) => {
if (!workspaceSlug || !globalViewId) return;
updateFilters(
workspaceSlug.toString(),
undefined,
EIssueFilterType.DISPLAY_PROPERTIES,
property,
globalViewId.toString()
);
updateFilters(workspaceSlug.toString(), undefined, EIssueFilterType.DISPLAY_PROPERTIES, property, globalViewId);
},
[workspaceSlug, updateFilters, globalViewId]
);
@ -88,7 +84,7 @@ export const GlobalIssuesHeader = observer(() => {
undefined,
EIssueFilterType.DISPLAY_FILTERS,
{ layout: layout },
globalViewId.toString()
globalViewId
);
},
[workspaceSlug, updateFilters, globalViewId]
@ -158,25 +154,24 @@ export const GlobalIssuesHeader = observer(() => {
</Header.LeftItem>
<Header.RightItem className="items-center">
{!isLocked ? (
<>
<GlobalViewLayoutSelection
onChange={handleLayoutChange}
selectedLayout={activeLayout ?? EIssueLayoutTypes.SPREADSHEET}
workspaceSlug={workspaceSlug.toString()}
{!isLocked && (
<GlobalViewLayoutSelection
onChange={handleLayoutChange}
selectedLayout={activeLayout ?? EIssueLayoutTypes.SPREADSHEET}
workspaceSlug={workspaceSlug.toString()}
/>
)}
{globalViewId && <WorkItemFiltersToggle entityType={EIssuesStoreType.GLOBAL} entityId={globalViewId} />}
{!isLocked && (
<FiltersDropdown title={t("common.display")} placement="bottom-end">
<DisplayFiltersSelection
layoutDisplayFiltersOptions={currentLayoutFilters}
displayFilters={issueFilters?.displayFilters ?? {}}
handleDisplayFiltersUpdate={handleDisplayFilters}
displayProperties={issueFilters?.displayProperties ?? {}}
handleDisplayPropertiesUpdate={handleDisplayProperties}
/>
<FiltersDropdown title={t("common.display")} placement="bottom-end">
<DisplayFiltersSelection
layoutDisplayFiltersOptions={currentLayoutFilters}
displayFilters={issueFilters?.displayFilters ?? {}}
handleDisplayFiltersUpdate={handleDisplayFilters}
displayProperties={issueFilters?.displayProperties ?? {}}
handleDisplayPropertiesUpdate={handleDisplayProperties}
/>
</FiltersDropdown>
</>
) : (
<></>
</FiltersDropdown>
)}
<Button