chore: filter, layout, display filters, extra filters and display properties render validation

This commit is contained in:
gurusainath 2023-09-14 16:03:35 +05:30
parent f579712092
commit c67f08fca4
6 changed files with 290 additions and 122 deletions

View File

@ -7,6 +7,8 @@ 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";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
export const FilterExtraOptions = observer(() => { export const FilterExtraOptions = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
@ -18,6 +20,13 @@ export const FilterExtraOptions = observer(() => {
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" : "others"
]?.extra_options?.[issueFilterStore?.issueLayout].values?.includes(key);
return ( return (
<div> <div>
<FilterHeader <FilterHeader
@ -29,7 +38,9 @@ export const FilterExtraOptions = observer(() => {
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
{issueFilterStore?.issueRenderFilters?.extra_properties && {issueFilterStore?.issueRenderFilters?.extra_properties &&
issueFilterStore?.issueRenderFilters?.extra_properties.length > 0 && issueFilterStore?.issueRenderFilters?.extra_properties.length > 0 &&
issueFilterStore?.issueRenderFilters?.extra_properties.map((_extraProperties) => ( issueFilterStore?.issueRenderFilters?.extra_properties.map(
(_extraProperties) =>
handleExtraOptionsSectionVisibility(_extraProperties?.key) && (
<FilterOption <FilterOption
key={_extraProperties?.key} key={_extraProperties?.key}
isChecked={ isChecked={
@ -45,7 +56,8 @@ export const FilterExtraOptions = observer(() => {
} }
title={_extraProperties.title} title={_extraProperties.title}
/> />
))} )
)}
</div> </div>
)} )}
</div> </div>

View File

@ -5,41 +5,78 @@ import { FilterGroupBy } from "./group-by";
import { FilterOrderBy } from "./order-by"; import { FilterOrderBy } from "./order-by";
import { FilterIssueType } from "./issue-type"; import { FilterIssueType } from "./issue-type";
import { FilterExtraOptions } from "./extra-options"; import { FilterExtraOptions } from "./extra-options";
// // 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";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
// const store: RootStore = useMobxStore(); export const DisplayFiltersSelection = observer(() => {
// const { issueFilters: issueFilterStore, issueView: issueViewStore } = store; const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore } = store;
export const DisplayFiltersSelection = () => ( const handleDisplayPropertiesSectionVisibility =
issueFilterStore?.issueView &&
issueFilterStore?.issueLayout &&
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"]
?.display_properties?.[issueFilterStore?.issueLayout];
const handleDisplayFilterSectionVisibility = (section_key: string) =>
issueFilterStore?.issueView &&
issueFilterStore?.issueLayout &&
issueFilterVisibilityData[
issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"
]?.display_filters?.[issueFilterStore?.issueLayout].includes(section_key);
const handleExtraOptionsSectionVisibility =
issueFilterStore?.issueView &&
issueFilterStore?.issueLayout &&
issueFilterVisibilityData[issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"]
?.extra_options?.[issueFilterStore?.issueLayout].access;
return (
<div className="w-full h-full overflow-hidden select-none relative flex flex-col"> <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"> <div className="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container Search container
</div> </div>
<div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2"> <div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
{/* display properties */} {/* display properties */}
{handleDisplayPropertiesSectionVisibility && (
<div className="pb-2 px-2 border-b border-custom-border-200"> <div className="pb-2 px-2 border-b border-custom-border-200">
<FilterDisplayProperties /> <FilterDisplayProperties />
</div> </div>
)}
{/* group by */} {/* group by */}
{handleDisplayFilterSectionVisibility("group_by") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterGroupBy /> <FilterGroupBy />
</div> </div>
)}
{/* order by */} {/* order by */}
{handleDisplayFilterSectionVisibility("order_by") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterOrderBy /> <FilterOrderBy />
</div> </div>
)}
{/* issue type */} {/* issue type */}
{handleDisplayFilterSectionVisibility("issue_type") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterIssueType /> <FilterIssueType />
</div> </div>
)}
{/* Options */} {/* Options */}
{handleExtraOptionsSectionVisibility && (
<div className="pt-1 px-2"> <div className="pt-1 px-2">
<FilterExtraOptions /> <FilterExtraOptions />
</div> </div>
)}
</div> </div>
</div> </div>
); );
});

View File

@ -8,53 +8,86 @@ 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";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
// const store: RootStore = useMobxStore(); export const FilterSelection = observer(() => {
// const { issueFilters: issueFilterStore, issueView: issueViewStore } = store; const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore } = store;
export const FilterSelection = () => ( const handleFilterSectionVisibility = (section_key: string) =>
issueFilterStore?.issueView &&
issueFilterVisibilityData[
issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"
].filters.includes(section_key);
return (
<div className="w-full h-full overflow-hidden select-none relative flex flex-col"> <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"> <div className="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container Search container
</div> </div>
<div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2"> <div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
{/* priority */} {/* priority */}
{handleFilterSectionVisibility("priority") && (
<div className="pb-1 px-2 border-b border-custom-border-200"> <div className="pb-1 px-2 border-b border-custom-border-200">
<FilterPriority /> <FilterPriority />
</div> </div>
)}
{/* state group */} {/* state group */}
{handleFilterSectionVisibility("state_group") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterStateGroup /> <FilterStateGroup />
</div> </div>
)}
{/* state */} {/* state */}
{handleFilterSectionVisibility("state") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterState /> <FilterState />
</div> </div>
)}
{/* assignees */} {/* assignees */}
{handleFilterSectionVisibility("assignees") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterAssignees /> <FilterAssignees />
</div> </div>
)}
{/* created_by */} {/* created_by */}
{handleFilterSectionVisibility("created_by") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterCreatedBy /> <FilterCreatedBy />
</div> </div>
)}
{/* labels */} {/* labels */}
{handleFilterSectionVisibility("labels") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterLabels /> <FilterLabels />
</div> </div>
)}
{/* start_date */} {/* start_date */}
{handleFilterSectionVisibility("start_date") && (
<div className="py-1 px-2 border-b border-custom-border-200"> <div className="py-1 px-2 border-b border-custom-border-200">
<FilterStartDate /> <FilterStartDate />
</div> </div>
)}
{/* due_date */} {/* due_date */}
{handleFilterSectionVisibility("due_date") && (
<div className="pt-1 px-2"> <div className="pt-1 px-2">
<FilterTargetDate /> <FilterTargetDate />
</div> </div>
)}
</div> </div>
</div> </div>
); );
});

View File

@ -32,18 +32,23 @@ export const FilterLabels = observer(() => {
issueFilterStore.handleUserFilter("filters", key, _value); issueFilterStore.handleUserFilter("filters", key, _value);
}; };
const handleLabels =
issueFilterStore.issueView && issueFilterStore.issueView === "my_issues"
? issueFilterStore?.workspaceLabels
: issueFilterStore?.projectLabels;
return ( return (
<div> <div>
<FilterHeader <FilterHeader
title={`Labels (${issueFilterStore?.projectLabels?.length || 0})`} title={`Labels (${(handleLabels && handleLabels?.length) || 0})`}
isPreviewEnabled={previewEnabled} isPreviewEnabled={previewEnabled}
handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)} handleIsPreviewEnabled={() => setPreviewEnabled(!previewEnabled)}
/> />
{previewEnabled && ( {previewEnabled && (
<div className="space-y-[2px] pt-1"> <div className="space-y-[2px] pt-1">
{issueFilterStore?.projectLabels && {handleLabels &&
issueFilterStore?.projectLabels.length > 0 && handleLabels.length > 0 &&
issueFilterStore?.projectLabels.map((_label) => ( handleLabels.map((_label) => (
<FilterOption <FilterOption
key={_label?.id} key={_label?.id}
isChecked={ isChecked={

View File

@ -5,8 +5,10 @@ import { Columns, Grid3x3, Calendar, GanttChart, List } from "lucide-react";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// mobx store // mobx store
import { RootStore } from "store/root"; import { RootStore } from "store/root";
import { TIssueLayouts } from "store/issue-views/issue_filters";
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
// types and default data
import { TIssueLayouts } from "store/issue-views/issue_filters";
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
export const LayoutSelection = observer(() => { export const LayoutSelection = observer(() => {
const store: RootStore = useMobxStore(); const store: RootStore = useMobxStore();
@ -40,11 +42,18 @@ export const LayoutSelection = observer(() => {
}, },
]; ];
const handleLayoutSectionVisibility = (layout_key: string) =>
issueFilterStore?.issueView &&
issueFilterVisibilityData[
issueFilterStore?.issueView === "my_issues" ? "my_issues" : "others"
].layout.includes(layout_key);
const handleLayoutSelection = (_layoutKey: string) => { const handleLayoutSelection = (_layoutKey: string) => {
issueFilterStore.handleUserFilter("display_filters", "layout", _layoutKey); issueFilterStore.handleUserFilter("display_filters", "layout", _layoutKey);
}; };
console.log("----"); console.log("----");
console.log("my_user_id", issueFilterStore.myUserId);
console.log("workspace_id", issueFilterStore.workspaceId); console.log("workspace_id", issueFilterStore.workspaceId);
console.log("project_id", issueFilterStore.projectId); console.log("project_id", issueFilterStore.projectId);
console.log("module_id", issueFilterStore.moduleId); console.log("module_id", issueFilterStore.moduleId);
@ -54,11 +63,17 @@ export const LayoutSelection = observer(() => {
console.log("issue_view", issueFilterStore.issueView); console.log("issue_view", issueFilterStore.issueView);
console.log("issue_layout", issueFilterStore.issueLayout); console.log("issue_layout", issueFilterStore.issueLayout);
console.log("user_filters", issueFilterStore.userFilters);
console.log("issues", issueStore.issues);
console.log("issues", issueStore.getIssues);
console.log("----"); console.log("----");
return ( return (
<div className="relative flex items-center p-1 rounded gap-1 bg-custom-background-80"> <div className="relative flex items-center p-1 rounded gap-1 bg-custom-background-80">
{layoutSelectionFilters.map((_layout) => ( {layoutSelectionFilters.map(
(_layout) =>
handleLayoutSectionVisibility(_layout?.key) && (
<div <div
key={_layout?.key} key={_layout?.key}
className={`w-[28px] h-[22px] 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 ${
@ -78,7 +93,8 @@ export const LayoutSelection = observer(() => {
}`} }`}
/> />
</div> </div>
))} )
)}
</div> </div>
); );
}); });

View File

@ -78,8 +78,73 @@ export const displayProperties: { key: string; title: string }[] = [
]; ];
export const extraProperties: { key: string; title: string }[] = [ export const extraProperties: { key: string; title: string }[] = [
{ key: "sub_issues", title: "Show sub-issues" }, // in spreadsheet its always false { 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: "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: "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 { key: "start_target_date", title: "Start target Date" }, // gantt always be true
]; ];
export const issueFilterVisibilityData: any = {
my_issues: {
layout: ["list", "kanban"],
filters: ["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"],
},
},
},
others: {
layout: ["list", "kanban", "calendar", "spreadsheet", "gantt"],
filters: ["priority", "state", "assignees", "created_by", "labels", "start_date", "due_date"],
display_properties: {
list: true,
kanban: true,
calendar: true,
spreadsheet: true,
gantt: 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: ["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: {
access: true,
values: ["sub_issue"],
},
},
},
};