3
0

Add record filter preset saving

This commit is contained in:
Kelani Tolulope
2023-05-24 13:00:51 +01:00
parent f09f1fa6d0
commit aa28be29cb
6 changed files with 269 additions and 39 deletions

View File

@@ -215,13 +215,23 @@
{{ $t('general:label.reset') }}
</b-button>
<b-button
ref="btnSave"
variant="primary"
@click="onSave"
>
{{ $t('general.label.save') }}
</b-button>
<div class="d-flex">
<b-button
v-if="allowFilterPresetSave"
variant="outline-primary"
class="mr-2"
@click="onSave(true, 'filter-preset')"
>
{{ $t('recordList.filter.addFilterToPreset') }}
</b-button>
<b-button
ref="btnSave"
variant="primary"
@click="onSave"
>
{{ $t('general.label.save') }}
</b-button>
</div>
</b-card-footer>
</b-card>
@@ -288,6 +298,11 @@ export default {
type: String,
default: '',
},
allowFilterPresetSave: {
type: Boolean,
default: false,
},
},
data () {
@@ -592,13 +607,8 @@ export default {
}
},
onSave (close = true) {
if (close) {
this.$refs.popover.$emit('close')
}
// Emit only value and not whole record with every filter
this.$emit('filter', this.componentFilter.map(({ groupCondition, filter = [], name }) => {
processFilter () {
return this.componentFilter.map(({ groupCondition, filter = [], name }) => {
filter = filter.map(({ record, ...f }) => {
if (record) {
f.value = record[f.name] || record.values[f.name]
@@ -615,7 +625,16 @@ export default {
})
return { groupCondition, filter, name }
}))
})
},
onSave (close = true, type = 'filter') {
if (close) {
this.$refs.popover.$emit('close')
}
// Emit only value and not whole record with every filter
this.$emit(type, this.processFilter())
},
updateFilterProperties (filter) {

View File

@@ -78,22 +78,32 @@
@export="onExport"
/>
<b-dropdown
v-if="filterPresets.length"
size="lg"
variant="light"
right
:text="$t('recordList.filter.filters.label')"
<b-button
:id="`${uniqueID}-filter-preset`"
class="btn dropdown-toggle btn-light btn-lg"
>
<b-dropdown-item
v-for="(f, idx) in filterPresets"
:key="idx"
:disabled="activeFilters.includes(f.name)"
@click="updateFilter(f.filter, f.name)"
>
{{ f.name }}
</b-dropdown-item>
</b-dropdown>
{{ $t('recordList.filter.filters.label') }}
</b-button>
<b-popover
:target="`${uniqueID}-filter-preset`"
triggers="click blur"
placement="bottom"
>
<ul class="list-style-none">
<li
v-for="(f, idx) in filterPresets"
:key="idx"
>
<button
class="dropdown-item"
:disabled="activeFilters.includes(f.name)"
@click="updateFilter(f.filter, f.name)"
>
{{ f.name }}
</button>
</li>
</ul>
</b-popover>
<column-picker
v-if="!options.hideConfigureFieldsButton"
@@ -293,8 +303,10 @@
:namespace="namespace"
:module="recordListModule"
:record-list-filter="recordListFilter"
:allow-filter-preset-save="options.customFilterPresets"
class="d-print-none ml-1"
@filter="onFilter"
@filter-preset="onSaveFilterPreset"
@reset="activeFilters = []"
/>
@@ -609,6 +621,13 @@
open-on-select
@save="onInlineEdit()"
/>
<!-- Modal for naming custom filter -->
<custom-filter-preset
:visible="showCustomPresetFilterModal"
@save="setStorageRecordListFilterPreset"
@close="showCustomPresetFilterModal = false"
/>
</template>
<template
@@ -733,6 +752,7 @@ import draggable from 'vuedraggable'
import RecordListFilter from 'corteza-webapp-compose/src/components/Common/RecordListFilter'
import ColumnPicker from 'corteza-webapp-compose/src/components/Admin/Module/Records/ColumnPicker'
import BulkEditModal from 'corteza-webapp-compose/src/components/Public/Record/BulkEdit'
import CustomFilterPreset from 'corteza-webapp-compose/src/components/Public/Record/CustomFilterPreset'
const { CInputSearch } = components
@@ -752,6 +772,7 @@ export default {
ColumnPicker,
CInputSearch,
BulkEditModal,
CustomFilterPreset,
},
extends: base,
@@ -815,6 +836,9 @@ export default {
items: [],
showingDeletedRecords: false,
activeFilters: [],
customPresetFilters: [],
currentCustomPresetFilter: undefined,
showCustomPresetFilterModal: false,
}
},
@@ -982,7 +1006,10 @@ export default {
},
filterPresets () {
return this.options.filterPresets.filter(({ name, roles }) => name && this.isUserRoleMember(roles))
return [
...this.options.filterPresets.filter(({ name, roles }) => name && this.isUserRoleMember(roles)),
...this.customPresetFilters,
]
},
authUserRoles () {
@@ -1008,6 +1035,7 @@ export default {
handler () {
this.createEvents()
this.getStorageRecordListFilter()
this.getStorageRecordListFilterPreset()
this.prepRecordList()
this.refresh(true)
},
@@ -1064,12 +1092,24 @@ export default {
onFilter (filter = []) {
filter.forEach(f => {
if (this.activeFilters.includes(f.name)) {
this.filterPresets.find(p => p.name === f.name).filter.forEach((filterPreset) => {
if (!isEqual(f.filter, filterPreset.filter)) {
const filterIndex = this.activeFilters.indexOf(f.name)
this.activeFilters.splice(filterIndex, 1)
}
})
const filterPresets = this.filterPresets.find(p => p.name === f.name)
if (filterPresets) {
filterPresets.filter.forEach((filterPreset) => {
if (!isEqual(f.filter, filterPreset.filter)) {
const filterIndex = this.activeFilters.indexOf(f.name)
this.activeFilters.splice(filterIndex, 1)
}
})
}
}
if (f.filter.length === 1 && (!f.filter[0].value && !f.filter[0].name)) {
const filterIndex = this.activeFilters.indexOf(f.name)
this.activeFilters.splice(filterIndex, 1)
} else {
this.activeFilters.push(this.$t('recordList.customFilter'))
f.name = this.$t('recordList.customFilter')
}
})
@@ -1078,6 +1118,15 @@ export default {
this.refresh(true)
},
onSaveFilterPreset (filter = []) {
this.currentCustomPresetFilter = {
filter,
}
this.showCustomPresetFilterModal = true
this.refresh(true)
},
onUpdateFields (fields = []) {
this.options.fields = [...fields]
this.$emit('save-fields', this.options.fields)
@@ -1597,6 +1646,7 @@ export default {
removeItem(`record-list-filters-${this.uniqueID}`)
} else {
this.recordListFilter = currentFilters
this.activeFilters = currentFilters.map(f => f.name)
}
} catch (e) {
// Land here if the filter is corrupted
@@ -1606,6 +1656,21 @@ export default {
}
},
getStorageRecordListFilterPreset () {
try {
// Get record list filters from localStorage
const currentFilterPresets = getItem(`record-list-preset-${this.uniqueID}`)
// Set the custom preset filters
this.customPresetFilters = currentFilterPresets
} catch (e) {
// Land here if the filter is corrupted
console.warn(this.$t('notification:record-list.corrupted-filter'))
// Remove filter from the local storage
removeItem(`record-list-filters-${this.uniqueID}`)
}
},
setStorageRecordListFilter () {
let currentListFilters = []
@@ -1615,7 +1680,23 @@ export default {
currentListFilters = this.recordListFilter
setItem(`record-list-filters-${this.uniqueID}`, currentListFilters)
} catch (e) {
console.warning(this.$t('notification:record-list.corrupted-filter'))
console.warn(this.$t('notification:record-list.corrupted-filter'))
}
},
setStorageRecordListFilterPreset ({ name }) {
this.showCustomPresetFilterModal = false
const currentListFilters = [...this.customPresetFilters]
currentListFilters.push({ ...this.currentCustomPresetFilter, name })
this.customPresetFilters = currentListFilters
this.updateFilter(this.currentCustomPresetFilter.filter, name)
try {
setItem(`record-list-preset-${this.uniqueID}`, currentListFilters)
} catch (e) {
console.warn(this.$t('notification:record-list.corrupted-filter'))
}
},
@@ -1714,7 +1795,7 @@ export default {
return !expressions.value
},
updateFilter (filter, name) {
updateFilter (filter = [], name) {
const lastFilterIdx = this.recordListFilter.length - 1
filter = filter.map((filter) => ({ ...filter, name }))
@@ -1800,4 +1881,10 @@ td:hover .inline-actions {
font-family: $font-regular !important;
}
}
.list-style-none {
list-style: none;
margin: 0;
padding: 0;
}
</style>

View File

@@ -347,6 +347,21 @@
{{ $t('recordList.filter.addFilter') }}
</b-button>
</b-form-group>
<b-row class="mb-3">
<b-col>
<b-form-group
:label="$t('recordList.record.setCustomFilterPresets')"
label-class="text-primary"
>
<c-input-checkbox
v-model="options.customFilterPresets"
switch
:labels="checkboxLabel"
/>
</b-form-group>
</b-col>
</b-row>
</b-col>
</b-row>
</div>

View File

@@ -0,0 +1,100 @@
<template>
<div>
<b-modal
:visible="showModal"
:title="$t('recordList.filterPresets.saveFilterAsPreset')"
body-class="p-0"
footer-class="d-flex w-100 align-items-center justify-content-between"
centered
@hide="onModalHide"
>
<b-card
class="pt-0"
>
<b-form-group
:label="$t('recordList.filterPresets.filterName')"
label-class="primary"
>
<b-form-input
v-model="filterName"
/>
</b-form-group>
</b-card>
<template #modal-footer>
<b-button
variant="light"
@click="onModalHide"
>
{{ $t('general.label.cancel') }}
</b-button>
<div>
<b-button
variant="primary"
:disabled="!filterName"
@click="onSave"
>
{{ $t('general.label.save') }}
</b-button>
</div>
</template>
</b-modal>
</div>
</template>
<script>
export default {
i18nOptions: {
namespaces: 'block',
},
name: 'CustomFilterPreset',
props: {
visible: {
type: Boolean,
default: false,
},
},
data () {
return {
showModal: false,
filterName: '',
}
},
watch: {
visible: {
immediate: true,
handler (val) {
this.showModal = val
},
},
},
methods: {
onModalHide () {
this.showModal = false
this.filterName = ''
this.$emit('close')
},
onSave () {
this.$emit('save', {
name: this.filterName,
})
this.onModalHide()
},
},
}
</script>
<style lang="scss">
.position-initial {
position: initial;
}
</style>

View File

@@ -40,6 +40,7 @@ interface Options {
fullPageNavigation: boolean;
showTotalCount: boolean;
showDeletedRecordsOption: boolean;
customFilterPresets: boolean;
refreshRate: number;
showRefresh: boolean;
@@ -97,6 +98,7 @@ const defaults: Readonly<Options> = Object.freeze({
fullPageNavigation: false,
showTotalCount: false,
showDeletedRecordsOption: false,
customFilterPresets: false,
editable: false,
draggable: false,
@@ -164,6 +166,7 @@ export class PageBlockRecordList extends PageBlock {
'fullPageNavigation',
'showTotalCount',
'showDeletedRecordsOption',
'customFilterPresets',
'hideSorting',
'allowExport',
'selectable',

View File

@@ -264,6 +264,10 @@ record:
recordList:
addRecord: Add
cancelSelection: Cancel
customFilter: Custom filter
filterPresets:
filterName: Filter name
saveFilterAsPreset: Save filter as preset
inlineEdit:
enabled: Inline value editing enabled
button:
@@ -321,6 +325,7 @@ recordList:
addField: Add new filter field
addFilter: + Add filter
byValue: Filter records based on field value
addFilterToPreset: Save as preset
conditions:
and: AND
or: OR
@@ -455,6 +460,7 @@ recordList:
presortPlaceholder: field1 DESC, field2 ASC
showTotalCount: Show total record count
showDeletedRecordsOption: Show option to see deleted records
setCustomFilterPresets: User will be able to set custom filter presets
openInSameTab: Open record in the same tab
openInNewTab: Open record in a new tab
openInModal: Open record in a modal