Filter apply + storage works now

This commit is contained in:
2020-10-09 12:17:58 +02:00
parent 85ffdaacc9
commit 5bbf4c86de
5 changed files with 205 additions and 40 deletions
+11
View File
@@ -0,0 +1,11 @@
using System;
namespace zero.Core.Entities
{
public class DateRange
{
public DateTimeOffset? From { get; set; }
public DateTimeOffset? To { get; set; }
}
}
+11
View File
@@ -0,0 +1,11 @@
using System;
namespace zero.Core.Entities
{
public class PriceRange
{
public decimal? From { get; set; }
public decimal? To { get; set; }
}
}
@@ -8,6 +8,7 @@
<template v-slot:footer>
<ui-button type="light onbg" label="@ui.close" @click="config.hide"></ui-button>
<ui-button v-if="!config.isCreate" type="light onbg" label="@ui.remove" @click="onRemove"></ui-button>
<ui-button type="primary" :submit="true" label="@ui.confirm" :state="form.state" :disabled="loading || disabled"></ui-button>
</template>
@@ -31,6 +32,12 @@
</div>
</div>
<div v-if="!loading && config.canSave" class="ui-box ui-table-filter-overlay-filtername">
<ui-property label="Save as..." description="You can optionally save this filter for future reference" :vertical="true">
<input v-model="filterName" type="text" class="ui-input" maxlength="40" />
</ui-property>
</div>
</ui-overlay-editor>
</ui-form>
</template>
@@ -52,7 +59,8 @@
defaults: {},
model: {},
activeGroup: null,
groups: []
groups: [],
filterName: null
}),
components: { EditorComponent },
@@ -77,14 +85,25 @@
onLoad()
{
this.groups = this.config.fields;
this.model = JSON.parse(JSON.stringify(this.config.model || {}));
this.model = JSON.parse(JSON.stringify(this.config.model.filter || {}));
this.defaults = JSON.parse(JSON.stringify(this.config.defaults || {}));
this.filterName = this.config.model.name;
this.loading = false;
},
onSubmit()
{
this.config.confirm(this.model);
this.config.confirm({
model: this.model,
filterName: this.filterName
});
},
onRemove()
{
this.config.confirm({
remove: true
});
}
}
@@ -131,8 +150,8 @@
.ui-table-filter-overlay-group-content
{
background: var(--color-box);
margin: var(--padding-s) -32px;
padding: var(--padding-m) var(--padding);
margin: var(--padding-s) 0;
padding: var(--padding-m) 0;
border-top: 1px solid var(--color-line);
border-bottom: 1px solid var(--color-line);
@@ -141,4 +160,9 @@
display: none;
}
}
.ui-table-filter-overlay-filtername .ui-property-content
{
margin-top: 12px !important;
}
</style>
@@ -3,14 +3,15 @@
<ui-search v-if="!hideSearch" v-model="value.search" class="onbg" />
<ui-dropdown v-if="!hideFilter && filters.length" align="right">
<template v-slot:button>
<ui-button v-if="!hideFilter" type="light onbg" label="Filter" caret="down" />
<ui-button v-if="!hideFilter" type="light onbg" :label="filterLabel" caret="down" />
</template>
<ui-dropdown-button label="@ui.add" icon="fth-plus" @click="onFilterAdd" />
<ui-dropdown-button label="Clear filter" icon="fth-x" @click="onFilterClear" />
<ui-dropdown-button v-if="filters.length" v-for="(filter, index) in filters" :key="index" :value="filter" :label="filter.name" @click="onFiltered" />
<ui-dropdown-separator v-if="filters.length" />
<ui-dropdown-button v-if="filters.length" v-for="(filter, index) in filters" :key="index" :value="filter" :label="filter.label" :icon="filter.icon" @click="onFiltered" />
<ui-dropdown-button label="@ui.add" icon="fth-plus" @click="openFilter()" />
<ui-dropdown-button v-if="filter" label="Edit filter" icon="fth-edit-2" @click="openFilter(filter.id)" />
<ui-dropdown-button label="Clear filter" icon="fth-x" @click="onFilterClear" />
</ui-dropdown>
<ui-button v-if="!hideFilter && !filters.length" type="light onbg" label="Filter" @click="onFilterAdd" />
<ui-button v-if="!hideFilter && !filters.length" type="light onbg" label="Filter" @click="openFilter()" />
<ui-dropdown v-if="!hideSelection && selection.length > 0" align="right">
<template v-slot:button>
<ui-button type="light" :label="selectedText" caret="down" />
@@ -29,6 +30,7 @@
<script>
import Overlay from 'zero/services/overlay';
import Strings from 'zero/services/strings';
import FilterOverlay from './table-filter-overlay';
import { isArray as _isArray } from 'underscore';
@@ -52,6 +54,10 @@
selection: {
type: Array,
default: () => []
},
alias: {
type: String,
default: null
}
},
@@ -66,7 +72,8 @@
hideFilter: true,
hideSearch: true,
hideSelection: true,
filters: []
filters: [],
filter: null
}),
created()
@@ -78,6 +85,14 @@
selectedText()
{
return this.selection.length + ' selected';
},
storageKey()
{
return 'zero.ui-table-filter.' + this.alias;
},
filterLabel()
{
return this.filter ? 'Filter: <span>' + this.filter.name + "</span>" : 'Filter';
}
},
@@ -88,6 +103,7 @@
this.hideFilter = typeof this.value.filter !== 'object';
this.hideSearch = typeof this.value.search === false;
this.hideSelection = this.value.selectable !== true;
this.filters = JSON.parse(localStorage.getItem(this.storageKey) || "[]");
},
onActionClicked(action, opts)
@@ -95,35 +111,113 @@
action.action(opts);
},
onFilterAdd()
{
this.openFilter();
},
onFilterClear()
{
this.updateFilter(null);
},
onFiltered()
onFiltered(value)
{
this.updateFilter(value);
},
openFilter()
openFilter(id)
{
let model = {
name: null,
filter: this.value.filter.model
};
if (id)
{
model = this.filters.find(x => x.id === id);
}
return Overlay.open({
component: FilterOverlay,
display: 'editor',
title: 'Filter',
defaults: this.value.filter.model,
model: this.value.filter.model,
fields: this.value.filter.fields
model: model,
fields: this.value.filter.fields,
canSave: !!this.alias,
isCreate: !id
}).then(value =>
{
console.info(value);
if (value.remove && id)
{
this.removeFilter(id);
return;
}
if (!!value.filterName)
{
id = this.saveFilter(value.filterName, value.model, id);
}
this.updateFilter({
id: id,
name: value.filterName,
filter: value.model
});
});
},
saveFilter(name, filter, id)
{
id = id || Strings.guid();
let savedFilter = this.filters.find(x => x.id === id);
let index = this.filters.indexOf(savedFilter);
let model = {
id: id,
name: name,
filter: filter
};
if (index > -1)
{
this.filters.splice(index, 1, model);
}
else
{
this.filters.push(model);
}
localStorage.setItem(this.storageKey, JSON.stringify(this.filters));
return id;
},
removeFilter(id)
{
let savedFilter = this.filters.find(x => x.id === id);
let index = this.filters.indexOf(savedFilter);
this.filters.splice(index, 1);
localStorage.setItem(this.storageKey, JSON.stringify(this.filters));
if (this.filter && this.filter.id === id)
{
this.updateFilter(null);
}
},
updateFilter(value)
{
if (!value)
{
this.filter = null;
this.$emit('filter', null);
}
else
{
this.filter = JSON.parse(JSON.stringify(value));
this.$emit('filter', this.filter.filter);
}
}
}
}
+41 -16
View File
@@ -4,7 +4,7 @@
<header class="ui-table-row ui-table-head">
<div v-for="column in columns" :key="column.key" class="ui-table-cell" :table-field="column.field" :style="column.flex">
{{ column.label | localize }}
<button :disabled="!column.canSort" @click="sort(column)" type="button" class="ui-table-sort" :class="filter.orderBy == column.field ? 'sort-' + (filter.orderIsDescending ? 'desc' : 'asc') : null">
<button :disabled="!column.canSort" @click="sort(column)" type="button" class="ui-table-sort" :class="tableFilter.orderBy == column.field ? 'sort-' + (tableFilter.orderIsDescending ? 'desc' : 'asc') : null">
<i class="arrow arrow-down"></i>
</button>
</div>
@@ -32,7 +32,7 @@
</div>
<footer class="ui-table-pagination" v-if="pages > 1">
<ui-pagination :pages="pages" :page="filter.page" @change="setPage" :inline="inline" />
<ui-pagination :pages="pages" :page="tableFilter.page" @change="setPage" :inline="inline" />
</footer>
</div>
@@ -79,6 +79,17 @@
inline: {
type: Boolean,
default: false
},
filter: {
type: Object,
default: () =>
{
return {};
}
},
search: {
type: String,
default: null
}
},
@@ -91,16 +102,28 @@
},
'value.search': function (val)
{
this.filter.search = val;
this.tableFilter.search = val;
},
'value.items': function (val)
{
this.initialize();
},
'filter.search': function (val)
'tableFilter.search': function (val)
{
this.debouncedUpdate();
},
'filter': {
deep: true,
handler: function (val)
{
this.tableFilter.filter = val;
this.debouncedUpdate();
}
},
'search': function (val)
{
this.tableFilter.search = val;
},
$route(to, from)
{
this.initialize();
@@ -114,7 +137,7 @@
isLoading: true,
pages: 1,
count: 0,
filter: {
tableFilter: {
orderBy: null,
orderIsDescending: true,
page: 1,
@@ -162,12 +185,12 @@
this.configuration = _extend(JSON.parse(JSON.stringify(defaultConfig)), this.value);
this.filter.pageSize = this.configuration.pageSize;
this.tableFilter.pageSize = this.configuration.pageSize;
if (this.configuration.order.enabled)
{
this.filter.orderBy = this.configuration.order.by;
this.filter.orderIsDescending = this.configuration.order.isDescending;
this.tableFilter.orderBy = this.configuration.order.by;
this.tableFilter.orderIsDescending = this.configuration.order.isDescending;
}
this.generateColumns(this.configuration.columns);
@@ -178,7 +201,9 @@
// load items based on the current filter
load(initial)
{
this.configuration.items(this.filter).then(result =>
this.tableFilter.filter = this.filter;
this.configuration.items(this.tableFilter).then(result =>
{
this.$emit('loaded', result);
this.pages = result.totalPages;
@@ -248,25 +273,25 @@
// set the active page
setPage(index)
{
this.filter.page = index;
this.tableFilter.page = index;
this.debouncedUpdate();
},
// sort by a column
sort(column)
{
if (this.filter.orderBy === column.field && this.filter.orderIsDescending)
if (this.tableFilter.orderBy === column.field && this.tableFilter.orderIsDescending)
{
this.filter.orderIsDescending = false;
this.tableFilter.orderIsDescending = false;
}
else if (this.filter.orderBy === column.field)
else if (this.tableFilter.orderBy === column.field)
{
this.filter.orderBy = null;
this.tableFilter.orderBy = null;
}
else
{
this.filter.orderBy = column.field;
this.filter.orderIsDescending = true;
this.tableFilter.orderBy = column.field;
this.tableFilter.orderIsDescending = true;
}
this.debouncedUpdate();