chore: created filters and updated the issue filters, display_filter and display_properties in mobx and components

This commit is contained in:
gurusainath 2023-09-12 19:15:36 +05:30
parent c0e3c81a9b
commit 0445c610bf
19 changed files with 2004 additions and 163 deletions

View File

@ -0,0 +1,15 @@
import React from "react";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
export const DisplayPropertiesSelection = () => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
return (
<div>
<div>Filter Selection</div>
</div>
);
};

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 FilterAssignees = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Assignees</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((priority) => (
<div
key={priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 FilterCreatedBy = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Created By</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((priority) => (
<div
key={priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,57 @@
import React from "react";
// components
import { FilterPriority } from "./priority";
import { FilterState } from "./state";
import { FilterStateGroup } from "./state-group";
import { FilterAssignees } from "./assignees";
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";
export const FilterSelection = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
return (
<div className="container w-full h-full overflow-y-auto mx-auto max-w-[400px] relative select-none">
{/* priority */}
<div className="py-2 border-b border-custom-border-100">
<FilterPriority />
</div>
{/* state group */}
<div className="py-2 border-b border-custom-border-100">
<FilterStateGroup />
</div>
{/* state */}
<div className="py-2 border-b border-custom-border-100">
<FilterState />
</div>
{/* assignees */}
<div className="py-2 border-b border-custom-border-100">
<FilterAssignees />
</div>
{/* created_by */}
<div className="py-2 border-b border-custom-border-100">
<FilterCreatedBy />
</div>
{/* labels */}
<div className="py-2 border-b border-custom-border-100">
<FilterLabels />
</div>
{/* start_date */}
<div className="py-2 border-b border-custom-border-100">
<FilterStartDate />
</div>
{/* due_date */}
<div className="py-2">
<FilterTargetDate />
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 FilterLabels = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Labels</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((priority) => (
<div
key={priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircle,
SignalHigh,
SignalMedium,
SignalLow,
Ban,
Check,
ChevronDown,
ChevronUp,
} from "lucide-react";
// mobx react lite
import { observer } from "mobx-react-lite";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircle size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHigh size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMedium size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLow size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<Ban size={14} strokeWidth={2} />
</div>
);
};
export const FilterPriority = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Priority</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((_priority) => (
<div
key={_priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={_priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{_priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
{false && <Check size={14} />}
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 FilterStartDate = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Start Date</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((priority) => (
<div
key={priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 StateGroupIcons = ({ stateGroup }: { stateGroup: string }) => {
if (stateGroup === "cancelled")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (stateGroup === "completed")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (stateGroup === "started")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (stateGroup === "unstarted")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
export const FilterStateGroup = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">State Group</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.state_group &&
issueFilterStore?.issueRenderFilters?.state_group.length > 0 &&
issueFilterStore?.issueRenderFilters?.state_group.map((_stateGroup) => (
<div
key={_stateGroup?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<StateGroupIcons stateGroup={_stateGroup.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{_stateGroup.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,51 @@
import React from "react";
// lucide icons
import { CheckIcon, ChevronDown, ChevronUp } from "lucide-react";
// components
import { StateGroupIcons } from "./state-group";
// 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 FilterState = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">State</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.projectStates &&
issueFilterStore?.projectStates.length > 0 &&
issueFilterStore?.projectStates.map((_state) => (
<div
key={_state?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<StateGroupIcons stateGroup={_state.group} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{_state?.name}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,90 @@
import React from "react";
// lucide icons
import {
AlertCircleIcon,
SignalHighIcon,
SignalMediumIcon,
SignalLowIcon,
BanIcon,
CheckIcon,
ChevronDown,
ChevronUp,
} from "lucide-react";
// 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 FilterTargetDate = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const [allFiltersToggle, setAllFiltersToggle] = React.useState(false);
const PriorityIcons = ({ priority }: { priority: string }) => {
if (priority === "urgent")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-red-500 bg-red-500 text-white flex justify-center items-center">
<AlertCircleIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "high")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-red-500 flex justify-center items-center pl-1">
<SignalHighIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "medium")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-orange-500 flex justify-center items-center pl-1">
<SignalMediumIcon size={14} strokeWidth={2} />
</div>
);
if (priority === "low")
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-green-500 flex justify-center items-center pl-1">
<SignalLowIcon size={14} strokeWidth={2} />
</div>
);
return (
<div className="flex-shrink-0 rounded-sm overflow-hidden w-[20px] h-[20px] border border-custom-border-300 text-gray-500 flex justify-center items-center">
<BanIcon size={14} strokeWidth={2} />
</div>
);
};
return (
<div>
<div className="flex items-center justify-between gap-2 p-[6px] pb-2">
<div className="text-gray-500 text-sm text-custom-text-300 font-medium">Target Date</div>
<div
className="flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm transition-all hover:bg-custom-border-100 cursor-pointer"
onClick={() => setAllFiltersToggle(!allFiltersToggle)}
>
{allFiltersToggle ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
</div>
</div>
<div className="space-y-[2px]">
{issueFilterStore?.issueRenderFilters?.priority &&
issueFilterStore?.issueRenderFilters?.priority.length > 0 &&
issueFilterStore?.issueRenderFilters?.priority.map((priority) => (
<div
key={priority?.key}
className={`flex items-center gap-2 cursor-pointer rounded-sm p-[6px] py-[5px] transition-all ${
false ? `bg-custom-border-100` : `hover:bg-custom-border-100`
}`}
>
<PriorityIcons priority={priority.key} />
<div className="hyphens-auto line-clamp-2 text-custom-text-200 text-sm w-full">
{priority.title}
</div>
<div className="ml-auto flex-shrink-0 w-[20px] h-[20px] flex justify-center items-center rounded-sm text-custom-text-200">
<CheckIcon size={14} />
</div>
</div>
))}
</div>
</div>
);
});

View File

@ -0,0 +1,115 @@
import React from "react";
// lucide icons
import { Columns, Grid3x3, Calendar, GanttChart, List } from "lucide-react";
// mobx react lite
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";
export const LayoutSelection = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
const layoutSelectionFilters: { key: TIssueLayouts; title: string; icon: any }[] = [
{
key: "list",
title: "List",
icon: List,
},
{
key: "kanban",
title: "Kanban",
icon: Grid3x3,
},
{
key: "calendar",
title: "Calendar",
icon: Calendar,
},
{
key: "spreadsheet",
title: "Spreadsheet",
icon: Columns,
},
{
key: "gantt",
title: "Gantt",
icon: GanttChart,
},
];
const handleLayoutSelection = (layout: TIssueLayouts) => {
if (!issueFilterStore.workspaceId) return;
if (issueFilterStore.issueView === "my_issues") {
issueStore.getMyIssuesAsync(issueFilterStore.workspaceId, issueFilterStore.issueView, layout);
return;
}
if (!issueFilterStore.projectId) return;
if (issueFilterStore.issueView === "issues") {
issueStore.getProjectIssuesAsync(
issueFilterStore.workspaceId,
issueFilterStore.projectId,
issueFilterStore.issueView,
layout
);
return;
}
if (issueFilterStore.issueView === "modules" && issueFilterStore.moduleId) {
issueStore.getIssuesForModulesAsync(
issueFilterStore.workspaceId,
issueFilterStore.projectId,
issueFilterStore.moduleId,
issueFilterStore.issueView,
layout
);
return;
}
if (issueFilterStore.issueView === "cycles" && issueFilterStore.cycleId) {
issueStore.getIssuesForCyclesAsync(
issueFilterStore.workspaceId,
issueFilterStore.projectId,
issueFilterStore.cycleId,
issueFilterStore.issueView,
layout
);
return;
}
if (issueFilterStore.issueView === "views" && issueFilterStore.viewId) {
issueStore.getIssuesForViewsAsync(
issueFilterStore.workspaceId,
issueFilterStore.projectId,
issueFilterStore.viewId,
issueFilterStore.issueView,
layout
);
return;
}
};
return (
<div className="relative flex items-center p-1 rounded bg-gray-100 gap-[1px]">
{layoutSelectionFilters.map((_layout) => (
<div
key={_layout?.key}
className={`w-[32px] h-[26px] rounded flex justify-center items-center cursor-pointer transition-all hover:bg-white overflow-hidden group ${
issueFilterStore?.issueLayout == _layout?.key ? `bg-white shadow shadow-gray-200` : ``
}}`}
onClick={() => handleLayoutSelection(_layout?.key)}
>
<_layout.icon
size={15}
strokeWidth={2}
className={`${
issueFilterStore?.issueLayout == _layout?.key
? `text-gray-900`
: `text-gray-700 group-hover:text-gray-900`
}`}
/>
</div>
))}
</div>
);
});

View File

@ -12,7 +12,7 @@ import { RootStore } from "store/root";
export const IssueKanBanViewRoot = observer(() => {
const store: RootStore = useMobxStore();
const { issueView: issueViewStore } = store;
const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
const onDragEnd = (result: any) => {
if (!result) return;
@ -28,9 +28,31 @@ export const IssueKanBanViewRoot = observer(() => {
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 (
<div className="relative w-full h-full">
{issueViewStore.loader && issueViewStore?.issues === null ? (
{issueViewStore.loader || issueViewStore?.getIssues === null ? (
<div>Loading...</div>
) : (
<>

View File

@ -0,0 +1,14 @@
import React from "react";
// mobx react lite
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";
export const IssuesRoot = observer(() => {
const store: RootStore = useMobxStore();
const { issueFilters: issueFilterStore, issueView: issueStore } = store;
return <div>issue root</div>;
});

View File

@ -3,6 +3,8 @@ import React from "react";
import useSWR from "swr";
// components
import { IssueKanBanViewRoot } from "components/issue-layouts/kanban";
import { LayoutSelection } from "components/issue-layouts/header/layout-filter";
import { FilterSelection } from "components/issue-layouts/header/filters";
// mobx store
import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root";
@ -15,21 +17,20 @@ const KanBanViewRoot = () => {
const viewSlug: string = "1f66a767-00d1-422c-8f8f-6925282b7249";
const store: RootStore = useMobxStore();
const { issueView: issueViewStore } = store;
const { issueFilters: issueFilterStore, issueView: issueViewStore } = store;
React.useEffect(() => {
const init = async () => {
// my issues under a workspace
console.log("started--->");
// console.log("started--->");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "list");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "kanban");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "calendar");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "spreadsheet");
// await issueViewStore.getMyIssuesAsync(workspaceSlug, "my_issues", "gantt");
// project issues under and workspace and project
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "list");
await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "kanban");
await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "list");
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "kanban");
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "calendar");
// await issueViewStore.getProjectIssuesAsync(
// workspaceSlug,
@ -38,7 +39,6 @@ const KanBanViewRoot = () => {
// "spreadsheet"
// );
// await issueViewStore.getProjectIssuesAsync(workspaceSlug, projectSlug, "issues", "gantt");
// module issues under and workspace and project
// await issueViewStore.getIssuesForModulesAsync(
// workspaceSlug,
@ -75,7 +75,6 @@ const KanBanViewRoot = () => {
// "modules",
// "gantt"
// );
// cycle issues under and workspace and project
// await issueViewStore.getIssuesForCyclesAsync(
// workspaceSlug,
@ -112,7 +111,6 @@ const KanBanViewRoot = () => {
// "cycles",
// "gantt"
// );
// cycle issues under and workspace and project
// await issueViewStore.getIssuesForViewsAsync(
// workspaceSlug,
@ -149,8 +147,7 @@ const KanBanViewRoot = () => {
// "views",
// "gantt"
// );
console.log("ended--->");
// console.log("ended--->");
};
init();
@ -163,10 +160,21 @@ const KanBanViewRoot = () => {
className="flex-shrink-0 h-[60px] border-b border-gray-200"
// style={{ writingMode: "vertical-lr" }}
>
Filter Header
<div className="w-full h-full p-2 px-5 relative flex justify-between items-center gap-2">
<div>
<div>Filter Header</div>
</div>
<div className="relative flex items-center gap-2">
<div>{/* <FilterSelection /> */}</div>
<div>
<LayoutSelection />
</div>
</div>
</div>
</div>
<div className="w-full h-full relative overflow-hidden">
<IssueKanBanViewRoot />
<FilterSelection />
{/* <IssueKanBanViewRoot /> */}
</div>
</div>
</div>

View File

@ -10,7 +10,7 @@ const trackEvent =
// types
import type { ICurrentUserResponse, IState, IStateResponse } from "types";
class ProjectStateServices extends APIService {
export class ProjectStateServices extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}

View File

@ -20,7 +20,7 @@ import {
const trackEvent =
process.env.NEXT_PUBLIC_TRACK_EVENTS === "true" || process.env.NEXT_PUBLIC_TRACK_EVENTS === "1";
class WorkspaceService extends APIService {
export class WorkspaceService extends APIService {
constructor() {
super(NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000");
}

View File

@ -121,14 +121,19 @@ class IssueViewStore implements IIssueViewStore {
get getIssues() {
if (this.issues != null) {
const currentView: TIssueViews | null = this.rootStore.issueFilters.issueView;
const currentLayout: TIssueLayouts | null = this.rootStore.issueFilters.issueLayout;
const currentWorkspaceId: string | null = this.rootStore.issueFilters.workspaceId;
const currentProjectId: string | null = this.rootStore.issueFilters.projectId;
const currentModuleId: string | null = this.rootStore.issueFilters.moduleId;
const currentCycleId: string | null = this.rootStore.issueFilters.cycleId;
const currentViewId: string | null = this.rootStore.issueFilters.viewId;
if (!currentView || !currentLayout || !currentWorkspaceId) return null;
if (!currentView || !currentWorkspaceId) return null;
const currentLayout: TIssueLayouts = currentProjectId
? this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]
?.project_issue_properties?.[currentProjectId]?.renderLayout
: this.rootStore.issueFilters.issueFilters?.[currentWorkspaceId]?.my_issue_properties
?.renderLayout;
if (currentView === "my_issues")
return this.issues?.[currentWorkspaceId]?.my_issues?.[currentLayout];
@ -149,6 +154,8 @@ class IssueViewStore implements IIssueViewStore {
currentViewId
]?.[currentLayout];
}
return null;
}
// fetching my issues
@ -157,6 +164,7 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
null,
@ -189,7 +197,7 @@ class IssueViewStore implements IIssueViewStore {
return issuesResponse;
} catch (error) {
console.warn("error", error);
console.warn("error in fetching the my issues", error);
this.loader = false;
this.error = null;
return error;
@ -207,6 +215,7 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
await this.rootStore.issueFilters.getProjectIssueFilters(workspaceId, projectId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -249,7 +258,7 @@ class IssueViewStore implements IIssueViewStore {
return issuesResponse;
} catch (error) {
console.warn("error", error);
console.warn("error in fetching the project issues", error);
this.loader = false;
this.error = null;
return error;
@ -268,6 +277,11 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
await this.rootStore.issueFilters.getProjectIssueModuleFilters(
workspaceId,
projectId,
moduleId
);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -314,7 +328,7 @@ class IssueViewStore implements IIssueViewStore {
return issuesResponse;
} catch (error) {
console.warn("error", error);
console.warn("error in fetching the project module issues", error);
this.loader = false;
this.error = null;
return error;
@ -333,6 +347,11 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
await this.rootStore.issueFilters.getProjectIssueCyclesFilters(
workspaceId,
projectId,
cycleId
);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -379,7 +398,7 @@ class IssueViewStore implements IIssueViewStore {
return issuesResponse;
} catch (error) {
console.warn("error", error);
console.warn("error in fetching the project cycles issues", error);
this.loader = false;
this.error = null;
return error;
@ -398,6 +417,7 @@ class IssueViewStore implements IIssueViewStore {
this.loader = true;
this.error = null;
await this.rootStore.issueFilters.getProjectIssueViewsFilters(workspaceId, projectId, viewId);
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
workspaceId,
projectId,
@ -443,7 +463,7 @@ class IssueViewStore implements IIssueViewStore {
return issuesResponse;
} catch (error) {
console.warn("error", error);
console.warn("error in fetching the project view issues", error);
this.loader = false;
this.error = null;
return error;

View File

@ -6,7 +6,15 @@ export const filtersPriority: { key: string; title: string }[] = [
{ key: "null", title: "None" },
];
export const filtersStartDate = [
export const filterStateGroup: { key: string; title: string }[] = [
{ key: "backlog", title: "Backlog" },
{ key: "unstarted", title: "Unstarted" },
{ key: "started", title: "Started" },
{ key: "completed", title: "Completed" },
{ key: "cancelled", title: "Cancelled" },
];
export const filtersStartDate: { 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" },
@ -14,7 +22,7 @@ export const filtersStartDate = [
{ key: "custom", title: "Custom" },
];
export const filtersDueDate = [
export const filtersDueDate: { 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" },
@ -22,16 +30,17 @@ export const filtersDueDate = [
{ key: "custom", title: "Custom" },
];
export const displayPropertyGroupBy = [
export const displayPropertyGroupBy: { 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 displayPropertyOrderBy = [
export const displayPropertyOrderBy: { key: string; title: string }[] = [
{ key: "sort_order", title: "Manual" },
{ key: "created_at", title: "Last Created" },
{ key: "updated_at", title: "Last Updated" },
@ -39,13 +48,13 @@ export const displayPropertyOrderBy = [
{ key: "priority", title: "Priority" },
];
export const displayPropertyIssueType = [
export const displayPropertyIssueType: { key: string; title: string }[] = [
{ key: "all", title: "All" },
{ key: "active", title: "Active Issues" },
{ key: "backlog", title: "Backlog Issues" },
];
export const displayProperties = [
export const displayProperties: { key: string; title: string }[] = [
{ key: "assignee", title: "Assignee" },
{ key: "start_date", title: "Start Date" },
{ key: "due_date", title: "Due Date" },

File diff suppressed because it is too large Load Diff