Filter apply + storage works now
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace zero.Core.Entities
|
||||
{
|
||||
public class DateRange
|
||||
{
|
||||
public DateTimeOffset? From { get; set; }
|
||||
|
||||
public DateTimeOffset? To { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user