mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ADF-4559] Add chips to multivalue metadata properties (#5552)
* [ADF-4559] Add chips to multivalue metadata properties * Fix app config schema * Restore app config * Fix checkListIsSorted method * Fix e2e datatable sorting * Fix e2e tests * Improve chips input
This commit is contained in:
parent
666dd45fa2
commit
144da83d0e
@ -820,7 +820,8 @@
|
|||||||
"exif:exif": "*"
|
"exif:exif": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"multi-value-pipe-separator": ", "
|
"multi-value-pipe-separator": ", ",
|
||||||
|
"multi-value-chips": true
|
||||||
},
|
},
|
||||||
"sideNav": {
|
"sideNav": {
|
||||||
"expandedSidenav": true,
|
"expandedSidenav": true,
|
||||||
|
@ -347,6 +347,13 @@ To customize the separator used by this card you can set it in your `app.config.
|
|||||||
"exif:exif": [ "exif:pixelXDimension", "exif:pixelYDimension"]
|
"exif:exif": [ "exif:pixelXDimension", "exif:pixelYDimension"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"multi-value-pipe-separator" : " - "
|
"multi-value-pipe-separator" : " - ",
|
||||||
|
"multi-value-chips" : false
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Use chips for multi value properties
|
||||||
|
|
||||||
|
If you want to display chips fo each value instead of a composed string you just need to enable it in the content-metadata config.
|
||||||
|
|
||||||
|

|
||||||
|
BIN
docs/docassets/images/metadata-chips.png
Normal file
BIN
docs/docassets/images/metadata-chips.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -204,10 +204,10 @@ describe('Edit task filters and task list properties', () => {
|
|||||||
await tasksCloudDemoPage.editTaskFilterCloudComponent().setSortFilterDropDown('Priority');
|
await tasksCloudDemoPage.editTaskFilterCloudComponent().setSortFilterDropDown('Priority');
|
||||||
await tasksCloudDemoPage.editTaskFilterCloudComponent().setOrderFilterDropDown('ASC');
|
await tasksCloudDemoPage.editTaskFilterCloudComponent().setOrderFilterDropDown('ASC');
|
||||||
|
|
||||||
await expect(await tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkListIsSorted('ASC', 'Priority')).toBe(true);
|
await expect(await tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkListIsSorted('ASC', 'Priority', 'NUMBER')).toBe(true);
|
||||||
|
|
||||||
await tasksCloudDemoPage.editTaskFilterCloudComponent().setOrderFilterDropDown('DESC');
|
await tasksCloudDemoPage.editTaskFilterCloudComponent().setOrderFilterDropDown('DESC');
|
||||||
await expect(await tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkListIsSorted('DESC', 'Priority')).toBe(true);
|
await expect(await tasksCloudDemoPage.taskListCloudComponent().getDataTable().checkListIsSorted('DESC', 'Priority', 'NUMBER')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('[C307115] Should display tasks sorted by owner when owner is selected from sort dropdown', async () => {
|
it('[C307115] Should display tasks sorted by owner when owner is selected from sort dropdown', async () => {
|
||||||
|
@ -899,26 +899,6 @@
|
|||||||
"pattern": "^\\*$",
|
"pattern": "^\\*$",
|
||||||
"description": "Wildcard for every aspect"
|
"description": "Wildcard for every aspect"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"description": "",
|
|
||||||
"required": [
|
|
||||||
"includeAll"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"includeAll": {
|
|
||||||
"description": "includeAll all property",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"postfix": {
|
|
||||||
"description": "exclude",
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"array"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/content-metadata-aspect"
|
"$ref": "#/definitions/content-metadata-aspect"
|
||||||
},
|
},
|
||||||
@ -932,6 +912,10 @@
|
|||||||
"multi-value-pipe-separator": {
|
"multi-value-pipe-separator": {
|
||||||
"description": "Content metadata's separator for multi value properties",
|
"description": "Content metadata's separator for multi value properties",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"multi-value-chips": {
|
||||||
|
"description": "Use chips for multi value properties",
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,95 +1,142 @@
|
|||||||
<div [attr.data-automation-id]="'card-textitem-label-' + property.key" class="adf-property-label" *ngIf="showProperty() || isEditable()">{{ property.label | translate }}</div>
|
<div [attr.data-automation-id]="'card-textitem-label-' + property.key"
|
||||||
|
class="adf-property-label"
|
||||||
|
*ngIf="showProperty() || isEditable()">{{ property.label | translate }}</div>
|
||||||
<div class="adf-property-value">
|
<div class="adf-property-value">
|
||||||
<span *ngIf="!isEditable()">
|
<span *ngIf="!isEditable()">
|
||||||
<span *ngIf="!isClickable(); else elseBlock" [attr.data-automation-id]="'card-textitem-value-' + property.key">
|
<span *ngIf="!isClickable(); else nonClickableTemplate"
|
||||||
<span *ngIf="showProperty()"
|
[attr.data-automation-id]="'card-textitem-value-' + property.key">
|
||||||
[ngClass]="property.multiline?'adf-textitem-multiline':'adf-textitem-scroll'">
|
<span *ngIf="!isChipViewEnabled; else chipListTemplate">
|
||||||
{{ property.displayValue }}</span>
|
<span *ngIf="showProperty()"
|
||||||
</span>
|
[ngClass]="property.multiline?'adf-textitem-multiline':'adf-textitem-scroll'">
|
||||||
<ng-template #elseBlock>
|
{{ property.displayValue }}
|
||||||
<div role="button" class="adf-textitem-clickable" [attr.data-automation-id]="'card-textitem-toggle-' + property.key" (click)="clicked()" fxLayout="row" fxLayoutAlign="space-between center">
|
|
||||||
<span class="adf-textitem-clickable-value" [attr.data-automation-id]="'card-textitem-value-' + property.key">
|
|
||||||
<span *ngIf="showProperty(); else elseEmptyValueBlock">{{ property.displayValue }}</span>
|
|
||||||
</span>
|
</span>
|
||||||
<button mat-icon-button fxFlex="0 0 auto" *ngIf="showClickableIcon()"
|
</span>
|
||||||
class="adf-textitem-action"
|
</span>
|
||||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
<ng-template #nonClickableTemplate>
|
||||||
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
<div role="button"
|
||||||
[attr.data-automation-id]="'card-textitem-clickable-icon-' + property.key">
|
class="adf-textitem-clickable"
|
||||||
|
[attr.data-automation-id]="'card-textitem-toggle-' + property.key"
|
||||||
|
(click)="clicked()"
|
||||||
|
fxLayout="row"
|
||||||
|
fxLayoutAlign="space-between center">
|
||||||
|
<span class="adf-textitem-clickable-value"
|
||||||
|
[attr.data-automation-id]="'card-textitem-value-' + property.key">
|
||||||
|
<span *ngIf="showProperty(); else emptyValueTemplate">{{ property.displayValue }}</span>
|
||||||
|
</span>
|
||||||
|
<button mat-icon-button
|
||||||
|
fxFlex="0 0 auto"
|
||||||
|
*ngIf="showClickableIcon()"
|
||||||
|
class="adf-textitem-action"
|
||||||
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
|
[attr.data-automation-id]="'card-textitem-clickable-icon-' + property.key">
|
||||||
<mat-icon class="adf-textitem-icon">{{property?.icon}}</mat-icon>
|
<mat-icon class="adf-textitem-icon">{{property?.icon}}</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</span>
|
</span>
|
||||||
<span *ngIf="isEditable()">
|
<span *ngIf="isEditable()">
|
||||||
<div *ngIf="!inEdit" role="button"
|
<div *ngIf="!inEdit"
|
||||||
tabindex="0"
|
role="button"
|
||||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
tabindex="0"
|
||||||
(click)="setEditMode(true)"
|
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
(keydown.enter)="setEditMode(true)"
|
(click)="setEditMode(true)"
|
||||||
class="adf-textitem-readonly"
|
(keydown.enter)="setEditMode(true)"
|
||||||
[attr.data-automation-id]="'card-textitem-toggle-' + property.key"
|
class="adf-textitem-readonly"
|
||||||
fxLayout="row" fxLayoutAlign="space-between center">
|
[attr.data-automation-id]="'card-textitem-toggle-' + property.key"
|
||||||
<span [attr.data-automation-id]="'card-textitem-value-' + property.key">
|
fxLayout="row"
|
||||||
<span *ngIf="showProperty(); else elseEmptyValueBlock">{{ property.displayValue }}</span>
|
fxLayoutAlign="space-between center">
|
||||||
|
<span *ngIf="!isChipViewEnabled; else chipListTemplate"
|
||||||
|
[attr.data-automation-id]="'card-textitem-value-' + property.key">
|
||||||
|
<span *ngIf="showProperty(); else emptyValueTemplate">{{ property.displayValue }}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<button mat-icon-button fxFlex="0 0 auto"
|
<button mat-icon-button
|
||||||
class="adf-textitem-action"
|
fxFlex="0 0 auto"
|
||||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
class="adf-textitem-action"
|
||||||
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
|
||||||
[attr.data-automation-id]="'card-textitem-edit-icon-' + property.key">
|
[attr.data-automation-id]="'card-textitem-edit-icon-' + property.key">
|
||||||
|
|
||||||
<mat-icon class="adf-textitem-icon"> create</mat-icon>
|
<mat-icon class="adf-textitem-icon"> create</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="inEdit" class="adf-textitem-editable">
|
<div *ngIf="inEdit"
|
||||||
|
class="adf-textitem-editable">
|
||||||
<div class="adf-textitem-editable-controls">
|
<div class="adf-textitem-editable-controls">
|
||||||
<mat-form-field floatPlaceholder="never" class="adf-input-container">
|
<mat-form-field floatPlaceholder="never"
|
||||||
<input *ngIf="!property.multiline" #editorInput
|
class="adf-input-container">
|
||||||
|
<input *ngIf="!isChipViewEnabled && !property.multiline"
|
||||||
|
#editorInput
|
||||||
(keydown.escape)="reset($event)"
|
(keydown.escape)="reset($event)"
|
||||||
(keydown.enter)="update($event)"
|
(keydown.enter)="update($event)"
|
||||||
matInput
|
matInput
|
||||||
class="adf-input"
|
class="adf-input"
|
||||||
[placeholder]="property.default | translate"
|
[placeholder]="property.default | translate"
|
||||||
[(ngModel)]="editedValue"
|
[(ngModel)]="editedValue"
|
||||||
[attr.data-automation-id]="'card-textitem-editinput-' + property.key">
|
[attr.data-automation-id]="'card-textitem-editinput-' + property.key">
|
||||||
<textarea *ngIf="property.multiline" #editorInput
|
<textarea *ngIf="!isChipViewEnabled && property.multiline"
|
||||||
matInput
|
#editorInput
|
||||||
matTextareaAutosize
|
matInput
|
||||||
matAutosizeMaxRows="1"
|
matTextareaAutosize
|
||||||
matAutosizeMaxRows="5"
|
matAutosizeMaxRows="1"
|
||||||
class="adf-textarea"
|
matAutosizeMaxRows="5"
|
||||||
[placeholder]="property.default | translate"
|
class="adf-textarea"
|
||||||
[(ngModel)]="editedValue"
|
[placeholder]="property.default | translate"
|
||||||
(input)="onTextAreaInputChange()"
|
[(ngModel)]="editedValue"
|
||||||
[attr.data-automation-id]="'card-textitem-edittextarea-' + property.key"></textarea>
|
(input)="onTextAreaInputChange()"
|
||||||
|
[attr.data-automation-id]="'card-textitem-edittextarea-' + property.key"></textarea>
|
||||||
|
<div *ngIf="isChipViewEnabled">
|
||||||
|
<mat-chip-list class="adf-input"
|
||||||
|
#chipList>
|
||||||
|
<mat-chip *ngFor="let propertyValue of editedValue; let idx = index"
|
||||||
|
[removable]="true"
|
||||||
|
(removed)="removeValueFromList(idx)">
|
||||||
|
{{ propertyValue }}
|
||||||
|
<mat-icon matChipRemove>cancel</mat-icon>
|
||||||
|
</mat-chip>
|
||||||
|
<input #editorInput
|
||||||
|
[placeholder]="property.default | translate"
|
||||||
|
[matChipInputFor]="chipList"
|
||||||
|
[matChipInputAddOnBlur]="true"
|
||||||
|
(matChipInputTokenEnd)="addValueToList($event)"
|
||||||
|
[attr.data-automation-id]="'card-textitem-editchipinput-' + property.key">
|
||||||
|
</mat-chip-list>
|
||||||
|
</div>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<button mat-icon-button class="adf-textitem-action" (click)="update($event)"
|
<button mat-icon-button
|
||||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.SAVE' | translate"
|
class="adf-textitem-action"
|
||||||
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
|
(click)="update($event)"
|
||||||
[attr.data-automation-id]="'card-textitem-update-' + property.key">
|
[attr.title]="'CORE.METADATA.ACTIONS.SAVE' | translate"
|
||||||
|
[attr.data-automation-id]="'card-textitem-update-' + property.key">
|
||||||
<mat-icon class="adf-textitem-icon">done</mat-icon>
|
<mat-icon class="adf-textitem-icon">done</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button mat-icon-button (click)="reset($event)" class="adf-textitem-action"
|
<button mat-icon-button
|
||||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
|
(click)="reset($event)"
|
||||||
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
|
class="adf-textitem-action"
|
||||||
[attr.data-automation-id]="'card-textitem-reset-' + property.key">
|
[attr.title]="'CORE.METADATA.ACTIONS.CANCEL' | translate"
|
||||||
|
[attr.data-automation-id]="'card-textitem-reset-' + property.key">
|
||||||
|
|
||||||
<mat-icon>clear</mat-icon>
|
<mat-icon>clear</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<mat-error [attr.data-automation-id]="'card-textitem-error-' + property.key" class="adf-textitem-editable-error" *ngIf="hasErrors()">
|
<mat-error [attr.data-automation-id]="'card-textitem-error-' + property.key"
|
||||||
|
class="adf-textitem-editable-error"
|
||||||
|
*ngIf="hasErrors()">
|
||||||
<ul>
|
<ul>
|
||||||
<li *ngFor="let errorMessage of errorMessages">{{ errorMessage | translate }}</li>
|
<li *ngFor="let errorMessage of errorMessages">{{ errorMessage | translate }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<ng-template #elseEmptyValueBlock>
|
<ng-template #emptyValueTemplate>
|
||||||
<span class="adf-textitem-default-value">{{ property.default | translate }}</span>
|
<span class="adf-textitem-default-value">{{ property.default | translate }}</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #chipListTemplate>
|
||||||
|
<mat-chip-list>
|
||||||
|
<mat-chip *ngFor="let propertyValue of editedValue">
|
||||||
|
{{ propertyValue }}
|
||||||
|
</mat-chip>
|
||||||
|
</mat-chip-list>
|
||||||
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,6 +23,7 @@ import { CardViewTextItemComponent } from './card-view-textitem.component';
|
|||||||
import { setupTestBed } from '../../../testing/setup-test-bed';
|
import { setupTestBed } from '../../../testing/setup-test-bed';
|
||||||
import { CoreTestingModule } from '../../../testing/core.testing.module';
|
import { CoreTestingModule } from '../../../testing/core.testing.module';
|
||||||
import { CardViewItemFloatValidator, CardViewItemIntValidator } from '@alfresco/adf-core';
|
import { CardViewItemFloatValidator, CardViewItemIntValidator } from '@alfresco/adf-core';
|
||||||
|
import { MatChipsModule } from '@angular/material';
|
||||||
|
|
||||||
describe('CardViewTextItemComponent', () => {
|
describe('CardViewTextItemComponent', () => {
|
||||||
|
|
||||||
@ -31,7 +32,10 @@ describe('CardViewTextItemComponent', () => {
|
|||||||
const mouseEvent = new MouseEvent('click');
|
const mouseEvent = new MouseEvent('click');
|
||||||
|
|
||||||
setupTestBed({
|
setupTestBed({
|
||||||
imports: [CoreTestingModule]
|
imports: [
|
||||||
|
CoreTestingModule,
|
||||||
|
MatChipsModule
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -146,6 +150,48 @@ describe('CardViewTextItemComponent', () => {
|
|||||||
const editIcon = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-edit-icon-${component.property.key}"]`));
|
const editIcon = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-edit-icon-${component.property.key}"]`));
|
||||||
expect(editIcon).toBeNull('Edit icon should NOT be shown');
|
expect(editIcon).toBeNull('Edit icon should NOT be shown');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render chips for multivalue properties when chips are enabled', () => {
|
||||||
|
component.property = new CardViewTextItemModel({
|
||||||
|
label: 'Text label',
|
||||||
|
value: ['item1', 'item2', 'item3'],
|
||||||
|
key: 'textkey',
|
||||||
|
default: ['FAKE-DEFAULT-KEY'],
|
||||||
|
editable: true,
|
||||||
|
multivalued: true
|
||||||
|
});
|
||||||
|
component.useChipsForMultiValueProperty = true;
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const valueChips = fixture.debugElement.queryAll(By.css(`mat-chip`));
|
||||||
|
expect(valueChips).not.toBeNull();
|
||||||
|
expect(valueChips.length).toBe(3);
|
||||||
|
expect(valueChips[0].nativeElement.innerText.trim()).toBe('item1');
|
||||||
|
expect(valueChips[1].nativeElement.innerText.trim()).toBe('item2');
|
||||||
|
expect(valueChips[2].nativeElement.innerText.trim()).toBe('item3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render string for multivalue properties when chips are disabled', () => {
|
||||||
|
component.property = new CardViewTextItemModel({
|
||||||
|
label: 'Text label',
|
||||||
|
value: ['item1', 'item2', 'item3'],
|
||||||
|
key: 'textkey',
|
||||||
|
default: ['FAKE-DEFAULT-KEY'],
|
||||||
|
editable: true,
|
||||||
|
multivalued: true
|
||||||
|
});
|
||||||
|
|
||||||
|
component.useChipsForMultiValueProperty = false;
|
||||||
|
component.ngOnChanges();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const valueChips = fixture.debugElement.query(By.css(`mat-chip-list`));
|
||||||
|
const value = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-value-${component.property.key}"]`));
|
||||||
|
expect(value).not.toBeNull();
|
||||||
|
expect(value.nativeElement.innerText.trim()).toBe('item1,item2,item3');
|
||||||
|
expect(valueChips).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('clickable', () => {
|
describe('clickable', () => {
|
||||||
|
@ -20,6 +20,7 @@ import { CardViewTextItemModel } from '../../models/card-view-textitem.model';
|
|||||||
import { CardViewUpdateService } from '../../services/card-view-update.service';
|
import { CardViewUpdateService } from '../../services/card-view-update.service';
|
||||||
import { AppConfigService } from '../../../app-config/app-config.service';
|
import { AppConfigService } from '../../../app-config/app-config.service';
|
||||||
import { BaseCardView } from '../base-card-view';
|
import { BaseCardView } from '../base-card-view';
|
||||||
|
import { MatChipInputEvent } from '@angular/material';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'adf-card-view-textitem',
|
selector: 'adf-card-view-textitem',
|
||||||
@ -29,6 +30,7 @@ import { BaseCardView } from '../base-card-view';
|
|||||||
export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemModel> implements OnChanges {
|
export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemModel> implements OnChanges {
|
||||||
|
|
||||||
static DEFAULT_SEPARATOR = ', ';
|
static DEFAULT_SEPARATOR = ', ';
|
||||||
|
static DEFAULT_USE_CHIPS = false;
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
editable: boolean = false;
|
editable: boolean = false;
|
||||||
@ -40,18 +42,20 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
|||||||
private editorInput: any;
|
private editorInput: any;
|
||||||
|
|
||||||
inEdit: boolean = false;
|
inEdit: boolean = false;
|
||||||
editedValue: string;
|
editedValue: string | string[];
|
||||||
errorMessages: string[];
|
errorMessages: string[];
|
||||||
valueSeparator: string;
|
valueSeparator: string;
|
||||||
|
useChipsForMultiValueProperty: boolean;
|
||||||
|
|
||||||
constructor(cardViewUpdateService: CardViewUpdateService,
|
constructor(cardViewUpdateService: CardViewUpdateService,
|
||||||
private appConfig: AppConfigService) {
|
private appConfig: AppConfigService) {
|
||||||
super(cardViewUpdateService);
|
super(cardViewUpdateService);
|
||||||
this.valueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || CardViewTextItemComponent.DEFAULT_SEPARATOR;
|
this.valueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || CardViewTextItemComponent.DEFAULT_SEPARATOR;
|
||||||
|
this.useChipsForMultiValueProperty = this.appConfig.get<boolean>('content-metadata.multi-value-chips') || CardViewTextItemComponent.DEFAULT_USE_CHIPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(): void {
|
ngOnChanges(): void {
|
||||||
this.editedValue = this.property.multiline ? this.property.displayValue : this.property.value;
|
this.resetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
showProperty(): boolean {
|
showProperty(): boolean {
|
||||||
@ -87,19 +91,27 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
|||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(event: MouseEvent|KeyboardEvent): void {
|
reset(event: Event): void {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
this.editedValue = this.property.multiline ? this.property.displayValue : this.property.value;
|
this.resetValue();
|
||||||
this.setEditMode(false);
|
this.setEditMode(false);
|
||||||
this.resetErrorMessages();
|
this.resetErrorMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetValue() {
|
||||||
|
if (this.isChipViewEnabled) {
|
||||||
|
this.editedValue = this.property.value ? Array.from(this.property.value) : [];
|
||||||
|
} else {
|
||||||
|
this.editedValue = this.property.multiline ? this.property.displayValue : this.property.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private resetErrorMessages() {
|
private resetErrorMessages() {
|
||||||
this.errorMessages = [];
|
this.errorMessages = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
update(event: MouseEvent|KeyboardEvent): void {
|
update(event: Event): void {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if (this.property.isValid(this.editedValue)) {
|
if (this.property.isValid(this.editedValue)) {
|
||||||
@ -113,14 +125,35 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareValueForUpload(property: CardViewTextItemModel, value: string): string | string [] {
|
prepareValueForUpload(property: CardViewTextItemModel, value: string | string[]): string | string[] {
|
||||||
if (property.multivalued) {
|
if (property.multivalued && typeof value === 'string') {
|
||||||
const listOfValues = value.split(this.valueSeparator.trim()).map((item) => item.trim());
|
const listOfValues = value.split(this.valueSeparator.trim()).map((item) => item.trim());
|
||||||
return listOfValues;
|
return listOfValues;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeValueFromList(itemIndex: number) {
|
||||||
|
if (typeof this.editedValue !== 'string') {
|
||||||
|
this.editedValue.splice(itemIndex, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addValueToList(newListItem: MatChipInputEvent) {
|
||||||
|
const chipInput = newListItem.input;
|
||||||
|
const chipValue = newListItem.value.trim() || '';
|
||||||
|
|
||||||
|
if (typeof this.editedValue !== 'string') {
|
||||||
|
if (chipValue) {
|
||||||
|
this.editedValue.push(chipValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chipInput) {
|
||||||
|
chipInput.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onTextAreaInputChange() {
|
onTextAreaInputChange() {
|
||||||
this.errorMessages = this.property.getValidationErrors(this.editedValue);
|
this.errorMessages = this.property.getValidationErrors(this.editedValue);
|
||||||
}
|
}
|
||||||
@ -132,4 +165,8 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
|||||||
this.cardViewUpdateService.clicked(this.property);
|
this.cardViewUpdateService.clicked(this.property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isChipViewEnabled(): boolean {
|
||||||
|
return this.property.multivalued && this.useChipsForMultiValueProperty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,14 +118,15 @@ export class DataTableComponentPage {
|
|||||||
*
|
*
|
||||||
* @param sortOrder: 'ASC' if the list is await expected to be sorted ascending and 'DESC' for descending
|
* @param sortOrder: 'ASC' if the list is await expected to be sorted ascending and 'DESC' for descending
|
||||||
* @param columnTitle: titleColumn column
|
* @param columnTitle: titleColumn column
|
||||||
|
* @param listType: 'string' for string typed lists and 'number' for number typed (int, float) lists
|
||||||
* @return 'true' if the list is sorted as await expected and 'false' if it isn't
|
* @return 'true' if the list is sorted as await expected and 'false' if it isn't
|
||||||
*/
|
*/
|
||||||
async checkListIsSorted(sortOrder: string, columnTitle: string): Promise<any> {
|
async checkListIsSorted(sortOrder: string, columnTitle: string, listType: string = 'STRING'): Promise<any> {
|
||||||
const column = element.all(by.css(`div.adf-datatable-cell[title='${columnTitle}'] span`));
|
const column = element.all(by.css(`div.adf-datatable-cell[title='${columnTitle}'] span`));
|
||||||
await BrowserVisibility.waitUntilElementIsVisible(column.first());
|
await BrowserVisibility.waitUntilElementIsVisible(column.first());
|
||||||
const initialList = [];
|
const initialList = [];
|
||||||
|
|
||||||
const length = await column.count();
|
const length = await column.count();
|
||||||
|
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
const text = await BrowserActions.getText(column.get(i));
|
const text = await BrowserActions.getText(column.get(i));
|
||||||
@ -135,7 +136,12 @@ export class DataTableComponentPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sortedList = [...initialList];
|
let sortedList = [...initialList];
|
||||||
sortedList = sortedList.sort();
|
if (listType.toLocaleLowerCase() === 'string') {
|
||||||
|
sortedList = sortedList.sort();
|
||||||
|
} else if (listType.toLocaleLowerCase() === 'number') {
|
||||||
|
sortedList = sortedList.sort((a, b) => a - b);
|
||||||
|
}
|
||||||
|
|
||||||
if (sortOrder.toLocaleLowerCase() === 'desc') {
|
if (sortOrder.toLocaleLowerCase() === 'desc') {
|
||||||
sortedList = sortedList.reverse();
|
sortedList = sortedList.reverse();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user