Skip to content

Instantly share code, notes, and snippets.

@quoctrungdh
Created May 14, 2020 15:42
Show Gist options
  • Save quoctrungdh/47a91708978a852c9d71d89f75ccc04d to your computer and use it in GitHub Desktop.
Save quoctrungdh/47a91708978a852c9d71d89f75ccc04d to your computer and use it in GitHub Desktop.

Revisions

  1. quoctrungdh created this gist May 14, 2020.
    127 changes: 127 additions & 0 deletions Project-Branch.git
    Original 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();