Created
May 14, 2020 15:42
-
-
Save quoctrungdh/47a91708978a852c9d71d89f75ccc04d to your computer and use it in GitHub Desktop.
Revisions
-
quoctrungdh created this gist
May 14, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,127 @@ // FROM: https://dataform.co/blog/how-we-use-mobx-to-solve-our-frontend-state // https://assets.dataform.co/blog/archive/mobx_store.png import {action, computed, observable, runInAction} from 'mobx'; import Loadable from './loadable'; export default class Loadable<T> { // our state entity class public static create<T>(val?: T) { return new Loadable<T>(val); } @observable private value: T; @observable private loading: boolean = false; constructor(val?: T) { this.set(val); } public isLoading() { return this.loading; } public val() { return this.value; } public set(value: T) { this.loading = false; this.value = value; } public setLoading(loading: boolean) { this.loading = loading; } } interface IProject { projectName: string; projectId: string; } export class RootStore { @observable public currentProjectId: string = null; @observable public projectsList = Loadable.create<IProject[]>(); public readonly projectStoreMap = new Map<string, ProjectStore>(); public projectStore(projectId: string) { if (!this.projectStoreMap.has(projectId)) { const project = this.projectsList .val() .find(project => project.projectId === projectId); if (!project) { throw new Error('Project not found'); } this.projectStoreMap.set(projectId, new ProjectStore(project)); } return this.projectStoreMap.get(projectId); } @computed public get currentProjectStore() { return this.projectStore(this.currentProjectId); } @action public setCurrentProjectId(projectId: string) { this.currentProjectId = projectId; } @action.bound public async fetchProjectsList() { this.projectsList.setLoading(true); const response = await ApiService.get().projectList({}); runInAction('fetchProjectsListSuccess', () => this.projectsList.set(response.projects) ); } } interface IBranch { branchName: string; } class ProjectStore { public readonly currentProject: IProject; @observable public branchList = Loadable.create<IBranch[]>(); @observable public currentBranchName: string = null; public readonly branchStoreMap = new Map<string, BranchStore>(); constructor(project: IProject) { this.currentProject = project; } public branchStore(branchName: string) { if (!this.branchStoreMap.has(branchName)) { const branch = this.branchList .val() .find(branch => branch.branchName === branchName); if (!branch) { throw new Error('Branch not found'); } this.branchStoreMap.set(branchName, new BranchStore(branch)); } return this.branchStoreMap.get(branchName); } @computed public get currentBranchStore() { return this.branchStore(this.currentBranchName); } @action public setCurrentBranchName(branchName: string) { this.currentBranchName = branchName; } @action.bound public async fetchBranchList() { this.branchList.setLoading(true); const response = await ApiService.get().branchList({ projectId: this.currentProject.projectId, }); runInAction('fetchBranchListSuccess', () => this.branchList.set(response.branches) ); } } const rootStore = new RootStore();