forked from github/plane
refactor: filters list component (#1687)
* refactor: filters list component * fix: build error
This commit is contained in:
parent
0b86080166
commit
c54b8b9a15
@ -1,7 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
|
||||||
|
|
||||||
// icons
|
// icons
|
||||||
import { XMarkIcon } from "@heroicons/react/24/outline";
|
import { XMarkIcon } from "@heroicons/react/24/outline";
|
||||||
import { getPriorityIcon, getStateGroupIcon } from "components/icons";
|
import { getPriorityIcon, getStateGroupIcon } from "components/icons";
|
||||||
@ -12,11 +10,13 @@ import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
|||||||
// helpers
|
// helpers
|
||||||
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssueFilterOptions, IIssueLabels, IState, IUserLite } from "types";
|
import { IIssueFilterOptions, IIssueLabels, IState, IUserLite, TStateGroups } from "types";
|
||||||
|
// constants
|
||||||
|
import { STATE_GROUP_COLORS } from "constants/state";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
filters: any;
|
filters: Partial<IIssueFilterOptions>;
|
||||||
setFilters: any;
|
setFilters: (updatedFilter: Partial<IIssueFilterOptions>) => void;
|
||||||
clearAllFilters: (...args: any) => void;
|
clearAllFilters: (...args: any) => void;
|
||||||
labels: IIssueLabels[] | undefined;
|
labels: IIssueLabels[] | undefined;
|
||||||
members: IUserLite[] | undefined;
|
members: IUserLite[] | undefined;
|
||||||
@ -31,9 +31,6 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
members,
|
members,
|
||||||
states,
|
states,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
|
||||||
const { viewId } = router.query;
|
|
||||||
|
|
||||||
if (!filters) return <></>;
|
if (!filters) return <></>;
|
||||||
|
|
||||||
const nullFilters = Object.keys(filters).filter(
|
const nullFilters = Object.keys(filters).filter(
|
||||||
@ -42,24 +39,26 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-wrap items-center gap-2 text-xs">
|
<div className="flex flex-1 flex-wrap items-center gap-2 text-xs">
|
||||||
{Object.keys(filters).map((key) => {
|
{Object.keys(filters).map((filterKey) => {
|
||||||
if (filters[key as keyof typeof filters] !== null)
|
const key = filterKey as keyof typeof filters;
|
||||||
return (
|
|
||||||
<div
|
if (filters[key] === null) return null;
|
||||||
key={key}
|
|
||||||
className="flex items-center gap-x-2 rounded-full border border-custom-border-200 bg-custom-background-80 px-2 py-1"
|
return (
|
||||||
>
|
<div
|
||||||
<span className="capitalize text-custom-text-200">
|
key={key}
|
||||||
{key === "target_date" ? "Due Date" : replaceUnderscoreIfSnakeCase(key)}:
|
className="flex items-center gap-x-2 rounded-full border border-custom-border-200 bg-custom-background-80 px-2 py-1"
|
||||||
</span>
|
>
|
||||||
{filters[key as keyof IIssueFilterOptions] === null ||
|
<span className="capitalize text-custom-text-200">
|
||||||
(filters[key as keyof IIssueFilterOptions]?.length ?? 0) <= 0 ? (
|
{key === "target_date" ? "Due Date" : replaceUnderscoreIfSnakeCase(key)}:
|
||||||
<span className="inline-flex items-center px-2 py-0.5 font-medium">None</span>
|
</span>
|
||||||
) : Array.isArray(filters[key as keyof IIssueFilterOptions]) ? (
|
{filters[key] === null || (filters[key]?.length ?? 0) <= 0 ? (
|
||||||
<div className="space-x-2">
|
<span className="inline-flex items-center px-2 py-0.5 font-medium">None</span>
|
||||||
{key === "state" ? (
|
) : Array.isArray(filters[key]) ? (
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
<div className="space-x-2">
|
||||||
{filters.state?.map((stateId: any) => {
|
<div className="flex flex-wrap items-center gap-1">
|
||||||
|
{key === "state"
|
||||||
|
? filters.state?.map((stateId: string) => {
|
||||||
const state = states?.find((s) => s.id === stateId);
|
const state = states?.find((s) => s.id === stateId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -83,33 +82,46 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
state: filters.state?.filter((s: any) => s !== stateId),
|
||||||
state: filters.state?.filter((s: any) => s !== stateId),
|
})
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
<button
|
: key === "state_group"
|
||||||
type="button"
|
? filters.state_group?.map((stateGroup) => {
|
||||||
onClick={() =>
|
const group = stateGroup as TStateGroups;
|
||||||
setFilters({
|
|
||||||
state: null,
|
return (
|
||||||
})
|
<p
|
||||||
}
|
key={group}
|
||||||
>
|
className="inline-flex items-center gap-x-1 rounded-full px-2 py-0.5 capitalize"
|
||||||
<XMarkIcon className="h-3 w-3" />
|
style={{
|
||||||
</button>
|
color: STATE_GROUP_COLORS[group],
|
||||||
</div>
|
backgroundColor: `${STATE_GROUP_COLORS[group]}20`,
|
||||||
) : key === "priority" ? (
|
}}
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
>
|
||||||
{filters.priority?.map((priority: any) => (
|
<span>{getStateGroupIcon(group, "16", "16")}</span>
|
||||||
|
<span>{group}</span>
|
||||||
|
<span
|
||||||
|
className="cursor-pointer"
|
||||||
|
onClick={() =>
|
||||||
|
setFilters({
|
||||||
|
state_group: filters.state_group?.filter((g) => g !== group),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<XMarkIcon className="h-3 w-3" />
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
: key === "priority"
|
||||||
|
? filters.priority?.map((priority: any) => (
|
||||||
<p
|
<p
|
||||||
key={priority}
|
key={priority}
|
||||||
className={`inline-flex items-center gap-x-1 rounded-full px-2 py-0.5 capitalize ${
|
className={`inline-flex items-center gap-x-1 rounded-full px-2 py-0.5 capitalize ${
|
||||||
@ -129,32 +141,17 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
priority: filters.priority?.filter((p: any) => p !== priority),
|
||||||
priority: filters.priority?.filter((p: any) => p !== priority),
|
})
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
))}
|
))
|
||||||
<button
|
: key === "assignees"
|
||||||
type="button"
|
? filters.assignees?.map((memberId: string) => {
|
||||||
onClick={() =>
|
|
||||||
setFilters({
|
|
||||||
priority: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<XMarkIcon className="h-3 w-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : key === "assignees" ? (
|
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
|
||||||
{filters.assignees?.map((memberId: string) => {
|
|
||||||
const member = members?.find((m) => m.id === memberId);
|
const member = members?.find((m) => m.id === memberId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -167,35 +164,18 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
assignees: filters.assignees?.filter((p: any) => p !== memberId),
|
||||||
assignees: filters.assignees?.filter(
|
})
|
||||||
(p: any) => p !== memberId
|
|
||||||
),
|
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
<button
|
: key === "created_by"
|
||||||
type="button"
|
? filters.created_by?.map((memberId: string) => {
|
||||||
onClick={() =>
|
|
||||||
setFilters({
|
|
||||||
assignees: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<XMarkIcon className="h-3 w-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : key === "created_by" ? (
|
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
|
||||||
{filters.created_by?.map((memberId: string) => {
|
|
||||||
const member = members?.find((m) => m.id === memberId);
|
const member = members?.find((m) => m.id === memberId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -208,35 +188,20 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
created_by: filters.created_by?.filter(
|
||||||
created_by: filters.created_by?.filter(
|
(p: any) => p !== memberId
|
||||||
(p: any) => p !== memberId
|
),
|
||||||
),
|
})
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
<button
|
: key === "labels"
|
||||||
type="button"
|
? filters.labels?.map((labelId: string) => {
|
||||||
onClick={() =>
|
|
||||||
setFilters({
|
|
||||||
created_by: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<XMarkIcon className="h-3 w-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : key === "labels" ? (
|
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
|
||||||
{filters.labels?.map((labelId: string) => {
|
|
||||||
const label = labels?.find((l) => l.id === labelId);
|
const label = labels?.find((l) => l.id === labelId);
|
||||||
|
|
||||||
if (!label) return null;
|
if (!label) return null;
|
||||||
@ -260,12 +225,9 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
labels: filters.labels?.filter((l: any) => l !== labelId),
|
||||||
labels: filters.labels?.filter((l: any) => l !== labelId),
|
})
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon
|
<XMarkIcon
|
||||||
@ -277,22 +239,10 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
<button
|
: key === "target_date"
|
||||||
type="button"
|
? filters.target_date?.map((date: string) => {
|
||||||
onClick={() =>
|
if (filters.target_date && filters.target_date.length <= 0) return null;
|
||||||
setFilters({
|
|
||||||
labels: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<XMarkIcon className="h-3 w-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : key === "target_date" ? (
|
|
||||||
<div className="flex flex-wrap items-center gap-1">
|
|
||||||
{filters.target_date?.map((date: string) => {
|
|
||||||
if (filters.target_date.length <= 0) return null;
|
|
||||||
|
|
||||||
const splitDate = date.split(";");
|
const splitDate = date.split(";");
|
||||||
|
|
||||||
@ -308,39 +258,17 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<span
|
<span
|
||||||
className="cursor-pointer"
|
className="cursor-pointer"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setFilters(
|
setFilters({
|
||||||
{
|
target_date: filters.target_date?.filter((d: any) => d !== date),
|
||||||
target_date: filters.target_date?.filter(
|
})
|
||||||
(d: any) => d !== date
|
|
||||||
),
|
|
||||||
},
|
|
||||||
!Boolean(viewId)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})
|
||||||
<button
|
: (filters[key] as any)?.join(", ")}
|
||||||
type="button"
|
|
||||||
onClick={() =>
|
|
||||||
setFilters({
|
|
||||||
target_date: null,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<XMarkIcon className="h-3 w-3" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
(filters[key as keyof IIssueFilterOptions] as any)?.join(", ")
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="flex items-center gap-x-1 capitalize">
|
|
||||||
{filters[key as keyof typeof filters]}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@ -352,9 +280,24 @@ export const FiltersList: React.FC<Props> = ({
|
|||||||
<XMarkIcon className="h-3 w-3" />
|
<XMarkIcon className="h-3 w-3" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</div>
|
) : (
|
||||||
);
|
<div className="flex items-center gap-x-1 capitalize">
|
||||||
|
{filters[key as keyof typeof filters]}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() =>
|
||||||
|
setFilters({
|
||||||
|
[key]: null,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<XMarkIcon className="h-3 w-3" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
{Object.keys(filters).length > 0 && nullFilters.length !== Object.keys(filters).length && (
|
{Object.keys(filters).length > 0 && nullFilters.length !== Object.keys(filters).length && (
|
||||||
<button
|
<button
|
||||||
|
@ -466,7 +466,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
<div className="flex items-center justify-between gap-2 px-5 pt-3 pb-0">
|
<div className="flex items-center justify-between gap-2 px-5 pt-3 pb-0">
|
||||||
<FiltersList
|
<FiltersList
|
||||||
filters={filters}
|
filters={filters}
|
||||||
setFilters={setFilters}
|
setFilters={(updatedFilter) => setFilters(updatedFilter, !Boolean(viewId))}
|
||||||
labels={labels}
|
labels={labels}
|
||||||
members={members?.map((m) => m.member)}
|
members={members?.map((m) => m.member)}
|
||||||
states={states}
|
states={states}
|
||||||
|
@ -200,17 +200,15 @@ export const MyIssuesView: React.FC<Props> = ({
|
|||||||
},
|
},
|
||||||
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
[makeIssueCopy, handleEditIssue, handleDeleteIssue]
|
||||||
);
|
);
|
||||||
const filtersToShow = { ...filters };
|
|
||||||
delete filtersToShow?.assignees;
|
|
||||||
delete filtersToShow?.created_by;
|
|
||||||
|
|
||||||
const nullFilters = Object.keys(filtersToShow).filter(
|
const filtersToDisplay = { ...filters, assignees: null, created_by: null };
|
||||||
(key) => filtersToShow[key as keyof IIssueFilterOptions] === null
|
|
||||||
|
const nullFilters = Object.keys(filtersToDisplay).filter(
|
||||||
|
(key) => filtersToDisplay[key as keyof IIssueFilterOptions] === null
|
||||||
);
|
);
|
||||||
|
|
||||||
const areFiltersApplied =
|
const areFiltersApplied =
|
||||||
Object.keys(filtersToShow).length > 0 &&
|
Object.keys(filtersToDisplay).length > 0 &&
|
||||||
nullFilters.length !== Object.keys(filtersToShow).length;
|
nullFilters.length !== Object.keys(filtersToDisplay).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -242,7 +240,7 @@ export const MyIssuesView: React.FC<Props> = ({
|
|||||||
<>
|
<>
|
||||||
<div className="flex items-center justify-between gap-2 px-5 pt-3 pb-0">
|
<div className="flex items-center justify-between gap-2 px-5 pt-3 pb-0">
|
||||||
<FiltersList
|
<FiltersList
|
||||||
filters={filtersToShow}
|
filters={filtersToDisplay}
|
||||||
setFilters={setFilters}
|
setFilters={setFilters}
|
||||||
labels={labels}
|
labels={labels}
|
||||||
members={undefined}
|
members={undefined}
|
||||||
|
@ -91,6 +91,7 @@ export const initialState: StateType = {
|
|||||||
assignees: null,
|
assignees: null,
|
||||||
labels: null,
|
labels: null,
|
||||||
state: null,
|
state: null,
|
||||||
|
state_group: null,
|
||||||
created_by: null,
|
created_by: null,
|
||||||
target_date: null,
|
target_date: null,
|
||||||
},
|
},
|
||||||
|
@ -88,18 +88,24 @@ const useMyIssuesFilters = (workspaceSlug: string | undefined) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const issueView = (myWorkspace?.view_props ?? initialValues).issueView;
|
const issueView = (myWorkspace?.view_props ?? initialValues).issueView;
|
||||||
|
const groupBy = (myWorkspace?.view_props ?? initialValues).groupByProperty;
|
||||||
|
const orderBy = (myWorkspace?.view_props ?? initialValues).orderBy;
|
||||||
|
const showEmptyGroups = (myWorkspace?.view_props ?? initialValues).showEmptyGroups;
|
||||||
|
const filters = (myWorkspace?.view_props ?? initialValues).filters;
|
||||||
|
|
||||||
const setIssueView = useCallback(
|
const setIssueView = useCallback(
|
||||||
(newView: TIssueViewOptions) => {
|
(newView: TIssueViewOptions) => {
|
||||||
console.log("newView", newView);
|
const payload: Partial<IWorkspaceViewProps> = {
|
||||||
|
|
||||||
saveData({
|
|
||||||
issueView: newView,
|
issueView: newView,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (newView === "kanban" && groupBy === null) payload.groupByProperty = "state_detail.group";
|
||||||
|
|
||||||
|
saveData(payload);
|
||||||
},
|
},
|
||||||
[saveData]
|
[groupBy, saveData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const groupBy = (myWorkspace?.view_props ?? initialValues).groupByProperty;
|
|
||||||
const setGroupBy = useCallback(
|
const setGroupBy = useCallback(
|
||||||
(newGroup: TIssueGroupByOptions) => {
|
(newGroup: TIssueGroupByOptions) => {
|
||||||
saveData({
|
saveData({
|
||||||
@ -109,7 +115,6 @@ const useMyIssuesFilters = (workspaceSlug: string | undefined) => {
|
|||||||
[saveData]
|
[saveData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const orderBy = (myWorkspace?.view_props ?? initialValues).orderBy;
|
|
||||||
const setOrderBy = useCallback(
|
const setOrderBy = useCallback(
|
||||||
(newOrderBy: TIssueOrderByOptions) => {
|
(newOrderBy: TIssueOrderByOptions) => {
|
||||||
saveData({
|
saveData({
|
||||||
@ -119,7 +124,6 @@ const useMyIssuesFilters = (workspaceSlug: string | undefined) => {
|
|||||||
[saveData]
|
[saveData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const showEmptyGroups = (myWorkspace?.view_props ?? initialValues).showEmptyGroups;
|
|
||||||
const setShowEmptyGroups = useCallback(() => {
|
const setShowEmptyGroups = useCallback(() => {
|
||||||
if (!myWorkspace) return;
|
if (!myWorkspace) return;
|
||||||
|
|
||||||
@ -142,9 +146,8 @@ const useMyIssuesFilters = (workspaceSlug: string | undefined) => {
|
|||||||
[myWorkspace, saveData]
|
[myWorkspace, saveData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const filters = (myWorkspace?.view_props ?? initialValues).filters;
|
|
||||||
const setFilters = useCallback(
|
const setFilters = useCallback(
|
||||||
(updatedFilter: Partial<IIssueFilterOptions & { state_group: string[] | null }>) => {
|
(updatedFilter: Partial<IIssueFilterOptions>) => {
|
||||||
if (!myWorkspace) return;
|
if (!myWorkspace) return;
|
||||||
|
|
||||||
saveData({
|
saveData({
|
||||||
|
2
apps/app/types/issues.d.ts
vendored
2
apps/app/types/issues.d.ts
vendored
@ -8,6 +8,7 @@ import type {
|
|||||||
IProjectLite,
|
IProjectLite,
|
||||||
IWorkspaceLite,
|
IWorkspaceLite,
|
||||||
IStateLite,
|
IStateLite,
|
||||||
|
TStateGroups,
|
||||||
} from "types";
|
} from "types";
|
||||||
|
|
||||||
export interface IIssueCycle {
|
export interface IIssueCycle {
|
||||||
@ -231,6 +232,7 @@ export interface IIssueFilterOptions {
|
|||||||
assignees: string[] | null;
|
assignees: string[] | null;
|
||||||
target_date: string[] | null;
|
target_date: string[] | null;
|
||||||
state: string[] | null;
|
state: string[] | null;
|
||||||
|
state_group: TStateGroups[] | null;
|
||||||
labels: string[] | null;
|
labels: string[] | null;
|
||||||
priority: string[] | null;
|
priority: string[] | null;
|
||||||
created_by: string[] | null;
|
created_by: string[] | null;
|
||||||
|
4
apps/app/types/projects.d.ts
vendored
4
apps/app/types/projects.d.ts
vendored
@ -6,7 +6,7 @@ import type {
|
|||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
TIssueOrderByOptions,
|
TIssueOrderByOptions,
|
||||||
TIssueViewOptions,
|
TIssueViewOptions,
|
||||||
TStateGroup,
|
TStateGroups,
|
||||||
} from "./";
|
} from "./";
|
||||||
|
|
||||||
export interface IProject {
|
export interface IProject {
|
||||||
@ -140,7 +140,7 @@ export interface ISearchIssueResponse {
|
|||||||
project__name: string;
|
project__name: string;
|
||||||
sequence_id: number;
|
sequence_id: number;
|
||||||
state__color: string;
|
state__color: string;
|
||||||
state__group: TStateGroup;
|
state__group: TStateGroups;
|
||||||
state__name: string;
|
state__name: string;
|
||||||
workspace__slug: string;
|
workspace__slug: string;
|
||||||
}
|
}
|
||||||
|
6
apps/app/types/state.d.ts
vendored
6
apps/app/types/state.d.ts
vendored
@ -1,6 +1,6 @@
|
|||||||
import { IProject, IProjectLite, IWorkspaceLite } from "types";
|
import { IProject, IProjectLite, IWorkspaceLite } from "types";
|
||||||
|
|
||||||
export type TStateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled";
|
export type TStateGroups = "backlog" | "unstarted" | "started" | "completed" | "cancelled";
|
||||||
|
|
||||||
export interface IState {
|
export interface IState {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
@ -9,7 +9,7 @@ export interface IState {
|
|||||||
readonly created_by: string;
|
readonly created_by: string;
|
||||||
default: boolean;
|
default: boolean;
|
||||||
description: string;
|
description: string;
|
||||||
group: TStateGroup;
|
group: TStateGroups;
|
||||||
name: string;
|
name: string;
|
||||||
project: string;
|
project: string;
|
||||||
readonly project_detail: IProjectLite;
|
readonly project_detail: IProjectLite;
|
||||||
@ -23,7 +23,7 @@ export interface IState {
|
|||||||
|
|
||||||
export interface IStateLite {
|
export interface IStateLite {
|
||||||
color: string;
|
color: string;
|
||||||
group: TStateGroup;
|
group: TStateGroups;
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
6
apps/app/types/workspace.d.ts
vendored
6
apps/app/types/workspace.d.ts
vendored
@ -67,11 +67,7 @@ export interface IWorkspaceViewProps {
|
|||||||
issueView: TIssueViewOptions;
|
issueView: TIssueViewOptions;
|
||||||
groupByProperty: TIssueGroupByOptions;
|
groupByProperty: TIssueGroupByOptions;
|
||||||
orderBy: TIssueOrderByOptions;
|
orderBy: TIssueOrderByOptions;
|
||||||
filters: Partial<
|
filters: Partial<IIssueFilterOptions>;
|
||||||
IIssueFilterOptions & {
|
|
||||||
state_group: string[] | null;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
showEmptyGroups: boolean;
|
showEmptyGroups: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user