chore: implemented filters and views in kanaban

This commit is contained in:
gurusainath 2023-09-13 19:40:35 +05:30
parent 698021ab8b
commit 0ec0ad6aba
24 changed files with 667 additions and 261 deletions

View File

@ -0,0 +1,43 @@
import React from "react";
// components
import { FilterHeader } from "../helpers/filter-header";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
export const FilterDisplayProperties = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(true);
return (
<div>
<FilterHeader
title={"Display Properties"}
isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/>
{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`
}`}
>
{_displayProperties?.title}
</div>
))}
</div>
)}
</div>
);
});

View File

@ -0,0 +1,43 @@
import React from "react";
// 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";
export const FilterExtraOptions = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(true);
return (
<div>
<FilterHeader
title={"Extra Options"}
isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/>
{previewEnabled && (
<div className="space-y-[2px] pt-1">
{issueFilterStore?.issueRenderFilters?.extra_properties &&
issueFilterStore?.issueRenderFilters?.extra_properties.length > 0 &&
issueFilterStore?.issueRenderFilters?.extra_properties.map((_extraProperties) => (
<FilterOption
key={_extraProperties?.key}
isChecked={
issueFilterStore?.userFilters?.display_filters?.[_extraProperties?.key]
? true
: false
}
title={_extraProperties.title}
/>
))}
</div>
)}
</div>
);
});

View File

@ -0,0 +1,44 @@
import React from "react";
// 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";
export const FilterGroupBy = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(true);
return (
<div>
<FilterHeader
title={"Group By"}
isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/>
{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
}
title={_groupBy.title}
multiple={false}
/>
))}
</div>
)}
</div>
);
});

View File

@ -1,15 +1,45 @@
import React from "react"; import React from "react";
// mobx store // components
import { useMobxStore } from "lib/mobx/store-provider"; import { FilterDisplayProperties } from "./display-properties";
import { RootStore } from "store/root"; import { FilterGroupBy } from "./group-by";
import { FilterOrderBy } from "./order-by";
import { FilterIssueType } from "./issue-type";
import { FilterExtraOptions } from "./extra-options";
// // mobx react lite
// import { observer } from "mobx-react-lite";
// // mobx store
// import { useMobxStore } from "lib/mobx/store-provider";
// import { RootStore } from "store/root";
export const DisplayPropertiesSelection = () => { // const store: RootStore = useMobxStore();
const store: RootStore = useMobxStore(); // const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
return ( export const DisplayFiltersSelection = () => (
<div> <div className="w-full h-full overflow-hidden select-none relative flex flex-col">
<div>Filter Selection</div> <div className="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container
</div> </div>
); <div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
}; {/* display properties */}
<div className="pb-2 px-2 border-b border-custom-border-200">
<FilterDisplayProperties />
</div>
{/* group by */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterGroupBy />
</div>
{/* order by */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterOrderBy />
</div>
{/* issue type */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterIssueType />
</div>
{/* Options */}
<div className="pt-1 px-2">
<FilterExtraOptions />
</div>
</div>
</div>
);

View File

@ -0,0 +1,44 @@
import React from "react";
// 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";
export const FilterIssueType = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(true);
return (
<div>
<FilterHeader
title={"Issue Type"}
isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/>
{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
}
title={_issueType.title}
multiple={false}
/>
))}
</div>
)}
</div>
);
});

View File

@ -0,0 +1,44 @@
import React from "react";
// 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";
export const FilterOrderBy = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(true);
return (
<div>
<FilterHeader
title={"Order By"}
isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/>
{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
}
title={_orderBy.title}
multiple={false}
/>
))}
</div>
)}
</div>
);
});

View File

@ -17,7 +17,7 @@ export const MemberIcons = ({
display_name: string; display_name: string;
avatar: string | null; avatar: string | null;
}) => ( }) => (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] flex justify-center items-center bg-custom-background-80"> <div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] flex justify-center items-center">
{avatar ? ( {avatar ? (
<img src={avatar} alt={display_name || ""} className="" /> <img src={avatar} alt={display_name || ""} className="" />
) : ( ) : (
@ -32,14 +32,14 @@ export const FilterAssignees = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"Assignees"} title={"Assignees"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -48,7 +48,12 @@ export const FilterAssignees = observer(() => {
issueFilterStore?.projectMembers.map((_member) => ( issueFilterStore?.projectMembers.map((_member) => (
<FilterOption <FilterOption
key={`assignees-${_member?.member?.id}`} key={`assignees-${_member?.member?.id}`}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.assignees != null &&
issueFilterStore?.userFilters?.filters?.assignees.includes(_member?.member?.id)
? true
: false
}
icon={ icon={
<MemberIcons <MemberIcons
display_name={_member?.member.display_name} display_name={_member?.member.display_name}

View File

@ -15,14 +15,14 @@ export const FilterCreatedBy = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"Created By"} title={"Created By"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -31,7 +31,12 @@ export const FilterCreatedBy = observer(() => {
issueFilterStore?.projectMembers.map((_member) => ( issueFilterStore?.projectMembers.map((_member) => (
<FilterOption <FilterOption
key={`create-by-${_member?.member?.id}`} key={`create-by-${_member?.member?.id}`}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.created_by != null &&
issueFilterStore?.userFilters?.filters?.created_by.includes(_member?.member?.id)
? true
: false
}
icon={ icon={
<MemberIcons <MemberIcons
display_name={_member?.member.display_name} display_name={_member?.member.display_name}

View File

@ -8,50 +8,53 @@ import { FilterCreatedBy } from "./created-by";
import { FilterLabels } from "./labels"; import { FilterLabels } from "./labels";
import { FilterStartDate } from "./start-date"; import { FilterStartDate } from "./start-date";
import { FilterTargetDate } from "./target-date"; import { FilterTargetDate } from "./target-date";
// mobx react lite // // mobx react lite
import { observer } from "mobx-react-lite"; // import { observer } from "mobx-react-lite";
// mobx store // // mobx store
import { useMobxStore } from "lib/mobx/store-provider"; // import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root"; // import { RootStore } from "store/root";
export const FilterSelection = observer(() => { // const store: RootStore = useMobxStore();
const store: RootStore = useMobxStore(); // const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
return ( export const FilterSelection = () => (
<div className="container w-full h-full overflow-y-auto mx-auto max-w-[400px] relative select-none"> <div className="w-full h-full overflow-hidden select-none relative flex flex-col">
<div className="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container
</div>
<div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
{/* priority */} {/* priority */}
<div className="py-2 border-b border-custom-border-100"> <div className="pb-1 px-2 border-b border-custom-border-200">
<FilterPriority /> <FilterPriority />
</div> </div>
{/* state group */} {/* state group */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterStateGroup /> <FilterStateGroup />
</div> </div>
{/* state */} {/* state */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterState /> <FilterState />
</div> </div>
{/* assignees */} {/* assignees */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterAssignees /> <FilterAssignees />
</div> </div>
{/* created_by */} {/* created_by */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterCreatedBy /> <FilterCreatedBy />
</div> </div>
{/* labels */} {/* labels */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterLabels /> <FilterLabels />
</div> </div>
{/* start_date */} {/* start_date */}
<div className="py-2 border-b border-custom-border-100"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterStartDate /> <FilterStartDate />
</div> </div>
{/* due_date */} {/* due_date */}
<div className="py-2"> <div className="pt-1 px-2">
<FilterTargetDate /> <FilterTargetDate />
</div> </div>
</div> </div>
); </div>
}); );

View File

@ -20,14 +20,14 @@ export const FilterLabels = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"labels"} title={"labels"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -35,8 +35,13 @@ export const FilterLabels = observer(() => {
issueFilterStore?.projectLabels.length > 0 && issueFilterStore?.projectLabels.length > 0 &&
issueFilterStore?.projectLabels.map((_label) => ( issueFilterStore?.projectLabels.map((_label) => (
<FilterOption <FilterOption
key={_label?.key} key={_label?.id}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.labels != null &&
issueFilterStore?.userFilters?.filters?.labels.includes(_label?.id)
? true
: false
}
icon={<LabelIcons color={_label.color} />} icon={<LabelIcons color={_label.color} />}
title={_label.name} title={_label.name}
/> />

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
// lucide icons // lucide icons
import { AlertCircle, SignalHigh, SignalMedium, SignalLow, Ban, Check } from "lucide-react"; import { AlertCircle, SignalHigh, SignalMedium, SignalLow, Ban } from "lucide-react";
// components // components
import { FilterHeader } from "../helpers/filter-header"; import { FilterHeader } from "../helpers/filter-header";
import { FilterOption } from "../helpers/filter-option"; import { FilterOption } from "../helpers/filter-option";
@ -54,14 +54,14 @@ export const FilterPriority = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"Priority"} title={"Priority"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -70,11 +70,21 @@ export const FilterPriority = observer(() => {
issueFilterStore?.issueRenderFilters?.priority.map((_priority) => ( issueFilterStore?.issueRenderFilters?.priority.map((_priority) => (
<FilterOption <FilterOption
key={_priority?.key} key={_priority?.key}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.priority != null &&
issueFilterStore?.userFilters?.filters?.priority.includes(_priority?.key)
? true
: false
}
icon={<PriorityIcons priority={_priority.key} />} icon={<PriorityIcons priority={_priority.key} />}
title={_priority.title} title={_priority.title}
/> />
))} ))}
<div className="pl-[32px] flex items-center gap-2 py-[6px] text-xs text-custom-primary-100">
<div>View more</div>
<div>View less</div>
<div>View all</div>
</div>
</div> </div>
)} )}
</div> </div>

View File

@ -14,14 +14,14 @@ export const FilterStartDate = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"Start Date"} title={"Start Date"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">

View File

@ -87,14 +87,14 @@ export const FilterStateGroup = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"State Group"} title={"State Group"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -103,7 +103,12 @@ export const FilterStateGroup = observer(() => {
issueFilterStore?.issueRenderFilters?.state_group.map((_stateGroup) => ( issueFilterStore?.issueRenderFilters?.state_group.map((_stateGroup) => (
<FilterOption <FilterOption
key={_stateGroup?.key} key={_stateGroup?.key}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.state_group != null &&
issueFilterStore?.userFilters?.filters?.state_group.includes(_stateGroup?.key)
? true
: false
}
icon={<StateGroupIcons stateGroup={_stateGroup.key} />} icon={<StateGroupIcons stateGroup={_stateGroup.key} />}
title={_stateGroup.title} title={_stateGroup.title}
/> />

View File

@ -17,14 +17,14 @@ export const FilterState = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"State"} title={"State"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
@ -36,7 +36,12 @@ export const FilterState = observer(() => {
issueFilterStore?.projectStates[_stateGroup].map((_state: any) => ( issueFilterStore?.projectStates[_stateGroup].map((_state: any) => (
<FilterOption <FilterOption
key={_state?.id} key={_state?.id}
isChecked={false} isChecked={
issueFilterStore?.userFilters?.filters?.state != null &&
issueFilterStore?.userFilters?.filters?.state.includes(_state?.id)
? true
: false
}
icon={<StateGroupIcons stateGroup={_stateGroup} color={_state?.color} />} icon={<StateGroupIcons stateGroup={_stateGroup} color={_state?.color} />}
title={_state?.name} title={_state?.name}
/> />

View File

@ -14,14 +14,14 @@ export const FilterTargetDate = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store; const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [previewEnabled, setPreviewEnabled] = React.useState(false); const [previewEnabled, setPreviewEnabled] = React.useState(true);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={"Target Date"} title={"Target Date"}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={setPreviewEnabled} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">

View File

@ -0,0 +1,50 @@
import { Fragment } from "react";
// headless ui
import { Popover, Transition } from "@headlessui/react";
// lucide icons
import { ChevronDown, ChevronUp } from "lucide-react";
interface IIssueDropdown {
children: React.ReactNode;
title?: string;
}
export const IssueDropdown = ({ children, title = "Dropdown" }: IIssueDropdown) => (
<Popover className="relative">
{({ open }) => {
if (open) {
}
return (
<>
<Popover.Button
className={`outline-none border border-custom-border-200 text-xs rounded flex items-center gap-2 p-2 py-1.5 hover:bg-custom-background-100`}
>
<div className="font-medium">{title}</div>
<div className="w-[14px] h-[14px] flex justify-center items-center">
{open ? (
<ChevronUp width={14} strokeWidth={2} />
) : (
<ChevronDown width={14} strokeWidth={2} />
)}
</div>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute right-0 z-10 mt-1 w-[300px] h-[700px]">
<div className="w-full h-full overflow-hidden rounded border border-custom-border-200 bg-custom-background-100 shadow-xl">
{children}
</div>
</Popover.Panel>
</Transition>
</>
);
}}
</Popover>
);

View File

@ -5,7 +5,7 @@ import { ChevronDown, ChevronUp } from "lucide-react";
interface IFilterHeader { interface IFilterHeader {
title: string; title: string;
isPreviewEnabled: boolean; isPreviewEnabled: boolean;
handleIsPreviewEnabled: (isPreviewEnabled: boolean) => void; handleIsPreviewEnabled: () => void;
} }
export const FilterHeader = ({ export const FilterHeader = ({
@ -13,11 +13,11 @@ export const FilterHeader = ({
isPreviewEnabled, isPreviewEnabled,
handleIsPreviewEnabled, handleIsPreviewEnabled,
}: IFilterHeader) => ( }: IFilterHeader) => (
<div className="flex items-center justify-between gap-2 p-[6px] pb-2 bg-custom-background-80 sticky top-0"> <div className="flex items-center justify-between gap-2 p-[6px] pb-1 bg-custom-background-100 sticky top-0">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">{title}</div> <div className="text-gray-500 text-xs text-custom-text-300 font-medium">{title}</div>
<div <div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-background-100 cursor-pointer" className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded transition-all hover:bg-custom-background-80 cursor-pointer"
onClick={() => handleIsPreviewEnabled(!isPreviewEnabled)} onClick={handleIsPreviewEnabled}
> >
{isPreviewEnabled ? <ChevronUp size={14} /> : <ChevronDown size={14} />} {isPreviewEnabled ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div> </div>

View File

@ -10,7 +10,7 @@ interface IFilterOption {
} }
export const FilterOption = ({ isChecked, icon, title, multiple = true }: IFilterOption) => ( export const FilterOption = ({ isChecked, icon, title, multiple = true }: IFilterOption) => (
<div className="flex items-center gap-3 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all hover:bg-custom-border-100"> <div className="flex items-center gap-3 cursor-pointer rounded p-[6px] py-[5px] transition-all hover:bg-custom-border-100">
<div <div
className={`flex-shrink-0 w-[14px] h-[14px] flex justify-center items-center border border-custom-border-300 bg-custom-background-90 ${ className={`flex-shrink-0 w-[14px] h-[14px] flex justify-center items-center border border-custom-border-300 bg-custom-background-90 ${
isChecked ? `bg-custom-primary-300 text-white` : `` isChecked ? `bg-custom-primary-300 text-white` : ``
@ -19,6 +19,6 @@ export const FilterOption = ({ isChecked, icon, title, multiple = true }: IFilte
{isChecked && <Check size={10} strokeWidth={2} />} {isChecked && <Check size={10} strokeWidth={2} />}
</div> </div>
{icon} {icon}
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">{title}</div> <div className="hyphens-auto line-clamp-1 text-custom-text-200 text-xs w-full">{title}</div>
</div> </div>
); );

View File

@ -28,28 +28,6 @@ export const IssueKanBanViewRoot = observer(() => {
console.log("result", result); console.log("result", result);
}; };
console.log("------");
console.log("workspace id -->", issueFilterStore?.workspaceId);
console.log("project id -->", issueFilterStore?.projectId);
console.log("module id -->", issueFilterStore?.moduleId);
console.log("cycle id -->", issueFilterStore?.cycleId);
console.log("view id -->", issueFilterStore?.viewId);
console.log("<-- workspace level -->");
console.log("workspace projects -->", issueFilterStore?.workspaceProjects);
console.log("workspace labels -->", issueFilterStore?.workspaceLabels);
console.log("<-- project level -->");
console.log("project states -->", issueFilterStore?.projectStates);
console.log("project labels -->", issueFilterStore?.projectLabels);
console.log("project members -->", issueFilterStore?.projectMembers);
console.log("project display properties -->", issueFilterStore?.projectDisplayProperties);
console.log("issue layout -->", issueFilterStore?.issueLayout);
console.log("issues -->", issueViewStore?.getIssues);
console.log("------");
return ( return (
<div className="relative w-full h-full"> <div className="relative w-full h-full">
{issueViewStore.loader || issueViewStore?.getIssues === null ? ( {issueViewStore.loader || issueViewStore?.getIssues === null ? (

View File

@ -94,7 +94,7 @@ export const LayoutSelection = observer(() => {
{layoutSelectionFilters.map((_layout) => ( {layoutSelectionFilters.map((_layout) => (
<div <div
key={_layout?.key} key={_layout?.key}
className={`w-[32px] h-[26px] rounded flex justify-center items-center cursor-pointer transition-all hover:bg-custom-background-100 overflow-hidden group ${ className={`w-[28px] h-[22px] rounded flex justify-center items-center cursor-pointer transition-all hover:bg-custom-background-100 overflow-hidden group ${
issueFilterStore?.issueLayout == _layout?.key issueFilterStore?.issueLayout == _layout?.key
? `bg-custom-background-100 shadow shadow-gray-200` ? `bg-custom-background-100 shadow shadow-gray-200`
: `` : ``
@ -102,7 +102,7 @@ export const LayoutSelection = observer(() => {
onClick={() => handleLayoutSelection(_layout?.key)} onClick={() => handleLayoutSelection(_layout?.key)}
> >
<_layout.icon <_layout.icon
size={15} size={14}
strokeWidth={2} strokeWidth={2}
className={`${ className={`${
issueFilterStore?.issueLayout == _layout?.key issueFilterStore?.issueLayout == _layout?.key

View File

@ -4,7 +4,11 @@ import useSWR from "swr";
// components // components
import { IssueKanBanViewRoot } from "components/issue-layouts/kanban"; import { IssueKanBanViewRoot } from "components/issue-layouts/kanban";
import { LayoutSelection } from "components/issue-layouts/layout-selection"; import { LayoutSelection } from "components/issue-layouts/layout-selection";
// issue dropdowns
import { IssueDropdown } from "components/issue-layouts/helpers/dropdown";
// filter components
import { FilterSelection } from "components/issue-layouts/filters"; import { FilterSelection } from "components/issue-layouts/filters";
import { DisplayFiltersSelection } from "components/issue-layouts/display-filters";
// mobx store // mobx store
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root"; import { RootStore } from "store/root";
@ -29,8 +33,8 @@ const KanBanViewRoot = () => {
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "spreadsheet"); // await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "spreadsheet");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "gantt"); // await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "gantt");
// project issues under and workspace and project // project issues under and workspace and project
await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "list"); // await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "list");
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "kanban"); await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "kanban");
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "calendar"); // await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "calendar");
// await issueViewStore.getProjectIssuesAsync( // await issueViewStore.getProjectIssuesAsync(
// workspaceSlug, // workspaceSlug,
@ -165,16 +169,18 @@ const KanBanViewRoot = () => {
<div>Filter Header</div> <div>Filter Header</div>
</div> </div>
<div className="relative flex items-center gap-2"> <div className="relative flex items-center gap-2">
<div>{/* <FilterSelection /> */}</div> <IssueDropdown title={"Filters"}>
<div> <FilterSelection />
<LayoutSelection /> </IssueDropdown>
</div> <IssueDropdown title={"View"}>
<DisplayFiltersSelection />
</IssueDropdown>
<LayoutSelection />
</div> </div>
</div> </div>
</div> </div>
<div className="w-full h-full relative overflow-hidden"> <div className="w-full h-full relative overflow-hidden">
<FilterSelection /> <IssueKanBanViewRoot />
{/* <IssueKanBanViewRoot /> */}
</div> </div>
</div> </div>
</div> </div>

View File

@ -131,9 +131,9 @@ class IssueViewStore implements IIssueViewStore {
const currentLayout: TIssueLayouts = currentProjectId const currentLayout: TIssueLayouts = currentProjectId
? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId] ? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]
?.project_issue_properties?.[currentProjectId]?.renderLayout ?.project_issue_properties?.[currentProjectId]?.issues?.display_filters?.layout
: this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties : this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties
?.renderLayout; ?.display_filters?.layout;
if (currentView === "my_issues") if (currentView === "my_issues")
return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout]; return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout];

View File

@ -12,7 +12,7 @@ export const filtersPriority: { key: string; title: string }[] = [
{ key: "high", title: "High" }, { key: "high", title: "High" },
{ key: "medium", title: "Medium" }, { key: "medium", title: "Medium" },
{ key: "low", title: "Low" }, { key: "low", title: "Low" },
{ key: "null", title: "None" }, { key: "none", title: "None" },
]; ];
export const filterStateGroup: { key: TStateGroup; title: string }[] = [ export const filterStateGroup: { key: TStateGroup; title: string }[] = [
@ -43,7 +43,7 @@ export const displayPropertyGroupBy: { key: string; title: string }[] = [
{ key: "state", title: "States" }, { key: "state", title: "States" },
{ key: "state_detail.group", title: "State Groups" }, { key: "state_detail.group", title: "State Groups" },
{ key: "priority", title: "Priority" }, { key: "priority", title: "Priority" },
{ key: "Project", title: "project" }, // required this on my issues { key: "Project", title: "Project" }, // required this on my issues
{ key: "labels", title: "Labels" }, { key: "labels", title: "Labels" },
{ key: "assignees", title: "Assignees" }, { key: "assignees", title: "Assignees" },
{ key: "created_by", title: "Created By" }, { key: "created_by", title: "Created By" },
@ -67,7 +67,7 @@ export const displayProperties: { key: string; title: string }[] = [
{ key: "assignee", title: "Assignee" }, { key: "assignee", title: "Assignee" },
{ key: "start_date", title: "Start Date" }, { key: "start_date", title: "Start Date" },
{ key: "due_date", title: "Due Date" }, { key: "due_date", title: "Due Date" },
{ key: "key", title: "Id" }, { key: "key", title: "ID" },
{ key: "labels", title: "Labels" }, { key: "labels", title: "Labels" },
{ key: "priority", title: "Priority" }, { key: "priority", title: "Priority" },
{ key: "state", title: "State" }, { key: "state", title: "State" },
@ -76,3 +76,10 @@ export const displayProperties: { key: string; title: string }[] = [
{ key: "link", title: "Link" }, { key: "link", title: "Link" },
{ key: "estimate", title: "Estimate" }, { key: "estimate", title: "Estimate" },
]; ];
export const extraProperties: { key: string; title: string }[] = [
{ key: "sub_issues", 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
];

View File

@ -16,6 +16,7 @@ import {
displayPropertyOrderBy, displayPropertyOrderBy,
displayPropertyIssueType, displayPropertyIssueType,
displayProperties, displayProperties,
extraProperties,
} from "./issue_data"; } from "./issue_data";
export type TIssueViews = "my_issues" | "issues" | "modules" | "views" | "cycles"; export type TIssueViews = "my_issues" | "issues" | "modules" | "views" | "cycles";
@ -70,6 +71,7 @@ export interface IIssueRenderFilters {
order_by: { key: string; title: string }[]; order_by: { key: string; title: string }[];
issue_type: { key: string; title: string }[]; issue_type: { key: string; title: string }[];
display_properties: { key: string; title: string }[]; display_properties: { key: string; title: string }[];
extra_properties: { key: string; title: string }[];
workspace_properties: { workspace_properties: {
[key: string]: { [key: string]: {
projects: any[]; projects: any[];
@ -91,7 +93,6 @@ export interface IIssueFilters {
filters: IIssueFilter; filters: IIssueFilter;
display_filters: IIssueDisplayFilters; display_filters: IIssueDisplayFilters;
display_properties: IIssueDisplayProperties; display_properties: IIssueDisplayProperties;
renderLayout: TIssueLayouts;
}; };
project_issue_properties: { project_issue_properties: {
[key: string]: { [key: string]: {
@ -99,11 +100,22 @@ export interface IIssueFilters {
filters: IIssueFilter; filters: IIssueFilter;
display_filters: IIssueDisplayFilters; display_filters: IIssueDisplayFilters;
}; };
cycles: { filters: IIssueFilter; display_filters: IIssueDisplayFilters }; cycles: {
modules: { filters: IIssueFilter; display_filters: IIssueDisplayFilters }; [key: string]: {
views: { filters: IIssueFilter; display_filters: IIssueDisplayFilters }; filters: IIssueFilter;
};
};
modules: {
[key: string]: {
filters: IIssueFilter;
};
};
views: {
[key: string]: {
filters: IIssueFilter;
};
};
display_properties: IIssueDisplayProperties; display_properties: IIssueDisplayProperties;
renderLayout: TIssueLayouts;
}; };
}; };
}; };
@ -124,6 +136,16 @@ export interface IIssueFilterStore {
issueRenderFilters: IIssueRenderFilters; issueRenderFilters: IIssueRenderFilters;
issueFilters: IIssueFilters; issueFilters: IIssueFilters;
filterRenderProperties:
| {
[key: string]: {
isPreviewEnabled: boolean;
totalElements: number;
elementsVisible: number;
};
}[]
| null;
// actions // actions
getWorkspaceMyIssuesFilters: (workspaceId: string) => Promise<any>; getWorkspaceMyIssuesFilters: (workspaceId: string) => Promise<any>;
updateWorkspaceMyIssuesFilters: () => any | Promise<any>; updateWorkspaceMyIssuesFilters: () => any | Promise<any>;
@ -173,10 +195,21 @@ class IssueFilterStore implements IIssueFilterStore {
order_by: displayPropertyOrderBy, order_by: displayPropertyOrderBy,
issue_type: displayPropertyIssueType, issue_type: displayPropertyIssueType,
display_properties: displayProperties, display_properties: displayProperties,
extra_properties: extraProperties,
workspace_properties: {}, workspace_properties: {},
}; };
issueFilters: IIssueFilters = {}; issueFilters: IIssueFilters = {};
filterRenderProperties:
| {
[key: string]: {
isPreviewEnabled: boolean;
totalElements: number;
elementsVisible: number;
};
}[]
| null = null;
// root store // root store
rootStore; rootStore;
// service // service
@ -211,6 +244,8 @@ class IssueFilterStore implements IIssueFilterStore {
projectMembers: computed, projectMembers: computed,
projectDisplayProperties: computed, projectDisplayProperties: computed,
userFilters: computed,
// action // action
setWorkspaceId: action, setWorkspaceId: action,
setProjectId: action, setProjectId: action,
@ -253,12 +288,11 @@ class IssueFilterStore implements IIssueFilterStore {
// computed // computed
get issueLayout() { get issueLayout() {
if (!this.workspaceId) return null; if (!this.workspaceId) return null;
if (!this.projectId) if (!this.projectId)
return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.renderLayout; return this.issueFilters?.[this.workspaceId]?.my_issue_properties?.display_filters?.layout;
if (this.projectId) if (this.projectId)
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.renderLayout; ?.issues?.display_filters?.layout;
} }
get workspaceProjects() { get workspaceProjects() {
@ -291,9 +325,68 @@ class IssueFilterStore implements IIssueFilterStore {
get projectDisplayProperties() { get projectDisplayProperties() {
if (!this.workspaceId || !this.projectId) return null; if (!this.workspaceId || !this.projectId) return null;
return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId] return this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.display_properties; ?.display_properties as any;
} }
get userFilters() {
if (!this.workspaceId) return null;
if (this.issueView === "my_issues")
return this.issueFilters?.[this.workspaceId]?.my_issue_properties;
if (!this.projectId) return null;
let _issueFilters: {
filters: IIssueFilter | null;
display_filters: IIssueDisplayFilters;
display_properties: IIssueDisplayProperties;
} = {
filters: null,
display_filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues
?.display_filters,
display_properties:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.display_properties,
};
if (this.issueView === "issues") {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]?.issues
?.filters,
};
return _issueFilters;
}
if (this.issueView === "modules" && this.moduleId) {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.modules?.[this.moduleId]?.filters,
};
return _issueFilters;
}
if (this.issueView === "cycles" && this.cycleId) {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.cycles?.[this.cycleId]?.filters,
};
return _issueFilters;
}
if (this.issueView === "views" && this.viewId) {
_issueFilters = {
..._issueFilters,
filters:
this.issueFilters?.[this.workspaceId]?.project_issue_properties?.[this.projectId]
?.views?.[this.viewId]?.filters,
};
return _issueFilters;
}
return null;
}
handleUserFilter = () => {};
computedFilter = (filters: any, filteredParams: any) => { computedFilter = (filters: any, filteredParams: any) => {
const computedFilters: any = {}; const computedFilters: any = {};
Object.keys(filters).map((key) => { Object.keys(filters).map((key) => {
@ -322,53 +415,51 @@ class IssueFilterStore implements IIssueFilterStore {
this.setViewId(_viewId); this.setViewId(_viewId);
this.setIssueView(_issueView); this.setIssueView(_issueView);
if (_workspaceId) { const _layout = this.userFilters?.display_filters?.layout;
if (!_projectId)
this.issueFilters = {
...this.issueFilters,
[_workspaceId]: {
...this.issueFilters[_workspaceId],
my_issue_properties: {
...this.issueFilters[_workspaceId]?.my_issue_properties,
renderLayout: _issueLayout,
},
},
};
else
this.issueFilters = {
...this.issueFilters,
[_workspaceId]: {
...this.issueFilters[_workspaceId],
project_issue_properties: {
...this.issueFilters[_workspaceId]?.project_issue_properties,
[_projectId]: {
...this.issueFilters[_workspaceId]?.project_issue_properties?.[_projectId],
renderLayout: _issueLayout,
},
},
},
};
}
let filteredRouteParams: any = { let filteredRouteParams: any = {
priority: [] || undefined, priority: this.userFilters?.filters?.priority || undefined,
state: [] || undefined, state_group: this.userFilters?.filters?.state_group || undefined,
assignees: [] || undefined, // ['user_id', 'user_id'] state: this.userFilters?.filters?.state || undefined,
created_by: [] || undefined, // ['user_id', 'user_id'] assignees: this.userFilters?.filters?.assignees || undefined,
labels: [] || undefined, // ['label_id', 'label_id'] created_by: this.userFilters?.filters?.created_by || undefined,
start_date: [] || undefined, // ['yyyy-mm-dd:after/before', 'yyyy-mm-dd:after/before'] labels: this.userFilters?.filters?.labels || undefined,
target_date: [] || undefined, // [yyyy-mm-dd:after, yyyy-mm-dd:before] start_date: this.userFilters?.filters?.start_date || undefined,
type: "" || undefined, // 'active' (started, un_started) || 'backlog' || 'null' (all_the_issues) target_date: this.userFilters?.filters?.target_date || undefined,
group_by: "state", // TIssueGroupByOptions type: this.userFilters?.display_filters?.type || undefined,
order_by: "-created_at", // TIssueOrderByOptions group_by: this.userFilters?.display_filters?.group_by || "state",
sub_issue: true, // true for all other views except spreadsheet order_by: this.userFilters?.display_filters?.order_by || "-created_at",
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,
}; };
let filteredParams: any = {}; console.log("filteredRouteParams", filteredRouteParams);
if (_issueLayout === "list") // start date and target date we have to construct the format here
let filteredParams: any = {};
if (_layout === "list")
filteredParams = [ filteredParams = [
"priority", "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")
filteredParams = [
"priority",
"state_group",
"state", "state",
"assignees", "assignees",
"created_by", "created_by",
@ -380,7 +471,33 @@ class IssueFilterStore implements IIssueFilterStore {
"order_by", "order_by",
"sub_issue", "sub_issue",
]; ];
if (_issueLayout === "kanban") if (_layout === "calendar")
filteredParams = [
"priority",
"state_group",
"state",
"assignees",
"created_by",
"labels",
"start_date",
"target_date",
"type",
"calendar_date_range",
];
if (_layout === "spreadsheet")
filteredParams = [
"priority",
"state_group",
"state",
"assignees",
"created_by",
"labels",
"start_date",
"target_date",
"type",
"sub_issues",
];
if (_layout === "gantt")
filteredParams = [ filteredParams = [
"priority", "priority",
"state", "state",
@ -389,49 +506,17 @@ class IssueFilterStore implements IIssueFilterStore {
"labels", "labels",
"start_date", "start_date",
"target_date", "target_date",
"type",
"group_by",
"order_by", "order_by",
"sub_issue",
];
if (_issueLayout === "calendar")
filteredParams = [
"priority",
"state",
"assignees",
"created_by",
"labels",
"start_date",
"target_date",
"type", "type",
];
if (_issueLayout === "spreadsheet")
filteredParams = [
"priority",
"state",
"assignees",
"created_by",
"labels",
"start_date",
"target_date",
"type",
];
if (_issueLayout === "gantt")
filteredParams = [
"priority",
"state",
"assignees",
"created_by",
"labels",
"start_date",
"target_date",
"type",
"order_by",
"sub_issue_id", "sub_issue_id",
"start_target_date",
]; ];
filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams); filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
// remove few attributes from the object when we are in workspace issues
console.log("filteredRouteParams", filteredRouteParams);
return filteredRouteParams; return filteredRouteParams;
}; };
@ -470,7 +555,6 @@ class IssueFilterStore implements IIssueFilterStore {
return error; return error;
} }
}; };
getWorkspaceMyIssuesLabels = async (workspaceId: string) => { getWorkspaceMyIssuesLabels = async (workspaceId: string) => {
try { try {
this.loader = true; this.loader = true;
@ -523,40 +607,48 @@ class IssueFilterStore implements IIssueFilterStore {
my_issue_properties: { my_issue_properties: {
...this?.issueFilters?.[workspaceId]?.my_issue_properties, ...this?.issueFilters?.[workspaceId]?.my_issue_properties,
filters: { filters: {
priority: undefined, priority: issuesFiltersResponse?.view_props?.filters?.priority ?? null,
state: undefined, state: issuesFiltersResponse?.view_props?.filters?.state ?? null,
state_group: undefined, state_group: issuesFiltersResponse?.view_props?.filters?.state_group ?? null,
assignees: undefined, assignees: issuesFiltersResponse?.view_props?.filters?.assignees ?? null,
created_by: undefined, created_by: issuesFiltersResponse?.view_props?.filters?.created_by ?? null,
labels: undefined, labels: issuesFiltersResponse?.view_props?.filters?.labels ?? null,
start_date: undefined, start_date: issuesFiltersResponse?.view_props?.filters?.start_date ?? null,
target_date: undefined, target_date: issuesFiltersResponse?.view_props?.filters?.target_date ?? null,
subscriber: undefined, subscriber: issuesFiltersResponse?.view_props?.filters?.subscriber ?? null,
}, },
display_filters: { display_filters: {
group_by: undefined, group_by: issuesFiltersResponse?.view_props?.display_filters?.group_by ?? null,
order_by: undefined, order_by: issuesFiltersResponse?.view_props?.display_filters?.order_by ?? null,
type: undefined, type: issuesFiltersResponse?.view_props?.display_filters?.type ?? null,
sub_issue: undefined, sub_issue: issuesFiltersResponse?.view_props?.display_filters?.sub_issue ?? false,
show_empty_groups: undefined, show_empty_groups:
layout: undefined, issuesFiltersResponse?.view_props?.display_filters?.show_empty_groups ?? false,
calendar_date_range: undefined, layout: issuesFiltersResponse?.view_props?.display_filters?.layout ?? "list",
start_target_date: undefined, 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: { display_properties: {
assignee: false, assignee: issuesFiltersResponse?.view_props?.display_properties?.assignee ?? false,
attachment_count: false, attachment_count:
created_on: false, issuesFiltersResponse?.view_props?.display_properties?.attachment_count ?? false,
due_date: false, created_on:
estimate: false, issuesFiltersResponse?.view_props?.display_properties?.created_on ?? false,
key: false, due_date: issuesFiltersResponse?.view_props?.display_properties?.due_date ?? false,
labels: false, estimate: issuesFiltersResponse?.view_props?.display_properties?.estimate ?? false,
link: false, key: issuesFiltersResponse?.view_props?.display_properties?.key ?? false,
priority: false, labels: issuesFiltersResponse?.view_props?.display_properties?.labels ?? false,
start_date: false, link: issuesFiltersResponse?.view_props?.display_properties?.link ?? false,
state: false, priority: issuesFiltersResponse?.view_props?.display_properties?.priority ?? false,
sub_issue_count: false, start_date:
updated_on: false, 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,
}, },
}, },
}, },
@ -652,7 +744,6 @@ class IssueFilterStore implements IIssueFilterStore {
return error; return error;
} }
}; };
getProjectLevelLabels = async (workspaceId: string, projectId: string) => { getProjectLevelLabels = async (workspaceId: string, projectId: string) => {
try { try {
this.loader = true; this.loader = true;
@ -692,7 +783,6 @@ class IssueFilterStore implements IIssueFilterStore {
return error; return error;
} }
}; };
getProjectLevelMembers = async (workspaceId: string, projectId: string) => { getProjectLevelMembers = async (workspaceId: string, projectId: string) => {
try { try {
this.loader = true; this.loader = true;
@ -755,7 +845,7 @@ class IssueFilterStore implements IIssueFilterStore {
...this?.issueFilters[workspaceId]?.project_issue_properties, ...this?.issueFilters[workspaceId]?.project_issue_properties,
[projectId]: { [projectId]: {
...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId], ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId],
display_properties: issuesDisplayPropertiesResponse, display_properties: issuesDisplayPropertiesResponse?.properties,
}, },
}, },
}, },
@ -822,25 +912,35 @@ class IssueFilterStore implements IIssueFilterStore {
this.loader = true; this.loader = true;
this.error = null; this.error = null;
const workspaceId = "1"; const issuesDisplayFiltersResponse = await this.projectService.projectMemberMe(
workspaceId,
projectId
);
const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId); if (issuesDisplayFiltersResponse) {
const _filters = { ...issuesDisplayFiltersResponse?.view_props?.filters };
const _displayFilters = { ...issuesDisplayFiltersResponse?.view_props?.display_filters };
if (issuesFiltersResponse) { const _issuesDisplayFiltersResponse: any = {
// const _issuesFiltersResponse = this.issueFilters; ...this.issueFilters,
// const _issuesFiltersResponse: any = { [workspaceId]: {
// ...this.issues, ...this?.issueFilters[workspaceId],
// [workspaceId]: { project_issue_properties: {
// ...this?.issues[workspaceId], ...this?.issueFilters[workspaceId]?.project_issue_properties,
// my_issues: { [projectId]: {
// ...this?.issues[workspaceId]?.my_issues, ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId],
// [_layout as string]: issuesResponse, issues: {
// }, ...this?.issueFilters[workspaceId]?.project_issue_properties?.[projectId]?.issues,
// }, filters: _filters,
// }; display_filters: _displayFilters,
},
},
},
},
};
runInAction(() => { runInAction(() => {
// this.issueFilters = _issuesFiltersResponse; this.issueFilters = _issuesDisplayFiltersResponse;
this.loader = false; this.loader = false;
this.error = null; this.error = null;
}); });
@ -901,28 +1001,12 @@ class IssueFilterStore implements IIssueFilterStore {
await this.getProjectLevelLabels(workspaceId, projectId); await this.getProjectLevelLabels(workspaceId, projectId);
await this.getProjectLevelMembers(workspaceId, projectId); await this.getProjectLevelMembers(workspaceId, projectId);
await this.getProjectDisplayProperties(workspaceId, projectId); await this.getProjectDisplayProperties(workspaceId, projectId);
await this.getProjectDisplayFilters(workspaceId, projectId);
const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId); runInAction(() => {
this.loader = false;
if (issuesFiltersResponse) { this.error = null;
// const _issuesFiltersResponse = this.issueFilters; });
// const _issuesFiltersResponse: any = {
// ...this.issues,
// [workspaceId]: {
// ...this?.issues[workspaceId],
// my_issues: {
// ...this?.issues[workspaceId]?.my_issues,
// [_layout as string]: issuesResponse,
// },
// },
// };
runInAction(() => {
// this.issueFilters = _issuesFiltersResponse;
this.loader = false;
this.error = null;
});
}
// return issuesResponse; // return issuesResponse;
} catch (error) { } catch (error) {
@ -937,11 +1021,6 @@ class IssueFilterStore implements IIssueFilterStore {
this.loader = true; this.loader = true;
this.error = null; this.error = null;
await this.getProjectLevelStates(workspaceId, projectId);
await this.getProjectLevelLabels(workspaceId, projectId);
await this.getProjectLevelMembers(workspaceId, projectId);
// await this.getProjectDisplayProperties(workspaceId, projectId);
const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId); const issuesFiltersResponse = await this.workspaceService.workspaceMemberMe(workspaceId);
if (issuesFiltersResponse) { if (issuesFiltersResponse) {