[ADF-3726] Add copy to clipbouard support to card view properties (#5565)

This commit is contained in:
davidcanonieto
2020-03-25 13:42:35 +00:00
committed by GitHub
parent 3f45e7b35d
commit 6806504a65
8 changed files with 97 additions and 41 deletions

View File

@@ -29,7 +29,8 @@ import {
MatSelectModule, MatSelectModule,
MatChipsModule, MatChipsModule,
MatMenuModule, MatMenuModule,
MatCardModule MatCardModule,
MatTooltipModule
} from '@angular/material'; } from '@angular/material';
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core'; import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
import { FlexLayoutModule } from '@angular/flex-layout'; import { FlexLayoutModule } from '@angular/flex-layout';
@@ -64,7 +65,8 @@ import { CardViewArrayItemComponent } from './components/card-view-arrayitem/car
MatMenuModule, MatMenuModule,
MatCardModule, MatCardModule,
MatDatetimepickerModule, MatDatetimepickerModule,
MatNativeDatetimeModule MatNativeDatetimeModule,
MatTooltipModule
], ],
declarations: [ declarations: [
CardViewComponent, CardViewComponent,

View File

@@ -1,54 +1,53 @@
<div <div *ngIf="showProperty() || isEditable()"
*ngIf="showProperty() || isEditable()" [attr.data-automation-id]="'card-dateitem-label-' + property.key"
[attr.data-automation-id]="'card-dateitem-label-' + property.key" class="adf-property-label">{{ property.label | translate }}</div>
class="adf-property-label"
>{{ property.label | translate }}</div>
<div class="adf-property-value"> <div class="adf-property-value">
<span *ngIf="!isEditable()" [attr.data-automation-id]="'card-' + property.type + '-value-' + property.key"> <span *ngIf="!isEditable()"
[attr.data-automation-id]="'card-' + property.type + '-value-' + property.key">
<span [attr.data-automation-id]="'card-dateitem-' + property.key"> <span [attr.data-automation-id]="'card-dateitem-' + property.key">
<span *ngIf="showProperty()">{{ property.displayValue }}</span> <span *ngIf="showProperty()"
(dblclick)="copyToClipboard(property.displayValue)"
matTooltipShowDelay="1000"
[matTooltip]="'CORE.METADATA.ACTIONS.COPY_TO_CLIPBOARD' | translate">{{ property.displayValue }}</span>
</span> </span>
</span> </span>
<div *ngIf="isEditable()" class="adf-dateitem-editable"> <div *ngIf="isEditable()"
class="adf-dateitem-editable">
<div class="adf-dateitem-editable-controls"> <div class="adf-dateitem-editable-controls">
<span <span class="adf-datepicker-toggle"
class="adf-datepicker-toggle" [attr.data-automation-id]="'datepicker-label-toggle-' + property.key"
[attr.data-automation-id]="'datepicker-label-toggle-' + property.key" (click)="showDatePicker()">
(click)="showDatePicker()"> <span *ngIf="showProperty(); else elseEmptyValueBlock"
<span [attr.data-automation-id]="'card-' + property.type + '-value-' + property.key">{{ property.displayValue }}</span>
*ngIf="showProperty(); else elseEmptyValueBlock"
[attr.data-automation-id]="'card-' + property.type + '-value-' + property.key"
>{{ property.displayValue }}</span>
</span> </span>
<mat-icon *ngIf="showClearAction()" <mat-icon *ngIf="showClearAction()"
class="adf-date-reset-icon" class="adf-date-reset-icon"
(click)="onDateClear()" (click)="onDateClear()"
[attr.title]="'CORE.METADATA.ACTIONS.CLEAR' | translate" [attr.title]="'CORE.METADATA.ACTIONS.CLEAR' | translate"
[attr.data-automation-id]="'datepicker-date-clear-' + property.key"> [attr.data-automation-id]="'datepicker-date-clear-' + property.key">
clear clear
</mat-icon> </mat-icon>
<mat-datetimepicker-toggle <mat-datetimepicker-toggle [attr.tabindex]="-1"
[attr.tabindex]="-1" [attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate"
[attr.title]="'CORE.METADATA.ACTIONS.EDIT' | translate" [attr.data-automation-id]="'datepickertoggle-' + property.key"
[attr.data-automation-id]="'datepickertoggle-' + property.key" [for]="datetimePicker">
[for]="datetimePicker">
</mat-datetimepicker-toggle> </mat-datetimepicker-toggle>
</div> </div>
<input class="adf-invisible-date-input" <input class="adf-invisible-date-input"
[attr.tabIndex]="-1" [attr.tabIndex]="-1"
[matDatetimepicker]="datetimePicker" [matDatetimepicker]="datetimePicker"
[value]="valueDate" [value]="valueDate"
(dateChange)="onDateChanged($event)"> (dateChange)="onDateChanged($event)">
<mat-datetimepicker #datetimePicker <mat-datetimepicker #datetimePicker
[type]="property.type" [type]="property.type"
timeInterval="5" timeInterval="5"
[attr.data-automation-id]="'datepicker-' + property.key" [attr.data-automation-id]="'datepicker-' + property.key"
[startAt]="valueDate"> [startAt]="valueDate">
</mat-datetimepicker> </mat-datetimepicker>
</div> </div>
<ng-template #elseEmptyValueBlock> <ng-template #elseEmptyValueBlock>

View File

@@ -23,6 +23,7 @@ import { CardViewDateItemModel } from '../../models/card-view-dateitem.model';
import { CardViewUpdateService } from '../../services/card-view-update.service'; import { CardViewUpdateService } from '../../services/card-view-update.service';
import { CardViewDateItemComponent } from './card-view-dateitem.component'; import { CardViewDateItemComponent } from './card-view-dateitem.component';
import { CoreTestingModule } from '../../../testing/core.testing.module'; import { CoreTestingModule } from '../../../testing/core.testing.module';
import { ClipboardService } from '../../../clipboard/clipboard.service';
import { AppConfigService } from '@alfresco/adf-core'; import { AppConfigService } from '@alfresco/adf-core';
describe('CardViewDateItemComponent', () => { describe('CardViewDateItemComponent', () => {
@@ -219,6 +220,20 @@ describe('CardViewDateItemComponent', () => {
); );
})); }));
it('should copy value to clipboard on double click', () => {
const clipboardService = TestBed.get(ClipboardService);
spyOn(clipboardService, 'copyContentToClipboard');
component.editable = false;
fixture.detectChanges();
const doubleClickEl = fixture.debugElement.query(By.css(`[data-automation-id="card-dateitem-${component.property.key}"] span`));
doubleClickEl.triggerEventHandler('dblclick', new MouseEvent('dblclick'));
fixture.detectChanges();
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith('Jul 10, 2017', 'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
});
describe('clear icon', () => { describe('clear icon', () => {
it('should render the clear icon in case of displayClearAction:true', () => { it('should render the clear icon in case of displayClearAction:true', () => {
component.editable = true; component.editable = true;

View File

@@ -30,6 +30,8 @@ import { AppConfigService } from '../../../app-config/app-config.service';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { BaseCardView } from '../base-card-view'; import { BaseCardView } from '../base-card-view';
import { ClipboardService } from '../../../clipboard/clipboard.service';
import { TranslationService } from '../../../services/translation.service';
@Component({ @Component({
providers: [ providers: [
@@ -67,7 +69,9 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
constructor(cardViewUpdateService: CardViewUpdateService, constructor(cardViewUpdateService: CardViewUpdateService,
private dateAdapter: DateAdapter<Moment>, private dateAdapter: DateAdapter<Moment>,
private userPreferencesService: UserPreferencesService, private userPreferencesService: UserPreferencesService,
private appConfig: AppConfigService) { private appConfig: AppConfigService,
private clipboardService: ClipboardService,
private translateService: TranslationService) {
super(cardViewUpdateService); super(cardViewUpdateService);
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat'); this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
} }
@@ -127,4 +131,8 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
this.property.default = null; this.property.default = null;
} }
copyToClipboard(valueToCopy: string) {
const clipboardMessage = this.translateService.instant('CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
this.clipboardService.copyContentToClipboard(valueToCopy, clipboardMessage);
}
} }

View File

@@ -7,7 +7,11 @@
[attr.data-automation-id]="'card-textitem-value-' + property.key"> [attr.data-automation-id]="'card-textitem-value-' + property.key">
<span *ngIf="!isChipViewEnabled; else chipListTemplate"> <span *ngIf="!isChipViewEnabled; else chipListTemplate">
<span *ngIf="showProperty()" <span *ngIf="showProperty()"
[ngClass]="property.multiline?'adf-textitem-multiline':'adf-textitem-scroll'"> [ngClass]="property.multiline?'adf-textitem-multiline':'adf-textitem-scroll'"
(dblclick)="copyToClipboard(property.displayValue)"
class="adf-textitem-value"
matTooltipShowDelay="1000"
[matTooltip]="'CORE.METADATA.ACTIONS.COPY_TO_CLIPBOARD' | translate">
{{ property.displayValue }} {{ property.displayValue }}
</span> </span>
</span> </span>

View File

@@ -24,6 +24,7 @@ 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'; import { MatChipsModule } from '@angular/material';
import { ClipboardService } from '../../../clipboard/clipboard.service';
describe('CardViewTextItemComponent', () => { describe('CardViewTextItemComponent', () => {
@@ -328,6 +329,22 @@ describe('CardViewTextItemComponent', () => {
expect(component.property.value).toBe(expectedText); expect(component.property.value).toBe(expectedText);
}); });
it('should copy value to clipboard on double click', () => {
const clipboardService = TestBed.get(ClipboardService);
spyOn(clipboardService, 'copyContentToClipboard');
component.property.value = 'myValueToCopy';
component.property.icon = 'FAKE_ICON';
component.editable = false;
fixture.detectChanges();
const doubleClickEl = fixture.debugElement.query(By.css('span[class*="adf-textitem-value"]'));
doubleClickEl.triggerEventHandler('dblclick', new MouseEvent('dblclick'));
fixture.detectChanges();
expect(clipboardService.copyContentToClipboard).toHaveBeenCalledWith('myValueToCopy', 'CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
});
}); });
describe('Update', () => { describe('Update', () => {
@@ -495,7 +512,7 @@ describe('CardViewTextItemComponent', () => {
expect(textItemReadOnly.nativeElement.textContent).toEqual('Lorem ipsum'); expect(textItemReadOnly.nativeElement.textContent).toEqual('Lorem ipsum');
expect(component.property.value).toBe('Lorem ipsum'); expect(component.property.value).toBe('Lorem ipsum');
cardViewUpdateService.updateElement({ key: component.property.key, value: expectedText }); cardViewUpdateService.updateElement({ key: component.property.key, value: expectedText });
fixture.detectChanges(); fixture.detectChanges();
expect(textItemReadOnly.nativeElement.textContent).toEqual(expectedText); expect(textItemReadOnly.nativeElement.textContent).toEqual(expectedText);

View File

@@ -21,6 +21,8 @@ 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'; import { MatChipInputEvent } from '@angular/material';
import { ClipboardService } from '../../../clipboard/clipboard.service';
import { TranslationService } from '../../../services/translation.service';
@Component({ @Component({
selector: 'adf-card-view-textitem', selector: 'adf-card-view-textitem',
@@ -48,7 +50,9 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
useChipsForMultiValueProperty: boolean; useChipsForMultiValueProperty: boolean;
constructor(cardViewUpdateService: CardViewUpdateService, constructor(cardViewUpdateService: CardViewUpdateService,
private appConfig: AppConfigService) { private appConfig: AppConfigService,
private clipboardService: ClipboardService,
private translateService: TranslationService) {
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; this.useChipsForMultiValueProperty = this.appConfig.get<boolean>('content-metadata.multi-value-chips') || CardViewTextItemComponent.DEFAULT_USE_CHIPS;
@@ -166,6 +170,11 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
} }
} }
copyToClipboard(valueToCopy: string) {
const clipboardMessage = this.translateService.instant('CORE.METADATA.ACCESSIBILITY.COPY_TO_CLIPBOARD_MESSAGE');
this.clipboardService.copyContentToClipboard(valueToCopy, clipboardMessage);
}
get isChipViewEnabled(): boolean { get isChipViewEnabled(): boolean {
return this.property.multivalued && this.useChipsForMultiValueProperty; return this.property.multivalued && this.useChipsForMultiValueProperty;
} }

View File

@@ -198,11 +198,13 @@
"SAVE": "Save", "SAVE": "Save",
"CANCEL": "Cancel", "CANCEL": "Cancel",
"CLEAR": "Clear", "CLEAR": "Clear",
"TOGGLE": "Toggle value" "TOGGLE": "Toggle value",
"COPY_TO_CLIPBOARD": "Double click to copy value"
}, },
"ACCESSIBILITY": { "ACCESSIBILITY": {
"EDIT": "Edit button", "EDIT": "Edit button",
"DATEPICKER": "Use the arrow keys to navigate between dates. Up and down move to the next or previous week but on the same day. Left and right move to the next or previous day. Press Enter or Return to select a date." "DATEPICKER": "Use the arrow keys to navigate between dates. Up and down move to the next or previous week but on the same day. Left and right move to the next or previous day. Press Enter or Return to select a date.",
"COPY_TO_CLIPBOARD_MESSAGE": "Value copied to clipboard"
} }
}, },
"SEARCH": { "SEARCH": {