diff --git a/ui/src/stores/BaseStore.ts b/ui/src/stores/BaseStore.ts new file mode 100644 index 0000000..5976429 --- /dev/null +++ b/ui/src/stores/BaseStore.ts @@ -0,0 +1,51 @@ +import {action, observable} from 'mobx'; + +interface HasID { + id: number; +} + +export interface IClearable { + clear(): void; +} + +/** + * Base implementation for handling items with ids. + */ +export abstract class BaseStore implements IClearable { + @observable + protected items: T[] = []; + + protected abstract requestItems(): Promise; + + protected abstract requestDelete(id: number): Promise; + + @action + public remove = async (id: number): Promise => { + await this.requestDelete(id); + await this.refresh(); + }; + + @action + public refresh = async (): Promise => { + this.items = await this.requestItems().then((items) => items || []); + }; + + public getByID = (id: number): T => { + const item = this.getByIDOrUndefined(id); + if (item === undefined) { + throw new Error('cannot find item with id ' + id); + } + return item; + }; + + public getByIDOrUndefined = (id: number): T | undefined => { + return this.items.find((hasId: HasID) => hasId.id === id); + }; + + public getItems = (): T[] => this.items; + + @action + public clear = (): void => { + this.items = []; + }; +}