2019-03-07 20:48:40 +01:00
|
|
|
<template>
|
2021-06-03 22:23:04 +02:00
|
|
|
<div :class="{ 'is-loading': loading}" class="loader-container">
|
2021-01-17 18:57:57 +01:00
|
|
|
<x-button
|
|
|
|
:to="{name:'labels.create'}"
|
|
|
|
class="is-pulled-right"
|
|
|
|
icon="plus"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('label.create.header') }}
|
2021-01-17 18:57:57 +01:00
|
|
|
</x-button>
|
|
|
|
|
|
|
|
<div class="content">
|
2021-06-24 01:24:57 +02:00
|
|
|
<h1>{{ $t('label.manage') }}</h1>
|
|
|
|
<p v-if="Object.entries(labels).length > 0">
|
|
|
|
{{ $t('label.description') }}
|
2021-01-17 20:21:33 +01:00
|
|
|
</p>
|
2021-01-21 18:14:22 +01:00
|
|
|
<p v-else class="has-text-centered has-text-grey is-italic">
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('label.newCTA') }}
|
|
|
|
<router-link :to="{name:'labels.create'}">{{ $t('label.create.title') }}.</router-link>
|
2021-01-17 18:57:57 +01:00
|
|
|
</p>
|
|
|
|
</div>
|
|
|
|
|
2019-03-07 20:48:40 +01:00
|
|
|
<div class="columns">
|
|
|
|
<div class="labels-list column">
|
2019-10-26 14:39:27 +02:00
|
|
|
<span
|
2020-09-05 22:35:52 +02:00
|
|
|
:class="{'disabled': userInfo.id !== l.createdBy.id}" :key="l.id"
|
|
|
|
:style="{'background': l.hexColor, 'color': l.textColor}"
|
|
|
|
class="tag"
|
|
|
|
v-for="l in labels"
|
2019-03-07 20:48:40 +01:00
|
|
|
>
|
|
|
|
<span
|
2020-09-05 22:35:52 +02:00
|
|
|
v-if="userInfo.id !== l.createdBy.id"
|
2021-06-24 01:24:57 +02:00
|
|
|
v-tooltip.bottom="$t('label.edit.forbidden')">
|
2019-03-07 20:48:40 +01:00
|
|
|
{{ l.title }}
|
|
|
|
</span>
|
2019-10-26 14:39:27 +02:00
|
|
|
<a
|
2020-09-05 22:35:52 +02:00
|
|
|
:style="{'color': l.textColor}"
|
|
|
|
@click="editLabel(l)"
|
|
|
|
v-else>
|
2019-10-26 14:39:27 +02:00
|
|
|
{{ l.title }}
|
|
|
|
</a>
|
2020-09-05 22:35:52 +02:00
|
|
|
<a @click="deleteLabel(l)" class="delete is-small" v-if="userInfo.id === l.createdBy.id"></a>
|
2019-10-26 14:39:27 +02:00
|
|
|
</span>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
|
|
|
<div class="column is-4" v-if="isLabelEdit">
|
2021-06-24 01:24:57 +02:00
|
|
|
<card :title="$t('label.edit.header')" :has-close="true" @close="() => isLabelEdit = false">
|
2021-01-17 18:57:57 +01:00
|
|
|
<form @submit.prevent="editLabelSubmit()">
|
|
|
|
<div class="field">
|
2021-06-24 01:24:57 +02:00
|
|
|
<label class="label">{{ $t('label.attributes.title') }}</label>
|
2021-01-17 18:57:57 +01:00
|
|
|
<div class="control">
|
|
|
|
<input
|
|
|
|
class="input"
|
2021-06-24 01:24:57 +02:00
|
|
|
:placeholder="$t('label.attributes.titlePlaceholder')"
|
2021-01-17 18:57:57 +01:00
|
|
|
type="text"
|
|
|
|
v-model="labelEditLabel.title"/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="field">
|
2021-06-24 01:24:57 +02:00
|
|
|
<label class="label">{{ $t('label.attributes.description') }}</label>
|
2021-01-17 18:57:57 +01:00
|
|
|
<div class="control">
|
|
|
|
<editor
|
|
|
|
:preview-is-default="false"
|
2021-06-24 01:24:57 +02:00
|
|
|
:placeholder="$t('label.attributes.description')"
|
2021-01-17 18:57:57 +01:00
|
|
|
v-if="editorActive"
|
|
|
|
v-model="labelEditLabel.description"
|
|
|
|
/>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
2021-01-17 18:57:57 +01:00
|
|
|
</div>
|
|
|
|
<div class="field">
|
2021-06-24 01:24:57 +02:00
|
|
|
<label class="label">{{ $t('label.attributes.color') }}</label>
|
2021-01-17 18:57:57 +01:00
|
|
|
<div class="control">
|
|
|
|
<color-picker v-model="labelEditLabel.hexColor"/>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
2021-01-17 18:57:57 +01:00
|
|
|
</div>
|
|
|
|
<div class="field has-addons">
|
|
|
|
<div class="control is-expanded">
|
|
|
|
<x-button
|
2021-06-03 22:23:04 +02:00
|
|
|
:loading="loading"
|
2021-01-17 18:57:57 +01:00
|
|
|
class="is-fullwidth"
|
|
|
|
@click="editLabelSubmit()"
|
|
|
|
>
|
2021-06-24 01:24:57 +02:00
|
|
|
{{ $t('misc.save') }}
|
2021-01-17 18:57:57 +01:00
|
|
|
</x-button>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
2021-01-17 18:57:57 +01:00
|
|
|
<div class="control">
|
|
|
|
<x-button
|
|
|
|
@click="() => {deleteLabel(labelEditLabel);isLabelEdit = false}"
|
|
|
|
icon="trash-alt"
|
|
|
|
class="is-danger"
|
|
|
|
/>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
2021-01-17 18:57:57 +01:00
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</card>
|
2019-03-07 20:48:40 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2020-09-05 22:35:52 +02:00
|
|
|
import {mapState} from 'vuex'
|
2019-03-07 20:48:40 +01:00
|
|
|
|
2020-09-05 22:35:52 +02:00
|
|
|
import LabelModel from '../../models/label'
|
|
|
|
import ColorPicker from '../../components/input/colorPicker'
|
|
|
|
import LoadingComponent from '../../components/misc/loading'
|
|
|
|
import ErrorComponent from '../../components/misc/error'
|
2021-06-03 22:23:04 +02:00
|
|
|
import {LOADING, LOADING_MODULE} from '@/store/mutation-types'
|
2019-03-07 20:48:40 +01:00
|
|
|
|
2020-09-05 22:35:52 +02:00
|
|
|
export default {
|
|
|
|
name: 'ListLabels',
|
|
|
|
components: {
|
|
|
|
ColorPicker,
|
|
|
|
editor: () => ({
|
2021-07-25 15:27:15 +02:00
|
|
|
component: import('../../components/input/editor'),
|
2020-09-05 22:35:52 +02:00
|
|
|
loading: LoadingComponent,
|
|
|
|
error: ErrorComponent,
|
|
|
|
timeout: 60000,
|
2020-05-08 20:43:51 +02:00
|
|
|
}),
|
2020-09-05 22:35:52 +02:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
labelEditLabel: LabelModel,
|
|
|
|
isLabelEdit: false,
|
|
|
|
editorActive: false,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
this.labelEditLabel = new LabelModel()
|
|
|
|
this.loadLabels()
|
|
|
|
},
|
|
|
|
mounted() {
|
2021-06-24 01:24:57 +02:00
|
|
|
this.setTitle(this.$t('label.title'))
|
2020-09-05 22:35:52 +02:00
|
|
|
},
|
|
|
|
computed: mapState({
|
|
|
|
userInfo: state => state.auth.info,
|
2021-07-26 10:55:19 +02:00
|
|
|
labels: state => Object.values(state.labels.labels).sort((f, s) => f.title > s.title ? 1 : -1), // Alphabetically sort the labels
|
2021-06-03 22:23:04 +02:00
|
|
|
loading: state => state[LOADING] && state[LOADING_MODULE] === 'labels',
|
2020-09-05 22:35:52 +02:00
|
|
|
}),
|
|
|
|
methods: {
|
|
|
|
loadLabels() {
|
2021-06-03 22:23:04 +02:00
|
|
|
this.$store.dispatch('labels/loadAllLabels')
|
2020-09-05 22:35:52 +02:00
|
|
|
.catch(e => {
|
2021-06-22 22:07:57 +02:00
|
|
|
this.error(e)
|
2020-09-05 22:35:52 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
deleteLabel(label) {
|
2021-06-03 22:23:04 +02:00
|
|
|
this.$store.dispatch('labels/deleteLabel', label)
|
2020-09-05 22:35:52 +02:00
|
|
|
.then(() => {
|
2021-06-24 01:24:57 +02:00
|
|
|
this.success({message: this.$t('label.deleteSuccess')})
|
2020-09-05 22:35:52 +02:00
|
|
|
})
|
|
|
|
.catch(e => {
|
2021-06-22 22:07:57 +02:00
|
|
|
this.error(e)
|
2020-09-05 22:35:52 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
editLabelSubmit() {
|
2021-06-03 22:23:04 +02:00
|
|
|
this.$store.dispatch('labels/updateLabel', this.labelEditLabel)
|
|
|
|
.then(() => {
|
2021-06-24 01:24:57 +02:00
|
|
|
this.success({message: this.$t('label.edit.success')})
|
2020-09-05 22:35:52 +02:00
|
|
|
})
|
|
|
|
.catch(e => {
|
2021-06-22 22:07:57 +02:00
|
|
|
this.error(e)
|
2020-09-05 22:35:52 +02:00
|
|
|
})
|
|
|
|
},
|
|
|
|
editLabel(label) {
|
|
|
|
if (label.createdBy.id !== this.userInfo.id) {
|
|
|
|
return
|
2019-03-07 20:48:40 +01:00
|
|
|
}
|
2021-07-22 22:03:49 +02:00
|
|
|
// Duplicating the label to make sure it does not look like changes take effect immediatly as the label
|
|
|
|
// object passed to this function here still has a reference to the store.
|
|
|
|
this.labelEditLabel = new LabelModel({
|
|
|
|
id: label.id,
|
|
|
|
title: label.title,
|
|
|
|
description: label.description,
|
|
|
|
hexColor: label.hexColor,
|
|
|
|
})
|
2020-09-05 22:35:52 +02:00
|
|
|
this.isLabelEdit = true
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2020-02-18 07:49:20 +01:00
|
|
|
</script>
|