UNPKG

@cnamts/vue-dot

Version:

Implementation of our Design System for the French Health Insurance

184 lines (146 loc) 3.93 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import Vue, { PropType } from 'vue'; import Component from 'vue-class-component'; import { FilterItem } from './types'; import { deepCopy } from '../../helpers/deepCopy'; import { ChipItem } from '../../elements/ChipList/types'; import slugify from 'slugify'; const Props = Vue.extend({ props: { value: { type: Array as PropType<FilterItem[]>, default: () => [] } } }); @Component<Filterable>({ model: { prop: 'value', event: 'update:value' }, watch: { value: { handler(newValue: FilterItem[]) { this.filters = deepCopy(newValue); }, immediate: true } } }) export class Filterable extends Props { filters: FilterItem[] = []; getFilterCount(filter: FilterItem): number { return this.getChips(filter).length; } formatFilterName(name: string): string { return slugify(name, { lower: true }); } getChips({ value, formatChip }: FilterItem): ChipItem[] { if (value !== undefined && formatChip) { return formatChip(value); } const isString = typeof value === 'string'; const isNumber = typeof value === 'number'; const isObject = typeof value === 'object'; const isArray = Array.isArray(value); if (isString || isNumber) { if (value === '') { return []; } return [{ text: value.toString(), value }]; } if (isArray) { return value.map(item => { if (typeof item !== 'object') { return { text: item.toString(), value: item }; } return { text: item.text || item.value.toString(), value: item }; }); } if (isObject && value !== null) { const typedValue: Record<string, any> = value; const isPeriodField = typedValue.from !== undefined && typedValue.to !== undefined; if (isPeriodField) { if (typedValue.from === null || typedValue.to === null) { return []; } return [{ text: `${typedValue.from} – ${typedValue.to}`, value: typedValue }]; } // Any object return Object.keys(typedValue).map(key => { // Use text property if it exists, else use value property or default to key value const text = typedValue[key].text || typedValue[key].value?.toString() || typedValue[key].toString(); return { text, value: typedValue[key] }; }); } return []; } removeChip(filter: FilterItem, chip: ChipItem): void { const value = filter.value; const isString = typeof value === 'string'; const isNumber = typeof value === 'number'; const isObject = typeof value === 'object'; const isArray = Array.isArray(value); if (isString || isNumber) { this.$set(filter, 'value', undefined); } if (isArray) { const typedValue = value; const chipValue = chip.value as any; const filteredValue = typedValue.filter(item => { if (Array.isArray(chipValue)) { return !chipValue.includes(item); } if (typeof item === 'object' && item !== null) { return item.value !== chipValue.value; } return item !== chipValue; }); const newValue = filteredValue.length ? filteredValue : undefined; this.$set(filter, 'value', newValue); this.updateValue(); return; } if (isObject) { const typedValue = value as Record<string, any>; const chipValue = chip.value as any; const isPeriodField = typedValue.from !== undefined && typedValue.to !== undefined; if (isPeriodField) { this.$set(filter, 'value', undefined); this.updateValue(); return; } delete typedValue[chipValue]; this.$set(filter, 'value', typedValue); } this.updateValue(); } resetFilter(filter: FilterItem): void { this.$set(filter, 'value', undefined); this.updateValue(); } resetAllFilters(): void { this.filters.forEach(filter => { this.$set(filter, 'value', undefined); }); this.updateValue(); } updateValue(): void { this.$emit('update:value', this.filters); } }