[WEB-5296]chore: grouping filter refactor (#8034)

This commit is contained in:
Vamsi Krishna 2025-10-29 20:36:28 +05:30 committed by GitHub
parent 0e8128594b
commit 710138f3a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 98 additions and 52 deletions

View file

@ -1,6 +1,6 @@
"use client";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useRef } from "react";
import { Rocket, Search } from "lucide-react";
import { Combobox, Dialog, Transition } from "@headlessui/react";
// i18n
@ -66,12 +66,14 @@ export const ExistingIssuesListModal: React.FC<Props> = (props) => {
const { isMobile } = usePlatformOS();
const debouncedSearchTerm: string = useDebounce(searchTerm, 500);
const { baseTabIndex } = getTabIndex(undefined, isMobile);
const hasInitializedSelection = useRef(false);
const handleClose = () => {
onClose();
setSearchTerm("");
setSelectedIssues([]);
setIsWorkspaceLevel(false);
hasInitializedSelection.current = false;
};
const onSubmit = async () => {
@ -118,10 +120,11 @@ export const ExistingIssuesListModal: React.FC<Props> = (props) => {
};
useEffect(() => {
if (selectedWorkItemIds) {
if (isOpen && !hasInitializedSelection.current && selectedWorkItemIds && issues.length > 0) {
setSelectedIssues(issues.filter((issue) => selectedWorkItemIds.includes(issue.id)));
hasInitializedSelection.current = true;
}
}, [isOpen, selectedWorkItemIds]);
}, [isOpen, issues, selectedWorkItemIds]);
useEffect(() => {
handleSearch();

View file

@ -36,6 +36,7 @@ import { useProjectState } from "@/hooks/store/use-project-state";
// components
import { WorkItemAdditionalSidebarProperties } from "@/plane-web/components/issues/issue-details/additional-properties";
import { IssueParentSelectRoot } from "@/plane-web/components/issues/issue-details/parent-select-root";
import { DateAlert } from "@/plane-web/components/issues/issue-details/sidebar.tsx/date-alert";
import { IssueWorklogProperty } from "@/plane-web/components/issues/worklog/property";
import { IssueCycleSelect } from "./cycle-select";
import { IssueLabel } from "./label";
@ -186,28 +187,31 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
<DueDatePropertyIcon className="h-4 w-4 flex-shrink-0" />
<span>{t("common.order_by.due_date")}</span>
</div>
<DateDropdown
placeholder={t("issue.add.due_date")}
value={issue.target_date}
onChange={(val) =>
issueOperations.update(workspaceSlug, projectId, issueId, {
target_date: val ? renderFormattedPayloadDate(val) : null,
})
}
minDate={minDate ?? undefined}
disabled={!isEditable}
buttonVariant="transparent-with-text"
className="group w-3/5 flex-grow"
buttonContainerClassName="w-full text-left"
buttonClassName={cn("text-sm", {
"text-custom-text-400": !issue.target_date,
"text-red-500": shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group),
})}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline !text-custom-text-100"
// TODO: add this logic
// showPlaceholderIcon
/>
<div className="flex items-center gap-2">
<DateDropdown
placeholder={t("issue.add.due_date")}
value={issue.target_date}
onChange={(val) =>
issueOperations.update(workspaceSlug, projectId, issueId, {
target_date: val ? renderFormattedPayloadDate(val) : null,
})
}
minDate={minDate ?? undefined}
disabled={!isEditable}
buttonVariant="transparent-with-text"
className="group w-3/5 flex-grow"
buttonContainerClassName="w-full text-left"
buttonClassName={cn("text-sm", {
"text-custom-text-400": !issue.target_date,
"text-red-500": shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group),
})}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline !text-custom-text-100"
// TODO: add this logic
// showPlaceholderIcon
/>
{issue.target_date && <DateAlert date={issue.target_date} workItem={issue} projectId={projectId} />}
</div>
</div>
{projectId && areEstimateEnabledByProjectId(projectId) && (

View file

@ -1,10 +1,10 @@
import React, { useState } from "react";
import { observer } from "mobx-react";
import { ISSUE_GROUP_BY_OPTIONS } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import type { IIssueDisplayFilterOptions, TIssueGroupByOptions } from "@plane/types";
// components
import { FilterHeader, FilterOption } from "@/components/issues/issue-layouts/filters";
import { useGroupByOptions } from "@/plane-web/components/issues/issue-layouts/utils";
type Props = {
displayFilters: IIssueDisplayFilterOptions | undefined;
@ -22,6 +22,8 @@ export const FilterGroupBy: React.FC<Props> = observer((props) => {
const selectedGroupBy = displayFilters?.group_by ?? null;
const selectedSubGroupBy = displayFilters?.sub_group_by ?? null;
const options = useGroupByOptions(groupByOptions);
return (
<>
<FilterHeader
@ -31,7 +33,7 @@ export const FilterGroupBy: React.FC<Props> = observer((props) => {
/>
{previewEnabled && (
<div>
{ISSUE_GROUP_BY_OPTIONS.filter((option) => groupByOptions.includes(option.key)).map((groupBy) => {
{options.map((groupBy) => {
if (
displayFilters?.layout === "kanban" &&
selectedSubGroupBy !== null &&

View file

@ -34,6 +34,7 @@ import { useProjectState } from "@/hooks/store/use-project-state";
// plane web components
import { WorkItemAdditionalSidebarProperties } from "@/plane-web/components/issues/issue-details/additional-properties";
import { IssueParentSelectRoot } from "@/plane-web/components/issues/issue-details/parent-select-root";
import { DateAlert } from "@/plane-web/components/issues/issue-details/sidebar.tsx/date-alert";
import { IssueWorklogProperty } from "@/plane-web/components/issues/worklog/property";
import type { TIssueOperations } from "../issue-detail";
import { IssueCycleSelect } from "../issue-detail/cycle-select";
@ -189,28 +190,31 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
<DueDatePropertyIcon className="h-4 w-4 flex-shrink-0" />
<span>{t("common.order_by.due_date")}</span>
</div>
<DateDropdown
value={issue.target_date}
onChange={(val) =>
issueOperations.update(workspaceSlug, projectId, issueId, {
target_date: val ? renderFormattedPayloadDate(val) : null,
})
}
placeholder={t("issue.add.due_date")}
buttonVariant="transparent-with-text"
minDate={minDate ?? undefined}
disabled={disabled}
className="w-3/4 flex-grow group"
buttonContainerClassName="w-full text-left"
buttonClassName={cn("text-sm", {
"text-custom-text-400": !issue.target_date,
"text-red-500": shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group),
})}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline !text-custom-text-100"
// TODO: add this logic
// showPlaceholderIcon
/>
<div className="flex items-center gap-2">
<DateDropdown
value={issue.target_date}
onChange={(val) =>
issueOperations.update(workspaceSlug, projectId, issueId, {
target_date: val ? renderFormattedPayloadDate(val) : null,
})
}
placeholder={t("issue.add.due_date")}
buttonVariant="transparent-with-text"
minDate={minDate ?? undefined}
disabled={disabled}
className="w-3/4 flex-grow group"
buttonContainerClassName="w-full text-left"
buttonClassName={cn("text-sm", {
"text-custom-text-400": !issue.target_date,
"text-red-500": shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group),
})}
hideIcon
clearIconClassName="h-3 w-3 hidden group-hover:inline !text-custom-text-100"
// TODO: add this logic
// showPlaceholderIcon
/>
{issue.target_date && <DateAlert date={issue.target_date} workItem={issue} projectId={projectId} />}
</div>
</div>
{/* estimate */}

View file

@ -24,6 +24,7 @@ import { EIssueLayoutTypes } from "@plane/types";
import { getComputedDisplayFilters, getComputedDisplayProperties } from "@plane/utils";
// lib
import { storage } from "@/lib/local-storage";
import { getEnabledDisplayFilters } from "@/plane-web/store/issue/helpers/filter-utils";
interface ILocalStoreIssueFilters {
key: EIssuesStoreType;
@ -176,7 +177,10 @@ export class IssueFilterHelperStore implements IIssueFilterHelperStore {
computedDisplayFilters = (
displayFilters: IIssueDisplayFilterOptions,
defaultValues?: IIssueDisplayFilterOptions
): IIssueDisplayFilterOptions => getComputedDisplayFilters(displayFilters, defaultValues);
): IIssueDisplayFilterOptions => {
const computedFilters = getComputedDisplayFilters(displayFilters, defaultValues);
return getEnabledDisplayFilters(computedFilters);
};
/**
* @description This method is used to apply the display properties on the issues

View file

@ -76,7 +76,7 @@ export class ProjectStore implements IProjectStore {
fetchStatus: TFetchStatus = undefined;
projectMap: Record<string, TProject> = {};
projectAnalyticsCountMap: Record<string, TProjectAnalyticsCount> = {};
openCollapsibleSection: ProjectOverviewCollapsible[] = [];
openCollapsibleSection: ProjectOverviewCollapsible[] = ["milestones"];
lastCollapsibleAction: ProjectOverviewCollapsible | null = null;
// root store