chore: added issue activity filters to local storage (#6324)

chore: added sort order to local storage
This commit is contained in:
Vamsi Krishna 2025-01-06 20:27:55 +05:30 committed by GitHub
parent bc27bc9dd2
commit 208df80c86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 55 additions and 31 deletions

View file

@ -16,6 +16,7 @@ import {
TIssueServiceType,
} from "@plane/types";
// plane web constants
import { TSORT_ORDER } from "@/constants/common";
import { EActivityFilterType } from "@/plane-web/constants/issues";
// services
import { IssueActivityService } from "@/services/issue";
@ -36,20 +37,17 @@ export interface IIssueActivityStoreActions {
export interface IIssueActivityStore extends IIssueActivityStoreActions {
// observables
sortOrder: "asc" | "desc";
loader: TActivityLoader;
activities: TIssueActivityIdMap;
activityMap: TIssueActivityMap;
// helper methods
getActivitiesByIssueId: (issueId: string) => string[] | undefined;
getActivityById: (activityId: string) => TIssueActivity | undefined;
getActivityCommentByIssueId: (issueId: string) => TIssueActivityComment[] | undefined;
toggleSortOrder: () => void;
getActivityCommentByIssueId: (issueId: string, sortOrder: TSORT_ORDER) => TIssueActivityComment[] | undefined;
}
export class IssueActivityStore implements IIssueActivityStore {
// observables
sortOrder: "asc" | "desc" = "asc";
loader: TActivityLoader = "fetch";
activities: TIssueActivityIdMap = {};
activityMap: TIssueActivityMap = {};
@ -64,13 +62,11 @@ export class IssueActivityStore implements IIssueActivityStore {
) {
makeObservable(this, {
// observables
sortOrder: observable.ref,
loader: observable.ref,
activities: observable,
activityMap: observable,
// actions
fetchActivities: action,
toggleSortOrder: action,
});
this.serviceType = serviceType;
// services
@ -88,7 +84,7 @@ export class IssueActivityStore implements IIssueActivityStore {
return this.activityMap[activityId] ?? undefined;
};
getActivityCommentByIssueId = computedFn((issueId: string) => {
getActivityCommentByIssueId = computedFn((issueId: string, sortOrder: TSORT_ORDER) => {
if (!issueId) return undefined;
let activityComments: TIssueActivityComment[] = [];
@ -119,15 +115,11 @@ export class IssueActivityStore implements IIssueActivityStore {
});
});
activityComments = orderBy(activityComments, (e) => new Date(e.created_at || 0), this.sortOrder);
activityComments = orderBy(activityComments, (e) => new Date(e.created_at || 0), sortOrder);
return activityComments;
});
toggleSortOrder = () => {
this.sortOrder = this.sortOrder === "asc" ? "desc" : "asc";
};
// actions
public async fetchActivities(
workspaceSlug: string,

View file

@ -1,5 +1,7 @@
import { FC } from "react";
import { observer } from "mobx-react";
// constants
import { TSORT_ORDER } from "@/constants/common";
// hooks
import { useIssueDetail } from "@/hooks/store";
// plane web components
@ -21,18 +23,27 @@ type TIssueActivityCommentRoot = {
activityOperations: TActivityOperations;
showAccessSpecifier?: boolean;
disabled?: boolean;
sortOrder: TSORT_ORDER;
};
export const IssueActivityCommentRoot: FC<TIssueActivityCommentRoot> = observer((props) => {
const { workspaceSlug, issueId, selectedFilters, activityOperations, showAccessSpecifier, projectId, disabled } =
props;
const {
workspaceSlug,
issueId,
selectedFilters,
activityOperations,
showAccessSpecifier,
projectId,
disabled,
sortOrder,
} = props;
// hooks
const {
activity: { getActivityCommentByIssueId },
comment: {},
} = useIssueDetail();
const activityComments = getActivityCommentByIssueId(issueId);
const activityComments = getActivityCommentByIssueId(issueId, sortOrder);
if (!activityComments || (activityComments && activityComments.length <= 0)) return <></>;

View file

@ -26,6 +26,9 @@ export const ActivityFilter: FC<TActivityFilter> = observer((props) => {
className="relative"
>
<span className="text-custom-text-200">Filters</span>
{selectedFilters.length < filterOptions.length && (
<span className="absolute h-2 w-2 -right-0.5 -top-0.5 bg-custom-primary-100 rounded-full" />
)}
</Button>
}
panelClassName="p-2 rounded-md border border-custom-border-200 bg-custom-background-100"

View file

@ -1,7 +1,8 @@
"use client";
import { FC, useMemo, useState } from "react";
import { FC, useMemo } from "react";
import { observer } from "mobx-react";
import { useLocalStorage } from "@plane/hooks";
// types
import { TFileSignedURLResponse, TIssueComment } from "@plane/types";
import { EFileAssetType } from "@plane/types/src/enums";
@ -10,6 +11,8 @@ import { TOAST_TYPE, setToast } from "@plane/ui";
// components
import { IssueCommentCreate } from "@/components/issues";
import { ActivitySortRoot, IssueActivityCommentRoot } from "@/components/issues/issue-detail";
// constants
import { TSORT_ORDER } from "@/constants/common";
// hooks
import { useIssueDetail, useProject, useUser, useUserPermissions } from "@/hooks/store";
// plane web components
@ -38,12 +41,14 @@ export type TActivityOperations = {
export const IssueActivity: FC<TIssueActivity> = observer((props) => {
const { workspaceSlug, projectId, issueId, disabled = false, isIntakeIssue = false } = props;
// state
const [selectedFilters, setSelectedFilters] = useState<TActivityFilters[]>(defaultActivityFilters);
// hooks
const { setValue: setFilterValue, storedValue: selectedFilters } = useLocalStorage(
"issue_activity_filters",
defaultActivityFilters
);
const { setValue: setSortOrder, storedValue: sortOrder } = useLocalStorage("activity_sort_order", TSORT_ORDER.ASC);
const {
issue: { getIssueById },
activity: { sortOrder, toggleSortOrder },
createComment,
updateComment,
removeComment,
@ -60,14 +65,20 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
const isWorklogButtonEnabled = !isIntakeIssue && !isGuest && (isAdmin || isAssigned);
// toggle filter
const toggleFilter = (filter: TActivityFilters) => {
setSelectedFilters((prevFilters) => {
if (prevFilters.includes(filter)) {
if (prevFilters.length === 1) return prevFilters; // Ensure at least one filter is applied
return prevFilters.filter((f) => f !== filter);
} else {
return [...prevFilters, filter];
}
});
if (!selectedFilters) return;
let _filters = [];
if (selectedFilters.includes(filter)) {
if (selectedFilters.length === 1) return selectedFilters; // Ensure at least one filter is applied
_filters = selectedFilters.filter((f) => f !== filter);
} else {
_filters = [...selectedFilters, filter];
}
setFilterValue(_filters);
};
const toggleSortOrder = () => {
setSortOrder(sortOrder === TSORT_ORDER.ASC ? TSORT_ORDER.DESC : TSORT_ORDER.ASC);
};
const activityOperations: TActivityOperations = useMemo(
@ -163,9 +174,9 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
disabled={disabled}
/>
)}
<ActivitySortRoot sortOrder={sortOrder} toggleSort={toggleSortOrder} />
<ActivitySortRoot sortOrder={sortOrder || TSORT_ORDER.ASC} toggleSort={toggleSortOrder} />
<ActivityFilterRoot
selectedFilters={selectedFilters}
selectedFilters={selectedFilters || defaultActivityFilters}
toggleFilter={toggleFilter}
isIntakeIssue={isIntakeIssue}
projectId={projectId}
@ -181,10 +192,11 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
projectId={projectId}
workspaceSlug={workspaceSlug}
issueId={issueId}
selectedFilters={selectedFilters}
selectedFilters={selectedFilters || defaultActivityFilters}
activityOperations={activityOperations}
showAccessSpecifier={!!project.anchor}
disabled={disabled}
sortOrder={sortOrder || TSORT_ORDER.ASC}
/>
{!disabled && (
<IssueCommentCreate

View file

@ -3,11 +3,12 @@
import { FC, memo } from "react";
import { ArrowUpWideNarrow, ArrowDownWideNarrow } from "lucide-react";
import { getButtonStyling } from "@plane/ui";
import { TSORT_ORDER } from "@/constants/common";
// helpers
import { cn } from "@/helpers/common.helper";
export type TActivitySortRoot = {
sortOrder: "asc" | "desc";
sortOrder: TSORT_ORDER;
toggleSort: () => void;
className?: string;
iconClassName?: string;

View file

@ -28,3 +28,8 @@ export const PROGRESS_STATE_GROUPS_DETAILS = [
color: "#A3A3A3",
},
];
export enum TSORT_ORDER {
ASC = "asc",
DESC = "desc",
}