mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: cycle events updated
This commit is contained in:
parent
bce768daf6
commit
801f135012
@ -14,13 +14,14 @@ import { StateDropdown } from "@/components/dropdowns";
|
|||||||
import { EmptyState } from "@/components/empty-state";
|
import { EmptyState } from "@/components/empty-state";
|
||||||
// constants
|
// constants
|
||||||
import { EmptyStateType } from "@/constants/empty-state";
|
import { EmptyStateType } from "@/constants/empty-state";
|
||||||
|
import { ACYCLE_TAB_CHANGED } from "@/constants/event-tracker";
|
||||||
import { CYCLE_ISSUES_WITH_PARAMS } from "@/constants/fetch-keys";
|
import { CYCLE_ISSUES_WITH_PARAMS } from "@/constants/fetch-keys";
|
||||||
import { EIssuesStoreType } from "@/constants/issue";
|
import { EIssuesStoreType } from "@/constants/issue";
|
||||||
// helper
|
// helper
|
||||||
import { cn } from "@/helpers/common.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
import { renderFormattedDate, renderFormattedDateWithoutYear } from "@/helpers/date-time.helper";
|
import { renderFormattedDate, renderFormattedDateWithoutYear } from "@/helpers/date-time.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssues, useProject } from "@/hooks/store";
|
import { useEventTracker, useIssues, useProject } from "@/hooks/store";
|
||||||
import useLocalStorage from "@/hooks/use-local-storage";
|
import useLocalStorage from "@/hooks/use-local-storage";
|
||||||
|
|
||||||
export type ActiveCycleStatsProps = {
|
export type ActiveCycleStatsProps = {
|
||||||
@ -51,6 +52,7 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
|
|||||||
} = useIssues(EIssuesStoreType.CYCLE);
|
} = useIssues(EIssuesStoreType.CYCLE);
|
||||||
|
|
||||||
const { currentProjectDetails } = useProject();
|
const { currentProjectDetails } = useProject();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
|
|
||||||
const { data: activeCycleIssues } = useSWR(
|
const { data: activeCycleIssues } = useSWR(
|
||||||
workspaceSlug && projectId && cycle.id ? CYCLE_ISSUES_WITH_PARAMS(cycle.id, { priority: "urgent,high" }) : null,
|
workspaceSlug && projectId && cycle.id ? CYCLE_ISSUES_WITH_PARAMS(cycle.id, { priority: "urgent,high" }) : null,
|
||||||
@ -65,17 +67,25 @@ export const ActiveCycleStats: FC<ActiveCycleStatsProps> = observer((props) => {
|
|||||||
as={Fragment}
|
as={Fragment}
|
||||||
defaultIndex={currentValue(tab)}
|
defaultIndex={currentValue(tab)}
|
||||||
onChange={(i) => {
|
onChange={(i) => {
|
||||||
|
let tab: string;
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
return setTab("Priority-Issues");
|
tab = "Priority-Issues";
|
||||||
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
return setTab("Assignees");
|
tab = "Assignees";
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return setTab("Labels");
|
tab = "Labels";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return setTab("Priority-Issues");
|
tab = "Priority-Issues";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
setTab(tab);
|
||||||
|
captureEvent(ACYCLE_TAB_CHANGED, {
|
||||||
|
tab: tab,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tab.List
|
<Tab.List
|
||||||
|
@ -10,10 +10,11 @@ import { EmptyState } from "@/components/empty-state";
|
|||||||
import { CycleModuleListLayout } from "@/components/ui";
|
import { CycleModuleListLayout } from "@/components/ui";
|
||||||
// constants
|
// constants
|
||||||
import { EmptyStateType } from "@/constants/empty-state";
|
import { EmptyStateType } from "@/constants/empty-state";
|
||||||
|
import { CYCLES_FILTER_REMOVED } from "@/constants/event-tracker";
|
||||||
// helpers
|
// helpers
|
||||||
import { calculateTotalFilters } from "@/helpers/filter.helper";
|
import { calculateTotalFilters } from "@/helpers/filter.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCycle, useCycleFilter } from "@/hooks/store";
|
import { useCycle, useCycleFilter, useEventTracker } from "@/hooks/store";
|
||||||
|
|
||||||
export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
||||||
// router
|
// router
|
||||||
@ -21,6 +22,7 @@ export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
|||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
// hooks
|
// hooks
|
||||||
const { fetchArchivedCycles, currentProjectArchivedCycleIds, loader } = useCycle();
|
const { fetchArchivedCycles, currentProjectArchivedCycleIds, loader } = useCycle();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// cycle filters hook
|
// cycle filters hook
|
||||||
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useCycleFilter();
|
const { clearAllFilters, currentProjectArchivedFilters, updateFilters } = useCycleFilter();
|
||||||
// derived values
|
// derived values
|
||||||
@ -43,6 +45,11 @@ export const ArchivedCycleLayoutRoot: React.FC = observer(() => {
|
|||||||
if (!value) newValues = [];
|
if (!value) newValues = [];
|
||||||
else newValues = newValues.filter((val) => val !== value);
|
else newValues = newValues.filter((val) => val !== value);
|
||||||
|
|
||||||
|
captureEvent(CYCLES_FILTER_REMOVED, {
|
||||||
|
filter_type: key,
|
||||||
|
filter_property: value,
|
||||||
|
current_filters: currentProjectArchivedFilters,
|
||||||
|
});
|
||||||
updateFilters(projectId.toString(), { [key]: newValues }, "archived");
|
updateFilters(projectId.toString(), { [key]: newValues }, "archived");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,13 +5,16 @@ import { CustomMenu } from "@plane/ui";
|
|||||||
// icon
|
// icon
|
||||||
// constants
|
// constants
|
||||||
import { CYCLE_VIEW_LAYOUTS } from "@/constants/cycle";
|
import { CYCLE_VIEW_LAYOUTS } from "@/constants/cycle";
|
||||||
|
import { CYCLE_LAYOUT_CHANGED } from "@/constants/event-tracker";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCycleFilter, useProject } from "@/hooks/store";
|
import { useCycleFilter, useEventTracker, useProject } from "@/hooks/store";
|
||||||
|
|
||||||
const CyclesListMobileHeader = observer(() => {
|
const CyclesListMobileHeader = observer(() => {
|
||||||
const { currentProjectDetails } = useProject();
|
|
||||||
// hooks
|
// hooks
|
||||||
|
const { currentProjectDetails } = useProject();
|
||||||
const { updateDisplayFilters } = useCycleFilter();
|
const { updateDisplayFilters } = useCycleFilter();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center sm:hidden">
|
<div className="flex justify-center sm:hidden">
|
||||||
<CustomMenu
|
<CustomMenu
|
||||||
@ -36,6 +39,9 @@ const CyclesListMobileHeader = observer(() => {
|
|||||||
updateDisplayFilters(currentProjectDetails!.id, {
|
updateDisplayFilters(currentProjectDetails!.id, {
|
||||||
layout: layout.key,
|
layout: layout.key,
|
||||||
});
|
});
|
||||||
|
captureEvent(CYCLE_LAYOUT_CHANGED, {
|
||||||
|
layout: layout.key,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
|
@ -11,10 +11,16 @@ import { CycleFiltersSelection } from "@/components/cycles";
|
|||||||
import { FiltersDropdown } from "@/components/issues";
|
import { FiltersDropdown } from "@/components/issues";
|
||||||
// constants
|
// constants
|
||||||
import { CYCLE_TABS_LIST, CYCLE_VIEW_LAYOUTS } from "@/constants/cycle";
|
import { CYCLE_TABS_LIST, CYCLE_VIEW_LAYOUTS } from "@/constants/cycle";
|
||||||
|
import {
|
||||||
|
CYCLES_FILTER_APPLIED,
|
||||||
|
CYCLES_FILTER_REMOVED,
|
||||||
|
CYCLE_LAYOUT_CHANGED,
|
||||||
|
CYCLE_TAB_CHANGED,
|
||||||
|
} from "@/constants/event-tracker";
|
||||||
// helpers
|
// helpers
|
||||||
import { cn } from "@/helpers/common.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCycleFilter } from "@/hooks/store";
|
import { useCycleFilter, useEventTracker } from "@/hooks/store";
|
||||||
import useOutsideClickDetector from "@/hooks/use-outside-click-detector";
|
import useOutsideClickDetector from "@/hooks/use-outside-click-detector";
|
||||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||||
|
|
||||||
@ -36,6 +42,7 @@ export const CyclesViewHeader: React.FC<Props> = observer((props) => {
|
|||||||
updateSearchQuery,
|
updateSearchQuery,
|
||||||
} = useCycleFilter();
|
} = useCycleFilter();
|
||||||
const { isMobile } = usePlatformOS();
|
const { isMobile } = usePlatformOS();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// states
|
// states
|
||||||
const [isSearchOpen, setIsSearchOpen] = useState(searchQuery !== "" ? true : false);
|
const [isSearchOpen, setIsSearchOpen] = useState(searchQuery !== "" ? true : false);
|
||||||
// outside click detector hook
|
// outside click detector hook
|
||||||
@ -48,7 +55,7 @@ export const CyclesViewHeader: React.FC<Props> = observer((props) => {
|
|||||||
const handleFilters = useCallback(
|
const handleFilters = useCallback(
|
||||||
(key: keyof TCycleFilters, value: string | string[]) => {
|
(key: keyof TCycleFilters, value: string | string[]) => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
const newValues = currentProjectFilters?.[key] ?? [];
|
const newValues = Array.from(currentProjectFilters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value))
|
if (Array.isArray(value))
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
@ -59,7 +66,14 @@ export const CyclesViewHeader: React.FC<Props> = observer((props) => {
|
|||||||
if (currentProjectFilters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (currentProjectFilters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
captureEvent(
|
||||||
|
(currentProjectFilters?.[key] ?? []).length > newValues.length ? CYCLES_FILTER_REMOVED : CYCLES_FILTER_APPLIED,
|
||||||
|
{
|
||||||
|
filter_type: key,
|
||||||
|
filter_property: value,
|
||||||
|
current_filters: currentProjectFilters,
|
||||||
|
}
|
||||||
|
);
|
||||||
updateFilters(projectId, { [key]: newValues });
|
updateFilters(projectId, { [key]: newValues });
|
||||||
},
|
},
|
||||||
[currentProjectFilters, projectId, updateFilters]
|
[currentProjectFilters, projectId, updateFilters]
|
||||||
@ -81,6 +95,11 @@ export const CyclesViewHeader: React.FC<Props> = observer((props) => {
|
|||||||
{CYCLE_TABS_LIST.map((tab) => (
|
{CYCLE_TABS_LIST.map((tab) => (
|
||||||
<Tab
|
<Tab
|
||||||
key={tab.key}
|
key={tab.key}
|
||||||
|
onClick={() =>
|
||||||
|
captureEvent(CYCLE_TAB_CHANGED, {
|
||||||
|
tab: tab.key,
|
||||||
|
})
|
||||||
|
}
|
||||||
className={({ selected }) =>
|
className={({ selected }) =>
|
||||||
`border-b-2 p-4 text-sm font-medium outline-none ${
|
`border-b-2 p-4 text-sm font-medium outline-none ${
|
||||||
selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent"
|
selected ? "border-custom-primary-100 text-custom-primary-100" : "border-transparent"
|
||||||
@ -146,11 +165,14 @@ export const CyclesViewHeader: React.FC<Props> = observer((props) => {
|
|||||||
className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${
|
className={`group grid h-[22px] w-7 place-items-center overflow-hidden rounded transition-all hover:bg-custom-background-100 ${
|
||||||
activeLayout == layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : ""
|
activeLayout == layout.key ? "bg-custom-background-100 shadow-custom-shadow-2xs" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={() =>
|
onClick={() => {
|
||||||
updateDisplayFilters(projectId, {
|
updateDisplayFilters(projectId, {
|
||||||
layout: layout.key,
|
layout: layout.key,
|
||||||
})
|
});
|
||||||
}
|
captureEvent(CYCLE_LAYOUT_CHANGED, {
|
||||||
|
layout: layout.key,
|
||||||
|
});
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<layout.icon
|
<layout.icon
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
|
@ -8,7 +8,7 @@ import { ArchiveIcon, CustomMenu, TOAST_TYPE, setToast } from "@plane/ui";
|
|||||||
// components
|
// components
|
||||||
import { ArchiveCycleModal, CycleCreateUpdateModal, CycleDeleteModal } from "@/components/cycles";
|
import { ArchiveCycleModal, CycleCreateUpdateModal, CycleDeleteModal } from "@/components/cycles";
|
||||||
// constants
|
// constants
|
||||||
import { E_CYCLES_LIST_LAYOUT } from "@/constants/event-tracker";
|
import { CYCLE_ARCHIVED, CYCLE_RESTORED, E_CYCLES } from "@/constants/event-tracker";
|
||||||
import { EUserProjectRoles } from "@/constants/project";
|
import { EUserProjectRoles } from "@/constants/project";
|
||||||
// helpers
|
// helpers
|
||||||
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
||||||
@ -31,7 +31,7 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
|
|||||||
const [archiveCycleModal, setArchiveCycleModal] = useState(false);
|
const [archiveCycleModal, setArchiveCycleModal] = useState(false);
|
||||||
const [deleteModal, setDeleteModal] = useState(false);
|
const [deleteModal, setDeleteModal] = useState(false);
|
||||||
// store hooks
|
// store hooks
|
||||||
const { setTrackElement } = useEventTracker();
|
const { setTrackElement, captureEvent } = useEventTracker();
|
||||||
const {
|
const {
|
||||||
membership: { currentWorkspaceAllProjectsRole },
|
membership: { currentWorkspaceAllProjectsRole },
|
||||||
} = useUser();
|
} = useUser();
|
||||||
@ -59,7 +59,7 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
|
|||||||
const handleEditCycle = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const handleEditCycle = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setTrackElement(E_CYCLES_LIST_LAYOUT);
|
setTrackElement(E_CYCLES);
|
||||||
setUpdateModal(true);
|
setUpdateModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,6 +67,10 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setArchiveCycleModal(true);
|
setArchiveCycleModal(true);
|
||||||
|
captureEvent(CYCLE_ARCHIVED, {
|
||||||
|
cycleId: cycleId,
|
||||||
|
element: E_CYCLES,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRestoreCycle = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
const handleRestoreCycle = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
@ -79,6 +83,10 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
|
|||||||
title: "Restore success",
|
title: "Restore success",
|
||||||
message: "Your cycle can be found in project cycles.",
|
message: "Your cycle can be found in project cycles.",
|
||||||
});
|
});
|
||||||
|
captureEvent(CYCLE_RESTORED, {
|
||||||
|
cycleId: cycleId,
|
||||||
|
element: E_CYCLES,
|
||||||
|
});
|
||||||
router.push(`/${workspaceSlug}/projects/${projectId}/archives/cycles`);
|
router.push(`/${workspaceSlug}/projects/${projectId}/archives/cycles`);
|
||||||
})
|
})
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
@ -93,7 +101,7 @@ export const CycleQuickActions: React.FC<Props> = observer((props) => {
|
|||||||
const handleDeleteCycle = (e: React.MouseEvent<HTMLButtonElement>) => {
|
const handleDeleteCycle = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setTrackElement(E_CYCLES_LIST_LAYOUT);
|
setTrackElement(E_CYCLES);
|
||||||
setDeleteModal(true);
|
setDeleteModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = Array.from(issueFilters?.filters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
// this validation is majorly for the filter start_date, target_date custom
|
||||||
@ -133,9 +133,10 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const event = newValues.length > (issueFilters?.filters?.[key] ?? []).length ? FILTER_APPLIED : FILTER_REMOVED;
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }, cycleId).then(() =>
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }, cycleId).then(() =>
|
||||||
captureIssuesFilterEvent({
|
captureIssuesFilterEvent({
|
||||||
eventName: (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED,
|
eventName: event,
|
||||||
payload: {
|
payload: {
|
||||||
routePath: router.asPath,
|
routePath: router.asPath,
|
||||||
filters: issueFilters,
|
filters: issueFilters,
|
||||||
|
@ -48,7 +48,7 @@ export const GlobalIssuesHeader: React.FC = observer(() => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !globalViewId) return;
|
if (!workspaceSlug || !globalViewId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = Array.from(issueFilters?.filters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
// this validation is majorly for the filter start_date, target_date custom
|
||||||
@ -61,6 +61,7 @@ export const GlobalIssuesHeader: React.FC = observer(() => {
|
|||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const event = (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED;
|
||||||
updateFilters(
|
updateFilters(
|
||||||
workspaceSlug.toString(),
|
workspaceSlug.toString(),
|
||||||
undefined,
|
undefined,
|
||||||
@ -69,7 +70,7 @@ export const GlobalIssuesHeader: React.FC = observer(() => {
|
|||||||
globalViewId.toString()
|
globalViewId.toString()
|
||||||
).then(() => {
|
).then(() => {
|
||||||
captureIssuesFilterEvent({
|
captureIssuesFilterEvent({
|
||||||
eventName: (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED,
|
eventName: event,
|
||||||
payload: {
|
payload: {
|
||||||
routePath: router.asPath,
|
routePath: router.asPath,
|
||||||
filters: issueFilters,
|
filters: issueFilters,
|
||||||
|
@ -121,7 +121,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = Array.from(issueFilters?.filters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
// this validation is majorly for the filter start_date, target_date custom
|
||||||
@ -134,9 +134,10 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const event = (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED;
|
||||||
updateFilters(projectId.toString(), EIssueFilterType.FILTERS, { [key]: newValues }).then(() => {
|
updateFilters(projectId.toString(), EIssueFilterType.FILTERS, { [key]: newValues }).then(() => {
|
||||||
captureIssuesFilterEvent({
|
captureIssuesFilterEvent({
|
||||||
eventName: (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED,
|
eventName: event,
|
||||||
payload: {
|
payload: {
|
||||||
routePath: router.asPath,
|
routePath: router.asPath,
|
||||||
filters: issueFilters,
|
filters: issueFilters,
|
||||||
|
@ -67,7 +67,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = Array.from(issueFilters?.filters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
// this validation is majorly for the filter start_date, target_date custom
|
||||||
@ -80,9 +80,10 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const event = (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED;
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }).then(() =>
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }).then(() =>
|
||||||
captureIssuesFilterEvent({
|
captureIssuesFilterEvent({
|
||||||
eventName: (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED,
|
eventName: event,
|
||||||
payload: {
|
payload: {
|
||||||
routePath: router.asPath,
|
routePath: router.asPath,
|
||||||
filters: issueFilters,
|
filters: issueFilters,
|
||||||
|
@ -86,7 +86,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
|||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId || !viewId) return;
|
if (!workspaceSlug || !projectId || !viewId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = Array.from(issueFilters?.filters?.[key] ?? []);
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
// this validation is majorly for the filter start_date, target_date custom
|
// this validation is majorly for the filter start_date, target_date custom
|
||||||
@ -98,24 +98,24 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
|
|||||||
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
}
|
}
|
||||||
|
const event = (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED;
|
||||||
updateFilters(
|
updateFilters(
|
||||||
workspaceSlug.toString(),
|
workspaceSlug.toString(),
|
||||||
projectId.toString(),
|
projectId.toString(),
|
||||||
EIssueFilterType.FILTERS,
|
EIssueFilterType.FILTERS,
|
||||||
{ [key]: newValues },
|
{ [key]: newValues },
|
||||||
viewId.toString()
|
viewId.toString()
|
||||||
).then(() => {
|
).then(() =>
|
||||||
captureIssuesFilterEvent({
|
captureIssuesFilterEvent({
|
||||||
eventName: (issueFilters?.filters?.[key] ?? []).length > newValues.length ? FILTER_REMOVED : FILTER_APPLIED,
|
eventName: event,
|
||||||
payload: {
|
payload: {
|
||||||
routePath: router.asPath,
|
routePath: router.asPath,
|
||||||
filters: issueFilters,
|
filters: issueFilters,
|
||||||
filter_property: value,
|
filter_property: value,
|
||||||
filter_type: key,
|
filter_type: key,
|
||||||
},
|
},
|
||||||
});
|
})
|
||||||
});
|
);
|
||||||
},
|
},
|
||||||
[workspaceSlug, projectId, viewId, issueFilters, updateFilters, captureIssuesFilterEvent, router.asPath]
|
[workspaceSlug, projectId, viewId, issueFilters, updateFilters, captureIssuesFilterEvent, router.asPath]
|
||||||
);
|
);
|
||||||
|
@ -13,7 +13,7 @@ import { EUserProjectRoles } from "@/constants/project";
|
|||||||
// helpers
|
// helpers
|
||||||
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
import { copyUrlToClipboard } from "@/helpers/string.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useModule, useEventTracker, useUser, useModuleFilter } from "@/hooks/store";
|
import { useModule, useEventTracker, useUser } from "@/hooks/store";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
|
@ -196,6 +196,15 @@ export const CYCLE_UPDATED = "Cycle updated";
|
|||||||
export const CYCLE_DELETED = "Cycle deleted";
|
export const CYCLE_DELETED = "Cycle deleted";
|
||||||
export const CYCLE_FAVORITED = "Cycle favorited";
|
export const CYCLE_FAVORITED = "Cycle favorited";
|
||||||
export const CYCLE_UNFAVORITED = "Cycle unfavorited";
|
export const CYCLE_UNFAVORITED = "Cycle unfavorited";
|
||||||
|
export const CYCLES_LAYOUT_CHANGED = "cycles layout changed";
|
||||||
|
export const CYCLES_SORT_UPDATED = "cycle sort updated";
|
||||||
|
export const CYCLES_FILTER_APPLIED = "Cycles filter applied";
|
||||||
|
export const CYCLES_FILTER_REMOVED = "Cycles filter removed";
|
||||||
|
export const CYCLE_ARCHIVED = "Cycle archived";
|
||||||
|
export const CYCLE_RESTORED = "Cycle restored";
|
||||||
|
export const CYCLE_LAYOUT_CHANGED = "Cycle layout changed";
|
||||||
|
export const CYCLE_TAB_CHANGED = "Cycle tab changed";
|
||||||
|
export const ACYCLE_TAB_CHANGED = "Active cycle tab changed";
|
||||||
// Module Events
|
// Module Events
|
||||||
export const MODULE_CREATED = "Module created";
|
export const MODULE_CREATED = "Module created";
|
||||||
export const MODULE_UPDATED = "Module updated";
|
export const MODULE_UPDATED = "Module updated";
|
||||||
|
@ -18,7 +18,7 @@ import { CyclesHeader } from "@/components/headers";
|
|||||||
import { CycleModuleBoardLayout, CycleModuleListLayout, GanttLayoutLoader } from "@/components/ui";
|
import { CycleModuleBoardLayout, CycleModuleListLayout, GanttLayoutLoader } from "@/components/ui";
|
||||||
import { CYCLE_TABS_LIST } from "@/constants/cycle";
|
import { CYCLE_TABS_LIST } from "@/constants/cycle";
|
||||||
import { EmptyStateType } from "@/constants/empty-state";
|
import { EmptyStateType } from "@/constants/empty-state";
|
||||||
import { E_CYCLES_EMPTY_STATE } from "@/constants/event-tracker";
|
import { CYCLES_FILTER_REMOVED, E_CYCLES_EMPTY_STATE } from "@/constants/event-tracker";
|
||||||
import { calculateTotalFilters } from "@/helpers/filter.helper";
|
import { calculateTotalFilters } from "@/helpers/filter.helper";
|
||||||
import { useEventTracker, useCycle, useProject, useCycleFilter } from "@/hooks/store";
|
import { useEventTracker, useCycle, useProject, useCycleFilter } from "@/hooks/store";
|
||||||
// layouts
|
// layouts
|
||||||
@ -37,6 +37,7 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
|||||||
const { setTrackElement } = useEventTracker();
|
const { setTrackElement } = useEventTracker();
|
||||||
const { currentProjectCycleIds, loader } = useCycle();
|
const { currentProjectCycleIds, loader } = useCycle();
|
||||||
const { getProjectById, currentProjectDetails } = useProject();
|
const { getProjectById, currentProjectDetails } = useProject();
|
||||||
|
const { captureEvent } = useEventTracker();
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, peekCycle } = router.query;
|
const { workspaceSlug, projectId, peekCycle } = router.query;
|
||||||
@ -58,6 +59,11 @@ const ProjectCyclesPage: NextPageWithLayout = observer(() => {
|
|||||||
if (!value) newValues = [];
|
if (!value) newValues = [];
|
||||||
else newValues = newValues.filter((val) => val !== value);
|
else newValues = newValues.filter((val) => val !== value);
|
||||||
|
|
||||||
|
captureEvent(CYCLES_FILTER_REMOVED, {
|
||||||
|
filter_type: key,
|
||||||
|
filter_property: value,
|
||||||
|
current_filters: currentProjectFilters,
|
||||||
|
});
|
||||||
updateFilters(projectId.toString(), { [key]: newValues });
|
updateFilters(projectId.toString(), { [key]: newValues });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user