import {Component} from '../../vues6.js'
import {Status} from './Listing.component.js'
import {Resource, ResourceActions} from '../Resource.js'
import {uuid} from '../util.js'
const template = `
`
export class FormComponent extends Component {
static get selector() { return 'cobalt-form' }
static get template() { return template }
static get props() { return ['resourcekey', 'resourceid', 'resourcemode'] }
constructor() {
super()
this.status = Status.loading
this.title = 'Loading...'
this.statusMessage = 'Loading...'
this.fields = []
this.data = {}
this.actions = []
this.unregister = []
this.mode = 'edit'
this.id = uuid()
this.internalResourceId = 0
this.errors = {}
/** @var {Resource} */
this.resource = undefined
}
async vue_on_create() {
this.resource = await Resource.get(this.resourcekey)
this.title = this.resource.singular()
this.mode = this.resourcemode || this.mode
this.internalResourceId = this.resourceid || this.internalResourceId
if ( !this.resource.supports(ResourceActions.readOne) ) {
this.status = Status.errorUnsupported
}
await this.load()
console.log('form', this)
}
async load() {
this.data = this.internalResourceId ? await this.resource.readOne(this.internalResourceId) : {}
this.fields = [...this.resource.configuration.fields].filter(f => {
return !(f.hideOn && f.hideOn.form)
})
this.fields.forEach(field => {
if ( field.type === 'date' && this.data[field.key] ) {
this.data[field.key] = new Date(this.data[field.key])
}
})
if ( this.resource.configuration.display.field ) {
this.title = this.resource.singular()
if ( this.internalResourceId ) this.title = `${this.title}: ${this.data[this.resource.configuration.display.field]}`
}
this.status = Status.ready
this.statusMessage = ''
}
onMonacoChange(field, data, args) {
console.log('on monaco change', {field, data, args})
this.data[field.key] = args[0]
console.log('after save', this.data)
}
async save() {
if ( !this.validate() ) return;
this.statusMessage = 'Saving...'
const values = {}
this.fields.forEach(field => {
let value = this.data[field.key]
const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) && (field.type !== 'bool')
if ( isUndef ) return;
if ( field.type === 'number' ) value = parseFloat(String(value))
if ( field.type === 'integer' ) value = parseInt(String(value), 10)
if ( field.type === 'date' ) value = value.toISOString()
if ( field.type === 'bool' ) value = !!value
values[field.key] = value
})
try {
if (this.internalResourceId) {
await this.resource.update(this.internalResourceId, values)
} else {
const result = await this.resource.create(values)
this.internalResourceId = result[this.resource.configuration.primaryKey]
history.replaceState({}, document.getElementsByTagName('title')[0].innerText, `${location.protocol}//${location.host}/dash/cobalt/form/${this.resource.key}/${this.internalResourceId}`)
}
await this.load()
this.statusMessage = `${this.resource.singular()} ${this.mode === 'insert' ? 'created' : 'saved'}`
this.mode = 'edit'
setTimeout(() => this.statusMessage = '', 7000)
} catch (e) {
console.error(e)
this.statusMessage = 'An unknown error occurred while saving'
}
}
validate() {
let pass = true
this.fields.forEach(field => this.errors[field.key] = undefined)
this.fields.forEach(field => {
// FIXME select
const value = this.data[field.key]
const isUndef = !value && !(['integer', 'number'].includes(field.type) && value === 0) && (field.type !== 'bool')
if ( field.required && isUndef ) {
this.errors[field.key] = 'This field is required'
pass = false
return
}
if ( field.type === 'date' && !isUndef && isNaN(value.getHours()) ) {
this.errors[field.key] = `Invalid ${field.renderer || 'date'}`
pass = false
return
}
if ( field.type === 'number' && !isUndef && isNaN(parseFloat(String(value))) ) {
this.errors[field.key] = 'Invalid number'
pass = false
return
}
if ( field.type === 'integer' && !isUndef && (isNaN(parseInt(String(value), 10)) || parseFloat(String(value)) !== parseInt(String(value), 10)) ) {
this.errors[field.key] = 'Invalid integer'
pass = false
return
}
})
this.$nextTick(() => this.$forceUpdate())
return pass
}
}