From 36043d1473a65b6ef9601757a032a44e6c6cff68 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 14 Jun 2019 12:59:09 +0100 Subject: [PATCH] [ACA-2182] ADF 3.3.0 alpha (#1126) * upgrade to latest adf 3.0.0 alpha * use ADF share dialog * [ACA-2069] make sure toggles have the right color * raise error popups for shared links * update test * use date only for sharing * [ACA-2069] small improvement - make sure toggles have the right color * remove old share dialog * move toggle-shared component to common module --- package-lock.json | 59 ++- package.json | 6 +- src/app.config.json | 1 + src/app/app.component.spec.ts | 1 + src/app/app.component.ts | 12 +- src/app/app.module.ts | 2 - src/app/components/common/common.module.ts | 12 +- .../toggle-shared.component.html | 0 .../toggle-shared.component.spec.ts | 0 .../toggle-shared/toggle-shared.component.ts | 0 .../content-node-share.dialog.html | 92 ----- .../content-node-share.dialog.scss | 64 ---- .../content-node-share.dialog.spec.ts | 350 ------------------ .../content-node-share.dialog.ts | 255 ------------- .../content-node-share.module.ts | 41 -- src/app/components/shared/shared.module.ts | 44 --- .../toggle-shared/toggle-shared.module.ts | 48 --- src/app/extensions/core.extensions.module.ts | 2 +- .../services/content-management.service.ts | 5 +- src/app/ui/theme.scss | 12 + 20 files changed, 78 insertions(+), 928 deletions(-) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.html (100%) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.spec.ts (100%) rename src/app/components/{shared => common}/toggle-shared/toggle-shared.component.ts (100%) delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.html delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.scss delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts delete mode 100644 src/app/components/shared/content-node-share/content-node-share.dialog.ts delete mode 100644 src/app/components/shared/content-node-share/content-node-share.module.ts delete mode 100644 src/app/components/shared/shared.module.ts delete mode 100644 src/app/components/shared/toggle-shared/toggle-shared.module.ts diff --git a/package-lock.json b/package-lock.json index a92e48b4d..d9f90e222 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,25 +5,25 @@ "requires": true, "dependencies": { "@alfresco/adf-content-services": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-QPbvSfCG/rOLVcwzAw2IWDrGe8fgzK209zgQwgOiGzmHhtY2Ru3GF2in+rlG+VK/qZvErv9x6nT0BVEmlc2SoQ==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-content-services/-/adf-content-services-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-2Y2VPvSxXxlhBJoKLQo9NGy0r9paAnAweXIi9EiuZctLNFDAzG2UVDb93gGhtcAi+ulH5xyoRu/9mDIpE4e5ew==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-core": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-BMqpwOyBAXKL9atGa4oNM+8KsQ/twiFiSJFTvi0tKbd+EhxaKINMv9/smnIE1D54hGzBHca/dBua4kT1FWbQwg==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-core/-/adf-core-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-mEL+/0udJ1R4vnb8UK6QsdLRd/PPMo1q1esTYUAu0in0TR6PesqBiTMAtmj5sVV40IIeW7u7kD/TpZNBRDlxrg==", "requires": { "tslib": "^1.9.0" } }, "@alfresco/adf-extensions": { - "version": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203.tgz", - "integrity": "sha512-iEABQcxgUxlh7/qhbUprgL+zxLue/NSPIAs5rxuBAsGbPusIPh15cvJmo1YUnm0cbjxLs5CMUGurenfeh7afEQ==", + "version": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "resolved": "https://registry.npmjs.org/@alfresco/adf-extensions/-/adf-extensions-3.3.0-626bb01bf7d26e693a4947982d20695c45794503.tgz", + "integrity": "sha512-qh2xdGTeNBvh7QzScvaYxHxvoTld5bCwDRIUKNj+Dt+C3aaAs5mdN85hTVQ82+vNptD8NO9nCBaS/CR5ISwt9Q==", "requires": { "tslib": "^1.9.0" } @@ -5113,7 +5113,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -5134,12 +5135,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5154,17 +5157,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -5281,7 +5287,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5293,6 +5300,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5307,6 +5315,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5314,12 +5323,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5338,6 +5349,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -5418,7 +5430,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5430,6 +5443,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -5515,7 +5529,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5551,6 +5566,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5570,6 +5586,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5613,12 +5630,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index b71d9a13c..309acd06e 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,9 @@ }, "private": true, "dependencies": { - "@alfresco/adf-content-services": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "@alfresco/adf-core": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", - "@alfresco/adf-extensions": "3.3.0-8a2a71d60be3f2b3dd0173f6a51d8075241e7203", + "@alfresco/adf-content-services": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "@alfresco/adf-core": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", + "@alfresco/adf-extensions": "3.3.0-626bb01bf7d26e693a4947982d20695c45794503", "@alfresco/js-api": "3.2.1", "@angular/animations": "7.2.15", "@angular/cdk": "^7.3.7", diff --git a/src/app.config.json b/src/app.config.json index 9b7937934..e82941ab9 100644 --- a/src/app.config.json +++ b/src/app.config.json @@ -20,6 +20,7 @@ "logo": "assets/images/alfresco-logo-flower.svg", "copyright": "APP.COPYRIGHT" }, + "sharedLinkDateTimePickerType": "date", "headerColor": "#2196F3", "languagePicker": true, "pagination": { diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index b5c55f0bc..11c2e77d7 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -54,6 +54,7 @@ describe('AppComponent', () => { null, null, null, + null, null ); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0295f2702..4f7ead6dd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -29,7 +29,8 @@ import { AuthenticationService, FileUploadErrorEvent, PageTitleService, - UploadService + UploadService, + SharedLinksApiService } from '@alfresco/adf-core'; import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; @@ -70,7 +71,8 @@ export class AppComponent implements OnInit, OnDestroy { private uploadService: UploadService, private extensions: AppExtensionService, private contentApi: ContentApiService, - private appService: AppService + private appService: AppService, + private sharedLinksApiService: SharedLinksApiService ) {} ngOnInit() { @@ -120,6 +122,12 @@ export class AppComponent implements OnInit, OnDestroy { this.onFileUploadedError(error) ); + this.sharedLinksApiService.error + .pipe(takeUntil(this.onDestroy$)) + .subscribe((err: { message: string }) => { + this.store.dispatch(new SnackbarErrorAction(err.message)); + }); + this.appService.ready$ .pipe(takeUntil(this.onDestroy$)) .subscribe(isReady => { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index d74c50003..9ef973b2b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -61,7 +61,6 @@ import { DirectivesModule } from './directives/directives.module'; import { ContextMenuModule } from './components/context-menu/context-menu.module'; import { ExtensionsModule } from '@alfresco/adf-extensions'; import { AppToolbarModule } from './components/toolbar/toolbar.module'; -import { AppSharedModule } from './components/shared/shared.module'; import { AppCreateMenuModule } from './components/create-menu/create-menu.module'; import { AppSidenavModule } from './components/sidenav/sidenav.module'; import { AppPermissionsModule } from './components/permissions/permissions.module'; @@ -102,7 +101,6 @@ import { environment } from '../environments/environment'; ContextMenuModule, AppInfoDrawerModule, AppToolbarModule, - AppSharedModule, AppSidenavModule, AppCreateMenuModule, DocumentListCustomComponentsModule, diff --git a/src/app/components/common/common.module.ts b/src/app/components/common/common.module.ts index fbda679d4..17ac4f12f 100644 --- a/src/app/components/common/common.module.ts +++ b/src/app/components/common/common.module.ts @@ -29,6 +29,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { GenericErrorModule } from '@alfresco/aca-shared'; import { LocationLinkComponent } from './location-link/location-link.component'; +import { ToggleSharedComponent } from './toggle-shared/toggle-shared.component'; @NgModule({ imports: [ @@ -37,8 +38,13 @@ import { LocationLinkComponent } from './location-link/location-link.component'; ExtensionsModule, GenericErrorModule ], - declarations: [LocationLinkComponent], - exports: [ExtensionsModule, LocationLinkComponent, GenericErrorModule], - entryComponents: [LocationLinkComponent] + declarations: [LocationLinkComponent, ToggleSharedComponent], + exports: [ + ExtensionsModule, + LocationLinkComponent, + GenericErrorModule, + ToggleSharedComponent + ], + entryComponents: [LocationLinkComponent, ToggleSharedComponent] }) export class AppCommonModule {} diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.html b/src/app/components/common/toggle-shared/toggle-shared.component.html similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.html rename to src/app/components/common/toggle-shared/toggle-shared.component.html diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.spec.ts b/src/app/components/common/toggle-shared/toggle-shared.component.spec.ts similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.spec.ts rename to src/app/components/common/toggle-shared/toggle-shared.component.spec.ts diff --git a/src/app/components/shared/toggle-shared/toggle-shared.component.ts b/src/app/components/common/toggle-shared/toggle-shared.component.ts similarity index 100% rename from src/app/components/shared/toggle-shared/toggle-shared.component.ts rename to src/app/components/common/toggle-shared/toggle-shared.component.ts diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.html b/src/app/components/shared/content-node-share/content-node-share.dialog.html deleted file mode 100644 index ffa3138e3..000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.html +++ /dev/null @@ -1,92 +0,0 @@ - diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.scss b/src/app/components/shared/content-node-share/content-node-share.dialog.scss deleted file mode 100644 index cfd380f8c..000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.scss +++ /dev/null @@ -1,64 +0,0 @@ -@mixin adf-share-link-typography { - letter-spacing: -0.4px; - line-height: 2; - font-weight: normal; - font-style: normal; - font-stretch: normal; - font-size: 16px; - opacity: 0.87; -} - -.adf-share-link-dialog { - .adf-share-link { - &__dialog-content { - display: flex; - flex-direction: column; - } - - &__label { - @include adf-share-link-typography; - flex: 1 1 auto; - } - - &__title { - @include adf-share-link-typography; - } - - &__info { - @include adf-share-link-typography; - opacity: 0.54; - font-size: 13px; - } - - &--row { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - } - - &__input { - opacity: 0.54; - } - } - - .adf-input-action { - cursor: pointer; - } - - .mat-form-field-infix { - border-top: unset; - } - - .mat-dialog-actions { - justify-content: flex-end; - - & > button { - text-transform: uppercase; - } - } - - .mat-form-field-flex { - align-items: center; - } -} diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts deleted file mode 100644 index 3f3a3af58..000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.spec.ts +++ /dev/null @@ -1,350 +0,0 @@ -/*! - * @license - * Copyright 2019 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 { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { TestBed, fakeAsync, async, tick } from '@angular/core/testing'; -import { - MatDialogRef, - MAT_DIALOG_DATA, - MatDialog -} from '@angular/material/dialog'; -import { of } from 'rxjs'; -import { - setupTestBed, - CoreModule, - SharedLinksApiService, - NodesApiService, - NotificationService -} from '@alfresco/adf-core'; -import { ContentNodeShareModule } from './content-node-share.module'; -import { ShareDialogComponent } from './content-node-share.dialog'; -import * as moment from 'moment'; -import { Store } from '@ngrx/store'; - -describe('ShareDialogComponent', () => { - let node; - let matDialog: MatDialog; - const notificationServiceMock = { - openSnackMessage: jasmine.createSpy('openSnackMessage') - }; - let sharedLinksApiService: SharedLinksApiService; - let nodesApiService: NodesApiService; - let fixture; - let component; - const storeMock = { - dispatch: jasmine.createSpy('dispatch') - }; - - setupTestBed({ - imports: [ - NoopAnimationsModule, - CoreModule.forRoot(), - ContentNodeShareModule - ], - providers: [ - NodesApiService, - SharedLinksApiService, - { provide: Store, useValue: storeMock }, - { provide: NotificationService, useValue: notificationServiceMock }, - { provide: MatDialogRef, useValue: {} }, - { provide: MAT_DIALOG_DATA, useValue: {} } - ] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(ShareDialogComponent); - matDialog = TestBed.get(MatDialog); - sharedLinksApiService = TestBed.get(SharedLinksApiService); - nodesApiService = TestBed.get(NodesApiService); - component = fixture.componentInstance; - }); - - beforeEach(() => { - node = { - entry: { - id: 'nodeId', - allowableOperations: ['update'], - isFile: true, - properties: {} - } - }; - }); - - afterEach(() => { - fixture.destroy(); - }); - - it(`should toggle share action when property 'sharedId' does not exists`, fakeAsync(() => { - spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue( - of({ - entry: { id: 'sharedId', sharedId: 'sharedId' } - }) - ); - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - tick(500); - - expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled(); - expect( - fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]') - .value - ).toBe('some-url/sharedId'); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"' - ).classList - ).toContain('mat-checked'); - })); - - it(`should not toggle share action when file has 'sharedId' property`, fakeAsync(() => { - spyOn(sharedLinksApiService, 'createSharedLinks'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - tick(500); - - expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled(); - expect( - fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]') - .value - ).toBe('some-url/sharedId'); - expect( - fixture.nativeElement.querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"' - ).classList - ).toContain('mat-checked'); - })); - - xit(`should copy shared link and notify on button event`, async(() => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(document, 'execCommand').and.callThrough(); - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.whenStable().then(() => { - fixture.detectChanges(); - - fixture.nativeElement - .querySelector('.adf-input-action') - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(document.execCommand).toHaveBeenCalledWith('copy'); - expect(notificationServiceMock.openSnackMessage).toHaveBeenCalledWith( - 'SHARE.CLIPBOARD-MESSAGE' - ); - }); - })); - - it('should open a confirmation dialog when unshare button is triggered', () => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(false) }); - spyOn(sharedLinksApiService, 'deleteSharedLink'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(matDialog.open).toHaveBeenCalled(); - }); - - it('should unshare file when confirmation dialog returns true', fakeAsync(() => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(true) }); - spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(of(null)); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled(); - })); - - it('should not unshare file when confirmation dialog returns false', fakeAsync(() => { - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(false) }); - spyOn(sharedLinksApiService, 'deleteSharedLink'); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: true, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - fixture.detectChanges(); - - 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 expiration date action when node has no update permission', () => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - - component.data = { - node, - permission: false, - 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 show permission error notification on un-share action', () => { - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(matDialog, 'open').and.returnValue({ beforeClose: () => of(true) }); - spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue( - of(new Error('{"error": { "statusCode": 403 } }')) - ); - component.data = { - node, - permission: false, - baseShareUrl: 'some-url/' - }; - - fixture.detectChanges(); - - fixture.nativeElement - .querySelector( - '.mat-slide-toggle[data-automation-id="adf-share-toggle"] label' - ) - .dispatchEvent(new MouseEvent('click')); - - expect(storeMock.dispatch).toHaveBeenCalled(); - }); - - it('should update node expiration date with selected date and time', () => { - const date = moment(); - node.entry.properties['qshare:sharedId'] = 'sharedId'; - spyOn(nodesApiService, 'updateNode').and.returnValue(of({})); - fixture.componentInstance.form.controls['time'].setValue(null); - - component.data = { - node, - permission: true, - 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).toHaveBeenCalledWith('nodeId', { - properties: { 'qshare:expiryDate': date } - }); - }); -}); diff --git a/src/app/components/shared/content-node-share/content-node-share.dialog.ts b/src/app/components/shared/content-node-share/content-node-share.dialog.ts deleted file mode 100644 index 43455dfa2..000000000 --- a/src/app/components/shared/content-node-share/content-node-share.dialog.ts +++ /dev/null @@ -1,255 +0,0 @@ -/*! - * @license - * Copyright 2019 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 { - Component, - Inject, - OnInit, - ViewEncapsulation, - ViewChild, - OnDestroy -} from '@angular/core'; -import { - MAT_DIALOG_DATA, - MatDialogRef, - MatDialog -} from '@angular/material/dialog'; -import { FormGroup, FormControl } from '@angular/forms'; -import { Subscription, Observable, throwError } from 'rxjs'; -import { AppStore, SnackbarErrorAction } from '@alfresco/aca-shared/store'; -import { Store } from '@ngrx/store'; -import { - skip, - mergeMap, - catchError, - distinctUntilChanged -} from 'rxjs/operators'; -import { SharedLinksApiService, NodesApiService } from '@alfresco/adf-core'; -import { SharedLinkEntry, MinimalNodeEntryEntity } from '@alfresco/js-api'; -import { ConfirmDialogComponent } from '@alfresco/adf-content-services'; -import * as moment from 'moment'; - -@Component({ - selector: 'aca-share-dialog', - templateUrl: './content-node-share.dialog.html', - styleUrls: ['./content-node-share.dialog.scss'], - host: { class: 'adf-share-dialog' }, - encapsulation: ViewEncapsulation.None -}) -export class ShareDialogComponent implements OnInit, OnDestroy { - private subscriptions: Subscription[] = []; - - minDate = moment().add(1, 'd'); - sharedId: string; - fileName: string; - baseShareUrl: string; - isFileShared = false; - isDisabled = false; - form: FormGroup = new FormGroup({ - sharedUrl: new FormControl(''), - time: new FormControl({ value: '', disabled: false }) - }); - - @ViewChild('matDatetimepickerToggle') - matDatetimepickerToggle; - - @ViewChild('slideToggleExpirationDate') - slideToggleExpirationDate; - - @ViewChild('dateTimePickerInput') - dateTimePickerInput; - - constructor( - private sharedLinksApiService: SharedLinksApiService, - private dialogRef: MatDialogRef, - private dialog: MatDialog, - private nodesApiService: NodesApiService, - private store: Store, - @Inject(MAT_DIALOG_DATA) public data: any - ) {} - - ngOnInit() { - if (!this.canUpdate) { - this.form.controls['time'].disable(); - } - - this.subscriptions.push( - this.form.controls.time.valueChanges - .pipe( - skip(1), - distinctUntilChanged(), - mergeMap( - updates => this.updateNode(updates), - formUpdates => formUpdates - ), - catchError(error => { - return throwError(error); - }) - ) - .subscribe(updates => { - this.updateEntryExpiryDate(updates); - }) - ); - - if (this.data.node && this.data.node.entry) { - this.fileName = this.data.node.entry.name; - this.baseShareUrl = this.data.baseShareUrl; - 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; - - this.updateForm(); - } - } - } - - ngOnDestroy() { - this.subscriptions.forEach(subscription => subscription.unsubscribe); - } - - onSlideShareChange() { - this.openConfirmationDialog(); - } - - get canUpdate() { - return this.data.permission; - } - - onToggleExpirationDate(slideToggle) { - 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() { - this.isFileShared = false; - - this.dialog - .open(ConfirmDialogComponent, { - data: { - title: 'SHARE.CONFIRMATION.DIALOG-TITLE', - message: 'SHARE.CONFIRMATION.MESSAGE', - yesLabel: 'SHARE.CONFIRMATION.REMOVE', - noLabel: 'SHARE.CONFIRMATION.CANCEL' - }, - minWidth: '250px', - closeOnNavigation: true - }) - .beforeClose() - .subscribe(deleteSharedLink => { - if (deleteSharedLink) { - this.deleteSharedLink(this.sharedId); - } else { - this.isFileShared = true; - } - }); - } - - private createSharedLinks(nodeId: string) { - this.isDisabled = true; - - this.sharedLinksApiService.createSharedLinks(nodeId).subscribe( - (sharedLink: SharedLinkEntry) => { - if (sharedLink.entry) { - this.sharedId = sharedLink.entry.id; - if (this.data.node.entry.properties) { - this.data.node.entry.properties['qshare:sharedId'] = this.sharedId; - } else { - this.data.node.entry.properties = { - 'qshare:sharedId': this.sharedId - }; - } - this.isDisabled = false; - this.isFileShared = true; - - this.updateForm(); - } - }, - () => { - this.isDisabled = false; - this.isFileShared = false; - } - ); - } - - private deleteSharedLink(sharedId: string) { - this.isDisabled = true; - - this.sharedLinksApiService - .deleteSharedLink(sharedId) - .subscribe((response: any) => { - if (response instanceof Error) { - this.isDisabled = false; - this.isFileShared = true; - this.showError(response); - } else { - this.data.node.entry.properties['qshare:sharedId'] = null; - this.data.node.entry.properties['qshare:expiryDate'] = null; - this.dialogRef.close(this.data.node); - } - }); - } - - private updateForm() { - const { entry } = this.data.node; - const expiryDate = entry.properties['qshare:expiryDate']; - - this.form.setValue({ - sharedUrl: `${this.baseShareUrl}${this.sharedId}`, - time: expiryDate ? expiryDate : null - }); - } - - private updateNode(date: moment.Moment): Observable { - return this.nodesApiService.updateNode(this.data.node.entry.id, { - properties: { - 'qshare:expiryDate': date ? date.endOf('day') : null - } - }); - } - - private updateEntryExpiryDate(date: moment.Moment) { - const { properties } = this.data.node.entry; - - properties['qshare:expiryDate'] = date ? date.toDate() : null; - } - - private showError(response: { message: any }) { - let message; - const statusCode = JSON.parse(response.message).error.statusCode; - if (statusCode === 403) { - message = 'SHARED_LINK.UNSHARE_PERMISSION_ERROR'; - } - - this.store.dispatch(new SnackbarErrorAction(message)); - } -} diff --git a/src/app/components/shared/content-node-share/content-node-share.module.ts b/src/app/components/shared/content-node-share/content-node-share.module.ts deleted file mode 100644 index eef58ca1a..000000000 --- a/src/app/components/shared/content-node-share/content-node-share.module.ts +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * @license - * Copyright 2019 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 { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ShareDialogComponent } from './content-node-share.dialog'; - -@NgModule({ - imports: [CoreModule.forChild(), CommonModule], - declarations: [ShareDialogComponent], - exports: [ShareDialogComponent], - entryComponents: [ShareDialogComponent] -}) -export class ContentNodeShareModule { - static forRoot(): ModuleWithProviders { - return { - ngModule: ContentNodeShareModule - }; - } - - static forChild(): ModuleWithProviders { - return { - ngModule: ContentNodeShareModule - }; - } -} diff --git a/src/app/components/shared/shared.module.ts b/src/app/components/shared/shared.module.ts deleted file mode 100644 index 06139e7ac..000000000 --- a/src/app/components/shared/shared.module.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ExtensionsModule } from '@alfresco/adf-extensions'; -import { ToggleSharedModule } from './toggle-shared/toggle-shared.module'; -import { ContentNodeShareModule } from './content-node-share/content-node-share.module'; -import { ShareDialogComponent } from './content-node-share/content-node-share.dialog'; - -@NgModule({ - imports: [ - CommonModule, - CoreModule.forChild(), - ExtensionsModule, - ContentNodeShareModule, - ToggleSharedModule - ], - entryComponents: [ShareDialogComponent] -}) -export class AppSharedModule {} diff --git a/src/app/components/shared/toggle-shared/toggle-shared.module.ts b/src/app/components/shared/toggle-shared/toggle-shared.module.ts deleted file mode 100644 index a9a0e7b76..000000000 --- a/src/app/components/shared/toggle-shared/toggle-shared.module.ts +++ /dev/null @@ -1,48 +0,0 @@ -/*! - * @license - * Alfresco Example Content Application - * - * Copyright (C) 2005 - 2019 Alfresco Software Limited - * - * This file is part of the Alfresco Example Content Application. - * If the software was purchased under a paid Alfresco license, the terms of - * the paid license agreement will prevail. Otherwise, the software is - * provided under the following open source license terms: - * - * The Alfresco Example Content Application is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The Alfresco Example Content Application is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ - -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { CoreModule } from '@alfresco/adf-core'; -import { ContentNodeShareModule } from '@alfresco/adf-content-services'; -import { ExtensionsModule } from '@alfresco/adf-extensions'; -import { ToggleSharedComponent } from './toggle-shared.component'; - -export function components() { - return [ToggleSharedComponent]; -} - -@NgModule({ - imports: [ - CommonModule, - CoreModule.forChild(), - ExtensionsModule, - ContentNodeShareModule - ], - declarations: components(), - exports: components(), - entryComponents: components() -}) -export class ToggleSharedModule {} diff --git a/src/app/extensions/core.extensions.module.ts b/src/app/extensions/core.extensions.module.ts index 7bd100641..b7a318d5c 100644 --- a/src/app/extensions/core.extensions.module.ts +++ b/src/app/extensions/core.extensions.module.ts @@ -32,7 +32,6 @@ import { AppExtensionService } from './extension.service'; import { ToggleInfoDrawerComponent } from '../components/toolbar/toggle-info-drawer/toggle-info-drawer.component'; import { ToggleFavoriteComponent } from '../components/toolbar/toggle-favorite/toggle-favorite.component'; import { ToggleFavoriteLibraryComponent } from '../components/toolbar/toggle-favorite-library/toggle-favorite-library.component'; -import { ToggleSharedComponent } from '../components/shared/toggle-shared/toggle-shared.component'; import { MetadataTabComponent } from '../components/info-drawer/metadata-tab/metadata-tab.component'; import { LibraryMetadataTabComponent } from '../components/info-drawer/library-metadata-tab/library-metadata-tab.component'; import { CommentsTabComponent } from '../components/info-drawer/comments-tab/comments-tab.component'; @@ -50,6 +49,7 @@ import { TrashcanNameColumnComponent, LibraryRoleColumnComponent } from '@alfresco/adf-content-services'; +import { ToggleSharedComponent } from '../components/common/toggle-shared/toggle-shared.component'; export function setupExtensions(service: AppExtensionService): Function { return () => service.load(); diff --git a/src/app/services/content-management.service.ts b/src/app/services/content-management.service.ts index 91ec3c779..5b57b4065 100644 --- a/src/app/services/content-management.service.ts +++ b/src/app/services/content-management.service.ts @@ -45,7 +45,8 @@ import { import { ConfirmDialogComponent, FolderDialogComponent, - LibraryDialogComponent + LibraryDialogComponent, + ShareDialogComponent } from '@alfresco/adf-content-services'; import { TranslationService } from '@alfresco/adf-core'; import { @@ -65,7 +66,6 @@ import { Store } from '@ngrx/store'; import { forkJoin, Observable, of, Subject, zip } from 'rxjs'; import { catchError, flatMap, map, mergeMap, take, tap } from 'rxjs/operators'; import { NodePermissionsDialogComponent } from '../components/permissions/permission-dialog/node-permissions.dialog'; -import { ShareDialogComponent } from '../components/shared/content-node-share/content-node-share.dialog'; import { NodeVersionUploadDialogComponent } from '../dialogs/node-version-upload/node-version-upload.dialog'; import { NodeVersionsDialogComponent } from '../dialogs/node-versions/node-versions.dialog'; import { NodeActionsService } from './node-actions.service'; @@ -208,7 +208,6 @@ export class ContentManagementService { width: '600px', panelClass: 'adf-share-link-dialog', data: { - permission: this.permission.check(node, ['update']), node, baseShareUrl } diff --git a/src/app/ui/theme.scss b/src/app/ui/theme.scss index be8881e7f..c2b968d9d 100644 --- a/src/app/ui/theme.scss +++ b/src/app/ui/theme.scss @@ -17,4 +17,16 @@ $theme: mat-light-theme($primary, $accent, $warn); @include adf-content-services-theme($theme); @include adf-core-theme($theme); +// fixes [ACA-2069] +$primary: map-get($theme, primary); +.mat-slide-toggle.mat-primary.mat-checked:not(.mat-disabled) { + .mat-slide-toggle-thumb, + .mat-slide-toggle-ripple .mat-ripple-element { + background-color: mat-color($primary); + } + .mat-slide-toggle-bar { + background-color: mat-color($primary, 0.54); + } +} + @include custom-theme($custom-theme);