import pluralize from 'pluralize'; import { Observable } from 'rxjs/Observable'; import { ActionContract, ToolbarContract, XformToFormContract, XformToTableContract, XformToDocketContract, TableContract, FormContract, DocketContract } from '../../contracts'; import { Agent, CleverQueryService } from "../../services"; import { FormFactory } from "./form-factory"; import { ColumnsContract, TokenContract, Response } from "./contracts"; export abstract class Model extends Agent implements XformToFormContract, XformToTableContract, XformToDocketContract{ creatable: boolean = true; soloable: boolean = true; collectionable: boolean = true; deletable: boolean = true; editable: boolean = true; statusChangeable: boolean = true; soloType: string | 'docket' = 'docket'; collectionType: string | 'table' | 'lists' | 'cards' = 'lists'; localModelName: string; model: M; models: M[] = []; protected actions: ActionContract[]; protected toolbars: ToolbarContract[]; protected exclude: string[] = ['status', 'creatorId', 'createdAt', 'updatedAt']; protected remoteModelName: string; //remote db table name protected id: number; transform(datum: Object): M{ let d = {}; for (var key in datum) { if (datum.hasOwnProperty(key)) { d = Object.assign({}, d, { [this._.camelCase(key)]: datum[key] }); } } return d; } toModel(datum: Object, pure = false): M | this{ this.model = this.transform(datum); return (pure) ? this.model : this; } toModels(data: Object[], pure = false): M[] | this{ this.models = []; data.forEach((datum) => { this.models.push(this.transform(datum)); }); return (pure) ? this.models : this; } getColumns(): Observable { return this.aGet>(`${this.urls.base}/${this.remoteModelName}/columns`) .map((response) => { return response.data; }); } getRows(payload?: Object): Observable{ return this.aGet>(`${this.urls.base}/${this.remoteModelName}?payload=${JSON.stringify(payload)}`) .map((response) => { return response.data; }); } getRow(): Observable{ return this.aGet>(`${this.urls.base}/${this.remoteModelName}/${this.id}`) .map((response) => { return response.datum; }); } createEntity(payload: Object): Observable{ return this.aPost>(`${this.urls.base}/${this.remoteModelName}`, payload) .map((response) => { return response.datum; }); } updateEntity(payload: Object): Observable{ return this.aPost>(`${this.urls.base}/${this.remoteModelName}/${this.id}`, payload) .map((response) => { return response.datum; }); } deleteEntity(): Observable{ return this.aDelete>(`${this.urls.base}/${this.remoteModelName}/${this.id}`) .map((response) => { return response.datum; }); } getToken(body: Object): Observable{ return this.aPost>(`${this.urls.base}/${this.remoteModelName}/token`, body) .map((response) => { return response.datum; }); } resetToken(body: Object): Observable{ return this.aPost>(`${this.urls.base}/${this.remoteModelName}/reset`, body) .map((response) => { return response.datum; }); } setActions(actions: ActionContract[]): this{ this.actions = actions; return this; } setToolbars(toolbars: ToolbarContract[]): this{ this.toolbars = toolbars; return this; } toForm(resource: Object = {}): Observable{ return this.getColumns().map((columns) => { return (new FormFactory(columns, resource, this.exclude)).make(); }); } toTable(): Observable{ let rows: string[][] = [], columns: string[], tmpRow: string[]; this.models.forEach((model) => { tmpRow = []; if(!columns){ columns = Object.keys(model).filter((column)=>{ return !this.exclude.includes(column); }); } for(let column in model){ if(!this.exclude.includes(column)){ tmpRow.push(model[ column]); } } rows.push(tmpRow); }); return Observable.of({ title: null, columns: columns, rows: rows, summary: null, image: { title: null, url: null }, meta: null, actions: this.actions, toolbars: this.toolbars }); } toDocket(): Observable{ let rows: string[][] = []; for(let cell in this.model){ if(!this.exclude.includes( cell)){ rows.push([ cell, this.model[ cell]]); } } return Observable.of({ title: null, columns: ['Key', 'Value'], rows: rows, summary: null, image: { title: null, url: null }, meta: null, actions: this.actions, toolbars: this.toolbars }); } }