diff --git a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html index edd8aff832236fb11a9b372a47c40f4bbb8d06d3..007a02ec854d9001c4eaef88f688760d6db3fa8d 100644 --- a/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html +++ b/alfa-client/libs/bescheid/src/lib/bescheid-wizard-container/bescheid-wizard/dokumente-hochladen-container/form/bescheid-wizard-dokumente-hochladen-form.component.html @@ -23,7 +23,7 @@ unter der Lizenz sind dem Lizenztext zu entnehmen. --> -<div class="mt-4 flex flex-col gap-4"> +<div class="mt-4 flex max-w-72 flex-col gap-4"> @if (bescheidResource | hasLink: BescheidLinkRel.CREATE_DOCUMENT) { <alfa-bescheid-wizard-create-document-button-container [bescheidResource]="bescheidResource" diff --git a/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts b/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts index 3a1a42958aca047046c5aa29edaed15dc77a1705..956be5722cdcd4966e12c8a5216bfb0dde53d706 100644 --- a/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts +++ b/alfa-client/libs/binary-file/src/lib/directive/binary-file-list-orientation/binary-file-list-orientation.directive.ts @@ -1,7 +1,7 @@ import { Directive, ElementRef, Input } from '@angular/core'; export const _verticalClasses: string[] = ['flex', 'flex-col']; -export const _horizontalClasses: string[] = ['flex', 'flex-row', 'flex-wrap']; +export const _horizontalClasses: string[] = ['flex', 'flex-wrap', 'gap-2']; export enum BinaryFileListOrientation { HORIZONTAL = 'horizontal', diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html index 1bfa1fb53740999476b2e6b342777abec551f000..4024dc2de95e58d010447f113834a2b1b0387252 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.html @@ -4,10 +4,12 @@ [attr.data-test-id]="(label | convertForDataTest) + '-file-upload-button'" [multi]="true" [isLoading]="isUploadInProgress$ | async" - class="relative w-72" + [variant]="uploadButtonVariant" data-test-id="binary-file-upload" > <ods-spinner-icon spinner size="medium" /> <ods-attachment-icon icon size="medium" /> - <p text class="text-center">{{ label }}</p> + @if (label) { + <p text data-test-id="upload-button-label" class="text-center">{{ label }}</p> + } </ods-file-upload-button> diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts index dc42e69a0f52518ba01f5f3ddf2009ef04e344e9..38303a464c9f128eb05963f94df756663567e129 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.spec.ts @@ -1,11 +1,17 @@ import { BinaryFileService, FileUploadType, ToUploadFile } from '@alfa-client/binary-file-shared'; import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; -import { existsAsHtmlElement, getElementComponentFromFixtureByCss, mock, Mock } from '@alfa-client/test-utils'; +import { + existsAsHtmlElement, + getElementComponentFromFixtureByCss, + mock, + Mock, + notExistsAsHtmlElement, +} from '@alfa-client/test-utils'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { faker } from '@faker-js/faker/.'; import { expect } from '@jest/globals'; import { getUrl, Resource } from '@ngxp/rest'; -import { FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { FileUploadButtonComponent, SpinnerIconComponent, UploadButtonVariants } from '@ods/system'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { MockComponent } from 'ng-mocks'; import { of } from 'rxjs'; @@ -23,6 +29,7 @@ describe('MultiFileUploadEditorComponent', () => { const uploadResource: Resource = createDummyResource([uploadLinkRel]); const buttonTestId: string = getDataTestIdOf('Ein_Label-file-upload-button'); + const buttonLabelTestId: string = getDataTestIdOf('upload-button-label'); let binaryFileService: Mock<BinaryFileService>; @@ -104,6 +111,24 @@ describe('MultiFileUploadEditorComponent', () => { } as ToUploadFile); }); }); + + describe('get uploadButtonVariant', () => { + it('should return "label"', () => { + component.label = 'test'; + + const result: UploadButtonVariants['variant'] = component.uploadButtonVariant; + + expect(result).toBe('label'); + }); + + it('should return "icon"', () => { + component.label = ''; + + const result: UploadButtonVariants['variant'] = component.uploadButtonVariant; + + expect(result).toBe('icon'); + }); + }); }); describe('template', () => { @@ -125,5 +150,22 @@ describe('MultiFileUploadEditorComponent', () => { expect(fileButtonComponent.isLoading).toEqual(true); }); }); + describe('upload button label', () => { + it('should show', () => { + component.label = 'test'; + + fixture.detectChanges(); + + existsAsHtmlElement(fixture, buttonLabelTestId); + }); + + it('should hide', () => { + component.label = ''; + + fixture.detectChanges(); + + notExistsAsHtmlElement(fixture, buttonLabelTestId); + }); + }); }); }); diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts index 4c057b3f3d7b52b25dc63164e62f06bb054b83c8..2a9623612015f5350b39822c605c8faed1903d59 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload-editor/multi-file-upload-editor.component.ts @@ -5,7 +5,7 @@ import { AsyncPipe } from '@angular/common'; import { Component, HostListener, inject, Input, OnInit } from '@angular/core'; import { ControlContainer, FormGroupDirective, ReactiveFormsModule } from '@angular/forms'; import { getUrl, Resource } from '@ngxp/rest'; -import { AttachmentIconComponent, FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { AttachmentIconComponent, FileUploadButtonComponent, SpinnerIconComponent, UploadButtonVariants } from '@ods/system'; import { uniqueId } from 'lodash-es'; import { Observable } from 'rxjs'; @@ -55,4 +55,8 @@ export class MultiFileUploadEditorComponent implements OnInit { }); } } + + get uploadButtonVariant(): UploadButtonVariants['variant'] { + return this.label ? 'label' : 'icon'; + } } diff --git a/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html b/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html index 184ac868f9f594da443f6f89b969ce1cc85b1dfc..8efd002c007d46dba8fc79c2526e59e132191c66 100644 --- a/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html +++ b/alfa-client/libs/binary-file/src/lib/multi-file-upload/multi-file-upload.component.html @@ -1,13 +1,15 @@ -<ods-file-upload-list-container - [parentFormArrayName]="filesFormFieldName" - [fileUploadType]="fileUploadType" - [filesResource]="filesResource" - [filesLinkRel]="filesLinkRelation" - data-test-id="file-list" -></ods-file-upload-list-container> -<ods-multi-file-upload-editor - [fileUploadType]="fileUploadType" - [uploadResource]="uploadResource" - [uploadLinkRelation]="uploadLinkRelation" - data-test-id="multi-file-upload-editor" -></ods-multi-file-upload-editor> \ No newline at end of file +<div class="flex flex-col gap-2"> + <ods-file-upload-list-container + [parentFormArrayName]="filesFormFieldName" + [fileUploadType]="fileUploadType" + [filesResource]="filesResource" + [filesLinkRel]="filesLinkRelation" + data-test-id="file-list" + /> + <ods-multi-file-upload-editor + [fileUploadType]="fileUploadType" + [uploadResource]="uploadResource" + [uploadLinkRelation]="uploadLinkRelation" + data-test-id="multi-file-upload-editor" + /> +</div> diff --git a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts index a62e384fb3c9ff9c15b453cc9927438d1e1790c4..7de4a0bf3fc04340fa80daed1896235559f6dd18 100644 --- a/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts +++ b/alfa-client/libs/design-component/src/lib/form/single-file-upload-editor/single-file-upload-editor.component.ts @@ -24,7 +24,7 @@ import { ConvertForDataTestPipe, isNotNil } from '@alfa-client/tech-shared'; import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; -import { FileUploadButtonComponent, SpinnerIconComponent } from '@ods/system'; +import { FileUploadButtonComponent } from '@ods/system'; import { uniqueId } from 'lodash-es'; import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstract.component'; @@ -32,7 +32,8 @@ import { FormControlEditorAbstractComponent } from '../formcontrol-editor.abstra selector: 'ods-single-file-upload-editor', templateUrl: './single-file-upload-editor.component.html', standalone: true, - imports: [FileUploadButtonComponent, SpinnerIconComponent, ReactiveFormsModule, ConvertForDataTestPipe], + styles: [':host {@apply contents}'], + imports: [FileUploadButtonComponent, ReactiveFormsModule, ConvertForDataTestPipe], }) export class SingleFileUploadEditorComponent extends FormControlEditorAbstractComponent { @Input() label: string = ''; diff --git a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html index dc2b6cef68ea7358023c7791fea0eb6efbaf47bf..b65b88d5b02c74982b872549c6d87aeccdf1644b 100644 --- a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html +++ b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.html @@ -34,14 +34,13 @@ [multiple]="multi" [attr.data-test-id]="(id | convertForDataTest) + '-file-upload-input'" /> -<label - [for]="id" - class="z-10 inline-flex w-full flex-grow items-center justify-start gap-4 break-words rounded-md bg-background-50 py-3 pl-6 pr-6 text-text hover:bg-background-100 focus:outline-none focus:ring-2 focus:ring-primary peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ozgblue-800 peer-disabled:cursor-wait peer-disabled:hover:bg-background-50" - role="button" -> - <ng-content *ngIf="!isLoading" select="[icon]"></ng-content> - <ng-content *ngIf="isLoading" select="[spinner]"></ng-content> - <div class="flex-grow"> +<label [for]="id" [ngClass]="uploadButtonVariants({ variant })" role="button"> + @if (isLoading) { + <ng-content select="[spinner]"></ng-content> + } @else { + <ng-content select="[icon]"></ng-content> + } + <div class="flex-grow empty:hidden"> <ng-content select="[text]"></ng-content> </div> </label> diff --git a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts index 2371918f9cdba62e0ea0ee3a5e315ee9f1d9e378..b5048be11b1b7e67eaf8c077e3d4cd0caab66388 100644 --- a/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts +++ b/alfa-client/libs/design-system/src/lib/form/file-upload-button/file-upload-button.component.ts @@ -24,12 +24,33 @@ import { ConvertForDataTestPipe } from '@alfa-client/tech-shared'; import { CommonModule } from '@angular/common'; import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { cva, VariantProps } from 'class-variance-authority'; + +export const uploadButtonVariants = cva( + [ + 'z-10 inline-flex flex-grow items-center justify-start gap-4 break-words rounded-md text-primary', + 'border border-transparent hover:bg-ghost-hover peer-focus-visible:border-background-200', + 'peer-focus-visible:outline peer-focus-visible:outline-focus peer-focus-visible:bg-ghost-hover peer-focus-visible:outline-offset-1', + ], + { + variants: { + variant: { + label: 'py-3 px-6 bg-background-50 w-full', + icon: 'p-2 w-fit', + }, + }, + defaultVariants: { + variant: 'label', + }, + }, +); +export type UploadButtonVariants = VariantProps<typeof uploadButtonVariants>; @Component({ selector: 'ods-file-upload-button', standalone: true, imports: [CommonModule, ConvertForDataTestPipe], - styles: [':host {@apply inline-flex}'], + styles: [':host {@apply relative}'], templateUrl: './file-upload-button.component.html', }) export class FileUploadButtonComponent { @@ -37,9 +58,12 @@ export class FileUploadButtonComponent { @Input() isLoading: boolean = false; @Input() accept: string = '*/*'; @Input() multi: boolean = false; + @Input() variant: UploadButtonVariants['variant']; @ViewChild('inputElement') inputElement: ElementRef = new ElementRef({}); + readonly uploadButtonVariants = uploadButtonVariants; + resetInput(): void { this.inputElement.nativeElement.value = ''; }