UNPKG

q42-cms-components

Version:

Front-end package that provides a UI on top of the QMS back-end

127 lines (111 loc) 4.07 kB
import _keyBy from 'lodash/keyBy'; import { ServerStore } from './server-store.js'; export class CRUDStore extends ServerStore { static get docs() { return `CRUDStore is een ServerStore subclass die een standaard REST API voor collecties implementeert, en ook het bijbehorende JSON schema ophaalt. <ul> <li><code>path</code> geeft de url van de API aan, het schema komt van <code><i>path</i>/schema</code> <li><code>options</code> heeft dezelfde properties als bij ServerStore. </ul> <b>Reactive data properties</b> <ul> <li><code>items</code> De lijst met items in de collectie. De items bevatten niet alle properties, gebruik daarvoor <code>getItemById</code>. <li><code>schema</code> Het JSON schema van de items in de collectie <li><code>fields</code> Object met velden voor het <a href="#listing"><code>listing</code></a> component <li><code>displayField</code> De propertynaam van de items die kan worden gebruikt om de item te tonen. </ul>` } constructor(path, options) { let { initial = {}, loaders = {}, computed = {} } = options || {}; super({ initial: { items: [], fetchItemsError: null, schema: { properties: {} }, ...initial }, loaders: { items: () => this.fetch(this.path).catch(error => { if (error.message) { this.state.fetchItemsError = error.message; } // fallback for not getting an undefined as value return []; }), schema: () => this.fetch(`${this.path}/schema`), ...loaders }, computed: { fields: () => this.fieldsObjectForProps(Object.keys(this.schema.properties)), displayField: () => { // Get first field from schema properties what is nice to show ('string-input') in a relation-picker. // Most of the time this is a Title or a Name property. for (const entry of Object.entries(this.schema.properties)) { const [ key, value ] = entry; if (value.format === 'string-input') { return key; } } // fallback to Guid of a CmsItem return 'id'; }, indexedItems: () => { return _keyBy(this.items, 'id'); }, ...computed } }); this.path = path; } create(item) { // when creating an item, the id is an empty string (comes from schema) // id & created will be set by the server delete item.id; delete item.created; return this.postJson(this.path, item).then(this.updaters.items); } static get createDocs() { return `POST een nieuw item en update de lijst met items.`; } update(item) { return this.putJson(`${this.path}/${item.id}`, item).then(this.updaters.items); } static get updateDocs() { return `PUT een bestaand item en update de lijst met items.`; } upsert(item) { return item.id ? this.update(item) : this.create(item); } static get upsertDocs() { return `Als het item nog geen <code>id</code> heeft, doe een <code>create</code>, anders een <code>update</code>.`; } delete(item) { return this.del(`${this.path}/${item.id}`).then(this.updaters.items); } static get deleteDocs() { return `DELETE een bestaand item en update de lijst met items.`; } getItemById(id) { return this.fetch(`${this.path}/${id}`) .catch(error => { if (error.message) { this.state.fetchItemsError = error.message; } }); } static get getItemByIdDocs() { return `GET een item, inclusief alle details.`; } fieldsObjectForProps(propNames) { var fields = {}; var props = this.schema.properties; propNames.forEach(name => { var prop = props[name]; if (prop && prop.title) { fields[prop.title] = name; } }); return fields; } }