Skip to content
Snippets Groups Projects

Remove Group creation view, use a modal for creation and edition

Merged ml bonhomme requested to merge group-modal into master
All threads resolved!
1 file
+ 4
2
Compare changes
  • Side-by-side
  • Inline
<template>
<form v-on:submit.prevent="create">
<div class="field">
<label class="label">Name</label>
<div class="columns">
<div class="column">
<div class="control is-expanded">
<Modal
:title="modalTitle"
:model-value="modelValue"
v-on:update:model-value="value => $emit('update:modelValue', value)"
>
<form v-on:submit.prevent="groupAction">
<div class="field">
<label class="label">Name</label>
<div class="control is-expanded">
<input
type="text"
placeholder="Group name"
class="input"
v-model.trim="fields.name"
:class="{ 'is-danger': fieldErrors.name }"
:disabled="loading || undefined"
required
/>
</div>
<template v-if="fieldErrors.name">
<p
class="help is-danger"
v-for="err in fieldErrors.name"
:key="err"
>
{{ err }}
</p>
</template>
</div>
<div class="field ml-1">
<div class="control">
<label class="checkbox">
<input
type="text"
placeholder="Group name"
class="input"
v-model.trim="fields.name"
:class="{ 'is-danger': fieldErrors.name }"
type="checkbox"
v-model="fields.public"
:disabled="loading || undefined"
required
/>
</div>
<template v-if="fieldErrors.name">
<p
class="help is-danger"
v-for="err in fieldErrors.name"
:key="err"
>
{{ err }}
</p>
</template>
Publicly searchable
</label>
</div>
<div class="column is-narrow">
<button
type="submit"
class="button is-primary"
:class="{ 'is-loading': loading }"
:disabled="loading || undefined"
<p class="help">Make this group searchable by any authenticated user</p>
<template v-if="fieldErrors.public">
<p
class="help is-danger"
v-for="err in fieldErrors.public"
:key="err"
>
{{ group && group.id ? 'Update' : 'Create' }}
</button>
</div>
{{ err }}
</p>
</template>
</div>
</div>
<div class="field">
<div class="control">
<label class="checkbox">
<input
type="checkbox"
v-model="fields.public"
:disabled="loading || undefined"
/>
Publicly searchable
</label>
</div>
<p class="help">Make this group searchable to any authenticated user</p>
<template v-if="fieldErrors.public">
<p
class="help is-danger"
v-for="err in fieldErrors.public"
:key="err"
>
{{ err }}
</p>
</template>
</div>
</form>
</form>
<template v-slot:footer="{ close }">
<button class="button" v-on:click="close">Cancel</button>
<button
class="button is-primary"
:class="{ 'is-loading': loading }"
:disabled="loading || undefined"
v-on:click="groupAction"
>
{{ buttonTitle }}
</button>
</template>
</Modal>
</template>
<script lang="ts">
@@ -67,12 +70,38 @@ import { isAxiosError } from 'axios'
import { PropType, defineComponent } from 'vue'
import { mapActions } from 'pinia'
import Modal from '@/components/Modal.vue'
import { GroupEdit } from '@/api'
import { errorParser } from '@/helpers'
import { useNotificationStore, useRightsStore } from '@/stores'
import { Group } from '@/types'
import { truncateMixin } from '@/mixins'
export default defineComponent({
components: {
Modal
},
mixins: [
truncateMixin
],
emits: {
'update:modelValue': (value: boolean) => typeof value === 'boolean',
created: () => true
},
props: {
modelValue: {
type: Boolean,
default: false
},
/**
* The group Object is not required when a user wants to create a new group.
*/
group: {
type: Object as PropType<Group | null>,
default: null
}
},
data: () => ({
loading: false,
fields: {
@@ -84,14 +113,6 @@ export default defineComponent({
public: null
} as Record<keyof GroupEdit, string[] | null>
}),
emits: ['updated'],
// The group Object is not required when a user wants to create a new group.
props: {
group: {
type: Object as PropType<Group | null>,
default: null
}
},
created () {
if (!this.group) return
this.fields = {
@@ -102,7 +123,7 @@ export default defineComponent({
methods: {
...mapActions(useNotificationStore, ['notify']),
...mapActions(useRightsStore, ['createGroup', 'updateGroup']),
async create () {
async groupAction () {
if (!this.fields.name) {
this.fieldErrors.name = ['This field may not be blank.']
return
@@ -112,14 +133,15 @@ export default defineComponent({
try {
if (this.group && this.group.id) {
await this.updateGroup(this.group.id, this.fields)
// success notif and emit (close the Modal when updated)
this.notify({ type: 'success', text: 'Group details successfully updated' })
this.$emit('updated')
} else {
const group = await this.createGroup(this.fields)
// Handle automatic redirection
this.$router.push({ name: 'group-manage', params: { groupId: group.id } })
await this.createGroup(this.fields)
// Refresh the group list in the parent component
this.$emit('created')
this.notify({ type: 'success', text: `Group ${this.fields.name} successfully created` })
}
// Close the modal
this.$emit('update:modelValue', false)
} catch (err) {
if (isAxiosError(err) && err.response?.status === 400 && err.response.data) {
this.fieldErrors = err.response.data
@@ -130,6 +152,16 @@ export default defineComponent({
this.loading = false
}
}
},
computed: {
modalTitle () {
if (this.group?.id) return `Update group ${this.truncateShort(this.group.name)}`
return 'Create a new group'
},
buttonTitle () {
if (this.group?.id) return 'Update'
return 'Create'
}
}
})
</script>
Loading