[WEB-5054]feat: added activity filters for state and assignee activities (#7918)

* feat: added activity filters for state and assignee

* chore: removed unused funtion

* chore: lint fix
This commit is contained in:
Vamsi Krishna 2025-10-15 17:12:03 +05:30 committed by GitHub
parent f9cca8e2cb
commit 2b106cbd66
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 70 additions and 13 deletions

View file

@ -46,7 +46,6 @@ export class IssueActivityStore implements IIssueActivityStore {
loader: TActivityLoader = "fetch";
activities: TIssueActivityIdMap = {};
activityMap: TIssueActivityMap = {};
// services
serviceType;
issueActivityService;
@ -79,10 +78,10 @@ export class IssueActivityStore implements IIssueActivityStore {
return this.activityMap[activityId] ?? undefined;
};
getActivityAndCommentsByIssueId = computedFn((issueId: string, sortOrder: E_SORT_ORDER) => {
protected buildActivityAndCommentItems(issueId: string): TIssueActivityComment[] | undefined {
if (!issueId) return undefined;
let activityComments: TIssueActivityComment[] = [];
const activityComments: TIssueActivityComment[] = [];
const currentStore =
this.serviceType === EIssueServiceType.EPICS ? this.store.issue.epicDetail : this.store.issue.issueDetail;
@ -92,17 +91,25 @@ export class IssueActivityStore implements IIssueActivityStore {
if (!activities || !comments) return undefined;
activities?.forEach((activityId) => {
activities.forEach((activityId) => {
const activity = this.getActivityById(activityId);
if (!activity) return;
const type =
activity.field === "state"
? EActivityFilterType.STATE
: activity.field === "assignees"
? EActivityFilterType.ASSIGNEE
: activity.field === null
? EActivityFilterType.DEFAULT
: EActivityFilterType.ACTIVITY;
activityComments.push({
id: activity.id,
activity_type: EActivityFilterType.ACTIVITY,
activity_type: type,
created_at: activity.created_at,
});
});
comments?.forEach((commentId) => {
comments.forEach((commentId) => {
const comment = currentStore.comment.getCommentById(commentId);
if (!comment) return;
activityComments.push({
@ -112,9 +119,17 @@ export class IssueActivityStore implements IIssueActivityStore {
});
});
activityComments = orderBy(activityComments, (e) => new Date(e.created_at || 0), sortOrder);
return activityComments;
}
protected sortActivityComments(items: TIssueActivityComment[], sortOrder: E_SORT_ORDER): TIssueActivityComment[] {
return orderBy(items, (e) => new Date(e.created_at || 0), sortOrder);
}
getActivityAndCommentsByIssueId = computedFn((issueId: string, sortOrder: E_SORT_ORDER) => {
const baseItems = this.buildActivityAndCommentItems(issueId);
if (!baseItems) return undefined;
return this.sortActivityComments(baseItems, sortOrder);
});
// actions

View file

@ -2,7 +2,7 @@ import type { FC } from "react";
import { observer } from "mobx-react";
// plane imports
import type { E_SORT_ORDER, TActivityFilters } from "@plane/constants";
import { filterActivityOnSelectedFilters } from "@plane/constants";
import { EActivityFilterType, filterActivityOnSelectedFilters } from "@plane/constants";
import type { TCommentsOperations } from "@plane/types";
// components
import { CommentCard } from "@/components/comments/card/root";
@ -53,6 +53,13 @@ export const IssueActivityCommentRoot: FC<TIssueActivityCommentRoot> = observer(
const filteredActivityAndComments = filterActivityOnSelectedFilters(activityAndComments, selectedFilters);
const BASE_ACTIVITY_FILTER_TYPES = [
EActivityFilterType.ACTIVITY,
EActivityFilterType.STATE,
EActivityFilterType.ASSIGNEE,
EActivityFilterType.DEFAULT,
];
return (
<div>
{filteredActivityAndComments.map((activityComment, index) => {
@ -69,7 +76,7 @@ export const IssueActivityCommentRoot: FC<TIssueActivityCommentRoot> = observer(
disabled={disabled}
projectId={projectId}
/>
) : activityComment.activity_type === "ACTIVITY" ? (
) : BASE_ACTIVITY_FILTER_TYPES.includes(activityComment.activity_type as EActivityFilterType) ? (
<IssueActivityItem
activityId={activityComment.id}
ends={index === 0 ? "top" : index === filteredActivityAndComments.length - 1 ? "bottom" : undefined}

View file

@ -308,17 +308,28 @@ export const SUB_WORK_ITEM_AVAILABLE_FILTERS_FOR_WORK_ITEM_PAGE: (keyof IIssueFi
export enum EActivityFilterType {
ACTIVITY = "ACTIVITY",
COMMENT = "COMMENT",
STATE = "STATE",
ASSIGNEE = "ASSIGNEE",
DEFAULT = "DEFAULT",
}
export type TActivityFilters = EActivityFilterType;
export const ACTIVITY_FILTER_TYPE_OPTIONS: Record<TActivityFilters, { labelTranslationKey: string }> = {
export type TActivityFilterOptionsKey = Exclude<TActivityFilters, EActivityFilterType.DEFAULT>;
export const ACTIVITY_FILTER_TYPE_OPTIONS: Record<TActivityFilterOptionsKey, { labelTranslationKey: string }> = {
[EActivityFilterType.ACTIVITY]: {
labelTranslationKey: "common.updates",
},
[EActivityFilterType.COMMENT]: {
labelTranslationKey: "common.comments",
},
[EActivityFilterType.STATE]: {
labelTranslationKey: "common.state",
},
[EActivityFilterType.ASSIGNEE]: {
labelTranslationKey: "common.assignee",
},
};
export type TActivityFilterOption = {
@ -328,12 +339,21 @@ export type TActivityFilterOption = {
onClick: () => void;
};
export const defaultActivityFilters: TActivityFilters[] = [EActivityFilterType.ACTIVITY, EActivityFilterType.COMMENT];
export const defaultActivityFilters: TActivityFilters[] = [
EActivityFilterType.ACTIVITY,
EActivityFilterType.COMMENT,
EActivityFilterType.STATE,
EActivityFilterType.ASSIGNEE,
EActivityFilterType.DEFAULT,
];
export const filterActivityOnSelectedFilters = (
activity: TIssueActivityComment[],
filters: TActivityFilters[]
): TIssueActivityComment[] =>
activity.filter((activity) => filters.includes(activity.activity_type as TActivityFilters));
activity.filter((activity) => {
if (activity.activity_type === EActivityFilterType.DEFAULT) return true;
return filters.includes(activity.activity_type as TActivityFilters);
});
export const ENABLE_ISSUE_DEPENDENCIES = false;

View file

@ -56,6 +56,21 @@ export type TIssueActivityComment =
activity_type: "ACTIVITY";
created_at?: string;
}
| {
id: string;
activity_type: "STATE";
created_at?: string;
}
| {
id: string;
activity_type: "ASSIGNEE";
created_at?: string;
}
| {
id: string;
activity_type: "DEFAULT";
created_at?: string;
}
| {
id: string;
activity_type: "WORKLOG";