forked from github/plane
chore: store fixes and static data setup
This commit is contained in:
parent
e96bc77215
commit
6d52801ea7
@ -27,7 +27,7 @@ import { checkIfArraysHaveSameElements } from "helpers/array.helper";
|
||||
// types
|
||||
import { Properties, TIssueViewOptions } from "types";
|
||||
// constants
|
||||
import { GROUP_BY_OPTIONS, ORDER_BY_OPTIONS, FILTER_ISSUE_OPTIONS } from "constants/issue";
|
||||
import { ISSUE_GROUP_BY_OPTIONS, ISSUE_ORDER_BY_OPTIONS, ISSUE_FILTER_OPTIONS } from "constants/issue";
|
||||
|
||||
const issueViewOptions: { type: TIssueViewOptions; Icon: any }[] = [
|
||||
{
|
||||
@ -69,19 +69,10 @@ export const IssuesFilterView: React.FC = () => {
|
||||
const isArchivedIssues = router.pathname.includes("archived-issues");
|
||||
const isDraftIssues = router.pathname.includes("draft-issues");
|
||||
|
||||
const {
|
||||
displayFilters,
|
||||
setDisplayFilters,
|
||||
filters,
|
||||
setFilters,
|
||||
resetFilterToDefault,
|
||||
setNewFilterDefaultView,
|
||||
} = useIssuesView();
|
||||
const { displayFilters, setDisplayFilters, filters, setFilters, resetFilterToDefault, setNewFilterDefaultView } =
|
||||
useIssuesView();
|
||||
|
||||
const [properties, setProperties] = useIssuesProperties(
|
||||
workspaceSlug as string,
|
||||
projectId as string
|
||||
);
|
||||
const [properties, setProperties] = useIssuesProperties(workspaceSlug as string, projectId as string);
|
||||
|
||||
const { isEstimateActive } = useEstimateOption();
|
||||
|
||||
@ -92,9 +83,7 @@ export const IssuesFilterView: React.FC = () => {
|
||||
{issueViewOptions.map((option) => (
|
||||
<Tooltip
|
||||
key={option.type}
|
||||
tooltipContent={
|
||||
<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>
|
||||
}
|
||||
tooltipContent={<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>}
|
||||
position="bottom"
|
||||
>
|
||||
<button
|
||||
@ -122,9 +111,7 @@ export const IssuesFilterView: React.FC = () => {
|
||||
{issueViewForDraftIssues.map((option) => (
|
||||
<Tooltip
|
||||
key={option.type}
|
||||
tooltipContent={
|
||||
<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>
|
||||
}
|
||||
tooltipContent={<span className="capitalize">{replaceUnderscoreIfSnakeCase(option.type)} View</span>}
|
||||
position="bottom"
|
||||
>
|
||||
<button
|
||||
@ -164,9 +151,7 @@ export const IssuesFilterView: React.FC = () => {
|
||||
if (valueExists)
|
||||
setFilters(
|
||||
{
|
||||
[option.key]: ((filters[key] ?? []) as any[])?.filter(
|
||||
(val) => val !== option.value
|
||||
),
|
||||
[option.key]: ((filters[key] ?? []) as any[])?.filter((val) => val !== option.value),
|
||||
},
|
||||
!Boolean(viewId)
|
||||
);
|
||||
@ -187,9 +172,7 @@ export const IssuesFilterView: React.FC = () => {
|
||||
<>
|
||||
<Popover.Button
|
||||
className={`group flex items-center gap-2 rounded-md border border-custom-border-200 px-3 py-1.5 text-xs hover:bg-custom-sidebar-background-90 hover:text-custom-sidebar-text-100 focus:outline-none duration-300 ${
|
||||
open
|
||||
? "bg-custom-sidebar-background-90 text-custom-sidebar-text-100"
|
||||
: "text-custom-sidebar-text-200"
|
||||
open ? "bg-custom-sidebar-background-90 text-custom-sidebar-text-100" : "text-custom-sidebar-text-200"
|
||||
}`}
|
||||
>
|
||||
Display
|
||||
@ -216,24 +199,24 @@ export const IssuesFilterView: React.FC = () => {
|
||||
<div className="w-28">
|
||||
<CustomMenu
|
||||
label={
|
||||
GROUP_BY_OPTIONS.find(
|
||||
(option) => option.key === displayFilters.group_by
|
||||
)?.name ?? "Select"
|
||||
ISSUE_GROUP_BY_OPTIONS.find((option) => option.key === displayFilters.group_by)
|
||||
?.title ?? "Select"
|
||||
}
|
||||
className="!w-full"
|
||||
buttonClassName="w-full"
|
||||
>
|
||||
{GROUP_BY_OPTIONS.map((option) => {
|
||||
if (displayFilters.layout === "kanban" && option.key === null)
|
||||
return null;
|
||||
{ISSUE_GROUP_BY_OPTIONS.map((option) => {
|
||||
if (displayFilters.layout === "kanban" && option.key === null) return null;
|
||||
if (option.key === "project") return null;
|
||||
|
||||
return (
|
||||
<CustomMenu.MenuItem
|
||||
key={option.key}
|
||||
onClick={() => setDisplayFilters({ group_by: option.key })}
|
||||
onClick={() => {
|
||||
// setDisplayFilters({ group_by: option.key })
|
||||
}}
|
||||
>
|
||||
{option.name}
|
||||
{option.title}
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
@ -241,79 +224,71 @@ export const IssuesFilterView: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{displayFilters.layout !== "calendar" &&
|
||||
displayFilters.layout !== "spreadsheet" && (
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="text-custom-text-200">Order by</h4>
|
||||
<div className="w-28">
|
||||
<CustomMenu
|
||||
label={
|
||||
ORDER_BY_OPTIONS.find(
|
||||
(option) => option.key === displayFilters.order_by
|
||||
)?.name ?? "Select"
|
||||
}
|
||||
className="!w-full"
|
||||
buttonClassName="w-full"
|
||||
>
|
||||
{ORDER_BY_OPTIONS.map((option) =>
|
||||
displayFilters.group_by === "priority" &&
|
||||
option.key === "priority" ? null : (
|
||||
<CustomMenu.MenuItem
|
||||
key={option.key}
|
||||
onClick={() => {
|
||||
setDisplayFilters({ order_by: option.key });
|
||||
}}
|
||||
>
|
||||
{option.name}
|
||||
</CustomMenu.MenuItem>
|
||||
)
|
||||
)}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
{displayFilters.layout !== "calendar" && displayFilters.layout !== "spreadsheet" && (
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="text-custom-text-200">Order by</h4>
|
||||
<div className="w-28">
|
||||
<CustomMenu
|
||||
label={
|
||||
ISSUE_ORDER_BY_OPTIONS.find((option) => option.key === displayFilters.order_by)?.title ??
|
||||
"Select"
|
||||
}
|
||||
className="!w-full"
|
||||
buttonClassName="w-full"
|
||||
>
|
||||
{ISSUE_ORDER_BY_OPTIONS.map((option) =>
|
||||
displayFilters.group_by === "priority" && option.key === "priority" ? null : (
|
||||
<CustomMenu.MenuItem
|
||||
key={option.key}
|
||||
onClick={() => {
|
||||
// setDisplayFilters({ order_by: option.key });
|
||||
}}
|
||||
>
|
||||
{option.title}
|
||||
</CustomMenu.MenuItem>
|
||||
)
|
||||
)}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="text-custom-text-200">Issue type</h4>
|
||||
<div className="w-28">
|
||||
<CustomMenu
|
||||
label={
|
||||
FILTER_ISSUE_OPTIONS.find(
|
||||
(option) => option.key === displayFilters.type
|
||||
)?.name ?? "Select"
|
||||
ISSUE_FILTER_OPTIONS.find((option) => option.key === displayFilters.type)?.title ?? "Select"
|
||||
}
|
||||
className="!w-full"
|
||||
buttonClassName="w-full"
|
||||
>
|
||||
{FILTER_ISSUE_OPTIONS.map((option) => (
|
||||
{ISSUE_FILTER_OPTIONS.map((option) => (
|
||||
<CustomMenu.MenuItem
|
||||
key={option.key}
|
||||
onClick={() =>
|
||||
setDisplayFilters({
|
||||
type: option.key,
|
||||
})
|
||||
}
|
||||
onClick={() => {
|
||||
// setDisplayFilters({
|
||||
// type: option.key,
|
||||
// })
|
||||
}}
|
||||
>
|
||||
{option.name}
|
||||
{option.title}
|
||||
</CustomMenu.MenuItem>
|
||||
))}
|
||||
</CustomMenu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{displayFilters.layout !== "calendar" &&
|
||||
displayFilters.layout !== "spreadsheet" && (
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="text-custom-text-200">Show sub-issues</h4>
|
||||
<div className="w-28">
|
||||
<ToggleSwitch
|
||||
value={displayFilters.sub_issue ?? true}
|
||||
onChange={() =>
|
||||
setDisplayFilters({ sub_issue: !displayFilters.sub_issue })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{displayFilters.layout !== "calendar" && displayFilters.layout !== "spreadsheet" && (
|
||||
<div className="flex items-center justify-between">
|
||||
<h4 className="text-custom-text-200">Show sub-issues</h4>
|
||||
<div className="w-28">
|
||||
<ToggleSwitch
|
||||
value={displayFilters.sub_issue ?? true}
|
||||
onChange={() => setDisplayFilters({ sub_issue: !displayFilters.sub_issue })}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{displayFilters.layout !== "calendar" &&
|
||||
displayFilters.layout !== "spreadsheet" &&
|
||||
displayFilters.layout !== "gantt_chart" && (
|
||||
@ -358,16 +333,11 @@ export const IssuesFilterView: React.FC = () => {
|
||||
|
||||
if (
|
||||
displayFilters.layout === "spreadsheet" &&
|
||||
(key === "attachment_count" ||
|
||||
key === "link" ||
|
||||
key === "sub_issue_count")
|
||||
(key === "attachment_count" || key === "link" || key === "sub_issue_count")
|
||||
)
|
||||
return null;
|
||||
|
||||
if (
|
||||
displayFilters.layout !== "spreadsheet" &&
|
||||
(key === "created_on" || key === "updated_on")
|
||||
)
|
||||
if (displayFilters.layout !== "spreadsheet" && (key === "created_on" || key === "updated_on"))
|
||||
return null;
|
||||
|
||||
return (
|
||||
|
@ -36,7 +36,7 @@ import {
|
||||
} from "@heroicons/react/24/outline";
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
// helpers
|
||||
import { handleIssuesMutation } from "constants/issue";
|
||||
import { handleIssuesMutation } from "helpers/issue.helper";
|
||||
import { copyTextToClipboard } from "helpers/string.helper";
|
||||
// types
|
||||
import { ICurrentUserResponse, IIssue, IIssueViewProps, ISubIssueResponse, UserAuth } from "types";
|
||||
|
@ -34,7 +34,7 @@ import {
|
||||
import { LayerDiagonalIcon } from "components/icons";
|
||||
// helpers
|
||||
import { copyTextToClipboard } from "helpers/string.helper";
|
||||
import { handleIssuesMutation } from "constants/issue";
|
||||
import { handleIssuesMutation } from "helpers/issue.helper";
|
||||
// types
|
||||
import {
|
||||
ICurrentUserResponse,
|
||||
|
@ -3,7 +3,7 @@ import { useRouter } from "next/router";
|
||||
// headless ui
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// services
|
||||
import CSVIntegrationService from "services/csv.services";
|
||||
import { CSVIntegrationService } from "services/csv.services";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// ui
|
||||
|
@ -6,15 +6,16 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
import { ISSUE_DISPLAY_PROPERTIES } from "constants/issue";
|
||||
|
||||
export const FilterDisplayProperties = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleDisplayProperties = (key: string, value: boolean) => {
|
||||
issueFilterStore.handleUserFilter("display_properties", key, !value);
|
||||
// issueFilterStore.handleUserFilter("display_properties", key, !value);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -26,26 +27,24 @@ export const FilterDisplayProperties = observer(() => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="space-y-[2px] pt-1 px-1 flex items-center whitespace-nowrap gap-2 flex-wrap">
|
||||
{issueFilterStore?.issueRenderFilters?.display_properties &&
|
||||
issueFilterStore?.issueRenderFilters?.display_properties.length > 0 &&
|
||||
issueFilterStore?.issueRenderFilters?.display_properties.map((_displayProperties) => (
|
||||
<div
|
||||
key={_displayProperties?.key}
|
||||
className={`cursor-pointer rounded-sm transition-all text-xs border p-0.5 px-1.5 ${
|
||||
issueFilterStore?.userFilters?.display_properties?.[_displayProperties?.key]
|
||||
? `bg-custom-primary-200 border-custom-primary-200 text-white`
|
||||
: `hover:bg-custom-border-100 border-custom-border-100`
|
||||
}`}
|
||||
onClick={() =>
|
||||
handleDisplayProperties(
|
||||
_displayProperties?.key,
|
||||
issueFilterStore?.userFilters?.display_properties?.[_displayProperties?.key]
|
||||
)
|
||||
}
|
||||
>
|
||||
{_displayProperties?.title}
|
||||
</div>
|
||||
))}
|
||||
{ISSUE_DISPLAY_PROPERTIES.map((displayProperty) => (
|
||||
<div
|
||||
key={displayProperty?.key}
|
||||
className={`cursor-pointer rounded-sm transition-all text-xs border p-0.5 px-1.5 ${
|
||||
issueFilterStore?.userDisplayProperties?.[displayProperty?.key]
|
||||
? `bg-custom-primary-200 border-custom-primary-200 text-white`
|
||||
: `hover:bg-custom-border-100 border-custom-border-100`
|
||||
}`}
|
||||
onClick={() => {
|
||||
handleDisplayProperties(
|
||||
displayProperty?.key,
|
||||
issueFilterStore?.userDisplayProperties?.[displayProperty?.key]
|
||||
);
|
||||
}}
|
||||
>
|
||||
{displayProperty?.title}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -7,25 +7,27 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
import { ISSUE_EXTRA_PROPERTIES } from "constants/issue";
|
||||
// default data
|
||||
import { issueFilterVisibilityData } from "store/helpers/issue-data";
|
||||
// import { issueFilterVisibilityData } from "helpers/issue.helper";
|
||||
|
||||
export const FilterExtraOptions = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleExtraOptions = (key: string, value: boolean) => {
|
||||
issueFilterStore.handleUserFilter("display_filters", key, !value);
|
||||
// issueFilterStore.handleUserFilter("display_filters", key, !value);
|
||||
};
|
||||
|
||||
const handleExtraOptionsSectionVisibility = (key: string) =>
|
||||
issueFilterStore?.issueView &&
|
||||
issueFilterStore?.issueLayout &&
|
||||
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]?.extra_options?.[
|
||||
issueFilterStore?.issueLayout
|
||||
].values?.includes(key);
|
||||
const handleExtraOptionsSectionVisibility = (key: string) => {
|
||||
// issueFilterStore?.issueView &&
|
||||
// issueFilterStore?.issueLayout &&
|
||||
// issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]?.extra_options?.[
|
||||
// issueFilterStore?.issueLayout
|
||||
// ].values?.includes(key);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
@ -36,24 +38,16 @@ export const FilterExtraOptions = observer(() => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="space-y-[2px] pt-1">
|
||||
{issueFilterStore?.issueRenderFilters?.extra_properties &&
|
||||
issueFilterStore?.issueRenderFilters?.extra_properties.length > 0 &&
|
||||
issueFilterStore?.issueRenderFilters?.extra_properties.map(
|
||||
(_extraProperties) =>
|
||||
handleExtraOptionsSectionVisibility(_extraProperties?.key) && (
|
||||
<FilterOption
|
||||
key={_extraProperties?.key}
|
||||
isChecked={issueFilterStore?.userFilters?.display_filters?.[_extraProperties?.key] ? true : false}
|
||||
onClick={() =>
|
||||
handleExtraOptions(
|
||||
_extraProperties?.key,
|
||||
issueFilterStore?.userFilters?.display_filters?.[_extraProperties?.key]
|
||||
)
|
||||
}
|
||||
title={_extraProperties.title}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{ISSUE_EXTRA_PROPERTIES.map((_extraProperties) => (
|
||||
<FilterOption
|
||||
key={_extraProperties?.key}
|
||||
isChecked={issueFilterStore?.userDisplayFilters?.[_extraProperties?.key] ? true : false}
|
||||
onClick={() =>
|
||||
handleExtraOptions(_extraProperties?.key, issueFilterStore?.userDisplayFilters?.[_extraProperties?.key])
|
||||
}
|
||||
title={_extraProperties.title}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -7,15 +7,16 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
import { ISSUE_GROUP_BY_OPTIONS } from "constants/issue";
|
||||
|
||||
export const FilterGroupBy = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleGroupBy = (key: string, value: string) => {
|
||||
issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
// issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -27,17 +28,15 @@ export const FilterGroupBy = observer(() => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="space-y-[2px] pt-1">
|
||||
{issueFilterStore?.issueRenderFilters?.group_by &&
|
||||
issueFilterStore?.issueRenderFilters?.group_by.length > 0 &&
|
||||
issueFilterStore?.issueRenderFilters?.group_by.map((_groupBy) => (
|
||||
<FilterOption
|
||||
key={_groupBy?.key}
|
||||
isChecked={issueFilterStore?.userFilters?.display_filters?.group_by === _groupBy?.key ? true : false}
|
||||
onClick={() => handleGroupBy("group_by", _groupBy?.key)}
|
||||
title={_groupBy.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
{ISSUE_GROUP_BY_OPTIONS.map((_groupBy) => (
|
||||
<FilterOption
|
||||
key={_groupBy?.key}
|
||||
isChecked={issueFilterStore?.userDisplayFilters?.group_by === _groupBy?.key ? true : false}
|
||||
onClick={() => handleGroupBy("group_by", _groupBy?.key)}
|
||||
title={_groupBy.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -11,70 +11,71 @@ import { observer } from "mobx-react-lite";
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
// default data
|
||||
import { issueFilterVisibilityData } from "store/helpers/issue-data";
|
||||
// import { issueFilterVisibilityData } from "store/helpers/issue-data";
|
||||
|
||||
export const DisplayFiltersSelection = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const handleDisplayPropertiesSectionVisibility =
|
||||
issueFilterStore?.issueView &&
|
||||
issueFilterStore?.issueLayout &&
|
||||
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]
|
||||
?.display_properties?.[issueFilterStore?.issueLayout];
|
||||
// const handleDisplayPropertiesSectionVisibility =
|
||||
// issueFilterStore?.issueView &&
|
||||
// issueFilterStore?.issueLayout &&
|
||||
// issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]
|
||||
// ?.display_properties?.[issueFilterStore?.issueLayout];
|
||||
|
||||
const handleDisplayFilterSectionVisibility = (section_key: string) =>
|
||||
issueFilterStore?.issueView &&
|
||||
issueFilterStore?.issueLayout &&
|
||||
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]?.display_filters?.[
|
||||
issueFilterStore?.issueLayout
|
||||
].includes(section_key);
|
||||
const handleDisplayFilterSectionVisibility = (section_key: string) => {
|
||||
// issueFilterStore?.issueView &&
|
||||
// issueFilterStore?.issueLayout &&
|
||||
// issueFilterVisibilityData[
|
||||
// issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"
|
||||
// ]?.display_filters?.[issueFilterStore?.issueLayout].includes(section_key);
|
||||
};
|
||||
|
||||
const handleExtraOptionsSectionVisibility =
|
||||
issueFilterStore?.issueView &&
|
||||
issueFilterStore?.issueLayout &&
|
||||
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]?.extra_options?.[
|
||||
issueFilterStore?.issueLayout
|
||||
].access;
|
||||
// const handleExtraOptionsSectionVisibility =
|
||||
// issueFilterStore?.issueView &&
|
||||
// issueFilterStore?.issueLayout &&
|
||||
// issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "issues"]?.extra_options?.[
|
||||
// issueFilterStore?.issueLayout
|
||||
// ].access;
|
||||
|
||||
return (
|
||||
<div className="w-full h-full overflow-hidden select-none relative flex flex-col divide-y divide-custom-border-200">
|
||||
<div className="flex-shrink-0 p-2 text-sm">Search container</div>
|
||||
<div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2 divide-y divide-custom-border-200">
|
||||
{/* display properties */}
|
||||
{handleDisplayPropertiesSectionVisibility && (
|
||||
{/* {handleDisplayPropertiesSectionVisibility && (
|
||||
<div className="pb-2 px-2">
|
||||
<FilterDisplayProperties />
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{/* group by */}
|
||||
{handleDisplayFilterSectionVisibility("group_by") && (
|
||||
{/* {handleDisplayFilterSectionVisibility("group_by") && (
|
||||
<div className="py-1 px-2">
|
||||
<FilterGroupBy />
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{/* order by */}
|
||||
{handleDisplayFilterSectionVisibility("order_by") && (
|
||||
{/* {handleDisplayFilterSectionVisibility("order_by") && (
|
||||
<div className="py-1 px-2">
|
||||
<FilterOrderBy />
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{/* issue type */}
|
||||
{handleDisplayFilterSectionVisibility("issue_type") && (
|
||||
{/* {handleDisplayFilterSectionVisibility("issue_type") && (
|
||||
<div className="py-1 px-2">
|
||||
<FilterIssueType />
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{/* Options */}
|
||||
{handleExtraOptionsSectionVisibility && (
|
||||
{/* {handleExtraOptionsSectionVisibility && (
|
||||
<div className="pt-1 px-2">
|
||||
<FilterExtraOptions />
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,21 +1,21 @@
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// components
|
||||
import { FilterHeader } from "../helpers/filter-header";
|
||||
import { FilterOption } from "../helpers/filter-option";
|
||||
// mobx react lite
|
||||
import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
import { ISSUE_FILTER_OPTIONS } from "constants/issue";
|
||||
|
||||
export const FilterIssueType = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleIssueType = (key: string, value: string) => {
|
||||
issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
// issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -27,17 +27,15 @@ export const FilterIssueType = observer(() => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="space-y-[2px] pt-1">
|
||||
{issueFilterStore?.issueRenderFilters?.issue_type &&
|
||||
issueFilterStore?.issueRenderFilters?.issue_type.length > 0 &&
|
||||
issueFilterStore?.issueRenderFilters?.issue_type.map((_issueType) => (
|
||||
<FilterOption
|
||||
key={_issueType?.key}
|
||||
isChecked={issueFilterStore?.userFilters?.display_filters?.type === _issueType?.key ? true : false}
|
||||
onClick={() => handleIssueType("type", _issueType?.key)}
|
||||
title={_issueType.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
{ISSUE_FILTER_OPTIONS.map((_issueType) => (
|
||||
<FilterOption
|
||||
key={_issueType?.key}
|
||||
isChecked={issueFilterStore?.userDisplayFilters?.type === _issueType?.key ? true : false}
|
||||
onClick={() => handleIssueType("type", _issueType?.key)}
|
||||
title={_issueType.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -7,15 +7,16 @@ import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
import { ISSUE_ORDER_BY_OPTIONS } from "constants/issue";
|
||||
|
||||
export const FilterOrderBy = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleOrderBy = (key: string, value: string) => {
|
||||
issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
// issueFilterStore.handleUserFilter("display_filters", key, value);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -27,17 +28,15 @@ export const FilterOrderBy = observer(() => {
|
||||
/>
|
||||
{previewEnabled && (
|
||||
<div className="space-y-[2px] pt-1">
|
||||
{issueFilterStore?.issueRenderFilters?.order_by &&
|
||||
issueFilterStore?.issueRenderFilters?.order_by.length > 0 &&
|
||||
issueFilterStore?.issueRenderFilters?.order_by.map((_orderBy) => (
|
||||
<FilterOption
|
||||
key={_orderBy?.key}
|
||||
isChecked={issueFilterStore?.userFilters?.display_filters?.order_by === _orderBy?.key ? true : false}
|
||||
onClick={() => handleOrderBy("order_by", _orderBy?.key)}
|
||||
title={_orderBy.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
{ISSUE_ORDER_BY_OPTIONS.map((_orderBy) => (
|
||||
<FilterOption
|
||||
key={_orderBy?.key}
|
||||
isChecked={issueFilterStore?.userDisplayFilters?.order_by === _orderBy?.key ? true : false}
|
||||
onClick={() => handleOrderBy("order_by", _orderBy?.key)}
|
||||
title={_orderBy.title}
|
||||
multiple={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -22,19 +22,19 @@ export const MemberIcons = ({ display_name, avatar }: { display_name: string; av
|
||||
|
||||
export const FilterAssignees = observer(() => {
|
||||
const store: RootStore = useMobxStore();
|
||||
const { issueFilters: issueFilterStore } = store;
|
||||
const { issueFilter: issueFilterStore } = store;
|
||||
|
||||
const [previewEnabled, setPreviewEnabled] = React.useState(true);
|
||||
|
||||
const handleFilter = (key: string, value: string) => {
|
||||
let _value =
|
||||
issueFilterStore?.userFilters?.filters?.[key] != null
|
||||
? issueFilterStore?.userFilters?.filters?.[key].includes(value)
|
||||
? issueFilterStore?.userFilters?.filters?.[key].filter((p: string) => p != value)
|
||||
: [...issueFilterStore?.userFilters?.filters?.[key], value]
|
||||
: [value];
|
||||
_value = _value && _value.length > 0 ? _value : null;
|
||||
issueFilterStore.handleUserFilter("filters", key, _value);
|
||||
// let _value =
|
||||
// issueFilterStore?.userFilters?.filters?.[key] != null
|
||||
// ? issueFilterStore?.userFilters?.filters?.[key].includes(value)
|
||||
// ? issueFilterStore?.userFilters?.filters?.[key].filter((p: string) => p != value)
|
||||
// : [...issueFilterStore?.userFilters?.filters?.[key], value]
|
||||
// : [value];
|
||||
// _value = _value && _value.length > 0 ? _value : null;
|
||||
// issueFilterStore.handleUserFilter("filters", key, _value);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -1,121 +1,182 @@
|
||||
export const GROUP_BY_OPTIONS: Array<{
|
||||
name: string;
|
||||
key: TIssueGroupByOptions;
|
||||
}> = [
|
||||
{ name: "States", key: "state" },
|
||||
{ name: "State Groups", key: "state_detail.group" },
|
||||
{ name: "Priority", key: "priority" },
|
||||
{ name: "Project", key: "project" },
|
||||
{ name: "Labels", key: "labels" },
|
||||
{ name: "Assignees", key: "assignees" },
|
||||
{ name: "Created by", key: "created_by" },
|
||||
{ name: "None", key: null },
|
||||
export const ISSUE_PRIORITIES = [
|
||||
{ key: "urgent", title: "Urgent" },
|
||||
{ key: "high", title: "High" },
|
||||
{ key: "medium", title: "Medium" },
|
||||
{ key: "low", title: "Low" },
|
||||
{ key: "none", title: "None" },
|
||||
];
|
||||
|
||||
export const ORDER_BY_OPTIONS: Array<{
|
||||
name: string;
|
||||
key: TIssueOrderByOptions;
|
||||
}> = [
|
||||
{ name: "Manual", key: "sort_order" },
|
||||
{ name: "Last created", key: "-created_at" },
|
||||
{ name: "Last updated", key: "-updated_at" },
|
||||
{ name: "Start date", key: "start_date" },
|
||||
{ name: "Priority", key: "priority" },
|
||||
export const ISSUE_STATE_GROUPS = [
|
||||
{ key: "backlog", title: "Backlog" },
|
||||
{ key: "unstarted", title: "Unstarted" },
|
||||
{ key: "started", title: "Started" },
|
||||
{ key: "completed", title: "Completed" },
|
||||
{ key: "cancelled", title: "Cancelled" },
|
||||
];
|
||||
|
||||
export const FILTER_ISSUE_OPTIONS: Array<{
|
||||
name: string;
|
||||
key: "active" | "backlog" | null;
|
||||
}> = [
|
||||
{
|
||||
name: "All",
|
||||
key: null,
|
||||
},
|
||||
{
|
||||
name: "Active Issues",
|
||||
key: "active",
|
||||
},
|
||||
{
|
||||
name: "Backlog Issues",
|
||||
key: "backlog",
|
||||
},
|
||||
export const ISSUE_START_DATE_OPTIONS = [
|
||||
{ key: "last_week", title: "Last Week" },
|
||||
{ key: "2_weeks_from_now", title: "2 weeks from now" },
|
||||
{ key: "1_month_from_now", title: "1 month from now" },
|
||||
{ key: "2_months_from_now", title: "2 months from now" },
|
||||
{ key: "custom", title: "Custom" },
|
||||
];
|
||||
|
||||
import { orderArrayBy } from "helpers/array.helper";
|
||||
import { IIssue, TIssueGroupByOptions, TIssueOrderByOptions } from "types";
|
||||
export const ISSUE_DUE_DATE_OPTIONS = [
|
||||
{ key: "last_week", title: "Last Week" },
|
||||
{ key: "2_weeks_from_now", title: "2 weeks from now" },
|
||||
{ key: "1_month_from_now", title: "1 month from now" },
|
||||
{ key: "2_months_from_now", title: "2 months from now" },
|
||||
{ key: "custom", title: "Custom" },
|
||||
];
|
||||
|
||||
type THandleIssuesMutation = (
|
||||
formData: Partial<IIssue>,
|
||||
oldGroupTitle: string,
|
||||
selectedGroupBy: TIssueGroupByOptions,
|
||||
issueIndex: number,
|
||||
orderBy: TIssueOrderByOptions,
|
||||
prevData?:
|
||||
| {
|
||||
[key: string]: IIssue[];
|
||||
}
|
||||
| IIssue[]
|
||||
) =>
|
||||
| {
|
||||
[key: string]: IIssue[];
|
||||
}
|
||||
| IIssue[]
|
||||
| undefined;
|
||||
export const ISSUE_GROUP_BY_OPTIONS = [
|
||||
{ key: "state", title: "States" },
|
||||
{ key: "state_detail.group", title: "State Groups" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "project", title: "Project" }, // required this on my issues
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
];
|
||||
|
||||
export const handleIssuesMutation: THandleIssuesMutation = (
|
||||
formData,
|
||||
oldGroupTitle,
|
||||
selectedGroupBy,
|
||||
issueIndex,
|
||||
orderBy,
|
||||
prevData
|
||||
) => {
|
||||
if (!prevData) return prevData;
|
||||
export const ISSUE_ORDER_BY_OPTIONS = [
|
||||
{ key: "sort_order", title: "Manual" },
|
||||
{ key: "created_at", title: "Last Created" },
|
||||
{ key: "updated_at", title: "Last Updated" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
];
|
||||
|
||||
if (Array.isArray(prevData)) {
|
||||
const updatedIssue = {
|
||||
...prevData[issueIndex],
|
||||
...formData,
|
||||
assignees: formData?.assignees_list ?? prevData[issueIndex]?.assignees,
|
||||
labels: formData?.labels_list ?? prevData[issueIndex]?.labels,
|
||||
};
|
||||
export const ISSUE_FILTER_OPTIONS = [
|
||||
{ key: "all", title: "All" },
|
||||
{ key: "active", title: "Active Issues" },
|
||||
{ key: "backlog", title: "Backlog Issues" },
|
||||
// { key: "draft", title: "Draft Issues" },
|
||||
];
|
||||
|
||||
prevData.splice(issueIndex, 1, updatedIssue);
|
||||
export const ISSUE_DISPLAY_PROPERTIES = [
|
||||
{ key: "assignee", title: "Assignee" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
{ key: "key", title: "ID" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "sub_issue_count", title: "Sub Issue Count" },
|
||||
{ key: "attachment_count", title: "Attachment Count" },
|
||||
{ key: "link", title: "Link" },
|
||||
{ key: "estimate", title: "Estimate" },
|
||||
];
|
||||
|
||||
return [...prevData];
|
||||
} else {
|
||||
const oldGroup = prevData[oldGroupTitle ?? ""] ?? [];
|
||||
export const ISSUE_EXTRA_PROPERTIES = [
|
||||
{ key: "sub_issue", title: "Show sub-issues" }, // in spreadsheet its always false
|
||||
{ key: "show_empty_groups", title: "Show empty states" }, // filter on front-end
|
||||
{ key: "calendar_date_range", title: "Calendar Date Range" }, // calendar date range yyyy-mm-dd;before range yyyy-mm-dd;after
|
||||
{ key: "start_target_date", title: "Start target Date" }, // gantt always be true
|
||||
];
|
||||
|
||||
let newGroup: IIssue[] = [];
|
||||
export const ISSUE_LAYOUTS = [
|
||||
{ key: "list", title: "List View" },
|
||||
{ key: "kanban", title: "Kanban View" },
|
||||
{ key: "calendar", title: "Calendar View" },
|
||||
{ key: "spreadsheet", title: "Spreadsheet View" },
|
||||
{ key: "gantt_chart", title: "Gantt Chart View" },
|
||||
];
|
||||
|
||||
if (selectedGroupBy === "priority") newGroup = prevData[formData.priority ?? ""] ?? [];
|
||||
else if (selectedGroupBy === "state") newGroup = prevData[formData.state ?? ""] ?? [];
|
||||
export const ISSUE_LIST_FILTERS = [
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
];
|
||||
|
||||
const updatedIssue = {
|
||||
...oldGroup[issueIndex],
|
||||
...formData,
|
||||
assignees: formData?.assignees_list ?? oldGroup[issueIndex]?.assignees,
|
||||
labels: formData?.labels_list ?? oldGroup[issueIndex]?.labels,
|
||||
};
|
||||
export const ISSUE_KANBAN_FILTERS = [
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
];
|
||||
|
||||
if (selectedGroupBy !== Object.keys(formData)[0])
|
||||
return {
|
||||
...prevData,
|
||||
[oldGroupTitle ?? ""]: orderArrayBy(
|
||||
oldGroup.map((i) => (i.id === updatedIssue.id ? updatedIssue : i)),
|
||||
orderBy
|
||||
),
|
||||
};
|
||||
export const ISSUE_CALENDER_FILTERS = [
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
];
|
||||
|
||||
const groupThatIsUpdated = selectedGroupBy === "priority" ? formData.priority : formData.state;
|
||||
export const ISSUE_SPREADSHEET_FILTERS = [
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
];
|
||||
|
||||
return {
|
||||
...prevData,
|
||||
[oldGroupTitle ?? ""]: orderArrayBy(
|
||||
oldGroup.filter((i) => i.id !== updatedIssue.id),
|
||||
orderBy
|
||||
),
|
||||
[groupThatIsUpdated ?? ""]: orderArrayBy([...newGroup, updatedIssue], orderBy),
|
||||
};
|
||||
}
|
||||
export const ISSUE_GANTT_FILTERS = [
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
];
|
||||
|
||||
export const ISSUE_LIST_DISPLAY_FILTERS = [
|
||||
{ key: "group_by", title: "Group By" },
|
||||
{ key: "order_by", title: "Order By" },
|
||||
{ key: "issue_type", title: "Issue Type" },
|
||||
{ key: "sub_issue", title: "Sub Issue" },
|
||||
{ key: "show_empty_groups", title: "Show Empty Groups" },
|
||||
];
|
||||
|
||||
export const ISSUE_KANBAN_DISPLAY_FILTERS = [
|
||||
{ key: "group_by", title: "Group By" },
|
||||
{ key: "order_by", title: "Order By" },
|
||||
{ key: "issue_type", title: "Issue Type" },
|
||||
{ key: "sub_issue", title: "Sub Issue" },
|
||||
{ key: "show_empty_groups", title: "Show Empty Groups" },
|
||||
];
|
||||
|
||||
export const ISSUE_CALENDER_DISPLAY_FILTERS = [{ key: "issue_type", title: "Issue Type" }];
|
||||
|
||||
export const ISSUE_SPREADSHEET_DISPLAY_FILTERS = [{ key: "issue_type", title: "Issue Type" }];
|
||||
|
||||
export const ISSUE_GANTT_DISPLAY_FILTERS = [
|
||||
{ key: "order_by", title: "Order By" },
|
||||
{ key: "issue_type", title: "Issue Type" },
|
||||
{ key: "sub_issue", title: "Sub Issue" },
|
||||
];
|
||||
|
||||
export const ISSUE_EXTRA_DISPLAY_PROPERTIES = {
|
||||
list: {
|
||||
access: true,
|
||||
values: ["show_empty_groups", "sub_issue"],
|
||||
},
|
||||
kanban: {
|
||||
access: true,
|
||||
values: ["show_empty_groups", "sub_issue"],
|
||||
},
|
||||
calendar: {
|
||||
access: false,
|
||||
values: [],
|
||||
},
|
||||
spreadsheet: {
|
||||
access: false,
|
||||
values: [],
|
||||
},
|
||||
gantt_chart: {
|
||||
access: true,
|
||||
values: ["sub_issue"],
|
||||
},
|
||||
};
|
||||
|
199
web/helpers/issue.helper.ts
Normal file
199
web/helpers/issue.helper.ts
Normal file
@ -0,0 +1,199 @@
|
||||
import { orderArrayBy } from "helpers/array.helper";
|
||||
import { renderDateFormat } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { IIssue, TIssueGroupByOptions, TIssueOrderByOptions } from "types";
|
||||
|
||||
type THandleIssuesMutation = (
|
||||
formData: Partial<IIssue>,
|
||||
oldGroupTitle: string,
|
||||
selectedGroupBy: TIssueGroupByOptions,
|
||||
issueIndex: number,
|
||||
orderBy: TIssueOrderByOptions,
|
||||
prevData?:
|
||||
| {
|
||||
[key: string]: IIssue[];
|
||||
}
|
||||
| IIssue[]
|
||||
) =>
|
||||
| {
|
||||
[key: string]: IIssue[];
|
||||
}
|
||||
| IIssue[]
|
||||
| undefined;
|
||||
|
||||
export const handleIssuesMutation: THandleIssuesMutation = (
|
||||
formData,
|
||||
oldGroupTitle,
|
||||
selectedGroupBy,
|
||||
issueIndex,
|
||||
orderBy,
|
||||
prevData
|
||||
) => {
|
||||
if (!prevData) return prevData;
|
||||
|
||||
if (Array.isArray(prevData)) {
|
||||
const updatedIssue = {
|
||||
...prevData[issueIndex],
|
||||
...formData,
|
||||
assignees: formData?.assignees_list ?? prevData[issueIndex]?.assignees,
|
||||
labels: formData?.labels_list ?? prevData[issueIndex]?.labels,
|
||||
};
|
||||
|
||||
prevData.splice(issueIndex, 1, updatedIssue);
|
||||
|
||||
return [...prevData];
|
||||
} else {
|
||||
const oldGroup = prevData[oldGroupTitle ?? ""] ?? [];
|
||||
|
||||
let newGroup: IIssue[] = [];
|
||||
|
||||
if (selectedGroupBy === "priority") newGroup = prevData[formData.priority ?? ""] ?? [];
|
||||
else if (selectedGroupBy === "state") newGroup = prevData[formData.state ?? ""] ?? [];
|
||||
|
||||
const updatedIssue = {
|
||||
...oldGroup[issueIndex],
|
||||
...formData,
|
||||
assignees: formData?.assignees_list ?? oldGroup[issueIndex]?.assignees,
|
||||
labels: formData?.labels_list ?? oldGroup[issueIndex]?.labels,
|
||||
};
|
||||
|
||||
if (selectedGroupBy !== Object.keys(formData)[0])
|
||||
return {
|
||||
...prevData,
|
||||
[oldGroupTitle ?? ""]: orderArrayBy(
|
||||
oldGroup.map((i) => (i.id === updatedIssue.id ? updatedIssue : i)),
|
||||
orderBy
|
||||
),
|
||||
};
|
||||
|
||||
const groupThatIsUpdated = selectedGroupBy === "priority" ? formData.priority : formData.state;
|
||||
|
||||
return {
|
||||
...prevData,
|
||||
[oldGroupTitle ?? ""]: orderArrayBy(
|
||||
oldGroup.filter((i) => i.id !== updatedIssue.id),
|
||||
orderBy
|
||||
),
|
||||
[groupThatIsUpdated ?? ""]: orderArrayBy([...newGroup, updatedIssue], orderBy),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export type TIssueLayouts = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt_chart";
|
||||
export type TIssueParams =
|
||||
| "priority"
|
||||
| "state_group"
|
||||
| "state"
|
||||
| "assignees"
|
||||
| "created_by"
|
||||
| "labels"
|
||||
| "start_date"
|
||||
| "target_date"
|
||||
| "group_by"
|
||||
| "order_by"
|
||||
| "type"
|
||||
| "sub_issue"
|
||||
| "show_empty_groups"
|
||||
| "calendar_date_range"
|
||||
| "start_target_date";
|
||||
|
||||
export const handleIssueQueryParamsByLayout = (_layout: TIssueLayouts | undefined): TIssueParams[] | null => {
|
||||
if (_layout === "list")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"group_by",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"show_empty_groups",
|
||||
];
|
||||
if (_layout === "kanban")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"group_by",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"show_empty_groups",
|
||||
];
|
||||
if (_layout === "calendar")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"type",
|
||||
"calendar_date_range",
|
||||
];
|
||||
if (_layout === "spreadsheet")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"type",
|
||||
"sub_issue",
|
||||
];
|
||||
if (_layout === "gantt_chart")
|
||||
return [
|
||||
"priority",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"start_target_date",
|
||||
];
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const handleIssueParamsDateFormat = (key: string, start_date: any | null, target_date: any | null) => {
|
||||
if (key === "last_week")
|
||||
return `${renderDateFormat(new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000))};after,${renderDateFormat(
|
||||
new Date()
|
||||
)};before`;
|
||||
|
||||
if (key === "2_weeks_from_now")
|
||||
return `${renderDateFormat(new Date())};after,
|
||||
${renderDateFormat(new Date(new Date().getTime() + 14 * 24 * 60 * 60 * 1000))};before`;
|
||||
|
||||
if (key === "1_month_from_now")
|
||||
return `${renderDateFormat(new Date())};after,${renderDateFormat(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate())
|
||||
)};before`;
|
||||
|
||||
if (key === "2_months_from_now")
|
||||
return `${renderDateFormat(new Date())};after,${renderDateFormat(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth() + 2, new Date().getDate())
|
||||
)};before`;
|
||||
|
||||
if (key === "custom" && start_date && target_date)
|
||||
return `${renderDateFormat(start_date)};after,${renderDateFormat(target_date)};before`;
|
||||
};
|
@ -34,5 +34,5 @@ export class JiraImporterService extends APIService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default JiraImporterService;
|
||||
const jiraService = new JiraImporterService();
|
||||
export default jiraService;
|
||||
|
@ -1,257 +0,0 @@
|
||||
import { renderDateFormat } from "helpers/date-time.helper";
|
||||
// types
|
||||
import { TIssueLayouts, TIssueParams } from "../issue_filters.legacy";
|
||||
|
||||
export type TStateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled";
|
||||
|
||||
export const priorities: { key: string; title: string }[] = [
|
||||
{ key: "urgent", title: "Urgent" },
|
||||
{ key: "high", title: "High" },
|
||||
{ key: "medium", title: "Medium" },
|
||||
{ key: "low", title: "Low" },
|
||||
{ key: "none", title: "None" },
|
||||
];
|
||||
|
||||
export const stateGroups: { key: TStateGroup; title: string }[] = [
|
||||
{ key: "backlog", title: "Backlog" },
|
||||
{ key: "unstarted", title: "Unstarted" },
|
||||
{ key: "started", title: "Started" },
|
||||
{ key: "completed", title: "Completed" },
|
||||
{ key: "cancelled", title: "Cancelled" },
|
||||
];
|
||||
|
||||
export const startDateOptions: { key: string; title: string }[] = [
|
||||
{ key: "last_week", title: "Last Week" },
|
||||
{ key: "2_weeks_from_now", title: "2 weeks from now" },
|
||||
{ key: "1_month_from_now", title: "1 month from now" },
|
||||
{ key: "2_months_from_now", title: "2 months from now" },
|
||||
{ key: "custom", title: "Custom" },
|
||||
];
|
||||
|
||||
export const dueDateOptions: { key: string; title: string }[] = [
|
||||
{ key: "last_week", title: "Last Week" },
|
||||
{ key: "2_weeks_from_now", title: "2 weeks from now" },
|
||||
{ key: "1_month_from_now", title: "1 month from now" },
|
||||
{ key: "2_months_from_now", title: "2 months from now" },
|
||||
{ key: "custom", title: "Custom" },
|
||||
];
|
||||
|
||||
export const groupByOptions: { key: string; title: string }[] = [
|
||||
{ key: "state", title: "States" },
|
||||
{ key: "state_detail.group", title: "State Groups" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "project", title: "Project" }, // required this on my issues
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "assignees", title: "Assignees" },
|
||||
{ key: "created_by", title: "Created By" },
|
||||
];
|
||||
|
||||
export const orderByOptions: { key: string; title: string }[] = [
|
||||
{ key: "sort_order", title: "Manual" },
|
||||
{ key: "created_at", title: "Last Created" },
|
||||
{ key: "updated_at", title: "Last Updated" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
];
|
||||
|
||||
export const issueTypes: { key: string; title: string }[] = [
|
||||
{ key: "all", title: "All" },
|
||||
{ key: "active", title: "Active Issues" },
|
||||
{ key: "backlog", title: "Backlog Issues" },
|
||||
];
|
||||
|
||||
export const displayProperties: { key: string; title: string }[] = [
|
||||
{ key: "assignee", title: "Assignee" },
|
||||
{ key: "start_date", title: "Start Date" },
|
||||
{ key: "due_date", title: "Due Date" },
|
||||
{ key: "key", title: "ID" },
|
||||
{ key: "labels", title: "Labels" },
|
||||
{ key: "priority", title: "Priority" },
|
||||
{ key: "state", title: "State" },
|
||||
{ key: "sub_issue_count", title: "Sub Issue Count" },
|
||||
{ key: "attachment_count", title: "Attachment Count" },
|
||||
{ key: "link", title: "Link" },
|
||||
{ key: "estimate", title: "Estimate" },
|
||||
];
|
||||
|
||||
export const extraProperties: { key: string; title: string }[] = [
|
||||
{ key: "sub_issue", title: "Show sub-issues" }, // in spreadsheet its always false
|
||||
{ key: "show_empty_groups", title: "Show empty states" }, // filter on front-end
|
||||
{ key: "calendar_date_range", title: "Calendar Date Range" }, // calendar date range yyyy-mm-dd;before range yyyy-mm-dd;after
|
||||
{ key: "start_target_date", title: "Start target Date" }, // gantt always be true
|
||||
];
|
||||
|
||||
export const issueFilterVisibilityData: any = {
|
||||
my_issues: {
|
||||
layout: ["list", "kanban"],
|
||||
filters: {
|
||||
list: ["priority", "state_group", "labels", "start_date", "due_date"],
|
||||
kanban: ["priority", "state_group", "labels", "start_date", "due_date"],
|
||||
},
|
||||
display_properties: {
|
||||
list: true,
|
||||
kanban: true,
|
||||
},
|
||||
display_filters: {
|
||||
list: ["group_by", "order_by", "issue_type"],
|
||||
kanban: ["group_by", "order_by", "issue_type"],
|
||||
},
|
||||
extra_options: {
|
||||
list: {
|
||||
access: true,
|
||||
values: ["show_empty_groups"],
|
||||
},
|
||||
kanban: {
|
||||
access: true,
|
||||
values: ["show_empty_groups"],
|
||||
},
|
||||
},
|
||||
},
|
||||
issues: {
|
||||
layout: ["list", "kanban", "calendar", "spreadsheet", "gantt_chart"],
|
||||
filters: {
|
||||
list: ["priority", "state", "assignees", "created_by", "labels", "start_date", "due_date"],
|
||||
kanban: ["priority", "state", "assignees", "created_by", "labels", "start_date", "due_date"],
|
||||
calendar: ["priority", "state", "assignees", "created_by", "labels"],
|
||||
spreadsheet: ["priority", "state", "assignees", "created_by", "labels", "start_date", "due_date"],
|
||||
gantt_chart: ["priority", "state", "assignees", "created_by", "labels", "start_date", "due_date"],
|
||||
},
|
||||
display_properties: {
|
||||
list: true,
|
||||
kanban: true,
|
||||
calendar: true,
|
||||
spreadsheet: true,
|
||||
gantt_chart: false,
|
||||
},
|
||||
display_filters: {
|
||||
list: ["group_by", "order_by", "issue_type", "sub_issue", "show_empty_groups"],
|
||||
kanban: ["group_by", "order_by", "issue_type", "sub_issue", "show_empty_groups"],
|
||||
calendar: ["issue_type"],
|
||||
spreadsheet: ["issue_type"],
|
||||
gantt_chart: ["order_by", "issue_type", "sub_issue"],
|
||||
},
|
||||
extra_options: {
|
||||
list: {
|
||||
access: true,
|
||||
values: ["show_empty_groups", "sub_issue"],
|
||||
},
|
||||
kanban: {
|
||||
access: true,
|
||||
values: ["show_empty_groups", "sub_issue"],
|
||||
},
|
||||
calendar: {
|
||||
access: false,
|
||||
values: [],
|
||||
},
|
||||
spreadsheet: {
|
||||
access: false,
|
||||
values: [],
|
||||
},
|
||||
gantt_chart: {
|
||||
access: true,
|
||||
values: ["sub_issue"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const handleIssueQueryParamsByLayout = (_layout: TIssueLayouts | undefined): TIssueParams[] | null => {
|
||||
if (_layout === "list")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"group_by",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"show_empty_groups",
|
||||
];
|
||||
if (_layout === "kanban")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"group_by",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"show_empty_groups",
|
||||
];
|
||||
if (_layout === "calendar")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"type",
|
||||
"calendar_date_range",
|
||||
];
|
||||
if (_layout === "spreadsheet")
|
||||
return [
|
||||
"priority",
|
||||
"state_group",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"type",
|
||||
"sub_issue",
|
||||
];
|
||||
if (_layout === "gantt_chart")
|
||||
return [
|
||||
"priority",
|
||||
"state",
|
||||
"assignees",
|
||||
"created_by",
|
||||
"labels",
|
||||
"start_date",
|
||||
"target_date",
|
||||
"order_by",
|
||||
"type",
|
||||
"sub_issue",
|
||||
"start_target_date",
|
||||
];
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const handleIssueParamsDateFormat = (key: string, start_date: any | null, target_date: any | null) => {
|
||||
if (key === "last_week")
|
||||
return `${renderDateFormat(new Date(new Date().getTime() - 7 * 24 * 60 * 60 * 1000))};after,${renderDateFormat(
|
||||
new Date()
|
||||
)};before`;
|
||||
|
||||
if (key === "2_weeks_from_now")
|
||||
return `${renderDateFormat(new Date())};after,
|
||||
${renderDateFormat(new Date(new Date().getTime() + 14 * 24 * 60 * 60 * 1000))};before`;
|
||||
|
||||
if (key === "1_month_from_now")
|
||||
return `${renderDateFormat(new Date())};after,${renderDateFormat(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate())
|
||||
)};before`;
|
||||
|
||||
if (key === "2_months_from_now")
|
||||
return `${renderDateFormat(new Date())};after,${renderDateFormat(
|
||||
new Date(new Date().getFullYear(), new Date().getMonth() + 2, new Date().getDate())
|
||||
)};before`;
|
||||
|
||||
if (key === "custom" && start_date && target_date)
|
||||
return `${renderDateFormat(start_date)};after,${renderDateFormat(target_date)};before`;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||
import { IIssue } from "types";
|
||||
import { RootStore } from "./root";
|
||||
|
||||
export interface IIssueStore {
|
||||
loader: boolean;
|
||||
@ -16,13 +17,16 @@ class IssueStore implements IIssueStore {
|
||||
};
|
||||
} = {};
|
||||
|
||||
constructor() {
|
||||
rootStore;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
loader: observable.ref,
|
||||
error: observable.ref,
|
||||
issues: observable.ref,
|
||||
});
|
||||
this.rootStore = _rootStore;
|
||||
}
|
||||
|
||||
fetchIssuesWithParams() {}
|
||||
|
@ -1,847 +0,0 @@
|
||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||
// types
|
||||
import { RootStore } from "./root";
|
||||
// services
|
||||
import { WorkspaceService } from "services/workspace.service";
|
||||
import { ProjectIssuesServices } from "services/issue.service";
|
||||
import { ProjectStateServices } from "services/project_state.service";
|
||||
import { ProjectServices } from "services/project.service";
|
||||
import { ProjectIssuesServices as ProjectModuleServices } from "services/modules.service";
|
||||
import { ProjectCycleServices } from "services/cycles.service";
|
||||
import { ViewService } from "services/views.service";
|
||||
// default data
|
||||
import {
|
||||
priorities,
|
||||
stateGroups,
|
||||
startDateOptions,
|
||||
dueDateOptions,
|
||||
groupByOptions,
|
||||
orderByOptions,
|
||||
issueTypes,
|
||||
displayProperties,
|
||||
extraProperties,
|
||||
handleIssueQueryParamsByLayout,
|
||||
} from "./helpers/issue-data";
|
||||
|
||||
export type TIssueViews = "issues" | "modules" | "views" | "cycles";
|
||||
export type TIssueLayouts = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt_chart";
|
||||
export type TIssueParams =
|
||||
| "priority"
|
||||
| "state_group"
|
||||
| "state"
|
||||
| "assignees"
|
||||
| "created_by"
|
||||
| "labels"
|
||||
| "start_date"
|
||||
| "target_date"
|
||||
| "group_by"
|
||||
| "order_by"
|
||||
| "type"
|
||||
| "sub_issue"
|
||||
| "show_empty_groups"
|
||||
| "calendar_date_range"
|
||||
| "start_target_date";
|
||||
|
||||
export interface IIssueFilter {
|
||||
priority: string[] | undefined;
|
||||
state_group: string[] | undefined;
|
||||
state: string[] | undefined;
|
||||
assignees: string[] | undefined;
|
||||
created_by: string[] | undefined;
|
||||
labels: string[] | undefined;
|
||||
start_date: string[] | undefined;
|
||||
target_date: string[] | undefined;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface IIssueDisplayFilters {
|
||||
group_by: undefined | string;
|
||||
order_by: undefined | string;
|
||||
type: string | undefined;
|
||||
sub_issue: boolean;
|
||||
show_empty_groups: boolean;
|
||||
layout: TIssueLayouts;
|
||||
calendar_date_range: string | undefined; // only for calendar
|
||||
start_target_date: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface IIssueDisplayProperties {
|
||||
assignee: boolean;
|
||||
attachment_count: boolean;
|
||||
created_on: boolean;
|
||||
due_date: boolean;
|
||||
estimate: boolean;
|
||||
key: boolean;
|
||||
labels: boolean;
|
||||
link: boolean;
|
||||
priority: boolean;
|
||||
start_date: boolean;
|
||||
state: boolean;
|
||||
sub_issue_count: boolean;
|
||||
updated_on: boolean;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface IIssueFilters {
|
||||
// project_id
|
||||
[key: string]: {
|
||||
issues: {
|
||||
// project_id
|
||||
[key: string]: {
|
||||
filters: IIssueFilter;
|
||||
};
|
||||
};
|
||||
cycles: {
|
||||
// cycle_id
|
||||
[key: string]: {
|
||||
filters: IIssueFilter;
|
||||
};
|
||||
};
|
||||
modules: {
|
||||
// module_id
|
||||
[key: string]: {
|
||||
filters: IIssueFilter;
|
||||
};
|
||||
};
|
||||
views: {
|
||||
// view_id
|
||||
[key: string]: {
|
||||
filters: IIssueFilter;
|
||||
};
|
||||
};
|
||||
display_filters: IIssueDisplayFilters;
|
||||
display_properties_id: string;
|
||||
display_properties: IIssueDisplayProperties;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IIssueFilterStore {
|
||||
// static data
|
||||
priorities: { key: string; title: string }[];
|
||||
stateGroups: { key: string; title: string }[];
|
||||
startDateOptions: { key: string; title: string }[];
|
||||
dueDateOptions: { key: string; title: string }[];
|
||||
groupByOptions: { key: string; title: string }[];
|
||||
orderByOptions: { key: string; title: string }[];
|
||||
issueTypes: { key: string; title: string }[];
|
||||
displayProperties: { key: string; title: string }[];
|
||||
extraProperties: { key: string; title: string }[];
|
||||
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
|
||||
// current workspace and project id
|
||||
issueView: TIssueViews | null;
|
||||
issueFilters: IIssueFilters;
|
||||
|
||||
// actions
|
||||
// getWorkspaceMyIssuesFilters: (workspaceId: string) => Promise<any>;
|
||||
// updateWorkspaceMyIssuesFilters: (workspaceId: string, data: any) => Promise<any>;
|
||||
|
||||
getProjectDisplayProperties: (workspaceId: string, projectId: string) => Promise<any>;
|
||||
updateProjectDisplayProperties: (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
display_properties_id: string,
|
||||
data: any
|
||||
) => Promise<any>;
|
||||
getProjectDisplayFilters: (workspaceId: string, projectId: string) => Promise<any>;
|
||||
updateProjectDisplayFilters: (workspaceId: string, projectId: string, data: any) => Promise<any>;
|
||||
|
||||
getProjectIssueFilters: (workspaceId: string, projectId: string) => Promise<any>;
|
||||
|
||||
getProjectIssueModuleFilters: (workspaceId: string, projectId: string, moduleId: string) => Promise<any>;
|
||||
updateProjectIssueModuleFilters: (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
data: any
|
||||
) => Promise<any>;
|
||||
getProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string) => Promise<any>;
|
||||
updateProjectIssueCyclesFilters: (workspaceId: string, projectId: string, cycleId: string, data: any) => Promise<any>;
|
||||
getProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string) => Promise<any>;
|
||||
updateProjectIssueViewsFilters: (workspaceId: string, projectId: string, viewId: string, data: any) => Promise<any>;
|
||||
}
|
||||
|
||||
class IssueFilterStore implements IIssueFilterStore {
|
||||
// static data
|
||||
priorities: { key: string; title: string }[] = priorities;
|
||||
stateGroups: { key: string; title: string }[] = stateGroups;
|
||||
startDateOptions: { key: string; title: string }[] = startDateOptions;
|
||||
dueDateOptions: { key: string; title: string }[] = dueDateOptions;
|
||||
groupByOptions: { key: string; title: string }[] = groupByOptions;
|
||||
orderByOptions: { key: string; title: string }[] = orderByOptions;
|
||||
issueTypes: { key: string; title: string }[] = issueTypes;
|
||||
displayProperties: { key: string; title: string }[] = displayProperties;
|
||||
extraProperties: { key: string; title: string }[] = extraProperties;
|
||||
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
|
||||
// workspaceId: string | null = null;
|
||||
// projectId: string | null = null;
|
||||
// moduleId: string | null = null;
|
||||
// cycleId: string | null = null;
|
||||
// viewId: string | null = null;
|
||||
|
||||
issueView: TIssueViews | null = null;
|
||||
|
||||
issueFilters: IIssueFilters = {};
|
||||
|
||||
// root store
|
||||
rootStore;
|
||||
// service
|
||||
workspaceService;
|
||||
issueService;
|
||||
stateService;
|
||||
projectService;
|
||||
moduleService;
|
||||
cycleService;
|
||||
viewService;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
loader: observable,
|
||||
error: observable,
|
||||
|
||||
issueView: observable,
|
||||
|
||||
issueFilters: observable.ref,
|
||||
|
||||
// computed
|
||||
issueLayout: computed,
|
||||
userFilters: computed,
|
||||
|
||||
// actions
|
||||
getComputedFilters: action,
|
||||
|
||||
handleIssueFilter: action,
|
||||
|
||||
// getWorkspaceMyIssuesFilters: action,
|
||||
// updateWorkspaceMyIssuesFilters: action,
|
||||
|
||||
getProjectDisplayFilters: action,
|
||||
updateProjectDisplayFilters: action,
|
||||
|
||||
getProjectDisplayProperties: action,
|
||||
updateProjectDisplayProperties: action,
|
||||
|
||||
getProjectIssueFilters: action,
|
||||
|
||||
getProjectIssueModuleFilters: action,
|
||||
updateProjectIssueModuleFilters: action,
|
||||
|
||||
getProjectIssueCyclesFilters: action,
|
||||
updateProjectIssueCyclesFilters: action,
|
||||
|
||||
getProjectIssueViewsFilters: action,
|
||||
updateProjectIssueViewsFilters: action,
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
this.workspaceService = new WorkspaceService();
|
||||
this.issueService = new ProjectIssuesServices();
|
||||
this.stateService = new ProjectStateServices();
|
||||
this.projectService = new ProjectServices();
|
||||
this.moduleService = new ProjectModuleServices();
|
||||
this.cycleService = new ProjectCycleServices();
|
||||
this.viewService = new ViewService();
|
||||
}
|
||||
|
||||
// computed
|
||||
get issueLayout() {
|
||||
// if (!this.projectId) return null;
|
||||
// if (!this.projectId)
|
||||
// return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout || null;
|
||||
// if (this.projectId)
|
||||
// return (
|
||||
// this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues?.display_filters
|
||||
// ?.layout || null
|
||||
// );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
get userFilters() {
|
||||
const projectId = this.rootStore?.project?.projectId;
|
||||
const moduleId = this.rootStore?.module?.moduleId;
|
||||
const cycleId = this.rootStore?.cycle?.cycleId;
|
||||
const viewId = this.rootStore?.view?.viewId;
|
||||
const _issueView = this.issueView;
|
||||
|
||||
if (!projectId || !_issueView) return null;
|
||||
const currentIssueViewId: string | null =
|
||||
_issueView === "issues" && projectId
|
||||
? projectId
|
||||
: _issueView === "modules" && moduleId
|
||||
? moduleId
|
||||
: _issueView === "cycles" && cycleId
|
||||
? cycleId
|
||||
: _issueView === "cycles" && viewId
|
||||
? viewId
|
||||
: null;
|
||||
|
||||
if (!currentIssueViewId) return null;
|
||||
const _issueFilters: {
|
||||
filters: IIssueFilter | null;
|
||||
display_filters: IIssueDisplayFilters;
|
||||
display_properties_id: string;
|
||||
display_properties: IIssueDisplayProperties;
|
||||
} = {
|
||||
filters: this.issueFilters?.[projectId]?.[_issueView]?.[currentIssueViewId]?.filters,
|
||||
display_filters: this.issueFilters?.[projectId]?.display_filters,
|
||||
display_properties_id: this.issueFilters?.[projectId]?.display_properties_id,
|
||||
display_properties: this.issueFilters?.[projectId]?.display_properties,
|
||||
};
|
||||
return _issueFilters;
|
||||
}
|
||||
|
||||
computedFilter = (filters: any, filteredParams: any) => {
|
||||
const computedFilters: any = {};
|
||||
Object.keys(filters).map((key) => {
|
||||
if (filters[key] != undefined && filteredParams.includes(key))
|
||||
computedFilters[key] =
|
||||
typeof filters[key] === "string" || typeof filters[key] === "boolean" ? filters[key] : filters[key].join(",");
|
||||
});
|
||||
|
||||
return computedFilters;
|
||||
};
|
||||
getComputedFilters = (
|
||||
_workspaceId: string | null,
|
||||
_projectId: string | null,
|
||||
_moduleId: string | null,
|
||||
_cycleId: string | null,
|
||||
_viewId: string | null,
|
||||
_issueView: TIssueViews
|
||||
) => {
|
||||
this.issueView = _issueView;
|
||||
|
||||
const _layout = this.userFilters?.display_filters?.layout;
|
||||
|
||||
let filteredRouteParams: any = {
|
||||
priority: this.userFilters?.filters?.priority || undefined,
|
||||
state_group: this.userFilters?.filters?.state_group || undefined,
|
||||
state: this.userFilters?.filters?.state || undefined,
|
||||
assignees: this.userFilters?.filters?.assignees || undefined,
|
||||
created_by: this.userFilters?.filters?.created_by || undefined,
|
||||
labels: this.userFilters?.filters?.labels || undefined,
|
||||
start_date: this.userFilters?.filters?.start_date || undefined,
|
||||
target_date: this.userFilters?.filters?.target_date || undefined,
|
||||
group_by: this.userFilters?.display_filters?.group_by || "state",
|
||||
order_by: this.userFilters?.display_filters?.order_by || "-created_at",
|
||||
type: this.userFilters?.display_filters?.type || undefined,
|
||||
sub_issue: this.userFilters?.display_filters?.sub_issue || true,
|
||||
show_empty_groups: this.userFilters?.display_filters?.show_empty_groups || true,
|
||||
calendar_date_range: this.userFilters?.display_filters?.calendar_date_range || undefined,
|
||||
start_target_date: this.userFilters?.display_filters?.start_target_date || true,
|
||||
};
|
||||
|
||||
// start date and target date we have to construct the format here
|
||||
// in calendar view calendar_date_range send as target_date
|
||||
// in spreadsheet sub issue is false for sure
|
||||
// in gantt start_target_date is true for sure
|
||||
|
||||
const filteredParams: TIssueParams[] | null = handleIssueQueryParamsByLayout(_layout);
|
||||
if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
|
||||
|
||||
return filteredRouteParams;
|
||||
};
|
||||
|
||||
handleIssueFilter = (
|
||||
filter_type: "filters" | "display_filters" | "display_properties" | "display_properties_id",
|
||||
value: any
|
||||
) => {
|
||||
const projectId = this.rootStore?.project?.projectId;
|
||||
const moduleId = this.rootStore?.module?.moduleId;
|
||||
const cycleId = this.rootStore?.cycle?.cycleId;
|
||||
const viewId = this.rootStore?.view?.viewId;
|
||||
const _issueView = this.issueView;
|
||||
|
||||
console.log("filter_type", filter_type);
|
||||
console.log("value", value);
|
||||
|
||||
if (!_issueView || !projectId || !moduleId || !cycleId || !viewId) return null;
|
||||
|
||||
// let _issueFilters: IIssueFilters = {
|
||||
// ...this.issueFilters,
|
||||
// [workspaceId]: {
|
||||
// ...this.issueFilters?.[workspaceId],
|
||||
// },
|
||||
// };
|
||||
|
||||
// console.log("_issueFilters", _issueFilters);
|
||||
|
||||
// if (this.issueView === "my_issues")
|
||||
// this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false);
|
||||
// if (this.issueView === "issues")
|
||||
// this.rootStore?.issueView?.getProjectIssuesAsync(this.workspaceId, this.projectId, false);
|
||||
// if (this.issueView === "modules" && this.moduleId)
|
||||
// this.rootStore?.issueView?.getIssuesForModulesAsync(this.workspaceId, this.projectId, this.moduleId, false);
|
||||
// if (this.issueView === "cycles" && this.cycleId)
|
||||
// this.rootStore?.issueView?.getIssuesForCyclesAsync(this.workspaceId, this.projectId, this.cycleId, false);
|
||||
// if (this.issueView === "views" && this.viewId)
|
||||
// this.rootStore?.issueView?.getIssuesForViewsAsync(this.workspaceId, this.projectId, this.viewId, false);
|
||||
};
|
||||
|
||||
// services
|
||||
// getWorkspaceMyIssuesFilters = async (workspaceId: string) => {
|
||||
// try {
|
||||
// this.loader = true;
|
||||
// this.error = null;
|
||||
|
||||
// const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId);
|
||||
// if (issuesFiltersResponse) {
|
||||
// const _issuesFiltersResponse: any = {
|
||||
// ...this.issueFilters,
|
||||
// [workspaceId]: {
|
||||
// ...this?.issueFilters?.[workspaceId],
|
||||
// my_issue_properties: {
|
||||
// ...this?.issueFilters?.[workspaceId]?.my_issue_properties,
|
||||
// filters: {
|
||||
// priority: issuesFiltersResponse?.view_props?.filters?.priority ?? null,
|
||||
// state: issuesFiltersResponse?.view_props?.filters?.state ?? null,
|
||||
// state_group: issuesFiltersResponse?.view_props?.filters?.state_group ?? null,
|
||||
// assignees: issuesFiltersResponse?.view_props?.filters?.assignees ?? null,
|
||||
// created_by: issuesFiltersResponse?.view_props?.filters?.created_by ?? null,
|
||||
// labels: issuesFiltersResponse?.view_props?.filters?.labels ?? null,
|
||||
// start_date: issuesFiltersResponse?.view_props?.filters?.start_date ?? null,
|
||||
// target_date: issuesFiltersResponse?.view_props?.filters?.target_date ?? null,
|
||||
// subscriber: issuesFiltersResponse?.view_props?.filters?.subscriber ?? null,
|
||||
// },
|
||||
// display_filters: {
|
||||
// group_by: issuesFiltersResponse?.view_props?.display_filters?.group_by ?? null,
|
||||
// order_by: issuesFiltersResponse?.view_props?.display_filters?.order_by ?? null,
|
||||
// type: issuesFiltersResponse?.view_props?.display_filters?.type ?? null,
|
||||
// sub_issue: issuesFiltersResponse?.view_props?.display_filters?.sub_issue ?? false,
|
||||
// show_empty_groups: issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false,
|
||||
// layout: issuesFiltersResponse?.view_props?.display_filters?.layout ?? "list",
|
||||
// calendar_date_range: issuesFiltersResponse?.view_props?.display_filters?.calendar_date_range ?? false,
|
||||
// start_target_date: issuesFiltersResponse?.view_props?.display_filters?.start_target_date ?? true,
|
||||
// },
|
||||
// display_properties: {
|
||||
// assignee: issuesFiltersResponse?.view_props?.display_properties?.assignee ?? false,
|
||||
// attachment_count: issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false,
|
||||
// created_on: issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false,
|
||||
// due_date: issuesFiltersResponse?.view_props?.display_properties?.due_date ?? false,
|
||||
// estimate: issuesFiltersResponse?.view_props?.display_properties?.estimate ?? false,
|
||||
// key: issuesFiltersResponse?.view_props?.display_properties?.key ?? false,
|
||||
// labels: issuesFiltersResponse?.view_props?.display_properties?.labels ?? false,
|
||||
// link: issuesFiltersResponse?.view_props?.display_properties?.link ?? false,
|
||||
// priority: issuesFiltersResponse?.view_props?.display_properties?.priority ?? false,
|
||||
// start_date: issuesFiltersResponse?.view_props?.display_properties?.start_date ?? false,
|
||||
// state: issuesFiltersResponse?.view_props?.display_properties?.state ?? false,
|
||||
// sub_issue_count: issuesFiltersResponse?.view_props?.display_properties?.sub_issue_count ?? false,
|
||||
// updated_on: issuesFiltersResponse?.view_props?.display_properties?.updated_on ?? false,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
// runInAction(() => {
|
||||
// this.issueFilters = _issuesFiltersResponse;
|
||||
// this.loader = false;
|
||||
// this.error = null;
|
||||
// });
|
||||
// }
|
||||
// return issuesFiltersResponse;
|
||||
// } catch (error) {
|
||||
// console.warn("error in fetching workspace level filters", error);
|
||||
// this.loader = false;
|
||||
// this.error = null;
|
||||
//
|
||||
// }
|
||||
// };
|
||||
// updateWorkspaceMyIssuesFilters = async (workspaceId: string, data: any) => {
|
||||
// try {
|
||||
// this.loader = true;
|
||||
// this.error = null;
|
||||
|
||||
// const payload = {
|
||||
// view_props: data,
|
||||
// };
|
||||
// const issuesFiltersResponse = await this.workspaceService.updateWorkspaceView(workspaceId, payload);
|
||||
|
||||
// if (issuesFiltersResponse) {
|
||||
// runInAction(() => {
|
||||
// this.loader = false;
|
||||
// this.error = null;
|
||||
// });
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.warn("error in fetching workspace level issue filters", error);
|
||||
// this.loader = false;
|
||||
// this.error = null;
|
||||
//
|
||||
// }
|
||||
// };
|
||||
|
||||
getProjectDisplayProperties = async (workspaceId: string, projectId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
await this.rootStore.user.setCurrentUser();
|
||||
const issuesDisplayPropertiesResponse = await this.issueService.getIssueProperties(workspaceId, projectId);
|
||||
|
||||
if (issuesDisplayPropertiesResponse) {
|
||||
const _issuesDisplayPropertiesResponse: any = {
|
||||
...this.issueFilters,
|
||||
[projectId]: {
|
||||
...this?.issueFilters?.[projectId],
|
||||
display_properties_id: issuesDisplayPropertiesResponse?.id,
|
||||
display_properties: {
|
||||
...issuesDisplayPropertiesResponse?.properties,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issueFilters = _issuesDisplayPropertiesResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesDisplayPropertiesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching project level display properties", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
updateProjectDisplayProperties = async (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
display_properties_id: string,
|
||||
data: any
|
||||
) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const payload = {
|
||||
properties: data,
|
||||
user: this.rootStore?.user?.currentUser?.id,
|
||||
};
|
||||
const issuesDisplayPropertiesResponse = await this.issueService.patchIssueProperties(
|
||||
workspaceId,
|
||||
projectId,
|
||||
display_properties_id,
|
||||
payload
|
||||
);
|
||||
|
||||
if (issuesDisplayPropertiesResponse) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesDisplayPropertiesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching project level display properties", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
|
||||
getProjectDisplayFilters = async (workspaceId: string, projectId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(workspaceId, projectId);
|
||||
|
||||
if (issuesDisplayFiltersResponse) {
|
||||
const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters };
|
||||
const _displayFilters = { ...issuesDisplayFiltersResponse?.view_props?.display_filters };
|
||||
|
||||
const _issuesDisplayFiltersResponse: any = {
|
||||
...this.issueFilters,
|
||||
[projectId]: {
|
||||
...this?.issueFilters?.[projectId],
|
||||
issues: {
|
||||
...this?.issueFilters?.[projectId]?.issues,
|
||||
filters: _filters,
|
||||
},
|
||||
display_filters: _displayFilters,
|
||||
},
|
||||
};
|
||||
|
||||
console.log("_issuesDisplayFiltersResponse", _issuesDisplayFiltersResponse);
|
||||
|
||||
runInAction(() => {
|
||||
this.issueFilters = _issuesDisplayFiltersResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesDisplayFiltersResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
updateProjectDisplayFilters = async (workspaceId: string, projectId: string, data: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const payload: any = {
|
||||
view_props: data,
|
||||
};
|
||||
const issuesFiltersResponse = await this.projectService.setProjectView(workspaceId, projectId, payload);
|
||||
|
||||
if (issuesFiltersResponse) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesFiltersResponse;
|
||||
} catch (error) {
|
||||
this.getProjectDisplayFilters(workspaceId, projectId);
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
|
||||
getProjectIssueFilters = async (workspaceId: string, projectId: string) => {
|
||||
try {
|
||||
await this.getProjectDisplayProperties(workspaceId, projectId);
|
||||
await this.getProjectDisplayFilters(workspaceId, projectId);
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
}
|
||||
};
|
||||
|
||||
getProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
await this.getProjectIssueFilters(workspaceId, projectId);
|
||||
const issuesFiltersModuleResponse = await this.moduleService.getModuleDetails(workspaceId, projectId, moduleId);
|
||||
if (issuesFiltersModuleResponse) {
|
||||
const _filters = { ...issuesFiltersModuleResponse?.view_props?.filters };
|
||||
const _issuesFiltersModuleResponse = {
|
||||
...this.issueFilters,
|
||||
[projectId]: {
|
||||
...this?.issueFilters?.[projectId],
|
||||
modules: {
|
||||
...this?.issueFilters?.[projectId]?.modules,
|
||||
[moduleId]: {
|
||||
...this?.issueFilters?.[projectId]?.modules?.[moduleId],
|
||||
filters: {
|
||||
priority: _filters?.priority ?? undefined,
|
||||
state: _filters?.state ?? undefined,
|
||||
state_group: _filters?.state_group ?? undefined,
|
||||
assignees: _filters?.assignees ?? undefined,
|
||||
created_by: _filters?.created_by ?? undefined,
|
||||
labels: _filters?.labels ?? undefined,
|
||||
start_date: _filters?.start_date ?? undefined,
|
||||
target_date: _filters?.target_date ?? undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issueFilters = _issuesFiltersModuleResponse as any;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
updateProjectIssueModuleFilters = async (workspaceId: string, projectId: string, moduleId: string, data: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const payload = {
|
||||
view_props: { filters: data },
|
||||
};
|
||||
const issuesFiltersModuleResponse = await this.moduleService.patchModule(
|
||||
workspaceId,
|
||||
projectId,
|
||||
moduleId,
|
||||
payload,
|
||||
undefined // TODO: replace this with user
|
||||
);
|
||||
|
||||
if (issuesFiltersModuleResponse) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.getProjectIssueModuleFilters(workspaceId, projectId, moduleId);
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
|
||||
getProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
await this.getProjectIssueFilters(workspaceId, projectId);
|
||||
const issuesFiltersCycleResponse = await this.cycleService.getCycleDetails(workspaceId, projectId, cycleId);
|
||||
if (issuesFiltersCycleResponse) {
|
||||
const _filters = { ...issuesFiltersCycleResponse?.view_props?.filters };
|
||||
const _issuesFiltersCycleResponse = {
|
||||
...this.issueFilters,
|
||||
[projectId]: {
|
||||
...this?.issueFilters?.[projectId],
|
||||
cycles: {
|
||||
...this?.issueFilters?.[projectId]?.cycles,
|
||||
[cycleId]: {
|
||||
...this?.issueFilters?.[projectId]?.modules?.[cycleId],
|
||||
filters: {
|
||||
priority: _filters?.priority ?? undefined,
|
||||
state: _filters?.state ?? undefined,
|
||||
state_group: _filters?.state_group ?? undefined,
|
||||
assignees: _filters?.assignees ?? undefined,
|
||||
created_by: _filters?.created_by ?? undefined,
|
||||
labels: _filters?.labels ?? undefined,
|
||||
start_date: _filters?.start_date ?? undefined,
|
||||
target_date: _filters?.target_date ?? undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issueFilters = _issuesFiltersCycleResponse as any;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
updateProjectIssueCyclesFilters = async (workspaceId: string, projectId: string, cycleId: string, data: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const payload = {
|
||||
view_props: { filters: data },
|
||||
};
|
||||
const issuesFiltersCycleResponse = await this.cycleService.patchCycle(
|
||||
workspaceId,
|
||||
projectId,
|
||||
cycleId,
|
||||
payload,
|
||||
undefined // TODO: replace this with user
|
||||
);
|
||||
|
||||
if (issuesFiltersCycleResponse) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId);
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
|
||||
getProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
await this.getProjectIssueFilters(workspaceId, projectId);
|
||||
const issuesFiltersViewResponse = await this.viewService.getViewDetails(workspaceId, projectId, viewId);
|
||||
if (issuesFiltersViewResponse) {
|
||||
const _filters = { ...issuesFiltersViewResponse?.query_data } as any;
|
||||
const _issuesFiltersViewResponse = {
|
||||
...this.issueFilters,
|
||||
[projectId]: {
|
||||
...this?.issueFilters?.[projectId],
|
||||
views: {
|
||||
...this?.issueFilters?.[projectId]?.views,
|
||||
[viewId]: {
|
||||
...this?.issueFilters?.[projectId]?.modules?.[viewId],
|
||||
filters: {
|
||||
priority: _filters?.priority ?? undefined,
|
||||
state: _filters?.state ?? undefined,
|
||||
state_group: _filters?.state_group ?? undefined,
|
||||
assignees: _filters?.assignees ?? undefined,
|
||||
created_by: _filters?.created_by ?? undefined,
|
||||
labels: _filters?.labels ?? undefined,
|
||||
start_date: _filters?.start_date ?? undefined,
|
||||
target_date: _filters?.target_date ?? undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issueFilters = _issuesFiltersViewResponse as any;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
updateProjectIssueViewsFilters = async (workspaceId: string, projectId: string, viewId: string, data: any) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
const payload = {
|
||||
query_data: data,
|
||||
};
|
||||
const issuesFiltersViewResponse = await this.viewService.patchView(
|
||||
workspaceId,
|
||||
projectId,
|
||||
viewId,
|
||||
payload,
|
||||
undefined // TODO: replace this with user
|
||||
);
|
||||
|
||||
if (issuesFiltersViewResponse) {
|
||||
runInAction(() => {
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesFiltersViewResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching workspace level issue filters", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default IssueFilterStore;
|
@ -2,11 +2,19 @@ import { observable, action, computed, makeObservable, runInAction } from "mobx"
|
||||
// types
|
||||
import { RootStore } from "./root";
|
||||
|
||||
export interface IIssueFilterStore {}
|
||||
export interface IIssueFilterStore {
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
userDisplayProperties: any;
|
||||
userDisplayFilters: any;
|
||||
}
|
||||
|
||||
class IssueFilterStore implements IIssueFilterStore {
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
// observables
|
||||
userDisplayProperties: any = {};
|
||||
userDisplayFilters: any = {};
|
||||
// root store
|
||||
rootStore;
|
||||
|
||||
@ -14,6 +22,8 @@ class IssueFilterStore implements IIssueFilterStore {
|
||||
makeObservable(this, {
|
||||
loader: observable.ref,
|
||||
error: observable.ref,
|
||||
userDisplayProperties: observable.ref,
|
||||
userDisplayFilters: observable.ref,
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
|
@ -1,417 +0,0 @@
|
||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||
// types
|
||||
import { RootStore } from "./root";
|
||||
// services
|
||||
import { UserService } from "services/user.service";
|
||||
import { IssueServices } from "services/issue.service";
|
||||
import { ModuleService } from "services/modules.service";
|
||||
import { CycleService } from "services/cycles.service";
|
||||
// types
|
||||
import { TIssueLayouts, TIssueViews } from "./issue_filters.legacy";
|
||||
|
||||
export interface IIssues {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface IIssuesLayout {
|
||||
list: IIssues[];
|
||||
kanban: IIssues[];
|
||||
calendar: IIssues[];
|
||||
spreadsheet: IIssues[];
|
||||
gantt_chart: IIssues[];
|
||||
}
|
||||
|
||||
export interface IIssueState {
|
||||
[key: string]: {
|
||||
// project_id: layout_view
|
||||
issues: {
|
||||
[key: string]: IIssuesLayout; // project_id: layout_key: ...issues, It's always one project id here
|
||||
};
|
||||
cycles: {
|
||||
[key: string]: IIssuesLayout; // cycle_id: layout_key: ...issues
|
||||
};
|
||||
modules: {
|
||||
[key: string]: IIssuesLayout; // module_id: layout_key: ...issues
|
||||
};
|
||||
views: {
|
||||
[key: string]: IIssuesLayout; // view_id: layout_key: ...issues
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface IIssueStore {
|
||||
loader: boolean;
|
||||
error: any | null;
|
||||
issues: IIssueState;
|
||||
// computed
|
||||
getIssues: IIssues | null | undefined;
|
||||
// actions
|
||||
updateIssues: (data: any) => void;
|
||||
getProjectIssuesAsync: (workspaceId: string, projectId: string, fetchFilterToggle?: boolean) => null | Promise<any>;
|
||||
getIssuesForModulesAsync: (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
fetchFilterToggle: boolean
|
||||
) => null | Promise<any>;
|
||||
getIssuesForCyclesAsync: (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
cycleId: string,
|
||||
fetchFilterToggle: boolean
|
||||
) => null | Promise<any>;
|
||||
getIssuesForViewsAsync: (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
viewId: string,
|
||||
fetchFilterToggle: boolean
|
||||
) => null | Promise<any>;
|
||||
}
|
||||
|
||||
class IssueStore implements IIssueStore {
|
||||
loader: boolean = false;
|
||||
error: any | null = null;
|
||||
issues: IIssueState = {};
|
||||
// root store
|
||||
rootStore;
|
||||
// service
|
||||
issueService;
|
||||
userService;
|
||||
modulesService;
|
||||
cyclesService;
|
||||
|
||||
constructor(_rootStore: RootStore) {
|
||||
makeObservable(this, {
|
||||
// observable
|
||||
loader: observable,
|
||||
error: observable,
|
||||
issues: observable.ref,
|
||||
// computed
|
||||
getIssues: computed,
|
||||
// action
|
||||
updateIssues: action,
|
||||
getProjectIssuesAsync: action,
|
||||
getIssuesForModulesAsync: action,
|
||||
getIssuesForCyclesAsync: action,
|
||||
getIssuesForViewsAsync: action,
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
this.issueService = new IssueServices();
|
||||
this.userService = new UserService();
|
||||
this.modulesService = new ModuleService();
|
||||
this.cyclesService = new CycleService();
|
||||
}
|
||||
|
||||
// computed
|
||||
get getIssues() {
|
||||
if (this.issues != null) {
|
||||
const issueView: TIssueViews | null = this.rootStore.issueFilter.issueView;
|
||||
const projectId: string | null = this.rootStore.project.projectId;
|
||||
const moduleId: string | null = this.rootStore.module.moduleId;
|
||||
const cycleId: string | null = this.rootStore.cycle.cycleId;
|
||||
const viewId: string | null = this.rootStore.view.viewId;
|
||||
const issueLayout: TIssueLayouts | null = this.rootStore.issueFilter.issueLayout;
|
||||
|
||||
if (!issueView || !projectId) return null;
|
||||
|
||||
const currentViewIdIndex: string | null =
|
||||
issueView === "issues" && projectId
|
||||
? projectId
|
||||
: issueView === "modules" && moduleId
|
||||
? moduleId
|
||||
: issueView === "cycles" && cycleId
|
||||
? cycleId
|
||||
: issueView === "cycles" && viewId
|
||||
? viewId
|
||||
: null;
|
||||
|
||||
if (!issueLayout || !currentViewIdIndex) return null;
|
||||
return this.issues[projectId][issueView][currentViewIdIndex][issueLayout];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
updateIssues = (data: any) => {
|
||||
const issueView: TIssueViews | null = this.rootStore.issueFilter.issueView;
|
||||
const projectId: string | null = this.rootStore.project.projectId;
|
||||
const moduleId: string | null = this.rootStore.module.moduleId;
|
||||
const cycleId: string | null = this.rootStore.cycle.cycleId;
|
||||
const viewId: string | null = this.rootStore.view.viewId;
|
||||
const issueLayout: TIssueLayouts | null = this.rootStore.issueFilter.issueLayout;
|
||||
|
||||
const { groupId, issueId, issueData } = data as {
|
||||
groupId?: any;
|
||||
issueId: string | null;
|
||||
issueData: any;
|
||||
};
|
||||
|
||||
if (!issueView || !projectId) return null;
|
||||
|
||||
const currentViewIdIndex: string | null =
|
||||
issueView === "issues" && projectId
|
||||
? projectId
|
||||
: issueView === "modules" && moduleId
|
||||
? moduleId
|
||||
: issueView === "cycles" && cycleId
|
||||
? cycleId
|
||||
: issueView === "cycles" && viewId
|
||||
? viewId
|
||||
: null;
|
||||
|
||||
if (!issueLayout || !currentViewIdIndex) return null;
|
||||
|
||||
let _issues = this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex]?.[issueLayout];
|
||||
if (groupId && groupId != null && ["list", "kanban"].includes(issueLayout)) {
|
||||
_issues = {
|
||||
..._issues,
|
||||
[groupId]:
|
||||
_issues?.[groupId] && _issues?.[groupId].length > 0
|
||||
? _issues?.[groupId]?.map((item: any) => (item.id === issueId ? { ...item, ...issueData } : { ...item }))
|
||||
: [],
|
||||
};
|
||||
} else {
|
||||
_issues = {
|
||||
..._issues,
|
||||
..._issues.map((item: any) => (item.id === issueId ? { ...item, ...issueData } : { ...item })),
|
||||
};
|
||||
}
|
||||
|
||||
this.issues = {
|
||||
...this.issues,
|
||||
[projectId]: {
|
||||
...this?.issues?.[projectId],
|
||||
[issueView]: {
|
||||
...this?.issues?.[projectId]?.[issueView],
|
||||
[currentViewIdIndex]: {
|
||||
...this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex],
|
||||
[issueLayout]: {
|
||||
...this?.issues?.[projectId]?.[issueView]?.[currentViewIdIndex]?.[issueLayout],
|
||||
..._issues,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// fetching project issues
|
||||
getProjectIssuesAsync = async (workspaceId: string, projectId: string, fetchFilterToggle: boolean = true) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
if (fetchFilterToggle) await this.rootStore.issueFilter.getProjectIssueFilters(workspaceId, projectId);
|
||||
// const filteredParams = this.rootStore.issueFilter.getComputedFilters(
|
||||
// workspaceId,
|
||||
// projectId,
|
||||
// null,
|
||||
// null,
|
||||
// null,
|
||||
// "issues"
|
||||
// );
|
||||
// const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams);
|
||||
|
||||
// if (issuesResponse) {
|
||||
// const _issueResponse: any = {
|
||||
// ...this.issues,
|
||||
// [projectId]: {
|
||||
// ...this?.issues?.[projectId],
|
||||
// issues: {
|
||||
// ...this?.issues?.[projectId]?.issues,
|
||||
// [this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse,
|
||||
// },
|
||||
// },
|
||||
// };
|
||||
|
||||
// runInAction(() => {
|
||||
// this.issues = _issueResponse;
|
||||
// this.loader = false;
|
||||
// this.error = null;
|
||||
// });
|
||||
// }
|
||||
|
||||
// return issuesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching the project issues", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
// fetching project issues for modules
|
||||
getIssuesForModulesAsync = async (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
fetchFilterToggle: boolean = true
|
||||
) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
if (fetchFilterToggle)
|
||||
await this.rootStore.issueFilter.getProjectIssueModuleFilters(workspaceId, projectId, moduleId);
|
||||
const filteredParams = this.rootStore.issueFilter.getComputedFilters(
|
||||
workspaceId,
|
||||
projectId,
|
||||
moduleId,
|
||||
null,
|
||||
null,
|
||||
"modules"
|
||||
);
|
||||
const issuesResponse = await this.modulesService.getModuleIssuesWithParams(
|
||||
workspaceId,
|
||||
projectId,
|
||||
moduleId,
|
||||
filteredParams
|
||||
);
|
||||
|
||||
if (issuesResponse) {
|
||||
const _issueResponse: any = {
|
||||
...this.issues,
|
||||
[projectId]: {
|
||||
...this?.issues?.[projectId],
|
||||
modules: {
|
||||
...this?.issues?.[projectId]?.modules,
|
||||
[moduleId]: {
|
||||
...this?.issues?.[projectId]?.modules?.[moduleId],
|
||||
[this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = _issueResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching the project module issues", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
// fetching project issues for cycles
|
||||
getIssuesForCyclesAsync = async (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
cycleId: string,
|
||||
fetchFilterToggle: boolean = true
|
||||
) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
if (fetchFilterToggle)
|
||||
await this.rootStore.issueFilter.getProjectIssueCyclesFilters(workspaceId, projectId, cycleId);
|
||||
const filteredParams = this.rootStore.issueFilter.getComputedFilters(
|
||||
workspaceId,
|
||||
projectId,
|
||||
null,
|
||||
cycleId,
|
||||
null,
|
||||
"cycles"
|
||||
);
|
||||
const issuesResponse = await this.cyclesService.getCycleIssuesWithParams(
|
||||
workspaceId,
|
||||
projectId,
|
||||
cycleId,
|
||||
filteredParams
|
||||
);
|
||||
|
||||
if (issuesResponse) {
|
||||
const _issueResponse: any = {
|
||||
...this.issues,
|
||||
[projectId]: {
|
||||
...this?.issues?.[projectId],
|
||||
cycles: {
|
||||
...this?.issues?.[projectId]?.cycles,
|
||||
[cycleId]: {
|
||||
...this?.issues?.[projectId]?.cycles?.[cycleId],
|
||||
[this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = _issueResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching the project cycles issues", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
// fetching project issues for views
|
||||
getIssuesForViewsAsync = async (
|
||||
workspaceId: string,
|
||||
projectId: string,
|
||||
viewId: string,
|
||||
fetchFilterToggle: boolean = true
|
||||
) => {
|
||||
try {
|
||||
this.loader = true;
|
||||
this.error = null;
|
||||
|
||||
if (fetchFilterToggle)
|
||||
await this.rootStore.issueFilter.getProjectIssueViewsFilters(workspaceId, projectId, viewId);
|
||||
const filteredParams = this.rootStore.issueFilter.getComputedFilters(
|
||||
workspaceId,
|
||||
projectId,
|
||||
null,
|
||||
null,
|
||||
viewId,
|
||||
"views"
|
||||
);
|
||||
const issuesResponse = await this.issueService.getIssuesWithParams(workspaceId, projectId, filteredParams);
|
||||
|
||||
if (issuesResponse) {
|
||||
const _issueResponse: any = {
|
||||
...this.issues,
|
||||
[projectId]: {
|
||||
...this?.issues?.[projectId],
|
||||
views: {
|
||||
...this?.issues?.[projectId]?.views,
|
||||
[viewId]: {
|
||||
...this?.issues?.[projectId]?.views?.[viewId],
|
||||
[this.rootStore?.issueFilter?.userFilters?.display_filters?.layout as string]: issuesResponse,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = _issueResponse;
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
});
|
||||
}
|
||||
|
||||
return issuesResponse;
|
||||
} catch (error) {
|
||||
console.warn("error in fetching the project view issues", error);
|
||||
this.loader = false;
|
||||
this.error = null;
|
||||
return error;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default IssueStore;
|
@ -1,150 +0,0 @@
|
||||
// mobx
|
||||
import { action, observable, runInAction, makeAutoObservable } from "mobx";
|
||||
// services
|
||||
import issueService from "services/issue.service";
|
||||
// types
|
||||
import type { ICurrentUserResponse, IIssue } from "types";
|
||||
|
||||
class IssuesStore {
|
||||
issues: { [key: string]: IIssue } = {};
|
||||
isIssuesLoading: boolean = false;
|
||||
rootStore: any | null = null;
|
||||
|
||||
constructor(_rootStore: any | null = null) {
|
||||
makeAutoObservable(this, {
|
||||
issues: observable.ref,
|
||||
loadIssues: action,
|
||||
getIssueById: action,
|
||||
isIssuesLoading: observable,
|
||||
createIssue: action,
|
||||
updateIssue: action,
|
||||
deleteIssue: action,
|
||||
});
|
||||
|
||||
this.rootStore = _rootStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Fetch all issues of a project and hydrate issues field
|
||||
*/
|
||||
|
||||
loadIssues = async (workspaceSlug: string, projectId: string) => {
|
||||
this.isIssuesLoading = true;
|
||||
try {
|
||||
const issuesResponse: IIssue[] = (await issueService.getIssuesWithParams(workspaceSlug, projectId)) as IIssue[];
|
||||
|
||||
const issues: { [kye: string]: IIssue } = {};
|
||||
issuesResponse.forEach((issue) => {
|
||||
issues[issue.id] = issue;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = issues;
|
||||
this.isIssuesLoading = false;
|
||||
});
|
||||
} catch (error) {
|
||||
this.isIssuesLoading = false;
|
||||
console.error("Fetching issues error", error);
|
||||
}
|
||||
};
|
||||
|
||||
getIssueById = async (workspaceSlug: string, projectId: string, issueId: string): Promise<IIssue> => {
|
||||
if (this.issues[issueId]) return this.issues[issueId];
|
||||
|
||||
try {
|
||||
const issueResponse: IIssue = await issueService.retrieve(workspaceSlug, projectId, issueId);
|
||||
|
||||
const issues = {
|
||||
...this.issues,
|
||||
[issueId]: { ...issueResponse },
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = issues;
|
||||
});
|
||||
|
||||
return issueResponse;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createIssue = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueForm: IIssue,
|
||||
user: ICurrentUserResponse
|
||||
): Promise<IIssue> => {
|
||||
try {
|
||||
const issueResponse = await issueService.createIssues(workspaceSlug, projectId, issueForm, user);
|
||||
|
||||
const issues = {
|
||||
...this.issues,
|
||||
[issueResponse.id]: { ...issueResponse },
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = issues;
|
||||
});
|
||||
return issueResponse;
|
||||
} catch (error) {
|
||||
console.error("Creating issue error", error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateIssue = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
issueForm: Partial<IIssue>,
|
||||
user: ICurrentUserResponse
|
||||
) => {
|
||||
// keep a copy of the issue in the store
|
||||
const originalIssue = { ...this.issues[issueId] };
|
||||
|
||||
// immediately update the issue in the store
|
||||
const updatedIssue = { ...this.issues[issueId], ...issueForm };
|
||||
if (updatedIssue.assignees_list) updatedIssue.assignees = updatedIssue.assignees_list;
|
||||
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.issues[issueId] = { ...updatedIssue };
|
||||
});
|
||||
|
||||
// make a patch request to update the issue
|
||||
const issueResponse: IIssue = await issueService.patchIssue(workspaceSlug, projectId, issueId, issueForm, user);
|
||||
|
||||
const updatedIssues = { ...this.issues };
|
||||
updatedIssues[issueId] = { ...issueResponse };
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = updatedIssues;
|
||||
});
|
||||
} catch (error) {
|
||||
// if there is an error, revert the changes
|
||||
runInAction(() => {
|
||||
this.issues[issueId] = originalIssue;
|
||||
});
|
||||
|
||||
return error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssue = async (workspaceSlug: string, projectId: string, issueId: string, user: ICurrentUserResponse) => {
|
||||
const issues = { ...this.issues };
|
||||
delete issues[issueId];
|
||||
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.issues = issues;
|
||||
});
|
||||
|
||||
issueService.deleteIssue(workspaceSlug, projectId, issueId, user);
|
||||
} catch (error) {
|
||||
console.error("Deleting issue error", error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default IssuesStore;
|
@ -4,8 +4,8 @@ import { enableStaticRendering } from "mobx-react-lite";
|
||||
import UserStore from "./user";
|
||||
import ThemeStore from "./theme";
|
||||
import ProjectPublishStore, { IProjectPublishStore } from "./project_publish";
|
||||
import IssueStore, { IIssueStore } from "./issue_store.legacy";
|
||||
import DraftIssuesStore from "./draft_issue";
|
||||
import IssueStore, { IIssueStore } from "./issue";
|
||||
import DraftIssuesStore from "./issue_draft";
|
||||
import WorkspaceStore, { IWorkspaceStore } from "./workspace";
|
||||
import ProjectStore, { IProjectStore } from "./project";
|
||||
import ModuleStore, { IModuleStore } from "./modules";
|
||||
@ -13,7 +13,7 @@ import CycleStore, { ICycleStore } from "./cycles";
|
||||
import ViewStore, { IViewStore } from "./views";
|
||||
import IssueFilterStore, { IIssueFilterStore } from "./issue_filters";
|
||||
import IssueViewDetailStore from "./issue_detail";
|
||||
import IssueKanBanViewStore from "./kanban-view";
|
||||
import IssueKanBanViewStore from "./kanban_view";
|
||||
|
||||
enableStaticRendering(typeof window === "undefined");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user