mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
daa3094911
* chore: dynamic position dropdown (#2138) * chore: dynamic position state dropdown for issue view * style: state select dropdown styling * fix: state icon attribute names * chore: state select dynamic dropdown * chore: member select dynamic dropdown * chore: label select dynamic dropdown * chore: priority select dynamic dropdown * chore: label select dropdown improvement * refactor: state dropdown location * chore: dropdown improvement and code refactor * chore: dynamic dropdown hook type added --------- Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com> * fix: fields not getting selected in the create issue form (#2212) * fix: hydration error and draft issue workflow * fix: build error * fix: properties getting de-selected after create, module & cycle not getting auto-select on the form * fix: display layout, props being updated directly * chore: sub issues count in individual issue (#2221) * Implemented nested issues in the sub issues section in issue detail page (#2233) * feat: subissues infinte level * feat: updated UI for sub issues * feat: subissues new ui and nested sub issues in issue detail * chore: removed repeated code * refactor: product updates modal layout (#2225) * fix: handle no issues in custom analytics (#2226) * fix: activity label color (#2227) * fix: profile issues layout switch (#2228) * chore: update service imports * chore: update issue detail store to handle peek overview --------- Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Co-authored-by: Dakshesh Jain <65905942+dakshesh14@users.noreply.github.com> Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Co-authored-by: guru_sainath <gurusainath007@gmail.com>
215 lines
5.1 KiB
TypeScript
215 lines
5.1 KiB
TypeScript
import { observable, action, makeObservable, runInAction } from "mobx";
|
|
|
|
// services
|
|
import { IssueService } from "services/issue.service";
|
|
// types
|
|
import { RootStore } from "./root";
|
|
import { ICurrentUserResponse, IIssue } from "types";
|
|
|
|
export type IPeekMode = "side" | "modal" | "full";
|
|
|
|
export interface IIssueDetailStore {
|
|
loader: boolean;
|
|
error: any | null;
|
|
|
|
peekId: string | null;
|
|
peekMode: IPeekMode | null;
|
|
|
|
issues: {
|
|
[issueId: string]: IIssue;
|
|
};
|
|
|
|
setPeekId: (issueId: string | null) => void;
|
|
setPeekMode: (issueId: IPeekMode | null) => void;
|
|
// fetch issue details
|
|
fetchIssueDetails: (workspaceId: string, projectId: string, issueId: string) => void;
|
|
// creating issue
|
|
createIssue: (workspaceId: string, projectId: string, data: Partial<IIssue>, user: ICurrentUserResponse) => void;
|
|
// updating issue
|
|
updateIssue: (
|
|
workspaceId: string,
|
|
projectId: string,
|
|
issueId: string,
|
|
data: Partial<IIssue>,
|
|
user: ICurrentUserResponse
|
|
) => void;
|
|
// deleting issue
|
|
deleteIssue: (workspaceId: string, projectId: string, issueId: string, user: ICurrentUserResponse) => void;
|
|
}
|
|
|
|
class IssueDetailStore implements IIssueDetailStore {
|
|
loader: boolean = false;
|
|
error: any | null = null;
|
|
|
|
peekId: string | null = null;
|
|
peekMode: IPeekMode | null = null;
|
|
|
|
issues: {
|
|
[issueId: string]: IIssue;
|
|
} = {};
|
|
|
|
// root store
|
|
rootStore;
|
|
// service
|
|
issueService;
|
|
|
|
constructor(_rootStore: RootStore) {
|
|
makeObservable(this, {
|
|
// observable
|
|
loader: observable.ref,
|
|
error: observable.ref,
|
|
|
|
peekId: observable.ref,
|
|
peekMode: observable.ref,
|
|
|
|
issues: observable.ref,
|
|
|
|
setPeekId: action,
|
|
setPeekMode: action,
|
|
|
|
fetchIssueDetails: action,
|
|
createIssue: action,
|
|
updateIssue: action,
|
|
deleteIssue: action,
|
|
});
|
|
|
|
this.rootStore = _rootStore;
|
|
this.issueService = new IssueService();
|
|
}
|
|
|
|
setPeekId = (issueId: string | null) => (this.peekId = issueId);
|
|
|
|
setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode);
|
|
|
|
fetchIssueDetails = async (workspaceId: string, projectId: string, issueId: string) => {
|
|
try {
|
|
this.loader = true;
|
|
this.error = null;
|
|
|
|
const issueDetailsResponse = await this.issueService.retrieve(workspaceId, projectId, issueId);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = null;
|
|
this.issues = {
|
|
...this.issues,
|
|
[issueId]: issueDetailsResponse,
|
|
};
|
|
});
|
|
} catch (error) {
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = error;
|
|
});
|
|
|
|
return error;
|
|
}
|
|
};
|
|
|
|
createIssue = async (workspaceId: string, projectId: string, data: Partial<IIssue>, user: ICurrentUserResponse) => {
|
|
try {
|
|
runInAction(() => {
|
|
this.loader = true;
|
|
this.error = null;
|
|
});
|
|
|
|
const response = await this.issueService.createIssues(workspaceId, projectId, data, user);
|
|
|
|
if (response) this.rootStore.issue.addIssueToIssuesStore(projectId, response);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = null;
|
|
this.issues = {
|
|
...this.issues,
|
|
[response.id]: response,
|
|
};
|
|
});
|
|
} catch (error) {
|
|
this.loader = false;
|
|
this.error = error;
|
|
return error;
|
|
}
|
|
};
|
|
|
|
updateIssue = async (
|
|
workspaceId: string,
|
|
projectId: string,
|
|
issueId: string,
|
|
data: Partial<IIssue>,
|
|
user: ICurrentUserResponse
|
|
) => {
|
|
const newIssues = { ...this.issues };
|
|
newIssues[issueId] = {
|
|
...newIssues[issueId],
|
|
...data,
|
|
};
|
|
|
|
try {
|
|
runInAction(() => {
|
|
this.loader = true;
|
|
this.error = null;
|
|
this.issues = newIssues;
|
|
});
|
|
|
|
const response = await this.issueService.patchIssue(workspaceId, projectId, issueId, data, user);
|
|
|
|
if (response) this.rootStore.issue.updateIssueInIssuesStore(projectId, response);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = null;
|
|
this.issues = {
|
|
...this.issues,
|
|
[issueId]: {
|
|
...this.issues[issueId],
|
|
...response,
|
|
},
|
|
};
|
|
});
|
|
} catch (error) {
|
|
this.fetchIssueDetails(workspaceId, projectId, issueId);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = error;
|
|
});
|
|
|
|
return error;
|
|
}
|
|
};
|
|
|
|
deleteIssue = async (workspaceId: string, projectId: string, issueId: string, user: ICurrentUserResponse) => {
|
|
const newIssues = { ...this.issues };
|
|
delete newIssues[issueId];
|
|
|
|
try {
|
|
runInAction(() => {
|
|
this.loader = true;
|
|
this.error = null;
|
|
this.issues = newIssues;
|
|
});
|
|
|
|
await this.issueService.deleteIssue(workspaceId, projectId, issueId, user);
|
|
|
|
this.rootStore.issue.deleteIssueFromIssuesStore(projectId, issueId);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = null;
|
|
});
|
|
} catch (error) {
|
|
this.fetchIssueDetails(workspaceId, projectId, issueId);
|
|
|
|
runInAction(() => {
|
|
this.loader = false;
|
|
this.error = error;
|
|
});
|
|
|
|
return error;
|
|
}
|
|
};
|
|
}
|
|
|
|
export default IssueDetailStore;
|