From 3064c0fc9a750f5214d2b7971545233ac1726932 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 04:13:25 +0530 Subject: [PATCH 01/60] [ACS-5540] changes for edit aspect button --- projects/aca-content/assets/app.extensions.json | 12 ++++++++++++ .../metadata-tab/metadata-tab.component.ts | 14 ++++++++++++-- .../src/lib/ui/variables/variables.scss | 6 +++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 9c0d7fff4d..c65d769e9d 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -1240,6 +1240,18 @@ "visible": "showInfoSelectionButton" } }, + { + "id": "app.toolbar.aspects", + "order": 160, + "title": "APP.ACTIONS.CHANGE_ASPECT", + "icon": "playlist_add", + "actions": { + "click": "ASPECT_LIST" + }, + "rules": { + "visible": "canEditAspects" + } + }, { "id": "app.sidebar.expand", "order": 200, diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts index dfcaad995f..f0fa0c66c4 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -39,14 +39,16 @@ import { Actions, ofType } from '@ngrx/effects'; imports: [CommonModule, ContentMetadataModule], selector: 'app-metadata-tab', template: ` - - + `, encapsulation: ViewEncapsulation.None, host: { class: 'app-metadata-tab' } @@ -57,6 +59,14 @@ export class MetadataTabComponent implements OnInit, OnDestroy { @Input() node: Node; + /** Display tags in the card **/ + @Input() + displayTags = true; + + /** Display categories in the card **/ + @Input() + displayCategories = true; + displayAspect$: Observable; canUpdateNode = false; editable = false; diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 8a11c08041..a3d528e0f0 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,6 +36,8 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; +$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); // CSS Variables $defaults: ( @@ -76,7 +78,9 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray + --theme-contrast-gray: $contrast-gray, + --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, + --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color ); // propagates SCSS variables into the CSS variables scope From 6a7f8b5b654c1421b7b1fe865807ec0e536630ad Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 14:29:30 +0530 Subject: [PATCH 02/60] added aspect edit button --- .../components/details/details.component.html | 25 +++++++++++++------ .../components/details/details.component.ts | 15 ++++++++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 2d9dda876a..0d553319f8 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -12,14 +12,23 @@ - {{ 'APP.INFO_DRAWER.TITLE' | translate }} - +
+ + +
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 a025c0409c..956ad8f544 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -22,12 +22,12 @@ * from Hyland Software. If not, see . */ -import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation, OnDestroy, Input } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent } from '@alfresco/aca-shared'; import { NavigateToPreviousPage, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { Subject } from 'rxjs'; -import { BreadcrumbModule, PermissionManagerModule } from '@alfresco/adf-content-services'; +import { BreadcrumbModule, PermissionManagerModule, NodeAspectService } from '@alfresco/adf-content-services'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatIconModule } from '@angular/material/icon'; @@ -59,12 +59,17 @@ import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.c encapsulation: ViewEncapsulation.None }) export class DetailsComponent extends PageComponent implements OnInit, OnDestroy { + @Input() + readOnly = false; + nodeId: string; isLoading: boolean; onDestroy$ = new Subject(); activeTab = 1; + editAspectSupported = false; + hasAllowableOperations = false; - constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private nodeAspectService: NodeAspectService) { super(); } @@ -105,6 +110,10 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new NavigateToPreviousPage()); } + openAspectDialog() { + this.nodeAspectService.updateNodeAspects(this.node.id); + } + ngOnDestroy(): void { this.store.dispatch(new SetSelectedNodesAction([])); this.onDestroy$.next(); From 3e435be1d0d1166b864d8678a25d9bc986680f4b Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 15:09:42 +0530 Subject: [PATCH 03/60] [ACS-5540]fixed unit test cases and added unit test cases --- .../details/details.component.spec.ts | 18 ++++++++++++++++-- .../metadata-tab.component.spec.ts | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) 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 0988ca7033..280dcbb882 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 @@ -31,10 +31,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Store } from '@ngrx/store'; import { ContentApiService } from '@alfresco/aca-shared'; import { STORE_INITIAL_APP_DATA, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; -import { NodeEntry } from '@alfresco/js-api'; +import { MinimalNodeEntryEntity, NodeEntry } from '@alfresco/js-api'; import { RouterTestingModule } from '@angular/router/testing'; import { AuthenticationService, PageTitleService } from '@alfresco/adf-core'; -import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { NodeAspectService, SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('DetailsComponent', () => { let component: DetailsComponent; @@ -42,6 +42,7 @@ describe('DetailsComponent', () => { let contentApiService: ContentApiService; let store: Store; let node: NodeEntry; + let mockNodeAspectService: jasmine.SpyObj; const mockStream = new Subject(); const storeMock = { @@ -50,6 +51,7 @@ describe('DetailsComponent', () => { }; beforeEach(() => { + const nodeAspectServiceSpy = jasmine.createSpyObj('NodeAspectService', ['updateNodeAspects']); TestBed.configureTestingModule({ imports: [AppTestingModule, DetailsComponent], providers: [ @@ -78,6 +80,10 @@ describe('DetailsComponent', () => { onLogout: new Subject(), isLoggedIn: () => true } + }, + { + provide: NodeAspectService, + useValue: nodeAspectServiceSpy } ], schemas: [NO_ERRORS_SCHEMA] @@ -86,6 +92,8 @@ describe('DetailsComponent', () => { fixture = TestBed.createComponent(DetailsComponent); component = fixture.componentInstance; contentApiService = TestBed.inject(ContentApiService); + mockNodeAspectService = TestBed.inject(NodeAspectService) as jasmine.SpyObj; + component.node = { id: 'test-id' } as MinimalNodeEntryEntity; store = TestBed.inject(Store); node = { @@ -128,4 +136,10 @@ describe('DetailsComponent', () => { fixture.detectChanges(); expect(store.dispatch).toHaveBeenCalledWith(new SetSelectedNodesAction([node])); }); + + it('should call openAspectDialog and updateNodeAspects when the button is clicked', () => { + component.openAspectDialog(); + fixture.detectChanges(); + expect(mockNodeAspectService.updateNodeAspects).toHaveBeenCalledWith('test-id'); + }); }); diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index f990d7b3d5..4d01789afc 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -256,7 +256,7 @@ describe('MetadataTabComponent', () => { }); it('show pass empty when store is in initial state', () => { - const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card')); + const initialState = fixture.debugElement.query(By.css('adf-content-metadata')); expect(initialState.componentInstance.displayAspect).toBeFalsy(); }); @@ -266,7 +266,7 @@ describe('MetadataTabComponent', () => { expect(aspect).toBe('EXIF'); }); fixture.detectChanges(); - const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card')); + const initialState = fixture.debugElement.query(By.css('adf-content-metadata')); expect(initialState.componentInstance.displayAspect).toBe('EXIF'); }); }); From bcd2d1c1476092b7d9d7d84fd64a6fb2c91789a8 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Tue, 5 Sep 2023 21:22:45 +0530 Subject: [PATCH 04/60] [ACS-5540] Modified changes --- .../components/details/details.component.html | 2 +- .../components/details/details.component.ts | 25 +++++++++++++++---- .../toggle-edit-offline.component.ts | 5 +++- .../src/lib/services/node-actions.service.ts | 15 +++++++++-- .../ui/overrides/adf-style-fixes.theme.scss | 19 ++++++++++++++ .../src/lib/ui/variables/variables.scss | 4 ++- 6 files changed, 60 insertions(+), 10 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 0d553319f8..ff3378f3a3 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -13,7 +13,7 @@ {{ 'APP.INFO_DRAWER.TITLE' | translate }}
-
-
- -
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 778bead773..de481d4647 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -1,19 +1,29 @@ app-details-manager { - .aca-close-details-button { - margin-right: 15px; - margin-top: 2px; - outline: none; - border-radius: 4px; - - &:focus { - background-color: var(--theme-selected-background-color); - outline: 2px solid var(--theme-blue-button-color); - border-radius: 4px; - } + .acs-details-buttons { + display: flex; - &:focus-visible { - outline: 2px solid var(--theme-blue-button-color); + .aca-close-details-button { + margin-right: 15px; + margin-top: 2px; + outline: none; border-radius: 4px; + + &:focus { + background-color: var(--theme-selected-background-color); + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + } + + &:focus-visible { + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + margin-top: 12px; + + &:focus-visible { + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + } + } } } } 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 264445fbe4..0988ca7033 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 @@ -31,10 +31,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Store } from '@ngrx/store'; import { ContentApiService } from '@alfresco/aca-shared'; import { STORE_INITIAL_APP_DATA, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; -import { Node, NodeEntry } from '@alfresco/js-api'; +import { NodeEntry } from '@alfresco/js-api'; import { RouterTestingModule } from '@angular/router/testing'; import { AuthenticationService, PageTitleService } from '@alfresco/adf-core'; -import { NodeAspectService, SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('DetailsComponent', () => { let component: DetailsComponent; @@ -42,7 +42,6 @@ describe('DetailsComponent', () => { let contentApiService: ContentApiService; let store: Store; let node: NodeEntry; - let nodeAspectService: NodeAspectService; const mockStream = new Subject(); const storeMock = { @@ -87,8 +86,6 @@ describe('DetailsComponent', () => { fixture = TestBed.createComponent(DetailsComponent); component = fixture.componentInstance; contentApiService = TestBed.inject(ContentApiService); - nodeAspectService = TestBed.inject(NodeAspectService); - component.node = { id: 'test-id' } as Node; store = TestBed.inject(Store); node = { @@ -106,7 +103,6 @@ describe('DetailsComponent', () => { } }; spyOn(contentApiService, 'getNode').and.returnValue(of(node)); - spyOn(nodeAspectService, 'updateNodeAspects'); }); afterEach(() => { @@ -132,26 +128,4 @@ describe('DetailsComponent', () => { fixture.detectChanges(); expect(store.dispatch).toHaveBeenCalledWith(new SetSelectedNodesAction([node])); }); - - it('should call updateNodeAspects when the aspect dialog is opened', () => { - component.openAspectDialog(); - fixture.detectChanges(); - expect(nodeAspectService.updateNodeAspects).toHaveBeenCalledWith('test-id'); - }); - - 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'); - fixture.detectChanges(); - component.ngOnDestroy(); - expect(component.onDestroy$.complete).toHaveBeenCalled(); - }); }); 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 d454acac10..567d7c816c 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -22,12 +22,12 @@ * from Hyland Software. If not, see . */ -import { Component, OnInit, ViewEncapsulation, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent, isLocked } from '@alfresco/aca-shared'; -import { NavigateToPreviousPage, SetSelectedNodesAction, getAppSelection } from '@alfresco/aca-shared/store'; +import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent } from '@alfresco/aca-shared'; +import { NavigateToPreviousPage, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { Subject } from 'rxjs'; -import { BreadcrumbModule, PermissionManagerModule, NodeAspectService } from '@alfresco/adf-content-services'; +import { BreadcrumbModule, PermissionManagerModule } from '@alfresco/adf-content-services'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatIconModule } from '@angular/material/icon'; @@ -36,9 +36,8 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatButtonModule } from '@angular/material/button'; import { MetadataTabComponent } from '../info-drawer/metadata-tab/metadata-tab.component'; import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.component'; -import { NodeActionsService } from '../../services/node-actions.service'; -import { NodeEntry } from '@alfresco/js-api'; import { takeUntil } from 'rxjs/operators'; +import { ContentActionRef } from '@alfresco/adf-extensions'; @Component({ standalone: true, @@ -66,16 +65,9 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy isLoading: boolean; onDestroy$ = new Subject(); activeTab = 1; - selectionState: NodeEntry; - isNodeLocked = false; + actionsAspect: Array = []; - constructor( - private route: ActivatedRoute, - private contentApi: ContentApiService, - private nodeAspectService: NodeAspectService, - private nodeActionsService: NodeActionsService, - private cdr: ChangeDetectorRef - ) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { super(); } @@ -96,14 +88,12 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new SetSelectedNodesAction([{ entry: this.node }])); }); }); - this.store.select(getAppSelection).subscribe(({ file }) => { - this.selectionState = file; - const isNodeLockedFromStore = this.selection && isLocked(this.selectionState); - this.nodeActionsService.isNodeLocked$.pipe(takeUntil(this.onDestroy$)).subscribe((isNodeLockedFromService) => { - this.isNodeLocked = isNodeLockedFromStore || isNodeLockedFromService; - this.cdr.detectChanges(); + this.extensions + .getAllowedSidebarActions() + .pipe(takeUntil(this.onDestroy$)) + .subscribe((actionsAspect) => { + this.actionsAspect = actionsAspect; }); - }); } setActiveTab(tabName: string) { @@ -124,10 +114,6 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new NavigateToPreviousPage()); } - openAspectDialog() { - this.nodeAspectService.updateNodeAspects(this.node.id); - } - ngOnDestroy(): void { this.store.dispatch(new SetSelectedNodesAction([])); this.onDestroy$.next(); diff --git a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts index 11a3c38227..e061c2a599 100644 --- a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts +++ b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts @@ -26,10 +26,9 @@ import { ToggleEditOfflineComponent } from './toggle-edit-offline.component'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { Store } from '@ngrx/store'; -import { NodeEntry, NodesApi } from '@alfresco/js-api'; +import { NodeEntry } from '@alfresco/js-api'; import { DownloadNodesAction, EditOfflineAction, SnackbarErrorAction } from '@alfresco/aca-shared/store'; import { AppTestingModule } from '../../../testing/app-testing.module'; -import { NodeActionsService } from '../../../services/node-actions.service'; describe('ToggleEditOfflineComponent', () => { let fixture: ComponentFixture; @@ -39,49 +38,6 @@ describe('ToggleEditOfflineComponent', () => { let selectSpy: jasmine.Spy; let selection: any; - const lockedNodeEntry: NodeEntry = { - entry: { - isFile: true, - createdByUser: { - id: 'hruser', - displayName: 'hruser' - }, - modifiedAt: new Date('2023-09-08T11:54:48.325+0000'), - nodeType: 'cm:content', - content: { - mimeType: 'image/jpeg', - mimeTypeName: 'JPEG Image', - sizeInBytes: 128473, - encoding: 'UTF-8' - }, - parentId: '5a2d88ec-a29c-408a-874d-6394940c51d7', - aspectNames: ['cm:versionable', 'cm:lockable', 'cm:auditable', 'cm:taggable', 'exif:exif'], - createdAt: new Date('2023-09-07T11:10:48.788+0000'), - isFolder: false, - modifiedByUser: { - id: 'hruser', - displayName: 'hruser' - }, - name: 'e2e_favorite_file.jpg', - id: '36e5b5ad-3fa0-47e2-b256-016b868ac772', - properties: { - 'cm:lockType': 'WRITE_LOCK', - 'cm:lockOwner': { - id: 'hruser', - displayName: 'hruser' - }, - 'cm:versionType': 'MAJOR', - 'cm:versionLabel': '1.0', - 'cm:lockLifetime': 'PERSISTENT', - 'exif:pixelYDimension': 1253, - 'exif:pixelXDimension': 1024 - } - } - }; - - const nodesApiMock = jasmine.createSpyObj('nodesApi', ['lockNode', 'unlockNode']); - const nodeActionsServiceMock = jasmine.createSpyObj('nodeActionsService', ['setNodeLocked']); - beforeEach(() => { TestBed.configureTestingModule({ imports: [AppTestingModule, ToggleEditOfflineComponent], @@ -92,9 +48,7 @@ describe('ToggleEditOfflineComponent', () => { select: () => {}, dispatch: () => {} } - }, - { provide: NodesApi, useValue: nodesApiMock }, - { provide: NodeActionsService, useValue: nodeActionsServiceMock } + } ] }); @@ -179,51 +133,4 @@ describe('ToggleEditOfflineComponent', () => { }) ]); }); - - it('should call setNodeLocked with true when a node is locked', () => { - const nodeId = 'testNode1'; - nodesApiMock.lockNode.and.returnValue(Promise.resolve(lockedNodeEntry)); - - component.lockNode(nodeId).then((result) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId, { - type: 'ALLOW_OWNER_CHANGES', - lifetime: 'PERSISTENT' - }); - expect(nodeActionsServiceMock.setNodeLocked).toHaveBeenCalledWith(true); - expect(result).toEqual(lockedNodeEntry); - }); - }); - - it('should call setNodeLocked with false when a node is unlocked', () => { - const nodeId = 'testNode2'; - nodesApiMock.unlockNode.and.returnValue(Promise.resolve(lockedNodeEntry)); - - component.unlockNode(nodeId).then((result) => { - expect(nodesApiMock.unlockNode).toHaveBeenCalledWith(nodeId); - expect(nodeActionsServiceMock.setNodeLocked).toHaveBeenCalledWith(false); - expect(result).toEqual(lockedNodeEntry); - }); - }); - - it('should handle errors when locking a node encounters an error', () => { - const nodeId = 'testNode1'; - const error = new Error('Locking failed'); - nodesApiMock.lockNode.and.returnValue(Promise.reject(error)); - component.lockNode(nodeId).catch((err) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId, { type: 'ALLOW_OWNER_CHANGES', lifetime: 'PERSISTENT' }); - expect(nodeActionsServiceMock.setNodeLocked).not.toHaveBeenCalled(); - expect(err).toEqual(error); - }); - }); - - it('should handle errors when unlocking a node encounters an error', () => { - const nodeId = 'testNode1'; - const error = new Error('Unlocking failed'); - nodesApiMock.unlockNode.and.returnValue(Promise.reject(error)); - component.unlockNode(nodeId).catch((err) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId); - expect(nodeActionsServiceMock.setNodeLocked).not.toHaveBeenCalled(); - expect(err).toEqual(error); - }); - }); }); diff --git a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts index a01f6e5f53..40410b94b5 100644 --- a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts +++ b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts @@ -31,7 +31,7 @@ import { getAppSelection } from '@alfresco/aca-shared/store'; import { NodeEntry, SharedLinkEntry, Node, NodesApi } from '@alfresco/js-api'; -import { ChangeDetectorRef, Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; import { AppExtensionService, isLocked } from '@alfresco/aca-shared'; import { AlfrescoApiService } from '@alfresco/adf-core'; @@ -39,7 +39,6 @@ import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatMenuModule } from '@angular/material/menu'; import { MatIconModule } from '@angular/material/icon'; -import { NodeActionsService } from '../../../services/node-actions.service'; @Component({ standalone: true, @@ -60,13 +59,7 @@ export class ToggleEditOfflineComponent implements OnInit { nodeTitle = ''; isNodeLocked = false; - constructor( - private store: Store, - private alfrescoApiService: AlfrescoApiService, - private nodeActionsService: NodeActionsService, - private cdr: ChangeDetectorRef, - private extensions: AppExtensionService - ) { + constructor(private store: Store, private alfrescoApiService: AlfrescoApiService, private extensions: AppExtensionService) { this.nodesApi = new NodesApi(this.alfrescoApiService.getInstance()); } @@ -75,7 +68,6 @@ export class ToggleEditOfflineComponent implements OnInit { this.selection = file; this.isNodeLocked = this.selection && isLocked(this.selection); this.nodeTitle = this.isNodeLocked ? 'APP.ACTIONS.EDIT_OFFLINE_CANCEL' : 'APP.ACTIONS.EDIT_OFFLINE'; - this.cdr.detectChanges(); }); } @@ -127,27 +119,15 @@ export class ToggleEditOfflineComponent implements OnInit { ); } - lockNode(nodeId: string): Promise { - return this.nodesApi.lockNode(nodeId, { type: 'ALLOW_OWNER_CHANGES', lifetime: 'PERSISTENT' }).then( - (res: NodeEntry) => { - this.nodeActionsService.setNodeLocked(true); - return res; - }, - (error) => { - return error; - } - ); + lockNode(nodeId: string) { + return this.nodesApi.lockNode(nodeId, { + type: 'ALLOW_OWNER_CHANGES', + lifetime: 'PERSISTENT' + }); } - unlockNode(nodeId: string): Promise { - return this.nodesApi.unlockNode(nodeId).then( - (res: NodeEntry) => { - this.nodeActionsService.setNodeLocked(false); - return res; - }, - (error) => { - return error; - } - ); + + unlockNode(nodeId: string) { + return this.nodesApi.unlockNode(nodeId); } private update(data: Node) { 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 382f5c9748..2485867783 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -24,7 +24,7 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Observable, Subject, of, zip, from, BehaviorSubject } from 'rxjs'; +import { Observable, Subject, of, zip, from } from 'rxjs'; import { AlfrescoApiService, TranslationService, ThumbnailService } from '@alfresco/adf-core'; import { DocumentListService, @@ -49,7 +49,6 @@ export class NodeActionsService { contentMoved: Subject = new Subject(); moveDeletedEntries: any[] = []; isSitesDestinationAvailable = false; - private isNodeLockedSubject = new BehaviorSubject(false); isNodeLocked$: Observable; _nodesApi: NodesApi; @@ -66,9 +65,7 @@ export class NodeActionsService { private apiService: AlfrescoApiService, private translation: TranslationService, private thumbnailService: ThumbnailService - ) { - this.isNodeLocked$ = this.isNodeLockedSubject.asObservable(); - } + ) {} /** * Copy node list @@ -92,10 +89,6 @@ export class NodeActionsService { return this.doBatchOperation(NodeAction.MOVE, contentEntities, permission, focusedElementOnCloseSelector); } - setNodeLocked(isLocked: boolean) { - this.isNodeLockedSubject.next(isLocked); - } - /** * General method for performing the given operation (copy|move) to multiple nodes * diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index 71333f4bc6..ef23e53556 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -511,6 +511,8 @@ export const canEditAspects = (context: RuleContext): boolean => repository.isMajorVersionAvailable(context, '7') ].every(Boolean); +export const canNotShowExpand = (context: RuleContext): boolean => [!navigation.isLibraries(context), !navigation.isDetails(context)].every(Boolean); + /** * Checks if user can manage permissions for the selected node. * JSON ref: `canManagePermissions` diff --git a/projects/aca-shared/rules/src/navigation.rules.ts b/projects/aca-shared/rules/src/navigation.rules.ts index 02d6a6df93..5a3c5569cf 100644 --- a/projects/aca-shared/rules/src/navigation.rules.ts +++ b/projects/aca-shared/rules/src/navigation.rules.ts @@ -110,6 +110,11 @@ export function isLibraryContent(context: RuleContext): boolean { return url && (url.endsWith('/libraries') || url.includes('/libraries/') || url.startsWith('/search-libraries')); } +export function isDetails(context: RuleContext): boolean { + const { url } = context.navigation; + return url && (url.endsWith('/details') || url.includes('/details/') || url.startsWith('/details')); +} + /** * Checks if the activated route is neither **Libraries** nor **Library Search Results**. * JSON ref: `app.navigation.isNotLibraries` From 5121ad09c062a7c5855fbb22f3d82ec9d882b8cb Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Wed, 13 Sep 2023 12:34:57 +0530 Subject: [PATCH 12/60] [ACS-5540] modified the changes --- .../src/lib/components/details/details.component.html | 2 +- .../src/lib/components/details/details.component.ts | 6 +++--- .../aca-content/src/lib/services/node-actions.service.ts | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index afcde3c44d..18dc2c3b13 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -13,7 +13,7 @@ {{ 'APP.INFO_DRAWER.TITLE' | translate }}
- +
-
From ed561bcf8b2185adf105b5e8fd6add6430f6b17c Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 22 Sep 2023 09:57:33 +0530 Subject: [PATCH 18/60] [ACS-5540]Implemented the changes as per the review comments --- projects/aca-shared/rules/src/navigation.rules.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/aca-shared/rules/src/navigation.rules.spec.ts b/projects/aca-shared/rules/src/navigation.rules.spec.ts index 5f7941f177..44f43e8e7f 100644 --- a/projects/aca-shared/rules/src/navigation.rules.spec.ts +++ b/projects/aca-shared/rules/src/navigation.rules.spec.ts @@ -226,7 +226,7 @@ describe('navigation.evaluators', () => { }); describe('isDetails', () => { - it('should return [true] if url ends with `/details`', () => { + it('should return true if url ends with `/details`', () => { const context: any = { navigation: { url: '/path/details' @@ -236,7 +236,7 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return [true] if url starts with `/details`', () => { + it('should return true if url starts with `/details`', () => { const context: any = { navigation: { url: '/details/path' @@ -246,7 +246,7 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return [true] if url includes with `/details`', () => { + it('should return true if url includes with `/details`', () => { const context: any = { navigation: { url: '/details/path' From c38a0460b8e3c36a0c66bd04fc3ca4e3aa7d184d Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 22 Sep 2023 20:56:13 +0530 Subject: [PATCH 19/60] [ACS-5540] added group lock changes --- .../info-drawer/metadata-tab/metadata-tab.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts index 34f125ddb8..2a5654fae3 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -49,6 +49,7 @@ import { Actions, ofType } from '@ngrx/effects'; [(editable)]="editable" [(editableTags)]="editableTags" [(editableCategories)]="editableCategories" + [(group)]="group" > `, @@ -65,6 +66,9 @@ export class MetadataTabComponent implements OnInit, OnDestroy { editable = false; editableTags = false; editableCategories = false; + group: any = { + editable: false + }; constructor( private permission: NodePermissionService, @@ -98,6 +102,7 @@ export class MetadataTabComponent implements OnInit, OnDestroy { this.editable = false; this.editableTags = false; this.editableCategories = false; + this.group.editable = false; } }); } From f4005753786d191388e953381fbd4543c4672920 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Mon, 25 Sep 2023 15:16:46 +0530 Subject: [PATCH 20/60] [ACS-5540] added tooltip --- projects/aca-content/assets/app.extensions.json | 2 +- projects/aca-content/assets/i18n/en.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 144023805a..51de285a05 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -1243,7 +1243,7 @@ { "id": "app.toolbar.aspects", "order": 160, - "title": "APP.ACTIONS.CHANGE_ASPECT", + "title": "APP.ACTIONS.ADD_ASPECTS", "icon": "playlist_add", "actions": { "click": "ASPECT_LIST" diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index bab98e67e3..0c07008e4e 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -259,7 +259,8 @@ "LEAVE": "Leave Library", "EDIT_OFFLINE": "Edit Offline", "EDIT_OFFLINE_CANCEL": "Cancel Editing", - "CHANGE_ASPECT": "Edit Aspects" + "CHANGE_ASPECT": "Edit Aspects", + "ADD_ASPECTS": "Add Aspects" }, "DIALOGS": { "CONFIRM_PURGE": { From 1116dfd3aeb41fcb5c3dcb30d07ffda696686dbd Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 28 Sep 2023 11:19:39 +0530 Subject: [PATCH 21/60] [ACS-5540] Implemented the review comments --- .../components/details/details.component.scss | 2 +- .../rules/src/navigation.rules.spec.ts | 18 ++++-------------- .../aca-shared/rules/src/navigation.rules.ts | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index de481d4647..4e76575e86 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -4,7 +4,7 @@ app-details-manager { .aca-close-details-button { margin-right: 15px; - margin-top: 2px; + margin-top: 12px; outline: none; border-radius: 4px; diff --git a/projects/aca-shared/rules/src/navigation.rules.spec.ts b/projects/aca-shared/rules/src/navigation.rules.spec.ts index 44f43e8e7f..9582223e44 100644 --- a/projects/aca-shared/rules/src/navigation.rules.spec.ts +++ b/projects/aca-shared/rules/src/navigation.rules.spec.ts @@ -226,17 +226,7 @@ describe('navigation.evaluators', () => { }); describe('isDetails', () => { - it('should return true if url ends with `/details`', () => { - const context: any = { - navigation: { - url: '/path/details' - } - }; - - expect(app.isDetails(context)).toBe(true); - }); - - it('should return true if url starts with `/details`', () => { + it('should return true if url includes with `/details`', () => { const context: any = { navigation: { url: '/details/path' @@ -246,14 +236,14 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return true if url includes with `/details`', () => { + it('should return false if url not includes with `/details`', () => { const context: any = { navigation: { - url: '/details/path' + url: '/path' } }; - expect(app.isDetails(context)).toBe(true); + expect(app.isDetails(context)).toBe(false); }); }); diff --git a/projects/aca-shared/rules/src/navigation.rules.ts b/projects/aca-shared/rules/src/navigation.rules.ts index 5a3c5569cf..a26d8a2366 100644 --- a/projects/aca-shared/rules/src/navigation.rules.ts +++ b/projects/aca-shared/rules/src/navigation.rules.ts @@ -112,7 +112,7 @@ export function isLibraryContent(context: RuleContext): boolean { export function isDetails(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.endsWith('/details') || url.includes('/details/') || url.startsWith('/details')); + return url?.includes('/details'); } /** From fab07b9a9bdf2170e4239e29625db8bcee7ba489 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 28 Sep 2023 17:51:28 +0530 Subject: [PATCH 22/60] [ACS-5540] added tooltips --- projects/aca-content/assets/i18n/en.json | 4 ++-- .../src/lib/components/details/details.component.html | 2 +- projects/aca-content/src/lib/ui/variables/variables.scss | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index 0c07008e4e..faf977f981 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -395,7 +395,7 @@ }, "INFO_DRAWER": { "TITLE": "Details", - "CLOSE": "Close", + "REDUCE_PANEL": "Reduce panel", "DATA_LOADING": "Data is loading", "TABS": { "PROPERTIES": "Properties", @@ -403,7 +403,7 @@ "VERSIONS": "Versions", "COMMENTS": "Comments", "PERMISSIONS": "Permissions", - "EXPAND": "Expand" + "EXPAND": "Expand panel" } }, "TOOLTIPS": { diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 7ba883cee6..d2b2b752b5 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -18,7 +18,7 @@ class="aca-close-details-button" mat-icon-button data-automation-id="close-library" - title="{{ 'APP.INFO_DRAWER.CLOSE' | translate }}" + title="{{ 'APP.INFO_DRAWER.REDUCE_PANEL' | translate }}" (click)="goBack()"> fullscreen_exit diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 8e4c0be6d9..45bcc8ecd8 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -38,6 +38,7 @@ $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; $metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); $metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$metadata-action-button-clear-color: #212328b2; // CSS Variables $defaults: ( @@ -80,7 +81,8 @@ $defaults: ( --theme-disabled-chip-background-color: $disabled-chip-background-color, --theme-contrast-gray: $contrast-gray, --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, - --theme-metadata-buttons-background-color: $metadata-buttons-background-color + --theme-metadata-buttons-background-color: $metadata-buttons-background-color, + --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color ); // propagates SCSS variables into the CSS variables scope From 627c953ed0c50736cafc98d9352921c23fe016f9 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Tue, 3 Oct 2023 21:35:48 +0530 Subject: [PATCH 23/60] [ACS-5540] Added styles --- .../src/lib/ui/overrides/adf-style-fixes.theme.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss index fc30adc81a..f96504711a 100644 --- a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss +++ b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss @@ -27,6 +27,10 @@ border: 1px solid var(--theme-metadata-property-panel-border-color); margin: 24px; border-radius: 12px; + + .adf-metadata-properties-group-title { + width: 548px; + } } } } From 0559405f183abf13a17d1a3e15bc5044aca443b3 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Wed, 4 Oct 2023 12:02:27 +0530 Subject: [PATCH 24/60] [ACS-5540]Added focus --- .../src/lib/ui/overrides/adf-style-fixes.theme.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss index f96504711a..0daf5ea047 100644 --- a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss +++ b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss @@ -17,6 +17,10 @@ border: 1px solid var(--theme-metadata-property-panel-border-color); border-radius: 12px; margin-bottom: 12px; + + .mat-expansion-panel-header { + border-radius: 12px; + } } .acs-details-container { @@ -28,6 +32,10 @@ margin: 24px; border-radius: 12px; + .mat-expansion-panel-header { + border-radius: 12px; + } + .adf-metadata-properties-group-title { width: 548px; } From 8d492e6e8836400cdf1526e3d89951057967d90a Mon Sep 17 00:00:00 2001 From: Eugenio Romano Date: Tue, 10 Oct 2023 09:30:58 +0200 Subject: [PATCH 25/60] [AAE-14484] fix peerdepend (#3471) * fix peerdepend * Update package.json --- projects/aca-content/package.json | 26 +++++++++++------------ projects/aca-shared/package.json | 34 +++++++++++++++---------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/projects/aca-content/package.json b/projects/aca-content/package.json index b2cedb1300..511122760a 100644 --- a/projects/aca-content/package.json +++ b/projects/aca-content/package.json @@ -3,19 +3,19 @@ "version": "0.0.1", "license": "LGPL-3.0", "peerDependencies": { - "@angular/common": "^14.1.0", - "@angular/core": "^14.1.0", - "@alfresco/adf-core": "^6.4.0-6341205853", - "@alfresco/adf-content-services": "^6.4.0-6341205853", - "@alfresco/adf-extensions": "^6.4.0-6341205853", - "@alfresco/js-api": "^7.1.0-1349", - "@angular/animations": "^14.1.3", - "@angular/cdk": "^14.1.3", - "@angular/forms": "^14.1.3", - "@angular/material": "^14.1.3", - "@ngx-translate/core": "^14.0.0", - "rxjs": "6.6.6", - "zone.js": "0.11.8" + "@angular/common": ">=14.1.0", + "@angular/core": ">=14.1.0", + "@alfresco/adf-core": ">=6.4.0-6341205853", + "@alfresco/adf-content-services": ">=6.4.0-6341205853", + "@alfresco/adf-extensions": ">=6.4.0-6341205853", + "@alfresco/js-api": ">=7.1.0-1349", + "@angular/animations": ">=14.1.3", + "@angular/cdk": ">=14.1.3", + "@angular/forms": ">=14.1.3", + "@angular/material": ">=14.1.3", + "@ngx-translate/core": ">=14.0.0", + "rxjs": ">=6.6.6", + "zone.js": ">=0.11.8" }, "dependencies": { "tslib": "^2.3.0" diff --git a/projects/aca-shared/package.json b/projects/aca-shared/package.json index f52ff74242..7c792e3150 100644 --- a/projects/aca-shared/package.json +++ b/projects/aca-shared/package.json @@ -5,23 +5,23 @@ "license": "LGPL-3.0", "scripts": {}, "peerDependencies": { - "@alfresco/adf-content-services": "^6.4.0-6341205853", - "@alfresco/adf-core": "^6.4.0-6341205853", - "@alfresco/adf-extensions": "^6.4.0-6341205853", - "@alfresco/js-api": "^7.1.0-1349", - "@angular/animations": "^14.1.3", - "@angular/common": "^14.1.3", - "@angular/compiler": "^14.1.3", - "@angular/core": "^14.1.3", - "@angular/forms": "^14.1.3", - "@angular/material": "^14.1.3", - "@ngrx/effects": "^14.2.0", - "@ngrx/router-store": "^14.2.0", - "@ngrx/store": "^14.2.0", - "@ngx-translate/core": "^14.0.0", - "rxjs": "6.6.6", - "tslib": "^2.0.0", - "zone.js": "0.11.8" + "@alfresco/adf-content-services": ">=6.4.0-6341205853", + "@alfresco/adf-core": ">=6.4.0-6341205853", + "@alfresco/adf-extensions": ">=6.4.0-6341205853", + "@alfresco/js-api": ">=7.1.0-1349", + "@angular/animations": ">=14.1.3", + "@angular/common": ">=14.1.3", + "@angular/compiler": ">=14.1.3", + "@angular/core": ">=14.1.3", + "@angular/forms": ">=14.1.3", + "@angular/material": ">=14.1.3", + "@ngrx/effects": ">=14.2.0", + "@ngrx/router-store": ">=14.2.0", + "@ngrx/store": ">=14.2.0", + "@ngx-translate/core": ">=14.0.0", + "rxjs": ">=6.6.6", + "tslib": ">=2.0.0", + "zone.js": ">=0.11.8" }, "repository": { "type": "git", From f92a2b19edd85b7759eb5cba1d8fdf9c120a540d Mon Sep 17 00:00:00 2001 From: swapnil-verma-gl <92505353+swapnil-verma-gl@users.noreply.github.com> Date: Wed, 11 Oct 2023 18:00:44 +0530 Subject: [PATCH 26/60] [ACS-4130] Added autocomplete to folder rules 'Has Category' condition (#3464) * [ACS-4130] Added autocomplete for 'Has Category' option in manage rules * [ACS-4130] Added loading spinner and 'No options found' template for Has Category rule condition. Options are now fetched as soon as user selected 'Has Category' option * [ACS-4130] Added code to fetch category name when viewing/editing existing rule with has category option selected * [ACS-4130] Resolved issues related to editing existing rules with 'Has Category' condition * [ACS-4130] Added safety checks and minor code refactoring * [ACS-4130] Added unit tests for new autocomplete functionality * [ACS-4130] Added feature to auto select first option from autocomplete dropdown when user focuses out of autocomplete input field * [ACS-4130] Minor code refactoring. Moved constants from global scope to local scope * [ACS-4130] Moved mock data to conditions.mock.ts. Removed redundant return type * [ACS-4130] Resolved PR review comments - AutoCompleteOption is now an interface. Changed occurences of autocomplete with auto-complete. Removed/Added types * [ACS-4130] Resolved PR review comments - AutoCompleteOption is now built using a single common helper method * [ACS-4130] Added missed types --- .../folder-rules/assets/i18n/en.json | 3 + .../folder-rules/src/mock/conditions.mock.ts | 57 +++++++- .../conditions/rule-condition-fields.ts | 6 +- .../rule-simple-condition.ui-component.html | 46 ++++++- .../rule-simple-condition.ui-component.scss | 7 + ...rule-simple-condition.ui-component.spec.ts | 128 +++++++++++++++++- .../rule-simple-condition.ui-component.ts | 126 +++++++++++++++-- 7 files changed, 350 insertions(+), 23 deletions(-) diff --git a/projects/aca-content/folder-rules/assets/i18n/en.json b/projects/aca-content/folder-rules/assets/i18n/en.json index fc89fd29b2..7387ef8242 100644 --- a/projects/aca-content/folder-rules/assets/i18n/en.json +++ b/projects/aca-content/folder-rules/assets/i18n/en.json @@ -139,6 +139,9 @@ }, "ERRORS": { "DELETE_RULE_SET_LINK_FAILED": "Error while trying to delete a link from a rule set" + }, + "AUTOCOMPLETE": { + "NO_OPTIONS_FOUND": "No options found" } } } diff --git a/projects/aca-content/folder-rules/src/mock/conditions.mock.ts b/projects/aca-content/folder-rules/src/mock/conditions.mock.ts index e471e49d27..e3aae15494 100644 --- a/projects/aca-content/folder-rules/src/mock/conditions.mock.ts +++ b/projects/aca-content/folder-rules/src/mock/conditions.mock.ts @@ -37,12 +37,65 @@ export const mimeTypeMock: RuleSimpleCondition = { parameter: '' }; -export const categoryMock: RuleSimpleCondition = { - field: 'category', +export const tagMock: RuleSimpleCondition = { + field: 'tag', comparator: 'equals', parameter: '' }; +export const categoriesListMock = { + list: { + pagination: { + count: 3, + hasMoreItems: false, + totalItems: 0, + skipCount: 0, + maxItems: 25 + }, + entries: [ + { + entry: { + path: { + name: '/a/fake/category/path/1' + }, + hasChildren: false, + name: 'FakeCategory1', + id: 'fake-category-id-1', + nodeType: 'cm:category', + isFile: false, + isFolder: false + } + }, + { + entry: { + path: { + name: '/a/fake/category/path/2' + }, + hasChildren: false, + name: 'FakeCategory2', + id: 'fake-category-id-2', + nodeType: 'cm:category', + isFile: false, + isFolder: false + } + }, + { + entry: { + path: { + name: '/a/fake/category/path/3' + }, + hasChildren: false, + name: 'FakeCategory3', + id: 'fake-category-id-3', + nodeType: 'cm:category', + isFile: false, + isFolder: false + } + } + ] + } +}; + export const simpleConditionUnknownFieldMock: RuleSimpleCondition = { field: 'unknown-field', comparator: 'equals', diff --git a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-condition-fields.ts b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-condition-fields.ts index af77ab683e..7575e226a4 100644 --- a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-condition-fields.ts +++ b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-condition-fields.ts @@ -22,7 +22,7 @@ * from Hyland Software. If not, see . */ -export type RuleConditionFieldType = 'string' | 'number' | 'date' | 'type' | 'special' | 'mimeType'; +export type RuleConditionFieldType = 'string' | 'number' | 'date' | 'type' | 'special' | 'mimeType' | 'auto-complete'; export interface RuleConditionField { name: string; @@ -30,7 +30,7 @@ export interface RuleConditionField { type: RuleConditionFieldType; } -export const comparatorHiddenForConditionFieldType: string[] = ['special', 'mimeType']; +export const comparatorHiddenForConditionFieldType: string[] = ['special', 'mimeType', 'auto-complete']; export const ruleConditionFields: RuleConditionField[] = [ { @@ -56,7 +56,7 @@ export const ruleConditionFields: RuleConditionField[] = [ { name: 'category', label: 'ACA_FOLDER_RULES.RULE_DETAILS.FIELDS.HAS_CATEGORY', - type: 'special' + type: 'auto-complete' }, { name: 'tag', diff --git a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.html b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.html index 290e850577..8cff2654dd 100644 --- a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.html +++ b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.html @@ -21,14 +21,54 @@ - - + + {{ mimeType.label }} - + + + + + + + + + + + + {{ option.displayLabel }} + + + + + {{ 'ACA_FOLDER_RULES.AUTOCOMPLETE.NO_OPTIONS_FOUND' | translate }} + + + + + + diff --git a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.scss b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.scss index 1d9e989ed4..958e977805 100644 --- a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.scss +++ b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.scss @@ -15,4 +15,11 @@ } } } + + &__auto-complete-loading-spinner { + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + } } diff --git a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.spec.ts b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.spec.ts index 5185027c09..adbb87c3e3 100644 --- a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.spec.ts +++ b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.spec.ts @@ -22,16 +22,21 @@ * from Hyland Software. If not, see . */ -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFixture, discardPeriodicTasks, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { RuleSimpleConditionUiComponent } from './rule-simple-condition.ui-component'; import { CoreTestingModule } from '@alfresco/adf-core'; import { By } from '@angular/platform-browser'; import { DebugElement } from '@angular/core'; -import { categoryMock, mimeTypeMock, simpleConditionUnknownFieldMock } from '../../mock/conditions.mock'; +import { tagMock, mimeTypeMock, simpleConditionUnknownFieldMock, categoriesListMock } from '../../mock/conditions.mock'; import { MimeType } from './rule-mime-types'; +import { CategoryService } from '@alfresco/adf-content-services'; +import { of } from 'rxjs'; +import { RuleSimpleCondition } from '../../model/rule-simple-condition.model'; +import { delay } from 'rxjs/operators'; describe('RuleSimpleConditionUiComponent', () => { let fixture: ComponentFixture; + let categoryService: CategoryService; const getByDataAutomationId = (dataAutomationId: string): DebugElement => fixture.debugElement.query(By.css(`[data-automation-id="${dataAutomationId}"]`)); @@ -45,12 +50,20 @@ describe('RuleSimpleConditionUiComponent', () => { fixture.detectChanges(); }; + const setValueInInputField = (inputFieldDataAutomationId: string, value: string) => { + const inputField = fixture.debugElement.query(By.css(`[data-automation-id="${inputFieldDataAutomationId}"]`)).nativeElement; + inputField.value = value; + inputField.dispatchEvent(new Event('input')); + fixture.detectChanges(); + }; + beforeEach(() => { TestBed.configureTestingModule({ imports: [CoreTestingModule, RuleSimpleConditionUiComponent] }); fixture = TestBed.createComponent(RuleSimpleConditionUiComponent); + categoryService = TestBed.inject(CategoryService); }); it('should default the field to the name, the comparator to equals and the value empty', () => { @@ -87,6 +100,20 @@ describe('RuleSimpleConditionUiComponent', () => { expect(getComputedStyle(comparatorFormField).display).toBe('none'); }); + it('should hide the comparator select box if the type of the field is autoComplete', () => { + const autoCompleteField = 'category'; + fixture.detectChanges(); + const comparatorFormField = getByDataAutomationId('comparator-form-field').nativeElement; + + expect(fixture.componentInstance.isComparatorHidden).toBeFalsy(); + expect(getComputedStyle(comparatorFormField).display).not.toBe('none'); + + changeMatSelectValue('field-select', autoCompleteField); + + expect(fixture.componentInstance.isComparatorHidden).toBeTruthy(); + expect(getComputedStyle(comparatorFormField).display).toBe('none'); + }); + it('should set the comparator to equals if the field is set to a type with different comparators', () => { const onChangeFieldSpy = spyOn(fixture.componentInstance, 'onChangeField').and.callThrough(); fixture.detectChanges(); @@ -165,9 +192,104 @@ describe('RuleSimpleConditionUiComponent', () => { expect(getByDataAutomationId('simple-condition-value-select')).toBeTruthy(); - fixture.componentInstance.writeValue(categoryMock); + fixture.componentInstance.writeValue(tagMock); fixture.detectChanges(); expect(getByDataAutomationId('value-input').nativeElement.value).toBe(''); }); + + it('should provide auto-complete option when category is selected', () => { + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + + expect(getByDataAutomationId('auto-complete-input-field')).toBeTruthy(); + expect(fixture.componentInstance.form.get('parameter').value).toEqual(''); + }); + + it('should fetch category list when category option is selected', fakeAsync(() => { + spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock)); + + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + tick(500); + + expect(categoryService.searchCategories).toHaveBeenCalledWith(''); + })); + + it('should fetch new category list with user input when user types into parameter field after category option is select', fakeAsync(() => { + const categoryValue = 'a new category'; + spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock)); + + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + tick(500); + expect(categoryService.searchCategories).toHaveBeenCalledWith(''); + + setValueInInputField('auto-complete-input-field', categoryValue); + tick(500); + expect(categoryService.searchCategories).toHaveBeenCalledWith(categoryValue); + })); + + it('should fetch category details when a saved rule with category condition is edited', () => { + const savedCategoryMock: RuleSimpleCondition = { + field: 'category', + comparator: 'equals', + parameter: 'a-fake-category-id' + }; + + const fakeCategory = { + entry: { + path: '/a/fake/category/path', + hasChildren: false, + name: 'FakeCategory', + id: 'fake-category-id-1' + } + }; + spyOn(categoryService, 'getCategory').and.returnValue(of(fakeCategory)); + + fixture.componentInstance.writeValue(savedCategoryMock); + fixture.detectChanges(); + + expect(categoryService.getCategory).toHaveBeenCalledWith(savedCategoryMock.parameter, { include: ['path'] }); + }); + + it('should show loading spinner while auto-complete options are fetched, and then remove it once it is received', fakeAsync(() => { + spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock).pipe(delay(1000))); + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + tick(500); + getByDataAutomationId('auto-complete-input-field')?.nativeElement?.click(); + let loadingSpinner = getByDataAutomationId('auto-complete-loading-spinner'); + expect(loadingSpinner).not.toBeNull(); + tick(1000); + fixture.detectChanges(); + loadingSpinner = getByDataAutomationId('auto-complete-loading-spinner'); + expect(loadingSpinner).toBeNull(); + discardPeriodicTasks(); + })); + + it('should display correct label for category when user selects a category from auto-complete dropdown', fakeAsync(() => { + spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock)); + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + tick(500); + getByDataAutomationId('auto-complete-input-field')?.nativeElement?.click(); + changeMatSelectValue('folder-rule-auto-complete', categoriesListMock.list.entries[0].entry.id); + const displayValue = getByDataAutomationId('auto-complete-input-field')?.nativeElement?.value; + expect(displayValue).toBe('category/path/1/FakeCategory1'); + discardPeriodicTasks(); + })); + + it('should automatically select first category when user focuses out of parameter form field with category option selected', fakeAsync(() => { + spyOn(categoryService, 'searchCategories').and.returnValue(of(categoriesListMock)); + fixture.detectChanges(); + changeMatSelectValue('field-select', 'category'); + tick(500); + const autoCompleteInputField = getByDataAutomationId('auto-complete-input-field')?.nativeElement; + autoCompleteInputField.value = 'FakeCat'; + autoCompleteInputField.dispatchEvent(new Event('focusout')); + const parameterValue = fixture.componentInstance.form.get('parameter').value; + expect(parameterValue).toEqual(categoriesListMock.list.entries[0].entry.id); + discardPeriodicTasks(); + })); }); diff --git a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.ts b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.ts index cc3f4193be..a3cda946ab 100644 --- a/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.ts +++ b/projects/aca-content/folder-rules/src/rule-details/conditions/rule-simple-condition.ui-component.ts @@ -22,22 +22,47 @@ * from Hyland Software. If not, see . */ -import { Component, forwardRef, Input, OnDestroy, ViewEncapsulation } from '@angular/core'; +import { Component, forwardRef, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { AbstractControl, ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms'; import { RuleSimpleCondition } from '../../model/rule-simple-condition.model'; import { comparatorHiddenForConditionFieldType, RuleConditionField, ruleConditionFields } from './rule-condition-fields'; import { RuleConditionComparator, ruleConditionComparators } from './rule-condition-comparators'; import { AppConfigService } from '@alfresco/adf-core'; import { MimeType } from './rule-mime-types'; -import { CommonModule } from '@angular/common'; +import { AsyncPipe, CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatSelectModule } from '@angular/material/select'; import { MatInputModule } from '@angular/material/input'; +import { CategoryService } from '@alfresco/adf-content-services'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { debounceTime, distinctUntilChanged, first, takeUntil } from 'rxjs/operators'; +import { Subject, Subscription } from 'rxjs'; +import { MatOptionModule } from '@angular/material/core'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { CategoryEntry } from '@alfresco/js-api'; + +interface AutoCompleteOption { + displayLabel: string; + value: string; +} + +const AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME = 500; @Component({ standalone: true, - imports: [CommonModule, TranslateModule, ReactiveFormsModule, MatFormFieldModule, MatSelectModule, MatInputModule], + imports: [ + CommonModule, + TranslateModule, + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatInputModule, + MatAutocompleteModule, + AsyncPipe, + MatOptionModule, + MatProgressSpinnerModule + ], selector: 'aca-rule-simple-condition', templateUrl: './rule-simple-condition.ui-component.html', styleUrls: ['./rule-simple-condition.ui-component.scss'], @@ -51,7 +76,7 @@ import { MatInputModule } from '@angular/material/input'; } ] }) -export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnDestroy { +export class RuleSimpleConditionUiComponent implements OnInit, ControlValueAccessor, OnDestroy { readonly fields = ruleConditionFields; form = new FormGroup({ @@ -62,6 +87,12 @@ export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnD mimeTypes: MimeType[] = []; + autoCompleteOptions: AutoCompleteOption[] = []; + + showLoadingSpinner: boolean; + + private onDestroy$ = new Subject(); + private autoCompleteOptionsSubscription: Subscription; private _readOnly = false; @Input() get readOnly(): boolean { @@ -71,15 +102,9 @@ export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnD this.setDisabledState(isReadOnly); } - constructor(private config: AppConfigService) { + constructor(private config: AppConfigService, private categoryService: CategoryService) { this.mimeTypes = this.config.get>('mimeTypes'); } - - private formSubscription = this.form.valueChanges.subscribe((value: any) => { - this.onChange(value); - this.onTouch(); - }); - get isSelectedFieldKnown(): boolean { const selectedFieldName = this.form.get('field').value; return this.fields.findIndex((field: RuleConditionField) => selectedFieldName === field.name) > -1; @@ -102,6 +127,7 @@ export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnD get isComparatorHidden(): boolean { return comparatorHiddenForConditionFieldType.includes(this.selectedField?.type); } + get comparatorControl(): AbstractControl { return this.form.get('comparator'); } @@ -115,6 +141,18 @@ export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnD writeValue(value: RuleSimpleCondition) { this.form.setValue(value); + if (value?.field === 'category') { + this.showLoadingSpinner = true; + this.categoryService + .getCategory(value.parameter, { include: ['path'] }) + .pipe(first()) + .subscribe((category: CategoryEntry) => { + this.showLoadingSpinner = false; + const option = this.buildAutocompleteOptionFromCategory(category.entry.id, category.entry.path, category.entry.name); + this.autoCompleteOptions.push(option); + this.parameterControl.setValue(option.value); + }); + } } registerOnChange(fn: () => void) { @@ -147,6 +185,70 @@ export class RuleSimpleConditionUiComponent implements ControlValueAccessor, OnD } ngOnDestroy() { - this.formSubscription.unsubscribe(); + this.onDestroy$.next(); + this.onDestroy$.complete(); + } + + ngOnInit() { + this.form.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((value: RuleSimpleCondition) => { + this.onChange(value); + this.onTouch(); + }); + + this.form + .get('field') + .valueChanges.pipe(distinctUntilChanged(), takeUntil(this.onDestroy$)) + .subscribe((field: string) => { + if (field === 'category') { + this.autoCompleteOptionsSubscription = this.form + .get('parameter') + .valueChanges.pipe(distinctUntilChanged(), debounceTime(AUTOCOMPLETE_OPTIONS_DEBOUNCE_TIME), takeUntil(this.onDestroy$)) + .subscribe((categoryName) => { + this.getCategories(categoryName); + }); + this.parameterControl.setValue(''); + } else { + this.autoCompleteOptionsSubscription?.unsubscribe(); + } + }); + } + + private getCategories(categoryName: string) { + this.showLoadingSpinner = true; + this.categoryService + .searchCategories(categoryName) + .pipe(first()) + .subscribe((existingCategoriesResult) => { + this.showLoadingSpinner = false; + const options: AutoCompleteOption[] = existingCategoriesResult?.list?.entries?.map((rowEntry) => + this.buildAutocompleteOptionFromCategory(rowEntry.entry.id, rowEntry.entry.path.name, rowEntry.entry.name) + ); + if (options.length > 0) { + this.autoCompleteOptions = this.sortAutoCompleteOptions(options); + } + }); + } + + private sortAutoCompleteOptions(autoCompleteOptions: AutoCompleteOption[]): AutoCompleteOption[] { + return autoCompleteOptions.sort((option1, option2) => option1.displayLabel.localeCompare(option2.displayLabel)); + } + + autoCompleteDisplayFunction = (optionValue: string): string => + optionValue && this.autoCompleteOptions ? this.autoCompleteOptions.find((option) => option.value === optionValue)?.displayLabel : optionValue; + + autoSelectValidOption() { + const currentValue = this.parameterControl.value; + const isValidValueSelected = !!this.autoCompleteOptions?.find((option) => option.value === currentValue); + if (!isValidValueSelected) { + this.parameterControl.setValue(this.autoCompleteOptions?.[0].value); + } + } + + buildAutocompleteOptionFromCategory(categoryId: string, categoryPath: string, categoryName: string): AutoCompleteOption { + const path = categoryPath.split('/').splice(3).join('/'); + return { + value: categoryId, + displayLabel: path ? `${path}/${categoryName}` : categoryName + }; } } From 71833269da951d0422066f2f93b36d8f0a248125 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Wed, 6 Sep 2023 20:42:50 +0530 Subject: [PATCH 27/60] [ACS-5551]updated property panel design --- .../components/details/details.component.html | 6 +- .../components/details/details.component.scss | 10 ++-- .../details/details.component.spec.ts | 38 +++++++++++++ .../components/details/details.component.ts | 8 ++- .../lib/services/node-actions.service.spec.ts | 57 ++++++++++++++++++- .../src/lib/services/node-actions.service.ts | 41 +++++++++++++ .../info-drawer/info-drawer.component.html | 6 +- .../page-layout/page-layout.component.scss | 2 + 8 files changed, 156 insertions(+), 12 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index d2b2b752b5..b6b8528e24 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -8,9 +8,9 @@
- {{ node.name }} - - - {{ 'APP.INFO_DRAWER.TITLE' | translate }} + + Info Drawer icon + {{ node.name }}
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 4e76575e86..98caa3dbe1 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -51,17 +51,19 @@ app-details-manager { display: flex; align-items: center; justify-content: space-between; + color: var(--adf-metadata-property-panel-title-color); } .acs-details-breadcrumb { - font-size: 18px; + font-size: 20px; margin-left: 20px; .acs-details-breadcrumb-library { - font-weight: 900; + font-weight: 400; } - .acs-details-breadcrumb-item { - font-weight: 100; + .acs-details-breadcrumb-icon { + display: inline-block; + vertical-align: text-bottom; } } 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 6911afef2e..caa068e453 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 @@ -58,6 +58,38 @@ describe('DetailsComponent', () => { const mockObservable = new BehaviorSubject(mockAspectActions); extensionsServiceMock.getAllowedSidebarActions.and.returnValue(mockObservable); + 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: [AppTestingModule, DetailsComponent], @@ -144,5 +176,11 @@ describe('DetailsComponent', () => { fixture.whenStable().then(() => { expect(component.aspectActions).toEqual(mockAspectActions); }); + it('should return the icon when getInfoDrawerIcon is called', () => { + const expectedIcon = 'assets/images/ft_ic_folder'; + spyOn(component['nodeActionsService'], 'getInfoDrawerIcon').and.returnValue(expectedIcon); + fixture.detectChanges(); + const result = component.getInfoDrawerIcon(mockNode); + expect(result).toContain(expectedIcon); }); }); 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 07a364e846..00ed1d0a53 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -38,6 +38,8 @@ 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({ standalone: true, @@ -67,7 +69,7 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy activeTab = 1; aspectActions: Array = []; - constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private nodeActionsService: NodeActionsService) { super(); } @@ -96,6 +98,10 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy }); } + getInfoDrawerIcon(node: Node): string { + return this.nodeActionsService.getInfoDrawerIcon(node); + } + setActiveTab(tabName: string) { switch (tabName) { case 'comments': 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 f825c894c2..ad62b7bbaa 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, TranslationService } from '@alfresco/adf-core'; +import { AlfrescoApiService, ThumbnailService, 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'; @@ -107,6 +107,7 @@ describe('NodeActionsService', () => { service = TestBed.inject(NodeActionsService); apiService = TestBed.inject(AlfrescoApiService); dialog = TestBed.inject(MatDialog); + apiService.reset(); nodesApi = service['nodesApi']; @@ -1227,4 +1228,58 @@ 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 testInfoDrawerIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { + spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); + mockNode.isFolder = isFoldeType; + mockNode.isFile = isFileType; + const value = service.getInfoDrawerIcon(mockNode); + expect(value).toContain(iconPath); + } + + it('should resolve folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder.svg', true, false); + }); + + it('should resolve smart folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_smart_folder.svg', true, false); + }); + + it('should resolve link folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); + }); + + it('should resolve rule folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder_rule.svg', true, false); + }); + + it('should resolve file icon for content type', () => { + testInfoDrawerIcon('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.getInfoDrawerIcon(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 7b2c1493d2..98bb02a071 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -563,6 +563,47 @@ export class NodeActionsService { return null; } + getInfoDrawerIcon(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 { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects.includes('smf:customConfigSmartFolder') || nodeAspects.includes('smf:systemConfigSmartFolder'); + } + + isRuleFolder(node: Node): boolean { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects.includes('rule:rules'); + } + + isLinkFolder(node: Node): boolean { + const nodeType = node.nodeType; + return nodeType === 'app:folderlink'; + } + + private getNodeAspectNames(node: Node): string[] { + return node.aspectNames ? 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.html b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html index 5f07ca0f5d..31de24e212 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html @@ -2,11 +2,11 @@
- + - + - + \ No newline at end of file diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index 2e1049fc4e..ff881a2cf9 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -37,6 +37,8 @@ .aca-page-layout-content { @include flex-row; + + border-top: 1px solid var(--adf-metadata-property-panel-border-color); } .aca-page-layout-error { From 7866c4017c89d53fe03645e337d6a0c268b2c1d5 Mon Sep 17 00:00:00 2001 From: pkundu Date: Sat, 9 Sep 2023 12:43:04 +0530 Subject: [PATCH 28/60] [ACS-5551]added null checks --- projects/aca-content/assets/i18n/en.json | 1 + .../components/details/details.component.html | 2 +- .../components/details/details.component.scss | 4 +- .../details/details.component.spec.ts | 4 +- .../components/details/details.component.ts | 4 +- .../lib/services/node-actions.service.spec.ts | 12 +++--- .../src/lib/services/node-actions.service.ts | 27 ++++++++----- .../aca-content/src/lib/ui/application.scss | 6 +-- .../src/lib/ui/variables/variables.scss | 17 ++++---- .../info-drawer/info-drawer.component.html | 2 +- .../info-drawer/info-drawer.component.spec.ts | 40 +++++++++++++++++++ .../info-drawer/info-drawer.component.ts | 12 +++++- .../page-layout/page-layout.component.scss | 2 +- 13 files changed, 97 insertions(+), 36 deletions(-) diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index faf977f981..cc001db517 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -397,6 +397,7 @@ "TITLE": "Details", "REDUCE_PANEL": "Reduce panel", "DATA_LOADING": "Data is loading", + "ICON": "Node Icon", "TABS": { "PROPERTIES": "Properties", "LIBRARY_PROPERTIES": "About", diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index b6b8528e24..2446680ae8 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -9,7 +9,7 @@
- Info Drawer icon + {{ 'APP.INFO_DRAWER.ICON' | translate }} {{ node.name }}
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 98caa3dbe1..d5f3b4d2f9 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -51,7 +51,9 @@ app-details-manager { display: flex; align-items: center; justify-content: space-between; - color: var(--adf-metadata-property-panel-title-color); + color: var(--theme-metadata-property-panel-title-color); + text-overflow: ellipsis; + white-space: normal; } .acs-details-breadcrumb { 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 caa068e453..da9eb48c15 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 @@ -178,9 +178,9 @@ describe('DetailsComponent', () => { }); it('should return the icon when getInfoDrawerIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; - spyOn(component['nodeActionsService'], 'getInfoDrawerIcon').and.returnValue(expectedIcon); + spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); - const result = component.getInfoDrawerIcon(mockNode); + const result = component.getNodeIcon(mockNode); expect(result).toContain(expectedIcon); }); }); 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 00ed1d0a53..b4651e7eb3 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -98,8 +98,8 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy }); } - getInfoDrawerIcon(node: Node): string { - return this.nodeActionsService.getInfoDrawerIcon(node); + getNodeIcon(node: Node): string { + return this.nodeActionsService.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 ad62b7bbaa..17d5822812 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 @@ -1246,7 +1246,7 @@ describe('NodeActionsService', () => { thumbnailService = TestBed.inject(ThumbnailService); }); - function testInfoDrawerIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { + function testNodeIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); mockNode.isFolder = isFoldeType; mockNode.isFile = isFileType; @@ -1255,23 +1255,23 @@ describe('NodeActionsService', () => { } it('should resolve folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder.svg', true, false); }); it('should resolve smart folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_smart_folder.svg', true, false); + testNodeIcon('assets/images/ft_ic_smart_folder.svg', true, false); }); it('should resolve link folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); }); it('should resolve rule folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder_rule.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder_rule.svg', true, false); }); it('should resolve file icon for content type', () => { - testInfoDrawerIcon('assets/images/ft_ic_raster_image.svg', false, true); + testNodeIcon('assets/images/ft_ic_raster_image.svg', false, true); }); it('should resolve fallback file icon for unknown node', () => { 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 98bb02a071..4fc02d1632 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -563,12 +563,12 @@ export class NodeActionsService { return null; } - getInfoDrawerIcon(node: Node): string { - if (node.isFolder) { + getNodeIcon(node: Node): string { + if (node?.isFolder) { return this.getFolderIcon(node); } - if (node.isFile) { - return this.thumbnailService.getMimeTypeIcon(node.content.mimeType); + if (node?.isFile) { + return this.thumbnailService.getMimeTypeIcon(node?.content?.mimeType); } return this.thumbnailService.getDefaultMimeTypeIcon(); } @@ -586,22 +586,27 @@ export class NodeActionsService { } isSmartFolder(node: Node): boolean { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects.includes('smf:customConfigSmartFolder') || nodeAspects.includes('smf:systemConfigSmartFolder'); + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('smf:customConfigSmartFolder') || nodeAspects?.includes('smf:systemConfigSmartFolder'); + } + return false; } isRuleFolder(node: Node): boolean { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects.includes('rule:rules'); + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('rule:rules'); + } + return false; } isLinkFolder(node: Node): boolean { - const nodeType = node.nodeType; - return nodeType === 'app:folderlink'; + return node?.nodeType === 'app:folderlink'; } private getNodeAspectNames(node: Node): string[] { - return node.aspectNames ? node.aspectNames : []; + return node?.aspectNames || []; } public getNewNameFrom(name: string, baseName?: string) { diff --git a/projects/aca-content/src/lib/ui/application.scss b/projects/aca-content/src/lib/ui/application.scss index 2be7581910..bfd057e8ed 100644 --- a/projects/aca-content/src/lib/ui/application.scss +++ b/projects/aca-content/src/lib/ui/application.scss @@ -50,9 +50,9 @@ ng-component { .aca-sidebar { display: block; height: 100%; - overflow-y: scroll; - max-width: 350px; - width: 350px; + max-width: 368px; + width: 368px; + border-top: 1px solid var(--theme-metadata-property-panel-border-color); } .aca-page-title { diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 45bcc8ecd8..534a830663 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,9 +36,10 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; -$metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); -$metadata-buttons-background-color: rgba(33, 33, 33, 0.05); -$metadata-action-button-clear-color: #212328b2; +$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$adf-metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); +$adf-metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); // CSS Variables $defaults: ( @@ -79,10 +80,12 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray, - --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, - --theme-metadata-buttons-background-color: $metadata-buttons-background-color, - --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color + --theme-contrast-gray: $contrast-gray + --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, + --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color, + --adf-metadata-property-panel-title-color: $selected-text-color, + --adf-metadata-property-panel-text-color: $adf-metadata-property-panel-text-color, + --adf-metadata-property-panel-label-color: $adf-metadata-property-panel-label-color ); // propagates SCSS variables into the CSS variables scope diff --git a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html index 31de24e212..7b1c8f0595 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html @@ -2,7 +2,7 @@
- + 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 7d16fadfa8..fe94ae7f7e 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 @@ -57,6 +57,38 @@ describe('InfoDrawerComponent', () => { ]) }; + 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: [LibTestingModule, InfoDrawerComponent], @@ -182,4 +214,12 @@ describe('InfoDrawerComponent', () => { } as ContentActionRef ]); }); + + it('should return the icon when getNodeIcon is called', () => { + const expectedIcon = 'assets/images/ft_ic_folder'; + spyOn(component['nodeActionsService'], '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 70c59e0cb4..8d6cd9e927 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,6 +37,7 @@ 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, @@ -64,7 +65,12 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { this.close(); } - constructor(private store: Store, private contentApi: ContentApiService, private extensions: AppExtensionService) {} + constructor( + private store: Store, + private contentApi: ContentApiService, + private extensions: AppExtensionService, + private nodeActionsService: NodeActionsService + ) {} ngOnInit() { this.tabs = this.extensions.getSidebarTabs(); @@ -125,4 +131,8 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { private setDisplayNode(node: any) { this.displayNode = node; } + + getNodeIcon(node: Node): string { + return this.nodeActionsService.getNodeIcon(node); + } } diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index ff881a2cf9..ff8455e474 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -38,7 +38,7 @@ .aca-page-layout-content { @include flex-row; - border-top: 1px solid var(--adf-metadata-property-panel-border-color); + border-top: 1px solid var(--theme-metadata-property-panel-border-color); } .aca-page-layout-error { From 500d8e5380033e3e433132ee26201e15f61f96f8 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 11:03:25 +0530 Subject: [PATCH 29/60] [ACS-5551] update style --- .../details/details.component.spec.ts | 4 +++- .../src/lib/ui/variables/variables.scss | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) 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 da9eb48c15..037e3753f8 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 @@ -176,7 +176,9 @@ describe('DetailsComponent', () => { fixture.whenStable().then(() => { expect(component.aspectActions).toEqual(mockAspectActions); }); - it('should return the icon when getInfoDrawerIcon is called', () => { + }); + + it('should return the icon when getNodeIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 534a830663..f9249ae961 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,10 +36,11 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; -$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); -$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); -$adf-metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); -$adf-metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); +$metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$metadata-action-button-clear-color: #212328b2; +$metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); +$metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); // CSS Variables $defaults: ( @@ -80,12 +81,13 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray - --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, - --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color, - --adf-metadata-property-panel-title-color: $selected-text-color, - --adf-metadata-property-panel-text-color: $adf-metadata-property-panel-text-color, - --adf-metadata-property-panel-label-color: $adf-metadata-property-panel-label-color + --theme-contrast-gray: $contrast-gray, + --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, + --theme-metadata-buttons-background-color: $metadata-buttons-background-color, + --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color, + --theme-metadata-property-panel-title-color: $selected-text-color, + --theme-metadata-property-panel-text-color: $metadata-property-panel-text-color, + --theme-metadata-property-panel-label-color: $metadata-property-panel-label-color ); // propagates SCSS variables into the CSS variables scope From 1484721178ce1799499e3451a723447bedfc35a3 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 04:13:25 +0530 Subject: [PATCH 30/60] [ACS-5540] changes for edit aspect button --- projects/aca-content/assets/app.extensions.json | 12 ++++++++++++ .../metadata-tab/metadata-tab.component.ts | 14 ++++++++++++-- .../src/lib/ui/variables/variables.scss | 6 +++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 9c0d7fff4d..c65d769e9d 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -1240,6 +1240,18 @@ "visible": "showInfoSelectionButton" } }, + { + "id": "app.toolbar.aspects", + "order": 160, + "title": "APP.ACTIONS.CHANGE_ASPECT", + "icon": "playlist_add", + "actions": { + "click": "ASPECT_LIST" + }, + "rules": { + "visible": "canEditAspects" + } + }, { "id": "app.sidebar.expand", "order": 200, diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts index dfcaad995f..f0fa0c66c4 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -39,14 +39,16 @@ import { Actions, ofType } from '@ngrx/effects'; imports: [CommonModule, ContentMetadataModule], selector: 'app-metadata-tab', template: ` - - + `, encapsulation: ViewEncapsulation.None, host: { class: 'app-metadata-tab' } @@ -57,6 +59,14 @@ export class MetadataTabComponent implements OnInit, OnDestroy { @Input() node: Node; + /** Display tags in the card **/ + @Input() + displayTags = true; + + /** Display categories in the card **/ + @Input() + displayCategories = true; + displayAspect$: Observable; canUpdateNode = false; editable = false; diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 8a11c08041..a3d528e0f0 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,6 +36,8 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; +$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); // CSS Variables $defaults: ( @@ -76,7 +78,9 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray + --theme-contrast-gray: $contrast-gray, + --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, + --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color ); // propagates SCSS variables into the CSS variables scope From cb78cd642ca1d9d6bad897695eb6b3c314f533d3 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 14:29:30 +0530 Subject: [PATCH 31/60] added aspect edit button --- .../components/details/details.component.html | 25 +++++++++++++------ .../components/details/details.component.ts | 15 ++++++++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 2d9dda876a..0d553319f8 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -12,14 +12,23 @@ - {{ 'APP.INFO_DRAWER.TITLE' | translate }}
- +
+ + +
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 a025c0409c..956ad8f544 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -22,12 +22,12 @@ * from Hyland Software. If not, see . */ -import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation, OnDestroy, Input } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent } from '@alfresco/aca-shared'; import { NavigateToPreviousPage, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { Subject } from 'rxjs'; -import { BreadcrumbModule, PermissionManagerModule } from '@alfresco/adf-content-services'; +import { BreadcrumbModule, PermissionManagerModule, NodeAspectService } from '@alfresco/adf-content-services'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatIconModule } from '@angular/material/icon'; @@ -59,12 +59,17 @@ import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.c encapsulation: ViewEncapsulation.None }) export class DetailsComponent extends PageComponent implements OnInit, OnDestroy { + @Input() + readOnly = false; + nodeId: string; isLoading: boolean; onDestroy$ = new Subject(); activeTab = 1; + editAspectSupported = false; + hasAllowableOperations = false; - constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private nodeAspectService: NodeAspectService) { super(); } @@ -105,6 +110,10 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new NavigateToPreviousPage()); } + openAspectDialog() { + this.nodeAspectService.updateNodeAspects(this.node.id); + } + ngOnDestroy(): void { this.store.dispatch(new SetSelectedNodesAction([])); this.onDestroy$.next(); From 4e0a5966d6bb5bd65cf6b7f3c5642c375b612668 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 1 Sep 2023 15:09:42 +0530 Subject: [PATCH 32/60] [ACS-5540]fixed unit test cases and added unit test cases --- .../details/details.component.spec.ts | 18 ++++++++++++++++-- .../metadata-tab.component.spec.ts | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) 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 0988ca7033..280dcbb882 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 @@ -31,10 +31,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Store } from '@ngrx/store'; import { ContentApiService } from '@alfresco/aca-shared'; import { STORE_INITIAL_APP_DATA, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; -import { NodeEntry } from '@alfresco/js-api'; +import { MinimalNodeEntryEntity, NodeEntry } from '@alfresco/js-api'; import { RouterTestingModule } from '@angular/router/testing'; import { AuthenticationService, PageTitleService } from '@alfresco/adf-core'; -import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { NodeAspectService, SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('DetailsComponent', () => { let component: DetailsComponent; @@ -42,6 +42,7 @@ describe('DetailsComponent', () => { let contentApiService: ContentApiService; let store: Store; let node: NodeEntry; + let mockNodeAspectService: jasmine.SpyObj; const mockStream = new Subject(); const storeMock = { @@ -50,6 +51,7 @@ describe('DetailsComponent', () => { }; beforeEach(() => { + const nodeAspectServiceSpy = jasmine.createSpyObj('NodeAspectService', ['updateNodeAspects']); TestBed.configureTestingModule({ imports: [AppTestingModule, DetailsComponent], providers: [ @@ -78,6 +80,10 @@ describe('DetailsComponent', () => { onLogout: new Subject(), isLoggedIn: () => true } + }, + { + provide: NodeAspectService, + useValue: nodeAspectServiceSpy } ], schemas: [NO_ERRORS_SCHEMA] @@ -86,6 +92,8 @@ describe('DetailsComponent', () => { fixture = TestBed.createComponent(DetailsComponent); component = fixture.componentInstance; contentApiService = TestBed.inject(ContentApiService); + mockNodeAspectService = TestBed.inject(NodeAspectService) as jasmine.SpyObj; + component.node = { id: 'test-id' } as MinimalNodeEntryEntity; store = TestBed.inject(Store); node = { @@ -128,4 +136,10 @@ describe('DetailsComponent', () => { fixture.detectChanges(); expect(store.dispatch).toHaveBeenCalledWith(new SetSelectedNodesAction([node])); }); + + it('should call openAspectDialog and updateNodeAspects when the button is clicked', () => { + component.openAspectDialog(); + fixture.detectChanges(); + expect(mockNodeAspectService.updateNodeAspects).toHaveBeenCalledWith('test-id'); + }); }); diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts index f990d7b3d5..4d01789afc 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.spec.ts @@ -256,7 +256,7 @@ describe('MetadataTabComponent', () => { }); it('show pass empty when store is in initial state', () => { - const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card')); + const initialState = fixture.debugElement.query(By.css('adf-content-metadata')); expect(initialState.componentInstance.displayAspect).toBeFalsy(); }); @@ -266,7 +266,7 @@ describe('MetadataTabComponent', () => { expect(aspect).toBe('EXIF'); }); fixture.detectChanges(); - const initialState = fixture.debugElement.query(By.css('adf-content-metadata-card')); + const initialState = fixture.debugElement.query(By.css('adf-content-metadata')); expect(initialState.componentInstance.displayAspect).toBe('EXIF'); }); }); From 4a9017269295a6a1aebaa0d047fcd95c25c9c79a Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Tue, 5 Sep 2023 21:22:45 +0530 Subject: [PATCH 33/60] [ACS-5540] Modified changes --- .../components/details/details.component.html | 2 +- .../components/details/details.component.ts | 25 +++++++++++++++---- .../toggle-edit-offline.component.ts | 5 +++- .../src/lib/services/node-actions.service.ts | 15 +++++++++-- .../ui/overrides/adf-style-fixes.theme.scss | 19 ++++++++++++++ .../src/lib/ui/variables/variables.scss | 4 ++- 6 files changed, 60 insertions(+), 10 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 0d553319f8..ff3378f3a3 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -13,7 +13,7 @@ {{ 'APP.INFO_DRAWER.TITLE' | translate }}
-
-
- -
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 778bead773..de481d4647 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -1,19 +1,29 @@ app-details-manager { - .aca-close-details-button { - margin-right: 15px; - margin-top: 2px; - outline: none; - border-radius: 4px; - - &:focus { - background-color: var(--theme-selected-background-color); - outline: 2px solid var(--theme-blue-button-color); - border-radius: 4px; - } + .acs-details-buttons { + display: flex; - &:focus-visible { - outline: 2px solid var(--theme-blue-button-color); + .aca-close-details-button { + margin-right: 15px; + margin-top: 2px; + outline: none; border-radius: 4px; + + &:focus { + background-color: var(--theme-selected-background-color); + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + } + + &:focus-visible { + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + margin-top: 12px; + + &:focus-visible { + outline: 2px solid var(--theme-blue-button-color); + border-radius: 4px; + } + } } } } 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 264445fbe4..0988ca7033 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 @@ -31,10 +31,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { Store } from '@ngrx/store'; import { ContentApiService } from '@alfresco/aca-shared'; import { STORE_INITIAL_APP_DATA, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; -import { Node, NodeEntry } from '@alfresco/js-api'; +import { NodeEntry } from '@alfresco/js-api'; import { RouterTestingModule } from '@angular/router/testing'; import { AuthenticationService, PageTitleService } from '@alfresco/adf-core'; -import { NodeAspectService, SearchQueryBuilderService } from '@alfresco/adf-content-services'; +import { SearchQueryBuilderService } from '@alfresco/adf-content-services'; describe('DetailsComponent', () => { let component: DetailsComponent; @@ -42,7 +42,6 @@ describe('DetailsComponent', () => { let contentApiService: ContentApiService; let store: Store; let node: NodeEntry; - let nodeAspectService: NodeAspectService; const mockStream = new Subject(); const storeMock = { @@ -87,8 +86,6 @@ describe('DetailsComponent', () => { fixture = TestBed.createComponent(DetailsComponent); component = fixture.componentInstance; contentApiService = TestBed.inject(ContentApiService); - nodeAspectService = TestBed.inject(NodeAspectService); - component.node = { id: 'test-id' } as Node; store = TestBed.inject(Store); node = { @@ -106,7 +103,6 @@ describe('DetailsComponent', () => { } }; spyOn(contentApiService, 'getNode').and.returnValue(of(node)); - spyOn(nodeAspectService, 'updateNodeAspects'); }); afterEach(() => { @@ -132,26 +128,4 @@ describe('DetailsComponent', () => { fixture.detectChanges(); expect(store.dispatch).toHaveBeenCalledWith(new SetSelectedNodesAction([node])); }); - - it('should call updateNodeAspects when the aspect dialog is opened', () => { - component.openAspectDialog(); - fixture.detectChanges(); - expect(nodeAspectService.updateNodeAspects).toHaveBeenCalledWith('test-id'); - }); - - 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'); - fixture.detectChanges(); - component.ngOnDestroy(); - expect(component.onDestroy$.complete).toHaveBeenCalled(); - }); }); 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 d454acac10..567d7c816c 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -22,12 +22,12 @@ * from Hyland Software. If not, see . */ -import { Component, OnInit, ViewEncapsulation, OnDestroy, ChangeDetectorRef } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent, isLocked } from '@alfresco/aca-shared'; -import { NavigateToPreviousPage, SetSelectedNodesAction, getAppSelection } from '@alfresco/aca-shared/store'; +import { ContentApiService, PageComponent, PageLayoutComponent, ToolbarComponent } from '@alfresco/aca-shared'; +import { NavigateToPreviousPage, SetSelectedNodesAction } from '@alfresco/aca-shared/store'; import { Subject } from 'rxjs'; -import { BreadcrumbModule, PermissionManagerModule, NodeAspectService } from '@alfresco/adf-content-services'; +import { BreadcrumbModule, PermissionManagerModule } from '@alfresco/adf-content-services'; import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatIconModule } from '@angular/material/icon'; @@ -36,9 +36,8 @@ import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatButtonModule } from '@angular/material/button'; import { MetadataTabComponent } from '../info-drawer/metadata-tab/metadata-tab.component'; import { CommentsTabComponent } from '../info-drawer/comments-tab/comments-tab.component'; -import { NodeActionsService } from '../../services/node-actions.service'; -import { NodeEntry } from '@alfresco/js-api'; import { takeUntil } from 'rxjs/operators'; +import { ContentActionRef } from '@alfresco/adf-extensions'; @Component({ standalone: true, @@ -66,16 +65,9 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy isLoading: boolean; onDestroy$ = new Subject(); activeTab = 1; - selectionState: NodeEntry; - isNodeLocked = false; + actionsAspect: Array = []; - constructor( - private route: ActivatedRoute, - private contentApi: ContentApiService, - private nodeAspectService: NodeAspectService, - private nodeActionsService: NodeActionsService, - private cdr: ChangeDetectorRef - ) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { super(); } @@ -96,14 +88,12 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new SetSelectedNodesAction([{ entry: this.node }])); }); }); - this.store.select(getAppSelection).subscribe(({ file }) => { - this.selectionState = file; - const isNodeLockedFromStore = this.selection && isLocked(this.selectionState); - this.nodeActionsService.isNodeLocked$.pipe(takeUntil(this.onDestroy$)).subscribe((isNodeLockedFromService) => { - this.isNodeLocked = isNodeLockedFromStore || isNodeLockedFromService; - this.cdr.detectChanges(); + this.extensions + .getAllowedSidebarActions() + .pipe(takeUntil(this.onDestroy$)) + .subscribe((actionsAspect) => { + this.actionsAspect = actionsAspect; }); - }); } setActiveTab(tabName: string) { @@ -124,10 +114,6 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy this.store.dispatch(new NavigateToPreviousPage()); } - openAspectDialog() { - this.nodeAspectService.updateNodeAspects(this.node.id); - } - ngOnDestroy(): void { this.store.dispatch(new SetSelectedNodesAction([])); this.onDestroy$.next(); diff --git a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts index 11a3c38227..e061c2a599 100644 --- a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts +++ b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts @@ -26,10 +26,9 @@ import { ToggleEditOfflineComponent } from './toggle-edit-offline.component'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { Store } from '@ngrx/store'; -import { NodeEntry, NodesApi } from '@alfresco/js-api'; +import { NodeEntry } from '@alfresco/js-api'; import { DownloadNodesAction, EditOfflineAction, SnackbarErrorAction } from '@alfresco/aca-shared/store'; import { AppTestingModule } from '../../../testing/app-testing.module'; -import { NodeActionsService } from '../../../services/node-actions.service'; describe('ToggleEditOfflineComponent', () => { let fixture: ComponentFixture; @@ -39,49 +38,6 @@ describe('ToggleEditOfflineComponent', () => { let selectSpy: jasmine.Spy; let selection: any; - const lockedNodeEntry: NodeEntry = { - entry: { - isFile: true, - createdByUser: { - id: 'hruser', - displayName: 'hruser' - }, - modifiedAt: new Date('2023-09-08T11:54:48.325+0000'), - nodeType: 'cm:content', - content: { - mimeType: 'image/jpeg', - mimeTypeName: 'JPEG Image', - sizeInBytes: 128473, - encoding: 'UTF-8' - }, - parentId: '5a2d88ec-a29c-408a-874d-6394940c51d7', - aspectNames: ['cm:versionable', 'cm:lockable', 'cm:auditable', 'cm:taggable', 'exif:exif'], - createdAt: new Date('2023-09-07T11:10:48.788+0000'), - isFolder: false, - modifiedByUser: { - id: 'hruser', - displayName: 'hruser' - }, - name: 'e2e_favorite_file.jpg', - id: '36e5b5ad-3fa0-47e2-b256-016b868ac772', - properties: { - 'cm:lockType': 'WRITE_LOCK', - 'cm:lockOwner': { - id: 'hruser', - displayName: 'hruser' - }, - 'cm:versionType': 'MAJOR', - 'cm:versionLabel': '1.0', - 'cm:lockLifetime': 'PERSISTENT', - 'exif:pixelYDimension': 1253, - 'exif:pixelXDimension': 1024 - } - } - }; - - const nodesApiMock = jasmine.createSpyObj('nodesApi', ['lockNode', 'unlockNode']); - const nodeActionsServiceMock = jasmine.createSpyObj('nodeActionsService', ['setNodeLocked']); - beforeEach(() => { TestBed.configureTestingModule({ imports: [AppTestingModule, ToggleEditOfflineComponent], @@ -92,9 +48,7 @@ describe('ToggleEditOfflineComponent', () => { select: () => {}, dispatch: () => {} } - }, - { provide: NodesApi, useValue: nodesApiMock }, - { provide: NodeActionsService, useValue: nodeActionsServiceMock } + } ] }); @@ -179,51 +133,4 @@ describe('ToggleEditOfflineComponent', () => { }) ]); }); - - it('should call setNodeLocked with true when a node is locked', () => { - const nodeId = 'testNode1'; - nodesApiMock.lockNode.and.returnValue(Promise.resolve(lockedNodeEntry)); - - component.lockNode(nodeId).then((result) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId, { - type: 'ALLOW_OWNER_CHANGES', - lifetime: 'PERSISTENT' - }); - expect(nodeActionsServiceMock.setNodeLocked).toHaveBeenCalledWith(true); - expect(result).toEqual(lockedNodeEntry); - }); - }); - - it('should call setNodeLocked with false when a node is unlocked', () => { - const nodeId = 'testNode2'; - nodesApiMock.unlockNode.and.returnValue(Promise.resolve(lockedNodeEntry)); - - component.unlockNode(nodeId).then((result) => { - expect(nodesApiMock.unlockNode).toHaveBeenCalledWith(nodeId); - expect(nodeActionsServiceMock.setNodeLocked).toHaveBeenCalledWith(false); - expect(result).toEqual(lockedNodeEntry); - }); - }); - - it('should handle errors when locking a node encounters an error', () => { - const nodeId = 'testNode1'; - const error = new Error('Locking failed'); - nodesApiMock.lockNode.and.returnValue(Promise.reject(error)); - component.lockNode(nodeId).catch((err) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId, { type: 'ALLOW_OWNER_CHANGES', lifetime: 'PERSISTENT' }); - expect(nodeActionsServiceMock.setNodeLocked).not.toHaveBeenCalled(); - expect(err).toEqual(error); - }); - }); - - it('should handle errors when unlocking a node encounters an error', () => { - const nodeId = 'testNode1'; - const error = new Error('Unlocking failed'); - nodesApiMock.unlockNode.and.returnValue(Promise.reject(error)); - component.unlockNode(nodeId).catch((err) => { - expect(nodesApiMock.lockNode).toHaveBeenCalledWith(nodeId); - expect(nodeActionsServiceMock.setNodeLocked).not.toHaveBeenCalled(); - expect(err).toEqual(error); - }); - }); }); diff --git a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts index a01f6e5f53..40410b94b5 100644 --- a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts +++ b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.ts @@ -31,7 +31,7 @@ import { getAppSelection } from '@alfresco/aca-shared/store'; import { NodeEntry, SharedLinkEntry, Node, NodesApi } from '@alfresco/js-api'; -import { ChangeDetectorRef, Component, OnInit, ViewEncapsulation } from '@angular/core'; +import { Component, OnInit, ViewEncapsulation } from '@angular/core'; import { Store } from '@ngrx/store'; import { AppExtensionService, isLocked } from '@alfresco/aca-shared'; import { AlfrescoApiService } from '@alfresco/adf-core'; @@ -39,7 +39,6 @@ import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; import { MatMenuModule } from '@angular/material/menu'; import { MatIconModule } from '@angular/material/icon'; -import { NodeActionsService } from '../../../services/node-actions.service'; @Component({ standalone: true, @@ -60,13 +59,7 @@ export class ToggleEditOfflineComponent implements OnInit { nodeTitle = ''; isNodeLocked = false; - constructor( - private store: Store, - private alfrescoApiService: AlfrescoApiService, - private nodeActionsService: NodeActionsService, - private cdr: ChangeDetectorRef, - private extensions: AppExtensionService - ) { + constructor(private store: Store, private alfrescoApiService: AlfrescoApiService, private extensions: AppExtensionService) { this.nodesApi = new NodesApi(this.alfrescoApiService.getInstance()); } @@ -75,7 +68,6 @@ export class ToggleEditOfflineComponent implements OnInit { this.selection = file; this.isNodeLocked = this.selection && isLocked(this.selection); this.nodeTitle = this.isNodeLocked ? 'APP.ACTIONS.EDIT_OFFLINE_CANCEL' : 'APP.ACTIONS.EDIT_OFFLINE'; - this.cdr.detectChanges(); }); } @@ -127,27 +119,15 @@ export class ToggleEditOfflineComponent implements OnInit { ); } - lockNode(nodeId: string): Promise { - return this.nodesApi.lockNode(nodeId, { type: 'ALLOW_OWNER_CHANGES', lifetime: 'PERSISTENT' }).then( - (res: NodeEntry) => { - this.nodeActionsService.setNodeLocked(true); - return res; - }, - (error) => { - return error; - } - ); + lockNode(nodeId: string) { + return this.nodesApi.lockNode(nodeId, { + type: 'ALLOW_OWNER_CHANGES', + lifetime: 'PERSISTENT' + }); } - unlockNode(nodeId: string): Promise { - return this.nodesApi.unlockNode(nodeId).then( - (res: NodeEntry) => { - this.nodeActionsService.setNodeLocked(false); - return res; - }, - (error) => { - return error; - } - ); + + unlockNode(nodeId: string) { + return this.nodesApi.unlockNode(nodeId); } private update(data: Node) { 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 382f5c9748..2485867783 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -24,7 +24,7 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Observable, Subject, of, zip, from, BehaviorSubject } from 'rxjs'; +import { Observable, Subject, of, zip, from } from 'rxjs'; import { AlfrescoApiService, TranslationService, ThumbnailService } from '@alfresco/adf-core'; import { DocumentListService, @@ -49,7 +49,6 @@ export class NodeActionsService { contentMoved: Subject = new Subject(); moveDeletedEntries: any[] = []; isSitesDestinationAvailable = false; - private isNodeLockedSubject = new BehaviorSubject(false); isNodeLocked$: Observable; _nodesApi: NodesApi; @@ -66,9 +65,7 @@ export class NodeActionsService { private apiService: AlfrescoApiService, private translation: TranslationService, private thumbnailService: ThumbnailService - ) { - this.isNodeLocked$ = this.isNodeLockedSubject.asObservable(); - } + ) {} /** * Copy node list @@ -92,10 +89,6 @@ export class NodeActionsService { return this.doBatchOperation(NodeAction.MOVE, contentEntities, permission, focusedElementOnCloseSelector); } - setNodeLocked(isLocked: boolean) { - this.isNodeLockedSubject.next(isLocked); - } - /** * General method for performing the given operation (copy|move) to multiple nodes * diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index 71333f4bc6..ef23e53556 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -511,6 +511,8 @@ export const canEditAspects = (context: RuleContext): boolean => repository.isMajorVersionAvailable(context, '7') ].every(Boolean); +export const canNotShowExpand = (context: RuleContext): boolean => [!navigation.isLibraries(context), !navigation.isDetails(context)].every(Boolean); + /** * Checks if user can manage permissions for the selected node. * JSON ref: `canManagePermissions` diff --git a/projects/aca-shared/rules/src/navigation.rules.ts b/projects/aca-shared/rules/src/navigation.rules.ts index 02d6a6df93..5a3c5569cf 100644 --- a/projects/aca-shared/rules/src/navigation.rules.ts +++ b/projects/aca-shared/rules/src/navigation.rules.ts @@ -110,6 +110,11 @@ export function isLibraryContent(context: RuleContext): boolean { return url && (url.endsWith('/libraries') || url.includes('/libraries/') || url.startsWith('/search-libraries')); } +export function isDetails(context: RuleContext): boolean { + const { url } = context.navigation; + return url && (url.endsWith('/details') || url.includes('/details/') || url.startsWith('/details')); +} + /** * Checks if the activated route is neither **Libraries** nor **Library Search Results**. * JSON ref: `app.navigation.isNotLibraries` From a1c5d8baaee8446fb93f483618f17e94d7358563 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Wed, 13 Sep 2023 12:34:57 +0530 Subject: [PATCH 41/60] [ACS-5540] modified the changes --- .../src/lib/components/details/details.component.html | 2 +- .../src/lib/components/details/details.component.ts | 6 +++--- .../aca-content/src/lib/services/node-actions.service.ts | 1 - 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index afcde3c44d..18dc2c3b13 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -13,7 +13,7 @@ {{ 'APP.INFO_DRAWER.TITLE' | translate }}
- +
-
From cdbffb26d9a90ee95a28c697d8fd9570ceefbd62 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 22 Sep 2023 09:57:33 +0530 Subject: [PATCH 47/60] [ACS-5540]Implemented the changes as per the review comments --- projects/aca-shared/rules/src/navigation.rules.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/aca-shared/rules/src/navigation.rules.spec.ts b/projects/aca-shared/rules/src/navigation.rules.spec.ts index 5f7941f177..44f43e8e7f 100644 --- a/projects/aca-shared/rules/src/navigation.rules.spec.ts +++ b/projects/aca-shared/rules/src/navigation.rules.spec.ts @@ -226,7 +226,7 @@ describe('navigation.evaluators', () => { }); describe('isDetails', () => { - it('should return [true] if url ends with `/details`', () => { + it('should return true if url ends with `/details`', () => { const context: any = { navigation: { url: '/path/details' @@ -236,7 +236,7 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return [true] if url starts with `/details`', () => { + it('should return true if url starts with `/details`', () => { const context: any = { navigation: { url: '/details/path' @@ -246,7 +246,7 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return [true] if url includes with `/details`', () => { + it('should return true if url includes with `/details`', () => { const context: any = { navigation: { url: '/details/path' From 7ff38f6518e2b54263107261f84e5cce417ef16a Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Fri, 22 Sep 2023 20:56:13 +0530 Subject: [PATCH 48/60] [ACS-5540] added group lock changes --- .../info-drawer/metadata-tab/metadata-tab.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts index 34f125ddb8..2a5654fae3 100644 --- a/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts +++ b/projects/aca-content/src/lib/components/info-drawer/metadata-tab/metadata-tab.component.ts @@ -49,6 +49,7 @@ import { Actions, ofType } from '@ngrx/effects'; [(editable)]="editable" [(editableTags)]="editableTags" [(editableCategories)]="editableCategories" + [(group)]="group" > `, @@ -65,6 +66,9 @@ export class MetadataTabComponent implements OnInit, OnDestroy { editable = false; editableTags = false; editableCategories = false; + group: any = { + editable: false + }; constructor( private permission: NodePermissionService, @@ -98,6 +102,7 @@ export class MetadataTabComponent implements OnInit, OnDestroy { this.editable = false; this.editableTags = false; this.editableCategories = false; + this.group.editable = false; } }); } From 638bdde9b33a7668f579d0bf039915850f6b8950 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Mon, 25 Sep 2023 15:16:46 +0530 Subject: [PATCH 49/60] [ACS-5540] added tooltip --- projects/aca-content/assets/app.extensions.json | 2 +- projects/aca-content/assets/i18n/en.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json index 144023805a..51de285a05 100644 --- a/projects/aca-content/assets/app.extensions.json +++ b/projects/aca-content/assets/app.extensions.json @@ -1243,7 +1243,7 @@ { "id": "app.toolbar.aspects", "order": 160, - "title": "APP.ACTIONS.CHANGE_ASPECT", + "title": "APP.ACTIONS.ADD_ASPECTS", "icon": "playlist_add", "actions": { "click": "ASPECT_LIST" diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index bab98e67e3..0c07008e4e 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -259,7 +259,8 @@ "LEAVE": "Leave Library", "EDIT_OFFLINE": "Edit Offline", "EDIT_OFFLINE_CANCEL": "Cancel Editing", - "CHANGE_ASPECT": "Edit Aspects" + "CHANGE_ASPECT": "Edit Aspects", + "ADD_ASPECTS": "Add Aspects" }, "DIALOGS": { "CONFIRM_PURGE": { From 77dff824e466d259407169834af5d247db8b30b8 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 28 Sep 2023 11:19:39 +0530 Subject: [PATCH 50/60] [ACS-5540] Implemented the review comments --- .../components/details/details.component.scss | 2 +- .../rules/src/navigation.rules.spec.ts | 18 ++++-------------- .../aca-shared/rules/src/navigation.rules.ts | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index de481d4647..4e76575e86 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -4,7 +4,7 @@ app-details-manager { .aca-close-details-button { margin-right: 15px; - margin-top: 2px; + margin-top: 12px; outline: none; border-radius: 4px; diff --git a/projects/aca-shared/rules/src/navigation.rules.spec.ts b/projects/aca-shared/rules/src/navigation.rules.spec.ts index 44f43e8e7f..9582223e44 100644 --- a/projects/aca-shared/rules/src/navigation.rules.spec.ts +++ b/projects/aca-shared/rules/src/navigation.rules.spec.ts @@ -226,17 +226,7 @@ describe('navigation.evaluators', () => { }); describe('isDetails', () => { - it('should return true if url ends with `/details`', () => { - const context: any = { - navigation: { - url: '/path/details' - } - }; - - expect(app.isDetails(context)).toBe(true); - }); - - it('should return true if url starts with `/details`', () => { + it('should return true if url includes with `/details`', () => { const context: any = { navigation: { url: '/details/path' @@ -246,14 +236,14 @@ describe('navigation.evaluators', () => { expect(app.isDetails(context)).toBe(true); }); - it('should return true if url includes with `/details`', () => { + it('should return false if url not includes with `/details`', () => { const context: any = { navigation: { - url: '/details/path' + url: '/path' } }; - expect(app.isDetails(context)).toBe(true); + expect(app.isDetails(context)).toBe(false); }); }); diff --git a/projects/aca-shared/rules/src/navigation.rules.ts b/projects/aca-shared/rules/src/navigation.rules.ts index 5a3c5569cf..a26d8a2366 100644 --- a/projects/aca-shared/rules/src/navigation.rules.ts +++ b/projects/aca-shared/rules/src/navigation.rules.ts @@ -112,7 +112,7 @@ export function isLibraryContent(context: RuleContext): boolean { export function isDetails(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.endsWith('/details') || url.includes('/details/') || url.startsWith('/details')); + return url?.includes('/details'); } /** From ccb340d20bb50548e400874a7618fe3375a8f7a5 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Thu, 28 Sep 2023 17:51:28 +0530 Subject: [PATCH 51/60] [ACS-5540] added tooltips --- projects/aca-content/assets/i18n/en.json | 4 ++-- .../src/lib/components/details/details.component.html | 2 +- projects/aca-content/src/lib/ui/variables/variables.scss | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index 0c07008e4e..faf977f981 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -395,7 +395,7 @@ }, "INFO_DRAWER": { "TITLE": "Details", - "CLOSE": "Close", + "REDUCE_PANEL": "Reduce panel", "DATA_LOADING": "Data is loading", "TABS": { "PROPERTIES": "Properties", @@ -403,7 +403,7 @@ "VERSIONS": "Versions", "COMMENTS": "Comments", "PERMISSIONS": "Permissions", - "EXPAND": "Expand" + "EXPAND": "Expand panel" } }, "TOOLTIPS": { diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index 7ba883cee6..d2b2b752b5 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -18,7 +18,7 @@ class="aca-close-details-button" mat-icon-button data-automation-id="close-library" - title="{{ 'APP.INFO_DRAWER.CLOSE' | translate }}" + title="{{ 'APP.INFO_DRAWER.REDUCE_PANEL' | translate }}" (click)="goBack()"> fullscreen_exit diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 8e4c0be6d9..45bcc8ecd8 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -38,6 +38,7 @@ $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; $metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); $metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$metadata-action-button-clear-color: #212328b2; // CSS Variables $defaults: ( @@ -80,7 +81,8 @@ $defaults: ( --theme-disabled-chip-background-color: $disabled-chip-background-color, --theme-contrast-gray: $contrast-gray, --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, - --theme-metadata-buttons-background-color: $metadata-buttons-background-color + --theme-metadata-buttons-background-color: $metadata-buttons-background-color, + --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color ); // propagates SCSS variables into the CSS variables scope From 4ccbb710cee69f4a2f0e26946bd779fd181506ff Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Tue, 3 Oct 2023 21:35:48 +0530 Subject: [PATCH 52/60] [ACS-5540] Added styles --- .../src/lib/ui/overrides/adf-style-fixes.theme.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss index fc30adc81a..f96504711a 100644 --- a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss +++ b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss @@ -27,6 +27,10 @@ border: 1px solid var(--theme-metadata-property-panel-border-color); margin: 24px; border-radius: 12px; + + .adf-metadata-properties-group-title { + width: 548px; + } } } } From 1d3ec3ed65382f4f3dd967110b638d25183d25d6 Mon Sep 17 00:00:00 2001 From: Yasa-Nataliya Date: Wed, 4 Oct 2023 12:02:27 +0530 Subject: [PATCH 53/60] [ACS-5540]Added focus --- .../src/lib/ui/overrides/adf-style-fixes.theme.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss index f96504711a..0daf5ea047 100644 --- a/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss +++ b/projects/aca-content/src/lib/ui/overrides/adf-style-fixes.theme.scss @@ -17,6 +17,10 @@ border: 1px solid var(--theme-metadata-property-panel-border-color); border-radius: 12px; margin-bottom: 12px; + + .mat-expansion-panel-header { + border-radius: 12px; + } } .acs-details-container { @@ -28,6 +32,10 @@ margin: 24px; border-radius: 12px; + .mat-expansion-panel-header { + border-radius: 12px; + } + .adf-metadata-properties-group-title { width: 548px; } From 4ebacdcf67c6919e6e6f60371f1b375dac323d88 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Wed, 6 Sep 2023 20:42:50 +0530 Subject: [PATCH 54/60] [ACS-5551]updated property panel design --- .../components/details/details.component.html | 6 +- .../components/details/details.component.scss | 10 ++-- .../details/details.component.spec.ts | 38 +++++++++++++ .../components/details/details.component.ts | 8 ++- .../lib/services/node-actions.service.spec.ts | 57 ++++++++++++++++++- .../src/lib/services/node-actions.service.ts | 41 +++++++++++++ .../info-drawer/info-drawer.component.html | 6 +- .../page-layout/page-layout.component.scss | 2 + 8 files changed, 156 insertions(+), 12 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index d2b2b752b5..b6b8528e24 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -8,9 +8,9 @@
- {{ node.name }} - - - {{ 'APP.INFO_DRAWER.TITLE' | translate }} + + Info Drawer icon + {{ node.name }}
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 4e76575e86..98caa3dbe1 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -51,17 +51,19 @@ app-details-manager { display: flex; align-items: center; justify-content: space-between; + color: var(--adf-metadata-property-panel-title-color); } .acs-details-breadcrumb { - font-size: 18px; + font-size: 20px; margin-left: 20px; .acs-details-breadcrumb-library { - font-weight: 900; + font-weight: 400; } - .acs-details-breadcrumb-item { - font-weight: 100; + .acs-details-breadcrumb-icon { + display: inline-block; + vertical-align: text-bottom; } } 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 6911afef2e..caa068e453 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 @@ -58,6 +58,38 @@ describe('DetailsComponent', () => { const mockObservable = new BehaviorSubject(mockAspectActions); extensionsServiceMock.getAllowedSidebarActions.and.returnValue(mockObservable); + 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: [AppTestingModule, DetailsComponent], @@ -144,5 +176,11 @@ describe('DetailsComponent', () => { fixture.whenStable().then(() => { expect(component.aspectActions).toEqual(mockAspectActions); }); + it('should return the icon when getInfoDrawerIcon is called', () => { + const expectedIcon = 'assets/images/ft_ic_folder'; + spyOn(component['nodeActionsService'], 'getInfoDrawerIcon').and.returnValue(expectedIcon); + fixture.detectChanges(); + const result = component.getInfoDrawerIcon(mockNode); + expect(result).toContain(expectedIcon); }); }); 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 07a364e846..00ed1d0a53 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -38,6 +38,8 @@ 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({ standalone: true, @@ -67,7 +69,7 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy activeTab = 1; aspectActions: Array = []; - constructor(private route: ActivatedRoute, private contentApi: ContentApiService) { + constructor(private route: ActivatedRoute, private contentApi: ContentApiService, private nodeActionsService: NodeActionsService) { super(); } @@ -96,6 +98,10 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy }); } + getInfoDrawerIcon(node: Node): string { + return this.nodeActionsService.getInfoDrawerIcon(node); + } + setActiveTab(tabName: string) { switch (tabName) { case 'comments': 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 f825c894c2..ad62b7bbaa 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, TranslationService } from '@alfresco/adf-core'; +import { AlfrescoApiService, ThumbnailService, 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'; @@ -107,6 +107,7 @@ describe('NodeActionsService', () => { service = TestBed.inject(NodeActionsService); apiService = TestBed.inject(AlfrescoApiService); dialog = TestBed.inject(MatDialog); + apiService.reset(); nodesApi = service['nodesApi']; @@ -1227,4 +1228,58 @@ 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 testInfoDrawerIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { + spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); + mockNode.isFolder = isFoldeType; + mockNode.isFile = isFileType; + const value = service.getInfoDrawerIcon(mockNode); + expect(value).toContain(iconPath); + } + + it('should resolve folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder.svg', true, false); + }); + + it('should resolve smart folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_smart_folder.svg', true, false); + }); + + it('should resolve link folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); + }); + + it('should resolve rule folder icon', () => { + testInfoDrawerIcon('assets/images/ft_ic_folder_rule.svg', true, false); + }); + + it('should resolve file icon for content type', () => { + testInfoDrawerIcon('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.getInfoDrawerIcon(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 7b2c1493d2..98bb02a071 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -563,6 +563,47 @@ export class NodeActionsService { return null; } + getInfoDrawerIcon(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 { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects.includes('smf:customConfigSmartFolder') || nodeAspects.includes('smf:systemConfigSmartFolder'); + } + + isRuleFolder(node: Node): boolean { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects.includes('rule:rules'); + } + + isLinkFolder(node: Node): boolean { + const nodeType = node.nodeType; + return nodeType === 'app:folderlink'; + } + + private getNodeAspectNames(node: Node): string[] { + return node.aspectNames ? 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.html b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html index 5f07ca0f5d..31de24e212 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html @@ -2,11 +2,11 @@
- + - + - + \ No newline at end of file diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index 2e1049fc4e..ff881a2cf9 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -37,6 +37,8 @@ .aca-page-layout-content { @include flex-row; + + border-top: 1px solid var(--adf-metadata-property-panel-border-color); } .aca-page-layout-error { From 83cde6a53cec87085e2d365ffd1f0a6a3731c05e Mon Sep 17 00:00:00 2001 From: pkundu Date: Sat, 9 Sep 2023 12:43:04 +0530 Subject: [PATCH 55/60] [ACS-5551]added null checks --- projects/aca-content/assets/i18n/en.json | 1 + .../components/details/details.component.html | 2 +- .../components/details/details.component.scss | 4 +- .../details/details.component.spec.ts | 4 +- .../components/details/details.component.ts | 4 +- .../lib/services/node-actions.service.spec.ts | 12 +++--- .../src/lib/services/node-actions.service.ts | 27 ++++++++----- .../aca-content/src/lib/ui/application.scss | 6 +-- .../src/lib/ui/variables/variables.scss | 17 ++++---- .../info-drawer/info-drawer.component.html | 2 +- .../info-drawer/info-drawer.component.spec.ts | 40 +++++++++++++++++++ .../info-drawer/info-drawer.component.ts | 12 +++++- .../page-layout/page-layout.component.scss | 2 +- 13 files changed, 97 insertions(+), 36 deletions(-) diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json index faf977f981..cc001db517 100644 --- a/projects/aca-content/assets/i18n/en.json +++ b/projects/aca-content/assets/i18n/en.json @@ -397,6 +397,7 @@ "TITLE": "Details", "REDUCE_PANEL": "Reduce panel", "DATA_LOADING": "Data is loading", + "ICON": "Node Icon", "TABS": { "PROPERTIES": "Properties", "LIBRARY_PROPERTIES": "About", diff --git a/projects/aca-content/src/lib/components/details/details.component.html b/projects/aca-content/src/lib/components/details/details.component.html index b6b8528e24..2446680ae8 100644 --- a/projects/aca-content/src/lib/components/details/details.component.html +++ b/projects/aca-content/src/lib/components/details/details.component.html @@ -9,7 +9,7 @@
- Info Drawer icon + {{ 'APP.INFO_DRAWER.ICON' | translate }} {{ node.name }}
diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 98caa3dbe1..d5f3b4d2f9 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -51,7 +51,9 @@ app-details-manager { display: flex; align-items: center; justify-content: space-between; - color: var(--adf-metadata-property-panel-title-color); + color: var(--theme-metadata-property-panel-title-color); + text-overflow: ellipsis; + white-space: normal; } .acs-details-breadcrumb { 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 caa068e453..da9eb48c15 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 @@ -178,9 +178,9 @@ describe('DetailsComponent', () => { }); it('should return the icon when getInfoDrawerIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; - spyOn(component['nodeActionsService'], 'getInfoDrawerIcon').and.returnValue(expectedIcon); + spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); - const result = component.getInfoDrawerIcon(mockNode); + const result = component.getNodeIcon(mockNode); expect(result).toContain(expectedIcon); }); }); 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 00ed1d0a53..b4651e7eb3 100644 --- a/projects/aca-content/src/lib/components/details/details.component.ts +++ b/projects/aca-content/src/lib/components/details/details.component.ts @@ -98,8 +98,8 @@ export class DetailsComponent extends PageComponent implements OnInit, OnDestroy }); } - getInfoDrawerIcon(node: Node): string { - return this.nodeActionsService.getInfoDrawerIcon(node); + getNodeIcon(node: Node): string { + return this.nodeActionsService.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 ad62b7bbaa..17d5822812 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 @@ -1246,7 +1246,7 @@ describe('NodeActionsService', () => { thumbnailService = TestBed.inject(ThumbnailService); }); - function testInfoDrawerIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { + function testNodeIcon(iconPath: string, isFoldeType: boolean, isFileType: boolean) { spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); mockNode.isFolder = isFoldeType; mockNode.isFile = isFileType; @@ -1255,23 +1255,23 @@ describe('NodeActionsService', () => { } it('should resolve folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder.svg', true, false); }); it('should resolve smart folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_smart_folder.svg', true, false); + testNodeIcon('assets/images/ft_ic_smart_folder.svg', true, false); }); it('should resolve link folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder_shortcut_link.svg', true, false); }); it('should resolve rule folder icon', () => { - testInfoDrawerIcon('assets/images/ft_ic_folder_rule.svg', true, false); + testNodeIcon('assets/images/ft_ic_folder_rule.svg', true, false); }); it('should resolve file icon for content type', () => { - testInfoDrawerIcon('assets/images/ft_ic_raster_image.svg', false, true); + testNodeIcon('assets/images/ft_ic_raster_image.svg', false, true); }); it('should resolve fallback file icon for unknown node', () => { 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 98bb02a071..4fc02d1632 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -563,12 +563,12 @@ export class NodeActionsService { return null; } - getInfoDrawerIcon(node: Node): string { - if (node.isFolder) { + getNodeIcon(node: Node): string { + if (node?.isFolder) { return this.getFolderIcon(node); } - if (node.isFile) { - return this.thumbnailService.getMimeTypeIcon(node.content.mimeType); + if (node?.isFile) { + return this.thumbnailService.getMimeTypeIcon(node?.content?.mimeType); } return this.thumbnailService.getDefaultMimeTypeIcon(); } @@ -586,22 +586,27 @@ export class NodeActionsService { } isSmartFolder(node: Node): boolean { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects.includes('smf:customConfigSmartFolder') || nodeAspects.includes('smf:systemConfigSmartFolder'); + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('smf:customConfigSmartFolder') || nodeAspects?.includes('smf:systemConfigSmartFolder'); + } + return false; } isRuleFolder(node: Node): boolean { - const nodeAspects = this.getNodeAspectNames(node); - return nodeAspects.includes('rule:rules'); + if (node) { + const nodeAspects = this.getNodeAspectNames(node); + return nodeAspects?.includes('rule:rules'); + } + return false; } isLinkFolder(node: Node): boolean { - const nodeType = node.nodeType; - return nodeType === 'app:folderlink'; + return node?.nodeType === 'app:folderlink'; } private getNodeAspectNames(node: Node): string[] { - return node.aspectNames ? node.aspectNames : []; + return node?.aspectNames || []; } public getNewNameFrom(name: string, baseName?: string) { diff --git a/projects/aca-content/src/lib/ui/application.scss b/projects/aca-content/src/lib/ui/application.scss index 2be7581910..bfd057e8ed 100644 --- a/projects/aca-content/src/lib/ui/application.scss +++ b/projects/aca-content/src/lib/ui/application.scss @@ -50,9 +50,9 @@ ng-component { .aca-sidebar { display: block; height: 100%; - overflow-y: scroll; - max-width: 350px; - width: 350px; + max-width: 368px; + width: 368px; + border-top: 1px solid var(--theme-metadata-property-panel-border-color); } .aca-page-title { diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 45bcc8ecd8..534a830663 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,9 +36,10 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; -$metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); -$metadata-buttons-background-color: rgba(33, 33, 33, 0.05); -$metadata-action-button-clear-color: #212328b2; +$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$adf-metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); +$adf-metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); // CSS Variables $defaults: ( @@ -79,10 +80,12 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray, - --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, - --theme-metadata-buttons-background-color: $metadata-buttons-background-color, - --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color + --theme-contrast-gray: $contrast-gray + --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, + --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color, + --adf-metadata-property-panel-title-color: $selected-text-color, + --adf-metadata-property-panel-text-color: $adf-metadata-property-panel-text-color, + --adf-metadata-property-panel-label-color: $adf-metadata-property-panel-label-color ); // propagates SCSS variables into the CSS variables scope diff --git a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html index 31de24e212..7b1c8f0595 100644 --- a/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html +++ b/projects/aca-shared/src/lib/components/info-drawer/info-drawer.component.html @@ -2,7 +2,7 @@
- + 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 7d16fadfa8..fe94ae7f7e 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 @@ -57,6 +57,38 @@ describe('InfoDrawerComponent', () => { ]) }; + 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: [LibTestingModule, InfoDrawerComponent], @@ -182,4 +214,12 @@ describe('InfoDrawerComponent', () => { } as ContentActionRef ]); }); + + it('should return the icon when getNodeIcon is called', () => { + const expectedIcon = 'assets/images/ft_ic_folder'; + spyOn(component['nodeActionsService'], '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 70c59e0cb4..8d6cd9e927 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,6 +37,7 @@ 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, @@ -64,7 +65,12 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { this.close(); } - constructor(private store: Store, private contentApi: ContentApiService, private extensions: AppExtensionService) {} + constructor( + private store: Store, + private contentApi: ContentApiService, + private extensions: AppExtensionService, + private nodeActionsService: NodeActionsService + ) {} ngOnInit() { this.tabs = this.extensions.getSidebarTabs(); @@ -125,4 +131,8 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy { private setDisplayNode(node: any) { this.displayNode = node; } + + getNodeIcon(node: Node): string { + return this.nodeActionsService.getNodeIcon(node); + } } diff --git a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss index ff881a2cf9..ff8455e474 100644 --- a/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss +++ b/projects/aca-shared/src/lib/components/page-layout/page-layout.component.scss @@ -38,7 +38,7 @@ .aca-page-layout-content { @include flex-row; - border-top: 1px solid var(--adf-metadata-property-panel-border-color); + border-top: 1px solid var(--theme-metadata-property-panel-border-color); } .aca-page-layout-error { From 958b307729cc81fdcc4469469f2a54e214e556c3 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 11:03:25 +0530 Subject: [PATCH 56/60] [ACS-5551] update style --- .../details/details.component.spec.ts | 4 +++- .../src/lib/ui/variables/variables.scss | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) 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 da9eb48c15..037e3753f8 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 @@ -176,7 +176,9 @@ describe('DetailsComponent', () => { fixture.whenStable().then(() => { expect(component.aspectActions).toEqual(mockAspectActions); }); - it('should return the icon when getInfoDrawerIcon is called', () => { + }); + + it('should return the icon when getNodeIcon is called', () => { const expectedIcon = 'assets/images/ft_ic_folder'; spyOn(component['nodeActionsService'], 'getNodeIcon').and.returnValue(expectedIcon); fixture.detectChanges(); diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss index 534a830663..f9249ae961 100644 --- a/projects/aca-content/src/lib/ui/variables/variables.scss +++ b/projects/aca-content/src/lib/ui/variables/variables.scss @@ -36,10 +36,11 @@ $page-layout-header-background-color: #fff; $search-chip-icon-color: #757575; $disabled-chip-background-color: #f5f5f5; $contrast-gray: #646569; -$adf-metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); -$adf-metadata-buttons-background-color: rgba(33, 33, 33, 0.05); -$adf-metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); -$adf-metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); +$metadata-property-panel-border-color: rgba(0, 0, 0, 0.12); +$metadata-buttons-background-color: rgba(33, 33, 33, 0.05); +$metadata-action-button-clear-color: #212328b2; +$metadata-property-panel-text-color: rgba(33, 35, 40, 0.7); +$metadata-property-panel-label-color: rgba(33, 33, 33, 0.24); // CSS Variables $defaults: ( @@ -80,12 +81,13 @@ $defaults: ( --theme-page-layout-header-background-color: $page-layout-header-background-color, --theme-search-chip-icon-color: $search-chip-icon-color, --theme-disabled-chip-background-color: $disabled-chip-background-color, - --theme-contrast-gray: $contrast-gray - --adf-metadata-property-panel-border-color: $adf-metadata-property-panel-border-color, - --adf-metadata-buttons-background-color: $adf-metadata-buttons-background-color, - --adf-metadata-property-panel-title-color: $selected-text-color, - --adf-metadata-property-panel-text-color: $adf-metadata-property-panel-text-color, - --adf-metadata-property-panel-label-color: $adf-metadata-property-panel-label-color + --theme-contrast-gray: $contrast-gray, + --theme-metadata-property-panel-border-color: $metadata-property-panel-border-color, + --theme-metadata-buttons-background-color: $metadata-buttons-background-color, + --theme-metadata-action-button-clear-color: $metadata-action-button-clear-color, + --theme-metadata-property-panel-title-color: $selected-text-color, + --theme-metadata-property-panel-text-color: $metadata-property-panel-text-color, + --theme-metadata-property-panel-label-color: $metadata-property-panel-label-color ); // propagates SCSS variables into the CSS variables scope From 2ebcef2e0da04d11e80f2e5344c3a556d5cda401 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 15:55:26 +0530 Subject: [PATCH 57/60] [ACS-5551] name updated --- .../aca-content/src/lib/services/node-actions.service.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 17d5822812..6721975cec 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 @@ -1250,7 +1250,7 @@ describe('NodeActionsService', () => { spyOn(thumbnailService, 'getMimeTypeIcon').and.returnValue(iconPath); mockNode.isFolder = isFoldeType; mockNode.isFile = isFileType; - const value = service.getInfoDrawerIcon(mockNode); + const value = service.getNodeIcon(mockNode); expect(value).toContain(iconPath); } @@ -1278,7 +1278,7 @@ describe('NodeActionsService', () => { spyOn(thumbnailService, 'getDefaultMimeTypeIcon').and.returnValue(`assets/images/ft_ic_miscellaneous.svg`); mockNode.isFile = false; mockNode.isFolder = false; - const value = service.getInfoDrawerIcon(mockNode); + const value = service.getNodeIcon(mockNode); expect(value).toContain(`assets/images/ft_ic_miscellaneous`); }); }); From 05f4c3650bc8a352f44a4fceec4e596cc0ff54b9 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 16:14:53 +0530 Subject: [PATCH 58/60] [ACS-5551] change case of text --- .../src/lib/components/details/details.component.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index d5f3b4d2f9..358ffdea0b 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -40,10 +40,6 @@ app-details-manager { .mat-tab-body-wrapper { height: 100%; } - - .mat-tab-labels { - text-transform: uppercase; - } } .acs-details-title { From bf2414110fa7ac771bcb5243a14da6dc5c5b27fd Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 20:50:40 +0530 Subject: [PATCH 59/60] [ACS-5551] unit test fix --- .../lib/components/info-drawer/info-drawer.component.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 fe94ae7f7e..c13852399e 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,6 +32,7 @@ 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; @@ -91,7 +92,7 @@ describe('InfoDrawerComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [LibTestingModule, InfoDrawerComponent], + imports: [LibTestingModule, InfoDrawerComponent, MatDialogModule], providers: [ { provide: AppExtensionService, useValue: extensionServiceMock }, { provide: Store, useValue: storeMock } From 9dc0900b82f6214f2f7f06be89a8e91f39f11b15 Mon Sep 17 00:00:00 2001 From: Anukriti Singh Date: Thu, 12 Oct 2023 21:29:54 +0530 Subject: [PATCH 60/60] [ACS-5551] header issue fixed --- .../src/lib/components/details/details.component.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/aca-content/src/lib/components/details/details.component.scss b/projects/aca-content/src/lib/components/details/details.component.scss index 358ffdea0b..7874f67835 100644 --- a/projects/aca-content/src/lib/components/details/details.component.scss +++ b/projects/aca-content/src/lib/components/details/details.component.scss @@ -34,7 +34,6 @@ app-details-manager { } .aca-details-tabs { - margin-top: 40px; height: calc(100% - 80px); .mat-tab-body-wrapper {