Move list edit/namespace to separate pages and in a menu (#397)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/397 Co-authored-by: konrad <konrad@kola-entertainments.de> Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
@ -1,201 +0,0 @@
|
||||
<template>
|
||||
<div class="loader-container is-max-width-desktop" v-bind:class="{ 'is-loading': namespaceService.loading}">
|
||||
<div class="notification is-warning" v-if="namespace.isArchived">
|
||||
This namespace is archived.
|
||||
It is not possible to create new lists or edit it.
|
||||
</div>
|
||||
<card title="Edit Namespace">
|
||||
<form @submit.prevent="submit()">
|
||||
<div class="field">
|
||||
<label class="label" for="namespacetext">Namespace Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
class="input"
|
||||
id="namespacetext"
|
||||
placeholder="The namespace text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="namespace.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="namespacedescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
:preview-is-default="false"
|
||||
id="namespacedescription"
|
||||
placeholder="The namespaces description goes here..."
|
||||
v-if="editorActive"
|
||||
v-model="namespace.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="namespace.isArchived"
|
||||
v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'">
|
||||
This namespace is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="namespace.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="field has-addons mt-4">
|
||||
<div class="control is-fullwidth">
|
||||
<x-button
|
||||
@click="submit()"
|
||||
:loading="namespaceService.loading"
|
||||
class="is-fullwidth"
|
||||
>
|
||||
Save
|
||||
</x-button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<x-button
|
||||
@click="showDeleteModal = true"
|
||||
:loading="namespaceService.loading"
|
||||
class="is-danger"
|
||||
icon="trash-alt"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</card>
|
||||
|
||||
<component
|
||||
:id="namespace.id"
|
||||
:is="manageUsersComponent"
|
||||
:userIsAdmin="userIsAdmin"
|
||||
shareType="user"
|
||||
type="namespace"/>
|
||||
<component
|
||||
:id="namespace.id"
|
||||
:is="manageTeamsComponent"
|
||||
:userIsAdmin="userIsAdmin"
|
||||
shareType="team"
|
||||
type="namespace"/>
|
||||
|
||||
<transition name="modal">
|
||||
<modal
|
||||
@close="showDeleteModal = false"
|
||||
v-if="showDeleteModal"
|
||||
@submit="deleteNamespace()">
|
||||
<span slot="header">Delete the namespace</span>
|
||||
<p slot="text">Are you sure you want to delete this namespace and all of its contents?
|
||||
<br/>This includes lists & tasks and <b>CANNOT BE UNDONE!</b></p>
|
||||
</modal>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '../../router'
|
||||
import manageSharing from '../../components/sharing/userTeam'
|
||||
|
||||
import NamespaceService from '../../services/namespace'
|
||||
import NamespaceModel from '../../models/namespace'
|
||||
import Fancycheckbox from '../../components/input/fancycheckbox'
|
||||
import ColorPicker from '../../components/input/colorPicker'
|
||||
import LoadingComponent from '../../components/misc/loading'
|
||||
import ErrorComponent from '../../components/misc/error'
|
||||
|
||||
export default {
|
||||
name: 'EditNamespace',
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
manageUsersComponent: '',
|
||||
manageTeamsComponent: '',
|
||||
|
||||
namespace: NamespaceModel,
|
||||
showDeleteModal: false,
|
||||
editorActive: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ColorPicker,
|
||||
Fancycheckbox,
|
||||
manageSharing,
|
||||
editor: () => ({
|
||||
component: import(/* webpackChunkName: "editor" */ '../../components/input/editor'),
|
||||
loading: LoadingComponent,
|
||||
error: ErrorComponent,
|
||||
timeout: 60000,
|
||||
}),
|
||||
},
|
||||
beforeMount() {
|
||||
this.namespace.id = this.$route.params.id
|
||||
},
|
||||
created() {
|
||||
this.namespaceService = new NamespaceService()
|
||||
this.namespace = new NamespaceModel()
|
||||
this.loadNamespace()
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadNamespace',
|
||||
},
|
||||
computed: {
|
||||
userIsAdmin() {
|
||||
return this.namespace.owner && this.namespace.owner.id === this.$store.state.auth.info.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadNamespace() {
|
||||
// This makes the editor trigger its mounted function again which makes it forget every input
|
||||
// it currently has in its textarea. This is a counter-hack to a hack inside of vue-easymde
|
||||
// which made it impossible to detect change from the outside. Therefore the component would
|
||||
// not update if new content from the outside was made available.
|
||||
// See https://github.com/NikulinIlya/vue-easymde/issues/3
|
||||
this.editorActive = false
|
||||
this.$nextTick(() => this.editorActive = true)
|
||||
|
||||
let namespace = new NamespaceModel({id: this.$route.params.id})
|
||||
this.namespaceService.get(namespace)
|
||||
.then(r => {
|
||||
this.$set(this, 'namespace', r)
|
||||
// This will trigger the dynamic loading of components once we actually have all the data to pass to them
|
||||
this.manageTeamsComponent = 'manageSharing'
|
||||
this.manageUsersComponent = 'manageSharing'
|
||||
this.setTitle(`Edit ${this.namespace.title}`)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
submit() {
|
||||
this.namespaceService.update(this.namespace)
|
||||
.then(r => {
|
||||
// Update the namespace in the parent
|
||||
this.$store.commit('namespaces/setNamespaceById', r)
|
||||
this.success({message: 'The namespace was successfully updated.'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
deleteNamespace() {
|
||||
this.namespaceService.delete(this.namespace)
|
||||
.then(() => {
|
||||
this.$store.commit('namespaces/removeNamespaceById', this.namespace.id)
|
||||
this.success({message: 'The namespace was successfully deleted.'}, this)
|
||||
router.push({name: 'home'})
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<create
|
||||
<create-edit
|
||||
title="Create a new namespace"
|
||||
@create="newNamespace()"
|
||||
:create-disabled="namespace.title === ''"
|
||||
@ -39,13 +39,13 @@
|
||||
>
|
||||
What's a namespace?
|
||||
</p>
|
||||
</create>
|
||||
</create-edit>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NamespaceModel from '../../models/namespace'
|
||||
import NamespaceService from '../../services/namespace'
|
||||
import Create from '@/components/misc/create'
|
||||
import CreateEdit from '@/components/misc/create-edit'
|
||||
import ColorPicker from '../../components/input/colorPicker'
|
||||
|
||||
export default {
|
||||
@ -59,7 +59,7 @@ export default {
|
||||
},
|
||||
components: {
|
||||
ColorPicker,
|
||||
Create,
|
||||
CreateEdit,
|
||||
},
|
||||
created() {
|
||||
this.namespace = new NamespaceModel()
|
||||
|
52
src/views/namespaces/settings/archive.vue
Normal file
52
src/views/namespaces/settings/archive.vue
Normal file
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<modal
|
||||
@close="$router.back()"
|
||||
@submit="archiveNamespace()"
|
||||
>
|
||||
<span slot="header">{{ namespace.isArchived ? 'Un-' : '' }}Archive this namespace</span>
|
||||
<p slot="text" v-if="namespace.isArchived">
|
||||
You will be able to create new lists or edit it.
|
||||
</p>
|
||||
<p slot="text" v-else>
|
||||
You won't be able to edit this namespace or create new list until you un-archive it.<br/>
|
||||
This will also archive all lists in this namespace.
|
||||
</p>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NamespaceService from '@/services/namespace'
|
||||
|
||||
export default {
|
||||
name: 'namespace-setting-archive',
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
namespace: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.namespaceService = new NamespaceService()
|
||||
this.namespace = this.$store.getters['namespaces/getNamespaceById'](this.$route.params.id)
|
||||
this.setTitle(`Archive "${this.namespace.title}"`)
|
||||
},
|
||||
methods: {
|
||||
archiveNamespace() {
|
||||
|
||||
this.namespace.isArchived = !this.namespace.isArchived
|
||||
|
||||
this.namespaceService.update(this.namespace)
|
||||
.then(r => {
|
||||
this.$store.commit('namespaces/setNamespaceById', r)
|
||||
this.success({message: 'The namespace was successfully archived.'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
.finally(() => {
|
||||
this.$router.back()
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
44
src/views/namespaces/settings/delete.vue
Normal file
44
src/views/namespaces/settings/delete.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<modal
|
||||
@close="$router.back()"
|
||||
@submit="deleteNamespace()"
|
||||
>
|
||||
<span slot="header">Delete this namespace</span>
|
||||
<p slot="text">Are you sure you want to delete this namespace and all of its contents?
|
||||
<br/>This includes all tasks and <b>CANNOT BE UNDONE!</b></p>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NamespaceService from '@/services/namespace'
|
||||
|
||||
export default {
|
||||
name: 'namespace-setting-delete',
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.namespaceService = new NamespaceService()
|
||||
|
||||
const namespace = this.$store.getters['namespaces/getNamespaceById'](this.$route.params.id)
|
||||
this.setTitle(`Delete "${namespace.title}"`)
|
||||
},
|
||||
methods: {
|
||||
deleteNamespace() {
|
||||
const namespace = this.$store.getters['namespaces/getNamespaceById'](this.$route.params.id)
|
||||
|
||||
this.namespaceService.delete(namespace)
|
||||
.then(() => {
|
||||
this.$store.commit('namespaces/removeNamespaceFromNamespaceById', namespace)
|
||||
this.success({message: 'The namespace was successfully deleted.'}, this)
|
||||
this.$router.push({name: 'home'})
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
137
src/views/namespaces/settings/edit.vue
Normal file
137
src/views/namespaces/settings/edit.vue
Normal file
@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<create-edit
|
||||
title="Edit This Namespace"
|
||||
primary-icon=""
|
||||
primary-label="Save"
|
||||
@primary="save"
|
||||
tertary="Delete"
|
||||
@tertary="$router.push({ name: 'namespace.settings.delete', params: { id: $route.params.id } })"
|
||||
>
|
||||
<form @submit.prevent="save()">
|
||||
<div class="field">
|
||||
<label class="label" for="namespacetext">Namespace Name</label>
|
||||
<div class="control">
|
||||
<input
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
class="input"
|
||||
id="namespacetext"
|
||||
placeholder="The namespace text is here..."
|
||||
type="text"
|
||||
v-focus
|
||||
v-model="namespace.title"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="namespacedescription">Description</label>
|
||||
<div class="control">
|
||||
<editor
|
||||
:class="{ 'disabled': namespaceService.loading}"
|
||||
:disabled="namespaceService.loading"
|
||||
:preview-is-default="false"
|
||||
id="namespacedescription"
|
||||
placeholder="The namespaces description goes here..."
|
||||
v-if="editorActive"
|
||||
v-model="namespace.description"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="isArchivedCheck">Is Archived</label>
|
||||
<div class="control">
|
||||
<fancycheckbox
|
||||
v-model="namespace.isArchived"
|
||||
v-tooltip="'If a namespace is archived, you cannot create new lists or edit it.'">
|
||||
This namespace is archived
|
||||
</fancycheckbox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Color</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="namespace.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</create-edit>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NamespaceService from '@/services/namespace'
|
||||
import NamespaceModel from '@/models/namespace'
|
||||
import Fancycheckbox from '@/components/input/fancycheckbox'
|
||||
import ColorPicker from '@/components/input/colorPicker'
|
||||
import LoadingComponent from '@/components/misc/loading'
|
||||
import ErrorComponent from '@/components/misc/error'
|
||||
import CreateEdit from '@/components/misc/create-edit'
|
||||
|
||||
export default {
|
||||
name: 'namespace-setting-edit',
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
|
||||
namespace: NamespaceModel,
|
||||
editorActive: false,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CreateEdit,
|
||||
ColorPicker,
|
||||
Fancycheckbox,
|
||||
editor: () => ({
|
||||
component: import(/* webpackChunkName: "editor" */ '@/components/input/editor'),
|
||||
loading: LoadingComponent,
|
||||
error: ErrorComponent,
|
||||
timeout: 60000,
|
||||
}),
|
||||
},
|
||||
beforeMount() {
|
||||
this.namespace.id = this.$route.params.id
|
||||
},
|
||||
created() {
|
||||
this.namespaceService = new NamespaceService()
|
||||
this.namespace = new NamespaceModel()
|
||||
this.loadNamespace()
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadNamespace',
|
||||
},
|
||||
methods: {
|
||||
loadNamespace() {
|
||||
// This makes the editor trigger its mounted function again which makes it forget every input
|
||||
// it currently has in its textarea. This is a counter-hack to a hack inside of vue-easymde
|
||||
// which made it impossible to detect change from the outside. Therefore the component would
|
||||
// not update if new content from the outside was made available.
|
||||
// See https://github.com/NikulinIlya/vue-easymde/issues/3
|
||||
this.editorActive = false
|
||||
this.$nextTick(() => this.editorActive = true)
|
||||
|
||||
const namespace = new NamespaceModel({id: this.$route.params.id})
|
||||
this.namespaceService.get(namespace)
|
||||
.then(r => {
|
||||
this.$set(this, 'namespace', r)
|
||||
// This will trigger the dynamic loading of components once we actually have all the data to pass to them
|
||||
this.manageTeamsComponent = 'manageSharing'
|
||||
this.manageUsersComponent = 'manageSharing'
|
||||
this.setTitle(`Edit "${r.title}"`)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
save() {
|
||||
this.namespaceService.update(this.namespace)
|
||||
.then(r => {
|
||||
// Update the namespace in the parent
|
||||
this.$store.commit('namespaces/setNamespaceById', r)
|
||||
this.success({message: 'The namespace was successfully updated.'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
77
src/views/namespaces/settings/share.vue
Normal file
77
src/views/namespaces/settings/share.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<create-edit
|
||||
title="Share this Namespace"
|
||||
primary-label=""
|
||||
>
|
||||
<component
|
||||
:id="namespace.id"
|
||||
:is="manageUsersComponent"
|
||||
:userIsAdmin="userIsAdmin"
|
||||
shareType="user"
|
||||
type="namespace"/>
|
||||
<component
|
||||
:id="namespace.id"
|
||||
:is="manageTeamsComponent"
|
||||
:userIsAdmin="userIsAdmin"
|
||||
shareType="team"
|
||||
type="namespace"/>
|
||||
</create-edit>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import manageSharing from '@/components/sharing/userTeam'
|
||||
import CreateEdit from '@/components/misc/create-edit'
|
||||
|
||||
import NamespaceService from '@/services/namespace'
|
||||
import NamespaceModel from '@/models/namespace'
|
||||
|
||||
export default {
|
||||
name: 'namespace-setting-share',
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
manageUsersComponent: '',
|
||||
manageTeamsComponent: '',
|
||||
|
||||
namespace: NamespaceModel,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
CreateEdit,
|
||||
manageSharing,
|
||||
},
|
||||
beforeMount() {
|
||||
this.namespace.id = this.$route.params.id
|
||||
},
|
||||
created() {
|
||||
this.namespaceService = new NamespaceService()
|
||||
this.namespace = new NamespaceModel()
|
||||
this.loadNamespace()
|
||||
},
|
||||
watch: {
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadNamespace',
|
||||
},
|
||||
computed: {
|
||||
userIsAdmin() {
|
||||
return this.namespace.owner && this.namespace.owner.id === this.$store.state.auth.info.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadNamespace() {
|
||||
const namespace = new NamespaceModel({id: this.$route.params.id})
|
||||
this.namespaceService.get(namespace)
|
||||
.then(r => {
|
||||
this.$set(this, 'namespace', r)
|
||||
// This will trigger the dynamic loading of components once we actually have all the data to pass to them
|
||||
this.manageTeamsComponent = 'manageSharing'
|
||||
this.manageUsersComponent = 'manageSharing'
|
||||
this.setTitle(`Share "${this.namespace.title}"`)
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user