diff --git a/lib/content-services/src/lib/directives/auto-focus.directive.spec.ts b/lib/content-services/src/lib/directives/auto-focus.directive.spec.ts index ed9e669d88..2895e441c9 100644 --- a/lib/content-services/src/lib/directives/auto-focus.directive.spec.ts +++ b/lib/content-services/src/lib/directives/auto-focus.directive.spec.ts @@ -22,7 +22,9 @@ import { By } from '@angular/platform-browser'; import { TranslateModule } from '@ngx-translate/core'; @Component({ - template: `
Test
` + standalone: true, + imports: [AutoFocusDirective], + template: `
Test
` }) class AutoFocusTestComponent {} @@ -31,13 +33,7 @@ describe('AutoFocusDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ - TranslateModule.forRoot() - ], - declarations: [ - AutoFocusDirective, - AutoFocusTestComponent - ] + imports: [TranslateModule.forRoot(), AutoFocusDirective, AutoFocusTestComponent] }); fixture = TestBed.createComponent(AutoFocusTestComponent); }); diff --git a/lib/content-services/src/lib/directives/auto-focus.directive.ts b/lib/content-services/src/lib/directives/auto-focus.directive.ts index e04b8955df..5b97855baa 100644 --- a/lib/content-services/src/lib/directives/auto-focus.directive.ts +++ b/lib/content-services/src/lib/directives/auto-focus.directive.ts @@ -18,14 +18,15 @@ import { AfterContentInit, Directive, ElementRef } from '@angular/core'; @Directive({ - selector: '[adf-auto-focus]' + standalone: true, + selector: '[adf-auto-focus]' }) export class AutoFocusDirective implements AfterContentInit { - public constructor(private el: ElementRef) {} + public constructor(private el: ElementRef) {} - public ngAfterContentInit() { - setTimeout(() => { - this.el.nativeElement.focus(); - }, 100); - } + public ngAfterContentInit() { + setTimeout(() => { + this.el.nativeElement.focus(); + }, 100); + } } diff --git a/lib/content-services/src/lib/directives/check-allowable-operation.directive.ts b/lib/content-services/src/lib/directives/check-allowable-operation.directive.ts index 8ac7651741..807e988704 100644 --- a/lib/content-services/src/lib/directives/check-allowable-operation.directive.ts +++ b/lib/content-services/src/lib/directives/check-allowable-operation.directive.ts @@ -17,37 +17,39 @@ /* eslint-disable @angular-eslint/no-input-rename */ -import { ChangeDetectorRef, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core'; +import { ChangeDetectorRef, Directive, ElementRef, Host, Inject, Input, OnChanges, Optional, Renderer2, SimpleChanges } from '@angular/core'; import { NodeEntry } from '@alfresco/js-api'; import { EXTENDIBLE_COMPONENT } from '@alfresco/adf-core'; import { ContentService } from '../common/services/content.service'; import { NodeAllowableOperationSubject } from '../interfaces/node-allowable-operation-subject.interface'; @Directive({ + standalone: true, selector: '[adf-check-allowable-operation]' }) export class CheckAllowableOperationDirective implements OnChanges { - /** * Node permission to check (create, delete, update, updatePermissions, * !create, !delete, !update, !updatePermissions). */ @Input('adf-check-allowable-operation') - permission: string = null; + permission: string = null; /** Nodes to check permission for. */ @Input('adf-nodes') nodes: NodeEntry[] = []; - constructor(private elementRef: ElementRef, - private renderer: Renderer2, - private contentService: ContentService, - private changeDetector: ChangeDetectorRef, + constructor( + private elementRef: ElementRef, + private renderer: Renderer2, + private contentService: ContentService, + private changeDetector: ChangeDetectorRef, - @Host() - @Optional() - @Inject(EXTENDIBLE_COMPONENT) private parentComponent?: NodeAllowableOperationSubject) { - } + @Host() + @Optional() + @Inject(EXTENDIBLE_COMPONENT) + private parentComponent?: NodeAllowableOperationSubject + ) {} ngOnChanges(changes: SimpleChanges) { if (changes.nodes && !changes.nodes.firstChange) { diff --git a/lib/content-services/src/lib/directives/content-directive.module.ts b/lib/content-services/src/lib/directives/content-directive.module.ts index a61b96e8c4..0e1e6060d1 100644 --- a/lib/content-services/src/lib/directives/content-directive.module.ts +++ b/lib/content-services/src/lib/directives/content-directive.module.ts @@ -15,11 +15,7 @@ * limitations under the License. */ -import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { MaterialModule } from '../material.module'; -import { TranslateModule } from '@ngx-translate/core'; - import { NodeLockDirective } from './node-lock.directive'; import { NodeCounterComponent, NodeCounterDirective } from './node-counter.directive'; import { AutoFocusDirective } from './auto-focus.directive'; @@ -31,37 +27,23 @@ import { NodeFavoriteDirective } from './node-favorite.directive'; import { NodeRestoreDirective } from './node-restore.directive'; import { NodeDownloadDirective } from './node-download.directive'; +export const CONTENT_DIRECTIVES = [ + NodeLockDirective, + NodeCounterDirective, + NodeCounterComponent, + AutoFocusDirective, + CheckAllowableOperationDirective, + LibraryFavoriteDirective, + LibraryMembershipDirective, + NodeDeleteDirective, + NodeFavoriteDirective, + NodeRestoreDirective, + NodeDownloadDirective +]; + +/** @deprecated import CONTENT_DIRECTIVES or standalone directives instead */ @NgModule({ - imports: [ - CommonModule, - MaterialModule, - TranslateModule - ], - declarations: [ - NodeLockDirective, - NodeCounterDirective, - NodeCounterComponent, - AutoFocusDirective, - CheckAllowableOperationDirective, - LibraryFavoriteDirective, - LibraryMembershipDirective, - NodeDeleteDirective, - NodeFavoriteDirective, - NodeRestoreDirective, - NodeDownloadDirective - ], - exports: [ - NodeLockDirective, - NodeCounterDirective, - AutoFocusDirective, - CheckAllowableOperationDirective, - LibraryFavoriteDirective, - LibraryMembershipDirective, - NodeDeleteDirective, - NodeFavoriteDirective, - NodeRestoreDirective, - NodeDownloadDirective - ] + imports: [...CONTENT_DIRECTIVES], + exports: [...CONTENT_DIRECTIVES] }) -export class ContentDirectiveModule { -} +export class ContentDirectiveModule {} diff --git a/lib/content-services/src/lib/directives/library-favorite.directive.spec.ts b/lib/content-services/src/lib/directives/library-favorite.directive.spec.ts index 9a1ed73b9f..bf0212b442 100644 --- a/lib/content-services/src/lib/directives/library-favorite.directive.spec.ts +++ b/lib/content-services/src/lib/directives/library-favorite.directive.spec.ts @@ -22,8 +22,10 @@ import { CoreTestingModule } from '@alfresco/adf-core'; import { LibraryEntity } from '../interfaces/library-entity.interface'; @Component({ + standalone: true, + imports: [LibraryFavoriteDirective], selector: 'app-test-component', - template: ` ` + template: `` }) class TestComponent { @ViewChild('favoriteLibrary', { static: true }) @@ -39,8 +41,7 @@ describe('LibraryFavoriteDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [CoreTestingModule], - declarations: [TestComponent, LibraryFavoriteDirective] + imports: [CoreTestingModule, LibraryFavoriteDirective, TestComponent] }); fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; diff --git a/lib/content-services/src/lib/directives/library-favorite.directive.ts b/lib/content-services/src/lib/directives/library-favorite.directive.ts index 37fd9cf36f..0e2c79fa93 100644 --- a/lib/content-services/src/lib/directives/library-favorite.directive.ts +++ b/lib/content-services/src/lib/directives/library-favorite.directive.ts @@ -21,6 +21,7 @@ import { AlfrescoApiService } from '@alfresco/adf-core'; import { LibraryEntity } from '../interfaces/library-entity.interface'; @Directive({ + standalone: true, selector: '[adf-favorite-library]', exportAs: 'favoriteLibrary' }) diff --git a/lib/content-services/src/lib/directives/library-membership.directive.ts b/lib/content-services/src/lib/directives/library-membership.directive.ts index 215be73cac..a78b8b83e2 100644 --- a/lib/content-services/src/lib/directives/library-membership.directive.ts +++ b/lib/content-services/src/lib/directives/library-membership.directive.ts @@ -25,6 +25,7 @@ import { VersionCompatibilityService } from '../version-compatibility/version-co import { SitesService } from '../common/services/sites.service'; @Directive({ + standalone: true, selector: '[adf-library-membership]', exportAs: 'libraryMembership' }) diff --git a/lib/content-services/src/lib/directives/node-counter.directive.spec.ts b/lib/content-services/src/lib/directives/node-counter.directive.spec.ts index 5dba4cf885..dc3f0f4c15 100644 --- a/lib/content-services/src/lib/directives/node-counter.directive.spec.ts +++ b/lib/content-services/src/lib/directives/node-counter.directive.spec.ts @@ -22,6 +22,8 @@ import { By } from '@angular/platform-browser'; import { TranslateModule } from '@ngx-translate/core'; @Component({ + standalone: true, + imports: [NodeCounterDirective], template: `
` }) class TestComponent { @@ -33,14 +35,7 @@ describe('NodeCounterDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [ - TranslateModule.forRoot() - ], - declarations: [ - NodeCounterDirective, - NodeCounterComponent, - TestComponent - ] + imports: [TranslateModule.forRoot(), NodeCounterDirective, NodeCounterComponent, TestComponent] }); fixture = TestBed.createComponent(TestComponent); fixture.detectChanges(); diff --git a/lib/content-services/src/lib/directives/node-counter.directive.ts b/lib/content-services/src/lib/directives/node-counter.directive.ts index 00c2ba81a4..7b43623987 100644 --- a/lib/content-services/src/lib/directives/node-counter.directive.ts +++ b/lib/content-services/src/lib/directives/node-counter.directive.ts @@ -16,8 +16,10 @@ */ import { Directive, Input, Component, OnInit, OnChanges, ViewContainerRef } from '@angular/core'; +import { TranslateModule } from '@ngx-translate/core'; @Directive({ + standalone: true, selector: '[adf-node-counter]' }) export class NodeCounterDirective implements OnInit, OnChanges { @@ -42,6 +44,8 @@ export class NodeCounterDirective implements OnInit, OnChanges { } @Component({ + standalone: true, + imports: [TranslateModule], selector: 'adf-node-counter', template: `
{{ 'NODE_COUNTER.SELECTED_COUNT' | translate : { count: counter } }}
` }) diff --git a/lib/content-services/src/lib/directives/node-delete.directive.spec.ts b/lib/content-services/src/lib/directives/node-delete.directive.spec.ts index 87b81b4d7f..74267d706b 100644 --- a/lib/content-services/src/lib/directives/node-delete.directive.spec.ts +++ b/lib/content-services/src/lib/directives/node-delete.directive.spec.ts @@ -23,7 +23,7 @@ import { CoreTestingModule } from '@alfresco/adf-core'; import { ContentDirectiveModule } from './content-directive.module'; @Component({ - template: `
` + template: `
` }) class TestComponent { selection = []; @@ -35,7 +35,7 @@ class TestComponent { } @Component({ - template: `
` + template: `
` }) class TestWithPermissionsComponent { selection = []; diff --git a/lib/content-services/src/lib/directives/node-delete.directive.ts b/lib/content-services/src/lib/directives/node-delete.directive.ts index ecdc11f8af..9aca4c9681 100644 --- a/lib/content-services/src/lib/directives/node-delete.directive.ts +++ b/lib/content-services/src/lib/directives/node-delete.directive.ts @@ -46,6 +46,7 @@ interface ProcessStatus { } @Directive({ + standalone: true, selector: '[adf-delete]' }) export class NodeDeleteDirective implements OnChanges { @@ -61,13 +62,13 @@ export class NodeDeleteDirective implements OnChanges { @Output() delete: EventEmitter = new EventEmitter(); - _trashcanApi: TrashcanApi; + private _trashcanApi: TrashcanApi; get trashcanApi(): TrashcanApi { this._trashcanApi = this._trashcanApi ?? new TrashcanApi(this.alfrescoApiService.getInstance()); return this._trashcanApi; } - _nodesApi: NodesApi; + private _nodesApi: NodesApi; get nodesApi(): NodesApi { this._nodesApi = this._nodesApi ?? new NodesApi(this.alfrescoApiService.getInstance()); return this._nodesApi; diff --git a/lib/content-services/src/lib/directives/node-download.directive.ts b/lib/content-services/src/lib/directives/node-download.directive.ts index 261cef33c7..23dc1cd7b6 100755 --- a/lib/content-services/src/lib/directives/node-download.directive.ts +++ b/lib/content-services/src/lib/directives/node-download.directive.ts @@ -25,11 +25,12 @@ import { ContentApi, NodeEntry, VersionEntry } from '@alfresco/js-api'; * Directive selectors without adf- prefix will be deprecated on 3.0.0 */ @Directive({ + standalone: true, // eslint-disable-next-line @angular-eslint/directive-selector selector: '[adfNodeDownload]' }) export class NodeDownloadDirective { - _contentApi: ContentApi; + private _contentApi: ContentApi; get contentApi(): ContentApi { this._contentApi = this._contentApi ?? new ContentApi(this.apiService.getInstance()); return this._contentApi; diff --git a/lib/content-services/src/lib/directives/node-favorite.directive.ts b/lib/content-services/src/lib/directives/node-favorite.directive.ts index 9587c93797..8fad4044e7 100644 --- a/lib/content-services/src/lib/directives/node-favorite.directive.ts +++ b/lib/content-services/src/lib/directives/node-favorite.directive.ts @@ -24,6 +24,7 @@ import { catchError, map } from 'rxjs/operators'; import { AlfrescoApiService } from '@alfresco/adf-core'; @Directive({ + standalone: true, selector: '[adf-node-favorite]', exportAs: 'adfFavorite' }) diff --git a/lib/content-services/src/lib/directives/node-lock.directive.ts b/lib/content-services/src/lib/directives/node-lock.directive.ts index 36a6c5cb33..3fbb9d9c97 100644 --- a/lib/content-services/src/lib/directives/node-lock.directive.ts +++ b/lib/content-services/src/lib/directives/node-lock.directive.ts @@ -24,15 +24,15 @@ import { AllowableOperationsEnum } from '../common/models/allowable-operations.e import { ContentNodeDialogService } from '../content-node-selector/content-node-dialog.service'; @Directive({ + standalone: true, selector: '[adf-node-lock]' }) export class NodeLockDirective implements AfterViewInit { - /** Node to lock/unlock. */ @Input('adf-node-lock') node: Node; - @HostListener('click', [ '$event' ]) + @HostListener('click', ['$event']) onClick(event) { event.stopPropagation(); this.contentNodeDialogService.openLockNodeDialog(this.node); diff --git a/lib/content-services/src/lib/directives/node-restore.directive.ts b/lib/content-services/src/lib/directives/node-restore.directive.ts index 010b80962f..fec1c82083 100644 --- a/lib/content-services/src/lib/directives/node-restore.directive.ts +++ b/lib/content-services/src/lib/directives/node-restore.directive.ts @@ -18,20 +18,20 @@ /* eslint-disable @angular-eslint/component-selector, @angular-eslint/no-input-rename */ import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core'; -import { - TrashcanApi, DeletedNodeEntry, DeletedNodesPaging } from '@alfresco/js-api'; +import { TrashcanApi, DeletedNodeEntry, DeletedNodesPaging } from '@alfresco/js-api'; import { Observable, forkJoin, from, of } from 'rxjs'; import { tap, mergeMap, map, catchError } from 'rxjs/operators'; import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core'; import { RestoreMessageModel } from '../interfaces/restore-message-model.interface'; @Directive({ + standalone: true, selector: '[adf-restore]' }) export class NodeRestoreDirective { private readonly restoreProcessStatus; - _trashcanApi: TrashcanApi; + private _trashcanApi: TrashcanApi; get trashcanApi(): TrashcanApi { this._trashcanApi = this._trashcanApi ?? new TrashcanApi(this.alfrescoApiService.getInstance()); return this._trashcanApi; @@ -50,8 +50,7 @@ export class NodeRestoreDirective { this.recover(this.selection); } - constructor(private alfrescoApiService: AlfrescoApiService, - private translation: TranslationService) { + constructor(private alfrescoApiService: AlfrescoApiService, private translation: TranslationService) { this.restoreProcessStatus = this.processStatus(); } @@ -63,28 +62,28 @@ export class NodeRestoreDirective { const nodesWithPath = this.getNodesWithPath(selection); if (selection.length && nodesWithPath.length) { + this.restoreNodesBatch(nodesWithPath) + .pipe( + tap((restoredNodes) => { + const status = this.processStatus(restoredNodes); - this.restoreNodesBatch(nodesWithPath).pipe( - tap((restoredNodes) => { - const status = this.processStatus(restoredNodes); + this.restoreProcessStatus.fail.push(...status.fail); + this.restoreProcessStatus.success.push(...status.success); + }), + mergeMap(() => this.getDeletedNodes()) + ) + .subscribe((deletedNodesList) => { + const { entries: nodeList } = deletedNodesList.list; + const { fail: restoreErrorNodes } = this.restoreProcessStatus; + const selectedNodes = this.diff(restoreErrorNodes, selection, false); + const remainingNodes = this.diff(selectedNodes, nodeList); - this.restoreProcessStatus.fail.push(...status.fail); - this.restoreProcessStatus.success.push(...status.success); - }), - mergeMap(() => this.getDeletedNodes()) - ) - .subscribe((deletedNodesList) => { - const { entries: nodeList } = deletedNodesList.list; - const { fail: restoreErrorNodes } = this.restoreProcessStatus; - const selectedNodes = this.diff(restoreErrorNodes, selection, false); - const remainingNodes = this.diff(selectedNodes, nodeList); - - if (!remainingNodes.length) { - this.notification(); - } else { - this.recover(remainingNodes); - } - }); + if (!remainingNodes.length) { + this.notification(); + } else { + this.recover(remainingNodes); + } + }); } else { this.restoreProcessStatus.fail.push(...selection); this.notification(); @@ -117,7 +116,7 @@ export class NodeRestoreDirective { entry })), catchError((error) => { - const { statusCode } = (JSON.parse(error.message)).error; + const { statusCode } = JSON.parse(error.message).error; return of({ status: 0, @@ -145,10 +144,10 @@ export class NodeRestoreDirective { fail: [], success: [], get someFailed() { - return !!(this.fail.length); + return !!this.fail.length; }, get someSucceeded() { - return !!(this.success.length); + return !!this.success.length; }, get oneFailed() { return this.fail.length === 1; @@ -168,58 +167,43 @@ export class NodeRestoreDirective { } }; - return data.reduce( - (acc, node) => { - if (node.status) { - acc.success.push(node); - } else { - acc.fail.push(node); - } + return data.reduce((acc, node) => { + if (node.status) { + acc.success.push(node); + } else { + acc.fail.push(node); + } - return acc; - }, - status - ); + return acc; + }, status); } private getRestoreMessage(): string | null { const { restoreProcessStatus: status } = this; if (status.someFailed && !status.oneFailed) { - return this.translation.instant( - 'CORE.RESTORE_NODE.PARTIAL_PLURAL', - { - // eslint-disable-next-line id-blacklist - number: status.fail.length - } - ); + return this.translation.instant('CORE.RESTORE_NODE.PARTIAL_PLURAL', { + // eslint-disable-next-line id-blacklist + number: status.fail.length + }); } if (status.oneFailed && status.fail[0].statusCode) { if (status.fail[0].statusCode === 409) { - return this.translation.instant( - 'CORE.RESTORE_NODE.NODE_EXISTS', - { - name: status.fail[0].entry.name - } - ); + return this.translation.instant('CORE.RESTORE_NODE.NODE_EXISTS', { + name: status.fail[0].entry.name + }); } else { - return this.translation.instant( - 'CORE.RESTORE_NODE.GENERIC', - { - name: status.fail[0].entry.name - } - ); + return this.translation.instant('CORE.RESTORE_NODE.GENERIC', { + name: status.fail[0].entry.name + }); } } if (status.oneFailed && !status.fail[0].statusCode) { - return this.translation.instant( - 'CORE.RESTORE_NODE.LOCATION_MISSING', - { - name: status.fail[0].entry.name - } - ); + return this.translation.instant('CORE.RESTORE_NODE.LOCATION_MISSING', { + name: status.fail[0].entry.name + }); } if (status.allSucceeded && !status.oneSucceeded) { @@ -227,12 +211,9 @@ export class NodeRestoreDirective { } if (status.allSucceeded && status.oneSucceeded) { - return this.translation.instant( - 'CORE.RESTORE_NODE.SINGULAR', - { - name: status.success[0].entry.name - } - ); + return this.translation.instant('CORE.RESTORE_NODE.SINGULAR', { + name: status.success[0].entry.name + }); } return null; @@ -244,7 +225,7 @@ export class NodeRestoreDirective { const message = this.getRestoreMessage(); this.reset(); - const action = (status.oneSucceeded && !status.someFailed) ? this.translation.instant('CORE.RESTORE_NODE.VIEW') : ''; + const action = status.oneSucceeded && !status.someFailed ? this.translation.instant('CORE.RESTORE_NODE.VIEW') : ''; let path; if (status.success && status.success.length > 0) { diff --git a/lib/content-services/src/lib/viewer/alfresco-viewer.module.ts b/lib/content-services/src/lib/viewer/alfresco-viewer.module.ts index a80f29a2ed..b49f41b261 100644 --- a/lib/content-services/src/lib/viewer/alfresco-viewer.module.ts +++ b/lib/content-services/src/lib/viewer/alfresco-viewer.module.ts @@ -15,37 +15,12 @@ * limitations under the License. */ -import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; -import { TranslateModule } from '@ngx-translate/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; - -import { ExtensionsModule } from '@alfresco/adf-extensions'; - -import { MaterialModule } from '../material.module'; -import { A11yModule } from '@angular/cdk/a11y'; import { AlfrescoViewerComponent } from './components/alfresco-viewer.component'; -import { CoreModule } from '@alfresco/adf-core'; -import { ContentDirectiveModule } from '../directives'; +/** @deprecated import AlfrescoViewerComponent instead */ @NgModule({ - imports: [ - CoreModule, - CommonModule, - MaterialModule, - TranslateModule, - FormsModule, - ReactiveFormsModule, - A11yModule, - ExtensionsModule, - ContentDirectiveModule - ], - declarations: [ - AlfrescoViewerComponent - ], - exports: [ - AlfrescoViewerComponent - ] + imports: [AlfrescoViewerComponent], + exports: [AlfrescoViewerComponent] }) -export class AlfrescoViewerModule { -} +export class AlfrescoViewerModule {} diff --git a/lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts b/lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts index d0f1214fe1..9ac2dcf2db 100644 --- a/lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts +++ b/lib/content-services/src/lib/viewer/components/alfresco-viewer.component.ts @@ -34,6 +34,7 @@ import { CloseButtonPosition, Track, ViewerComponent, + ViewerModule, ViewerMoreActionsComponent, ViewerOpenWithComponent, ViewerSidebarComponent, @@ -51,9 +52,16 @@ import { NodesApiService } from '../../common/services/nodes-api.service'; import { UploadService } from '../../common/services/upload.service'; import { FileModel } from '../../common/models/file.model'; import { NodeActionsService } from '../../document-list'; +import { CommonModule } from '@angular/common'; +import { TranslateModule } from '@ngx-translate/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { NodeDownloadDirective } from '../../directives'; @Component({ selector: 'adf-alfresco-viewer', + standalone: true, + imports: [CommonModule, TranslateModule, MatButtonModule, MatIconModule, ViewerModule, NodeDownloadDirective], templateUrl: './alfresco-viewer.component.html', styleUrls: ['./alfresco-viewer.component.scss'], host: { class: 'adf-alfresco-viewer' }, @@ -115,7 +123,7 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit, OnDestroy { /** * If `true` then show the Viewer as a full page over the current content. - * Otherwise fit inside the parent div. + * Otherwise, fit inside the parent div. */ @Input() overlayMode = false; @@ -211,25 +219,25 @@ export class AlfrescoViewerComponent implements OnChanges, OnInit, OnDestroy { sidebarRightTemplateContext: { node: Node } = { node: null }; sidebarLeftTemplateContext: { node: Node } = { node: null }; - _sharedLinksApi: SharedlinksApi; + private _sharedLinksApi: SharedlinksApi; get sharedLinksApi(): SharedlinksApi { this._sharedLinksApi = this._sharedLinksApi ?? new SharedlinksApi(this.apiService.getInstance()); return this._sharedLinksApi; } - _versionsApi: VersionsApi; + private _versionsApi: VersionsApi; get versionsApi(): VersionsApi { this._versionsApi = this._versionsApi ?? new VersionsApi(this.apiService.getInstance()); return this._versionsApi; } - _nodesApi: NodesApi; + private _nodesApi: NodesApi; get nodesApi(): NodesApi { this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance()); return this._nodesApi; } - _contentApi: ContentApi; + private _contentApi: ContentApi; get contentApi(): ContentApi { this._contentApi = this._contentApi ?? new ContentApi(this.apiService.getInstance()); return this._contentApi; diff --git a/lib/core/shell/src/lib/components/shell/shell.component.spec.ts b/lib/core/shell/src/lib/components/shell/shell.component.spec.ts index d4197acf8a..c309211a95 100644 --- a/lib/core/shell/src/lib/components/shell/shell.component.spec.ts +++ b/lib/core/shell/src/lib/components/shell/shell.component.spec.ts @@ -29,154 +29,154 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { TranslateModule } from '@ngx-translate/core'; class MockRouter { - private url = 'some-url'; - private subject = new Subject(); - events = this.subject.asObservable(); - routerState = { snapshot: { url: this.url } }; + private url = 'some-url'; + private subject = new Subject(); + events = this.subject.asObservable(); + routerState = { snapshot: { url: this.url } }; - navigateByUrl(url: string) { - const navigationStart = new NavigationStart(0, url); - this.subject.next(navigationStart); - } + navigateByUrl(url: string) { + const navigationStart = new NavigationStart(0, url); + this.subject.next(navigationStart); + } } describe('AppLayoutComponent', () => { - let fixture: ComponentFixture; - let component: ShellLayoutComponent; - let appConfig: AppConfigService; - let shellAppService: ShellAppService; + let fixture: ComponentFixture; + let component: ShellLayoutComponent; + let appConfig: AppConfigService; + let shellAppService: ShellAppService; - beforeEach(() => { - const shellService: ShellAppService = { - pageHeading$: of('Title'), - hideSidenavConditions: [], - minimizeSidenavConditions: [], - preferencesService: { - get: () => 'true', - set: () => {} - } - }; + beforeEach(() => { + const shellService: ShellAppService = { + pageHeading$: of('Title'), + hideSidenavConditions: [], + minimizeSidenavConditions: [], + preferencesService: { + get: () => 'true', + set: () => {} + } + }; - TestBed.configureTestingModule({ - imports: [ - CommonModule, - NoopAnimationsModule, - HttpClientModule, - SidenavLayoutModule, - ExtensionsModule, - RouterModule.forChild([]), - TranslateModule.forRoot() - ], - providers: [ - { - provide: Router, - useClass: MockRouter - }, - { - provide: SHELL_APP_SERVICE, - useValue: shellService - } - ], - declarations: [ShellLayoutComponent], - schemas: [NO_ERRORS_SCHEMA] + TestBed.configureTestingModule({ + imports: [ + CommonModule, + NoopAnimationsModule, + HttpClientModule, + SidenavLayoutModule, + ExtensionsModule, + RouterModule.forChild([]), + TranslateModule.forRoot(), + ShellLayoutComponent + ], + providers: [ + { + provide: Router, + useClass: MockRouter + }, + { + provide: SHELL_APP_SERVICE, + useValue: shellService + } + ], + schemas: [NO_ERRORS_SCHEMA] + }); + + fixture = TestBed.createComponent(ShellLayoutComponent); + component = fixture.componentInstance; + appConfig = TestBed.inject(AppConfigService); + shellAppService = TestBed.inject(SHELL_APP_SERVICE); }); - fixture = TestBed.createComponent(ShellLayoutComponent); - component = fixture.componentInstance; - appConfig = TestBed.inject(AppConfigService); - shellAppService = TestBed.inject(SHELL_APP_SERVICE); - }); - - beforeEach(() => { - appConfig.config.languages = []; - appConfig.config.locale = 'en'; - }); - - describe('sidenav state', () => { - it('should get state from configuration', () => { - appConfig.config.sideNav = { - expandedSidenav: false, - preserveState: false - }; - - fixture.detectChanges(); - - expect(component.expandedSidenav).toBe(false); + beforeEach(() => { + appConfig.config.languages = []; + appConfig.config.locale = 'en'; }); - it('should resolve state to true is no configuration', () => { - appConfig.config.sidenav = {}; + describe('sidenav state', () => { + it('should get state from configuration', () => { + appConfig.config.sideNav = { + expandedSidenav: false, + preserveState: false + }; - fixture.detectChanges(); + fixture.detectChanges(); - expect(component.expandedSidenav).toBe(true); + expect(component.expandedSidenav).toBe(false); + }); + + it('should resolve state to true is no configuration', () => { + appConfig.config.sidenav = {}; + + fixture.detectChanges(); + + expect(component.expandedSidenav).toBe(true); + }); + + it('should get state from user settings as true', () => { + appConfig.config.sideNav = { + expandedSidenav: false, + preserveState: true + }; + + spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => { + if (key === 'expandedSidenav') { + return 'true'; + } + return 'false'; + }); + + fixture.detectChanges(); + + expect(component.expandedSidenav).toBe(true); + }); + + it('should get state from user settings as false', () => { + appConfig.config.sidenav = { + expandedSidenav: false, + preserveState: true + }; + + spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => { + if (key === 'expandedSidenav') { + return 'false'; + } + return 'true'; + }); + + fixture.detectChanges(); + + expect(component.expandedSidenav).toBe(false); + }); }); - it('should get state from user settings as true', () => { - appConfig.config.sideNav = { - expandedSidenav: false, - preserveState: true - }; + it('should close menu on mobile screen size', () => { + component.minimizeSidenav = false; + component.layout.container = { + isMobileScreenSize: true, + toggleMenu: () => {} + }; - spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => { - if (key === 'expandedSidenav') { - return 'true'; - } - return 'false'; - }); + spyOn(component.layout.container, 'toggleMenu'); + fixture.detectChanges(); - fixture.detectChanges(); + component.hideMenu({ preventDefault: () => {} } as any); - expect(component.expandedSidenav).toBe(true); + expect(component.layout.container.toggleMenu).toHaveBeenCalled(); }); - it('should get state from user settings as false', () => { - appConfig.config.sidenav = { - expandedSidenav: false, - preserveState: true - }; + it('should close menu on mobile screen size also when minimizeSidenav true', () => { + fixture.detectChanges(); + component.minimizeSidenav = true; + component.layout.container = { + isMobileScreenSize: true, + toggleMenu: () => {} + }; - spyOn(shellAppService.preferencesService, 'get').and.callFake((key) => { - if (key === 'expandedSidenav') { - return 'false'; - } - return 'true'; - }); + spyOn(component.layout.container, 'toggleMenu'); + fixture.detectChanges(); - fixture.detectChanges(); + component.hideMenu({ preventDefault: () => {} } as any); - expect(component.expandedSidenav).toBe(false); + expect(component.layout.container.toggleMenu).toHaveBeenCalled(); }); - }); - - it('should close menu on mobile screen size', () => { - component.minimizeSidenav = false; - component.layout.container = { - isMobileScreenSize: true, - toggleMenu: () => {} - }; - - spyOn(component.layout.container, 'toggleMenu'); - fixture.detectChanges(); - - component.hideMenu({ preventDefault: () => {} } as any); - - expect(component.layout.container.toggleMenu).toHaveBeenCalled(); - }); - - it('should close menu on mobile screen size also when minimizeSidenav true', () => { - fixture.detectChanges(); - component.minimizeSidenav = true; - component.layout.container = { - isMobileScreenSize: true, - toggleMenu: () => {} - }; - - spyOn(component.layout.container, 'toggleMenu'); - fixture.detectChanges(); - - component.hideMenu({ preventDefault: () => {} } as any); - - expect(component.layout.container.toggleMenu).toHaveBeenCalled(); - }); }); diff --git a/lib/core/shell/src/lib/components/shell/shell.component.ts b/lib/core/shell/src/lib/components/shell/shell.component.ts index 876fa8e6ff..dc7eb5ff3d 100644 --- a/lib/core/shell/src/lib/components/shell/shell.component.ts +++ b/lib/core/shell/src/lib/components/shell/shell.component.ts @@ -15,125 +15,129 @@ * limitations under the License. */ -import { AppConfigService, SidenavLayoutComponent } from '@alfresco/adf-core'; +import { AppConfigService, SidenavLayoutComponent, SidenavLayoutModule } from '@alfresco/adf-core'; +import { DynamicExtensionComponent } from '@alfresco/adf-extensions'; import { Component, Inject, OnDestroy, OnInit, Optional, ViewChild, ViewEncapsulation } from '@angular/core'; -import { NavigationEnd, Router } from '@angular/router'; +import { NavigationEnd, Router, RouterModule } from '@angular/router'; import { Subject, Observable } from 'rxjs'; import { filter, takeUntil, map, withLatestFrom } from 'rxjs/operators'; import { BreakpointObserver } from '@angular/cdk/layout'; import { Directionality } from '@angular/cdk/bidi'; import { SHELL_APP_SERVICE, ShellAppService, SHELL_NAVBAR_MIN_WIDTH, SHELL_NAVBAR_MAX_WIDTH } from '../../services/shell-app.service'; +import { CommonModule } from '@angular/common'; @Component({ - selector: 'app-shell', - templateUrl: './shell.component.html', - styleUrls: ['./shell.component.scss'], - encapsulation: ViewEncapsulation.None, - host: { class: 'app-shell' } + selector: 'app-shell', + standalone: true, + imports: [CommonModule, SidenavLayoutModule, RouterModule, DynamicExtensionComponent], + templateUrl: './shell.component.html', + styleUrls: ['./shell.component.scss'], + encapsulation: ViewEncapsulation.None, + host: { class: 'app-shell' } }) export class ShellLayoutComponent implements OnInit, OnDestroy { - @ViewChild('layout', { static: true }) - layout: SidenavLayoutComponent; + @ViewChild('layout', { static: true }) + layout: SidenavLayoutComponent; - onDestroy$: Subject = new Subject(); - isSmallScreen$: Observable; + onDestroy$: Subject = new Subject(); + isSmallScreen$: Observable; - expandedSidenav: boolean; - minimizeSidenav = false; - hideSidenav = false; - sidenavMin: number; - sidenavMax: number; - direction: Directionality; + expandedSidenav: boolean; + minimizeSidenav = false; + hideSidenav = false; + sidenavMin: number; + sidenavMax: number; + direction: Directionality; - constructor( - private router: Router, - private appConfigService: AppConfigService, - private breakpointObserver: BreakpointObserver, - @Inject(SHELL_APP_SERVICE) private shellService: ShellAppService, - @Optional() @Inject(SHELL_NAVBAR_MIN_WIDTH) navBarMinWidth: number, - @Optional() @Inject(SHELL_NAVBAR_MAX_WIDTH) navbarMaxWidth: number - ) { - this.sidenavMin = navBarMinWidth ?? 70; - this.sidenavMax = navbarMaxWidth ?? 320; - } - - ngOnInit() { - this.isSmallScreen$ = this.breakpointObserver.observe(['(max-width: 600px)']).pipe(map((result) => result.matches)); - - this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el)); - this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el)); - - if (!this.minimizeSidenav) { - this.expandedSidenav = this.getSidenavState(); - } else { - this.expandedSidenav = false; + constructor( + private router: Router, + private appConfigService: AppConfigService, + private breakpointObserver: BreakpointObserver, + @Inject(SHELL_APP_SERVICE) private shellService: ShellAppService, + @Optional() @Inject(SHELL_NAVBAR_MIN_WIDTH) navBarMinWidth: number, + @Optional() @Inject(SHELL_NAVBAR_MAX_WIDTH) navbarMaxWidth: number + ) { + this.sidenavMin = navBarMinWidth ?? 70; + this.sidenavMax = navbarMaxWidth ?? 320; } - this.router.events - .pipe( - withLatestFrom(this.isSmallScreen$), - filter(([event, isSmallScreen]) => isSmallScreen && event instanceof NavigationEnd), - takeUntil(this.onDestroy$) - ) - .subscribe(() => { - this.layout.container.sidenav.close(); - }); + ngOnInit() { + this.isSmallScreen$ = this.breakpointObserver.observe(['(max-width: 600px)']).pipe(map((result) => result.matches)); - this.router.events - .pipe( - filter((event) => event instanceof NavigationEnd), - takeUntil(this.onDestroy$) - ) - .subscribe((event: NavigationEnd) => { - this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => event.urlAfterRedirects.includes(el)); - this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => event.urlAfterRedirects.includes(el)); + this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el)); + this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => this.router.routerState.snapshot.url.includes(el)); - this.updateState(); - }); - } + if (!this.minimizeSidenav) { + this.expandedSidenav = this.getSidenavState(); + } else { + this.expandedSidenav = false; + } - ngOnDestroy() { - this.onDestroy$.next(true); - this.onDestroy$.complete(); - } + this.router.events + .pipe( + withLatestFrom(this.isSmallScreen$), + filter(([event, isSmallScreen]) => isSmallScreen && event instanceof NavigationEnd), + takeUntil(this.onDestroy$) + ) + .subscribe(() => { + this.layout.container.sidenav.close(); + }); - hideMenu(event: Event) { - if (this.layout.container.isMobileScreenSize) { - event.preventDefault(); - this.layout.container.toggleMenu(); - } - } + this.router.events + .pipe( + filter((event) => event instanceof NavigationEnd), + takeUntil(this.onDestroy$) + ) + .subscribe((event: NavigationEnd) => { + this.minimizeSidenav = this.shellService.minimizeSidenavConditions.some((el) => event.urlAfterRedirects.includes(el)); + this.hideSidenav = this.shellService.hideSidenavConditions.some((el) => event.urlAfterRedirects.includes(el)); - private updateState() { - if (this.minimizeSidenav && !this.layout.isMenuMinimized) { - this.layout.isMenuMinimized = true; - if (!this.layout.container.isMobileScreenSize) { - this.layout.container.toggleMenu(); - } + this.updateState(); + }); } - if (!this.minimizeSidenav) { - if (this.getSidenavState() && this.layout.isMenuMinimized) { - this.layout.isMenuMinimized = false; - this.layout.container.toggleMenu(); - } - } - } - - onExpanded(state: boolean) { - if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) { - this.shellService.preferencesService.set('expandedSidenav', state); - } - } - - private getSidenavState(): boolean { - const expand = this.appConfigService.get('sideNav.expandedSidenav', true); - const preserveState = this.appConfigService.get('sideNav.preserveState', true); - - if (preserveState) { - return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true'; + ngOnDestroy() { + this.onDestroy$.next(true); + this.onDestroy$.complete(); } - return expand; - } + hideMenu(event: Event) { + if (this.layout.container.isMobileScreenSize) { + event.preventDefault(); + this.layout.container.toggleMenu(); + } + } + + private updateState() { + if (this.minimizeSidenav && !this.layout.isMenuMinimized) { + this.layout.isMenuMinimized = true; + if (!this.layout.container.isMobileScreenSize) { + this.layout.container.toggleMenu(); + } + } + + if (!this.minimizeSidenav) { + if (this.getSidenavState() && this.layout.isMenuMinimized) { + this.layout.isMenuMinimized = false; + this.layout.container.toggleMenu(); + } + } + } + + onExpanded(state: boolean) { + if (!this.minimizeSidenav && this.appConfigService.get('sideNav.preserveState')) { + this.shellService.preferencesService.set('expandedSidenav', state); + } + } + + private getSidenavState(): boolean { + const expand = this.appConfigService.get('sideNav.expandedSidenav', true); + const preserveState = this.appConfigService.get('sideNav.preserveState', true); + + if (preserveState) { + return this.shellService.preferencesService.get('expandedSidenav', expand.toString()) === 'true'; + } + + return expand; + } } diff --git a/lib/core/shell/src/lib/shell.module.ts b/lib/core/shell/src/lib/shell.module.ts index f3010533cb..e5648b8429 100644 --- a/lib/core/shell/src/lib/shell.module.ts +++ b/lib/core/shell/src/lib/shell.module.ts @@ -15,32 +15,28 @@ * limitations under the License. */ -import { CommonModule } from '@angular/common'; import { ModuleWithProviders, NgModule } from '@angular/core'; -import { Routes, provideRoutes, RouterModule, Route } from '@angular/router'; +import { Routes, provideRoutes, Route } from '@angular/router'; import { SHELL_LAYOUT_ROUTE } from './shell.routes'; -import { SidenavLayoutModule } from '@alfresco/adf-core'; -import { ExtensionsModule } from '@alfresco/adf-extensions'; import { ShellLayoutComponent } from './components/shell/shell.component'; export interface AppShellRoutesConfig { - shellParentRoute?: Route; - shellChildren: Routes; + shellParentRoute?: Route; + shellChildren: Routes; } @NgModule({ - imports: [SidenavLayoutModule, ExtensionsModule, RouterModule.forChild([]), CommonModule], - exports: [ShellLayoutComponent], - declarations: [ShellLayoutComponent] + imports: [ShellLayoutComponent], + exports: [ShellLayoutComponent] }) export class ShellModule { - static withRoutes(routes: Routes | AppShellRoutesConfig): ModuleWithProviders { - if (Array.isArray(routes)) { - return getModuleForRoutes(routes); - } + static withRoutes(routes: Routes | AppShellRoutesConfig): ModuleWithProviders { + if (Array.isArray(routes)) { + return getModuleForRoutes(routes); + } - return getModuleForRouteConfig(routes); - } + return getModuleForRouteConfig(routes); + } } /** @@ -50,16 +46,16 @@ export class ShellModule { * @returns module with providers */ function getModuleForRoutes(routes: Routes): ModuleWithProviders { - const shellLayoutRoute = SHELL_LAYOUT_ROUTE; + const shellLayoutRoute = SHELL_LAYOUT_ROUTE; - routes.forEach((childRoute) => { - shellLayoutRoute.children.push(childRoute); - }); + routes.forEach((childRoute) => { + shellLayoutRoute.children.push(childRoute); + }); - return { - ngModule: ShellModule, - providers: provideRoutes([shellLayoutRoute]) - }; + return { + ngModule: ShellModule, + providers: provideRoutes([shellLayoutRoute]) + }; } /** @@ -69,25 +65,25 @@ function getModuleForRoutes(routes: Routes): ModuleWithProviders { * @returns module with providers */ function getModuleForRouteConfig(config: AppShellRoutesConfig): ModuleWithProviders { - const shellLayoutRoute = SHELL_LAYOUT_ROUTE; + const shellLayoutRoute = SHELL_LAYOUT_ROUTE; - const shellParentRoute = config.shellParentRoute; - const shellChildrenRoutes = config.shellChildren; + const shellParentRoute = config.shellParentRoute; + const shellChildrenRoutes = config.shellChildren; - shellLayoutRoute.children.push(...shellChildrenRoutes); + shellLayoutRoute.children.push(...shellChildrenRoutes); - const rootRoute = shellParentRoute ? shellParentRoute : shellLayoutRoute; + const rootRoute = shellParentRoute ? shellParentRoute : shellLayoutRoute; - if (config.shellParentRoute) { - if (rootRoute.children === undefined) { - rootRoute.children = []; + if (config.shellParentRoute) { + if (rootRoute.children === undefined) { + rootRoute.children = []; + } + + rootRoute.children.push(shellLayoutRoute); } - rootRoute.children.push(shellLayoutRoute); - } - - return { - ngModule: ShellModule, - providers: provideRoutes([rootRoute]) - }; + return { + ngModule: ShellModule, + providers: provideRoutes([rootRoute]) + }; } diff --git a/lib/core/src/lib/about/about.component.stories.ts b/lib/core/src/lib/about/about.component.stories.ts index 24ad169077..bd06a3ac8b 100644 --- a/lib/core/src/lib/about/about.component.stories.ts +++ b/lib/core/src/lib/about/about.component.stories.ts @@ -20,10 +20,28 @@ import { AboutComponent } from './about.component'; import { AboutModule } from './about.module'; import { AuthenticationService } from '../auth/services/authentication.service'; import { AuthenticationMock } from '../auth/mock/authentication.service.mock'; -import { AppExtensionService, AppExtensionServiceMock } from '@alfresco/adf-extensions'; +import { AppExtensionService, ExtensionRef, ViewerExtensionRef } from '@alfresco/adf-extensions'; import { AppConfigService } from '../app-config/app-config.service'; import { AppConfigServiceMock } from '../common/mock/app-config.service.mock'; import { CoreStoryModule } from '../testing/core.story.module'; +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class AppExtensionServiceMock { + references$: Observable; + private _references = new BehaviorSubject([]); + + constructor() { + this.references$ = this._references.asObservable(); + } + + getViewerExtensions(): ViewerExtensionRef[] { + return []; + } +} export default { component: AboutComponent, @@ -74,7 +92,10 @@ const template: Story = (args: AboutComponent) => ({ export const about = template.bind({}); about.args = { pkg: { - name: 'My Storybook App', commit: 'my-commit-value', version: '1.0.0', dependencies: { + name: 'My Storybook App', + commit: 'my-commit-value', + version: '1.0.0', + dependencies: { '@alfresco/adf-content-services': '4.7.0', '@alfresco/adf-core': '4.7.0', '@alfresco/adf-extensions': '4.7.0', diff --git a/lib/core/src/lib/viewer/components/viewer.component.ts b/lib/core/src/lib/viewer/components/viewer.component.ts index 04643f9b08..61a8f4008d 100644 --- a/lib/core/src/lib/viewer/components/viewer.component.ts +++ b/lib/core/src/lib/viewer/components/viewer.component.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -import { ExtensionsModule } from '@alfresco/adf-extensions'; import { A11yModule } from '@angular/cdk/a11y'; import { NgIf, NgTemplateOutlet } from '@angular/common'; import { @@ -41,7 +40,6 @@ import { TranslateModule } from '@ngx-translate/core'; import { fromEvent, Subject } from 'rxjs'; import { filter, first, skipWhile, takeUntil } from 'rxjs/operators'; import { AppConfigService } from '../../app-config'; -import { PipeModule } from '../../pipes'; import { ToolbarComponent, ToolbarDividerComponent, ToolbarTitleComponent } from '../../toolbar'; import { DownloadPromptActions } from '../models/download-prompt.actions'; import { CloseButtonPosition, Track } from '../models/viewer.model'; @@ -52,6 +50,9 @@ import { ViewerOpenWithComponent } from './viewer-open-with.component'; import { ViewerRenderComponent } from './viewer-render/viewer-render.component'; import { ViewerSidebarComponent } from './viewer-sidebar.component'; import { ViewerToolbarComponent } from './viewer-toolbar.component'; +import { ViewerToolbarActionsComponent } from './viewer-toolbar-actions.component'; +import { ViewerToolbarCustomActionsComponent } from './viewer-toolbar-custom-actions.component'; +import { MimeTypeIconPipe } from '../../pipes'; const DEFAULT_NON_PREVIEW_CONFIG = { enableDownloadPrompt: false, @@ -75,12 +76,15 @@ const DEFAULT_NON_PREVIEW_CONFIG = { MatButtonModule, TranslateModule, MatIconModule, - PipeModule, MatMenuModule, ToolbarDividerComponent, ViewerRenderComponent, NgTemplateOutlet, - ExtensionsModule + ViewerToolbarComponent, + ViewerSidebarComponent, + ViewerToolbarActionsComponent, + ViewerToolbarCustomActionsComponent, + MimeTypeIconPipe ], providers: [ViewUtilService] }) @@ -137,7 +141,7 @@ export class ViewerComponent implements OnDestroy, OnInit, OnChanges { /** * If `true` then show the Viewer as a full page over the current content. - * Otherwise fit inside the parent div. + * Otherwise, fit inside the parent div. */ @Input() overlayMode = false; diff --git a/lib/core/src/lib/viewer/viewer.module.ts b/lib/core/src/lib/viewer/viewer.module.ts index f4e61d04c9..a969462116 100644 --- a/lib/core/src/lib/viewer/viewer.module.ts +++ b/lib/core/src/lib/viewer/viewer.module.ts @@ -35,45 +35,29 @@ import { ViewerToolbarComponent } from './components/viewer-toolbar.component'; import { ViewerComponent } from './components/viewer.component'; import { ViewerExtensionDirective } from './directives/viewer-extension.directive'; +export const VIEWER_DIRECTIVES = [ + PdfPasswordDialogComponent, + ViewerRenderComponent, + ImgViewerComponent, + TxtViewerComponent, + MediaPlayerComponent, + PdfViewerComponent, + PdfThumbComponent, + PdfThumbListComponent, + ViewerExtensionDirective, + UnknownFormatComponent, + ViewerToolbarComponent, + ViewerSidebarComponent, + ViewerOpenWithComponent, + ViewerMoreActionsComponent, + ViewerToolbarActionsComponent, + ViewerComponent, + ViewerToolbarCustomActionsComponent, + DownloadPromptDialogComponent +] as const; + @NgModule({ - imports: [ - PdfPasswordDialogComponent, - ViewerRenderComponent, - ImgViewerComponent, - TxtViewerComponent, - MediaPlayerComponent, - PdfViewerComponent, - PdfThumbComponent, - PdfThumbListComponent, - ViewerExtensionDirective, - UnknownFormatComponent, - ViewerToolbarComponent, - ViewerSidebarComponent, - ViewerOpenWithComponent, - ViewerMoreActionsComponent, - ViewerToolbarActionsComponent, - ViewerComponent, - ViewerToolbarCustomActionsComponent, - DownloadPromptDialogComponent - ], - exports: [ - ViewerRenderComponent, - ImgViewerComponent, - TxtViewerComponent, - MediaPlayerComponent, - PdfViewerComponent, - PdfPasswordDialogComponent, - PdfThumbComponent, - PdfThumbListComponent, - ViewerExtensionDirective, - UnknownFormatComponent, - ViewerToolbarComponent, - ViewerSidebarComponent, - ViewerOpenWithComponent, - ViewerMoreActionsComponent, - ViewerToolbarActionsComponent, - ViewerComponent, - ViewerToolbarCustomActionsComponent - ] + imports: [...VIEWER_DIRECTIVES], + exports: [...VIEWER_DIRECTIVES] }) export class ViewerModule {} diff --git a/lib/extensions/src/lib/components/dynamic-column/dynamic-column.component.ts b/lib/extensions/src/lib/components/dynamic-column/dynamic-column.component.ts index 646f8caf9f..19af04539b 100644 --- a/lib/extensions/src/lib/components/dynamic-column/dynamic-column.component.ts +++ b/lib/extensions/src/lib/components/dynamic-column/dynamic-column.component.ts @@ -32,7 +32,8 @@ import { ExtensionService } from '../../services/extension.service'; @Component({ selector: 'adf-dynamic-column', - template: ` `, + standalone: true, + template: ``, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'adf-dynamic-column' }, diff --git a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts index 14fe9d8de0..2a82c0330b 100644 --- a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts +++ b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts @@ -26,6 +26,7 @@ import { HttpClientModule } from '@angular/common/http'; @Component({ selector: 'test-component', + standalone: true, template: '
Hey I am the mighty test component!
' }) export class TestComponent implements OnChanges { @@ -47,8 +48,7 @@ describe('DynamicExtensionComponent', () => { componentRegister.setComponents({ 'test-component': TestComponent }); TestBed.configureTestingModule({ - imports: [HttpClientModule], - declarations: [DynamicExtensionComponent, TestComponent], + imports: [HttpClientModule, DynamicExtensionComponent, TestComponent], providers: [{ provide: ComponentRegisterService, useValue: componentRegister }] }); diff --git a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts index 2d5ef9e4ff..7efc203f8b 100644 --- a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts +++ b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts @@ -22,6 +22,7 @@ import { ExtensionComponent } from '../../services/component-register.service'; // cSpell:words lifecycle @Component({ selector: 'adf-dynamic-component', + standalone: true, template: `
` }) export class DynamicExtensionComponent implements OnChanges, OnDestroy { diff --git a/lib/extensions/src/lib/components/dynamic-tab/dynamic-tab.component.ts b/lib/extensions/src/lib/components/dynamic-tab/dynamic-tab.component.ts index 4faa271a5e..c559b02b1f 100644 --- a/lib/extensions/src/lib/components/dynamic-tab/dynamic-tab.component.ts +++ b/lib/extensions/src/lib/components/dynamic-tab/dynamic-tab.component.ts @@ -21,6 +21,7 @@ import { ExtensionService } from '../../services/extension.service'; @Component({ selector: 'adf-dynamic-tab', + standalone: true, template: `
` }) export class DynamicTabComponent implements OnInit, OnChanges, OnDestroy { diff --git a/lib/extensions/src/lib/components/viewer/preview-extension.component.ts b/lib/extensions/src/lib/components/viewer/preview-extension.component.ts index ad3d046db4..e0d4559933 100644 --- a/lib/extensions/src/lib/components/viewer/preview-extension.component.ts +++ b/lib/extensions/src/lib/components/viewer/preview-extension.component.ts @@ -20,7 +20,8 @@ import { ExtensionService } from '../../services/extension.service'; @Component({ selector: 'adf-preview-extension', - template: `
` + standalone: true, + template: `
` }) export class PreviewExtensionComponent implements OnInit, OnChanges, OnDestroy { @ViewChild('content', { read: ViewContainerRef, static: true }) diff --git a/lib/extensions/src/lib/extensions.module.ts b/lib/extensions/src/lib/extensions.module.ts index d424d43742..e6af9ffa1e 100644 --- a/lib/extensions/src/lib/extensions.module.ts +++ b/lib/extensions/src/lib/extensions.module.ts @@ -23,19 +23,12 @@ import { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core'; import { AppExtensionService } from './services/app-extension.service'; import { setupExtensions } from './services/startup-extension-factory'; +export const EXTENSION_DIRECTIVES = [DynamicExtensionComponent, DynamicTabComponent, DynamicColumnComponent, PreviewExtensionComponent] as const; + +/** @deprecated import EXTENSION_DIRECTIVES or standalone components instead */ @NgModule({ - declarations: [ - DynamicExtensionComponent, - DynamicTabComponent, - DynamicColumnComponent, - PreviewExtensionComponent - ], - exports: [ - DynamicExtensionComponent, - DynamicTabComponent, - DynamicColumnComponent, - PreviewExtensionComponent - ] + imports: [...EXTENSION_DIRECTIVES], + exports: [...EXTENSION_DIRECTIVES] }) export class ExtensionsModule { static forRoot(): ModuleWithProviders { @@ -51,10 +44,4 @@ export class ExtensionsModule { ] }; } - - static forChild(): ModuleWithProviders { - return { - ngModule: ExtensionsModule - }; - } } diff --git a/lib/extensions/src/lib/mock/app-extension.service.mock.ts b/lib/extensions/src/lib/mock/app-extension.service.mock.ts deleted file mode 100644 index ae0cbfe58d..0000000000 --- a/lib/extensions/src/lib/mock/app-extension.service.mock.ts +++ /dev/null @@ -1,37 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * 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 { Injectable } from '@angular/core'; -import { ExtensionRef } from '../config/extension.config'; -import { Observable, BehaviorSubject } from 'rxjs'; -import { ViewerExtensionRef } from '../config/viewer.extensions'; - -@Injectable({ - providedIn: 'root' -}) -export class AppExtensionServiceMock { - references$: Observable; - private _references = new BehaviorSubject([]); - - constructor() { - this.references$ = this._references.asObservable(); - } - - getViewerExtensions(): ViewerExtensionRef[] { - return []; - } -} diff --git a/lib/extensions/src/lib/mock/public-api.ts b/lib/extensions/src/lib/mock/public-api.ts deleted file mode 100644 index 2c8fe2faf5..0000000000 --- a/lib/extensions/src/lib/mock/public-api.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * @license - * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * 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. - */ - -export * from './app-extension.service.mock'; diff --git a/lib/extensions/src/public-api.ts b/lib/extensions/src/public-api.ts index a50d8119f0..0bc9224139 100644 --- a/lib/extensions/src/public-api.ts +++ b/lib/extensions/src/public-api.ts @@ -41,5 +41,3 @@ export * from './lib/store/states/repository.state'; export * from './lib/components/public-api'; export * from './lib/extensions.module'; - -export * from './lib/mock/public-api';