forked from github/plane
feat: added labels in filters (#585)
* feat: added labels in filters * fix: added labels in fetch keys
This commit is contained in:
parent
1509c8611d
commit
b441a2ce20
@ -11,7 +11,6 @@ import issuesService from "services/issues.service";
|
|||||||
import stateService from "services/state.service";
|
import stateService from "services/state.service";
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
import modulesService from "services/modules.service";
|
import modulesService from "services/modules.service";
|
||||||
import viewsService from "services/views.service";
|
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
import useIssuesView from "hooks/use-issues-view";
|
import useIssuesView from "hooks/use-issues-view";
|
||||||
@ -49,9 +48,9 @@ import {
|
|||||||
MODULE_ISSUES,
|
MODULE_ISSUES,
|
||||||
MODULE_ISSUES_WITH_PARAMS,
|
MODULE_ISSUES_WITH_PARAMS,
|
||||||
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
PROJECT_ISSUES_LIST_WITH_PARAMS,
|
||||||
|
PROJECT_ISSUE_LABELS,
|
||||||
PROJECT_MEMBERS,
|
PROJECT_MEMBERS,
|
||||||
STATE_LIST,
|
STATE_LIST,
|
||||||
VIEW_DETAILS,
|
|
||||||
} from "constants/fetch-keys";
|
} from "constants/fetch-keys";
|
||||||
import { getPriorityIcon } from "components/icons/priority-icon";
|
import { getPriorityIcon } from "components/icons/priority-icon";
|
||||||
|
|
||||||
@ -119,6 +118,13 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { data: issueLabels } = useSWR(
|
||||||
|
projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null,
|
||||||
|
workspaceSlug && projectId
|
||||||
|
? () => issuesService.getIssueLabels(workspaceSlug as string, projectId.toString())
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
|
||||||
const handleDeleteIssue = useCallback(
|
const handleDeleteIssue = useCallback(
|
||||||
(issue: IIssue) => {
|
(issue: IIssue) => {
|
||||||
setDeleteIssueModal(true);
|
setDeleteIssueModal(true);
|
||||||
@ -616,6 +622,34 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
) : key === "labels" ? (
|
||||||
|
<div className="flex items-center gap-x-1">
|
||||||
|
{filters.labels?.map((labelId: string) => {
|
||||||
|
const label = issueLabels?.find((l) => l.id === labelId);
|
||||||
|
|
||||||
|
if (!label) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div
|
||||||
|
className="w-4 h-4 rounded-full"
|
||||||
|
style={{ backgroundColor: label.color }}
|
||||||
|
/>
|
||||||
|
{label.name}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
setFilters({
|
||||||
|
labels: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<XMarkIcon className="h-3 w-3" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
(filters[key as keyof IIssueFilterOptions] as any)?.join(", ")
|
(filters[key as keyof IIssueFilterOptions] as any)?.join(", ")
|
||||||
)}
|
)}
|
||||||
|
@ -5,6 +5,7 @@ import useSWR from "swr";
|
|||||||
// services
|
// services
|
||||||
import stateService from "services/state.service";
|
import stateService from "services/state.service";
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
|
import issuesService from "services/issues.service";
|
||||||
// ui
|
// ui
|
||||||
import { Avatar, MultiLevelDropdown } from "components/ui";
|
import { Avatar, MultiLevelDropdown } from "components/ui";
|
||||||
// icons
|
// icons
|
||||||
@ -14,7 +15,7 @@ import { getStatesList } from "helpers/state.helper";
|
|||||||
// types
|
// types
|
||||||
import { IIssueFilterOptions, IQuery } from "types";
|
import { IIssueFilterOptions, IQuery } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_MEMBERS, STATE_LIST } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS, STATE_LIST } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
import { PRIORITIES } from "constants/project";
|
import { PRIORITIES } from "constants/project";
|
||||||
|
|
||||||
@ -49,6 +50,13 @@ export const SelectFilters: React.FC<Props> = ({
|
|||||||
: null
|
: null
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { data: issueLabels } = useSWR(
|
||||||
|
projectId ? PROJECT_ISSUE_LABELS(projectId.toString()) : null,
|
||||||
|
workspaceSlug && projectId
|
||||||
|
? () => issuesService.getIssueLabels(workspaceSlug as string, projectId.toString())
|
||||||
|
: null
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MultiLevelDropdown
|
<MultiLevelDropdown
|
||||||
label="Filters"
|
label="Filters"
|
||||||
@ -142,6 +150,27 @@ export const SelectFilters: React.FC<Props> = ({
|
|||||||
})) ?? []),
|
})) ?? []),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "labels",
|
||||||
|
label: "Labels",
|
||||||
|
value: issueLabels,
|
||||||
|
children: [
|
||||||
|
...(issueLabels?.map((label) => ({
|
||||||
|
id: label.id,
|
||||||
|
label: (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="w-4 h-4 rounded-full" style={{ backgroundColor: label.color }} />
|
||||||
|
{label.name}
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
value: {
|
||||||
|
key: "labels",
|
||||||
|
value: label.id,
|
||||||
|
},
|
||||||
|
selected: filters?.labels?.includes(label.id),
|
||||||
|
})) ?? []),
|
||||||
|
],
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
const paramsToKey = (params: any) => {
|
const paramsToKey = (params: any) => {
|
||||||
const { state, priority, assignees, created_by } = params;
|
const { state, priority, assignees, created_by, labels } = params;
|
||||||
|
|
||||||
let stateKey = state ? state.split(",") : [];
|
let stateKey = state ? state.split(",") : [];
|
||||||
let priorityKey = priority ? priority.split(",") : [];
|
let priorityKey = priority ? priority.split(",") : [];
|
||||||
let assigneesKey = assignees ? assignees.split(",") : [];
|
let assigneesKey = assignees ? assignees.split(",") : [];
|
||||||
let createdByKey = created_by ? created_by.split(",") : [];
|
let createdByKey = created_by ? created_by.split(",") : [];
|
||||||
|
let labelsKey = labels ? labels.split(",") : [];
|
||||||
const type = params.type ? params.type.toUpperCase() : "NULL";
|
const type = params.type ? params.type.toUpperCase() : "NULL";
|
||||||
const groupBy = params.group_by ? params.group_by.toUpperCase() : "NULL";
|
const groupBy = params.group_by ? params.group_by.toUpperCase() : "NULL";
|
||||||
const orderBy = params.order_by ? params.order_by.toUpperCase() : "NULL";
|
const orderBy = params.order_by ? params.order_by.toUpperCase() : "NULL";
|
||||||
@ -14,8 +15,9 @@ const paramsToKey = (params: any) => {
|
|||||||
priorityKey = priorityKey.sort().join("_");
|
priorityKey = priorityKey.sort().join("_");
|
||||||
assigneesKey = assigneesKey.sort().join("_");
|
assigneesKey = assigneesKey.sort().join("_");
|
||||||
createdByKey = createdByKey.sort().join("_");
|
createdByKey = createdByKey.sort().join("_");
|
||||||
|
labelsKey = labelsKey.sort().join("_");
|
||||||
|
|
||||||
return `${stateKey}_${priorityKey}_${assigneesKey}_${createdByKey}_${type}_${groupBy}_${orderBy}`;
|
return `${stateKey}_${priorityKey}_${assigneesKey}_${createdByKey}_${type}_${groupBy}_${orderBy}_${labelsKey}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CURRENT_USER = "CURRENT_USER";
|
export const CURRENT_USER = "CURRENT_USER";
|
||||||
@ -23,18 +25,21 @@ export const USER_WORKSPACE_INVITATIONS = "USER_WORKSPACE_INVITATIONS";
|
|||||||
export const USER_WORKSPACES = "USER_WORKSPACES";
|
export const USER_WORKSPACES = "USER_WORKSPACES";
|
||||||
export const APP_INTEGRATIONS = "APP_INTEGRATIONS";
|
export const APP_INTEGRATIONS = "APP_INTEGRATIONS";
|
||||||
|
|
||||||
export const WORKSPACE_DETAILS = (workspaceSlug: string) => `WORKSPACE_DETAILS_${workspaceSlug.toUpperCase()}`;
|
export const WORKSPACE_DETAILS = (workspaceSlug: string) =>
|
||||||
|
`WORKSPACE_DETAILS_${workspaceSlug.toUpperCase()}`;
|
||||||
export const WORKSPACE_INTEGRATIONS = (workspaceSlug: string) =>
|
export const WORKSPACE_INTEGRATIONS = (workspaceSlug: string) =>
|
||||||
`WORKSPACE_INTEGRATIONS_${workspaceSlug.toUpperCase()}`;
|
`WORKSPACE_INTEGRATIONS_${workspaceSlug.toUpperCase()}`;
|
||||||
|
|
||||||
export const WORKSPACE_MEMBERS = (workspaceSlug: string) => `WORKSPACE_MEMBERS_${workspaceSlug.toUpperCase()}`;
|
export const WORKSPACE_MEMBERS = (workspaceSlug: string) =>
|
||||||
|
`WORKSPACE_MEMBERS_${workspaceSlug.toUpperCase()}`;
|
||||||
export const WORKSPACE_MEMBERS_ME = (workspaceSlug: string) =>
|
export const WORKSPACE_MEMBERS_ME = (workspaceSlug: string) =>
|
||||||
`WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`;
|
`WORKSPACE_MEMBERS_ME${workspaceSlug.toUpperCase()}`;
|
||||||
export const WORKSPACE_INVITATIONS = "WORKSPACE_INVITATIONS";
|
export const WORKSPACE_INVITATIONS = "WORKSPACE_INVITATIONS";
|
||||||
export const WORKSPACE_INVITATION = "WORKSPACE_INVITATION";
|
export const WORKSPACE_INVITATION = "WORKSPACE_INVITATION";
|
||||||
export const LAST_ACTIVE_WORKSPACE_AND_PROJECTS = "LAST_ACTIVE_WORKSPACE_AND_PROJECTS";
|
export const LAST_ACTIVE_WORKSPACE_AND_PROJECTS = "LAST_ACTIVE_WORKSPACE_AND_PROJECTS";
|
||||||
|
|
||||||
export const PROJECTS_LIST = (workspaceSlug: string) => `PROJECTS_LIST_${workspaceSlug.toUpperCase()}`;
|
export const PROJECTS_LIST = (workspaceSlug: string) =>
|
||||||
|
`PROJECTS_LIST_${workspaceSlug.toUpperCase()}`;
|
||||||
export const FAVORITE_PROJECTS_LIST = (workspaceSlug: string) =>
|
export const FAVORITE_PROJECTS_LIST = (workspaceSlug: string) =>
|
||||||
`FAVORITE_PROJECTS_LIST_${workspaceSlug.toUpperCase()}`;
|
`FAVORITE_PROJECTS_LIST_${workspaceSlug.toUpperCase()}`;
|
||||||
export const PROJECT_DETAILS = (projectId: string) => `PROJECT_DETAILS_${projectId.toUpperCase()}`;
|
export const PROJECT_DETAILS = (projectId: string) => `PROJECT_DETAILS_${projectId.toUpperCase()}`;
|
||||||
@ -51,13 +56,18 @@ export const PROJECT_ISSUES_LIST_WITH_PARAMS = (projectId: string, params?: any)
|
|||||||
|
|
||||||
return `PROJECT_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}_${paramsKey}`;
|
return `PROJECT_ISSUES_LIST_WITH_PARAMS_${projectId.toUpperCase()}_${paramsKey}`;
|
||||||
};
|
};
|
||||||
export const PROJECT_ISSUES_DETAILS = (issueId: string) => `PROJECT_ISSUES_DETAILS_${issueId.toUpperCase()}`;
|
export const PROJECT_ISSUES_DETAILS = (issueId: string) =>
|
||||||
|
`PROJECT_ISSUES_DETAILS_${issueId.toUpperCase()}`;
|
||||||
export const PROJECT_ISSUES_PROPERTIES = (projectId: string) =>
|
export const PROJECT_ISSUES_PROPERTIES = (projectId: string) =>
|
||||||
`PROJECT_ISSUES_PROPERTIES_${projectId.toUpperCase()}`;
|
`PROJECT_ISSUES_PROPERTIES_${projectId.toUpperCase()}`;
|
||||||
export const PROJECT_ISSUES_COMMENTS = (issueId: string) => `PROJECT_ISSUES_COMMENTS_${issueId.toUpperCase()}`;
|
export const PROJECT_ISSUES_COMMENTS = (issueId: string) =>
|
||||||
export const PROJECT_ISSUES_ACTIVITY = (issueId: string) => `PROJECT_ISSUES_ACTIVITY_${issueId.toUpperCase()}`;
|
`PROJECT_ISSUES_COMMENTS_${issueId.toUpperCase()}`;
|
||||||
export const PROJECT_ISSUE_BY_STATE = (projectId: string) => `PROJECT_ISSUE_BY_STATE_${projectId.toUpperCase()}`;
|
export const PROJECT_ISSUES_ACTIVITY = (issueId: string) =>
|
||||||
export const PROJECT_ISSUE_LABELS = (projectId: string) => `PROJECT_ISSUE_LABELS_${projectId.toUpperCase()}`;
|
`PROJECT_ISSUES_ACTIVITY_${issueId.toUpperCase()}`;
|
||||||
|
export const PROJECT_ISSUE_BY_STATE = (projectId: string) =>
|
||||||
|
`PROJECT_ISSUE_BY_STATE_${projectId.toUpperCase()}`;
|
||||||
|
export const PROJECT_ISSUE_LABELS = (projectId: string) =>
|
||||||
|
`PROJECT_ISSUE_LABELS_${projectId.toUpperCase()}`;
|
||||||
export const PROJECT_GITHUB_REPOSITORY = (projectId: string) =>
|
export const PROJECT_GITHUB_REPOSITORY = (projectId: string) =>
|
||||||
`PROJECT_GITHUB_REPOSITORY_${projectId.toUpperCase()}`;
|
`PROJECT_GITHUB_REPOSITORY_${projectId.toUpperCase()}`;
|
||||||
|
|
||||||
@ -73,17 +83,21 @@ export const CYCLE_ISSUES_WITH_PARAMS = (cycleId: string, params?: any) => {
|
|||||||
export const CYCLE_DETAILS = (cycleId: string) => `CYCLE_DETAILS_${cycleId.toUpperCase()}`;
|
export const CYCLE_DETAILS = (cycleId: string) => `CYCLE_DETAILS_${cycleId.toUpperCase()}`;
|
||||||
export const CYCLE_CURRENT_AND_UPCOMING_LIST = (projectId: string) =>
|
export const CYCLE_CURRENT_AND_UPCOMING_LIST = (projectId: string) =>
|
||||||
`CYCLE_CURRENT_AND_UPCOMING_LIST_${projectId.toUpperCase()}`;
|
`CYCLE_CURRENT_AND_UPCOMING_LIST_${projectId.toUpperCase()}`;
|
||||||
export const CYCLE_DRAFT_LIST = (projectId: string) => `CYCLE_DRAFT_LIST_${projectId.toUpperCase()}`;
|
export const CYCLE_DRAFT_LIST = (projectId: string) =>
|
||||||
export const CYCLE_COMPLETE_LIST = (projectId: string) => `CYCLE_COMPLETE_LIST_${projectId.toUpperCase()}`;
|
`CYCLE_DRAFT_LIST_${projectId.toUpperCase()}`;
|
||||||
|
export const CYCLE_COMPLETE_LIST = (projectId: string) =>
|
||||||
|
`CYCLE_COMPLETE_LIST_${projectId.toUpperCase()}`;
|
||||||
|
|
||||||
export const STATE_LIST = (projectId: string) => `STATE_LIST_${projectId.toUpperCase()}`;
|
export const STATE_LIST = (projectId: string) => `STATE_LIST_${projectId.toUpperCase()}`;
|
||||||
export const STATE_DETAIL = "STATE_DETAILS";
|
export const STATE_DETAIL = "STATE_DETAILS";
|
||||||
|
|
||||||
export const USER_ISSUE = (workspaceSlug: string) => `USER_ISSUE_${workspaceSlug.toUpperCase()}`;
|
export const USER_ISSUE = (workspaceSlug: string) => `USER_ISSUE_${workspaceSlug.toUpperCase()}`;
|
||||||
export const USER_ACTIVITY = (workspaceSlug: string) => `USER_ACTIVITY_${workspaceSlug.toUpperCase()}`;
|
export const USER_ACTIVITY = (workspaceSlug: string) =>
|
||||||
|
`USER_ACTIVITY_${workspaceSlug.toUpperCase()}`;
|
||||||
export const USER_WORKSPACE_DASHBOARD = (workspaceSlug: string) =>
|
export const USER_WORKSPACE_DASHBOARD = (workspaceSlug: string) =>
|
||||||
`USER_WORKSPACE_DASHBOARD_${workspaceSlug.toUpperCase()}`;
|
`USER_WORKSPACE_DASHBOARD_${workspaceSlug.toUpperCase()}`;
|
||||||
export const USER_PROJECT_VIEW = (projectId: string) => `USER_PROJECT_VIEW_${projectId.toUpperCase()}`;
|
export const USER_PROJECT_VIEW = (projectId: string) =>
|
||||||
|
`USER_PROJECT_VIEW_${projectId.toUpperCase()}`;
|
||||||
|
|
||||||
export const MODULE_LIST = (projectId: string) => `MODULE_LIST_${projectId.toUpperCase()}`;
|
export const MODULE_LIST = (projectId: string) => `MODULE_LIST_${projectId.toUpperCase()}`;
|
||||||
export const MODULE_ISSUES = (moduleId: string) => `MODULE_ISSUES_${moduleId.toUpperCase()}`;
|
export const MODULE_ISSUES = (moduleId: string) => `MODULE_ISSUES_${moduleId.toUpperCase()}`;
|
||||||
@ -107,11 +121,14 @@ export const SUB_ISSUES = (issueId: string) => `SUB_ISSUES_${issueId.toUpperCase
|
|||||||
// integrations
|
// integrations
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
export const RECENT_PAGES_LIST = (projectId: string) => `RECENT_PAGES_LIST_${projectId.toUpperCase()}`;
|
export const RECENT_PAGES_LIST = (projectId: string) =>
|
||||||
|
`RECENT_PAGES_LIST_${projectId.toUpperCase()}`;
|
||||||
export const ALL_PAGES_LIST = (projectId: string) => `ALL_PAGES_LIST_${projectId.toUpperCase()}`;
|
export const ALL_PAGES_LIST = (projectId: string) => `ALL_PAGES_LIST_${projectId.toUpperCase()}`;
|
||||||
export const FAVORITE_PAGES_LIST = (projectId: string) => `FAVORITE_PAGES_LIST_${projectId.toUpperCase()}`;
|
export const FAVORITE_PAGES_LIST = (projectId: string) =>
|
||||||
|
`FAVORITE_PAGES_LIST_${projectId.toUpperCase()}`;
|
||||||
export const MY_PAGES_LIST = (projectId: string) => `MY_PAGES_LIST_${projectId.toUpperCase()}`;
|
export const MY_PAGES_LIST = (projectId: string) => `MY_PAGES_LIST_${projectId.toUpperCase()}`;
|
||||||
export const OTHER_PAGES_LIST = (projectId: string) => `OTHER_PAGES_LIST_${projectId.toUpperCase()}`;
|
export const OTHER_PAGES_LIST = (projectId: string) =>
|
||||||
|
`OTHER_PAGES_LIST_${projectId.toUpperCase()}`;
|
||||||
export const PAGE_DETAILS = (pageId: string) => `PAGE_DETAILS_${pageId.toUpperCase()}`;
|
export const PAGE_DETAILS = (pageId: string) => `PAGE_DETAILS_${pageId.toUpperCase()}`;
|
||||||
export const PAGE_BLOCKS_LIST = (pageId: string) => `PAGE_BLOCK_LIST_${pageId.toUpperCase()}`;
|
export const PAGE_BLOCKS_LIST = (pageId: string) => `PAGE_BLOCK_LIST_${pageId.toUpperCase()}`;
|
||||||
export const PAGE_BLOCK_DETAILS = (pageId: string) => `PAGE_BLOCK_DETAILS_${pageId.toUpperCase()}`;
|
export const PAGE_BLOCK_DETAILS = (pageId: string) => `PAGE_BLOCK_DETAILS_${pageId.toUpperCase()}`;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import APIService from "services/api.service";
|
import APIService from "services/api.service";
|
||||||
import trackEventServices from "services/track-event.service";
|
import trackEventServices from "services/track-event.service";
|
||||||
// type
|
// type
|
||||||
import type { IIssue, IIssueActivity, IIssueComment, IIssueViewOptions } from "types";
|
import type { IIssue, IIssueActivity, IIssueComment, IIssueLabels, IIssueViewOptions } from "types";
|
||||||
|
|
||||||
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
const { NEXT_PUBLIC_API_BASE_URL } = process.env;
|
||||||
|
|
||||||
@ -196,7 +196,7 @@ class ProjectIssuesServices extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getIssueLabels(workspaceSlug: string, projectId: string): Promise<any> {
|
async getIssueLabels(workspaceSlug: string, projectId: string): Promise<IIssueLabels[]> {
|
||||||
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/`)
|
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-labels/`)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user