chore: issue peek overview (#2918)

* chore: autorun for the issue detail store

* fix: labels mutation

* chore: remove old peek overview code

* chore: move add to cycle and module logic to store

* fix: build errors

* chore: add peekProjectId query param for the peek overview

* chore: update profile layout

* fix: multiple workspaces

* style: Issue activity and link design improvements in Peek overview.
* fix issue with labels not occupying full widht.
* fix links overflow issue.
* add tooltip in links to display entire link.
* add functionality to copy links to clipboard.

* chore: peek overview for all the layouts

* fix: build errors

---------

Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
Aaryan Khandelwal 2023-11-29 14:25:57 +05:30 committed by sriram veeraghanta
parent b30e41f324
commit 220389e74e
56 changed files with 637 additions and 1510 deletions

View file

@ -250,7 +250,7 @@ export class CycleIssueStore implements ICycleIssueStore {
if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;
this.rootStore.issueDetail.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
this.rootStore.projectIssues.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
};
deleteIssue = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {

View file

@ -76,7 +76,7 @@ export class CycleIssueCalendarViewStore implements ICycleIssueCalendarViewStore
this.rootStore.cycleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -289,7 +289,7 @@ export class CycleIssueKanBanViewStore implements ICycleIssueKanBanViewStore {
this.rootStore.cycleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,
@ -437,7 +437,7 @@ export class CycleIssueKanBanViewStore implements ICycleIssueKanBanViewStore {
this.rootStore.cycleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -278,7 +278,7 @@ export class IssueStore implements IIssueStore {
if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;
this.rootStore.issueDetail.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
this.rootStore.projectIssues.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
};
fetchIssues = async (

View file

@ -75,7 +75,7 @@ export class IssueCalendarViewStore implements IIssueCalendarViewStore {
this.rootStore.issue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -1,4 +1,4 @@
import { observable, action, makeObservable, runInAction, computed } from "mobx";
import { observable, action, makeObservable, runInAction, computed, autorun } from "mobx";
// services
import { IssueService, IssueReactionService, IssueCommentService } from "services/issue";
import { NotificationService } from "services/notification.service";
@ -7,8 +7,6 @@ import { RootStore } from "../root";
import { IIssue } from "types";
// constants
import { groupReactionEmojis } from "constants/issue";
// uuid
import { v4 as uuidv4 } from "uuid";
export interface IIssueDetailStore {
loader: boolean;
@ -44,11 +42,6 @@ export interface IIssueDetailStore {
// fetch issue details
fetchIssueDetails: (workspaceSlug: string, projectId: string, issueId: string) => Promise<IIssue>;
// creating issue
createIssue: (workspaceSlug: string, projectId: string, data: Partial<IIssue>) => Promise<IIssue>;
optimisticallyCreateIssue: (workspaceSlug: string, projectId: string, data: Partial<IIssue>) => Promise<IIssue>;
// updating issue
updateIssue: (workspaceId: string, projectId: string, issueId: string, data: Partial<IIssue>) => Promise<IIssue>;
// deleting issue
deleteIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise<void>;
@ -146,9 +139,6 @@ export class IssueDetailStore implements IIssueDetailStore {
setPeekId: action,
fetchIssueDetails: action,
createIssue: action,
optimisticallyCreateIssue: action,
updateIssue: action,
deleteIssue: action,
fetchPeekIssueDetails: action,
@ -171,6 +161,26 @@ export class IssueDetailStore implements IIssueDetailStore {
removeIssueSubscription: action,
});
autorun(() => {
const projectId = this.rootStore?.project.projectId;
const peekId = this.peekId;
if (!projectId || !peekId) return;
const issue = this.rootStore.projectIssues.issues?.[projectId]?.[peekId];
if (issue && issue.id)
runInAction(() => {
this.issues = {
...this.issues,
[issue.id]: {
...this.issues[issue.id],
...issue,
},
};
});
});
this.rootStore = _rootStore;
this.issueService = new IssueService();
this.issueReactionService = new IssueReactionService();
@ -238,111 +248,6 @@ export class IssueDetailStore implements IIssueDetailStore {
}
};
optimisticallyCreateIssue = async (workspaceSlug: string, projectId: string, data: Partial<IIssue>) => {
const tempId = data?.id || uuidv4();
runInAction(() => {
this.loader = true;
this.error = null;
this.issues = {
...this.issues,
[tempId]: data as IIssue,
};
});
try {
const response = await this.issueService.createIssue(workspaceSlug, projectId, data);
runInAction(() => {
this.loader = false;
this.error = null;
this.issues = {
...this.issues,
[response.id]: response,
};
});
return response;
} catch (error) {
this.loader = false;
this.error = error;
throw error;
}
};
createIssue = async (workspaceSlug: string, projectId: string, data: Partial<IIssue>) => {
try {
runInAction(() => {
this.loader = true;
this.error = null;
});
const response = await this.issueService.createIssue(workspaceSlug, projectId, data);
runInAction(() => {
this.loader = false;
this.error = null;
this.issues = {
...this.issues,
[response.id]: response,
};
});
return response;
} catch (error) {
this.loader = false;
this.error = error;
throw error;
}
};
updateIssue = async (workspaceSlug: string, projectId: string, issueId: string, data: Partial<IIssue>) => {
const newIssues = { ...this.issues };
newIssues[issueId] = {
...newIssues[issueId],
...data,
};
try {
runInAction(() => {
this.loader = true;
this.error = null;
this.issues = newIssues;
});
const user = this.rootStore.user.currentUser;
if (!user) return;
const response = await this.issueService.patchIssue(workspaceSlug, projectId, issueId, data);
runInAction(() => {
this.loader = false;
this.error = null;
this.issues = {
...this.issues,
[issueId]: {
...this.issues[issueId],
...response,
},
};
});
return response;
} catch (error) {
this.fetchIssueDetails(workspaceSlug, projectId, issueId);
runInAction(() => {
this.loader = false;
this.error = error;
});
return error;
}
};
deleteIssue = async (workspaceSlug: string, projectId: string, issueId: string) => {
const newIssues = { ...this.issues };
delete newIssues[issueId];

View file

@ -289,7 +289,7 @@ export class IssueKanBanViewStore implements IIssueKanBanViewStore {
this.rootStore.issue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,
@ -437,7 +437,7 @@ export class IssueKanBanViewStore implements IIssueKanBanViewStore {
this.rootStore.issue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -54,7 +54,7 @@ export interface IModuleIssuesStore {
moduleId: string,
issueIds: string[],
fetchAfterAddition?: boolean
) => Promise<IIssue>;
) => Promise<any>;
removeIssueFromModule: (
workspaceSlug: string,
projectId: string,
@ -193,7 +193,7 @@ export class ModuleIssuesStore extends IssueBaseStore implements IModuleIssuesSt
try {
const response = await this.rootStore.projectIssues.createIssue(workspaceSlug, projectId, data);
const issueToModule = await this.addIssueToModule(workspaceSlug, moduleId, [response.id], false);
await this.addIssueToModule(workspaceSlug, moduleId, [response.id], false);
let _issues = this.issues;
if (!_issues) _issues = {};
@ -204,7 +204,7 @@ export class ModuleIssuesStore extends IssueBaseStore implements IModuleIssuesSt
this.issues = _issues;
});
return issueToModule;
return response;
} catch (error) {
this.fetchIssues(workspaceSlug, projectId, "mutation", moduleId);
throw error;
@ -286,7 +286,7 @@ export class ModuleIssuesStore extends IssueBaseStore implements IModuleIssuesSt
const response = await this.createIssue(workspaceSlug, projectId, data, moduleId);
if (this.issues) {
if (this.issues && response) {
delete this.issues[moduleId][data.id as keyof IIssue];
let _issues = { ...this.issues };

View file

@ -260,7 +260,7 @@ export class ModuleIssueStore implements IModuleIssueStore {
if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;
this.rootStore.issueDetail.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
this.rootStore.projectIssues.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
};
deleteIssue = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {

View file

@ -76,7 +76,7 @@ export class ModuleIssueCalendarViewStore implements IModuleIssueCalendarViewSto
this.rootStore.moduleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -289,7 +289,7 @@ export class ModuleIssueKanBanViewStore implements IModuleIssueKanBanViewStore {
this.rootStore.moduleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,
@ -437,7 +437,7 @@ export class ModuleIssueKanBanViewStore implements IModuleIssueKanBanViewStore {
this.rootStore.moduleIssue.issues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -76,7 +76,7 @@ export class ProjectViewIssueCalendarViewStore implements IProjectViewIssueCalen
this.rootStore.projectViewIssues.viewIssues = { ...reorderedIssues };
});
this.rootStore.issueDetail?.updateIssue(
this.rootStore.projectIssues.updateIssue(
updateIssue.workspaceSlug,
updateIssue.projectId,
updateIssue.issueId,

View file

@ -278,7 +278,7 @@ export class ProjectViewIssuesStore implements IProjectViewIssuesStore {
if (newPayload.sort_order && payload.sort_order) newPayload.sort_order = payload.sort_order.newSortOrder;
this.rootStore.issueDetail.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
this.rootStore.projectIssues.updateIssue(workspaceSlug, issue.project, issue.id, newPayload);
};
deleteIssue = async (group_id: string | null, sub_group_id: string | null, issue: IIssue) => {