Skip to content

Commit

Permalink
feat(admin): refactor search & design
Browse files Browse the repository at this point in the history
  • Loading branch information
pYassine committed Dec 2, 2024
1 parent 5a3040f commit 2456560
Show file tree
Hide file tree
Showing 116 changed files with 1,039 additions and 2,473 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[SUPPORT] {{subject}} - {{ structureName }}
{{subject}} - {{ structureName }}
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export class ContactSupportDto {
type: String,
required: false,
})
@IsNotEmpty()
@Transform(({ value }: TransformFnParams) => {
value = sanitizeHtml(value);
return value.toString().trim();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function sendMail(model: ContactSupport): Promise<void> {
personalName: "DomiFa",
},
];
const subject = `[SUPPORT] ${model.subject} - ${model.name}`;
const subject = `${model.subject} - ${model.structureName}`;

const attachments: MessageEmailAttachment[] = model.attachment
? [model.attachment]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,12 @@ export class AdminStructuresService {
public async getAdminStructuresListData(): Promise<StructureAdminForList[]> {
return await structureRepository
.createQueryBuilder("structure")
.select("structure.*")
.leftJoin("usager", "usager", `usager."structureId" = structure.id`)
.leftJoin(
"user_structure",
"user_structure",
`user_structure."structureId" = structure.id`
)
.addSelect("COUNT(DISTINCT usager.uuid)", "usagers")
.addSelect("COUNT(DISTINCT user_structure.uuid)", "users")
.groupBy("structure.uuid")
.orderBy(`structure."createdAt"`, "DESC")
.select([
"structure.*",
`(SELECT COUNT(DISTINCT u.uuid) FROM usager u WHERE u."structureId" = structure.id) as usagers`,
`(SELECT COUNT(DISTINCT us.uuid) FROM user_structure us WHERE us."structureId" = structure.id) as users`,
])
.orderBy("structure.createdAt", "DESC")
.getRawMany();
}

Expand Down
10 changes: 7 additions & 3 deletions packages/backend/src/usagers/controllers/usagers.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ import { UsagerHistoryStateService } from "../services/usagerHistoryState.servic
import { domifaConfig } from "../../config";
import { FileManagerService } from "../../util/file-manager/file-manager.service";
import { Not } from "typeorm";
import { isDateString } from "class-validator";
import { isValid, parse } from "date-fns";

@Controller("usagers")
@ApiTags("usagers")
Expand Down Expand Up @@ -171,9 +171,13 @@ export class UsagersController {
}

if (search.searchString && search.searchStringField === "DATE_NAISSANCE") {
if (!isDateString(search.searchString)) {
throw new BadRequestException("SEARCH_PARAMS_ERROR");
const parsedDate = parse(search.searchString, "dd MM yyyy", new Date());
if (!isValid(parsedDate)) {
throw new BadRequestException(
'Format de date invalide. Utilisez le format "dd MM yyyy"'
);
}

query.andWhere(`DATE("dateNaissance") = DATE(:date)`, {
date: new Date(search.searchString),
});
Expand Down
2 changes: 1 addition & 1 deletion packages/common/src/search/USAGER_DEADLINES.const.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { subMonths, addMonths, subYears, addWeeks } from "date-fns";
import { TimingsConfig, Timings } from "./Timings.type";
import { TimingsConfig, Timings } from "./types/Timings.type";

export function getUsagerDeadlines(refDate: Date = new Date()): TimingsConfig {
return {
Expand Down
15 changes: 15 additions & 0 deletions packages/common/src/search/classes/Search.class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { SortValues } from "../types";

export class Search {
public searchString: string | null;
public sortKey: string;
public sortValue: SortValues;
public page: number;

constructor(search?: any) {
this.searchString = search?.searchString ?? null;
this.sortKey = search?.sortKey ?? null;
this.sortValue = search?.sortValue ?? "asc";
this.page = search?.page ?? 1;
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
//@index('./*', f => `export * from '${f.path}'`)
export * from "./constants";
export * from "./Search.class";
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./search";
export * from "./searchChunks";
export * from "./searchCore";
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { searchChunks } from "./searchChunks";
import { searchCore } from "./searchCore";
import { buildWords, clean } from "./searchCore";

type MatchWithScoreResults = {
match: boolean;
Expand All @@ -20,7 +20,7 @@ function matchWord({
if (!attr) {
return score;
}
const matchElement = attr.indexOf(word) !== -1;
const matchElement = attr.includes(word);
if (matchElement) {
if (attr === word) {
// perfect match
Expand All @@ -43,7 +43,7 @@ function matchWord({
if (!attr) {
return false;
}
return searchCore.clean(attr as unknown as string).indexOf(word) !== -1;
return clean(attr as unknown as string).includes(word);
});
if (firstMatchingAttribute !== undefined) {
return {
Expand Down Expand Up @@ -81,10 +81,10 @@ function match<T>(
}

const attributes: string[] = getAttributes(item, index) ?? [];
const cleanAttributes: string[] = [].concat(
const cleanAttributes: string[] = ([] as string[]).concat(
...attributes
.filter((x) => x !== null && x !== undefined && x.trim().length !== 0)
.map((x) => searchCore.buildWords(x))
.map((x) => buildWords(x))
);

if (!cleanAttributes?.length) {
Expand Down Expand Up @@ -136,6 +136,4 @@ function match<T>(
export const search = {
match,
contentChunks: searchChunks.find,
clean: searchCore.clean,
buildWords: searchCore.buildWords,
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { searchCore } from "./searchCore";
import { buildWords, clean } from "./searchCore";

export interface Bounds {
start: number;
Expand Down Expand Up @@ -50,7 +50,7 @@ function find(
searchText: string;
}
): Chunk[] {
const words = searchCore.buildWords(searchText);
const words = buildWords(searchText);
if (words.length === 0 || !content || !content.length) {
return [
{
Expand All @@ -59,7 +59,7 @@ function find(
},
];
}
const cleanContent = searchCore.clean(content);
const cleanContent = clean(content);

const allWordsIndices: Bounds[] = _findAllWordsIndices(words, cleanContent);

Expand Down
14 changes: 14 additions & 0 deletions packages/common/src/search/core/searchCore.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { buildWords, clean, trim } from "./searchCore";

it("trim", () => {
expect(trim(" \ttwo words\n \t ")).toEqual("two words");
});

it("clean", () => {
expect(clean("à la Câmpagne éÂ!")).toEqual("a la campagne ea ");
});

it("buildWords", () => {
expect(buildWords("a few words")).toEqual(["a", "few", "words"]);
expect(buildWords("two_words ")).toEqual(["two", "words"]);
});
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { normalizeString } from "@domifa/common";
import { normalizeString } from "../functions";

export function trim(str: string): string {
export const trim = (str: string): string => {
return str.trim();
}
};

export function clean(str: string): string {
export const clean = (str: string): string => {
if (!str) {
return str;
}
return normalizeString(trim(str).toLowerCase());
}
};

export function buildWords(searchText: string): string[] {
export const buildWords = (searchText: string): string[] => {
const str = searchText ? clean(searchText) : undefined;
if (!str?.length) {
return [];
Expand All @@ -20,10 +20,4 @@ export function buildWords(searchText: string): string[] {
.split(" ")
.filter((x) => x !== null && x !== undefined && x.trim().length !== 0)
.map((word) => clean(word));
}

export const searchCore = {
trim,
clean,
buildWords,
};
5 changes: 4 additions & 1 deletion packages/common/src/search/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// @index('./*', f => `export * from '${f.path}'`)
export * from "./classes";
export * from "./core";
export * from "./functions";
export * from "./Timings.type";
export * from "./sorter";
export * from "./types";
export * from "./USAGER_DEADLINES.const";
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { dataSorter } from "./dataSorter.service";
import { sortMultiple } from "./dataSorter.service";

describe("dataSorter.sortMultiple", () => {
const obj1 = {
Expand Down Expand Up @@ -29,17 +29,21 @@ describe("dataSorter.sortMultiple", () => {

it("Should sort by cat ASC", () => {
expect(
dataSorter.sortMultiple([obj1, obj4, obj2, obj5, obj3], true, {
getSortAttributes: (item) => [item.cat, item.score, item.label],
})
sortMultiple([obj1, obj4, obj2, obj5, obj3], true, (item) => [
item.cat,
item.score,
item.label,
])
).toEqual([obj1, obj2, obj5, obj3, obj4]);
});

it("Should sort by cat DESC", () => {
expect(
dataSorter.sortMultiple([obj1, obj4, obj2, obj5, obj3], false, {
getSortAttributes: (item) => [item.cat, item.score, item.label],
})
sortMultiple([obj1, obj4, obj2, obj5, obj3], false, (item) => [
item.cat,
item.score,
item.label,
])
).toEqual([obj4, obj3, obj5, obj2, obj1]);
});
});
Original file line number Diff line number Diff line change
@@ -1,41 +1,10 @@
export type SortableValue = string | number | Date | null | undefined;

export const dataSorter = {
sortMultiple,
};

function sortMultiple<T>(
items: T[],
asc: boolean,
{
getSortAttributes,
}: {
getSortAttributes: (item: T) => SortableValue[];
}
): T[] {
return items.sort((a, b) => {
const attrsA = getSortAttributes(a);
const attrsB = getSortAttributes(b);

for (let i = 0; i < attrsA.length; i++) {
const attrA = attrsA[i];
const attrB = attrsB[i];

const comparison = compareAttributes(attrA, attrB, asc !== false);
if (comparison !== 0) {
return comparison;
}
}

return 0;
});
}

export function compareAttributes(
export const compareAttributes = (
a: SortableValue,
b: SortableValue,
asc: boolean
): number {
): number => {
if (a === b) return 0;
if (asc) {
if (a === null || a === undefined) return -1;
Expand Down Expand Up @@ -66,7 +35,30 @@ export function compareAttributes(
const strA = String(a);
const strB = String(b);
return asc ? strA.localeCompare(strB) : strB.localeCompare(strA);
}
};

export const sortMultiple = <T>(
items: T[],
asc: boolean,
getSortAttributes: (item: T) => SortableValue[]
): T[] => {
return items.sort((a, b) => {
const attrsA = getSortAttributes(a);
const attrsB = getSortAttributes(b);

for (let i = 0; i < attrsA.length; i++) {
const attrA = attrsA[i];
const attrB = attrsB[i];

const comparison = compareAttributes(attrA, attrB, asc !== false);
if (comparison !== 0) {
return comparison;
}
}

return 0;
});
};

function isValidDate(value?: SortableValue): boolean {
if (!value) return false;
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions packages/common/src/search/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @index('./*', f => `export * from '${f.path}'`)
export * from "./SortValues.type";
export * from "./Timings.type";
1 change: 0 additions & 1 deletion packages/frontend/src/_common/model/_general/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//@index('./*', f => `export * from '${f.path}'`)
export * from "./DEFAULT_MODAL_OPTIONS.const";
export * from "./FormEmailTakenValidator.type";
export * from "./SortValues.type";
1 change: 0 additions & 1 deletion packages/frontend/src/_common/model/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@index('./*', f => `export * from '${f.path}'`)
export * from "./_general";
export * from "./interaction";
export * from "./structure-doc";
export * from "./telephone";
export * from "./usager";
export * from "./user-structure";

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ <h1 class="col-md-2 col-6 title text-start order-1 order-md-1">
aria-hidden="true"
></fa-icon>
<br />
<span class="loading_message">Chargement des dossiers...</span>
<span>Chargement des dossiers...</span>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe("ManageUsagersPageComponent", () => {

let fixture: ComponentFixture<ManageUsagersPageComponent>;

beforeAll(async () => {
beforeAll(() => {
TestBed.configureTestingModule({
declarations: [ManageUsagersPageComponent],
imports: [
Expand Down
Loading

0 comments on commit 2456560

Please sign in to comment.