From e6ee90c4c9bd9a33c17a86a2670a5073050de1b8 Mon Sep 17 00:00:00 2001 From: "Yassine R." Date: Fri, 18 Oct 2024 01:44:43 +0200 Subject: [PATCH] fix(backend): strip tags from labels --- .../_common/decorators/StripTagsDecorator.ts | 11 ++++-- .../src/usagers/dto/UploadUsagerDoc.dto.ts | 3 +- .../src/usagers/dto/UsagerAyantDroitDto.ts | 5 ++- .../dto/check-duplicate-usager-ref.dto.ts | 2 + .../src/usagers/dto/search-usager.dto.ts | 7 +++- .../backend/src/usagers/dto/transfert.dto.ts | 4 +- packages/frontend/.deepsource.toml | 9 ----- .../model/structure-doc/constants/index.ts | 2 - .../interceptors/server-error.interceptor.ts | 7 ++-- .../manage-structure-information.component.ts | 2 - .../src/app/modules/general/general.module.ts | 2 + .../STRUCTURE_DOC_ICONS.const.ts | 23 ------------ .../display-table-image.component.html | 4 +- .../display-table-image.component.scss | 21 +++++++++++ .../display-table-image.component.spec.ts | 2 +- .../display-table-image.component.ts | 30 +++++++++++++-- .../shared/directives/clean-str.directive.ts | 37 ++++++++++--------- .../src/app/modules/shared/shared.module.ts | 1 + .../structures-custom-docs.component.ts | 6 +-- .../structures-upload-docs.component.html | 1 + .../structures-upload-docs.component.ts | 8 ++-- .../modules/structures/structures.module.ts | 2 + .../profil-structure-docs.component.html | 26 +++++++++++-- .../profil-structure-docs.component.spec.ts | 2 + .../profil-structure-docs.component.ts | 4 ++ .../display-usager-docs.component.ts | 29 +++++++-------- .../components/upload/upload.component.html | 1 + packages/frontend/src/assets/css/main.scss | 22 ----------- 28 files changed, 153 insertions(+), 120 deletions(-) delete mode 100644 packages/frontend/.deepsource.toml delete mode 100644 packages/frontend/src/app/modules/shared/components/display-table-image/STRUCTURE_DOC_ICONS.const.ts create mode 100644 packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.scss diff --git a/packages/backend/src/_common/decorators/StripTagsDecorator.ts b/packages/backend/src/_common/decorators/StripTagsDecorator.ts index c4d93c36a9..1ef5898928 100644 --- a/packages/backend/src/_common/decorators/StripTagsDecorator.ts +++ b/packages/backend/src/_common/decorators/StripTagsDecorator.ts @@ -5,18 +5,23 @@ import { } from "class-transformer"; import striptags from "striptags"; +import sanitizeHtml from "sanitize-html"; export function StripTagsTransform( transformOptions?: TransformOptions ): (target: any, key: string) => void { return Transform((sourceData: TransformFnParams) => { - if ("string" !== typeof sourceData.value) { + if (typeof sourceData.value !== "string") { return null; } - if (sourceData.value.trim() === "") { + + const trimmedValue = sourceData.value.trim(); + if (trimmedValue === "") { return null; } - return striptags(sourceData.value) + + const sanitized = sanitizeHtml(trimmedValue); + return striptags(sanitized) .replace(/[\\$~*<>{}]/gi, "") .replace(/\s+/g, " ") .trim(); diff --git a/packages/backend/src/usagers/dto/UploadUsagerDoc.dto.ts b/packages/backend/src/usagers/dto/UploadUsagerDoc.dto.ts index e51e121a31..bdb460b3e7 100644 --- a/packages/backend/src/usagers/dto/UploadUsagerDoc.dto.ts +++ b/packages/backend/src/usagers/dto/UploadUsagerDoc.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty, IsString, MaxLength } from "class-validator"; -import { Trim } from "../../_common/decorators"; +import { StripTagsTransform, Trim } from "../../_common/decorators"; export class UploadUsagerDocDto { @ApiProperty({ @@ -12,6 +12,7 @@ export class UploadUsagerDocDto { @MaxLength(100) @IsString() @Trim() + @StripTagsTransform() public label!: string; @ApiProperty({ type: "string", format: "binary" }) diff --git a/packages/backend/src/usagers/dto/UsagerAyantDroitDto.ts b/packages/backend/src/usagers/dto/UsagerAyantDroitDto.ts index 9788166347..6bb32f0f39 100644 --- a/packages/backend/src/usagers/dto/UsagerAyantDroitDto.ts +++ b/packages/backend/src/usagers/dto/UsagerAyantDroitDto.ts @@ -8,7 +8,7 @@ import { } from "class-validator"; import { LIEN_PARENTE_LABELS, AyantDroiLienParent } from "@domifa/common"; -import { Trim } from "../../_common/decorators"; +import { StripTagsTransform, Trim } from "../../_common/decorators"; export class UsagerAyantDroitDto { @ApiProperty({ @@ -19,6 +19,7 @@ export class UsagerAyantDroitDto { @IsNotEmpty() @MaxLength(200) @IsString() + @StripTagsTransform() @Trim() public nom!: string; @@ -29,6 +30,7 @@ export class UsagerAyantDroitDto { }) @IsNotEmpty() @MaxLength(200) + @StripTagsTransform() @IsString() @Trim() public prenom!: string; @@ -40,6 +42,7 @@ export class UsagerAyantDroitDto { }) @IsNotEmpty() @IsString() + @StripTagsTransform() @Trim() @IsIn(Object.keys(LIEN_PARENTE_LABELS)) public lien!: AyantDroiLienParent; diff --git a/packages/backend/src/usagers/dto/check-duplicate-usager-ref.dto.ts b/packages/backend/src/usagers/dto/check-duplicate-usager-ref.dto.ts index d72537ad3a..d355c04623 100644 --- a/packages/backend/src/usagers/dto/check-duplicate-usager-ref.dto.ts +++ b/packages/backend/src/usagers/dto/check-duplicate-usager-ref.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty, IsString, MaxLength } from "class-validator"; +import { StripTagsTransform } from "../../_common/decorators"; export class CheckDuplicateUsagerRefDto { @ApiProperty({ @@ -7,6 +8,7 @@ export class CheckDuplicateUsagerRefDto { }) @IsNotEmpty() @IsString() + @StripTagsTransform() @MaxLength(100) public customRef!: string; } diff --git a/packages/backend/src/usagers/dto/search-usager.dto.ts b/packages/backend/src/usagers/dto/search-usager.dto.ts index 287101bd9f..c296a31247 100644 --- a/packages/backend/src/usagers/dto/search-usager.dto.ts +++ b/packages/backend/src/usagers/dto/search-usager.dto.ts @@ -1,6 +1,10 @@ import { ApiProperty } from "@nestjs/swagger"; import { IsNotEmpty, IsString, MinLength } from "class-validator"; -import { LowerCaseTransform, Trim } from "../../_common/decorators"; +import { + LowerCaseTransform, + StripTagsTransform, + Trim, +} from "../../_common/decorators"; export class SearchUsagerDto { @ApiProperty({ @@ -11,6 +15,7 @@ export class SearchUsagerDto { @IsString() @Trim() @MinLength(3) + @StripTagsTransform() @LowerCaseTransform() public searchString!: string; } diff --git a/packages/backend/src/usagers/dto/transfert.dto.ts b/packages/backend/src/usagers/dto/transfert.dto.ts index a7fba1a9de..fa60b9297c 100644 --- a/packages/backend/src/usagers/dto/transfert.dto.ts +++ b/packages/backend/src/usagers/dto/transfert.dto.ts @@ -9,7 +9,7 @@ import { import { ApiProperty } from "@nestjs/swagger"; import { Transform, TransformFnParams } from "class-transformer"; -import { Trim } from "../../_common/decorators"; +import { StripTagsTransform, Trim } from "../../_common/decorators"; import { UsagerOptionsTransfert } from "@domifa/common"; export class TransfertDto implements UsagerOptionsTransfert { @@ -27,6 +27,7 @@ export class TransfertDto implements UsagerOptionsTransfert { @IsString() @MaxLength(200) @Trim() + @StripTagsTransform() public nom!: string; @ApiProperty({ @@ -37,6 +38,7 @@ export class TransfertDto implements UsagerOptionsTransfert { @IsString() @MaxLength(400) @MinLength(10) + @StripTagsTransform() @Trim() public adresse!: string; diff --git a/packages/frontend/.deepsource.toml b/packages/frontend/.deepsource.toml deleted file mode 100644 index c1db6d8df0..0000000000 --- a/packages/frontend/.deepsource.toml +++ /dev/null @@ -1,9 +0,0 @@ -# DeepSource configuration file -# Learn how to configure: https://docs.deepsource.com/docs/configuration -version = 1 -exclude_patterns = ["node_modules", "bower_components", "out", "bin", "build", "dist"] -test_patterns = ["**/__tests__/**", "**/*.spec.ts", "**/*.spec.js", "**/*.test.ts", "**/*.test.js"] - -[[analyzers]] - name = "javascript" - enabled = true diff --git a/packages/frontend/src/_common/model/structure-doc/constants/index.ts b/packages/frontend/src/_common/model/structure-doc/constants/index.ts index 035d5d281d..65af98d5e6 100644 --- a/packages/frontend/src/_common/model/structure-doc/constants/index.ts +++ b/packages/frontend/src/_common/model/structure-doc/constants/index.ts @@ -1,4 +1,2 @@ //@index('./*', f => `export * from '${f.path}'`) export * from "./DOCUMENT_EXTENSION_LABELS.const"; -export * from "../../../../app/modules/structures/constants/DOMIFA_CUSTOM_DOCS.const"; -export * from "../../../../app/modules/shared/components/display-table-image/STRUCTURE_DOC_ICONS.const"; diff --git a/packages/frontend/src/app/interceptors/server-error.interceptor.ts b/packages/frontend/src/app/interceptors/server-error.interceptor.ts index 91d0fa22b5..05625acea2 100644 --- a/packages/frontend/src/app/interceptors/server-error.interceptor.ts +++ b/packages/frontend/src/app/interceptors/server-error.interceptor.ts @@ -38,8 +38,9 @@ export class ServerErrorInterceptor implements HttpInterceptor { getCurrentScope().setTag("structure", user?.structureId?.toString()); getCurrentScope().setUser({ email: user.email, - username: - "STRUCTURE " + user?.structureId?.toString() + " : " + user?.prenom, + username: `STRUCTURE ${user?.structureId?.toString()} : ${ + user?.prenom + }`, }); } @@ -93,7 +94,7 @@ export class ServerErrorInterceptor implements HttpInterceptor { } private logError(request: HttpRequest, error: HttpErrorResponse): void { - console.error(error.message, { + console.warn(error.message, { status: error.status, statusText: error.statusText, url: error.url, diff --git a/packages/frontend/src/app/modules/admin-portail-usagers/components/manage-structure-information/manage-structure-information.component.ts b/packages/frontend/src/app/modules/admin-portail-usagers/components/manage-structure-information/manage-structure-information.component.ts index 839f0d8f74..a7df5aba2b 100644 --- a/packages/frontend/src/app/modules/admin-portail-usagers/components/manage-structure-information/manage-structure-information.component.ts +++ b/packages/frontend/src/app/modules/admin-portail-usagers/components/manage-structure-information/manage-structure-information.component.ts @@ -36,8 +36,6 @@ export class ManageStructureInformationComponent implements OnInit { this.loading = false; this.structureInformation = []; this.selectedStructureInformation = null; - - console.log(STRUCTURE_INFORMATION_TYPES); } ngOnInit(): void { diff --git a/packages/frontend/src/app/modules/general/general.module.ts b/packages/frontend/src/app/modules/general/general.module.ts index c0a80c8509..7be7b410a8 100644 --- a/packages/frontend/src/app/modules/general/general.module.ts +++ b/packages/frontend/src/app/modules/general/general.module.ts @@ -33,6 +33,7 @@ import { HelpModalComponent } from "./components/static-modals/help-modal/help-m import { RgaaComponent } from "./components/static-pages/rgaa/rgaa.component"; import { LandingPagePortailComponent } from "./components/static-pages/landing-page-portail/landing-page-portail.component"; import { HomeStatsComponent } from "../stats/components/home-stats/home-stats.component"; +import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; @NgModule({ declarations: [ @@ -73,6 +74,7 @@ import { HomeStatsComponent } from "../stats/components/home-stats/home-stats.co SharedModule, RouterModule.forChild([]), NgbModule, + FontAwesomeModule, HomeStatsComponent, ], providers: [GeneralService], diff --git a/packages/frontend/src/app/modules/shared/components/display-table-image/STRUCTURE_DOC_ICONS.const.ts b/packages/frontend/src/app/modules/shared/components/display-table-image/STRUCTURE_DOC_ICONS.const.ts deleted file mode 100644 index fb4067e74d..0000000000 --- a/packages/frontend/src/app/modules/shared/components/display-table-image/STRUCTURE_DOC_ICONS.const.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; -import { - faFileWord, - faImage, - faFileExcel, - faFilePdf, -} from "@fortawesome/free-regular-svg-icons"; - -export const STRUCTURE_DOC_ICONS: { - [key: string]: IconDefinition; -} = { - "image/jpg": faImage, - "image/jpeg": faImage, - "image/png": faImage, - "application/pdf": faFilePdf, - "application/msword": faFileWord, - "application/vnd.openxmlformats-officedocument.wordprocessingml.document": - faFileWord, - "application/vnd.oasis.opendocument.text": faFileWord, - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": - faFileExcel, - "application/vnd.ms-excel": faFileExcel, -}; diff --git a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.html b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.html index 14d0e9c49f..3e054eed73 100644 --- a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.html +++ b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.html @@ -1,14 +1,12 @@ - {{ STRUCTURE_DOC_EXTENSIONS_LABELS[document.filetype] }} diff --git a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.scss b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.scss new file mode 100644 index 0000000000..74c4eb59ca --- /dev/null +++ b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.scss @@ -0,0 +1,21 @@ +.doc-icon { + padding: 0.4rem 1.2rem; + font-size: 2rem; + text-align: center; + border-radius: 6px; + display: inline-block; + background-color: #ecefff; +} + +.icon-image { + color: #553828; +} +.icon-file-pdf { + color: #fe3b31; +} +.icon-file-word { + color: #017aff; +} +.icon-file-excel { + color: #33c75a; +} diff --git a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.spec.ts b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.spec.ts index ebc466f0d3..d1ea299d17 100644 --- a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.spec.ts +++ b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.spec.ts @@ -1,10 +1,10 @@ import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from "@angular/core"; import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { DOMIFA_CUSTOM_DOCS } from "../../../../../_common/model"; import { DisplayTableImageComponent } from "./display-table-image.component"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; import { NgClass } from "@angular/common"; +import { DOMIFA_CUSTOM_DOCS } from "../../../structures/constants/DOMIFA_CUSTOM_DOCS.const"; describe("DisplayTableImageComponent", () => { let component: DisplayTableImageComponent; diff --git a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.ts b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.ts index 8aed16aaba..97e26d92a3 100644 --- a/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.ts +++ b/packages/frontend/src/app/modules/shared/components/display-table-image/display-table-image.component.ts @@ -1,15 +1,23 @@ import { Component, Input } from "@angular/core"; import { StructureDoc, UsagerDoc } from "@domifa/common"; -import { STRUCTURE_DOC_ICONS } from "./STRUCTURE_DOC_ICONS.const"; +import { JsonPipe, NgClass } from "@angular/common"; + import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; -import { NgClass } from "@angular/common"; +import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; +import { + faFileWord, + faImage, + faFileExcel, + faFilePdf, +} from "@fortawesome/free-regular-svg-icons"; @Component({ selector: "app-display-table-image", templateUrl: "./display-table-image.component.html", standalone: true, - imports: [FontAwesomeModule, NgClass], + imports: [FontAwesomeModule, NgClass, JsonPipe], + styleUrl: "./display-table-image.component.scss", }) export class DisplayTableImageComponent { @Input() public document!: UsagerDoc | StructureDoc; @@ -29,5 +37,19 @@ export class DisplayTableImageComponent { "application/vnd.ms-excel": "Feuille de calcul Excel", }; - public readonly STRUCTURE_DOC_ICONS = STRUCTURE_DOC_ICONS; + public readonly STRUCTURE_DOC_ICONS: { + [key: string]: IconDefinition; + } = { + "image/jpg": faImage, + "image/jpeg": faImage, + "image/png": faImage, + "application/pdf": faFilePdf, + "application/msword": faFileWord, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + faFileWord, + "application/vnd.oasis.opendocument.text": faFileWord, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": + faFileExcel, + "application/vnd.ms-excel": faFileExcel, + }; } diff --git a/packages/frontend/src/app/modules/shared/directives/clean-str.directive.ts b/packages/frontend/src/app/modules/shared/directives/clean-str.directive.ts index 4151a65a6f..2e45d5a03d 100644 --- a/packages/frontend/src/app/modules/shared/directives/clean-str.directive.ts +++ b/packages/frontend/src/app/modules/shared/directives/clean-str.directive.ts @@ -1,29 +1,30 @@ -import { Directive, ElementRef, HostListener } from "@angular/core"; +import { Directive, ElementRef, HostListener, Renderer2 } from "@angular/core"; import { stringCleaner } from "../../../shared/string-cleaner.service"; +import { NgControl } from "@angular/forms"; @Directive({ selector: "[appCleanStr]", }) export class CleanStrDirective { - constructor(private readonly el: ElementRef) {} - - @HostListener("keypress", ["$event"]) - public onKeyPress(event: KeyboardEvent) { - return this.validateFields(event); - } + constructor( + private readonly el: ElementRef, + private renderer: Renderer2, + private control: NgControl + ) {} @HostListener("paste", ["$event"]) - public blockPaste(event: KeyboardEvent) { - this.validateFields(event); - } - - public validateFields(event: KeyboardEvent) { - setTimeout(() => { - this.el.nativeElement.value = stringCleaner.cleanString( - this.el.nativeElement.value - ); - event.preventDefault(); - }, 10); + @HostListener("input", ["$event"]) + @HostListener("keypress", ["$event"]) + onInputChange(event: Event) { + const inputElement = event.target as HTMLInputElement; + const cleanedValue = stringCleaner.cleanString(inputElement.value); + this.renderer.setProperty(inputElement, "value", cleanedValue); + this.renderer.setProperty(this.el.nativeElement, "value", cleanedValue); + this.control.control.setValue(cleanedValue, { emitEvent: false }); + this.control.control.updateValueAndValidity({ + onlySelf: true, + emitEvent: false, + }); } } diff --git a/packages/frontend/src/app/modules/shared/shared.module.ts b/packages/frontend/src/app/modules/shared/shared.module.ts index 512ece8c39..e5268d5642 100644 --- a/packages/frontend/src/app/modules/shared/shared.module.ts +++ b/packages/frontend/src/app/modules/shared/shared.module.ts @@ -23,6 +23,7 @@ import { DateFrDirective, CleanStrDirective } from "./directives"; DateFrDirective, CleanStrDirective, CustomToastrComponent, + FontAwesomeModule, ], imports: [CommonModule, FontAwesomeModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/packages/frontend/src/app/modules/structures/components/structures-custom-docs/structures-custom-docs.component.ts b/packages/frontend/src/app/modules/structures/components/structures-custom-docs/structures-custom-docs.component.ts index e02ea917df..4b57b891fa 100644 --- a/packages/frontend/src/app/modules/structures/components/structures-custom-docs/structures-custom-docs.component.ts +++ b/packages/frontend/src/app/modules/structures/components/structures-custom-docs/structures-custom-docs.component.ts @@ -9,14 +9,12 @@ import { Title } from "@angular/platform-browser"; import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap"; import { Subscription } from "rxjs"; import { CustomToastService } from "src/app/modules/shared/services/custom-toast.service"; -import { - DOMIFA_CUSTOM_DOCS, - DEFAULT_MODAL_OPTIONS, -} from "../../../../../_common/model"; +import { DEFAULT_MODAL_OPTIONS } from "../../../../../_common/model"; import { AuthService } from "../../../shared/services/auth.service"; import { StructureDocService } from "../../services/structure-doc.service"; import { StructureDoc, UserStructure } from "@domifa/common"; +import { DOMIFA_CUSTOM_DOCS } from "../../constants/DOMIFA_CUSTOM_DOCS.const"; @Component({ selector: "app-structures-custom-docs", diff --git a/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.html b/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.html index c05fe4e1e8..ef45d22aac 100644 --- a/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.html +++ b/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.html @@ -58,6 +58,7 @@ formControlName="label" name="label" id="label" + appCleanStr [ngClass]="{ 'is-invalid': submitted && f.label.errors }" [attr.aria-describedby]=" submitted && f.label.errors ? 'label-errors' : 'label-description' diff --git a/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.ts b/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.ts index 4d3a8765a0..6988c732e2 100644 --- a/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.ts +++ b/packages/frontend/src/app/modules/structures/components/structures-upload-docs/structures-upload-docs.component.ts @@ -15,7 +15,7 @@ import { import { Subscription } from "rxjs"; import { StructureDocService } from "../../services/structure-doc.service"; -import { validateUpload } from "../../../../shared"; +import { NoWhiteSpaceValidator, validateUpload } from "../../../../shared"; import { CustomToastService } from "../../../shared/services"; @Component({ @@ -31,10 +31,10 @@ export class StructuresUploadDocsComponent implements OnInit, OnDestroy { private subscription = new Subscription(); @Output() - public cancel = new EventEmitter(); + public readonly cancel = new EventEmitter(); @Output() - public getAllStructureDocs = new EventEmitter(); + public readonly getAllStructureDocs = new EventEmitter(); constructor( private readonly formBuilder: UntypedFormBuilder, @@ -44,7 +44,7 @@ export class StructuresUploadDocsComponent implements OnInit, OnDestroy { public ngOnInit(): void { this.uploadForm = this.formBuilder.group({ - label: ["", [Validators.required]], + label: ["", [Validators.required, NoWhiteSpaceValidator]], file: ["", [Validators.required]], fileSource: [ "", diff --git a/packages/frontend/src/app/modules/structures/structures.module.ts b/packages/frontend/src/app/modules/structures/structures.module.ts index 2f254efe9c..9c1a6c08d4 100644 --- a/packages/frontend/src/app/modules/structures/structures.module.ts +++ b/packages/frontend/src/app/modules/structures/structures.module.ts @@ -20,6 +20,7 @@ import { StructuresUploadDocsComponent } from "./components/structures-upload-do import { StructuresRoutingModule } from "./structures-routing.module"; import { GeneralModule } from "../general/general.module"; import { SortArrayPipe } from "../shared/pipes"; +import { DisplayTableImageComponent } from "../shared/components/display-table-image/display-table-image.component"; @NgModule({ declarations: [ @@ -46,6 +47,7 @@ import { SortArrayPipe } from "../shared/pipes"; GeneralModule, StructuresRoutingModule, SortArrayPipe, + DisplayTableImageComponent, ], providers: [], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.html b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.html index 694fa8c56a..32aac22944 100644 --- a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.html +++ b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.html @@ -6,9 +6,25 @@ Type - Nom du document + + + + Ajouté par - Ajouté le + + + + Actions @@ -112,7 +128,11 @@ diff --git a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.spec.ts b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.spec.ts index 69e28882b8..0067abcdb6 100644 --- a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.spec.ts +++ b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.spec.ts @@ -11,6 +11,7 @@ import { RouterTestingModule } from "@angular/router/testing"; import { NgbModule } from "@ng-bootstrap/ng-bootstrap"; import { SharedModule } from "../../../../shared/shared.module"; +import { SortArrayPipe } from "../../../../shared/pipes"; describe("ProfilStructureDocsComponent", () => { let component: ProfilStructureDocsComponent; @@ -26,6 +27,7 @@ describe("ProfilStructureDocsComponent", () => { ReactiveFormsModule, RouterTestingModule, SharedModule, + SortArrayPipe, ], providers: [{ provide: APP_BASE_HREF, useValue: "/" }], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.ts b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.ts index 7e6e634dfd..633fed4355 100644 --- a/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.ts +++ b/packages/frontend/src/app/modules/usager-profil/components/_documents/profil-structure-documents/profil-structure-docs.component.ts @@ -10,6 +10,7 @@ import { StructureDocTypesAvailable, UserStructure, } from "@domifa/common"; +import { UsagersFilterCriteriaSortValues } from "../../../../manage-usagers/components/usager-filter"; @Component({ selector: "app-profil-structure-docs", @@ -30,6 +31,9 @@ export class ProfilStructureDocsComponent implements OnInit, OnDestroy { // Frontend variables public loadings: string[]; + public sortValue: UsagersFilterCriteriaSortValues = "desc"; + public currentKey: keyof StructureDoc = "createdAt"; + constructor( private readonly documentService: DocumentService, private readonly toastService: CustomToastService diff --git a/packages/frontend/src/app/modules/usager-shared/components/display-usager-docs/display-usager-docs.component.ts b/packages/frontend/src/app/modules/usager-shared/components/display-usager-docs/display-usager-docs.component.ts index 6446c64fae..918084e9ae 100644 --- a/packages/frontend/src/app/modules/usager-shared/components/display-usager-docs/display-usager-docs.component.ts +++ b/packages/frontend/src/app/modules/usager-shared/components/display-usager-docs/display-usager-docs.component.ts @@ -8,6 +8,7 @@ import { saveAs } from "file-saver"; import { Subscription } from "rxjs"; import { UsagerDoc, UserStructure } from "@domifa/common"; import { UsagersFilterCriteriaSortValues } from "../../../manage-usagers/components/usager-filter"; +import slug from "slug"; @Component({ selector: "app-display-usager-docs", @@ -68,13 +69,12 @@ export class DisplayUsagerDocsComponent implements OnInit, OnDestroy { const extension = STRUCTURE_DOC_EXTENSIONS[doc.filetype]; const newBlob = new Blob([blob], { type: doc.filetype }); - saveAs( - newBlob, + const name = this.slugLabel(doc.label) + - "_" + - this.slugLabel(this.usager.nom + " " + this.usager.prenom) + - extension - ); + "_" + + this.slugLabel(this.usager.nom + " " + this.usager.prenom) + + extension; + saveAs(newBlob, name); this.stopLoading("download", docIndex); }, error: () => { @@ -105,15 +105,14 @@ export class DisplayUsagerDocsComponent implements OnInit, OnDestroy { } private slugLabel(docName: string): string { - docName = docName.trim().toLowerCase(); - docName = docName.replace(/\W/g, "_"); - docName = docName.replace(/-+/g, "_"); - docName = docName.replace("_l_", "_"); - docName = docName.replace("_d_", "_"); - docName = docName.replace("_a_", "_"); - docName = docName.replace("_n_", "_"); - docName = docName.replace(/__/g, "_"); - return docName; + return slug(docName, { + mode: "rfc3986" as const, + lower: true, + replacement: "-", + locale: "fr", + trim: true, + remove: /[.]/g, // Supprime tous les points + }); } private startLoading( diff --git a/packages/frontend/src/app/modules/usager-shared/components/upload/upload.component.html b/packages/frontend/src/app/modules/usager-shared/components/upload/upload.component.html index 4c36dc912e..c422107959 100644 --- a/packages/frontend/src/app/modules/usager-shared/components/upload/upload.component.html +++ b/packages/frontend/src/app/modules/usager-shared/components/upload/upload.component.html @@ -14,6 +14,7 @@ class="form-control" formControlName="label" name="label" + appCleanStr id="label" [ngClass]="{ 'is-invalid': submitted && u.label.errors }" [attr.aria-describedby]=" diff --git a/packages/frontend/src/assets/css/main.scss b/packages/frontend/src/assets/css/main.scss index 4fe9783a5c..772b660c89 100644 --- a/packages/frontend/src/assets/css/main.scss +++ b/packages/frontend/src/assets/css/main.scss @@ -337,28 +337,6 @@ legend { color: black; } -.doc-icon { - padding: 0.4rem 1.2rem; - font-size: 2rem; - text-align: center; - border-radius: 6px; - display: inline-block; - background-color: #ecefff; -} - -.file-image { - color: #782f08; -} -.file-pdf { - color: #fe3b31; -} -.file-word { - color: #017aff; -} -.file-excel { - color: #33c75a; -} - .upload-table td { vertical-align: middle; border-bottom: 1px solid #eceffe;