diff --git a/client/web/compose/src/components/Common/RecordListFilter.vue b/client/web/compose/src/components/Common/RecordListFilter.vue
index c2bf299e4..29d973da3 100644
--- a/client/web/compose/src/components/Common/RecordListFilter.vue
+++ b/client/web/compose/src/components/Common/RecordListFilter.vue
@@ -215,13 +215,23 @@
{{ $t('general:label.reset') }}
-
- {{ $t('general.label.save') }}
-
+
+
+ {{ $t('recordList.filter.addFilterToPreset') }}
+
+
+ {{ $t('general.label.save') }}
+
+
@@ -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) {
diff --git a/client/web/compose/src/components/PageBlocks/RecordListBase.vue b/client/web/compose/src/components/PageBlocks/RecordListBase.vue
index 49e1e227c..72b954e0f 100644
--- a/client/web/compose/src/components/PageBlocks/RecordListBase.vue
+++ b/client/web/compose/src/components/PageBlocks/RecordListBase.vue
@@ -78,22 +78,32 @@
@export="onExport"
/>
-
-
- {{ f.name }}
-
-
+ {{ $t('recordList.filter.filters.label') }}
+
+
+
+
@@ -609,6 +621,13 @@
open-on-select
@save="onInlineEdit()"
/>
+
+
+
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;
+}
diff --git a/client/web/compose/src/components/PageBlocks/RecordListConfigurator.vue b/client/web/compose/src/components/PageBlocks/RecordListConfigurator.vue
index 02b67d02d..45a22a3f2 100644
--- a/client/web/compose/src/components/PageBlocks/RecordListConfigurator.vue
+++ b/client/web/compose/src/components/PageBlocks/RecordListConfigurator.vue
@@ -347,6 +347,21 @@
{{ $t('recordList.filter.addFilter') }}
+
+
+
+
+
+
+
+
diff --git a/client/web/compose/src/components/Public/Record/CustomFilterPreset/index.vue b/client/web/compose/src/components/Public/Record/CustomFilterPreset/index.vue
new file mode 100644
index 000000000..7ca5a8a36
--- /dev/null
+++ b/client/web/compose/src/components/Public/Record/CustomFilterPreset/index.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('general.label.cancel') }}
+
+
+
+
+ {{ $t('general.label.save') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/js/src/compose/types/page-block/record-list.ts b/lib/js/src/compose/types/page-block/record-list.ts
index 3bbdb7f62..0f9f012b1 100644
--- a/lib/js/src/compose/types/page-block/record-list.ts
+++ b/lib/js/src/compose/types/page-block/record-list.ts
@@ -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 = 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',
diff --git a/locale/en/corteza-webapp-compose/block.yaml b/locale/en/corteza-webapp-compose/block.yaml
index d13bb6c75..5a14b1ff5 100644
--- a/locale/en/corteza-webapp-compose/block.yaml
+++ b/locale/en/corteza-webapp-compose/block.yaml
@@ -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