Skip to content

Commit 3da1270

Browse files
committed
feat: add ability to change order of filters and align clear button to the end of grid
1 parent 175beac commit 3da1270

File tree

1 file changed

+77
-27
lines changed

1 file changed

+77
-27
lines changed

custom/FiltersArea.vue

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@
7777

7878
<CustomRangePicker
7979
v-else-if="['integer', 'decimal', 'float'].includes(c.type) && c.allowMinMaxQuery"
80-
:min="getFilterMinValue(c.name)"
81-
:max="getFilterMaxValue(c.name)"
8280
:valueStart="getFilterItem({ column: c, operator: 'gte' })"
8381
@update:valueStart="onFilterInput[c.name]({ column: c, operator: 'gte', value: ($event !== '' && $event !== null) ? $event : undefined })"
8482
:valueEnd="getFilterItem({ column: c, operator: 'lte' })"
@@ -105,21 +103,27 @@
105103
</div>
106104
</div>
107105
</div>
108-
</div>
109-
<div v-if="isExpanded" class="flex w-full justify-end">
106+
<template v-if="freeCells > 0" v-for="n in freeCells-1" :key="'free-cell-' + n">
107+
<div></div>
108+
</template>
109+
<template v-if="freeCells === 0" v-for="n in cols-1" :key="'free-cell2-' + n">
110+
<div></div>
111+
</template>
112+
<div class="flex items-end justify-end">
110113
<Button
111-
class="mt-4 max-w-24"
114+
class="mt-6 max-w-24"
112115
@click="filtersStore.filters = [...filtersStore.filters.filter(f => filtersStore.shouldFilterBeHidden(f.field))]"
113116
:disabled="filtersStore.filters.length === 0"
114117
>
115118
Clear all
116119
</Button>
120+
</div>
117121
</div>
118122
</div>
119123
</template>
120124

121125
<script lang="ts" setup>
122-
import { onMounted, computed, ref, reactive } from 'vue';
126+
import { onMounted, onUnmounted, computed, ref, reactive, watch } from 'vue';
123127
import { useFiltersStore } from '@/stores/filters';
124128
import { callAdminForthApi, loadMoreForeignOptions, searchForeignOptions, createSearchInputHandlers } from '@/utils';
125129
import { useRouter } from 'vue-router';
@@ -136,7 +140,10 @@ const columnOffsets = reactive({});
136140
const columnEmptyResultsCount = reactive({});
137141
const filtersStore = useFiltersStore();
138142
const columnsMinMax = ref({});
139-
const isExpanded = ref(false);
143+
const isExpanded = ref(true);
144+
const freeCells = ref(0);
145+
const currentBreakpoint = ref("base");
146+
const cols = ref(1);
140147
141148
const props = defineProps<{
142149
meta: any,
@@ -146,37 +153,37 @@ const props = defineProps<{
146153
147154
const columnOptions = ref({});
148155
const columnsWithFilter = computed(
149-
() => props.resource.columns?.filter(column => column.showIn.filter && props.meta.options.columns.some(c => c.column === column.name)) || []
156+
() => sortFilters(props.resource.columns?.filter(column => column.showIn.filter && props.meta.options.columns.some(c => c.column === column.name)), props.meta.options.columns) || []
150157
);
151158
152159
onMounted(async () => {
153-
console.log('FiltersArea mounted', props.resource);
154-
columnsMinMax.value = await callAdminForthApi({
155-
path: '/get_min_max_for_columns',
156-
method: 'POST',
157-
body: {
158-
resourceId: route.params.resourceId
160+
// columnsMinMax.value = await callAdminForthApi({
161+
// path: '/get_min_max_for_columns',
162+
// method: 'POST',
163+
// body: {
164+
// resourceId: route.params.resourceId
165+
// }
166+
// });
167+
currentBreakpoint.value = getBreakpoint(window.innerWidth);
168+
calculateGridCols();
169+
window.addEventListener('resize', () => {
170+
const newBreakpoint = getBreakpoint(window.innerWidth)
171+
if (newBreakpoint !== currentBreakpoint.value) {
172+
currentBreakpoint.value = newBreakpoint;
173+
calculateGridCols();
159174
}
160-
});
161-
console.log('Fetched columnsMinMax:', columnsMinMax.value);
175+
})
162176
});
163177
178+
onUnmounted(() => {
179+
window.removeEventListener('resize', getBreakpoint)
180+
})
181+
164182
function getFilterItem({ column, operator }) {
165183
const filterValue = filtersStore.filters.find(f => f.field === column.name && f.operator === operator)?.value;
166184
return filterValue !== undefined ? filterValue : '';
167185
}
168186
169-
function getFilterMinValue(columnName) {
170-
if(columnsMinMax.value && columnsMinMax.value[columnName]) {
171-
return columnsMinMax.value[columnName]?.min
172-
}
173-
}
174-
175-
function getFilterMaxValue(columnName) {
176-
if(columnsMinMax.value && columnsMinMax.value[columnName]) {
177-
return columnsMinMax.value[columnName]?.max
178-
}
179-
}
180187
async function loadMoreOptions(columnName, searchTerm = '') {
181188
return loadMoreForeignOptions({
182189
columnName,
@@ -244,4 +251,47 @@ function setFilterItem({ column, operator, value }) {
244251
}
245252
}
246253
254+
255+
function getBreakpoint(width) {
256+
if (width >= 1536) return '2xl'
257+
if (width >= 1280) return 'xl'
258+
if (width >= 1024) return 'lg'
259+
if (width >= 768) return 'md'
260+
if (width >= 640) return 'sm'
261+
return 'base'
262+
}
263+
264+
function calculateGridCols() {
265+
const size = currentBreakpoint.value;
266+
switch (size) {
267+
case '2xl':
268+
cols.value = 6;
269+
break;
270+
case 'xl':
271+
cols.value = 3;
272+
break;
273+
case 'lg':
274+
cols.value = 2;
275+
break;
276+
case 'md':
277+
cols.value = 1;
278+
break;
279+
default:
280+
cols.value = 1;
281+
}
282+
const rows = Math.ceil(columnsWithFilter.value.length / cols.value);
283+
freeCells.value = (cols.value * rows) - columnsWithFilter.value.length;
284+
}
285+
286+
function sortFilters(array, fieldsObject) {
287+
let desiredOrder = [];
288+
fieldsObject.forEach(element => {
289+
desiredOrder.push(element.column);
290+
});
291+
const sortedObjects = array.sort(
292+
(a, b) => desiredOrder.indexOf(a.name) - desiredOrder.indexOf(b.name)
293+
);
294+
return sortedObjects;
295+
}
296+
247297
</script>

0 commit comments

Comments
 (0)