diff --git a/projects/aca-content/src/lib/components/details/details.component.spec.ts b/projects/aca-content/src/lib/components/details/details.component.spec.ts index ab61a17fd0..b654032864 100644 --- a/projects/aca-content/src/lib/components/details/details.component.spec.ts +++ b/projects/aca-content/src/lib/components/details/details.component.spec.ts @@ -180,7 +180,7 @@ describe('DetailsComponent', () => { it('should return the icon when getNodeIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; - spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); + spyOn(contentApiService, 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); const result = component.getNodeIcon(mockNode); expect(result).toContain(expectedIcon); @@ -188,20 +188,12 @@ describe('DetailsComponent', () => { it('should return the icon when getNodeIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; - spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); + spyOn(contentApiService, 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); const result = component.getNodeIcon(mockNode); expect(result).toContain(expectedIcon); }); - it('should subscribe to store and update isNodeLocked', () => { - const mockSelection = { file: { entry: { name: 'test', properties: {}, isLocked: false } } }; - spyOn(store, 'select').and.returnValue(of(mockSelection)); - fixture.detectChanges(); - expect(store.select).toHaveBeenCalled(); - expect(component.isNodeLocked).toBe(false); - }); - it('should unsubscribe from observables on component destroy', () => { spyOn(component.onDestroy$, 'next'); spyOn(component.onDestroy$, 'complete'); diff --git a/projects/aca-content/src/lib/components/details/details.component.ts b/projects/aca-content/src/lib/components/details/details.component.ts index b4651e7eb3..739a7e8ec4 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -38,7 +38,6 @@ import { MetadataTabComponent } from '../info-drawer/metadata-tab/metadata-tab.c import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.component'; import { takeUntil } from 'rxjs/operators'; import { ContentActionRef } from '@alfresco/adf-extensions'; -import { NodeActionsService } from '../../services/node-actions.service'; import { Node } from '@alfresco/js-api'; @Component({ @@ -69,7 +68,7 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy activeTab = 1; aspectActions: Array = []; - constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private nodeActionsService: NodeActionsService) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { super(); } @@ -99,7 +98,7 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy } getNodeIcon(node: Node): string { - return this.nodeActionsService.getNodeIcon(node); + return this.contentApi.getNodeIcon(node); } setActiveTab(tabName: string) { diff --git a/projects/aca-content/src/lib/services/node-actions.service.spec.ts b/projects/aca-content/src/lib/services/node-actions.service.spec.ts index 6721975cec..170c769250 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.spec.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.spec.ts @@ -25,7 +25,7 @@ import { TestBed } from '@angular/core/testing'; import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; import { of, throwError, Subject, Observable } from 'rxjs'; -import { AlfrescoApiService, ThumbnailService, TranslationService } from '@alfresco/adf-core'; +import { AlfrescoApiService, TranslationService } from '@alfresco/adf-core'; import { DocumentListService, NodeAction } from '@alfresco/adf-content-services'; import { NodeActionsService } from './node-actions.service'; import { Node, NodeChildAssociationEntry, NodeEntry } from '@alfresco/js-api'; @@ -1228,58 +1228,4 @@ describe('NodeActionsService', () => { }); }); }); - - describe('Info Drawer header Icon', () => { - let thumbnailService: ThumbnailService; - - const mockNode = { - isFolder: false, - isFile: false, - content: { - mimeType: 'image/jpeg' - }, - nodeType: 'app:folderlink', - aspectNames: ['aspect1', 'aspect2'] - }; - - beforeEach(() => { - thumbnailService = TestBed.inject(ThumbnailService); - }); - - function testNodeIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { - spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); - mockNode.isFolder = isFoldeType; - mockNode.isFile = isFileType; - const value = service.getNodeIcon(mockNode); - expect(value).toContain(iconPath); - } - - it('should resolve folder icon', () => { - testNodeIcon('assets/images/ft_ic_folder.svg', true, false); - }); - - it('should resolve smart folder icon', () => { - testNodeIcon('assets/images/ft_ic_smart_folder.svg', true, false); - }); - - it('should resolve link folder icon', () => { - testNodeIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); - }); - - it('should resolve rule folder icon', () => { - testNodeIcon('assets/images/ft_ic_folder_rule.svg', true, false); - }); - - it('should resolve file icon for content type', () => { - testNodeIcon('assets/images/ft_ic_raster_image.svg', false, true); - }); - - it('should resolve fallback file icon for unknown node', () => { - spyOn(thumbnailService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`); - mockNode.isFile = false; - mockNode.isFolder = false; - const value = service.getNodeIcon(mockNode); - expect(value).toContain(`assets/images/ft_ic_miscellaneous`); - }); - }); }); diff --git a/projects/aca-content/src/lib/services/node-actions.service.ts b/projects/aca-content/src/lib/services/node-actions.service.ts index 4fc02d1632..db588d3573 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -25,7 +25,7 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Observable, Subject, of, zip, from } from 'rxjs'; -import { AlfrescoApiService, TranslationService, ThumbnailService } from '@alfresco/adf-core'; +import { AlfrescoApiService, ThumbnailService, TranslationService } from '@alfresco/adf-core'; import { DocumentListService, ContentNodeSelectorComponent, @@ -563,52 +563,6 @@ export class NodeActionsService { return null; } - getNodeIcon(node: Node): string { - if (node?.isFolder) { - return this.getFolderIcon(node); - } - if (node?.isFile) { - return this.thumbnailService.getMimeTypeIcon(node?.content?.mimeType); - } - return this.thumbnailService.getDefaultMimeTypeIcon(); - } - - private getFolderIcon(node: Node): string { - if (this.isSmartFolder(node)) { - return this.thumbnailService.getMimeTypeIcon('smartFolder'); - } else if (this.isRuleFolder(node)) { - return this.thumbnailService.getMimeTypeIcon('ruleFolder'); - } else if (this.isLinkFolder(node)) { - return this.thumbnailService.getMimeTypeIcon('linkFolder'); - } else { - return this.thumbnailService.getMimeTypeIcon('folder'); - } - } - - isSmartFolder(node: Node): boolean { - if (node) { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects?.includes('smf:customConfigSmartFolder') || nodeAspects?.includes('smf:systemConfigSmartFolder'); - } - return false; - } - - isRuleFolder(node: Node): boolean { - if (node) { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects?.includes('rule:rules'); - } - return false; - } - - isLinkFolder(node: Node): boolean { - return node?.nodeType === 'app:folderlink'; - } - - private getNodeAspectNames(node: Node): string[] { - return node?.aspectNames || []; - } - public getNewNameFrom(name: string, baseName?: string) { const extensionMatch = name.match(/\.[^/.]+$/); diff --git a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.spec.ts b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.spec.ts index c13852399e..37fe2dbfd2 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.spec.ts +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.spec.ts @@ -32,7 +32,6 @@ import { InfoDrawerComponent } from './info-drawer.component'; import { LibTestingModule } from '../../testing/lib-testing-module'; import { AppExtensionService } from '../../services/app.extension.service'; import { ContentApiService } from '../../services/content-api.service'; -import { MatDialogModule } from '@angular/material/dialog'; describe('InfoDrawerComponent', () => { let fixture: ComponentFixture; @@ -92,7 +91,7 @@ describe('InfoDrawerComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [LibTestingModule, InfoDrawerComponent, MatDialogModule], + imports: [LibTestingModule, InfoDrawerComponent], providers: [ { provide: AppExtensionService, useValue: extensionServiceMock }, { provide: Store, useValue: storeMock } @@ -218,7 +217,7 @@ describe('InfoDrawerComponent', () => { it('should return the icon when getNodeIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; - spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); + spyOn(contentApiService, 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); const result = component.getNodeIcon(mockNode); expect(result).toContain(expectedIcon); diff --git a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.ts b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.ts index 8d6cd9e927..6ae52da080 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.ts +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.ts @@ -37,7 +37,6 @@ import { InfoDrawerModule } from '@alfresco/adf-core'; import { TranslateModule } from '@ngx-translate/core'; import { A11yModule } from '@angular/cdk/a11y'; import { ToolbarComponent } from '../toolbar/toolbar.component'; -import { NodeActionsService } from '../../../../../aca-content/src/lib/services/node-actions.service'; @Component({ standalone: true, @@ -65,12 +64,7 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { this.close(); } - constructor( - private store: Store, - private contentApi: ContentApiService, - private extensions: AppExtensionService, - private nodeActionsService: NodeActionsService - ) {} + constructor(private store: Store, private contentApi: ContentApiService, private extensions: AppExtensionService) {} ngOnInit() { this.tabs = this.extensions.getSidebarTabs(); @@ -133,6 +127,6 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { } getNodeIcon(node: Node): string { - return this.nodeActionsService.getNodeIcon(node); + return this.contentApi.getNodeIcon(node); } } diff --git a/projects/aca-shared/src/lib/services/content-api.service.spec.ts b/projects/aca-shared/src/lib/services/content-api.service.spec.ts index 8170ba898c..1fd4895127 100644 --- a/projects/aca-shared/src/lib/services/content-api.service.spec.ts +++ b/projects/aca-shared/src/lib/services/content-api.service.spec.ts @@ -22,10 +22,96 @@ * from Hyland Software. If not, see . */ +import { ThumbnailService } from '@alfresco/adf-core'; import { ContentApiService } from './content-api.service'; +import { TestBed } from '@angular/core/testing'; +import { TranslateModule, TranslateService } from '@ngx-translate/core'; +import { HttpClientModule } from '@angular/common/http'; describe('ContentApiService', () => { it('should be defined', () => { expect(ContentApiService).toBeDefined(); }); + + describe('Info Drawer header Icon', () => { + let thumbnailService: ThumbnailService; + let service: any; + + const mockNode = { + isFile: false, + createdByUser: { id: 'admin', displayName: 'Administrator' }, + modifiedAt: new Date('2017-05-24T15:08:55.640Z'), + nodeType: 'cm:content', + content: { + mimeType: 'application/rtf', + mimeTypeName: 'Rich Text Format', + sizeInBytes: 14530, + encoding: 'UTF-8' + }, + parentId: 'd124de26-6ba0-4f40-8d98-4907da2d337a', + createdAt: new Date('2017-05-24T15:08:55.640Z'), + path: { + name: '/Company Home/Guest Home', + isComplete: true, + elements: [ + { + id: '94acfc73-7014-4475-9bd9-93a2162f0f8c', + name: 'Company Home' + }, + { id: 'd124de26-6ba0-4f40-8d98-4907da2d337a', name: 'Guest Home' } + ] + }, + isFolder: true, + modifiedByUser: { id: 'admin', displayName: 'Administrator' }, + name: 'b_txt_file.rtf', + id: '70e1cc6a-6918-468a-b84a-1048093b06fd', + properties: { 'cm:versionLabel': '1.0', 'cm:versionType': 'MAJOR' }, + allowableOperations: ['delete', 'update'] + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [HttpClientModule, TranslateModule.forRoot()], + providers: [TranslateService] + }); + thumbnailService = TestBed.inject(ThumbnailService); + service = TestBed.inject(ContentApiService); + }); + + function testNodeIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { + spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); + mockNode.isFolder = isFoldeType; + mockNode.isFile = isFileType; + const value = service.getNodeIcon(mockNode); + expect(value).toContain(iconPath); + } + + it('should resolve folder icon', () => { + testNodeIcon('assets/images/ft_ic_folder.svg', true, false); + }); + + it('should resolve smart folder icon', () => { + testNodeIcon('assets/images/ft_ic_smart_folder.svg', true, false); + }); + + it('should resolve link folder icon', () => { + testNodeIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); + }); + + it('should resolve rule folder icon', () => { + testNodeIcon('assets/images/ft_ic_folder_rule.svg', true, false); + }); + + it('should resolve file icon for content type', () => { + testNodeIcon('assets/images/ft_ic_raster_image.svg', false, true); + }); + + it('should resolve fallback file icon for unknown node', () => { + spyOn(thumbnailService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`); + mockNode.isFile = false; + mockNode.isFolder = false; + const value = service.getNodeIcon(mockNode); + expect(value).toContain(`assets/images/ft_ic_miscellaneous`); + }); + }); }); diff --git a/projects/aca-shared/src/lib/services/content-api.service.ts b/projects/aca-shared/src/lib/services/content-api.service.ts index 781f0c5662..cfa59af19c 100644 --- a/projects/aca-shared/src/lib/services/content-api.service.ts +++ b/projects/aca-shared/src/lib/services/content-api.service.ts @@ -23,7 +23,7 @@ */ import { Injectable } from '@angular/core'; -import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core'; +import { AlfrescoApiService, ThumbnailService, UserPreferencesService } from '@alfresco/adf-core'; import { Observable, from } from 'rxjs'; import { NodePaging, @@ -118,7 +118,7 @@ export class ContentApiService { this._versionsApi = this._versionsApi ?? new VersionsApi(this.api.getInstance()); return this._versionsApi; } - constructor(private api: AlfrescoApiService, private preferences: UserPreferencesService) {} + constructor(private api: AlfrescoApiService, private preferences: UserPreferencesService, private thumbnailService: ThumbnailService) {} /** * Moves a node to the trashcan. @@ -361,4 +361,50 @@ export class ContentApiService { requestVersionDirectAccessUrl(nodeId: string, versionId: string): Observable { return from(this.versionsApi.requestDirectAccessUrl(nodeId, versionId)); } + + getNodeIcon(node: Node): string { + if (node?.isFolder) { + return this.getFolderIcon(node); + } + if (node?.isFile) { + return this.thumbnailService.getMimeTypeIcon(node?.content?.mimeType); + } + return this.thumbnailService.getDefaultMimeTypeIcon(); + } + + private getFolderIcon(node: Node): string { + if (this.isSmartFolder(node)) { + return this.thumbnailService.getMimeTypeIcon('smartFolder'); + } else if (this.isRuleFolder(node)) { + return this.thumbnailService.getMimeTypeIcon('ruleFolder'); + } else if (this.isLinkFolder(node)) { + return this.thumbnailService.getMimeTypeIcon('linkFolder'); + } else { + return this.thumbnailService.getMimeTypeIcon('folder'); + } + } + + isSmartFolder(node: Node): boolean { + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('smf:customConfigSmartFolder') || nodeAspects?.includes('smf:systemConfigSmartFolder'); + } + return false; + } + + isRuleFolder(node: Node): boolean { + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('rule:rules'); + } + return false; + } + + isLinkFolder(node: Node): boolean { + return node?.nodeType === 'app:folderlink'; + } + + private getNodeAspectNames(node: Node): string[] { + return node?.aspectNames || []; + } }