chore: issue activity, comments, and comment reaction store and component restructure (#3428)
* fix: issue activity and comment change * chore: posthog enabled * chore: comment creation in activity * chore: comment crud in store mutation * fix: issue activity/ comments `disable` and `showAccessSpecifier` logic. * chore: comment reaction serializer change * conflicts: merge conflicts resolved * conflicts: merge conflicts resolved * chore: add issue activity/ comments to peek-overview. * imporve `showAccessIdentifier` logic. * chore: remove quotes from issue activity. * chore: use `projectLabels` instead of `workspaceLabels` in labels activity. * fix: project publish `is_deployed` not updating bug. * cleanup * fix: posthog enabled * fix: typos and the comment endpoint updates * fix: issue activity icons update --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
This commit is contained in:
parent
bb50df0dff
commit
f88109ef04
66 changed files with 2555 additions and 395 deletions
|
|
@ -271,6 +271,11 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
|||
const issueToCycle = await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, {
|
||||
issues: issueIds,
|
||||
});
|
||||
|
||||
issueIds.map((issueId) => {
|
||||
this.rootIssueStore.issues.updateIssue(issueId, { cycle_id: cycleId });
|
||||
});
|
||||
|
||||
return issueToCycle;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
|
|||
|
|
@ -1,57 +1,61 @@
|
|||
import { action, computed, makeObservable, observable, runInAction } from "mobx";
|
||||
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||
import set from "lodash/set";
|
||||
import sortBy from "lodash/sortBy";
|
||||
import update from "lodash/update";
|
||||
import concat from "lodash/concat";
|
||||
import uniq from "lodash/uniq";
|
||||
// services
|
||||
import { IssueService } from "services/issue";
|
||||
import { IssueActivityService } from "services/issue";
|
||||
// types
|
||||
import { IIssueDetail } from "./root.store";
|
||||
import { TIssueActivity, TIssueActivityIdMap, TIssueActivityMap } from "@plane/types";
|
||||
import { TIssueActivityComment, TIssueActivity, TIssueActivityMap, TIssueActivityIdMap } from "@plane/types";
|
||||
|
||||
export type TActivityLoader = "fetch" | "mutate" | undefined;
|
||||
|
||||
export interface IIssueActivityStoreActions {
|
||||
// actions
|
||||
fetchActivities: (workspaceSlug: string, projectId: string, issueId: string) => Promise<TIssueActivity[]>;
|
||||
fetchActivities: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
loaderType?: TActivityLoader
|
||||
) => Promise<TIssueActivity[]>;
|
||||
}
|
||||
|
||||
export interface IIssueActivityStore extends IIssueActivityStoreActions {
|
||||
// observables
|
||||
loader: TActivityLoader;
|
||||
activities: TIssueActivityIdMap;
|
||||
activityMap: TIssueActivityMap;
|
||||
// computed
|
||||
issueActivities: string[] | undefined;
|
||||
// helper methods
|
||||
getActivitiesByIssueId: (issueId: string) => string[] | undefined;
|
||||
getActivityById: (activityId: string) => TIssueActivity | undefined;
|
||||
getActivityCommentByIssueId: (issueId: string) => TIssueActivityComment[] | undefined;
|
||||
}
|
||||
|
||||
export class IssueActivityStore implements IIssueActivityStore {
|
||||
// observables
|
||||
loader: TActivityLoader = "fetch";
|
||||
activities: TIssueActivityIdMap = {};
|
||||
activityMap: TIssueActivityMap = {};
|
||||
// root store
|
||||
rootIssueDetailStore: IIssueDetail;
|
||||
// services
|
||||
issueService;
|
||||
issueActivityService;
|
||||
|
||||
constructor(rootStore: IIssueDetail) {
|
||||
makeObservable(this, {
|
||||
// observables
|
||||
loader: observable.ref,
|
||||
activities: observable,
|
||||
activityMap: observable,
|
||||
// computed
|
||||
issueActivities: computed,
|
||||
// actions
|
||||
fetchActivities: action,
|
||||
});
|
||||
// root store
|
||||
this.rootIssueDetailStore = rootStore;
|
||||
// services
|
||||
this.issueService = new IssueService();
|
||||
}
|
||||
|
||||
// computed
|
||||
get issueActivities() {
|
||||
const issueId = this.rootIssueDetailStore.peekIssue?.issueId;
|
||||
if (!issueId) return undefined;
|
||||
return this.activities[issueId] ?? undefined;
|
||||
this.issueActivityService = new IssueActivityService();
|
||||
}
|
||||
|
||||
// helper methods
|
||||
|
|
@ -65,17 +69,73 @@ export class IssueActivityStore implements IIssueActivityStore {
|
|||
return this.activityMap[activityId] ?? undefined;
|
||||
};
|
||||
|
||||
getActivityCommentByIssueId = (issueId: string) => {
|
||||
if (!issueId) return undefined;
|
||||
|
||||
let activityComments: TIssueActivityComment[] = [];
|
||||
|
||||
const activities = this.getActivitiesByIssueId(issueId) || [];
|
||||
const comments = this.rootIssueDetailStore.comment.getCommentsByIssueId(issueId) || [];
|
||||
|
||||
activities.forEach((activityId) => {
|
||||
const activity = this.getActivityById(activityId);
|
||||
if (!activity) return;
|
||||
activityComments.push({
|
||||
id: activity.id,
|
||||
activity_type: "ACTIVITY",
|
||||
created_at: activity.created_at,
|
||||
});
|
||||
});
|
||||
|
||||
comments.forEach((commentId) => {
|
||||
const comment = this.rootIssueDetailStore.comment.getCommentById(commentId);
|
||||
if (!comment) return;
|
||||
activityComments.push({
|
||||
id: comment.id,
|
||||
activity_type: "COMMENT",
|
||||
created_at: comment.created_at,
|
||||
});
|
||||
});
|
||||
|
||||
activityComments = sortBy(activityComments, "created_at");
|
||||
activityComments = activityComments.map((activityComment) => ({
|
||||
id: activityComment.id,
|
||||
activity_type: activityComment.activity_type,
|
||||
}));
|
||||
|
||||
return activityComments;
|
||||
};
|
||||
|
||||
// actions
|
||||
fetchActivities = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
fetchActivities = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
loaderType: TActivityLoader = "fetch"
|
||||
) => {
|
||||
try {
|
||||
const activities = await this.issueService.getIssueActivities(workspaceSlug, projectId, issueId);
|
||||
this.loader = loaderType;
|
||||
|
||||
let props = {};
|
||||
const _activityIds = this.getActivitiesByIssueId(issueId);
|
||||
if (_activityIds && _activityIds.length > 0) {
|
||||
const _activity = this.getActivityById(_activityIds[_activityIds.length - 1]);
|
||||
if (_activity) props = { created_at__gt: _activity.created_at };
|
||||
}
|
||||
|
||||
const activities = await this.issueActivityService.getIssueActivities(workspaceSlug, projectId, issueId, props);
|
||||
|
||||
const activityIds = activities.map((activity) => activity.id);
|
||||
|
||||
runInAction(() => {
|
||||
set(this.activities, issueId, activityIds);
|
||||
update(this.activities, issueId, (_activityIds) => {
|
||||
if (!_activityIds) return activityIds;
|
||||
return uniq(concat(_activityIds, activityIds));
|
||||
});
|
||||
activities.forEach((activity) => {
|
||||
set(this.activityMap, activity.id, activity);
|
||||
});
|
||||
this.loader = undefined;
|
||||
});
|
||||
|
||||
return activities;
|
||||
|
|
|
|||
|
|
@ -1,31 +1,55 @@
|
|||
import { action, makeObservable, runInAction } from "mobx";
|
||||
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||
import set from "lodash/set";
|
||||
import update from "lodash/update";
|
||||
import concat from "lodash/concat";
|
||||
import uniq from "lodash/uniq";
|
||||
import pull from "lodash/pull";
|
||||
// services
|
||||
import { IssueCommentService } from "services/issue";
|
||||
// types
|
||||
import { IIssueDetail } from "./root.store";
|
||||
import { TIssueActivity } from "@plane/types";
|
||||
import { TIssueComment, TIssueCommentMap, TIssueCommentIdMap } from "@plane/types";
|
||||
|
||||
export type TCommentLoader = "fetch" | "create" | "update" | "delete" | "mutate" | undefined;
|
||||
|
||||
export interface IIssueCommentStoreActions {
|
||||
fetchComments: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
loaderType?: TCommentLoader
|
||||
) => Promise<TIssueComment[]>;
|
||||
createComment: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: Partial<TIssueActivity>
|
||||
data: Partial<TIssueComment>
|
||||
) => Promise<any>;
|
||||
updateComment: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: Partial<TIssueActivity>
|
||||
data: Partial<TIssueComment>
|
||||
) => Promise<any>;
|
||||
removeComment: (workspaceSlug: string, projectId: string, issueId: string, commentId: string) => Promise<any>;
|
||||
}
|
||||
|
||||
export interface IIssueCommentStore extends IIssueCommentStoreActions {}
|
||||
export interface IIssueCommentStore extends IIssueCommentStoreActions {
|
||||
// observables
|
||||
loader: TCommentLoader;
|
||||
comments: TIssueCommentIdMap;
|
||||
commentMap: TIssueCommentMap;
|
||||
// helper methods
|
||||
getCommentsByIssueId: (issueId: string) => string[] | undefined;
|
||||
getCommentById: (activityId: string) => TIssueComment | undefined;
|
||||
}
|
||||
|
||||
export class IssueCommentStore implements IIssueCommentStore {
|
||||
// observables
|
||||
loader: TCommentLoader = "fetch";
|
||||
comments: TIssueCommentIdMap = {};
|
||||
commentMap: TIssueCommentMap = {};
|
||||
// root store
|
||||
rootIssueDetail: IIssueDetail;
|
||||
// services
|
||||
|
|
@ -33,7 +57,12 @@ export class IssueCommentStore implements IIssueCommentStore {
|
|||
|
||||
constructor(rootStore: IIssueDetail) {
|
||||
makeObservable(this, {
|
||||
// observables
|
||||
loader: observable.ref,
|
||||
comments: observable,
|
||||
commentMap: observable,
|
||||
// actions
|
||||
fetchComments: action,
|
||||
createComment: action,
|
||||
updateComment: action,
|
||||
removeComment: action,
|
||||
|
|
@ -44,13 +73,64 @@ export class IssueCommentStore implements IIssueCommentStore {
|
|||
this.issueCommentService = new IssueCommentService();
|
||||
}
|
||||
|
||||
createComment = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssueActivity>) => {
|
||||
// helper methods
|
||||
getCommentsByIssueId = (issueId: string) => {
|
||||
if (!issueId) return undefined;
|
||||
return this.comments[issueId] ?? undefined;
|
||||
};
|
||||
|
||||
getCommentById = (commentId: string) => {
|
||||
if (!commentId) return undefined;
|
||||
return this.commentMap[commentId] ?? undefined;
|
||||
};
|
||||
|
||||
fetchComments = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
loaderType: TCommentLoader = "fetch"
|
||||
) => {
|
||||
try {
|
||||
this.loader = loaderType;
|
||||
|
||||
let props = {};
|
||||
const _commentIds = this.getCommentsByIssueId(issueId);
|
||||
if (_commentIds && _commentIds.length > 0) {
|
||||
const _comment = this.getCommentById(_commentIds[_commentIds.length - 1]);
|
||||
if (_comment) props = { created_at__gt: _comment.created_at };
|
||||
}
|
||||
|
||||
const comments = await this.issueCommentService.getIssueComments(workspaceSlug, projectId, issueId, props);
|
||||
|
||||
const commentIds = comments.map((comment) => comment.id);
|
||||
runInAction(() => {
|
||||
update(this.comments, issueId, (_commentIds) => {
|
||||
if (!_commentIds) return commentIds;
|
||||
return uniq(concat(_commentIds, commentIds));
|
||||
});
|
||||
comments.forEach((comment) => {
|
||||
this.rootIssueDetail.commentReaction.applyCommentReactions(comment.id, comment?.comment_reactions || []);
|
||||
set(this.commentMap, comment.id, comment);
|
||||
});
|
||||
this.loader = undefined;
|
||||
});
|
||||
|
||||
return comments;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
createComment = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssueComment>) => {
|
||||
try {
|
||||
const response = await this.issueCommentService.createIssueComment(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
runInAction(() => {
|
||||
this.rootIssueDetail.activity.activities[issueId].push(response.id);
|
||||
set(this.rootIssueDetail.activity.activityMap, response.id, response);
|
||||
update(this.comments, issueId, (_commentIds) => {
|
||||
if (!_commentIds) return [response.id];
|
||||
return uniq(concat(_commentIds, [response.id]));
|
||||
});
|
||||
set(this.commentMap, response.id, response);
|
||||
});
|
||||
|
||||
return response;
|
||||
|
|
@ -64,12 +144,12 @@ export class IssueCommentStore implements IIssueCommentStore {
|
|||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: Partial<TIssueActivity>
|
||||
data: Partial<TIssueComment>
|
||||
) => {
|
||||
try {
|
||||
runInAction(() => {
|
||||
Object.keys(data).forEach((key) => {
|
||||
set(this.rootIssueDetail.activity.activityMap, [commentId, key], data[key as keyof TIssueActivity]);
|
||||
set(this.commentMap, [commentId, key], data[key as keyof TIssueComment]);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -92,14 +172,10 @@ export class IssueCommentStore implements IIssueCommentStore {
|
|||
try {
|
||||
const response = await this.issueCommentService.deleteIssueComment(workspaceSlug, projectId, issueId, commentId);
|
||||
|
||||
const reactionIndex = this.rootIssueDetail.activity.activities[issueId].findIndex(
|
||||
(_comment) => _comment === commentId
|
||||
);
|
||||
if (reactionIndex >= 0)
|
||||
runInAction(() => {
|
||||
this.rootIssueDetail.activity.activities[issueId].splice(reactionIndex, 1);
|
||||
delete this.rootIssueDetail.activity.activityMap[commentId];
|
||||
});
|
||||
runInAction(() => {
|
||||
pull(this.comments[issueId], commentId);
|
||||
delete this.commentMap[commentId];
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||
import set from "lodash/set";
|
||||
import update from "lodash/update";
|
||||
import concat from "lodash/concat";
|
||||
import find from "lodash/find";
|
||||
import pull from "lodash/pull";
|
||||
// services
|
||||
import { IssueReactionService } from "services/issue";
|
||||
// types
|
||||
import { IIssueDetail } from "./root.store";
|
||||
import { TIssueCommentReaction, TIssueCommentReactionIdMap, TIssueCommentReactionMap } from "@plane/types";
|
||||
// helpers
|
||||
import { groupReactions } from "helpers/emoji.helper";
|
||||
|
||||
export interface IIssueCommentReactionStoreActions {
|
||||
// actions
|
||||
|
|
@ -13,6 +19,7 @@ export interface IIssueCommentReactionStoreActions {
|
|||
projectId: string,
|
||||
commentId: string
|
||||
) => Promise<TIssueCommentReaction[]>;
|
||||
applyCommentReactions: (commentId: string, commentReactions: TIssueCommentReaction[]) => void;
|
||||
createCommentReaction: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
|
|
@ -23,7 +30,8 @@ export interface IIssueCommentReactionStoreActions {
|
|||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
commentId: string,
|
||||
reaction: string
|
||||
reaction: string,
|
||||
userId: string
|
||||
) => Promise<any>;
|
||||
}
|
||||
|
||||
|
|
@ -32,8 +40,9 @@ export interface IIssueCommentReactionStore extends IIssueCommentReactionStoreAc
|
|||
commentReactions: TIssueCommentReactionIdMap;
|
||||
commentReactionMap: TIssueCommentReactionMap;
|
||||
// helper methods
|
||||
getCommentReactionsByCommentId: (commentId: string) => string[] | undefined;
|
||||
getCommentReactionsByCommentId: (commentId: string) => { [reaction_id: string]: string[] } | undefined;
|
||||
getCommentReactionById: (reactionId: string) => TIssueCommentReaction | undefined;
|
||||
commentReactionsByUser: (commentId: string, userId: string) => TIssueCommentReaction[];
|
||||
}
|
||||
|
||||
export class IssueCommentReactionStore implements IIssueCommentReactionStore {
|
||||
|
|
@ -52,6 +61,7 @@ export class IssueCommentReactionStore implements IIssueCommentReactionStore {
|
|||
commentReactionMap: observable,
|
||||
// actions
|
||||
fetchCommentReactions: action,
|
||||
applyCommentReactions: action,
|
||||
createCommentReaction: action,
|
||||
removeCommentReaction: action,
|
||||
});
|
||||
|
|
@ -72,25 +82,67 @@ export class IssueCommentReactionStore implements IIssueCommentReactionStore {
|
|||
return this.commentReactionMap[reactionId] ?? undefined;
|
||||
};
|
||||
|
||||
commentReactionsByUser = (commentId: string, userId: string) => {
|
||||
if (!commentId || !userId) return [];
|
||||
|
||||
const reactions = this.getCommentReactionsByCommentId(commentId);
|
||||
if (!reactions) return [];
|
||||
|
||||
const _userReactions: TIssueCommentReaction[] = [];
|
||||
Object.keys(reactions).forEach((reaction) => {
|
||||
if (reactions?.[reaction])
|
||||
reactions?.[reaction].map((reactionId) => {
|
||||
const currentReaction = this.getCommentReactionById(reactionId);
|
||||
if (currentReaction && currentReaction.actor === userId) _userReactions.push(currentReaction);
|
||||
});
|
||||
});
|
||||
|
||||
return _userReactions;
|
||||
};
|
||||
|
||||
// actions
|
||||
fetchCommentReactions = async (workspaceSlug: string, projectId: string, commentId: string) => {
|
||||
try {
|
||||
const reactions = await this.issueReactionService.listIssueCommentReactions(workspaceSlug, projectId, commentId);
|
||||
const response = await this.issueReactionService.listIssueCommentReactions(workspaceSlug, projectId, commentId);
|
||||
|
||||
const reactionIds = reactions.map((reaction) => reaction.id);
|
||||
runInAction(() => {
|
||||
set(this.commentReactions, commentId, reactionIds);
|
||||
reactions.forEach((reaction) => {
|
||||
set(this.commentReactionMap, reaction.id, reaction);
|
||||
});
|
||||
const groupedReactions = groupReactions(response || [], "reaction");
|
||||
|
||||
const commentReactionIdsMap: { [reaction: string]: string[] } = {};
|
||||
|
||||
Object.keys(groupedReactions).map((reactionId) => {
|
||||
const reactionIds = (groupedReactions[reactionId] || []).map((reaction) => reaction.id);
|
||||
commentReactionIdsMap[reactionId] = reactionIds;
|
||||
});
|
||||
|
||||
return reactions;
|
||||
runInAction(() => {
|
||||
set(this.commentReactions, commentId, commentReactionIdsMap);
|
||||
response.forEach((reaction) => set(this.commentReactionMap, reaction.id, reaction));
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
applyCommentReactions = (commentId: string, commentReactions: TIssueCommentReaction[]) => {
|
||||
const groupedReactions = groupReactions(commentReactions || [], "reaction");
|
||||
|
||||
const commentReactionIdsMap: { [reaction: string]: string[] } = {};
|
||||
|
||||
Object.keys(groupedReactions).map((reactionId) => {
|
||||
const reactionIds = (groupedReactions[reactionId] || []).map((reaction) => reaction.id);
|
||||
commentReactionIdsMap[reactionId] = reactionIds;
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
set(this.commentReactions, commentId, commentReactionIdsMap);
|
||||
commentReactions.forEach((reaction) => set(this.commentReactionMap, reaction.id, reaction));
|
||||
});
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
createCommentReaction = async (workspaceSlug: string, projectId: string, commentId: string, reaction: string) => {
|
||||
try {
|
||||
const response = await this.issueReactionService.createIssueCommentReaction(workspaceSlug, projectId, commentId, {
|
||||
|
|
@ -98,7 +150,10 @@ export class IssueCommentReactionStore implements IIssueCommentReactionStore {
|
|||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.commentReactions[commentId].push(response.id);
|
||||
update(this.commentReactions, [commentId, reaction], (reactionId) => {
|
||||
if (!reactionId) return [response.id];
|
||||
return concat(reactionId, response.id);
|
||||
});
|
||||
set(this.commentReactionMap, response.id, response);
|
||||
});
|
||||
|
||||
|
|
@ -108,14 +163,23 @@ export class IssueCommentReactionStore implements IIssueCommentReactionStore {
|
|||
}
|
||||
};
|
||||
|
||||
removeCommentReaction = async (workspaceSlug: string, projectId: string, commentId: string, reaction: string) => {
|
||||
removeCommentReaction = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
commentId: string,
|
||||
reaction: string,
|
||||
userId: string
|
||||
) => {
|
||||
try {
|
||||
const reactionIndex = this.commentReactions[commentId].findIndex((_reaction) => _reaction === reaction);
|
||||
if (reactionIndex >= 0)
|
||||
const userReactions = this.commentReactionsByUser(commentId, userId);
|
||||
const currentReaction = find(userReactions, { actor: userId, reaction: reaction });
|
||||
|
||||
if (currentReaction && currentReaction.id) {
|
||||
runInAction(() => {
|
||||
this.commentReactions[commentId].splice(reactionIndex, 1);
|
||||
pull(this.commentReactions[commentId][reaction], currentReaction.id);
|
||||
delete this.commentReactionMap[reaction];
|
||||
});
|
||||
}
|
||||
|
||||
const response = await this.issueReactionService.deleteIssueCommentReaction(
|
||||
workspaceSlug,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ export class IssueStore implements IIssueStore {
|
|||
// fetch issue activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
|
||||
// fetch issue comments
|
||||
this.rootIssueDetailStore.comment.fetchComments(workspaceSlug, projectId, issueId);
|
||||
|
||||
// fetch issue subscription
|
||||
this.rootIssueDetailStore.subscription.fetchSubscriptions(workspaceSlug, projectId, issueId);
|
||||
|
||||
|
|
@ -92,36 +95,63 @@ export class IssueStore implements IIssueStore {
|
|||
}
|
||||
};
|
||||
|
||||
updateIssue = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.projectIssues.updateIssue(workspaceSlug, projectId, issueId, data);
|
||||
updateIssue = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => {
|
||||
const issue = await this.rootIssueDetailStore.rootIssueStore.projectIssues.updateIssue(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
issueId,
|
||||
data
|
||||
);
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return issue;
|
||||
};
|
||||
|
||||
removeIssue = async (workspaceSlug: string, projectId: string, issueId: string) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.projectIssues.removeIssue(workspaceSlug, projectId, issueId);
|
||||
|
||||
addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.cycleIssues.addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||
addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||
const cycle = await this.rootIssueDetailStore.rootIssueStore.cycleIssues.addIssueToCycle(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
cycleId,
|
||||
issueIds
|
||||
);
|
||||
if (issueIds && issueIds.length > 0)
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueIds[0]);
|
||||
return cycle;
|
||||
};
|
||||
|
||||
removeIssueFromCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.cycleIssues.removeIssueFromCycle(
|
||||
removeIssueFromCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => {
|
||||
const cycle = await this.rootIssueDetailStore.rootIssueStore.cycleIssues.removeIssueFromCycle(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
cycleId,
|
||||
issueId
|
||||
);
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return cycle;
|
||||
};
|
||||
|
||||
addIssueToModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.moduleIssues.addIssueToModule(
|
||||
addIssueToModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => {
|
||||
const _module = await this.rootIssueDetailStore.rootIssueStore.moduleIssues.addIssueToModule(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
moduleId,
|
||||
issueIds
|
||||
);
|
||||
if (issueIds && issueIds.length > 0)
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueIds[0]);
|
||||
return _module;
|
||||
};
|
||||
|
||||
removeIssueFromModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueId: string) =>
|
||||
this.rootIssueDetailStore.rootIssueStore.moduleIssues.removeIssueFromModule(
|
||||
removeIssueFromModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueId: string) => {
|
||||
const _module = await this.rootIssueDetailStore.rootIssueStore.moduleIssues.removeIssueFromModule(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
moduleId,
|
||||
issueId
|
||||
);
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return _module;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ export class IssueLinkStore implements IIssueLinkStore {
|
|||
set(this.linkMap, response.id, response);
|
||||
});
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
@ -123,6 +125,8 @@ export class IssueLinkStore implements IIssueLinkStore {
|
|||
|
||||
const response = await this.issueService.updateIssueLink(workspaceSlug, projectId, issueId, linkId, data);
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
// TODO: fetch issue detail
|
||||
|
|
@ -141,6 +145,8 @@ export class IssueLinkStore implements IIssueLinkStore {
|
|||
delete this.linkMap[linkId];
|
||||
});
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
|
|||
|
|
@ -79,10 +79,11 @@ export class IssueReactionStore implements IIssueReactionStore {
|
|||
|
||||
const _userReactions: TIssueReaction[] = [];
|
||||
Object.keys(reactions).forEach((reaction) => {
|
||||
reactions[reaction].map((reactionId) => {
|
||||
const currentReaction = this.getReactionById(reactionId);
|
||||
if (currentReaction && currentReaction.actor === userId) _userReactions.push(currentReaction);
|
||||
});
|
||||
if (reactions?.[reaction])
|
||||
reactions?.[reaction].map((reactionId) => {
|
||||
const currentReaction = this.getReactionById(reactionId);
|
||||
if (currentReaction && currentReaction.actor === userId) _userReactions.push(currentReaction);
|
||||
});
|
||||
});
|
||||
|
||||
return _userReactions;
|
||||
|
|
@ -126,6 +127,8 @@ export class IssueReactionStore implements IIssueReactionStore {
|
|||
set(this.reactionMap, response.id, response);
|
||||
});
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
@ -152,6 +155,8 @@ export class IssueReactionStore implements IIssueReactionStore {
|
|||
|
||||
const response = await this.issueReactionService.deleteIssueReaction(workspaceSlug, projectId, issueId, reaction);
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ export class IssueRelationStore implements IIssueRelationStore {
|
|||
});
|
||||
});
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
@ -149,6 +151,8 @@ export class IssueRelationStore implements IIssueRelationStore {
|
|||
related_issue,
|
||||
});
|
||||
|
||||
// fetching activity
|
||||
this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
return response;
|
||||
} catch (error) {
|
||||
this.fetchRelations(workspaceSlug, projectId, issueId);
|
||||
|
|
|
|||
|
|
@ -3,20 +3,20 @@ import { action, computed, makeObservable, observable } from "mobx";
|
|||
import { IIssueRootStore } from "../root.store";
|
||||
import { IIssueStore, IssueStore, IIssueStoreActions } from "./issue.store";
|
||||
import { IIssueReactionStore, IssueReactionStore, IIssueReactionStoreActions } from "./reaction.store";
|
||||
import { IIssueActivityStore, IssueActivityStore, IIssueActivityStoreActions } from "./activity.store";
|
||||
import { IIssueCommentStore, IssueCommentStore, IIssueCommentStoreActions } from "./comment.store";
|
||||
import {
|
||||
IIssueCommentReactionStore,
|
||||
IssueCommentReactionStore,
|
||||
IIssueCommentReactionStoreActions,
|
||||
} from "./comment_reaction.store";
|
||||
import { IIssueLinkStore, IssueLinkStore, IIssueLinkStoreActions } from "./link.store";
|
||||
import { IIssueSubscriptionStore, IssueSubscriptionStore, IIssueSubscriptionStoreActions } from "./subscription.store";
|
||||
import { IIssueAttachmentStore, IssueAttachmentStore, IIssueAttachmentStoreActions } from "./attachment.store";
|
||||
import { IIssueSubIssuesStore, IssueSubIssuesStore, IIssueSubIssuesStoreActions } from "./sub_issues.store";
|
||||
import { IIssueRelationStore, IssueRelationStore, IIssueRelationStoreActions } from "./relation.store";
|
||||
import { IIssueActivityStore, IssueActivityStore, IIssueActivityStoreActions, TActivityLoader } from "./activity.store";
|
||||
import { IIssueCommentStore, IssueCommentStore, IIssueCommentStoreActions, TCommentLoader } from "./comment.store";
|
||||
import {
|
||||
IIssueCommentReactionStore,
|
||||
IssueCommentReactionStore,
|
||||
IIssueCommentReactionStoreActions,
|
||||
} from "./comment_reaction.store";
|
||||
|
||||
import { TIssue, IIssueActivity, TIssueLink, TIssueRelationTypes } from "@plane/types";
|
||||
import { TIssue, TIssueComment, TIssueCommentReaction, TIssueLink, TIssueRelationTypes } from "@plane/types";
|
||||
|
||||
export type TPeekIssue = {
|
||||
workspaceSlug: string;
|
||||
|
|
@ -27,14 +27,14 @@ export type TPeekIssue = {
|
|||
export interface IIssueDetail
|
||||
extends IIssueStoreActions,
|
||||
IIssueReactionStoreActions,
|
||||
IIssueActivityStoreActions,
|
||||
IIssueCommentStoreActions,
|
||||
IIssueCommentReactionStoreActions,
|
||||
IIssueLinkStoreActions,
|
||||
IIssueSubIssuesStoreActions,
|
||||
IIssueSubscriptionStoreActions,
|
||||
IIssueAttachmentStoreActions,
|
||||
IIssueRelationStoreActions {
|
||||
IIssueRelationStoreActions,
|
||||
IIssueActivityStoreActions,
|
||||
IIssueCommentStoreActions,
|
||||
IIssueCommentReactionStoreActions {
|
||||
// observables
|
||||
peekIssue: TPeekIssue | undefined;
|
||||
isIssueLinkModalOpen: boolean;
|
||||
|
|
@ -72,13 +72,13 @@ export class IssueDetail implements IIssueDetail {
|
|||
issue: IIssueStore;
|
||||
reaction: IIssueReactionStore;
|
||||
attachment: IIssueAttachmentStore;
|
||||
activity: IIssueActivityStore;
|
||||
comment: IIssueCommentStore;
|
||||
commentReaction: IIssueCommentReactionStore;
|
||||
subIssues: IIssueSubIssuesStore;
|
||||
link: IIssueLinkStore;
|
||||
subscription: IIssueSubscriptionStore;
|
||||
relation: IIssueRelationStore;
|
||||
activity: IIssueActivityStore;
|
||||
comment: IIssueCommentStore;
|
||||
commentReaction: IIssueCommentReactionStore;
|
||||
|
||||
constructor(rootStore: IIssueRootStore) {
|
||||
makeObservable(this, {
|
||||
|
|
@ -150,31 +150,6 @@ export class IssueDetail implements IIssueDetail {
|
|||
userId: string
|
||||
) => this.reaction.removeReaction(workspaceSlug, projectId, issueId, reaction, userId);
|
||||
|
||||
// activity
|
||||
fetchActivities = async (workspaceSlug: string, projectId: string, issueId: string) =>
|
||||
this.activity.fetchActivities(workspaceSlug, projectId, issueId);
|
||||
|
||||
// comment
|
||||
createComment = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<IIssueActivity>) =>
|
||||
this.comment.createComment(workspaceSlug, projectId, issueId, data);
|
||||
updateComment = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: Partial<IIssueActivity>
|
||||
) => this.comment.updateComment(workspaceSlug, projectId, issueId, commentId, data);
|
||||
removeComment = async (workspaceSlug: string, projectId: string, issueId: string, commentId: string) =>
|
||||
this.comment.removeComment(workspaceSlug, projectId, issueId, commentId);
|
||||
|
||||
// comment reaction
|
||||
fetchCommentReactions = async (workspaceSlug: string, projectId: string, commentId: string) =>
|
||||
this.commentReaction.fetchCommentReactions(workspaceSlug, projectId, commentId);
|
||||
createCommentReaction = async (workspaceSlug: string, projectId: string, commentId: string, reaction: string) =>
|
||||
this.commentReaction.createCommentReaction(workspaceSlug, projectId, commentId, reaction);
|
||||
removeCommentReaction = async (workspaceSlug: string, projectId: string, commentId: string, reaction: string) =>
|
||||
this.commentReaction.removeCommentReaction(workspaceSlug, projectId, commentId, reaction);
|
||||
|
||||
// attachments
|
||||
fetchAttachments = async (workspaceSlug: string, projectId: string, issueId: string) =>
|
||||
this.attachment.fetchAttachments(workspaceSlug, projectId, issueId);
|
||||
|
|
@ -240,4 +215,38 @@ export class IssueDetail implements IIssueDetail {
|
|||
relationType: TIssueRelationTypes,
|
||||
relatedIssue: string
|
||||
) => this.relation.removeRelation(workspaceSlug, projectId, issueId, relationType, relatedIssue);
|
||||
|
||||
// activity
|
||||
fetchActivities = async (workspaceSlug: string, projectId: string, issueId: string, loaderType?: TActivityLoader) =>
|
||||
this.activity.fetchActivities(workspaceSlug, projectId, issueId, loaderType);
|
||||
|
||||
// comment
|
||||
fetchComments = async (workspaceSlug: string, projectId: string, issueId: string, loaderType?: TCommentLoader) =>
|
||||
this.comment.fetchComments(workspaceSlug, projectId, issueId, loaderType);
|
||||
createComment = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssueComment>) =>
|
||||
this.comment.createComment(workspaceSlug, projectId, issueId, data);
|
||||
updateComment = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
commentId: string,
|
||||
data: Partial<TIssueComment>
|
||||
) => this.comment.updateComment(workspaceSlug, projectId, issueId, commentId, data);
|
||||
removeComment = async (workspaceSlug: string, projectId: string, issueId: string, commentId: string) =>
|
||||
this.comment.removeComment(workspaceSlug, projectId, issueId, commentId);
|
||||
|
||||
// comment reaction
|
||||
fetchCommentReactions = async (workspaceSlug: string, projectId: string, commentId: string) =>
|
||||
this.commentReaction.fetchCommentReactions(workspaceSlug, projectId, commentId);
|
||||
applyCommentReactions = async (commentId: string, commentReactions: TIssueCommentReaction[]) =>
|
||||
this.commentReaction.applyCommentReactions(commentId, commentReactions);
|
||||
createCommentReaction = async (workspaceSlug: string, projectId: string, commentId: string, reaction: string) =>
|
||||
this.commentReaction.createCommentReaction(workspaceSlug, projectId, commentId, reaction);
|
||||
removeCommentReaction = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
commentId: string,
|
||||
reaction: string,
|
||||
userId: string
|
||||
) => this.commentReaction.removeCommentReaction(workspaceSlug, projectId, commentId, reaction, userId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,6 +264,10 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||
issues: issueIds,
|
||||
});
|
||||
|
||||
issueIds.map((issueId) => {
|
||||
this.rootIssueStore.issues.updateIssue(issueId, { module_id: moduleId });
|
||||
});
|
||||
|
||||
return issueToModule;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue