diff --git a/CHANGELOG.md b/CHANGELOG.md index 62a8ace58..4cae16cac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Extended the tags selector component by a `readonly` attribute - Added global styles to the _Storybook_ setup ## 2.138.0 - 2025-02-08 diff --git a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html index a20c9af7a..d820ddf7d 100644 --- a/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html +++ b/apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.html @@ -366,33 +366,12 @@ </mat-tab> </mat-tab-group> - <div - class="row" - [ngClass]="{ - 'd-none': !data.hasPermissionToUpdateOrder - }" - > - <div class="col"> - <gf-tags-selector - [tags]="activityForm.get('tags')?.value" - [tagsAvailable]="tagsAvailable" - (tagsChanged)="onTagsChanged($event)" - /> - </div> - </div> - - @if (!data.hasPermissionToUpdateOrder && tagsAvailable?.length > 0) { - <div class="row"> - <div class="col"> - <div class="h5" i18n>Tags</div> - <mat-chip-listbox> - @for (tag of tags; track tag) { - <mat-chip-option disabled>{{ tag.name }}</mat-chip-option> - } - </mat-chip-listbox> - </div> - </div> - } + <gf-tags-selector + [readonly]="!data.hasPermissionToUpdateOrder" + [tags]="activityForm.get('tags')?.value" + [tagsAvailable]="tagsAvailable" + (tagsChanged)="onTagsChanged($event)" + /> @if ( dataSource?.data.length > 0 && diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.html b/libs/ui/src/lib/tags-selector/tags-selector.component.html index 55f8a39f2..1b6817724 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.html +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.html @@ -1,32 +1,49 @@ -<mat-form-field appearance="outline" class="w-100 without-hint"> - <mat-label i18n>Tags</mat-label> - <mat-chip-grid #tagsChipList> - @for (tag of tagsSelected(); track tag.id) { - <mat-chip-row - matChipRemove - [removable]="true" - (removed)="onRemoveTag(tag)" - > - {{ tag.name }} - <ion-icon matChipTrailingIcon name="close-outline" /> - </mat-chip-row> +<div class="row"> + <div class="col"> + @if (readonly) { + <div class="h5" i18n>Tags</div> + @if (tags?.length > 0) { + <mat-chip-listbox> + @for (tag of tags; track tag) { + <mat-chip-option disabled>{{ tag.name }}</mat-chip-option> + } + </mat-chip-listbox> + } @else { + <div>-</div> + } + } @else { + <mat-form-field appearance="outline" class="w-100 without-hint"> + <mat-label i18n>Tags</mat-label> + <mat-chip-grid #tagsChipList> + @for (tag of tagsSelected(); track tag.id) { + <mat-chip-row + matChipRemove + [removable]="true" + (removed)="onRemoveTag(tag)" + > + {{ tag.name }} + <ion-icon matChipTrailingIcon name="close-outline" /> + </mat-chip-row> + } + <input + #tagInput + [formControl]="tagInputControl" + [matAutocomplete]="autocompleteTags" + [matChipInputFor]="tagsChipList" + [matChipInputSeparatorKeyCodes]="separatorKeysCodes" + /> + </mat-chip-grid> + <mat-autocomplete + #autocompleteTags="matAutocomplete" + (optionSelected)="onAddTag($event)" + > + @for (tag of filteredOptions | async; track tag.id) { + <mat-option [value]="tag.id"> + {{ tag.name }} + </mat-option> + } + </mat-autocomplete> + </mat-form-field> } - <input - #tagInput - [formControl]="tagInputControl" - [matAutocomplete]="autocompleteTags" - [matChipInputFor]="tagsChipList" - [matChipInputSeparatorKeyCodes]="separatorKeysCodes" - /> - </mat-chip-grid> - <mat-autocomplete - #autocompleteTags="matAutocomplete" - (optionSelected)="onAddTag($event)" - > - @for (tag of filteredOptions | async; track tag.id) { - <mat-option [value]="tag.id"> - {{ tag.name }} - </mat-option> - } - </mat-autocomplete> -</mat-form-field> + </div> +</div> diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts index c1adf1286..4fd0f7e77 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.stories.ts @@ -47,6 +47,25 @@ export const Default: Story = { } }; +export const Readonly: Story = { + args: { + readonly: true, + tags: [ + { + id: 'EMERGENCY_FUND', + name: 'Emergency Fund', + userId: null + }, + { + id: 'RETIREMENT_FUND', + name: 'Retirement Fund', + userId: null + } + ], + tagsAvailable: OPTIONS + } +}; + export const WithoutValue: Story = { args: { tags: [], diff --git a/libs/ui/src/lib/tags-selector/tags-selector.component.ts b/libs/ui/src/lib/tags-selector/tags-selector.component.ts index 77c776ece..6b59d53f4 100644 --- a/libs/ui/src/lib/tags-selector/tags-selector.component.ts +++ b/libs/ui/src/lib/tags-selector/tags-selector.component.ts @@ -42,6 +42,7 @@ import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; templateUrl: 'tags-selector.component.html' }) export class GfTagsSelectorComponent implements OnInit, OnChanges, OnDestroy { + @Input() readonly = false; @Input() tags: Tag[]; @Input() tagsAvailable: Tag[];