summaryrefslogtreecommitdiffstats
path: root/webapp/src/components/GroupModuleDialog.vue
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/src/components/GroupModuleDialog.vue')
-rw-r--r--webapp/src/components/GroupModuleDialog.vue195
1 files changed, 195 insertions, 0 deletions
diff --git a/webapp/src/components/GroupModuleDialog.vue b/webapp/src/components/GroupModuleDialog.vue
new file mode 100644
index 0000000..69527b2
--- /dev/null
+++ b/webapp/src/components/GroupModuleDialog.vue
@@ -0,0 +1,195 @@
+<i18n>
+{
+ "en": {
+ "title": {
+ "delete": {
+ "group": "Delete this group? | Delete these {0} groups?",
+ "client": "Delete this client? | Delete these {0} clients?"
+ },
+ "remove": {
+ "group": "Remove this subgroup? | Remove these {0} subgroups?",
+ "client": "Remove this client? | Remove these {0} clients?"
+ },
+ "add": {
+ "group": "Add groups | Add this group? | Add these {0} groups?",
+ "client": "Add clients | Add this client? | Add these {0} clients?"
+ }
+ },
+ "deletePermanently": {
+ "group": "Permanently delete group | Permanently delete groups",
+ "client": "Permanently delete client | Permanently delete clients"
+ },
+ "new": "New"
+ },
+ "de": {
+ "title": {
+ "delete": {
+ "group": "Diese Gruppe löschen? | Diese {0} Gruppen löschen?",
+ "client": "Diesen Clienten löschen? | Diese {0} Clienten löschen?"
+ },
+ "remove": {
+ "group": "Diese Untergruppe entfernen? | Diese {0} Untergruppen entfernen?",
+ "client": "Diesen Clienten entfernen? | Diese {0} Clienten entfernen?"
+ },
+ "add": {
+ "group": "Gruppen hinzufügen | Diese Gruppe hinzufügen? | Diese {0} Gruppen hinzufügen?",
+ "client": "Clienten hinzufügen | Diesen Clienten hinzufügen? | Diese {0} Clienten hinzufügen?"
+ }
+ },
+ "deletePermanently": {
+ "group": "Gruppe dauerhaft löschen | Gruppen dauerhaft löschen",
+ "client": "Client dauerhaft löschen | Clienten dauerhaft löschen"
+ },
+ "new": "Neu"
+ }
+}
+</i18n>
+
+<template>
+ <v-dialog
+ :value="dialog.show"
+ @input="setDialog({ show: $event })"
+ max-width="500px"
+ scrollable
+ >
+ <v-card>
+ <v-card-title primary-title class="dialog-title elevation-3">
+ <div class="headline">{{ title }}</div>
+ </v-card-title>
+ <v-card-text v-if="action === 'add'" class="table-container">
+ <v-layout justify-space-between align-center>
+ <v-btn flat color="success" @click="newItem"><v-icon left>create</v-icon>{{ $t('new') }}</v-btn>
+ <v-text-field class="search-field" v-model="search" hide-details prepend-inner-icon="search"></v-text-field>
+ </v-layout>
+ <v-divider></v-divider>
+ <v-data-table
+ :headers="headers"
+ :items="items"
+ item-key="id"
+ select-all
+ hide-actions
+ v-model="selected"
+ :search="search"
+ >
+ <template slot="items" slot-scope="props">
+ <tr @click="props.selected = !props.selected">
+ <td>
+ <v-checkbox
+ color="primary"
+ v-model="props.selected"
+ hide-details
+ @click.native.stop
+ ></v-checkbox>
+ </td>
+ <td>{{ props.item.id }}</td>
+ <td>{{ props.item.name }}</td>
+ </tr>
+ </template>
+ </v-data-table>
+ </v-card-text>
+ <v-card-text v-else class="selected-list">
+ <v-checkbox
+ class="delete-checkbox"
+ v-if="dialog.info.action === 'remove'"
+ :label="$tc('deletePermanently.' + dialog.info.type, selectedCount)"
+ color="error"
+ v-model="deleteInsteadOfRemove"
+ hide-details
+ ></v-checkbox>
+ <div v-for="item in dialog.info.selected" class="grey--text" :key="item.id">[{{ item.id }}] {{ item.name }}</div>
+ </v-card-text>
+ <v-divider></v-divider>
+ <v-card-actions>
+ <v-spacer></v-spacer>
+ <v-btn flat="flat" @click="setDialog({ show: false })">{{ $t('cancel') }}</v-btn>
+ <v-btn :color="action === 'add' ? 'success' : 'error'" @click="submitAction">{{ $t(action) }}</v-btn>
+ </v-card-actions>
+ </v-card>
+ </v-dialog>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex'
+
+export default {
+ name: 'GroupModuleDialog',
+ data () {
+ return {
+ headers: [
+ { text: 'ID', value: 'id' },
+ { text: 'Name', value: 'name', width: '100000px' }
+ ],
+ selected: [],
+ search: '',
+ deleteInsteadOfRemove: false
+ }
+ },
+ computed: {
+ ...mapState('groups', ['dialog', 'tabChain']),
+ action () {
+ return this.dialog.info.action === 'remove' && this.deleteInsteadOfRemove ? 'delete' : this.dialog.info.action
+ },
+ selectedCount () {
+ return this.action === 'add' ? this.selected.length : (this.dialog.info.selected ? this.dialog.info.selected.length : 0)
+ },
+ title () {
+ return this.$tc('title.' + this.action + '.' + this.dialog.info.type, this.selectedCount, [this.selectedCount])
+ },
+ items () {
+ if (this.dialog.info.type === 'group') return this.$store.state.groups.groupList
+ if (this.dialog.info.type === 'client') return this.$store.state.groups.clientList
+ }
+ },
+ methods: {
+ ...mapMutations('groups', ['setActiveTab', 'setTab']),
+ setDialog (data) {
+ this.$store.commit('groups/setDialog', data)
+ if (data.show === false) {
+ this.selected = []
+ this.search = ''
+ this.deleteInsteadOfRemove = false
+ }
+ },
+ submitAction () {
+ const actionMap = {
+ 'delete': { 'group': 'deleteGroups', 'client': 'deleteClients' },
+ 'remove': { 'group': 'removeSubroups', 'client': 'removeClients' },
+ 'add': { 'group': 'addSubgroups', 'client': 'addClients' }
+ }
+ var data = { ...this.dialog.info }
+ if (this.action === 'add') data.selected = this.selected
+ this.$store.dispatch('groups/' + actionMap[this.action][this.dialog.info.type], data)
+ this.setDialog({ show: false })
+ },
+ newItem () {
+ this.setDialog({ show: false })
+ var item = { tabType: this.dialog.info.type }
+ if (this.dialog.info.type === 'group') item.parents = [this.tabChain[this.dialog.info.tabIndex]]
+ else if (this.dialog.info.type === 'client') item.groups = [this.tabChain[this.dialog.info.tabIndex]]
+ this.setTab({ index: this.dialog.info.tabIndex + 1, item })
+ this.setActiveTab(this.dialog.info.tabIndex + 1)
+ }
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+.table-container {
+ padding: 0;
+}
+.search-field {
+ margin: 10px;
+ max-width: 200px;
+}
+.dialog-title {
+ z-index: 1;
+}
+.delete-checkbox {
+ margin-top: 0;
+ margin-bottom: 20px;
+}
+.selected-list {
+ padding: 30px;
+}
+</style>