import { Component } from '../../lib/vues6/vues6.js' import { utility } from '../service/Utility.service.js' import { location_service } from '../service/Location.service.js' import { resource_service } from '../service/Resource.service.js' import { action_service } from '../service/Action.service.js' const template = `

{{ title }}

{{ field.error }} {{ field.error }}
{{ error_message }} {{ other_message }}
` const title_map = { insert: 'Create', update: 'Edit', view: 'View', } export default class FormComponent extends Component { static get selector() { return 'cobalt-form' } static get template() { return template } static get props() { return ['resource', 'form_id', 'initial_mode'] } definition = {} data = {} uuid = '' title = '' error_message = '' other_message = '' is_ready = false mode = '' id = '' reset() { this.definition = {} this.data = {} this.uuid = '' this.title = '' this.error_message = '' this.other_message = '' this.is_ready = false } async vue_on_create(internal = false) { if ( !internal ) { this.mode = this.initial_mode this.id = this.form_id this.resource_class = await resource_service.get(this.resource) } else { this.reset() } this.uuid = utility.uuid() await this.load() await this.init() } async init() { for ( const field of this.definition.fields ) { if ( field.type.startsWith('select.dynamic') ) { field._options = field._options || field.options const rsc = await resource_service.get(field._options.resource) field.options = (await rsc.list()).map(item => { return { display: typeof field._options.display === 'function' ? field._options.display(item) : item[field._options.display || 'display'], value: typeof field._options.value === 'function' ? field._options.value(item) : item[field._options.value || 'display'], } }) } if ( field.type.endsWith('.multiple') ) { this.data[field.field] = [] } } this.is_ready = true this.$nextTick(() => { if ( this.mode !== 'view' ) this.$refs.input[0].focus() }) } async load() { this.definition = this.resource_class.form_definition if (this.mode !== 'insert') { this.data = await this.resource_class.get(this.id) } this.title = title_map[this.mode] + ' ' + this.resource_class.item } async on_create() { this.id = this.data.id this.mode = 'update' await this.vue_on_create(true) location_service.set_query(`mode=update&id=${this.id}`) } async save_click() { if ( !this.validate() ) return try { if (this.mode === 'insert') { this.data = await this.resource_class.create(this.data) await this.on_create() } else if (this.mode === 'update') { await this.resource_class.update(this.id, this.data) } this.error_message = '' this.other_message = `The ${this.resource_class.item} was saved.` } catch (e) { if ( e.response && e.response.data && e.response.data.message ) this.error_message = e.response.data.message else this.error_message = 'An unknown error occurred while saving the form.' } } validate() { let valid = true for ( const field of this.definition.fields ) { if ( field.required && (!(field.field in this.data) || !this.data[field.field]) ) { field.error = 'This field is required.' valid = false } else { field.error = '' } } this.$forceUpdate() return valid } back() { return action_service.perform({ text: '', type: 'resource', resource: this.resource, action: 'list', }) } do_nothing() {} }