Skip to content

Commit

Permalink
Merge branch 'hotfix/0.24.4' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
polosson committed May 30, 2024
2 parents 0a21e4d + 81484f5 commit dfc2b65
Show file tree
Hide file tree
Showing 17 changed files with 176 additions and 60 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ Tous les changements notables sur le projet sont documentés dans ce fichier.

Ce projet adhère au principe du [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.24.4 (2024-05-30)

- Correction d'un bug dans la fonctionnalité de recherche des tableaux lorsque ceux-ci contiennent des dates.

## 0.24.3 (2024-05-23)

- Résolution d'un problème de suppression des assignations des techniciens lorsque la
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.24.3
0.24.4
18 changes: 16 additions & 2 deletions client/src/globals/types/vendors/vue-tables-2.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ declare module 'vue-tables-2-premium' {
perPage?: number,
orderBy?: { column: string, ascending: boolean },
sortable?: string[],
filterable?: boolean | string[],
multiSorting?: Record<string, Array<{ column: string, matchDir: boolean }>>,
filterByColumn?: boolean,
filterable?: boolean,
columnsDropdown?: boolean,
preserveState?: boolean,
saveState?: boolean,
Expand Down Expand Up @@ -82,7 +82,7 @@ declare module 'vue-tables-2-premium' {
};

/**
* Fonction personnalisé de tri de la colonne.
* Fonction personnalisée de tri de colonne.
*
* Cette fonction, à qui la direction de tri souhaité est passé (via `ascending`),
* doit renvoyer une autre fonction qui s'occupera de comparer deux éléments de
Expand All @@ -100,9 +100,23 @@ declare module 'vue-tables-2-premium' {
(a: Datum, b: Datum) => number
);

/**
* Fonction personnalisée de recherche de colonne.
*
* Cette fonction doit retourner un booléen en fonction de si oui ou non la colonne
* est satisfaisante pour la recherche passée en paramètre (`query`).
*
* Si non spécifié, une fonction de recherche "universelle" sera utilisée.
*
* @param row - Les données de la ligne en question.
* @param query - La recherche actuelle.
*/
export type ColumnSearcher<Datum = any> = (row: Datum, query: string) => boolean;

export type ClientTableOptions<Datum = any, Filters = any> = BaseTableOptions<Datum> & {
initFilters?: Filters,
customSorting?: Record<string, ColumnSorter<Datum>>,
filterAlgorithm?: Record<string, ColumnSearcher<Datum>>,
customFilters?: Array<ClientCustomFilter<Datum>>,
};

Expand Down
3 changes: 0 additions & 3 deletions client/src/themes/default/components/Table/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ export type Column<Data = any> = {
*/
render?: RenderFunction<Data>,

/** Le tri doit-il être activé sur cette colonne ? */
sortable?: boolean,

/** Une ou plusieurs classes à ajouter à la colonne. */
class?: ClassValue,

Expand Down
37 changes: 27 additions & 10 deletions client/src/themes/default/components/Table/Client/_types.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
import type { Merge } from 'type-fest';
import type { Column as CoreColumn } from '../@types';
import type { ColumnSorter } from 'vue-tables-2-premium';
import type { ColumnSearcher, ColumnSorter } from 'vue-tables-2-premium';

export type Column<Datum = any> = Merge<CoreColumn<Datum>, {
/**
* Fonction personnalisé de tri de la colonne.
* Le tri doit-il être activé sur cette colonne ?
*
* Cette fonction, à qui la direction de tri souhaité est passé (via `ascending`),
* doit renvoyer une autre fonction qui s'occupera de comparer deux éléments de
* la colonne et devra renvoyé si le premier élément (`a`) arrive avant (= `-1`) ou
* après (= `1`) le deuxième (`b`) (ou s'ils sont égaux (= `0`)).
* Peut contenir:
* - Un booléen, auquel cas le tri consistera en une simple comparaison des valeurs
* (e.g si ascendant: `a > b ? 1 : -1`) en ayant au préalable mis les chaînes
* de caractères en minuscules (si ce sont des chaînes qui sont comparées).
* - Une fonction personnalisée de tri pour la colonne.
* Cette fonction, à qui la direction de tri souhaité est passée (via `ascending`),
* doit renvoyer une autre fonction qui s'occupera de comparer deux éléments de
* la colonne et devra renvoyer si le premier élément (`a`) arrive avant (= `-1`) ou
* après (= `1`) le deuxième (`b`) (ou s'ils sont égaux (= `0`)).
*
* Si non spécifié, le tri consistera en une simple comparaison des valeurs
* (e.g si ascendant: `a > b ? 1 : -1`) en ayant au préalable mis les chaînes
* de caractères en minuscules (si ce sont des chaînes qui sont comparés).
* @default false
*/
sorter?: ColumnSorter<Datum>,
sortable?: boolean | ColumnSorter<Datum>,

/**
* La recherche doit-elle être activée sur cette colonne ?
*
* Peut contenir:
* - Un booléen, auquel cas une fonction de recherche "universelle" sera utilisée pour la recherche.
* {@see {@link import('./_utils.ts').defaultSearcher}}
* - Une fonction personnalisée de recherche pour la colonne.
* Cette fonction doit retourner un booléen en fonction de si oui ou non la colonne
* est satisfaisante pour la recherche passée en paramètre (`query`).
*
* @default false
*/
searchable?: boolean | ColumnSearcher<Datum>,
}>;

export type Columns<Data> = Array<Column<Data>>;
57 changes: 57 additions & 0 deletions client/src/themes/default/components/Table/Client/_utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable import/prefer-default-export */

import Color from '@/utils/color';
import DateTime from '@/utils/datetime';
import Day from '@/utils/day';
import stringIncludes from '@/utils/stringIncludes';
import get from 'lodash/get';

import type { ColumnSearcher } from 'vue-tables-2-premium';

// @see https://github.com/matfish2/vue-tables-2-private/blob/master/lib/methods/client-search.js
export const defaultSearcher = (key: string): ColumnSearcher => {
const isMatching = (value: unknown, query: string): boolean => {
if (value === undefined || value === null || typeof query !== 'string') {
return false;
}

if (['string', 'number', 'boolean'].includes(typeof value)) {
const normalizedValue = String(value).toLowerCase();
return stringIncludes(normalizedValue, query);
}

if (value instanceof Color) {
const normalizedValue = value.toHexString();
return stringIncludes(normalizedValue, query);
}

if (value instanceof Day || value instanceof DateTime || value instanceof Date) {
return false;
}

if (typeof value === 'object') {
return Object.values(value).some(
(subValue: unknown) => isMatching(subValue, query),
);
}

// - Affiche un message, en développement uniquement, quand on arrive pas à traiter
// explicitement la valeur de la colonne via les conditions ci-dessus.
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn(`Unhandled search value type \`${typeof value}\``, value);
}

return false;
};

return (row: unknown, query: string): boolean => {
if (typeof row !== 'object' || row === null) {
return false;
}

// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
const value: unknown = get(row, key, undefined);
return isMatching(value, query);
};
};
61 changes: 46 additions & 15 deletions client/src/themes/default/components/Table/Client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import clsx from 'clsx';
import { defineComponent } from '@vue/composition-api';
import generateUniqueId from 'lodash/uniqueId';
import { initColumnsDisplay } from '../@utils';
import { defaultSearcher } from './_utils';

import type { ClassValue } from 'clsx';
import type { CreateElement } from 'vue';
Expand All @@ -11,6 +12,7 @@ import type { Column, Columns } from './_types';
import type { ColumnsDisplay } from '../@utils';
import type {
ColumnSorter,
ColumnSearcher,
ClientTableOptions,
ClientTableInstance,
ColumnsVisibility,
Expand Down Expand Up @@ -46,9 +48,6 @@ export type Props<Datum = any, TColumns extends Columns<Datum> = Columns<Datum>>
/** Les données du tableau. */
data: Datum[],

/** Permet d'activer ou de désactiver le champ de filtrage du tableau. */
filterable?: boolean,

/**
* L'ordre dans lequel le tableau doit être triée initialement.
*
Expand Down Expand Up @@ -109,10 +108,6 @@ const ClientTable = defineComponent({
type: Array as PropType<Props['data']>,
required: true,
},
filterable: {
type: Boolean as PropType<Required<Props>['filterable']>,
default: true,
},
defaultOrderBy: {
type: [Object, String] as PropType<Props['defaultOrderBy']>,
default: undefined,
Expand Down Expand Up @@ -188,24 +183,54 @@ const ClientTable = defineComponent({

columnsSortable(): Array<Column['key']> {
return this.columns
.filter(({ sortable }: Column) => sortable)
.filter(({ sortable }: Column) => !!sortable)
.map(({ key }: Column) => key);
},

columnsSorting(): Record<string, ColumnSorter> {
return this.columns
.filter(({ sortable }: Column) => sortable)
.filter(({ sortable }: Column) => !!sortable)
.reduce(
(acc: Record<Column['key'], ColumnSorter>, column: Column) => {
const columnSorter = column.sorter;
return undefined !== columnSorter
const columnSorter = typeof column.sortable === 'function'
? column.sortable
: undefined;

return columnSorter !== undefined
? { ...acc, [column.key]: columnSorter }
: acc;
},
{},
);
},

columnsSearchable(): Array<Column['key']> {
return this.columns
.filter(({ searchable }: Column) => !!searchable)
.map(({ key }: Column) => key);
},

columnsSearches(): Record<string, ColumnSearcher> {
return this.columns
.filter(({ searchable }: Column) => !!searchable)
.reduce(
(acc: Record<Column['key'], ColumnSearcher>, column: Column) => {
const columnSearcher = typeof column.searchable === 'function'
? column.searchable
: defaultSearcher(column.key);

const searcher = (row: unknown, query: unknown): boolean => {
if (typeof query !== 'string' || query.length < 1) {
return false;
}
return columnSearcher(row, query);
};
return { ...acc, [column.key]: searcher };
},
{},
);
},

columnsDisplay(): ColumnsVisibility {
const columnsDisplay = this.columns.reduce(
(acc: ColumnsDisplay, column: Column) => {
Expand All @@ -221,12 +246,13 @@ const ClientTable = defineComponent({
const {
name,
rowClass,
filterable,
defaultOrderBy,
columnsHeadings,
columnsClasses,
columnsDisplay,
columnsSortable,
columnsSearchable,
columnsSearches,
columnsSorting,
columnsRenders,
withColumnsSelector,
Expand All @@ -238,11 +264,16 @@ const ClientTable = defineComponent({
preserveState: persistState,
saveState: persistState,
sortable: columnsSortable,
filterable: (
columnsSearchable.length > 0
? columnsSearchable
: false
),
headings: columnsHeadings,
templates: columnsRenders,
customSorting: columnsSorting,
filterByColumn: false,
filterable,
filterAlgorithm: columnsSearches,
columnsDisplay,
columnsClasses,
rowClassCallback: (row: any): ClassValue => (
Expand Down Expand Up @@ -312,14 +343,14 @@ const ClientTable = defineComponent({
name,
data,
uniqueId,
filterable,
columnsKeys,
columnsSearchable,
options,
handleRowClick,
} = this;

const className = ['Table', {
'Table--filterable': filterable,
'Table--filterable': columnsSearchable.length > 0,
}];

return (
Expand Down
9 changes: 9 additions & 0 deletions client/src/themes/default/components/Table/Server/_types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Merge } from 'type-fest';
import type { Column as CoreColumn } from '../@types';

export type Column<Datum = any> = Merge<CoreColumn<Datum>, {
/** Le tri doit-il être activé sur cette colonne ? */
sortable?: boolean,
}>;

export type Columns<Data> = Array<Column<Data>>;
13 changes: 6 additions & 7 deletions client/src/themes/default/components/Table/Server/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,20 @@ import { initColumnsDisplay } from '../@utils';
import type { ClassValue } from 'clsx';
import type { CreateElement } from 'vue';
import type { PropType } from '@vue/composition-api';
import type { Column, Columns } from './_types';
import type { ColumnsDisplay } from '../@utils';
import type {
Column,
Columns,
OrderBy,
RenderFunction,
RenderedColumn,
} from '../@types';
import type {
RequestFunction,
ColumnsVisibility,
ServerTableOptions,
ServerTableInstance,
RowClickEventPayload,
} from 'vue-tables-2-premium';
import type {
OrderBy,
RenderFunction,
RenderedColumn,
} from '../@types';

export type Props<Datum = any, TColumns extends Columns<Datum> = Columns<Datum>> = {
/**
Expand Down
8 changes: 0 additions & 8 deletions client/src/themes/default/components/Table/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
// - Types
export type { Columns, Column } from './@types';
export type {
Column as ClientColumn,
Columns as ClientColumns,
} from './Client';

// - Tables
export { default as ServerTable } from './Server';
export { default as ClientTable } from './Client';
2 changes: 2 additions & 0 deletions client/src/themes/default/pages/Attributes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const Attributes = defineComponent({
key: 'name',
title: __('page.attributes.name'),
sortable: true,
searchable: true,
class: [
'Attributes__table__cell',
'Attributes__table__cell--name',
Expand Down Expand Up @@ -68,6 +69,7 @@ const Attributes = defineComponent({
'Attributes__table__cell',
'Attributes__table__cell--unit',
],
searchable: true,
render: (h: CreateElement, attribute: Attribute) => (
attribute.type === AttributeType.INTEGER || attribute.type === AttributeType.FLOAT
? attribute.unit
Expand Down
2 changes: 1 addition & 1 deletion client/src/themes/default/pages/Beneficiaries/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Link from '@/themes/default/components/Link';

import type { ComponentRef, CreateElement } from 'vue';
import type { Beneficiary } from '@/stores/api/beneficiaries';
import type { Columns } from '@/themes/default/components/Table';
import type { Columns } from '@/themes/default/components/Table/Server';
import type { ListingParams } from '@/stores/api/@types';

type Data = {
Expand Down
Loading

0 comments on commit dfc2b65

Please sign in to comment.