Skip to content

Commit 7fbefb3

Browse files
committed
fix filters date
1 parent a0ec8d8 commit 7fbefb3

File tree

7 files changed

+132
-36
lines changed

7 files changed

+132
-36
lines changed

apps/web/src/components/core/edit-filters.vue

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
3030
v-model='filter.operator'
3131
label='Opérateur'
3232
:options='availableComparators'
33+
:readonly='!filter.key'
3334
option-value='value'
3435
option-label='label'
3536
dense
@@ -54,7 +55,8 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
5455
label='Valeur'
5556
:prefix="comparator?.prefix"
5657
:suffix="comparator?.suffix"
57-
:type='searchInputType'
58+
:readonly='!filter.operator'
59+
:type='searchInputType === "date" ? "datetime-local" : searchInputType'
5860
@keydown.enter.prevent="writeFilter(filter)"
5961
dense
6062
outlined
@@ -67,9 +69,11 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
6769
:prefix="comparator?.prefix"
6870
:suffix="comparator?.suffix"
6971
:type='searchInputType'
72+
:readonly='!filter.operator'
7073
@keydown.enter.prevent="writeFilter(filter)"
7174
:options="optionsMapping"
7275
emit-value
76+
use-chips
7377
map-options
7478
dense
7579
outlined
@@ -79,6 +83,7 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
7983
v-show="comparator?.multiplefields && comparator?.querySign === '<<'"
8084
v-model="filter.min"
8185
:type='searchInputType'
86+
:readonly='!filter.operator'
8287
label="Minimum"
8388
clearable
8489
dense
@@ -89,6 +94,7 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
8994
v-show="comparator?.multiplefields && comparator?.querySign === '<<'"
9095
v-model="filter.max"
9196
:type='searchInputType'
97+
:readonly='!filter.operator'
9298
label="Maximum"
9399
clearable
94100
dense
@@ -103,6 +109,7 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
103109
:suffix="comparator?.suffix"
104110
:type='searchInputType'
105111
:options="optionsMapping"
112+
:readonly='!filter.operator'
106113
input-debounce="100"
107114
new-value-mode="add-unique"
108115
emit-value
@@ -129,11 +136,12 @@ q-card.transparent(style='min-width: 40vw; max-width: 80vw')
129136

130137
<script lang="ts">
131138
import type { QTableProps } from 'quasar'
139+
import dayjs from 'dayjs'
132140
133141
type Filter = {
134142
key: string
135143
operator: string
136-
value: string
144+
value: string | number | undefined
137145
138146
min?: string
139147
max?: string
@@ -180,10 +188,14 @@ export default defineNuxtComponent({
180188
},
181189
'filter.operator': {
182190
handler() {
183-
this.filter.value = ''
184-
this.filter.min = ''
185-
this.filter.max = ''
186-
this.filter.items = []
191+
if (this.comparator?.multiplefields) {
192+
this.filter.value = undefined
193+
} else if (this.filter.items && this.filter.items.length > 0) {
194+
this.filter.items = []
195+
} else {
196+
this.filter.min = ''
197+
this.filter.max = ''
198+
}
187199
},
188200
},
189201
},
@@ -260,11 +272,22 @@ export default defineNuxtComponent({
260272
}
261273
}
262274
275+
let initialValue = ref<string | number | undefined>(undefined)
276+
const operator = detectInitialOperator()
277+
const comp = comparatorTypes.value.find((comp) => comp.value === operator)
278+
279+
if (comp?.type.includes('date') && initialFilter.value) {
280+
const dateValue = dayjs(initialFilter.value).format('YYYY-MM-DDTHH:mm')
281+
initialValue.value = dateValue
282+
} else {
283+
initialValue.value = stripPrefixSuffix(initialFilter?.value) || undefined
284+
}
285+
263286
const fieldType = ref<string>()
264287
const filter = ref<Filter>({
288+
operator,
265289
key: initialFilter?.field?.replace('[]', '') || '',
266-
operator: detectInitialOperator(),
267-
value: stripPrefixSuffix(initialFilter?.value) || '',
290+
value: initialValue.value,
268291
269292
min: '',
270293
max: '',
@@ -300,7 +323,7 @@ export default defineNuxtComponent({
300323
this.columnsType.forEach((col) => {
301324
if (col.name === this.filter.key && col.valueMapping) {
302325
Object.entries(col.valueMapping).forEach(([key, val]) => {
303-
mapping.push({ label: val, value: key })
326+
mapping.push({ label: val + ' (' + key + ')', value: key })
304327
})
305328
}
306329
})
@@ -309,9 +332,9 @@ export default defineNuxtComponent({
309332
},
310333
},
311334
mounted() {
312-
console.log('comparator', this.comparator)
313-
console.log('optionsMapping', this.optionsMapping)
314-
console.log('this.columnsType', this.columnsType)
335+
// console.log('comparator', this.comparator)
336+
// console.log('optionsMapping', this.optionsMapping)
337+
// console.log('this.columnsType', this.columnsType)
315338
this.fieldType = this.columnsType.find((col) => col.name === this.filter.key)?.type || 'text'
316339
},
317340
})

apps/web/src/components/layouts/default/drawer.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ q-drawer.flex(v-model="drawer" side="left" :mini="true" :breakpoint="0" bordered
1111
div(v-for="menu in getMenuByPart(part)")
1212
q-item(v-if="menu.hideInMenuBar !== true"
1313
:key="part" clickable v-ripple
14-
:href="menu.path" :active="menu.path === $route.fullPath" active-class="q-item--active"
14+
:href="encodePath(menu.path)" :active="encodePath(menu.path) === $route.fullPath" active-class="q-item--active"
1515
)
16-
q-separator(v-if='menu.path === $route.fullPath' vertical color='primary' size="5px" style='position: absolute; left: 0; height: 100%; margin-top: -8px;')
16+
q-separator(v-if='encodePath(menu.path) === $route.fullPath' vertical color='primary' size="5px" style='position: absolute; left: 0; height: 100%; margin-top: -8px;')
1717
q-item-section(avatar)
1818
q-icon(:name="menu.icon" :color="menu.color")
1919
q-badge(
@@ -46,12 +46,14 @@ export default defineNuxtComponent({
4646
async setup() {
4747
const identityStateStore = useIdentityStateStore()
4848
const { menuParts, getMenuByPart, initialize } = useMenu(identityStateStore)
49+
const { encodePath } = useFiltersQuery(ref([]))
4950
5051
await initialize()
5152
5253
return {
5354
menuParts,
5455
getMenuByPart,
56+
encodePath,
5557
}
5658
},
5759
})

apps/web/src/composables/useColumnsIdentities.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,14 @@ export function useColumnsIdentites(): useColumnsIdentitesReturnType {
118118
])
119119

120120
const columnsType = ref<ColumnType[]>([
121-
...config?.identitiesColumns?.entries.map((col: any) => ({ name: col.name, type: col.type || 'text' })) || [],
121+
...config?.identitiesColumns?.entries.map((col: any) => {
122+
// console.log('Processing column config', col)
123+
return {
124+
name: col.name,
125+
type: col.type || 'text',
126+
valueMapping: col.valueMapping || [],
127+
}
128+
}) || [],
122129
{ name: 'state', type: 'number', valueMapping: IdentityStateLabels },
123130
{ name: 'metadata.lastUpdatedAt', type: 'date' },
124131
{ name: 'metadata.createdAt', type: 'date' },

apps/web/src/composables/useFiltersQuery.ts

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,20 @@ const comparatorTypes = ref<ComparatorType[]>([
7878
},
7979
{
8080
label: 'Supérieur ou égal à',
81-
querySign: '>=',
82-
value: '>=',
81+
querySign: '>|#',
82+
value: '>|#',
8383
icon: 'mdi-greater-than-or-equal',
84-
type: ['number', 'date'],
84+
type: ['number'],
85+
multiplefields: false,
86+
prefix: '',
87+
suffix: '',
88+
},
89+
{
90+
label: 'Supérieur ou égal à',
91+
querySign: '>|',
92+
value: '>|',
93+
icon: 'mdi-greater-than-or-equal',
94+
type: ['date'],
8595
multiplefields: false,
8696
prefix: '',
8797
suffix: '',
@@ -98,10 +108,20 @@ const comparatorTypes = ref<ComparatorType[]>([
98108
},
99109
{
100110
label: 'Inférieur ou égal à',
101-
querySign: '<=',
102-
value: '<=',
111+
querySign: '<|#',
112+
value: '<|#',
103113
icon: 'mdi-less-than-or-equal',
104-
type: ['number', 'date'],
114+
type: ['number'],
115+
multiplefields: false,
116+
prefix: '',
117+
suffix: '',
118+
},
119+
{
120+
label: 'Inférieur ou égal à',
121+
querySign: '<|',
122+
value: '<|',
123+
icon: 'mdi-less-than-or-equal',
124+
type: ['date'],
105125
multiplefields: false,
106126
prefix: '',
107127
suffix: '',
@@ -195,10 +215,11 @@ const getLabelByName = (columns: Ref<QTableProps['columns'] & { type: string }[]
195215
* @returns comparator and field extracted from the key
196216
*/
197217
const extractComparator = (key: string): { comparator: string, field: string } | null => {
198-
const match = key.match(/^(\:|\?|\#|\!|\>|\<|\^|\@)+/)
218+
const match = key.match(/^(\:|\?|\||\#|\!|\>|\<|\^|\@)+/m)
199219

200220
if (!match) return null
201221

222+
// console.log('Extracted comparator', match, 'from key', key)
202223
const comparator = match[0]
203224
const field = key.replace(comparator, '')
204225

@@ -253,7 +274,7 @@ const getSearchString = (
253274
// }
254275

255276
if (fieldType === 'date') {
256-
return dayjs(search!.toString()).format('DD/MM/YYYY')
277+
return dayjs(search!.toString()).format('DD/MM/YYYY HH:mm')
257278
}
258279

259280
if (['number', 'array', 'text'].includes(fieldType) && columnType?.valueMapping) {
@@ -340,6 +361,7 @@ export function useFiltersQuery(columns: Ref<QTableProps['columns'] & { type: st
340361
console.warn(`Invalid search for filter key: ${key} ${filteredKey}`, {
341362
label,
342363
search,
364+
extract,
343365
})
344366
continue
345367
}
@@ -403,7 +425,12 @@ export function useFiltersQuery(columns: Ref<QTableProps['columns'] & { type: st
403425
break
404426

405427
default:
406-
query[filterKey] = `${comparator?.prefix || ''}${value}${comparator?.suffix || ''}`
428+
if (comparator?.type.includes('date') && value) {
429+
const dateValue = dayjs(value as string).toISOString()
430+
query[filterKey] = `${comparator?.prefix || ''}${dateValue}${comparator?.suffix || ''}`
431+
} else if (value) {
432+
query[filterKey] = `${comparator?.prefix || ''}${value}${comparator?.suffix || ''}`
433+
}
407434
break
408435
}
409436

@@ -412,6 +439,26 @@ export function useFiltersQuery(columns: Ref<QTableProps['columns'] & { type: st
412439
})
413440
}
414441

442+
const encodePath = (path: string) => {
443+
const [base, query] = path.split('?')
444+
if (!query) return path
445+
const encodedQuery = query
446+
.split('&')
447+
.map((param) => {
448+
const [key, value] = param.split('=')
449+
if (key.includes('filters')) {
450+
const finalKey = encodeURIComponent(key)
451+
.replace(/%5B/g, '[')
452+
.replace(/%5D/g, ']')
453+
.replace(/%25/g, '%')
454+
return `${finalKey}=${encodeURIComponent(value)}`
455+
}
456+
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
457+
})
458+
.join('&')
459+
return `${base}?${encodedQuery}`
460+
}
461+
415462
return {
416463
countFilters,
417464
hasFilters,
@@ -420,5 +467,6 @@ export function useFiltersQuery(columns: Ref<QTableProps['columns'] & { type: st
420467
writeFilter,
421468
comparatorTypes,
422469
fieldTypes,
470+
encodePath,
423471
}
424472
}

apps/web/src/composables/useIdentityStates.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export function useIdentityStates(): useIdentityStateReturnType {
4949
}
5050

5151
function getStateBadge(state: number): { color: string, name: string, icon: string, textColor?: string } {
52+
// console.log('Getting badge for state', state, getStateInfos(state))
5253
return omit(getStateInfos(state), ['value'])
5354
}
5455

0 commit comments

Comments
 (0)