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
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
export const FilterExtraOptions = observer(() => {
const store: RootStore = useMobxStore();
@ -18,6 +20,13 @@ export const FilterExtraOptions = observer(() => {
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 (
<div>
<FilterHeader
@ -29,23 +38,26 @@ export const FilterExtraOptions = observer(() => {
<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
}
onClick={() =>
handleExtraOptions(
_extraProperties?.key,
issueFilterStore?.userFilters?.display_filters?.[_extraProperties?.key]
)
}
title={_extraProperties.title}
/>
))}
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}
/>
)
)}
</div>
)}
</div>

View File

@ -5,41 +5,78 @@ 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";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
// const store: RootStore = useMobxStore();
// const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
export const DisplayFiltersSelection = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore } = store;
export const DisplayFiltersSelection = () => (
<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">
{/* display properties */}
<div className="pb-2 px-2 border-b border-custom-border-200">
<FilterDisplayProperties />
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="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container
</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 className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
{/* display properties */}
{handleDisplayPropertiesSectionVisibility && (
<div className="pb-2 px-2 border-b border-custom-border-200">
<FilterDisplayProperties />
</div>
)}
{/* group by */}
{handleDisplayFilterSectionVisibility("group_by") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterGroupBy />
</div>
)}
{/* order by */}
{handleDisplayFilterSectionVisibility("order_by") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterOrderBy />
</div>
)}
{/* issue type */}
{handleDisplayFilterSectionVisibility("issue_type") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterIssueType />
</div>
)}
{/* Options */}
{handleExtraOptionsSectionVisibility && (
<div className="pt-1 px-2">
<FilterExtraOptions />
</div>
)}
</div>
</div>
</div>
);
);
});

View File

@ -8,53 +8,86 @@ import { FilterCreatedBy } from "./created-by";
import { FilterLabels } from "./labels";
import { FilterStartDate } from "./start-date";
import { FilterTargetDate } from "./target-date";
// // mobx react lite
// import { observer } from "mobx-react-lite";
// // mobx store
// import { useMobxStore } from "lib/mobx/store-provider";
// import { RootStore } from "store/root";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
// default data
import { issueFilterVisibilityData } from "store/issue-views/issue_data";
// const store: RootStore = useMobxStore();
// const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
export const FilterSelection = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore } = store;
export const FilterSelection = () => (
<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 */}
<div className="pb-1 px-2 border-b border-custom-border-200">
<FilterPriority />
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="flex-shrink-0 p-2 text-sm border-b border-custom-border-200">
Search container
</div>
{/* state group */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterStateGroup />
</div>
{/* state */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterState />
</div>
{/* assignees */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterAssignees />
</div>
{/* created_by */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterCreatedBy />
</div>
{/* labels */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterLabels />
</div>
{/* start_date */}
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterStartDate />
</div>
{/* due_date */}
<div className="pt-1 px-2">
<FilterTargetDate />
<div className="w-full h-full overflow-hidden overflow-y-auto relative pb-2">
{/* priority */}
{handleFilterSectionVisibility("priority") && (
<div className="pb-1 px-2 border-b border-custom-border-200">
<FilterPriority />
</div>
)}
{/* state group */}
{handleFilterSectionVisibility("state_group") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterStateGroup />
</div>
)}
{/* state */}
{handleFilterSectionVisibility("state") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterState />
</div>
)}
{/* assignees */}
{handleFilterSectionVisibility("assignees") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterAssignees />
</div>
)}
{/* created_by */}
{handleFilterSectionVisibility("created_by") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterCreatedBy />
</div>
)}
{/* labels */}
{handleFilterSectionVisibility("labels") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterLabels />
</div>
)}
{/* start_date */}
{handleFilterSectionVisibility("start_date") && (
<div className="py-1 px-2 border-b border-custom-border-200">
<FilterStartDate />
</div>
)}
{/* due_date */}
{handleFilterSectionVisibility("due_date") && (
<div className="pt-1 px-2">
<FilterTargetDate />
</div>
)}
</div>
</div>
</div>
);
);
});

View File

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

View File

@ -5,8 +5,10 @@ import { Columns, Grid3x3, Calendar, GanttChart, List } from "lucide-react";
import { observer } from "mobx-react-lite";
// mobx store
import { RootStore } from "store/root";
import { TIssueLayouts } from "store/issue-views/issue_filters";
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(() => {
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) => {
issueFilterStore.handleUserFilter("display_filters", "layout", _layoutKey);
};
console.log("----");
console.log("my_user_id", issueFilterStore.myUserId);
console.log("workspace_id", issueFilterStore.workspaceId);
console.log("project_id", issueFilterStore.projectId);
console.log("module_id", issueFilterStore.moduleId);
@ -54,31 +63,38 @@ export const LayoutSelection = observer(() => {
console.log("issue_view", issueFilterStore.issueView);
console.log("issue_layout", issueFilterStore.issueLayout);
console.log("user_filters", issueFilterStore.userFilters);
console.log("issues", issueStore.issues);
console.log("issues", issueStore.getIssues);
console.log("----");
return (
<div className="relative flex items-center p-1 rounded gap-1 bg-custom-background-80">
{layoutSelectionFilters.map((_layout) => (
<div
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 ${
issueFilterStore?.issueLayout == _layout?.key
? `bg-custom-background-100 shadow shadow-gray-200`
: ``
}}`}
onClick={() => handleLayoutSelection(_layout?.key)}
>
<_layout.icon
size={14}
strokeWidth={2}
className={`${
issueFilterStore?.issueLayout == _layout?.key
? `text-custom-text-100`
: `text-custom-text-100 group-hover:text-custom-text-200`
}`}
/>
</div>
))}
{layoutSelectionFilters.map(
(_layout) =>
handleLayoutSectionVisibility(_layout?.key) && (
<div
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 ${
issueFilterStore?.issueLayout == _layout?.key
? `bg-custom-background-100 shadow shadow-gray-200`
: ``
}}`}
onClick={() => handleLayoutSelection(_layout?.key)}
>
<_layout.icon
size={14}
strokeWidth={2}
className={`${
issueFilterStore?.issueLayout == _layout?.key
? `text-custom-text-100`
: `text-custom-text-100 group-hover:text-custom-text-200`
}`}
/>
</div>
)
)}
</div>
);
});

View File

@ -78,8 +78,73 @@ export const displayProperties: { 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: "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: ["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"],
},
},
},
};