summaryrefslogtreecommitdiffstats
path: root/webapp/src/components/GroupModuleGroupView.vue
diff options
context:
space:
mode:
authorUdo Walter2019-02-24 02:33:52 +0100
committerUdo Walter2019-02-24 02:33:52 +0100
commit813195e3dfb5baae09aa11cddeef12fb0b9fb49b (patch)
tree58562c85d76efdad41afcd0664c5a8cdc8cb4a55 /webapp/src/components/GroupModuleGroupView.vue
parent[webapp/alerts] Remove unnecessary code which produced vue warnings (diff)
downloadbas-813195e3dfb5baae09aa11cddeef12fb0b9fb49b.tar.gz
bas-813195e3dfb5baae09aa11cddeef12fb0b9fb49b.tar.xz
bas-813195e3dfb5baae09aa11cddeef12fb0b9fb49b.zip
[webapp/groups] rework old tables to new data table
slightly redesigned the editing of groups and clients
Diffstat (limited to 'webapp/src/components/GroupModuleGroupView.vue')
-rw-r--r--webapp/src/components/GroupModuleGroupView.vue190
1 files changed, 114 insertions, 76 deletions
diff --git a/webapp/src/components/GroupModuleGroupView.vue b/webapp/src/components/GroupModuleGroupView.vue
index d3a66ab..41bff09 100644
--- a/webapp/src/components/GroupModuleGroupView.vue
+++ b/webapp/src/components/GroupModuleGroupView.vue
@@ -12,7 +12,8 @@
"config": "iPXE Config",
"parents": "Parents",
"startIp": "Start IP",
- "endIp": "End IP"
+ "endIp": "End IP",
+ "selectParents": "Select parents"
},
"de": {
"info": "Info",
@@ -26,7 +27,8 @@
"config": "iPXE Konfiguration",
"parents": "Übergruppen",
"startIp": "Start IP",
- "endIp": "End IP"
+ "endIp": "End IP",
+ "selectParents": "Übergruppen auswählen"
}
}
</i18n>
@@ -40,86 +42,103 @@
<v-flex lg4 sm6 xs12 order-lg1 order-xs2>
<v-layout column>
<v-flex>
- <v-text-field prepend-icon="label" v-if="editMode" class="info-input" :label="$t('name')" color="primary" v-model="info.name"></v-text-field>
- <div v-else class="info-input">
+ <div class="info-box">
<div class="body-2 info-heading"><v-icon>label</v-icon><span>{{ $t('name') }}</span></div>
- <div class="info-text">{{ group.name || '-' }}</div>
+ <div class="info-text">
+ <v-text-field v-if="editMode" class="info-input" color="primary" v-model="info.name" hide-details></v-text-field>
+ <div v-else>{{ group.name || '-' }}</div>
+ </div>
</div>
</v-flex>
<v-flex>
- <v-autocomplete
- prepend-icon="device_hub"
- v-if="editMode"
- class="info-input"
- :items="$store.state.groups.groupList"
- v-model="parents"
- :menu-props="{ offsetY: '' }"
- :label="$t('parents')"
- color="primary"
- multiple
- item-value="id"
- item-text="name"
- return-object
- small-chips
- deletable-chips
- >
- </v-autocomplete>
- <div v-else class="info-input">
- <div class="body-2 info-heading"><v-icon>device_hub</v-icon><span>{{ $t('parents') }}</span></div>
+ <div class="info-box">
+ <div class="body-2 info-heading">
+ <v-icon>device_hub</v-icon><span>{{ $t('parents') }}</span>
+ <v-menu v-if="editMode" offset-y :close-on-content-click="false" :max-width="400" lazy>
+ <v-btn slot="activator" small icon class="info-heading-button"><v-icon>edit</v-icon></v-btn>
+ <v-card>
+ <data-table ref="datatable" v-model="parents" :headers="headers" :items="groupList" menu-mode></data-table>
+ </v-card>
+ </v-menu>
+ </div>
<div class="info-text">
- <v-chip v-for="parent in group.parents" :key="parent.id" small>
- {{ parent.name || parent.id }}
- </v-chip>
- <span v-if="group.parents && group.parents.length === 0">-</span>
+ <div>
+ <v-chip
+ v-for="(parent, index) in parentChips"
+ :key="parent.id"
+ v-if="index <= 5"
+ small
+ :close="editMode"
+ @input="removeParentChip(index)"
+ >
+ {{ parent.name || parent.id }}
+ </v-chip>
+ <span v-if="parentChips.length > 5" class="and-more-chip">...</span>
+ <span v-if="parentChips && parentChips.length === 0">-</span>
+ </div>
</div>
</div>
</v-flex>
<v-flex>
- <v-select v-if="editMode" class="info-input" prepend-icon="list" clearable item-text="name" item-value="id" :menu-props="{ offsetY: '' }" :label="$t('config')" color="primary" v-model="info.configId" :items="configList"></v-select>
- <div v-else class="info-input">
+ <div class="info-box">
<div class="body-2 info-heading"><v-icon>list</v-icon><span>{{ $t('config') }}</span></div>
- <div class="info-text">{{ configName || '-' }}</div>
+ <div class="info-text">
+ <v-select v-if="editMode"
+ class="info-input"
+ clearable
+ item-text="name"
+ item-value="id"
+ :menu-props="{ offsetY: '' }"
+ hide-details
+ color="primary"
+ v-model="info.configId"
+ :items="configList"
+ ></v-select>
+ <div v-else>{{ configName || '-' }}</div>
+ </div>
</div>
</v-flex>
</v-layout>
</v-flex>
<v-flex lg4 sm6 xs12 order-lg2 order-xs3>
- <v-textarea prepend-icon="description" v-if="editMode" rows="1" auto-grow class="info-input" :label="$t('description')" color="primary" v-model="info.description"></v-textarea>
- <div v-else class="info-input">
+ <div class="info-box">
<div class="body-2 info-heading"><v-icon>description</v-icon><span>{{ $t('description') }}</span></div>
- <pre class="info-text">{{ group.description || '-' }}</pre>
+ <div class="info-text">
+ <v-textarea v-if="editMode" class="info-input" rows="1" auto-grow hide-details color="primary" v-model="info.description"></v-textarea>
+ <div v-else style="white-space: pre-wrap;">{{ group.description || '-' }}</div>
+ </div>
</div>
- <div v-if="editMode" class="info-input">
+ <div class="info-box">
<div class="body-2 info-heading">
<v-icon>settings_ethernet</v-icon><span>{{ $t('ipranges') }}</span>
- <v-btn small icon @click="addIprange"><v-icon>add</v-icon></v-btn>
- </div>
- <div>
- <div v-for="(iprange, index) in ipranges" class="iprange" :key="index">
- <v-btn small icon class="remove-iprange" @click="removeIprange(index)"><v-icon>remove</v-icon></v-btn>
- <v-text-field :label="$t('startIp')" color="primary" v-model="iprange.startIp"></v-text-field>
- <span>-</span>
- <v-text-field :label="$t('endIp')" color="primary" v-model="iprange.endIp"></v-text-field>
- </div>
+ <v-btn v-if="editMode" small icon @click="addIprange" class="info-heading-button"><v-icon>add</v-icon></v-btn>
</div>
- </div>
- <div v-else class="info-input">
- <div class="body-2 info-heading"><v-icon>settings_ethernet</v-icon><span>{{ $t('ipranges') }}</span></div>
<div class="info-text">
- <table>
- <tr v-for="(iprange, index) in group.ipranges" :key="index">
- <td class="text-xs-right">{{ iprange.startIp }}</td>
- <td class="ip-seperator">-</td>
- <td>{{ iprange.endIp }}</td>
- </tr>
- </table>
- <div v-if="group.ipranges && group.ipranges.length === 0">-</div>
+ <div v-if="editMode">
+ <div v-for="(iprange, index) in ipranges" :key="index" class="iprange">
+ <v-btn class="iprange-remove-button" small icon @click="removeIprange(index)"><v-icon>remove</v-icon></v-btn>
+ <v-text-field class="info-input" hide-details :label="$t('startIp')" color="primary" v-model="iprange.startIp" single-line></v-text-field>
+ <span class="ip-seperator">-</span>
+ <v-text-field class="info-input" hide-details :label="$t('endIp')" color="primary" v-model="iprange.endIp" single-line></v-text-field>
+ </div>
+ <div v-if="ipranges && ipranges.length === 0">-</div>
+ </div>
+ <div v-else>
+ <table>
+ <tr v-for="(iprange, index) in group.ipranges" :key="index">
+ <td class="text-xs-right">{{ iprange.startIp }}</td>
+ <td class="ip-seperator">-</td>
+ <td>{{ iprange.endIp }}</td>
+ </tr>
+ </table>
+ <div v-if="group.ipranges && group.ipranges.length === 0">-</div>
+ </div>
</div>
</div>
</v-flex>
<v-flex lg4 xs12 order-lg3 order-xs1 class="text-xs-right">
- <div class="info-input">
+ <div class="info-box">
<div v-if="!editMode">
<v-btn color="error" flat @click="deleteGroup" class="info-buttons">
<v-icon left>delete</v-icon>{{ $t('delete') }}
@@ -162,14 +181,16 @@
<script>
import GroupModuleGroupList from '@/components/GroupModuleGroupList'
import GroupModuleClientList from '@/components/GroupModuleClientList'
-import { mapMutations } from 'vuex'
+import DataTable from '@/components/DataTable'
+import { mapState, mapMutations } from 'vuex'
export default {
name: 'GroupModuleGroupView',
props: ['tabIndex', 'group'],
components: {
GroupModuleGroupList,
- GroupModuleClientList
+ GroupModuleClientList,
+ DataTable
},
data () {
return {
@@ -180,15 +201,22 @@ export default {
configId: null
},
parents: [],
- ipranges: [{ startIp: '', endIp: '' }]
+ ipranges: []
}
},
computed: {
- configList () {
- return this.$store.state.groups.configList
- },
+ ...mapState('groups', ['groupList', 'configList']),
configName () {
return this.$store.state.groups.configNames[this.group.configId]
+ },
+ parentChips () {
+ if (this.editMode) return this.parents
+ else return this.group.parents
+ },
+ headers () {
+ return [
+ { key: 'name', text: this.$t('name') }
+ ]
}
},
watch: {
@@ -209,13 +237,16 @@ export default {
addIprange () {
this.ipranges.push({ startIp: '', endIp: '' })
},
+ removeParentChip (index) {
+ this.parents.splice(index, 1)
+ },
editInfo () {
this.editMode = true
this.info.name = this.group.name
this.info.description = this.group.description
this.info.configId = this.group.configId
this.parents = this.group.parents ? this.group.parents.slice(0) : []
- this.ipranges = this.group.ipranges ? this.group.ipranges.slice(0) : [{ startIp: '', endIp: '' }]
+ this.ipranges = this.group.ipranges ? this.group.ipranges.slice(0) : []
},
cancelEdit () {
this.editMode = false
@@ -226,6 +257,7 @@ export default {
},
saveData () {
this.info.configId = this.info.configId === undefined ? null : this.info.configId
+ this.ipranges = this.ipranges.filter(iprange => iprange.startIp && iprange.endIp)
this.$store.dispatch('groups/saveGroup', {
id: this.group.id,
data: this.info,
@@ -261,30 +293,29 @@ export default {
.iprange {
display: flex;
align-items: center;
+ min-height: 34px;
}
-.ip-seperator {
- padding: 0 10px;
+.iprange >>> input {
+ font-size: 14px;
}
-.iprange > .remove-iprange {
- margin: 0 8px 0 -2px;
+.ip-seperator {
+ padding: 0 10px;
}
-.iprange >>> input {
- font-size: 14px;
+.iprange-remove-button {
+ margin: 0 8px 0 0;
}
-.iprange > span {
- margin: 0 10px;
+.info-box {
+ padding: 20px;
}
.info-input {
- padding: 10px 20px;
-}
-
-.info-input >>> input, .info-input >>> textarea {
- font-family: 'Roboto Mono';
+ margin: 0;
+ padding: 0 0 1px 0;
+ overflow: hidden;
}
.info-heading {
@@ -293,6 +324,10 @@ export default {
margin-bottom: 10px;
}
+.info-heading-button {
+ margin: -2px 0 -2px 10px;
+}
+
.info-heading > span {
margin-left: 10px;
}
@@ -301,6 +336,9 @@ export default {
overflow-x: auto;
margin-left: 34px;
font-family: 'Roboto Mono';
+ min-height: 34px;
+ display: flex;
+ align-items: center;
}
.show-toggle {