diff --git a/apps/app/store/labels.ts b/apps/app/store/labels.ts new file mode 100644 index 000000000..9e3452d1c --- /dev/null +++ b/apps/app/store/labels.ts @@ -0,0 +1,102 @@ +// mobx +import { action, observable, runInAction, makeObservable } from "mobx"; + +// services +import issueService from "services/issues.service"; + +// types +import type { IIssueLabels, LabelForm, ICurrentUserResponse } from "types"; + +class LabelStore { + labels: IIssueLabels[] = []; + rootStore: any | null = null; + + constructor(_rootStore: any | null = null) { + makeObservable(this, { + labels: observable.ref, + loadLabels: action, + createLabel: action, + updateLabel: action, + deleteLabel: action, + }); + + this.rootStore = _rootStore; + } + + loadLabels = async (workspaceSlug: string, projectId: string) => { + try { + const labelsResponse: IIssueLabels[] = await issueService.getIssueLabels( + workspaceSlug, + projectId + ); + runInAction(() => { + this.labels = labelsResponse; + }); + } catch (error) { + console.error("Fetching labels error", error); + } + }; + + createLabel = async ( + workspaceSlug: string, + projectId: string, + labelForm: LabelForm, + user: ICurrentUserResponse + ) => { + try { + const labelResponse: IIssueLabels = await issueService.createIssueLabel( + workspaceSlug, + projectId, + labelForm, + user + ); + runInAction(() => { + this.labels.push(labelResponse); + }); + } catch (error) { + console.error("Creating label error", error); + } + }; + + updateLabel = async ( + workspaceSlug: string, + projectId: string, + labelId: string, + labelForm: LabelForm, + user: ICurrentUserResponse + ) => { + try { + const labelResponse: IIssueLabels = await issueService.patchIssueLabel( + workspaceSlug, + projectId, + labelId, + labelForm, + user + ); + runInAction(() => { + const labelIndex = this.labels.findIndex((label) => label.id === labelId); + this.labels[labelIndex] = labelResponse; + }); + } catch (error) { + console.error("Updating label error", error); + } + }; + + deleteLabel = async ( + workspaceSlug: string, + projectId: string, + labelId: string, + user: ICurrentUserResponse + ) => { + try { + await issueService.deleteIssueLabel(workspaceSlug, projectId, labelId, user); + runInAction(() => { + this.labels = this.labels.filter((label) => label.id !== labelId); + }); + } catch (error) { + console.error("Deleting label error", error); + } + }; +} + +export default LabelStore; diff --git a/apps/app/store/root.ts b/apps/app/store/root.ts index 43daa32e6..4d081650e 100644 --- a/apps/app/store/root.ts +++ b/apps/app/store/root.ts @@ -3,15 +3,18 @@ import { enableStaticRendering } from "mobx-react-lite"; // store imports import UserStore from "./user"; import ThemeStore from "./theme"; +import LabelStore from "./labels"; enableStaticRendering(typeof window === "undefined"); export class RootStore { user; theme; + labels; constructor() { this.user = new UserStore(this); this.theme = new ThemeStore(this); + this.labels = new LabelStore(this); } } diff --git a/apps/app/types/issues.d.ts b/apps/app/types/issues.d.ts index 683704f9f..20271bdab 100644 --- a/apps/app/types/issues.d.ts +++ b/apps/app/types/issues.d.ts @@ -164,6 +164,15 @@ export interface IIssueLabels { parent: string | null; } +export interface LabelForm { + name: string; + description: string; + color: string; + project: string; + workspace: string; + parent: string | null; +} + export interface IIssueActivity { actor: string; actor_detail: IUserLite;