Some checks failed
continuous-integration/drone/push Build is failing
- Complete GGZ Ecademy Nuxt.js user portal - Learning products browser and management - Member management interface - User authentication and roles - Multi-language support (NL/EN) - Vuex store for state management - Component-based architecture
168 lines
4.3 KiB
Vue
168 lines
4.3 KiB
Vue
<template>
|
|
<v-card tile>
|
|
<v-toolbar dark color="primary" flat>
|
|
<v-toolbar-title>Add Component</v-toolbar-title>
|
|
<v-spacer></v-spacer>
|
|
<v-toolbar-items>
|
|
<v-btn dark text @click="saveComponent">Save</v-btn>
|
|
</v-toolbar-items>
|
|
</v-toolbar>
|
|
|
|
<!-- Components -->
|
|
<v-overflow-btn
|
|
:items="component_types"
|
|
v-model="componentSelected"
|
|
item-text="name"
|
|
return-object
|
|
label="Choose one"
|
|
hide-details
|
|
class="ma-4"
|
|
overflow
|
|
dense
|
|
flat
|
|
solo
|
|
></v-overflow-btn>
|
|
|
|
<v-row>
|
|
<v-col cols="12" sm="6">
|
|
<!-- Dynamic Component -->
|
|
<component :is="component" :data="model" />
|
|
<!-- End Dynamic Component -->
|
|
</v-col>
|
|
<v-col cols="12" sm="6" class="pr-4">
|
|
<v-form
|
|
ref="form"
|
|
v-model="valid"
|
|
:lazy-validation="lazy"
|
|
v-if="componentSelected"
|
|
class="my-4"
|
|
>
|
|
<v-text-field v-model="name" label="Name" :rules="nameRules" required></v-text-field>
|
|
<v-text-field
|
|
v-model="description"
|
|
label="Description"
|
|
:rules="descriptionRules"
|
|
required
|
|
></v-text-field>
|
|
</v-form>
|
|
|
|
<vue-form-generator
|
|
v-if="componentSelected"
|
|
:schema="componentSelected.schema"
|
|
:model="model"
|
|
:options="formOptions"
|
|
></vue-form-generator>
|
|
</v-col>
|
|
</v-row>
|
|
|
|
<v-tabs vertical v-if="componentSelected">
|
|
<v-tab>Data</v-tab>
|
|
<v-tab>Schema</v-tab>
|
|
<v-tab-item>
|
|
<pre v-if="model" v-html="model"></pre>
|
|
</v-tab-item>
|
|
<v-tab-item>
|
|
<pre v-if="componentSelected.schema" v-html="componentSelected.schema"></pre>
|
|
</v-tab-item>
|
|
</v-tabs>
|
|
|
|
<div class="d-flex ma-4">
|
|
<v-btn class="ma-2" color="info" tile depressed to="/manager/components">Back to components</v-btn>
|
|
<v-spacer></v-spacer>
|
|
<v-btn class="ma-2" color="success" tile depressed @click="saveComponent">Save Component</v-btn>
|
|
</div>
|
|
</v-card>
|
|
</template>
|
|
|
|
<script>
|
|
import VueFormGenerator from 'vue-form-generator'
|
|
import 'vue-form-generator/dist/vfg.css'
|
|
|
|
export default {
|
|
layout: `${process.env.CUSTOMER}Admin`,
|
|
components: {
|
|
'vue-form-generator': VueFormGenerator.component
|
|
},
|
|
data() {
|
|
return {
|
|
components: [],
|
|
dialog: false,
|
|
componentSelected: '',
|
|
component_types: [],
|
|
model: {},
|
|
name: '',
|
|
description: '',
|
|
valid: true,
|
|
lazy: false,
|
|
nameRules: [
|
|
v => !!v || 'Name is required',
|
|
v => (v && v.length <= 20) || 'Name must be less than 20 characters'
|
|
],
|
|
descriptionRules: [
|
|
v => !!v || 'Description is required',
|
|
v =>
|
|
(v && v.length <= 50) || 'Description must be less than 50 characters'
|
|
],
|
|
formOptions: {
|
|
validateAfterLoad: true,
|
|
validateAfterChanged: true,
|
|
validateAsync: true
|
|
}
|
|
}
|
|
},
|
|
computed: {
|
|
pageSlug() {
|
|
return this.$route.params.component
|
|
},
|
|
isNewComponent() {
|
|
return this.pageSlug.toLowerCase() === 'new'
|
|
},
|
|
hasComponents() {
|
|
return Object.keys(this.components).length > 0
|
|
},
|
|
isSlugNumber() {
|
|
return !isNaN(this.pageSlug)
|
|
},
|
|
isValidSlug() {
|
|
return this.isNewComponent || this.isSlugNumber
|
|
},
|
|
component() {
|
|
if (!this.componentSelected) return
|
|
return this.componentSelected.name
|
|
? () =>
|
|
import(
|
|
`@/components/DynamicComponents/${this.componentSelected.name}`
|
|
)
|
|
: null
|
|
}
|
|
},
|
|
mounted() {
|
|
this.getComponentTypes()
|
|
},
|
|
methods: {
|
|
async getComponentTypes() {
|
|
try {
|
|
const response = await this.$axios.get(`/component-types`)
|
|
this.component_types = response.data
|
|
} catch (error) {
|
|
console.log('TCL: getComponentTypes -> error', error)
|
|
}
|
|
},
|
|
async saveComponent() {
|
|
const data = {
|
|
name: this.name,
|
|
description: this.description || null,
|
|
content: this.model,
|
|
component_type_id: this.componentSelected.id
|
|
}
|
|
|
|
try {
|
|
const response = await this.$axios.post('/components', data)
|
|
this.$router.push('/manager/components')
|
|
} catch (error) {
|
|
console.log('TCL: saveComponent -> error', error)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script> |