<template> <Modal :model-value="modelValue" v-on:update:model-value="onModalUpdateValue" title="New folder"> <form v-on:submit.prevent="addFolder"> <div class="field is-horizontal"> <div class="field-label"> <label class="label">Name</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <input type="text" class="input" v-model="name" /> </div> </div> </div> </div> <div class="field is-horizontal"> <div class="field-label"> <label class="label">Type</label> </div> <div class="field-body"> <div class="field"> <div class="control"> <span class="select is-fullwidth"> <select v-model="typeSlug" class="select" :disabled="availableTypes.length < 1 || null"> <option value="" disabled selected>Select a type</option> <option v-for="{ slug, display_name } in availableTypes" :key="slug" :value="slug"> {{ truncateSelect(display_name) }} </option> </select> </span> </div> </div> </div> </div> </form> <template v-slot:footer> <button class="button is-primary" :class="{ 'is-loading': loading }" :disabled="loading || !canWrite(corpus) || !typeSlug || !name || null" v-on:click="addFolder" > Add folder </button> </template> </Modal> </template> <script> import { mapMutations } from 'vuex' import { errorParser } from '@/helpers' import { truncateMixin, corporaMixin } from '@/mixins.js' import Modal from '@/components/Modal.vue' export default { mixins: [ truncateMixin, corporaMixin ], components: { Modal }, emits: ['update:modelValue'], props: { modelValue: { type: Boolean, required: true }, corpusId: { type: String, required: true }, parentId: { type: String, default: null } }, data: () => ({ loading: false, typeSlug: '', name: '' }), computed: { availableTypes () { return this.corpus ? this.folderTypes(this.corpus.types) : [] } }, methods: { ...mapMutations('notifications', ['notify']), async addFolder () { if (this.loading || !this.canWrite(this.corpus) || !this.typeSlug || !this.name) return this.loading = true try { const folder = await this.$store.dispatch('elements/create', { corpus: this.corpusId, parent: this.parentId, type: this.typeSlug, name: this.name }) // Display a notification with a link to the folder const type = this.availableTypes.find(t => t.slug === this.typeSlug) this.notify({ type: 'success', text: 'Successfully created', link: { text: `${(type && type.display_name.toLowerCase()) || this.typeSlug} "${this.name}"`, route: { name: 'element-details', params: { id: folder.id } } } }) } catch (e) { this.notify({ type: 'error', text: `An error occurred while creating the folder: ${errorParser(e)}` }) } finally { this.loading = false this.$emit('update:modelValue', false) } }, onModalUpdateValue (value) { // Propagate the value updates to allow v-model on this component this.$emit('update:modelValue', value) } }, watch: { availableTypes (newTypes) { // Unselect any non-existent type if (!newTypes.some(t => t.slug === this.typeSlug)) this.typeSlug = '' // Autoselect when there is only one folder type if (newTypes.length === 1 && this.typeSlug === '') this.typeSlug = newTypes[0].slug } } } </script>