mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
[ADF-4496] Share dialog enhancements (#4705)
* raise snackbars on unshare errors * remove time from datepicker * update tests * Update en.json * code updates as per review * update docs * bind datetimepicker type attribute * set datetimepicker type by configuration or default * tests * e2e test * update docs * e2e set sharedLinkDateTimePickerType config
This commit is contained in:
parent
c3b1300d86
commit
99f4b07878
@ -67,3 +67,17 @@ and passes it to a [Viewer component](../../core/components/viewer.component.md)
|
||||
[allowGoBack]="false">
|
||||
</adf-viewer>
|
||||
```
|
||||
|
||||
## Date and time widget
|
||||
|
||||
Date and time widget for setting the expiration date can be configured to show only the date picker or both date and time piker.
|
||||
By default, the widget will show both date and time picker if `sharedLinkDateTimePickerType` is not present in the app.config.json.
|
||||
Possible values are `'date'` or `'datetime'`
|
||||
|
||||
```json
|
||||
{
|
||||
...
|
||||
"sharedLinkDateTimePickerType": 'date'
|
||||
...
|
||||
}
|
||||
```
|
||||
|
@ -27,6 +27,12 @@ Finds shared links to Content Services items.
|
||||
- _options:_ `any` - Options supported by JS-API
|
||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/development/src/api/content-rest-api/docs/NodePaging.md)`>` - List of shared links
|
||||
|
||||
### Events
|
||||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| error | `Subject<{ statusCode: number, message: string }>` | Gets emitted upon errors. |
|
||||
|
||||
## Details
|
||||
|
||||
Content Services allows users to generate URLs that can be shared with
|
||||
|
@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { LoginPage, BrowserActions } from '@alfresco/adf-testing';
|
||||
import { LoginPage, BrowserActions, LocalStorageUtil } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../pages/adf/contentServicesPage';
|
||||
import { NavigationBarPage } from '../../pages/adf/navigationBarPage';
|
||||
import { ViewerPage } from '../../pages/adf/viewerPage';
|
||||
@ -140,6 +140,22 @@ describe('Share file', () => {
|
||||
shareDialog.clickDateTimePickerButton();
|
||||
shareDialog.calendarTodayDayIsDisabled();
|
||||
});
|
||||
|
||||
it('[C310329] Should be possible to set expiry date only for link', async () => {
|
||||
await LocalStorageUtil.setConfigField('sharedLinkDateTimePickerType', JSON.stringify('date'));
|
||||
contentServicesPage.clickShareButton();
|
||||
shareDialog.checkDialogIsDisplayed();
|
||||
shareDialog.clickDateTimePickerButton();
|
||||
shareDialog.setDefaultDay();
|
||||
shareDialog.dateTimePickerDialogIsClosed();
|
||||
const value = await shareDialog.getExpirationDate();
|
||||
shareDialog.clickCloseButton();
|
||||
shareDialog.dialogIsClosed();
|
||||
contentServicesPage.clickShareButton();
|
||||
shareDialog.checkDialogIsDisplayed();
|
||||
shareDialog.expirationDateInputHasValue(value);
|
||||
BrowserActions.closeMenuAndDialogs();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Shared link preview', () => {
|
||||
|
@ -1,6 +1,5 @@
|
||||
<div class="adf-share-link__dialog-content">
|
||||
<h1 data-automation-id="adf-share-dialog-title"
|
||||
class="adf-share-link__title">
|
||||
<h1 data-automation-id="adf-share-dialog-title" class="adf-share-link__title">
|
||||
{{ 'SHARE.DIALOG-TITLE' | translate }} {{ fileName }}
|
||||
</h1>
|
||||
|
||||
@ -10,50 +9,47 @@
|
||||
<div class="adf-share-link--row">
|
||||
<h1 class="adf-share-link__label">{{ 'SHARE.TITLE' | translate }}</h1>
|
||||
|
||||
<mat-slide-toggle
|
||||
color="primary"
|
||||
data-automation-id="adf-share-toggle"
|
||||
[checked]="isFileShared"
|
||||
[disabled]="!canUpdate || isDisabled"
|
||||
(change)="onSlideShareChange($event)">
|
||||
<mat-slide-toggle color="primary" data-automation-id="adf-share-toggle" [checked]="isFileShared"
|
||||
[disabled]="!canUpdate || isDisabled" (change)="onSlideShareChange($event)">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<input #sharedLinkInput
|
||||
data-automation-id="adf-share-link"
|
||||
class="adf-share-link__input"
|
||||
matInput
|
||||
cdkFocusInitial
|
||||
placeholder="{{ 'SHARE.PUBLIC-LINK' | translate }}"
|
||||
formControlName="sharedUrl"
|
||||
<input #sharedLinkInput data-automation-id="adf-share-link" class="adf-share-link__input" matInput
|
||||
cdkFocusInitial placeholder="{{ 'SHARE.PUBLIC-LINK' | translate }}" formControlName="sharedUrl"
|
||||
readonly="readonly">
|
||||
<mat-icon class="adf-input-action" matSuffix
|
||||
[clipboard-notification]="'SHARE.CLIPBOARD-MESSAGE' | translate"
|
||||
[adf-clipboard] [target]="sharedLinkInput">
|
||||
link
|
||||
</mat-icon>
|
||||
<mat-icon class="adf-input-action" matSuffix
|
||||
[clipboard-notification]="'SHARE.CLIPBOARD-MESSAGE' | translate" [adf-clipboard]
|
||||
[target]="sharedLinkInput">
|
||||
link
|
||||
</mat-icon>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-share-link--row">
|
||||
<h1 class="adf-share-link__label">{{ 'SHARE.EXPIRES' | translate }}</h1>
|
||||
<mat-slide-toggle [disabled]="!canUpdate" #slideToggleExpirationDate color="primary"
|
||||
data-automation-id="adf-expire-toggle" [checked]="form.controls['time'].value"
|
||||
(change)="onToggleExpirationDate($event)">
|
||||
</mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-datetimepicker-toggle [for]="datetimePicker" matSuffix></mat-datetimepicker-toggle>
|
||||
<mat-datetimepicker #datetimePicker type="datetime" openOnFocus="true" timeInterval="1"></mat-datetimepicker>
|
||||
<mat-datetimepicker-toggle #matDatetimepickerToggle="matDatetimepickerToggle" [for]="datetimePicker" matSuffix></mat-datetimepicker-toggle>
|
||||
<mat-datetimepicker #datetimePicker (closed)="onDatetimepickerClosed()" [type]="type" openOnFocus="true" timeInterval="1"></mat-datetimepicker>
|
||||
<input class="adf-share-link__input"
|
||||
#dateTimePickerInput
|
||||
matInput
|
||||
[min]="minDate"
|
||||
formControlName="time"
|
||||
[matDatetimepicker]="datetimePicker">
|
||||
[matDatetimepicker]="datetimePicker" />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<div mat-dialog-actions>
|
||||
<button
|
||||
data-automation-id="adf-share-dialog-close"
|
||||
mat-button color="primary" mat-dialog-close>
|
||||
<button data-automation-id="adf-share-dialog-close" mat-button color="primary" mat-dialog-close>
|
||||
{{ 'SHARE.CLOSE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -16,17 +16,19 @@
|
||||
*/
|
||||
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TestBed, fakeAsync, async } from '@angular/core/testing';
|
||||
import { TestBed, fakeAsync, async, ComponentFixture } from '@angular/core/testing';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material';
|
||||
import { of, empty } from 'rxjs';
|
||||
import {
|
||||
setupTestBed,
|
||||
CoreModule,
|
||||
SharedLinksApiService,
|
||||
NodesApiService,
|
||||
NotificationService,
|
||||
RenditionsService
|
||||
RenditionsService,
|
||||
AppConfigService
|
||||
} from '@alfresco/adf-core';
|
||||
import { CoreTestingModule } from '../../core/testing/core.testing.module';
|
||||
import { AppConfigServiceMock } from '../../core/mock/app-config.service.mock';
|
||||
import { ContentNodeShareModule } from './content-node-share.module';
|
||||
import { ShareDialogComponent } from './content-node-share.dialog';
|
||||
import moment from 'moment-es6';
|
||||
@ -40,18 +42,20 @@ describe('ShareDialogComponent', () => {
|
||||
let sharedLinksApiService: SharedLinksApiService;
|
||||
let renditionService: RenditionsService;
|
||||
let nodesApiService: NodesApiService;
|
||||
let fixture;
|
||||
let component;
|
||||
let fixture: ComponentFixture<ShareDialogComponent>;
|
||||
let component: ShareDialogComponent;
|
||||
let appConfigService: AppConfigService;
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
CoreModule.forRoot(),
|
||||
CoreTestingModule,
|
||||
ContentNodeShareModule
|
||||
],
|
||||
providers: [
|
||||
NodesApiService,
|
||||
SharedLinksApiService,
|
||||
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||
{ provide: NotificationService, useValue: notificationServiceMock },
|
||||
{ provide: MatDialogRef, useValue: { close: () => {}} },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: {} }
|
||||
@ -64,10 +68,9 @@ describe('ShareDialogComponent', () => {
|
||||
sharedLinksApiService = TestBed.get(SharedLinksApiService);
|
||||
renditionService = TestBed.get(RenditionsService);
|
||||
nodesApiService = TestBed.get(NodesApiService);
|
||||
appConfigService = TestBed.get(AppConfigService);
|
||||
component = fixture.componentInstance;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
node = {
|
||||
entry: {
|
||||
id: 'nodeId',
|
||||
@ -78,6 +81,38 @@ describe('ShareDialogComponent', () => {
|
||||
};
|
||||
});
|
||||
|
||||
describe('Error Handling', () => {
|
||||
it('should emit a generic error when unshare fails', (done) => {
|
||||
spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(
|
||||
of(new Error(`{ "error": { "statusCode": 999 } }`))
|
||||
);
|
||||
|
||||
const sub = sharedLinksApiService.error.subscribe((err) => {
|
||||
expect(err.statusCode).toBe(999);
|
||||
expect(err.message).toBe('SHARE.UNSHARE_ERROR');
|
||||
sub.unsubscribe();
|
||||
done();
|
||||
});
|
||||
|
||||
component.deleteSharedLink('guid');
|
||||
});
|
||||
|
||||
it('should emit permission error when unshare fails', (done) => {
|
||||
spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(
|
||||
of(new Error(`{ "error": { "statusCode": 403 } }`))
|
||||
);
|
||||
|
||||
const sub = sharedLinksApiService.error.subscribe((err) => {
|
||||
expect(err.statusCode).toBe(403);
|
||||
expect(err.message).toBe('SHARE.UNSHARE_PERMISSION_ERROR');
|
||||
sub.unsubscribe();
|
||||
done();
|
||||
});
|
||||
|
||||
component.deleteSharedLink('guid');
|
||||
});
|
||||
});
|
||||
|
||||
it(`should toggle share action when property 'sharedId' does not exists`, () => {
|
||||
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(of({
|
||||
entry: { id: 'sharedId', sharedId: 'sharedId' }
|
||||
@ -196,21 +231,126 @@ describe('ShareDialogComponent', () => {
|
||||
expect(fixture.nativeElement.querySelector('mat-datetimepicker-toggle button').disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should not update shared node expiryDate property when value changes', () => {
|
||||
const date = moment();
|
||||
|
||||
it('should reset expiration date when toggle is unchecked', () => {
|
||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
spyOn(nodesApiService, 'updateNode');
|
||||
fixture.componentInstance.form.controls['time'].setValue(null);
|
||||
node.entry.properties['qshare:sharedId'] = '2017-04-15T18:31:37+00:00';
|
||||
node.entry.allowableOperations = ['update'];
|
||||
component.data = {
|
||||
node,
|
||||
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 expiration date action when node has no update permission', () => {
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
node.entry.allowableOperations = [];
|
||||
|
||||
component.data = {
|
||||
node,
|
||||
baseShareUrl: 'some-url/'
|
||||
};
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.nativeElement.querySelector('input[formcontrolname="time"]').disabled).toBe(true);
|
||||
expect(fixture.nativeElement.querySelector('.mat-slide-toggle[data-automation-id="adf-expire-toggle"]')
|
||||
.classList).toContain('mat-disabled');
|
||||
});
|
||||
|
||||
it('should update node expiration date with selected date', () => {
|
||||
const date = moment();
|
||||
node.entry.allowableOperations = ['update'];
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
||||
fixture.componentInstance.form.controls['time'].setValue(null);
|
||||
|
||||
component.data = {
|
||||
node,
|
||||
baseShareUrl: 'some-url/'
|
||||
};
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.nativeElement
|
||||
.querySelector(
|
||||
'mat-slide-toggle[data-automation-id="adf-expire-toggle"] label'
|
||||
)
|
||||
.dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
fixture.componentInstance.form.controls['time'].setValue(date);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(nodesApiService.updateNode).toHaveBeenCalled();
|
||||
expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', {
|
||||
properties: { 'qshare:expiryDate': date.utc().format() }
|
||||
});
|
||||
});
|
||||
|
||||
describe('datetimepicker type', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of({}));
|
||||
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(of({}));
|
||||
node.entry.allowableOperations = ['update'];
|
||||
component.data = {
|
||||
node,
|
||||
baseShareUrl: 'some-url/'
|
||||
};
|
||||
});
|
||||
|
||||
it('it should update node with input date and end of day time when type is `date`', () => {
|
||||
const dateTimePickerType = 'date';
|
||||
const date = moment('2525-01-01 13:00:00');
|
||||
spyOn(appConfigService, 'get').and.callFake(() => dateTimePickerType);
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.nativeElement.querySelector('mat-slide-toggle[data-automation-id="adf-expire-toggle"] label')
|
||||
.dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
fixture.componentInstance.form.controls['time'].setValue(date);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', {
|
||||
properties: { 'qshare:expiryDate': date.endOf('day').utc().format() }
|
||||
});
|
||||
});
|
||||
|
||||
it('it should update node with input date and time when type is `datetime`', () => {
|
||||
const dateTimePickerType = 'datetime';
|
||||
const date = moment('2525-01-01 13:00:00');
|
||||
spyOn(appConfigService, 'get').and.callFake(() => dateTimePickerType);
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.nativeElement.querySelector('mat-slide-toggle[data-automation-id="adf-expire-toggle"] label')
|
||||
.dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
fixture.componentInstance.form.controls['time'].setValue(date);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(nodesApiService.updateNode).toHaveBeenCalledWith('nodeId', {
|
||||
properties: { 'qshare:expiryDate': date.utc().format() }
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -21,18 +21,23 @@ import {
|
||||
OnInit,
|
||||
ViewEncapsulation,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog } from '@angular/material';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef, MatDialog, MatSlideToggleChange } from '@angular/material';
|
||||
import { FormGroup, FormControl } from '@angular/forms';
|
||||
import { Subscription, Observable } from 'rxjs';
|
||||
import { tap, skip } from 'rxjs/operators';
|
||||
import { Subscription, Observable, throwError } from 'rxjs';
|
||||
import {
|
||||
skip,
|
||||
distinctUntilChanged,
|
||||
mergeMap,
|
||||
catchError
|
||||
} from 'rxjs/operators';
|
||||
import {
|
||||
SharedLinksApiService,
|
||||
NodesApiService,
|
||||
ContentService,
|
||||
RenditionsService
|
||||
RenditionsService,
|
||||
AppConfigService
|
||||
} from '@alfresco/adf-core';
|
||||
import { SharedLinkEntry, Node } from '@alfresco/js-api';
|
||||
import { ConfirmDialogComponent } from '../dialogs/confirm.dialog';
|
||||
@ -42,7 +47,7 @@ import moment from 'moment-es6';
|
||||
selector: 'adf-share-dialog',
|
||||
templateUrl: './content-node-share.dialog.html',
|
||||
styleUrls: ['./content-node-share.dialog.scss'],
|
||||
host: { 'class': 'adf-share-dialog' },
|
||||
host: { class: 'adf-share-dialog' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
@ -55,34 +60,49 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
isFileShared: boolean = false;
|
||||
isDisabled: boolean = false;
|
||||
form: FormGroup = new FormGroup({
|
||||
'sharedUrl': new FormControl(''),
|
||||
'time': new FormControl({value: '', disabled: false})
|
||||
sharedUrl: new FormControl(''),
|
||||
time: new FormControl({ value: '', disabled: false })
|
||||
});
|
||||
type = 'datetime';
|
||||
|
||||
@ViewChild('sharedLinkInput') sharedLinkInput: ElementRef;
|
||||
@ViewChild('matDatetimepickerToggle')
|
||||
matDatetimepickerToggle;
|
||||
|
||||
@ViewChild('slideToggleExpirationDate')
|
||||
slideToggleExpirationDate;
|
||||
|
||||
@ViewChild('dateTimePickerInput')
|
||||
dateTimePickerInput;
|
||||
|
||||
constructor(
|
||||
private appConfigService: AppConfigService,
|
||||
private sharedLinksApiService: SharedLinksApiService,
|
||||
private dialogRef: MatDialogRef<ShareDialogComponent>,
|
||||
private dialog: MatDialog,
|
||||
private nodesApiService: NodesApiService,
|
||||
private contentService: ContentService,
|
||||
private renditionService: RenditionsService,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any) {
|
||||
}
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.type = this.appConfigService.get<string>('sharedLinkDateTimePickerType', 'datetime');
|
||||
|
||||
if (!this.canUpdate) {
|
||||
this.form.controls['time'].disable();
|
||||
}
|
||||
|
||||
this.subscriptions.push(
|
||||
this.form.valueChanges
|
||||
this.form.controls.time.valueChanges
|
||||
.pipe(
|
||||
skip(1),
|
||||
tap((updates) => {
|
||||
this.updateNode(updates);
|
||||
distinctUntilChanged(),
|
||||
mergeMap(
|
||||
(updates) => this.updateNode(updates),
|
||||
(formUpdates) => formUpdates
|
||||
),
|
||||
catchError((error) => {
|
||||
return throwError(error);
|
||||
})
|
||||
)
|
||||
.subscribe((updates) => this.updateEntryExpiryDate(updates))
|
||||
@ -94,9 +114,7 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
const properties = this.data.node.entry.properties;
|
||||
|
||||
if (properties && !properties['qshare:sharedId']) {
|
||||
|
||||
this.createSharedLinks(this.data.node.entry.id);
|
||||
|
||||
} else {
|
||||
this.sharedId = properties['qshare:sharedId'];
|
||||
this.isFileShared = true;
|
||||
@ -123,7 +141,27 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
get canUpdate() {
|
||||
return this.contentService.hasAllowableOperations(this.data.node.entry, 'update');
|
||||
return this.contentService.hasAllowableOperations(
|
||||
this.data.node.entry,
|
||||
'update'
|
||||
);
|
||||
}
|
||||
|
||||
onToggleExpirationDate(slideToggle: MatSlideToggleChange) {
|
||||
if (slideToggle.checked) {
|
||||
this.matDatetimepickerToggle.datetimepicker.open();
|
||||
} else {
|
||||
this.matDatetimepickerToggle.datetimepicker.close();
|
||||
this.form.controls.time.setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
onDatetimepickerClosed() {
|
||||
this.dateTimePickerInput.nativeElement.blur();
|
||||
|
||||
if (!this.form.controls.time.value) {
|
||||
this.slideToggleExpirationDate.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private openConfirmationDialog() {
|
||||
@ -140,7 +178,8 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
minWidth: '250px',
|
||||
closeOnNavigation: true
|
||||
})
|
||||
.beforeClose().subscribe((deleteSharedLink) => {
|
||||
.beforeClose()
|
||||
.subscribe((deleteSharedLink) => {
|
||||
if (deleteSharedLink) {
|
||||
this.deleteSharedLink(this.sharedId);
|
||||
} else {
|
||||
@ -152,15 +191,18 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
private createSharedLinks(nodeId: string) {
|
||||
this.isDisabled = true;
|
||||
|
||||
this.sharedLinksApiService.createSharedLinks(nodeId)
|
||||
.subscribe((sharedLink: SharedLinkEntry) => {
|
||||
|
||||
this.sharedLinksApiService.createSharedLinks(nodeId).subscribe(
|
||||
(sharedLink: SharedLinkEntry) => {
|
||||
if (sharedLink.entry) {
|
||||
this.sharedId = sharedLink.entry.id;
|
||||
this.data.node.entry.properties['qshare:sharedId'] = this.sharedId;
|
||||
this.data.node.entry.properties[
|
||||
'qshare:sharedId'
|
||||
] = this.sharedId;
|
||||
this.isDisabled = false;
|
||||
this.isFileShared = true;
|
||||
this.renditionService.generateRenditionForNode(this.data.node.entry.id).subscribe(() => {});
|
||||
this.renditionService
|
||||
.generateRenditionForNode(this.data.node.entry.id)
|
||||
.subscribe(() => {});
|
||||
|
||||
this.updateForm();
|
||||
}
|
||||
@ -168,21 +210,48 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
() => {
|
||||
this.isDisabled = false;
|
||||
this.isFileShared = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private deleteSharedLink(sharedId: string) {
|
||||
deleteSharedLink(sharedId: string) {
|
||||
this.isDisabled = true;
|
||||
|
||||
this.sharedLinksApiService.deleteSharedLink(sharedId).subscribe(() => {
|
||||
this.data.node.entry.properties['qshare:sharedId'] = null;
|
||||
this.data.node.entry.properties['qshare:expiryDate'] = null;
|
||||
this.dialogRef.close(false);
|
||||
this.sharedLinksApiService.deleteSharedLink(sharedId).subscribe(
|
||||
(response: any) => {
|
||||
if (response instanceof Error) {
|
||||
this.isDisabled = false;
|
||||
this.isFileShared = true;
|
||||
this.handleError(response);
|
||||
} else {
|
||||
this.data.node.entry.properties['qshare:sharedId'] = null;
|
||||
this.data.node.entry.properties['qshare:expiryDate'] = null;
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
this.isDisabled = false;
|
||||
this.isFileShared = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private handleError(error: Error) {
|
||||
let message = 'SHARE.UNSHARE_ERROR';
|
||||
let statusCode = 0;
|
||||
|
||||
try {
|
||||
statusCode = JSON.parse(error.message).error.statusCode;
|
||||
} catch {}
|
||||
|
||||
if (statusCode === 403) {
|
||||
message = 'SHARE.UNSHARE_PERMISSION_ERROR';
|
||||
}
|
||||
|
||||
this.sharedLinksApiService.error.next({
|
||||
statusCode,
|
||||
message
|
||||
});
|
||||
}
|
||||
|
||||
private updateForm() {
|
||||
@ -190,27 +259,26 @@ export class ShareDialogComponent implements OnInit, OnDestroy {
|
||||
const expiryDate = entry.properties['qshare:expiryDate'];
|
||||
|
||||
this.form.setValue({
|
||||
'sharedUrl': `${this.baseShareUrl}${this.sharedId}`,
|
||||
'time': expiryDate ? expiryDate : null
|
||||
sharedUrl: `${this.baseShareUrl}${this.sharedId}`,
|
||||
time: expiryDate ? moment(expiryDate).local() : null
|
||||
});
|
||||
}
|
||||
|
||||
private updateNode(updates): Observable<Node> {
|
||||
return this.nodesApiService.updateNode(
|
||||
this.data.node.entry.id,
|
||||
{
|
||||
properties: {
|
||||
'qshare:expiryDate': updates.time ? updates.time.utc().format() : null
|
||||
}
|
||||
private updateNode(date: moment.Moment): Observable<Node> {
|
||||
return this.nodesApiService.updateNode(this.data.node.entry.id, {
|
||||
properties: {
|
||||
'qshare:expiryDate': date ?
|
||||
(this.type === 'date' ? date.endOf('day').utc().format() : date.utc().format()) :
|
||||
null
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private updateEntryExpiryDate(updates) {
|
||||
private updateEntryExpiryDate(date: moment.Moment) {
|
||||
const { properties } = this.data.node.entry;
|
||||
|
||||
properties['qshare:expiryDate'] = updates.time
|
||||
? updates.time.local()
|
||||
properties['qshare:expiryDate'] = date
|
||||
? date.local()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "سيتم حذف هذا الرابط وسيتم إنشاء رابط جديد في المرة التالية التي يتم فيها مشاركة هذا الملف",
|
||||
"CANCEL": "إلغاء",
|
||||
"REMOVE": "إزالة"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "ليس لديك إذن لإلغاء مشاركة هذا الملف"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "تم تحديث خصائص المكتبة"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Tento odkaz se odstraní a při dalším sdílení tohoto souboru se vytvoří odkaz nový",
|
||||
"CANCEL": "Zrušit",
|
||||
"REMOVE": "Odstranit"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Nemáte potřebná oprávnění pro zrušení sdílení tohoto souboru"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Vlastnosti knihovny byly upraveny"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Dette link bliver slettet, og der oprettes et nyt link, når filen deles næste gang",
|
||||
"CANCEL": "Annuller",
|
||||
"REMOVE": "Fjern"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Du har ikke tilladelse til at ophæve delingen af denne fil"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Egenskaberne for biblioteket er blevet opdateret"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Dieser Link wird gelöscht und ein neuer Link wird erstellt wenn diese Datei das nächste Mal geteilt wird.",
|
||||
"CANCEL": "Abbrechen",
|
||||
"REMOVE": "Entfernen"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Sie verfügen nicht über die Berechtigung die Freigabe für diese Datei aufzuheben"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Bibliothekseigenschaften aktualisiert"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +297,9 @@
|
||||
"MESSAGE": "This link will be deleted and a new link will be created next time this file is shared",
|
||||
"CANCEL": "Cancel",
|
||||
"REMOVE": "Remove"
|
||||
}
|
||||
},
|
||||
"UNSHARE_ERROR": "Error unsharing this file",
|
||||
"UNSHARE_PERMISSION_ERROR": "You don't have permission to unshare this file"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Este enlace será eliminado. Se creará un enlace nuevo la próxima vez que comparta este fichero.",
|
||||
"CANCEL": "Cancelar",
|
||||
"REMOVE": "Eliminar"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "No tiene acceso para dejar de compartir este fichero"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Propiedades de la biblioteca actualizadas"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Tämä linkki poistetaan ja uusi linkki luodaan, kun tiedosto jaetaan seuraavan kerran",
|
||||
"CANCEL": "Peruuta",
|
||||
"REMOVE": "Poista"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Sinulla ei ole oikeuksia peruuttaa tämän tiedoston jakamista"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Kirjaston ominaisuudet päivitettiin"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Ce lien sera supprimé et un nouveau lien sera créé lors du prochain partage de ce fichier",
|
||||
"CANCEL": "Annuler",
|
||||
"REMOVE": "Supprimer"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Vous n'avez pas les droits d'accès pour ne pas partager ce fichier"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Les propriétés de la bibliothèque ont été mises à jour"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Il link verrà eliminato e verrà creato un nuovo link per il prossimo file condiviso",
|
||||
"CANCEL": "Annulla",
|
||||
"REMOVE": "Rimuovi"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Non hai il permesso per rimuovere la condivisione di questo file"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Proprietà della raccolta aggiornate"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "このリンクは削除され、次回このファイルを共有するときに新しいリンクが作成されます。",
|
||||
"CANCEL": "キャンセル",
|
||||
"REMOVE": "削除"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "このファイルの共有を解除する権限がありません。"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "ライブラリのプロパティが更新されました"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Denne koblingen vil bli slettet, og en ny kobling vil bli opprettet neste gang denne filen deles",
|
||||
"CANCEL": "Avbryt",
|
||||
"REMOVE": "Fjern"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Du har ikke tillatelse til å oppheve deling av denne filen"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Bibliotekegenskaper oppdatert"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Deze koppeling wordt verwijderd en er wordt een nieuwe koppeling gemaakt de volgende keer dat dit bestand wordt gedeeld",
|
||||
"CANCEL": "Annuleren",
|
||||
"REMOVE": "Verwijderen"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "U hebt geen rechten om het delen van dit bestand ongedaan te maken"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Bibliotheekeigenschappen bijgewerkt"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Ten link zostanie usunięty, a przy następnym udostępnieniu tego pliku zostanie utworzony nowy link.",
|
||||
"CANCEL": "Anuluj",
|
||||
"REMOVE": "Usuń"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Nie masz uprawnień, aby cofnąć udostępnianie tego pliku"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Zaktualizowano właściwości biblioteki"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Este link será excluído. Um novo link será criado na próxima vez que esse arquivo for compartilhado.",
|
||||
"CANCEL": "Cancelar",
|
||||
"REMOVE": "Remover"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Você não tem permissão para descompartilhar deste arquivo"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Propriedades da biblioteca atualizadas"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Эта ссылка будет удалена, и новая ссылка будет создана при следующем совместном использовании этого файла",
|
||||
"CANCEL": "Отмена",
|
||||
"REMOVE": "Удалить"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "У вас нет разрешения на снятие этого файла с публикации"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Свойства библиотеки обновлены"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "Den här länken kommer att raderas och en ny länk kommer att skapas nästa gång den här filen delas",
|
||||
"CANCEL": "Avbryt",
|
||||
"REMOVE": "Ta bort"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "Du har inte behörighet att sluta dela den här filen"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "Biblioteksegenskaper uppdaterade"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@
|
||||
"MESSAGE": "此链接将被删除,下次共享此文件时将会创建新链接",
|
||||
"CANCEL": "取消",
|
||||
"REMOVE": "删除"
|
||||
}
|
||||
},
|
||||
"UNSHARE_PERMISSION_ERROR": "你没有权限取消这个文件的共享"
|
||||
},
|
||||
"PERMISSION_MANAGER": {
|
||||
"PERMISSION_DISPLAY": {
|
||||
@ -363,4 +364,4 @@
|
||||
"LIBRARY_UPDATED": "已更新库属性"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { NodePaging, SharedLinkEntry } from '@alfresco/js-api';
|
||||
import { Observable, from, of } from 'rxjs';
|
||||
import { Observable, from, of, Subject } from 'rxjs';
|
||||
import { AlfrescoApiService } from './alfresco-api.service';
|
||||
import { UserPreferencesService } from './user-preferences.service';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
@ -27,6 +27,8 @@ import { catchError } from 'rxjs/operators';
|
||||
})
|
||||
export class SharedLinksApiService {
|
||||
|
||||
error = new Subject<{ statusCode: number, message: string }>();
|
||||
|
||||
constructor(private apiService: AlfrescoApiService,
|
||||
private preferences: UserPreferencesService) {
|
||||
}
|
||||
@ -73,11 +75,11 @@ export class SharedLinksApiService {
|
||||
* @param sharedId ID of the link to delete
|
||||
* @returns Null response notifying when the operation is complete
|
||||
*/
|
||||
deleteSharedLink(sharedId: string): Observable<SharedLinkEntry> {
|
||||
deleteSharedLink(sharedId: string): Observable<any | Error> {
|
||||
const promise = this.sharedLinksApi.deleteSharedLink(sharedId);
|
||||
|
||||
return from(promise).pipe(
|
||||
catchError((err) => of(err))
|
||||
catchError((err: Error) => of(err))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user