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:
parent
b30e41f324
commit
220389e74e
56 changed files with 637 additions and 1510 deletions
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue