mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-31 17:38:28 +00:00
[ACA] Shared link expiration date update (#719)
* delete input field animation * refactor show hide date input * update date time input functonality on toggle * refactor tests * remove unsunsed method * update tests
This commit is contained in:
committed by
Denys Vuika
parent
c3ed743cd0
commit
84f8931eb4
@@ -1,53 +0,0 @@
|
|||||||
/*!
|
|
||||||
* @license
|
|
||||||
* Copyright 2016 Alfresco Software, Ltd.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {
|
|
||||||
state,
|
|
||||||
style,
|
|
||||||
transition,
|
|
||||||
animate,
|
|
||||||
sequence,
|
|
||||||
AnimationStateMetadata,
|
|
||||||
AnimationTransitionMetadata
|
|
||||||
} from '@angular/animations';
|
|
||||||
|
|
||||||
export const formFieldAnimation: (
|
|
||||||
| AnimationStateMetadata
|
|
||||||
| AnimationTransitionMetadata)[] = [
|
|
||||||
state(
|
|
||||||
'false',
|
|
||||||
style({
|
|
||||||
opacity: 0,
|
|
||||||
height: 0,
|
|
||||||
visibility: 'hidden'
|
|
||||||
})
|
|
||||||
),
|
|
||||||
transition(
|
|
||||||
'true => false',
|
|
||||||
sequence([
|
|
||||||
animate('200ms linear', style({ opacity: 0, height: 0 })),
|
|
||||||
animate('2ms', style({ visibility: 'hidden' }))
|
|
||||||
])
|
|
||||||
),
|
|
||||||
transition(
|
|
||||||
'false => true',
|
|
||||||
sequence([
|
|
||||||
animate('200ms linear', style({ opacity: 1, height: '*' })),
|
|
||||||
animate('200ms', style({ visibility: 'visible' }))
|
|
||||||
])
|
|
||||||
)
|
|
||||||
];
|
|
@@ -40,17 +40,25 @@
|
|||||||
<h1 class="adf-share-link__label">{{ 'SHARE.EXPIRES' | translate }}</h1>
|
<h1 class="adf-share-link__label">{{ 'SHARE.EXPIRES' | translate }}</h1>
|
||||||
<mat-slide-toggle
|
<mat-slide-toggle
|
||||||
[disabled]="!canUpdate"
|
[disabled]="!canUpdate"
|
||||||
#slideToggle
|
#slideToggleExpirationDate
|
||||||
color="primary"
|
color="primary"
|
||||||
data-automation-id="adf-expire-toggle"
|
data-automation-id="adf-expire-toggle"
|
||||||
[checked]="form.controls['time'].value"
|
[checked]="form.controls['time'].value"
|
||||||
(change)="removeExpirationDate()">
|
(change)="onToggleExpirationDate($event)">
|
||||||
</mat-slide-toggle>
|
</mat-slide-toggle>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-form-field class="full-width" [@visibilityChanged]="slideToggle.checked">
|
<mat-form-field class="full-width">
|
||||||
<mat-datetimepicker-toggle [for]="datetimePicker" matSuffix></mat-datetimepicker-toggle>
|
<mat-datetimepicker-toggle
|
||||||
<mat-datetimepicker #datetimePicker (closed)="blur(dateTimePickerInput)" type="datetime" openOnFocus="true" timeInterval="1"></mat-datetimepicker>
|
#matDatetimepickerToggle="matDatetimepickerToggle"
|
||||||
|
[for]="datetimePicker"
|
||||||
|
matSuffix>
|
||||||
|
</mat-datetimepicker-toggle>
|
||||||
|
<mat-datetimepicker #datetimePicker
|
||||||
|
(closed)="onDatetimepickerClosed()"
|
||||||
|
type="datetime" openOnFocus="true"
|
||||||
|
timeInterval="1">
|
||||||
|
</mat-datetimepicker>
|
||||||
<input class="adf-share-link__input"
|
<input class="adf-share-link__input"
|
||||||
#dateTimePickerInput
|
#dateTimePickerInput
|
||||||
matInput
|
matInput
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { TestBed, fakeAsync, async } from '@angular/core/testing';
|
import { TestBed, fakeAsync, async, tick } from '@angular/core/testing';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material';
|
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material';
|
||||||
import { of } from 'rxjs';
|
import { of } from 'rxjs';
|
||||||
import {
|
import {
|
||||||
@@ -79,7 +79,7 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.destroy();
|
fixture.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should toggle share action when property 'sharedId' does not exists`, () => {
|
it(`should toggle share action when property 'sharedId' does not exists`, fakeAsync(() => {
|
||||||
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(
|
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(
|
||||||
of({
|
of({
|
||||||
entry: { id: 'sharedId', sharedId: 'sharedId' }
|
entry: { id: 'sharedId', sharedId: 'sharedId' }
|
||||||
@@ -93,6 +93,7 @@ describe('ShareDialogComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
tick(500);
|
||||||
|
|
||||||
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled();
|
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
@@ -100,13 +101,14 @@ describe('ShareDialogComponent', () => {
|
|||||||
.value
|
.value
|
||||||
).toBe('some-url/sharedId');
|
).toBe('some-url/sharedId');
|
||||||
expect(
|
expect(
|
||||||
fixture.nativeElement.querySelector('.mat-slide-toggle').classList
|
fixture.nativeElement.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"'
|
||||||
|
).classList
|
||||||
).toContain('mat-checked');
|
).toContain('mat-checked');
|
||||||
});
|
}));
|
||||||
|
|
||||||
it(`should not toggle share action when file has 'sharedId' property`, () => {
|
it(`should not toggle share action when file has 'sharedId' property`, fakeAsync(() => {
|
||||||
spyOn(sharedLinksApiService, 'createSharedLinks');
|
spyOn(sharedLinksApiService, 'createSharedLinks');
|
||||||
|
|
||||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||||
|
|
||||||
component.data = {
|
component.data = {
|
||||||
@@ -116,6 +118,7 @@ describe('ShareDialogComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
tick(500);
|
||||||
|
|
||||||
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
|
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
|
||||||
expect(
|
expect(
|
||||||
@@ -123,9 +126,11 @@ describe('ShareDialogComponent', () => {
|
|||||||
.value
|
.value
|
||||||
).toBe('some-url/sharedId');
|
).toBe('some-url/sharedId');
|
||||||
expect(
|
expect(
|
||||||
fixture.nativeElement.querySelector('.mat-slide-toggle').classList
|
fixture.nativeElement.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"'
|
||||||
|
).classList
|
||||||
).toContain('mat-checked');
|
).toContain('mat-checked');
|
||||||
});
|
}));
|
||||||
|
|
||||||
it(`should copy shared link and notify on button event`, async(() => {
|
it(`should copy shared link and notify on button event`, async(() => {
|
||||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||||
@@ -169,7 +174,9 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.nativeElement
|
fixture.nativeElement
|
||||||
.querySelector('.mat-slide-toggle label')
|
.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"] label'
|
||||||
|
)
|
||||||
.dispatchEvent(new MouseEvent('click'));
|
.dispatchEvent(new MouseEvent('click'));
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -191,7 +198,9 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.nativeElement
|
fixture.nativeElement
|
||||||
.querySelector('.mat-slide-toggle label')
|
.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"] label'
|
||||||
|
)
|
||||||
.dispatchEvent(new MouseEvent('click'));
|
.dispatchEvent(new MouseEvent('click'));
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -213,7 +222,9 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.nativeElement
|
fixture.nativeElement
|
||||||
.querySelector('.mat-slide-toggle label')
|
.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"] label'
|
||||||
|
)
|
||||||
.dispatchEvent(new MouseEvent('click'));
|
.dispatchEvent(new MouseEvent('click'));
|
||||||
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -221,9 +232,42 @@ describe('ShareDialogComponent', () => {
|
|||||||
expect(sharedLinksApiService.deleteSharedLink).not.toHaveBeenCalled();
|
expect(sharedLinksApiService.deleteSharedLink).not.toHaveBeenCalled();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should reset expiration date when toggle is unchecked', () => {
|
||||||
|
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
||||||
|
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||||
|
node.entry.properties['qshare:sharedId'] = '2017-04-15T18:31:37+00:00';
|
||||||
|
|
||||||
|
component.data = {
|
||||||
|
node,
|
||||||
|
permission: true,
|
||||||
|
baseShareUrl: 'some-url/'
|
||||||
|
};
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
component.form.controls['time'].setValue(moment());
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
fixture.nativeElement
|
||||||
|
.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-expire-toggle"] label'
|
||||||
|
)
|
||||||
|
.dispatchEvent(new MouseEvent('click'));
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', {
|
||||||
|
properties: { 'qshare:expiryDate': null }
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(
|
||||||
|
fixture.nativeElement.querySelector('input[formcontrolname="time"]').value
|
||||||
|
).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
it('should not allow unshare when node has no update permission', () => {
|
it('should not allow unshare when node has no update permission', () => {
|
||||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||||
node.entry.allowableOperations = [];
|
|
||||||
|
|
||||||
component.data = {
|
component.data = {
|
||||||
node,
|
node,
|
||||||
@@ -234,22 +278,24 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
fixture.nativeElement.querySelector('.mat-slide-toggle').classList
|
fixture.nativeElement.querySelector(
|
||||||
|
'.mat-slide-toggle[data-automation-id="adf-share-toggle"'
|
||||||
|
).classList
|
||||||
).toContain('mat-disabled');
|
).toContain('mat-disabled');
|
||||||
expect(
|
expect(
|
||||||
fixture.nativeElement.querySelector('input[formcontrolname="time"]')
|
fixture.nativeElement.querySelector('input[formcontrolname="time"]')
|
||||||
.disabled
|
.disabled
|
||||||
).toBe(true);
|
).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
fixture.nativeElement.querySelector('mat-datetimepicker-toggle button')
|
fixture.nativeElement.querySelector(
|
||||||
.disabled
|
'.mat-slide-toggle[data-automation-id="adf-expire-toggle"]'
|
||||||
).toBe(true);
|
).classList
|
||||||
|
).toContain('mat-disabled');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update node expiration date with selected date and time', () => {
|
it('should update node expiration date with selected date and time', () => {
|
||||||
const date = moment();
|
const date = moment();
|
||||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||||
node.entry.allowableOperations = [];
|
|
||||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
||||||
fixture.componentInstance.form.controls['time'].setValue(null);
|
fixture.componentInstance.form.controls['time'].setValue(null);
|
||||||
|
|
||||||
@@ -262,7 +308,9 @@ describe('ShareDialogComponent', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
fixture.nativeElement
|
fixture.nativeElement
|
||||||
.querySelector('mat-slide-toggle[data-automation-id="adf-expire-toggle"]')
|
.querySelector(
|
||||||
|
'mat-slide-toggle[data-automation-id="adf-expire-toggle"] label'
|
||||||
|
)
|
||||||
.dispatchEvent(new MouseEvent('click'));
|
.dispatchEvent(new MouseEvent('click'));
|
||||||
|
|
||||||
fixture.componentInstance.form.controls['time'].setValue(date);
|
fixture.componentInstance.form.controls['time'].setValue(date);
|
||||||
|
@@ -21,7 +21,6 @@ import {
|
|||||||
OnInit,
|
OnInit,
|
||||||
ViewEncapsulation,
|
ViewEncapsulation,
|
||||||
ViewChild,
|
ViewChild,
|
||||||
ElementRef,
|
|
||||||
OnDestroy
|
OnDestroy
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material';
|
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material';
|
||||||
@@ -33,8 +32,6 @@ import {
|
|||||||
catchError,
|
catchError,
|
||||||
distinctUntilChanged
|
distinctUntilChanged
|
||||||
} from 'rxjs/operators';
|
} from 'rxjs/operators';
|
||||||
import { trigger } from '@angular/animations';
|
|
||||||
import { formFieldAnimation } from './animation';
|
|
||||||
import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core';
|
import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core';
|
||||||
import { SharedLinkEntry, MinimalNodeEntryEntity } from 'alfresco-js-api';
|
import { SharedLinkEntry, MinimalNodeEntryEntity } from 'alfresco-js-api';
|
||||||
import { ConfirmDialogComponent } from '@alfresco/adf-content-services';
|
import { ConfirmDialogComponent } from '@alfresco/adf-content-services';
|
||||||
@@ -45,8 +42,7 @@ import moment from 'moment-es6';
|
|||||||
templateUrl: './content-node-share.dialog.html',
|
templateUrl: './content-node-share.dialog.html',
|
||||||
styleUrls: ['./content-node-share.dialog.scss'],
|
styleUrls: ['./content-node-share.dialog.scss'],
|
||||||
host: { class: 'adf-share-dialog' },
|
host: { class: 'adf-share-dialog' },
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None
|
||||||
animations: [trigger('visibilityChanged', formFieldAnimation)]
|
|
||||||
})
|
})
|
||||||
export class ShareDialogComponent implements OnInit, OnDestroy {
|
export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||||
private subscriptions: Subscription[] = [];
|
private subscriptions: Subscription[] = [];
|
||||||
@@ -62,8 +58,14 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
|||||||
time: new FormControl({ value: '', disabled: false })
|
time: new FormControl({ value: '', disabled: false })
|
||||||
});
|
});
|
||||||
|
|
||||||
@ViewChild('sharedLinkInput')
|
@ViewChild('matDatetimepickerToggle')
|
||||||
sharedLinkInput: ElementRef;
|
matDatetimepickerToggle;
|
||||||
|
|
||||||
|
@ViewChild('slideToggleExpirationDate')
|
||||||
|
slideToggleExpirationDate;
|
||||||
|
|
||||||
|
@ViewChild('dateTimePickerInput')
|
||||||
|
dateTimePickerInput;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sharedLinksApiService: SharedLinksApiService,
|
private sharedLinksApiService: SharedLinksApiService,
|
||||||
@@ -116,10 +118,6 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
|||||||
this.subscriptions.forEach(subscription => subscription.unsubscribe);
|
this.subscriptions.forEach(subscription => subscription.unsubscribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeShare() {
|
|
||||||
this.deleteSharedLink(this.sharedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSlideShareChange() {
|
onSlideShareChange() {
|
||||||
this.openConfirmationDialog();
|
this.openConfirmationDialog();
|
||||||
}
|
}
|
||||||
@@ -128,12 +126,21 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
|||||||
return this.data.permission;
|
return this.data.permission;
|
||||||
}
|
}
|
||||||
|
|
||||||
removeExpirationDate() {
|
onToggleExpirationDate(slideToggle) {
|
||||||
this.form.controls.time.setValue(null);
|
if (slideToggle.checked) {
|
||||||
|
this.matDatetimepickerToggle.datetimepicker.open();
|
||||||
|
} else {
|
||||||
|
this.matDatetimepickerToggle.datetimepicker.close();
|
||||||
|
this.form.controls.time.setValue(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blur(input: HTMLInputElement) {
|
onDatetimepickerClosed() {
|
||||||
input.blur();
|
this.dateTimePickerInput.nativeElement.blur();
|
||||||
|
|
||||||
|
if (!this.form.controls.time.value) {
|
||||||
|
this.slideToggleExpirationDate.checked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private openConfirmationDialog() {
|
private openConfirmationDialog() {
|
||||||
|
Reference in New Issue
Block a user