summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--webapp/src/components/ComponentTableActions.vue126
-rw-r--r--webapp/src/components/GroupModuleClientList.vue29
-rw-r--r--webapp/src/components/GroupModuleGroupList.vue29
3 files changed, 146 insertions, 38 deletions
diff --git a/webapp/src/components/ComponentTableActions.vue b/webapp/src/components/ComponentTableActions.vue
new file mode 100644
index 0000000..989a83a
--- /dev/null
+++ b/webapp/src/components/ComponentTableActions.vue
@@ -0,0 +1,126 @@
+<i18n>
+{
+ "en": {
+ "search": "Search",
+ "all": "All",
+ "pageText": "{0}-{1} of {2}",
+ "pageTextZero": "0 of 0",
+ "rowsPerPageText": "Rows per page:"
+ },
+ "de": {
+ "search": "Suche",
+ "all": "Alle",
+ "pageText": "{0}-{1} von {2}",
+ "pageTextZero": "0 von 0",
+ "rowsPerPageText": "Reihen pro page:"
+ }
+}
+</i18n>
+
+<template>
+ <v-layout wrap align-center class="caption font-weight-thin">
+ <v-flex md3 sm5 xs12 order-md1 order-sm1 order-xs1 class="text-xs-left">
+ <v-text-field
+ class="search-field"
+ :placeholder="$t('search')"
+ :value="search"
+ @input="setSearch"
+ hide-details
+ prepend-inner-icon="search"
+ ></v-text-field>
+ </v-flex>
+ <v-flex md4 sm12 xs12 offset-md1 offset-sm0 offset-xs0 order-md2 order-sm3 order-xs3 class="text-md-center text-xs-right">
+ {{ $t('rowsPerPageText') }}
+ <v-select
+ class="rows-per-page-select body-1"
+ :value="pagination.rowsPerPage"
+ @input="setRowsPerPage"
+ :items="rowsPerPageOptions.concat({ text: $t('all'), value: -1 })"
+ offset-y
+ color="primary"
+ hide-details
+ ></v-select>
+ </v-flex>
+ <v-flex md4 sm6 xs12 offset-md0 offset-sm1 offset-xs0 order-md3 order-sm2 order-xs2 class="text-xs-right">
+ <span class="page-text">{{
+ pagination.totalItems > 0 ? $t('pageText', [
+ (pagination.page - 1) * pagination.rowsPerPage + 1,
+ Math.min(pagination.page * pagination.rowsPerPage, pagination.totalItems),
+ pagination.totalItems
+ ]) : $t('pageTextZero')
+ }}</span>
+ <v-btn class="page-button" icon @click="prevPage"><v-icon>keyboard_arrow_left</v-icon></v-btn>
+ <v-btn class="page-button" icon @click="nextPage"><v-icon>keyboard_arrow_right</v-icon></v-btn>
+ </v-flex>
+ </v-layout>
+</template>
+
+<script>
+
+export default {
+ name: 'ComponentTableActions',
+ props: {
+ pagination: {
+ type: Object,
+ required: true
+ },
+ search: {
+ type: String,
+ required: true
+ },
+ itemCount: {
+ type: Number,
+ required: true
+ },
+ rowsPerPageOptions: {
+ type: Array,
+ default: () => [10, 25, 50]
+ }
+ },
+ data () {
+ return {
+ }
+ },
+ methods: {
+ setRowsPerPage (value) {
+ this.$emit('update:pagination', { ...this.pagination, rowsPerPage: value, page: 1 })
+ },
+ setPage (value) {
+ this.$emit('update:pagination', { ...this.pagination, page: value })
+ },
+ setSearch (value) { this.$emit('update:search', value) },
+ prevPage () {
+ if (this.pagination.page > 1) this.setPage(this.pagination.page - 1)
+ },
+ nextPage () {
+ if (this.pagination.page * this.pagination.rowsPerPage < this.pagination.totalItems) this.setPage(this.pagination.page + 1)
+ }
+ },
+ created () {
+ this.$emit('update:pagination', { ...this.pagination, totalItems: this.itemCount, rowsPerPage: this.rowsPerPageOptions[0] || -1 })
+ this.setSearch('')
+ }
+}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+.search-field {
+ margin-top: 0;
+ margin-left: 10px;
+ margin-right: 10px;
+ margin-bottom: 5px;
+}
+.rows-per-page-select {
+ display: inline-block;
+ margin: 0 10px 0 20px;
+ width: min-content;
+}
+.page-text {
+ margin-right: 20px;
+}
+.page-button {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+</style>
diff --git a/webapp/src/components/GroupModuleClientList.vue b/webapp/src/components/GroupModuleClientList.vue
index e8809d3..c491b63 100644
--- a/webapp/src/components/GroupModuleClientList.vue
+++ b/webapp/src/components/GroupModuleClientList.vue
@@ -6,7 +6,6 @@
"ip": "IP Address",
"mac": "MAC Address",
"uuid": "UUID",
- "search": "Search",
"removeClients": "Remove one client | Remove {0} clients",
"addClients": "Add clients",
"deleteClients": "Delete one client | Delete {0} clients",
@@ -18,7 +17,6 @@
"ip": "IP Adresse",
"mac": "MAC Adresse",
"uuid": "UUID",
- "search": "Suche",
"removeClients": "Entferne einen Clienten | Entferne {0} Clienten",
"addClients": "Füge Clienten hinzu",
"deleteClients": "Lösche einen Clienten | Lösche {0} Clienten",
@@ -30,10 +28,8 @@
<template>
<div>
<v-card>
- <v-card-title v-if="tabIndex === 0 && showAll" class="search-container">
- <div>
- <v-text-field class="search-field" :placeholder="$t('search')" v-model="search" hide-details prepend-inner-icon="search"></v-text-field>
- </div>
+ <v-card-title v-if="clients.length > 10">
+ <component-table-actions :pagination.sync="pagination" :search.sync="search" :item-count="clients.length" />
</v-card-title>
<v-divider></v-divider>
<v-data-table
@@ -41,9 +37,10 @@
:items="clients"
item-key="id"
select-all
- :hide-actions="tabIndex > 0 || !showAll"
+ hide-actions
v-model="selected"
:search="search"
+ :pagination.sync="pagination"
>
<template slot="items" slot-scope="props">
<tr @click.stop="props.selected = !props.selected" @dblclick="loadClient(props.item.id)">
@@ -84,15 +81,20 @@
</template>
<script>
+import ComponentTableActions from '@/components/ComponentTableActions'
import { mapState, mapMutations } from 'vuex'
export default {
name: 'GroupModuleClientList',
props: ['tabIndex', 'groupId', 'clients'],
+ components: {
+ ComponentTableActions
+ },
data () {
return {
selected: [],
- search: ''
+ search: '',
+ pagination: {}
}
},
computed: {
@@ -148,15 +150,4 @@ export default {
margin-left: 20px;
margin-right: -10px;
}
-
-.search-container {
- display: flex;
- justify-content: flex-end;
-}
-
-.search-field {
- margin-top: 0;
- margin-right: 10px;
- margin-bottom: 5px;
-}
</style>
diff --git a/webapp/src/components/GroupModuleGroupList.vue b/webapp/src/components/GroupModuleGroupList.vue
index cb593df..2adfcaf 100644
--- a/webapp/src/components/GroupModuleGroupList.vue
+++ b/webapp/src/components/GroupModuleGroupList.vue
@@ -4,7 +4,6 @@
"id": "ID",
"name": "Name",
"description": "Description",
- "search": "Search",
"removeSubgroups": "Remove one subgroup | Remove {0} subgroups",
"addSubgroups": "Add subgroups",
"deleteGroups": "Delete one group | Delete {0} groups",
@@ -14,7 +13,6 @@
"id": "ID",
"name": "Name",
"description": "Beschreibung",
- "search": "Suche",
"removeSubgroups": "Entferne eine Untergruppe | Entferne {0} Untergruppen",
"addSubgroups": "Füge Untergruppen hinzu",
"deleteGroups": "Lösche eine Gruppe | Lösche {0} Gruppen",
@@ -26,10 +24,8 @@
<template>
<div>
<v-card>
- <v-card-title v-if="tabIndex === 0 && showAll" class="search-container">
- <div>
- <v-text-field class="search-field" :placeholder="$t('search')" v-model="search" hide-details prepend-inner-icon="search"></v-text-field>
- </div>
+ <v-card-title v-if="groups.length > 10" class="search-container">
+ <component-table-actions :pagination.sync="pagination" :search.sync="search" :item-count="groups.length" />
</v-card-title>
<v-divider></v-divider>
<v-data-table
@@ -37,9 +33,10 @@
:items="groups"
item-key="id"
select-all
- :hide-actions="tabIndex > 0 || !showAll"
+ hide-actions
v-model="selected"
:search="search"
+ :pagination.sync="pagination"
>
<template slot="items" slot-scope="props">
<tr @click.stop="props.selected = !props.selected" @dblclick="loadGroup(props.item.id)">
@@ -78,15 +75,20 @@
</template>
<script>
+import ComponentTableActions from '@/components/ComponentTableActions'
import { mapState, mapMutations } from 'vuex'
export default {
name: 'GroupModuleGroupList',
props: ['tabIndex', 'groupId', 'groups'],
+ components: {
+ ComponentTableActions
+ },
data () {
return {
selected: [],
- search: ''
+ search: '',
+ pagination: {}
}
},
computed: {
@@ -136,15 +138,4 @@ export default {
margin-left: 20px;
margin-right: -10px;
}
-
-.search-container {
- display: flex;
- justify-content: flex-end;
-}
-
-.search-field {
- margin-top: 0;
- margin-right: 10px;
- margin-bottom: 5px;
-}
</style>