diff --git a/alfa-client/libs/binary-file/src/index.ts b/alfa-client/libs/binary-file/src/index.ts index dcb64fe7734d612f4b32126aa10986e96c30480c..a6fbc2a2e6dfbc8f384dd0cec73eb941c555a7b8 100644 --- a/alfa-client/libs/binary-file/src/index.ts +++ b/alfa-client/libs/binary-file/src/index.ts @@ -24,5 +24,6 @@ export * from './lib/binary-file-attachment-container/binary-file-attachment-container.component'; export * from './lib/binary-file-container/binary-file-container.component'; export * from './lib/binary-file.module'; +export * from './lib/binary-file2-container/binary-file2-container.component'; export * from './lib/horizontal-binary-file-list/horizontal-binary-file-list.component'; export * from './lib/vertical-binary-file-list/vertical-binary-file-list.component'; diff --git a/alfa-client/libs/binary-file/src/lib/binary-file.module.ts b/alfa-client/libs/binary-file/src/lib/binary-file.module.ts index b71b9994e43c405867bafdc5a0f597ffcb605bfa..267a83df8e1b1d3361e5a286d382e4c7c058cbeb 100644 --- a/alfa-client/libs/binary-file/src/lib/binary-file.module.ts +++ b/alfa-client/libs/binary-file/src/lib/binary-file.module.ts @@ -21,30 +21,43 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; import { TechSharedModule } from '@alfa-client/tech-shared'; import { UiModule } from '@alfa-client/ui'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { AttachmentComponent, IconComponent, SpinnerIconComponent } from 'design-system'; import { BinaryFileAttachmentContainerComponent } from './binary-file-attachment-container/binary-file-attachment-container.component'; import { BinaryFileContainerComponent } from './binary-file-container/binary-file-container.component'; import { BinaryFileComponent } from './binary-file-container/binary-file/binary-file.component'; +import { BinaryFile2ContainerComponent } from './binary-file2-container/binary-file2-container.component'; +import { BinaryFile2Component } from './binary-file2-container/binary-file2/binary-file2.component'; import { HorizontalBinaryFileListComponent } from './horizontal-binary-file-list/horizontal-binary-file-list.component'; import { VerticalBinaryFileListComponent } from './vertical-binary-file-list/vertical-binary-file-list.component'; @NgModule({ - imports: [CommonModule, UiModule, TechSharedModule], + imports: [ + CommonModule, + UiModule, + TechSharedModule, + AttachmentComponent, + IconComponent, + SpinnerIconComponent, + ], declarations: [ BinaryFileAttachmentContainerComponent, BinaryFileComponent, BinaryFileContainerComponent, HorizontalBinaryFileListComponent, VerticalBinaryFileListComponent, + BinaryFile2ContainerComponent, + BinaryFile2Component, ], exports: [ BinaryFileAttachmentContainerComponent, BinaryFileContainerComponent, HorizontalBinaryFileListComponent, VerticalBinaryFileListComponent, + BinaryFile2ContainerComponent, ], }) export class BinaryFileModule {} diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.html b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..41fe9ab51a28ec7cc893e0dfd418cbffb86075c5 --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.html @@ -0,0 +1,11 @@ +<alfa-binary-file2 + [attr.data-test-id]="(file.name | convertForDataTest) + '-file-item'" + [file]="file" + [stateResource]="fileStateResource$ | async" + [deletable]="deletable" + [downloadToken]="downloadToken$ | async" + (startDownload)="startDownload($event)" + (startDelete)="startDelete.emit($event)" + (getDownloadToken)="getDownloadToken()" +> +</alfa-binary-file2> diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.spec.ts b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c75349608e0fa24b766e9eba7e9fdf72e9e2bdae --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BinaryFile2ContainerComponent } from './binary-file2-container.component'; + +describe('BinaryFile2ContainerComponent', () => { + let component: BinaryFile2ContainerComponent; + let fixture: ComponentFixture<BinaryFile2ContainerComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [BinaryFile2ContainerComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(BinaryFile2ContainerComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.ts b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..90a10b6ffba33d101eb05f4599eded38984f954d --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2-container.component.ts @@ -0,0 +1,37 @@ +import { ApiDownloadToken, ApiRootService } from '@alfa-client/api-root-shared'; +import { BinaryFileResource, BinaryFileService } from '@alfa-client/binary-file-shared'; +import { StateResource } from '@alfa-client/tech-shared'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'alfa-binary-file2-container', + templateUrl: './binary-file2-container.component.html', + //styles: [':host {@apply flex flex-grow}'], +}) +export class BinaryFile2ContainerComponent { + @Input() file: BinaryFileResource; + @Input() downloadFileNamePrefix: string; + @Input() deletable: boolean = false; + + @Output() startDelete: EventEmitter<BinaryFileResource> = new EventEmitter(); + + fileStateResource$: Observable<StateResource<any>>; + downloadToken$: Observable<ApiDownloadToken>; + + constructor( + private binaryFileService: BinaryFileService, + private apiRootService: ApiRootService, + ) {} + + startDownload(file: BinaryFileResource): void { + this.fileStateResource$ = this.binaryFileService.downloadFile( + file, + this.downloadFileNamePrefix, + ); + } + + getDownloadToken(): void { + this.downloadToken$ = this.apiRootService.getDownloadToken(this.file); + } +} diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.html b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.html new file mode 100644 index 0000000000000000000000000000000000000000..2f1b7d16ba4daa2cbb3d10053baef53917c7764b --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.html @@ -0,0 +1,19 @@ +<ods-attachment + [documentName]="file.name" + [description]="file.size | fileSizePlain" + (click)="downloadFile()" + [attr.aria-label]="'Anhang: Dateiname: ' + file.name" +> + <ods-spinner-icon spinner *ngIf="false" class="mr-3 size-10" /> + <ods-icon icon name="file-pdf" class="mr-3 size-10 fill-primary"></ods-icon> + <button + close + *ngIf="deletable" + class="absolute right-2 top-1/2 flex size-10 -translate-y-1/2 items-center justify-center rounded-md hover:border hover:border-ozggray-600 hover:bg-ozggray-100" + (click)="deleteFile()" + title="Anhang löschen" + aria-label="Anhang löschen Button" + > + <ods-icon name="close" size="14" fillColor="black" class="ml-3 w-6"></ods-icon> + </button> +</ods-attachment> diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.spec.ts b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..173419d3940363b7f578fa58347a80cdfe3b9af7 --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BinaryFile2Component } from './binary-file2.component'; + +describe('BinaryFile2Component', () => { + let component: BinaryFile2Component; + let fixture: ComponentFixture<BinaryFile2Component>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [BinaryFile2Component], + }).compileComponents(); + + fixture = TestBed.createComponent(BinaryFile2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.ts b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..116b9a6cbce09dd602e461a39a3e238d9e8d6e0d --- /dev/null +++ b/alfa-client/libs/binary-file/src/lib/binary-file2-container/binary-file2/binary-file2.component.ts @@ -0,0 +1,81 @@ +import { ApiDownloadToken } from '@alfa-client/api-root-shared'; +import { BinaryFileLinkRel, BinaryFileResource } from '@alfa-client/binary-file-shared'; +import { StateResource, createEmptyStateResource } from '@alfa-client/tech-shared'; +import { HttpParams } from '@angular/common/http'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { Resource, getUrl } from '@ngxp/rest'; +import { isEmpty, isNil } from 'lodash-es'; + +@Component({ + selector: 'alfa-binary-file2', + templateUrl: './binary-file2.component.html', + styles: [':host {@apply flex flex-grow}'], +}) +export class BinaryFile2Component { + @Input() file: BinaryFileResource; + @Input() stateResource: StateResource<Resource>; + @Input() deletable: boolean = false; + @Input() downloadToken: ApiDownloadToken = <ApiDownloadToken>{}; + + readonly fileLinkRel = BinaryFileLinkRel; + + @Output() public startDownload: EventEmitter<BinaryFileResource> = + new EventEmitter<BinaryFileResource>(); + @Output() public startDelete: EventEmitter<BinaryFileResource> = + new EventEmitter<BinaryFileResource>(); + @Output() public getDownloadToken: EventEmitter<void> = new EventEmitter<void>(); + + get isDisabled(): boolean { + return this.getStateResource().loading; + } + + getStateResource(): StateResource<Resource> { + return isNil(this.stateResource) ? createEmptyStateResource<Resource>() : this.stateResource; + } + + downloadFile(): void { + this.startDownload.emit(this.file); + } + + deleteFile(): void { + this.startDelete.emit(this.file); + } + + getNewDownloadToken(): void { + this.getDownloadToken.emit(); + } + + dragStart(event: DragEvent): void { + event.dataTransfer.setData('DownloadURL', this.createDownloadUrl()); + } + + dragEnd(event: DragEvent): void { + if (this.isValidDrop(event)) { + this.handleSpinnerForDragEnd(); + } + } + + private isValidDrop(event: DragEvent): boolean { + return event.dataTransfer.dropEffect !== 'none'; + } + + handleSpinnerForDragEnd(): void { + this.stateResource = { ...this.stateResource, loading: true }; + setTimeout(() => (this.stateResource = { ...this.stateResource, loading: false }), 3000); + } + + createDownloadUrl(): string { + return `${this.getContentType()}:${this.file.name}:${this.createRemoteUrl()}`; + } + + private getContentType(): string { + return isEmpty(this.file.contentType) ? 'application/octet-stream' : this.file.contentType; + } + + private createRemoteUrl(): string { + let getParam = new HttpParams(); + getParam = getParam.set('token', this.downloadToken?.token); + + return getUrl(this.file, BinaryFileLinkRel.DOWNLOAD) + '?' + getParam.toString(); + } +} diff --git a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.html b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.html index bc1c01088f2da95974a88f931928da56294c76c4..686ca85b4f8f8e241904ffff97474e647ac4dec7 100644 --- a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.html +++ b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.html @@ -1,8 +1,11 @@ -<div class="flex w-full items-center bg-ozggray px-3 py-2 hover:bg-ozggray-200"> - <ng-content select="[before-content]"></ng-content> - <div class="flex w-full flex-col"> +<button + class="relative flex flex-grow items-center rounded-md border border-black/25 bg-background-100 px-3 pb-3 pt-2 hover:bg-ozggray-200" +> + <ng-content select="[spinner]"></ng-content> + <ng-content select="[icon]"></ng-content> + <div class="flex w-full flex-col items-start"> <p class="text-sm">{{ documentName }}</p> <p class="text-xs text-ozggray-600">{{ description }}</p> </div> - <ng-content select="[after-content]"></ng-content> -</div> + <ng-content select="[close]"></ng-content> +</button> diff --git a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts index d2bfad564d88222988066efa63e1c7b9747197df..054d74f5b3a5c0c1e0410bc039bf59b6d4571103 100644 --- a/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts +++ b/alfa-client/libs/design-system/src/lib/attachment/attachment.component.ts @@ -1,10 +1,11 @@ -import { Component, Input } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { Component, Input } from '@angular/core'; @Component({ selector: 'ods-attachment', standalone: true, imports: [CommonModule], + styles: [':host {@apply flex flex-grow}'], templateUrl: './attachment.component.html', }) export class AttachmentComponent { diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html index 94a2aa1cdf2372b1c2689bc713c99c0da79439ad..c8aef82deb0bc01ab84d9d0db6fd198700f372eb 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-attachments/vorgang-detail-bescheiden-result-attachments.component.html @@ -1,21 +1,21 @@ -<alfa-binary-file-container +<alfa-binary-file2-container *ngFor="let attachment of existingAttachments" [file]="attachment" [deletable]="true" (startDelete)="deleteFile($event)" > -</alfa-binary-file-container> +</alfa-binary-file2-container> <ng-container *ngFor="let attachment of uploadedAttachments"> <alfa-vorgang-detail-bescheiden-form-error *ngIf="attachment.error" [error]="attachment.error" ></alfa-vorgang-detail-bescheiden-form-error> <p *ngIf="attachment.loading">loading...</p> - <alfa-binary-file-container + <alfa-binary-file2-container *ngIf="!attachment.error && attachment.loaded" [file]="attachment.resource" [deletable]="true" (startDelete)="deleteFile($event)" > - </alfa-binary-file-container> + </alfa-binary-file2-container> </ng-container> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html index c0295225f608228064ed11653ff81fde92d73ff2..49f56be6006b8f159f8d7ac9f0824e1ed31b9daa 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-bescheiden/vorgang-detail-bescheiden-result/vorgang-detail-bescheiden-result-dokument/vorgang-detail-bescheiden-result-dokument.component.html @@ -3,13 +3,13 @@ @Output() delete: EventEmitter<BinaryFileResource> --> <ng-container *ngIf="bescheidDocumentFile.resource"> - <alfa-binary-file-container + <alfa-binary-file2-container *ngIf="!bescheidDocumentFile.loading" [file]="bescheidDocumentFile.resource" [deletable]="true" (startDelete)="deleteFile.emit()" > - </alfa-binary-file-container> + </alfa-binary-file2-container> </ng-container> <ng-container *ngIf="bescheidDocumentFile.loading"> <span *ngIf="bescheidDocumentFile.resource">{{ bescheidDocumentFile.resource.name }}</span> diff --git a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts index 6399101f06cb540b56b21406bdb73ad25a8189c2..e766aa38002e0187f7f03fda8841d6fc603dda4e 100644 --- a/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts +++ b/alfa-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts @@ -41,6 +41,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { + AttachmentComponent, BescheidGenerateIconComponent, BescheidUploadIconComponent, ButtonComponent, @@ -133,6 +134,7 @@ const routes: Routes = [ SpinnerIconComponent, BescheidUploadIconComponent, BescheidGenerateIconComponent, + AttachmentComponent, ], declarations: [ VorgangDetailPageComponent, diff --git a/alfa-client/tsconfig.base.json b/alfa-client/tsconfig.base.json index c891e16fc00429d78d6874102e71c4c3196e606c..1f7364bba7606a74a3d102427b82bb77ac3049cb 100644 --- a/alfa-client/tsconfig.base.json +++ b/alfa-client/tsconfig.base.json @@ -54,8 +54,7 @@ "@alfa-client/wiedervorlage": ["libs/wiedervorlage/src/index.ts"], "@alfa-client/wiedervorlage-shared": ["libs/wiedervorlage-shared/src/index.ts"], "authentication": ["libs/authentication/src/index.ts"], - "design-system": ["libs/design-system/src/index.ts"], - "design-ui": ["libs/design-ui/src/index.ts"] + "design-system": ["libs/design-system/src/index.ts"] } }, "exclude": ["node_modules", "tmp"]