Add cobalt JSON field type
This commit is contained in:
		
							parent
							
								
									b275391674
								
							
						
					
					
						commit
						c74e3b0685
					
				@ -1,4 +1,3 @@
 | 
			
		||||
- Cobalt form JSON field type - Setting resource
 | 
			
		||||
- MFA recovery codes handling
 | 
			
		||||
- Forgot password handling
 | 
			
		||||
    - Admin password reset mechanism -> flag users as needing PW resets
 | 
			
		||||
 | 
			
		||||
@ -74,6 +74,20 @@ const template = `
 | 
			
		||||
                    ></textarea>
 | 
			
		||||
                    <small class="form-text" style="color: darkred;" v-if="field.error">{{ field.error }}</small>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span v-if="field.type === 'json' && (Array.isArray(field.hidden) ? !field.hidden.includes(mode) : !field.hidden) && (typeof field.if !== 'function' || field.if(data))">
 | 
			
		||||
                    <label :for="uuid+field.field">{{ field.name }}</label>
 | 
			
		||||
                    <textarea
 | 
			
		||||
                        class="form-control"
 | 
			
		||||
                        :id="uuid+field.field"
 | 
			
		||||
                        v-model="data[field.field]"
 | 
			
		||||
                        :required="Array.isArray(field.required) ? field.required.includes(mode) : field.required"
 | 
			
		||||
                        :placeholder="field.placeholder"
 | 
			
		||||
                        :readonly="mode === 'view' || (Array.isArray(field.readonly) ? field.readonly.includes(mode) : field.readonly)"
 | 
			
		||||
                        ref="input"
 | 
			
		||||
                        rows="10"
 | 
			
		||||
                    ></textarea>
 | 
			
		||||
                    <small class="form-text" style="color: darkred;" v-if="field.error">{{ field.error }}</small>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span v-if="field.type === 'password' && (Array.isArray(field.hidden) ? !field.hidden.includes(mode) : !field.hidden) && (typeof field.if !== 'function' || field.if(data))">
 | 
			
		||||
                    <label :for="uuid+field.field">{{ field.name }}</label>
 | 
			
		||||
                    <input
 | 
			
		||||
@ -207,6 +221,10 @@ export default class FormComponent extends Component {
 | 
			
		||||
            if ( field.type.endsWith('.multiple') && !this.data[field.field] ) {
 | 
			
		||||
                this.data[field.field] = []
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ( field.type === 'json' ) {
 | 
			
		||||
                this.data[field.field] = JSON.stringify(this.data[field.field], undefined, 4)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.title = title_map[this.mode] + ' ' + this.resource_class.item
 | 
			
		||||
@ -224,25 +242,55 @@ export default class FormComponent extends Component {
 | 
			
		||||
        location_service.set_query(`mode=update&id=${this.id}`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data_to_save() {
 | 
			
		||||
        const data = Object.assign({}, this.data)
 | 
			
		||||
        for ( const field of this.definition.fields ) {
 | 
			
		||||
            if ( field.type === 'json' ) {
 | 
			
		||||
                data[field.field] = JSON.parse(data[field.field])
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return data
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data_to_restore(data) {
 | 
			
		||||
        const new_data = Object.assign({}, data)
 | 
			
		||||
        for ( const field of this.definition.fields ) {
 | 
			
		||||
            if ( field.type === 'json' ) {
 | 
			
		||||
                new_data[field.field] = JSON.stringify(data[field.field], undefined, 4)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        this.data = new_data
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async save_click() {
 | 
			
		||||
        if ( !this.validate() ) return
 | 
			
		||||
        try {
 | 
			
		||||
            if (this.mode === 'insert') {
 | 
			
		||||
                this.data = await this.resource_class.create(this.data)
 | 
			
		||||
                this.data_to_restore(await this.resource_class.create(this.data_to_save()))
 | 
			
		||||
                await this.on_create()
 | 
			
		||||
            } else if (this.mode === 'update') {
 | 
			
		||||
                await this.resource_class.update(this.id, this.data)
 | 
			
		||||
                await this.resource_class.update(this.id, this.data_to_save())
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.error_message = ''
 | 
			
		||||
            this.other_message = `The ${this.resource_class.item} was saved.`
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            console.error(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.'
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    is_json(string) {
 | 
			
		||||
        try {
 | 
			
		||||
            JSON.parse(string)
 | 
			
		||||
            return true
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
            return false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    validate() {
 | 
			
		||||
        let valid = true
 | 
			
		||||
        for ( const field of this.definition.fields ) {
 | 
			
		||||
@ -252,6 +300,9 @@ export default class FormComponent extends Component {
 | 
			
		||||
            } else if ( field.type === 'password' && this.data[field.field] !== this.data[field.field + '-confirm'] ) {
 | 
			
		||||
                field.error = field.name + ' confirmation does not match.'
 | 
			
		||||
                valid = false
 | 
			
		||||
            } else if ( field.type === 'json' && !this.is_json(this.data[field.field]) ) {
 | 
			
		||||
                field.error = field.name + ' must be valid JSON.'
 | 
			
		||||
                valid = false
 | 
			
		||||
            } else {
 | 
			
		||||
                field.error = ''
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ export default class CRUDBase {
 | 
			
		||||
 | 
			
		||||
    async create(properties) {
 | 
			
		||||
        for ( const field of this.required_fields ) {
 | 
			
		||||
            if ( !properties[field] ) throw new Error(`Missing required field: ${field}`)
 | 
			
		||||
            if ( !(field in properties) ) throw new Error(`Missing required field: ${field}`)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const results = await axios.post(this._endpoint(), properties)
 | 
			
		||||
@ -40,7 +40,7 @@ export default class CRUDBase {
 | 
			
		||||
 | 
			
		||||
    async update(id, properties) {
 | 
			
		||||
        for ( const field of this.required_fields ) {
 | 
			
		||||
            if ( !properties[field] ) throw new Error(`Missing required field: ${field}`)
 | 
			
		||||
            if ( !(field in properties) ) throw new Error(`Missing required field: ${field}`)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        await axios.patch(this._endpoint(id), properties)
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import CRUDBase from './CRUDBase.js'
 | 
			
		||||
import { session } from '../service/Session.service.js'
 | 
			
		||||
 | 
			
		||||
class SettingResource extends CRUDBase {
 | 
			
		||||
    endpoint = '/api/v1/settings'
 | 
			
		||||
@ -9,6 +10,9 @@ class SettingResource extends CRUDBase {
 | 
			
		||||
    plural = 'Settings'
 | 
			
		||||
 | 
			
		||||
    listing_definition = {
 | 
			
		||||
        display: `
 | 
			
		||||
        <p>These are advanced settings that allow you to tweak the way ${session.get('app.name')} behaves. Tweak them at your own risk.</p>
 | 
			
		||||
        `,
 | 
			
		||||
        columns: [
 | 
			
		||||
            {
 | 
			
		||||
                name: 'Setting Key',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user