chore: issue filters restructuring. (#5372)
This commit is contained in:
parent
49a895f117
commit
4ca45a971c
18 changed files with 94 additions and 29 deletions
8
packages/types/src/view-props.d.ts
vendored
8
packages/types/src/view-props.d.ts
vendored
|
|
@ -51,7 +51,7 @@ export type TIssueOrderByOptions =
|
||||||
| "sub_issues_count"
|
| "sub_issues_count"
|
||||||
| "-sub_issues_count";
|
| "-sub_issues_count";
|
||||||
|
|
||||||
export type TIssueTypeFilters = "active" | "backlog" | null;
|
export type TIssueGroupingFilters = "active" | "backlog" | null;
|
||||||
|
|
||||||
export type TIssueExtraOptions = "show_empty_groups" | "sub_issue";
|
export type TIssueExtraOptions = "show_empty_groups" | "sub_issue";
|
||||||
|
|
||||||
|
|
@ -76,7 +76,8 @@ export type TIssueParams =
|
||||||
| "sub_issue"
|
| "sub_issue"
|
||||||
| "show_empty_groups"
|
| "show_empty_groups"
|
||||||
| "cursor"
|
| "cursor"
|
||||||
| "per_page";
|
| "per_page"
|
||||||
|
| "issue_type";
|
||||||
|
|
||||||
export type TCalendarLayouts = "month" | "week";
|
export type TCalendarLayouts = "month" | "week";
|
||||||
|
|
||||||
|
|
@ -94,6 +95,7 @@ export interface IIssueFilterOptions {
|
||||||
state_group?: string[] | null;
|
state_group?: string[] | null;
|
||||||
subscriber?: string[] | null;
|
subscriber?: string[] | null;
|
||||||
target_date?: string[] | null;
|
target_date?: string[] | null;
|
||||||
|
issue_type?: string[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IIssueDisplayFilterOptions {
|
export interface IIssueDisplayFilterOptions {
|
||||||
|
|
@ -107,7 +109,7 @@ export interface IIssueDisplayFilterOptions {
|
||||||
order_by?: TIssueOrderByOptions;
|
order_by?: TIssueOrderByOptions;
|
||||||
show_empty_groups?: boolean;
|
show_empty_groups?: boolean;
|
||||||
sub_issue?: boolean;
|
sub_issue?: boolean;
|
||||||
type?: TIssueTypeFilters;
|
type?: TIssueGroupingFilters;
|
||||||
}
|
}
|
||||||
export interface IIssueDisplayProperties {
|
export interface IIssueDisplayProperties {
|
||||||
assignee?: boolean;
|
assignee?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./issue-types";
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
handleRemove: (val: string) => void;
|
||||||
|
values: string[];
|
||||||
|
editable: boolean | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AppliedIssueTypeFilters: React.FC<Props> = observer(() => null);
|
||||||
2
web/ce/components/issues/filters/index.ts
Normal file
2
web/ce/components/issues/filters/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./applied-filters";
|
||||||
|
export * from "./issue-types";
|
||||||
12
web/ce/components/issues/filters/issue-types.tsx
Normal file
12
web/ce/components/issues/filters/issue-types.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
appliedFilters: string[] | null;
|
||||||
|
handleUpdate: (val: string) => void;
|
||||||
|
searchQuery: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const FilterIssueTypes: React.FC<Props> = observer(() => null);
|
||||||
|
|
@ -3,3 +3,4 @@ export * from "./worklog";
|
||||||
export * from "./issue-modal";
|
export * from "./issue-modal";
|
||||||
export * from "./issue-details";
|
export * from "./issue-details";
|
||||||
export * from "./quick-add";
|
export * from "./quick-add";
|
||||||
|
export * from "./filters";
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import { EUserProjectRoles } from "@/constants/project";
|
||||||
import { replaceUnderscoreIfSnakeCase } from "@/helpers/string.helper";
|
import { replaceUnderscoreIfSnakeCase } from "@/helpers/string.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useUser } from "@/hooks/store";
|
import { useUser } from "@/hooks/store";
|
||||||
|
// plane web components
|
||||||
|
import { AppliedIssueTypeFilters } from "@/plane-web/components/issues";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
appliedFilters: IIssueFilterOptions;
|
appliedFilters: IIssueFilterOptions;
|
||||||
|
|
@ -131,6 +133,13 @@ export const AppliedFiltersList: React.FC<Props> = observer((props) => {
|
||||||
values={value}
|
values={value}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{filterKey === "issue_type" && (
|
||||||
|
<AppliedIssueTypeFilters
|
||||||
|
editable={isEditingAllowed}
|
||||||
|
handleRemove={(val) => handleRemoveFilter("issue_type", val)}
|
||||||
|
values={value}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{isEditingAllowed && (
|
{isEditingAllowed && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@ export * from "./display-filters-selection";
|
||||||
export * from "./display-properties";
|
export * from "./display-properties";
|
||||||
export * from "./extra-options";
|
export * from "./extra-options";
|
||||||
export * from "./group-by";
|
export * from "./group-by";
|
||||||
export * from "./issue-type";
|
export * from "./issue-grouping";
|
||||||
export * from "./order-by";
|
export * from "./order-by";
|
||||||
export * from "./sub-group-by";
|
export * from "./sub-group-by";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { TIssueTypeFilters } from "@plane/types";
|
import { TIssueGroupingFilters } from "@plane/types";
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { FilterHeader, FilterOption } from "@/components/issues";
|
import { FilterHeader, FilterOption } from "@/components/issues";
|
||||||
|
|
@ -9,11 +9,11 @@ import { ISSUE_FILTER_OPTIONS } from "@/constants/issue";
|
||||||
// constants
|
// constants
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
selectedIssueType: TIssueTypeFilters | undefined;
|
selectedIssueType: TIssueGroupingFilters | undefined;
|
||||||
handleUpdate: (val: TIssueTypeFilters) => void;
|
handleUpdate: (val: TIssueGroupingFilters) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const FilterIssueType: React.FC<Props> = observer((props) => {
|
export const FilterIssueGrouping: React.FC<Props> = observer((props) => {
|
||||||
const { selectedIssueType, handleUpdate } = props;
|
const { selectedIssueType, handleUpdate } = props;
|
||||||
|
|
||||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||||
|
|
@ -23,7 +23,7 @@ export const FilterIssueType: React.FC<Props> = observer((props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FilterHeader
|
<FilterHeader
|
||||||
title="Issue Type"
|
title="Issue Grouping"
|
||||||
isPreviewEnabled={previewEnabled}
|
isPreviewEnabled={previewEnabled}
|
||||||
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
|
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -2,8 +2,9 @@ import { useState } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { useParams } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import { Search, X } from "lucide-react";
|
import { Search, X } from "lucide-react";
|
||||||
|
// types
|
||||||
import { IIssueDisplayFilterOptions, IIssueFilterOptions, IIssueLabel, IState } from "@plane/types";
|
import { IIssueDisplayFilterOptions, IIssueFilterOptions, IIssueLabel, IState } from "@plane/types";
|
||||||
// hooks
|
// components
|
||||||
import {
|
import {
|
||||||
FilterAssignees,
|
FilterAssignees,
|
||||||
FilterMentions,
|
FilterMentions,
|
||||||
|
|
@ -17,12 +18,12 @@ import {
|
||||||
FilterTargetDate,
|
FilterTargetDate,
|
||||||
FilterCycle,
|
FilterCycle,
|
||||||
FilterModule,
|
FilterModule,
|
||||||
FilterIssueType,
|
FilterIssueGrouping,
|
||||||
} from "@/components/issues";
|
} from "@/components/issues";
|
||||||
import { ILayoutDisplayFiltersOptions } from "@/constants/issue";
|
|
||||||
// components
|
|
||||||
// types
|
|
||||||
// constants
|
// constants
|
||||||
|
import { ILayoutDisplayFiltersOptions } from "@/constants/issue";
|
||||||
|
// plane web components
|
||||||
|
import { FilterIssueTypes } from "@/plane-web/components/issues";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
filters: IIssueFilterOptions;
|
filters: IIssueFilterOptions;
|
||||||
|
|
@ -115,6 +116,15 @@ export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* issue type */}
|
||||||
|
{isFilterEnabled("issue_type") && (
|
||||||
|
<FilterIssueTypes
|
||||||
|
appliedFilters={filters.issue_type ?? null}
|
||||||
|
handleUpdate={(val) => handleFiltersUpdate("issue_type", val)}
|
||||||
|
searchQuery={filtersSearchQuery}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* assignees */}
|
{/* assignees */}
|
||||||
{isFilterEnabled("assignees") && (
|
{isFilterEnabled("assignees") && (
|
||||||
<div className="py-2">
|
<div className="py-2">
|
||||||
|
|
@ -198,7 +208,7 @@ export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||||
{/* issue type */}
|
{/* issue type */}
|
||||||
{isDisplayFilterEnabled("type") && displayFilters && handleDisplayFiltersUpdate && (
|
{isDisplayFilterEnabled("type") && displayFilters && handleDisplayFiltersUpdate && (
|
||||||
<div className="py-2">
|
<div className="py-2">
|
||||||
<FilterIssueType
|
<FilterIssueGrouping
|
||||||
selectedIssueType={displayFilters.type}
|
selectedIssueType={displayFilters.type}
|
||||||
handleUpdate={(val) =>
|
handleUpdate={(val) =>
|
||||||
handleDisplayFiltersUpdate({
|
handleDisplayFiltersUpdate({
|
||||||
|
|
|
||||||
|
|
@ -79,17 +79,11 @@ const KanbanIssueDetailsBlock: React.FC<IssueDetailsBlockProps> = observer((prop
|
||||||
</div>
|
</div>
|
||||||
</WithDisplayPropertiesHOC>
|
</WithDisplayPropertiesHOC>
|
||||||
|
|
||||||
{issue?.is_draft ? (
|
<div className="w-full line-clamp-1 text-sm text-custom-text-100 mb-1.5">
|
||||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
||||||
<span>{issue.name}</span>
|
<span>{issue.name}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
) : (
|
</div>
|
||||||
<div className="w-full line-clamp-1 text-sm text-custom-text-100 mb-1.5">
|
|
||||||
<Tooltip tooltipContent={issue.name} isMobile={isMobile}>
|
|
||||||
<span>{issue.name}</span>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<IssueProperties
|
<IssueProperties
|
||||||
className="flex flex-wrap items-center gap-2 whitespace-nowrap text-custom-text-300 pt-1.5"
|
className="flex flex-wrap items-center gap-2 whitespace-nowrap text-custom-text-300 pt-1.5"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
TIssueOrderByOptions,
|
TIssueOrderByOptions,
|
||||||
TIssuePriorities,
|
TIssuePriorities,
|
||||||
TIssueTypeFilters,
|
TIssueGroupingFilters,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
|
|
||||||
export const DRAG_ALLOWED_GROUPS: TIssueGroupByOptions[] = [
|
export const DRAG_ALLOWED_GROUPS: TIssueGroupByOptions[] = [
|
||||||
|
|
@ -99,7 +99,7 @@ export const ISSUE_ORDER_BY_OPTIONS: {
|
||||||
];
|
];
|
||||||
|
|
||||||
export const ISSUE_FILTER_OPTIONS: {
|
export const ISSUE_FILTER_OPTIONS: {
|
||||||
key: TIssueTypeFilters;
|
key: TIssueGroupingFilters;
|
||||||
title: string;
|
title: string;
|
||||||
}[] = [
|
}[] = [
|
||||||
{ key: null, title: "All" },
|
{ key: null, title: "All" },
|
||||||
|
|
@ -171,7 +171,7 @@ export interface ILayoutDisplayFiltersOptions {
|
||||||
group_by?: TIssueGroupByOptions[];
|
group_by?: TIssueGroupByOptions[];
|
||||||
sub_group_by?: TIssueGroupByOptions[];
|
sub_group_by?: TIssueGroupByOptions[];
|
||||||
order_by?: TIssueOrderByOptions[];
|
order_by?: TIssueOrderByOptions[];
|
||||||
type?: TIssueTypeFilters[];
|
type?: TIssueGroupingFilters[];
|
||||||
};
|
};
|
||||||
extra_options: {
|
extra_options: {
|
||||||
access: boolean;
|
access: boolean;
|
||||||
|
|
@ -222,6 +222,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
"labels",
|
"labels",
|
||||||
"start_date",
|
"start_date",
|
||||||
"target_date",
|
"target_date",
|
||||||
|
"issue_type",
|
||||||
],
|
],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
|
|
@ -247,7 +248,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
},
|
},
|
||||||
draft_issues: {
|
draft_issues: {
|
||||||
list: {
|
list: {
|
||||||
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date"],
|
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels", null],
|
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels", null],
|
||||||
|
|
@ -260,7 +261,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
kanban: {
|
kanban: {
|
||||||
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date"],
|
filters: ["priority", "state_group", "cycle", "module", "labels", "start_date", "target_date", "issue_type"],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels"],
|
group_by: ["state_detail.group", "cycle", "module", "priority", "project", "labels"],
|
||||||
|
|
@ -331,6 +332,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
"labels",
|
"labels",
|
||||||
"start_date",
|
"start_date",
|
||||||
"target_date",
|
"target_date",
|
||||||
|
"issue_type",
|
||||||
],
|
],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
|
|
@ -355,6 +357,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
"labels",
|
"labels",
|
||||||
"start_date",
|
"start_date",
|
||||||
"target_date",
|
"target_date",
|
||||||
|
"issue_type",
|
||||||
],
|
],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
|
|
@ -369,7 +372,18 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
calendar: {
|
calendar: {
|
||||||
filters: ["priority", "state", "cycle", "module", "assignees", "mentions", "created_by", "labels", "start_date"],
|
filters: [
|
||||||
|
"priority",
|
||||||
|
"state",
|
||||||
|
"cycle",
|
||||||
|
"module",
|
||||||
|
"assignees",
|
||||||
|
"mentions",
|
||||||
|
"created_by",
|
||||||
|
"labels",
|
||||||
|
"start_date",
|
||||||
|
"issue_type",
|
||||||
|
],
|
||||||
display_properties: false,
|
display_properties: false,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
type: [null, "active", "backlog"],
|
type: [null, "active", "backlog"],
|
||||||
|
|
@ -391,6 +405,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
"labels",
|
"labels",
|
||||||
"start_date",
|
"start_date",
|
||||||
"target_date",
|
"target_date",
|
||||||
|
"issue_type",
|
||||||
],
|
],
|
||||||
display_properties: true,
|
display_properties: true,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
|
|
@ -414,6 +429,7 @@ export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
|
||||||
"labels",
|
"labels",
|
||||||
"start_date",
|
"start_date",
|
||||||
"target_date",
|
"target_date",
|
||||||
|
"issue_type",
|
||||||
],
|
],
|
||||||
display_properties: false,
|
display_properties: false,
|
||||||
display_filters: {
|
display_filters: {
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ export class IssueFilterHelperStore implements IIssueFilterHelperStore {
|
||||||
target_date: filters?.target_date || undefined,
|
target_date: filters?.target_date || undefined,
|
||||||
project: filters?.project || undefined,
|
project: filters?.project || undefined,
|
||||||
subscriber: filters?.subscriber || undefined,
|
subscriber: filters?.subscriber || undefined,
|
||||||
|
issue_type: filters?.issue_type || undefined,
|
||||||
// display filters
|
// display filters
|
||||||
group_by: displayFilters?.group_by ? EIssueGroupByToServerOptions[displayFilters.group_by] : undefined,
|
group_by: displayFilters?.group_by ? EIssueGroupByToServerOptions[displayFilters.group_by] : undefined,
|
||||||
sub_group_by: displayFilters?.sub_group_by
|
sub_group_by: displayFilters?.sub_group_by
|
||||||
|
|
|
||||||
1
web/ee/components/issues/filters/active-filters/index.ts
Normal file
1
web/ee/components/issues/filters/active-filters/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./issue-types";
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "ce/components/issues/filters/applied-filters/issue-types";
|
||||||
2
web/ee/components/issues/filters/index.ts
Normal file
2
web/ee/components/issues/filters/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./active-filters";
|
||||||
|
export * from "./issue-types";
|
||||||
1
web/ee/components/issues/filters/issue-types.tsx
Normal file
1
web/ee/components/issues/filters/issue-types.tsx
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "ce/components/issues/filters/issue-types";
|
||||||
|
|
@ -3,3 +3,4 @@ export * from "./worklog";
|
||||||
export * from "./issue-modal";
|
export * from "./issue-modal";
|
||||||
export * from "./issue-details";
|
export * from "./issue-details";
|
||||||
export * from "./quick-add";
|
export * from "./quick-add";
|
||||||
|
export * from "./filters";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue