mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-02 17:53:30 +00:00
[ACS-8468] Add copy icon functionality (#12079)
* [ACS-9106] Make the descendants false iin data column component * [ACS-8468] Add copy icon * [ACS-8468] Remove change from data column * [ACS-8468] Use if instead of *ngIf * [ACS-8468] Revert to double click functionality * [ACS-8468] Make copy button toggable and make it icon * [ACS-8468] Add unit test for copy icons * [ACS-8468] Add unit test for mat registry * [ACS-8468] Remove deprecated component * [ACS-8468] Align the styling with dropdown menu * [ACS-8468] Fix sonar cloud issue * [ACS-8468] Remove deprecated component * [ACS-8468] Remove svg icon and use material icon * [ACS-8468] Fix styling and remove mat-form-field-icon-suffix selector * [ACS-8468] Make copy to clipboard icon property true * [ACS-8468] Add unit tests and remove unused class * [ACS-8468] Add unitTestingUtils * [ACS-8468] use with args instead of callFake * [ACS-8468] remove jasmine.spy
This commit is contained in:
@@ -417,7 +417,8 @@ Once you have enabled this feature you will be able to double click on your meta
|
||||
"exif:exif": [ "exif:pixelXDimension", "exif:pixelYDimension"]
|
||||
}
|
||||
},
|
||||
"copy-to-clipboard-action": true
|
||||
"copy-to-clipboard-action": true,
|
||||
"display-copy-to-clipboard-icon": true
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ Defining properties from Typescript:
|
||||
| Name | Type | Default value | Description |
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| copyToClipboardAction | `boolean` | true | Toggles whether or not to enable copy to clipboard action. |
|
||||
| displayCopyToClipboardIcon | `boolean` | true | Toggles whether or not to show copy to clipboard icon. |
|
||||
| displayClearAction | `boolean` | true | Toggles whether or not to display clear action. |
|
||||
| displayEmpty | `boolean` | true | Toggles whether or not to show empty items in non-editable mode. |
|
||||
| displayNoneOption | `boolean` | true | Toggles whether or not to display none option. |
|
||||
@@ -193,6 +194,7 @@ const textItemProperty = new CardViewTextItemModel(options);
|
||||
| clickable | boolean | false | Toggles whether the property responds to clicks |
|
||||
| clickableCallBack | function | null | Function to execute when click the element |
|
||||
| copyToClipboardAction | `boolean` | true | Toggles whether or not to enable copy to clipboard action. |
|
||||
| displayCopyToClipboardIcon | `boolean` | true | Toggles whether or not to show copy to clipboard icon. |
|
||||
| useChipsForMultiValueProperty | `boolean` | true | Toggles whether or not to enable chips for multivalued properties. |
|
||||
| multiValueSeparator | `string` | ',' | String separator between multi-value property items. |
|
||||
| icon | string | | The material icon to show beside the item if it is clickable |
|
||||
@@ -249,6 +251,7 @@ const dateItemProperty = new CardViewDateItemModel(options);
|
||||
| label\* | string | | Item label |
|
||||
| value\* | any | | The original data value for the item |
|
||||
| copyToClipboardAction | `boolean` | true | Toggles whether or not to enable copy to clipboard action. |
|
||||
| displayCopyToClipboardIcon | `boolean` | true | Toggles whether or not to show copy to clipboard icon. |
|
||||
| key\* | string | | Identifying key (important when editing the item) |
|
||||
| default | any | | The default value to display if the value is empty |
|
||||
| displayValue\* | any | | The value to display |
|
||||
|
||||
@@ -109,9 +109,10 @@ Now that the `my-preset` configuration is defined, let's use it in a view of the
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Default value | Description |
|
||||
|----------|-----------|---------------|------------------------------------------------------------------------------|
|
||||
| readOnly | `boolean` | false | (optional) This flag sets the metadata in read only mode preventing changes. |
|
||||
| Name | Type | Default value | Description |
|
||||
|----------------------------|-----------|---------------|------------------------------------------------------------------------------|
|
||||
| readOnly | `boolean` | false | (optional) This flag sets the metadata in read only mode preventing changes. |
|
||||
| displayCopyToClipboardIcon | `boolean` | true | Toggles whether or not to display the copy to clipboard icon. |
|
||||
|
||||
### Viewing the result
|
||||
|
||||
|
||||
+2
@@ -51,6 +51,7 @@
|
||||
[editable]="!readOnly && isPanelEditing(DefaultPanels.PROPERTIES)"
|
||||
[displayEmpty]="displayEmpty"
|
||||
[copyToClipboardAction]="copyToClipboardAction"
|
||||
[displayCopyToClipboardIcon]="displayCopyToClipboardIcon"
|
||||
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
||||
[multiValueSeparator]="multiValueSeparator" />
|
||||
</mat-expansion-panel>
|
||||
@@ -252,6 +253,7 @@
|
||||
[editable]="!readOnly && group.editable && isPanelEditing(group.title)"
|
||||
[displayEmpty]="displayEmpty"
|
||||
[copyToClipboardAction]="copyToClipboardAction"
|
||||
[displayCopyToClipboardIcon]="displayCopyToClipboardIcon"
|
||||
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
||||
[multiValueSeparator]="multiValueSeparator" />
|
||||
</mat-expansion-panel>
|
||||
|
||||
+20
@@ -50,6 +50,7 @@ describe('ContentMetadataComponent', () => {
|
||||
let contentMetadataService: ContentMetadataService;
|
||||
let updateService: CardViewContentUpdateService;
|
||||
let nodesApiService: NodesApiService;
|
||||
let appConfigService: AppConfigService;
|
||||
let node: Node;
|
||||
let folderNode: Node;
|
||||
let tagService: TagService;
|
||||
@@ -212,6 +213,7 @@ describe('ContentMetadataComponent', () => {
|
||||
tagService = TestBed.inject(TagService);
|
||||
categoryService = TestBed.inject(CategoryService);
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
appConfigService = TestBed.inject(AppConfigService);
|
||||
const propertyDescriptorsService = TestBed.inject(PropertyDescriptorsService);
|
||||
const classesApi = propertyDescriptorsService['classesApi'];
|
||||
|
||||
@@ -255,6 +257,24 @@ describe('ContentMetadataComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Copy to clipboard configuration', () => {
|
||||
it('should set displayCopyToClipboardIcon to true when config value is true', () => {
|
||||
const getSpy = spyOn(appConfigService, 'get').and.callThrough();
|
||||
getSpy.withArgs('content-metadata.display-copy-to-clipboard-icon').and.returnValue(true);
|
||||
const newFixture = TestBed.createComponent(ContentMetadataComponent);
|
||||
|
||||
expect(newFixture.componentInstance.displayCopyToClipboardIcon).toBeTrue();
|
||||
});
|
||||
|
||||
it('should set displayCopyToClipboardIcon to false when config value is false', () => {
|
||||
const getSpy = spyOn(appConfigService, 'get').and.callThrough();
|
||||
getSpy.withArgs('content-metadata.display-copy-to-clipboard-icon').and.returnValue(false);
|
||||
const newFixture = TestBed.createComponent(ContentMetadataComponent);
|
||||
|
||||
expect(newFixture.componentInstance.displayCopyToClipboardIcon).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Folder', () => {
|
||||
it('should show the folder node', (done) => {
|
||||
component.expanded = false;
|
||||
|
||||
+5
@@ -131,6 +131,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
|
||||
@Input()
|
||||
copyToClipboardAction: boolean = true;
|
||||
|
||||
/** Toggles whether or not to display the copy to clipboard icon. */
|
||||
@Input()
|
||||
displayCopyToClipboardIcon = true;
|
||||
|
||||
/** Toggles whether or not to enable chips for multivalued properties. */
|
||||
@Input()
|
||||
useChipsForMultiValueProperty: boolean = true;
|
||||
@@ -186,6 +190,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
|
||||
|
||||
constructor() {
|
||||
this.copyToClipboardAction = this.appConfig.get<boolean>('content-metadata.copy-to-clipboard-action');
|
||||
this.displayCopyToClipboardIcon = this.appConfig.get<boolean>('content-metadata.display-copy-to-clipboard-icon');
|
||||
this.multiValueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || DEFAULT_SEPARATOR;
|
||||
this.useChipsForMultiValueProperty = this.appConfig.get<boolean>('content-metadata.multi-value-chips');
|
||||
}
|
||||
|
||||
@@ -1471,6 +1471,10 @@
|
||||
"description": "Copy property to the clipboard on double click",
|
||||
"type": "boolean"
|
||||
},
|
||||
"display-copy-to-clipboard-icon": {
|
||||
"description": "Displays the copy to clipboard icon",
|
||||
"type": "boolean"
|
||||
},
|
||||
"selectFilterLimit": {
|
||||
"description": "Shows a filter if list options exceed a specified number. Default value 5",
|
||||
"type": "number"
|
||||
|
||||
+16
@@ -87,6 +87,22 @@
|
||||
<span class="adf-error-text">{{ 'FORM.FIELD.VALIDATOR.INVALID_DATE_FORMAT' | translate }}</span>
|
||||
</mat-error>
|
||||
}
|
||||
@if (displayCopyToClipboardIcon && !isEditable) {
|
||||
<button
|
||||
matSuffix
|
||||
type="button"
|
||||
class="adf-copy-to-clipboard-button"
|
||||
(click)="copyToClipboard(property.displayValue, $event)"
|
||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.COPY_TO_CLIPBOARD' | translate"
|
||||
[attr.data-automation-id]="'card-dateitem-copy-to-clipboard-' + property.key"
|
||||
>
|
||||
<mat-icon
|
||||
adf-icon="content_copy"
|
||||
class="adf-copy-to-clipboard-icon"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
}
|
||||
</mat-form-field>
|
||||
} @else {
|
||||
<mat-form-field class="adf-property-field adf-dateitem-editable" [floatLabel]="property.default ? 'always' : null">
|
||||
|
||||
+27
@@ -64,4 +64,31 @@
|
||||
border-bottom: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.adf-copy-to-clipboard-button {
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
|
||||
.adf-copy-to-clipboard-icon {
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
.adf-copy-to-clipboard-button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.adf-copy-to-clipboard-button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -225,6 +225,47 @@ describe('CardViewDateItemComponent', () => {
|
||||
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith('Jul 10, 2017', 'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
|
||||
});
|
||||
|
||||
it('should copy value to clipboard when clicking the copy icon', () => {
|
||||
const clipboardService = TestBed.inject(ClipboardService);
|
||||
spyOn(clipboardService, 'copyContentToClipboard');
|
||||
|
||||
component.editable = false;
|
||||
component.displayCopyToClipboardIcon = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
testingUtils.clickByDataAutomationId('card-dateitem-copy-to-clipboard-' + component.property.key);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith('Jul 10, 2017', 'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
|
||||
});
|
||||
|
||||
it('should render the copy icon by default', () => {
|
||||
component.editable = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-dateitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should NOT render the copy icon when displayCopyToClipboardIcon is false', () => {
|
||||
component.editable = false;
|
||||
component.displayCopyToClipboardIcon = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-dateitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).toBeNull();
|
||||
});
|
||||
|
||||
it('should NOT render the copy icon when the item is editable', () => {
|
||||
component.editable = true;
|
||||
component.property.editable = true;
|
||||
component.displayCopyToClipboardIcon = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-dateitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).toBeNull();
|
||||
});
|
||||
|
||||
describe('clear icon', () => {
|
||||
it('should render the clear icon in case of displayClearAction:true', () => {
|
||||
component.editable = true;
|
||||
|
||||
+9
-2
@@ -86,6 +86,12 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
@Input()
|
||||
displayClearAction = true;
|
||||
|
||||
@Input()
|
||||
copyToClipboardAction = true;
|
||||
|
||||
@Input()
|
||||
displayCopyToClipboardIcon = true;
|
||||
|
||||
@ViewChild('datetimePicker')
|
||||
public datepicker: MatDatetimepickerComponent<any>;
|
||||
|
||||
@@ -203,11 +209,12 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
this.property.default = null;
|
||||
}
|
||||
|
||||
copyToClipboard(valueToCopy: string | string[]) {
|
||||
if (typeof valueToCopy === 'string') {
|
||||
copyToClipboard(valueToCopy: string | string[], event?: MouseEvent) {
|
||||
if (typeof valueToCopy === 'string' && (this.copyToClipboardAction || this.displayCopyToClipboardIcon)) {
|
||||
const clipboardMessage = this.translateService.instant('CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
|
||||
this.clipboardService.copyContentToClipboard(valueToCopy, clipboardMessage);
|
||||
}
|
||||
(event?.currentTarget as HTMLElement)?.blur();
|
||||
}
|
||||
|
||||
addDateToList(event: MatDatetimepickerInputEvent<Date>) {
|
||||
|
||||
+4
-1
@@ -110,6 +110,7 @@ describe('CardViewItemDispatcherComponent', () => {
|
||||
const expectedCustomInput = 1;
|
||||
const expectedDisplayNoneOption = false;
|
||||
const expectedDisplayClearAction = false;
|
||||
const expectedDisplayCopyToClipboardIcon = true;
|
||||
|
||||
component.ngOnChanges({
|
||||
editable: new SimpleChange(true, expectedEditable, false),
|
||||
@@ -117,7 +118,8 @@ describe('CardViewItemDispatcherComponent', () => {
|
||||
property: new SimpleChange(null, expectedProperty, false),
|
||||
customInput: new SimpleChange(0, expectedCustomInput, false),
|
||||
displayNoneOption: new SimpleChange(true, expectedDisplayNoneOption, false),
|
||||
displayClearAction: new SimpleChange(true, expectedDisplayClearAction, false)
|
||||
displayClearAction: new SimpleChange(true, expectedDisplayClearAction, false),
|
||||
displayCopyToClipboardIcon: new SimpleChange(false, expectedDisplayCopyToClipboardIcon, true)
|
||||
});
|
||||
|
||||
const shinyCustomElementItemComponent = testingUtils.getByCSS('whatever-you-want-to-have').componentInstance;
|
||||
@@ -127,6 +129,7 @@ describe('CardViewItemDispatcherComponent', () => {
|
||||
expect(shinyCustomElementItemComponent.customInput).toBe(expectedCustomInput);
|
||||
expect(shinyCustomElementItemComponent.displayNoneOption).toBe(expectedDisplayNoneOption);
|
||||
expect(shinyCustomElementItemComponent.displayClearAction).toBe(expectedDisplayClearAction);
|
||||
expect(shinyCustomElementItemComponent.displayCopyToClipboardIcon).toBe(expectedDisplayCopyToClipboardIcon);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+4
@@ -45,6 +45,9 @@ export class CardViewItemDispatcherComponent implements OnChanges {
|
||||
@Input()
|
||||
copyToClipboardAction: boolean = true;
|
||||
|
||||
@Input()
|
||||
displayCopyToClipboardIcon = true;
|
||||
|
||||
@Input()
|
||||
useChipsForMultiValueProperty: boolean = true;
|
||||
|
||||
@@ -100,6 +103,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
|
||||
this.componentReference.instance.displayNoneOption = this.displayNoneOption;
|
||||
this.componentReference.instance.displayClearAction = this.displayClearAction;
|
||||
this.componentReference.instance.copyToClipboardAction = this.copyToClipboardAction;
|
||||
this.componentReference.instance.displayCopyToClipboardIcon = this.displayCopyToClipboardIcon;
|
||||
this.componentReference.instance.useChipsForMultiValueProperty = this.useChipsForMultiValueProperty;
|
||||
this.componentReference.instance.multiValueSeparator = this.multiValueSeparator;
|
||||
}
|
||||
|
||||
+18
-1
@@ -29,7 +29,8 @@
|
||||
'adf-property-value-editable': editable,
|
||||
'adf-property-readonly-value': isReadonlyProperty || !editable,
|
||||
'adf-property-value-has-error': isEditable && hasErrors,
|
||||
'adf-property-value-not-editable': !editable
|
||||
'adf-property-value-not-editable': !editable,
|
||||
'adf-property-value-has-icon-suffix': displayCopyToClipboardIcon && !isEditable
|
||||
}"
|
||||
title="{{ property.label | translate }}"
|
||||
[placeholder]="property.default"
|
||||
@@ -58,6 +59,22 @@
|
||||
[attr.data-automation-id]="'card-textitem-value-' + property.key"
|
||||
>
|
||||
</textarea>
|
||||
@if (displayCopyToClipboardIcon && !isEditable) {
|
||||
<button
|
||||
matSuffix
|
||||
type="button"
|
||||
class="adf-textitem-action adf-copy-to-clipboard-button"
|
||||
(click)="copyToClipboard(property.displayValue, $event)"
|
||||
[attr.aria-label]="'CORE.METADATA.ACTIONS.COPY_TO_CLIPBOARD' | translate"
|
||||
[attr.data-automation-id]="'card-textitem-copy-to-clipboard-' + property.key"
|
||||
>
|
||||
<mat-icon
|
||||
adf-icon="content_copy"
|
||||
class="adf-copy-to-clipboard-icon"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
}
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
|
||||
+37
@@ -59,6 +59,7 @@
|
||||
}
|
||||
|
||||
.adf-property-value-has-icon-suffix {
|
||||
box-sizing: border-box;
|
||||
padding-right: 34px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -68,4 +69,40 @@
|
||||
|
||||
.adf-card-textitem-field-container {
|
||||
padding-top: 5px;
|
||||
|
||||
.adf-card-textitem-field .adf-copy-to-clipboard-button {
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.adf-copy-to-clipboard-icon {
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
right: 5px;
|
||||
bottom: 6px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
.adf-card-textitem-field .adf-copy-to-clipboard-button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
.adf-card-textitem-field .adf-copy-to-clipboard-button {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -597,6 +597,52 @@ describe('CardViewTextItemComponent', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should copy value to clipboard when clicking the copy icon', () => {
|
||||
const clipboardService = TestBed.inject(ClipboardService);
|
||||
spyOn(clipboardService, 'copyContentToClipboard');
|
||||
|
||||
component.property.value = 'myValueToCopy';
|
||||
component.editable = false;
|
||||
component.displayCopyToClipboardIcon = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
testingUtils.clickByDataAutomationId('card-textitem-copy-to-clipboard-' + component.property.key);
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith(
|
||||
'myValueToCopy',
|
||||
'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE'
|
||||
);
|
||||
});
|
||||
|
||||
it('should render the copy icon by default', () => {
|
||||
component.editable = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-textitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should NOT render the copy icon when displayCopyToClipboardIcon is false', () => {
|
||||
component.editable = false;
|
||||
component.displayCopyToClipboardIcon = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-textitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).toBeNull();
|
||||
});
|
||||
|
||||
it('should NOT render the copy icon when the item is editable', () => {
|
||||
component.editable = true;
|
||||
component.property.editable = true;
|
||||
component.displayCopyToClipboardIcon = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
const copyIcon = testingUtils.getByDataAutomationId('card-textitem-copy-to-clipboard-' + component.property.key);
|
||||
expect(copyIcon).toBeNull();
|
||||
});
|
||||
|
||||
it('should input be disabled if item it NOT editable', async () => {
|
||||
component.editable = false;
|
||||
component.property.clickable = true;
|
||||
|
||||
+6
-2
@@ -71,6 +71,9 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
@Input()
|
||||
copyToClipboardAction = true;
|
||||
|
||||
@Input()
|
||||
displayCopyToClipboardIcon = true;
|
||||
|
||||
@Input()
|
||||
useChipsForMultiValueProperty = true;
|
||||
|
||||
@@ -218,11 +221,12 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
this.update();
|
||||
}
|
||||
|
||||
copyToClipboard(valueToCopy: string) {
|
||||
if (this.copyToClipboardAction) {
|
||||
copyToClipboard(valueToCopy: string, event?: MouseEvent) {
|
||||
if (this.copyToClipboardAction || this.displayCopyToClipboardIcon) {
|
||||
const clipboardMessage = this.translateService.instant('CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
|
||||
this.clipboardService.copyContentToClipboard(valueToCopy, clipboardMessage);
|
||||
}
|
||||
(event?.currentTarget as HTMLElement)?.blur();
|
||||
}
|
||||
|
||||
undoText(event: KeyboardEvent) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[displayNoneOption]="property['displayNoneOption'] !== undefined ? property['displayNoneOption'] : displayNoneOption"
|
||||
[displayClearAction]="displayClearAction"
|
||||
[copyToClipboardAction]="copyToClipboardAction"
|
||||
[displayCopyToClipboardIcon]="displayCopyToClipboardIcon"
|
||||
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
||||
[multiValueSeparator]="multiValueSeparator" />
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CardViewDateItemModel } from '../../models/card-view-dateitem.model';
|
||||
import { CardViewTextItemModel } from '../../models/card-view-textitem.model';
|
||||
import { CardViewComponent } from './card-view.component';
|
||||
import { CardViewItemDispatcherComponent } from '../card-view-item-dispatcher/card-view-item-dispatcher.component';
|
||||
import { CardViewSelectItemModel } from '../../models/card-view-selectitem.model';
|
||||
import { of } from 'rxjs';
|
||||
import { CardViewSelectItemOption } from '../../interfaces/card-view-selectitem-properties.interface';
|
||||
@@ -81,6 +82,20 @@ describe('CardViewComponent', () => {
|
||||
expect(testingUtils.getByDataAutomationId('datepicker-some-key')).not.toBeNull('Datepicker should be in DOM');
|
||||
});
|
||||
|
||||
it('should pass through displayCopyToClipboardIcon property to the item dispatcher', () => {
|
||||
component.displayCopyToClipboardIcon = false;
|
||||
component.properties = [new CardViewTextItemModel({ label: 'My label', value: 'My value', key: 'some key' })];
|
||||
fixture.detectChanges();
|
||||
|
||||
const dispatcher = testingUtils.getByDirective(CardViewItemDispatcherComponent).componentInstance;
|
||||
expect(dispatcher.displayCopyToClipboardIcon).toBeFalse();
|
||||
|
||||
component.displayCopyToClipboardIcon = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dispatcher.displayCopyToClipboardIcon).toBeTrue();
|
||||
});
|
||||
|
||||
it('should render the date in the correct format', async () => {
|
||||
component.properties = [
|
||||
new CardViewDateItemModel({
|
||||
|
||||
@@ -53,6 +53,10 @@ export class CardViewComponent {
|
||||
@Input()
|
||||
copyToClipboardAction: boolean = true;
|
||||
|
||||
/** Toggles whether or not to display the copy to clipboard icon. */
|
||||
@Input()
|
||||
displayCopyToClipboardIcon: boolean = true;
|
||||
|
||||
/** Toggles whether or not to enable chips for multivalued properties. */
|
||||
@Input()
|
||||
useChipsForMultiValueProperty: boolean = true;
|
||||
|
||||
@@ -77,6 +77,14 @@ export const cardViewArgTypes: ArgTypes = {
|
||||
defaultValue: { summary: 'true' }
|
||||
}
|
||||
},
|
||||
displayCopyToClipboardIcon: {
|
||||
control: 'boolean',
|
||||
description: 'Display copy to clipboard icon',
|
||||
table: {
|
||||
type: { summary: 'boolean' },
|
||||
defaultValue: { summary: 'true' }
|
||||
}
|
||||
},
|
||||
useChipsForMultiValueProperty: {
|
||||
control: 'boolean',
|
||||
description: 'Split text for chips using defined separator',
|
||||
@@ -104,6 +112,7 @@ export const cardViewDefaultArgs: Record<string, unknown> = {
|
||||
displayNoneOption: true,
|
||||
displayClearAction: true,
|
||||
copyToClipboardAction: true,
|
||||
displayCopyToClipboardIcon: true,
|
||||
useChipsForMultiValueProperty: true,
|
||||
multiValueSeparator: ', '
|
||||
};
|
||||
|
||||
+1
@@ -8,6 +8,7 @@
|
||||
[multi]="multi"
|
||||
[displayAspect]="displayAspect"
|
||||
[copyToClipboardAction]="copyToClipboardAction"
|
||||
[displayCopyToClipboardIcon]="displayCopyToClipboardIcon"
|
||||
[useChipsForMultiValueProperty]="useChipsForMultiValueProperty"
|
||||
[displayTags]="false"
|
||||
[displayCategories]="false"
|
||||
|
||||
+4
@@ -73,6 +73,10 @@ export class PropertiesViewerWrapperComponent implements OnInit, OnChanges {
|
||||
@Input()
|
||||
copyToClipboardAction: boolean;
|
||||
|
||||
/** Toggles the visibility of the copy to clipboard icon */
|
||||
@Input()
|
||||
displayCopyToClipboardIcon: boolean;
|
||||
|
||||
/** Toggles chips for multivalued properties. */
|
||||
@Input()
|
||||
useChipsForMultiValueProperty: boolean;
|
||||
|
||||
+1
@@ -19,6 +19,7 @@
|
||||
[multi]="properties?.multi !== undefined ? properties?.multi : false"
|
||||
[displayAspect]="properties?.displayAspect !== undefined ? properties?.displayAspect : null"
|
||||
[copyToClipboardAction]="properties?.copyToClipboardAction !== undefined ? properties?.copyToClipboardAction : true"
|
||||
[displayCopyToClipboardIcon]="properties?.displayCopyToClipboardIcon ?? true"
|
||||
[useChipsForMultiValueProperty]="properties?.useChipsForMultiValueProperty !== undefined ? properties?.useChipsForMultiValueProperty : true"
|
||||
(nodeContentLoaded)="onNodeContentLoaded($event)"
|
||||
/>
|
||||
|
||||
+29
-1
@@ -16,8 +16,9 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { FormFieldModel, FormModel, NoopTranslateModule, NoopAuthModule } from '@alfresco/adf-core';
|
||||
import { FormFieldModel, FormModel, NoopTranslateModule, NoopAuthModule, UnitTestingUtils } from '@alfresco/adf-core';
|
||||
import { PropertiesViewerWidgetComponent } from './properties-viewer.widget';
|
||||
import { PropertiesViewerWrapperComponent } from './properties-viewer-wrapper/properties-viewer-wrapper.component';
|
||||
import { fakeNodeWithProperties } from '../../../mocks/attach-file-cloud-widget.mock';
|
||||
import { NodesApiService, BasicPropertiesService } from '@alfresco/adf-content-services';
|
||||
import { of } from 'rxjs';
|
||||
@@ -27,6 +28,7 @@ describe('PropertiesViewerWidgetComponent', () => {
|
||||
let fixture: ComponentFixture<PropertiesViewerWidgetComponent>;
|
||||
let element: HTMLElement;
|
||||
let nodesApiService: NodesApiService;
|
||||
let testingUtils: UnitTestingUtils;
|
||||
|
||||
const fakePngAnswer: any = {
|
||||
id: '1933',
|
||||
@@ -52,6 +54,7 @@ describe('PropertiesViewerWidgetComponent', () => {
|
||||
nodesApiService = TestBed.inject(NodesApiService);
|
||||
widget = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
testingUtils = new UnitTestingUtils(fixture.debugElement);
|
||||
|
||||
widget.field = new FormFieldModel(new FormModel());
|
||||
spyOn(nodesApiService, 'getNode').and.returnValue(of(fakeNodeWithProperties));
|
||||
@@ -97,6 +100,31 @@ describe('PropertiesViewerWidgetComponent', () => {
|
||||
expect(propertiesViewer).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should default displayCopyToClipboardIcon to true when not set in options', async () => {
|
||||
widget.field.value = '1234';
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const wrapper = testingUtils.getByDirective(PropertiesViewerWrapperComponent).componentInstance;
|
||||
|
||||
expect(wrapper.displayCopyToClipboardIcon).toBeTrue();
|
||||
});
|
||||
|
||||
it('should pass displayCopyToClipboardIcon from options to the properties viewer wrapper', async () => {
|
||||
widget.field = new FormFieldModel(new FormModel(), {
|
||||
value: '1234',
|
||||
params: { propertiesViewerOptions: { displayCopyToClipboardIcon: false } }
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const wrapper = testingUtils.getByDirective(PropertiesViewerWrapperComponent).componentInstance;
|
||||
|
||||
expect(wrapper.displayCopyToClipboardIcon).toBeFalse();
|
||||
});
|
||||
|
||||
it('should emit the node when node content is loaded', async () => {
|
||||
const nodeContentLoadedSpy = spyOn(widget.nodeContentLoaded, 'emit');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user