diff --git a/projects/aca-content/assets/app.extensions.json b/projects/aca-content/assets/app.extensions.json
index 288a453032..670e8f3df9 100644
--- a/projects/aca-content/assets/app.extensions.json
+++ b/projects/aca-content/assets/app.extensions.json
@@ -632,6 +632,21 @@
"visible": "app.selection.canDelete"
}
},
+ {
+ "id": "app.context.menu.folder-info",
+ "title": "APP.ACTIONS.FOLDER_INFO",
+ "order": 800,
+ "icon": "info",
+ "actions": {
+ "click": "FOLDER_INFORMATION"
+ },
+ "rules": {
+ "visible": [
+ "app.selection.folder",
+ "!app.navigation.isTrashcan"
+ ]
+ }
+ },
{
"id": "app.create.separator.3",
"type": "separator",
@@ -877,6 +892,21 @@
"visible": "app.selection.canDelete"
}
},
+ {
+ "id": "app.context.menu.folder-info",
+ "title": "APP.ACTIONS.FOLDER_INFO",
+ "order": 1200,
+ "icon": "info",
+ "actions": {
+ "click": "FOLDER_INFORMATION"
+ },
+ "rules": {
+ "visible": [
+ "app.selection.folder",
+ "!app.navigation.isTrashcan"
+ ]
+ }
+ },
{
"id": "app.create.separator.3",
"type": "separator",
diff --git a/projects/aca-content/assets/i18n/en.json b/projects/aca-content/assets/i18n/en.json
index 51d5e22cc4..9d71c194b7 100644
--- a/projects/aca-content/assets/i18n/en.json
+++ b/projects/aca-content/assets/i18n/en.json
@@ -299,7 +299,8 @@
"EDIT_OFFLINE": "Edit Offline",
"EDIT_OFFLINE_CANCEL": "Cancel Editing",
"CHANGE_ASPECT": "Edit Aspects",
- "ADD_ASPECTS": "Add Aspects"
+ "ADD_ASPECTS": "Add Aspects",
+ "FOLDER_INFO": "Folder Information"
},
"DIALOGS": {
"CONFIRM_PURGE": {
@@ -451,7 +452,19 @@
"OPTIONS_SETTINGS": "Options and settings",
"MY_PROFILE": "My profile",
"EXPAND_NAVIGATION": "Expand navigation menu"
- }
+ },
+ "FOLDER_INFO": {
+ "ICON": "Folder Icon",
+ "TITLE": "Folder Information",
+ "SIZE" : "Size",
+ "CALCULATING": "Calculating...",
+ "CALCULATED_SIZE_LARGE": "{{sizeInBytes}} bytes ({{sizeInLargeUnit}} {{unit}} on disk) for {{count}} files",
+ "CALCULATED_SIZE_NORMAL": "{{sizeInBytes}} bytes for {{count}} files",
+ "LOCATION": "Location",
+ "CREATED": "Created",
+ "MODIFIED": "Modified",
+ "DONE": "Done"
+ }
},
"NODE_SELECTOR": {
"COPY_ITEM": "Copy '{{ name }}' to...",
diff --git a/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.html b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.html
new file mode 100644
index 0000000000..08fdbe364c
--- /dev/null
+++ b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.html
@@ -0,0 +1,32 @@
+
+
+
+
+
{{ 'APP.FOLDER_INFO.SIZE' | translate }}
+
{{ folderDetails.size }}
+
+
+
+
{{ 'APP.FOLDER_INFO.LOCATION' | translate }}
+
{{ folderDetails.location }}
+
+
+
+
{{ 'APP.FOLDER_INFO.CREATED' | translate }}
+
{{ folderDetails.created | adfTimeAgo }}
+
+
+
+
{{ 'APP.FOLDER_INFO.MODIFIED' | translate }}
+
{{ folderDetails.modified | adfTimeAgo }}
+
+
diff --git a/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.scss b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.scss
new file mode 100644
index 0000000000..b2173e9dcd
--- /dev/null
+++ b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.scss
@@ -0,0 +1,43 @@
+.app-folder-info {
+ display: flex;
+ flex-direction: column;
+ border: 1px solid var(--theme-border-color);
+ border-radius: 12px;
+
+ .aca-folder-info {
+ &-header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ column-gap: 10px;
+ padding: 20px;
+
+ .aca-folder-title {
+ flex: 1;
+ font-weight: bold;
+ }
+ }
+
+ &-body {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ padding: 10px 20px;
+
+ .aca-folder-info-item {
+ display: flex;
+ flex-direction: row;
+ padding: 20px 0;
+
+ &-label {
+ width: 30%;
+ color: var(--theme-text-color);
+ }
+
+ &-value {
+ width: 70%;
+ }
+ }
+ }
+ }
+}
diff --git a/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.spec.ts b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.spec.ts
new file mode 100644
index 0000000000..00a5a3c60b
--- /dev/null
+++ b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.spec.ts
@@ -0,0 +1,117 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { FolderInformationComponent } from './folder-information.component';
+import { DIALOG_COMPONENT_DATA, RedirectAuthService } from '@alfresco/adf-core';
+import { ContentService, NodesApiService } from '@alfresco/adf-content-services';
+import { By } from '@angular/platform-browser';
+import { EMPTY, Observable, of, Subject } from 'rxjs';
+import { LibTestingModule } from '@alfresco/aca-shared';
+import { JobIdBodyEntry, SizeDetails, SizeDetailsEntry, Node } from '@alfresco/js-api';
+
+describe('FolderInformationComponent', () => {
+ let fixture: ComponentFixture;
+ let nodeService: NodesApiService;
+ let initiateFolderSizeCalculationSpy: jasmine.Spy<(nodeId: string) => Observable>;
+ let getFolderSizeInfoSpy: jasmine.Spy<(nodeId: string, jobId: string) => Observable>;
+
+ const mockSub = new Subject();
+ const dialogData = {
+ name: 'mock-folder',
+ id: 'mock-folder-id',
+ path: {
+ name: 'mock-folder-path'
+ },
+ createdAt: new Date(2024, 1, 1, 11, 11),
+ modifiedAt: new Date(2024, 2, 2, 22, 22)
+ } as Node;
+ const mockSizeDetailsEntry: SizeDetailsEntry = {
+ entry: {
+ id: 'mock-id',
+ sizeInBytes: '1',
+ calculatedAt: 'mock-date',
+ numberOfFiles: 1,
+ status: SizeDetails.StatusEnum.COMPLETE,
+ jobId: 'mock-job-id'
+ }
+ };
+
+ const getValueFromElement = (id: string): string => fixture.debugElement.query(By.css(`[data-automation-id="${id}"]`)).nativeElement.textContent;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [FolderInformationComponent, LibTestingModule],
+ providers: [
+ { provide: DIALOG_COMPONENT_DATA, useValue: dialogData },
+ { provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: EMPTY } }
+ ]
+ });
+ fixture = TestBed.createComponent(FolderInformationComponent);
+ nodeService = TestBed.inject(NodesApiService);
+ spyOn(TestBed.inject(ContentService), 'getNodeIcon').and.returnValue('./assets/images/ft_ic_folder.svg');
+ initiateFolderSizeCalculationSpy = spyOn(nodeService, 'initiateFolderSizeCalculation').and.returnValue(mockSub.asObservable());
+ getFolderSizeInfoSpy = spyOn(nodeService, 'getFolderSizeInfo').and.returnValue(EMPTY);
+ });
+
+ it('should render all information in init', () => {
+ fixture.detectChanges();
+ expect(getValueFromElement('folder-info-name')).toBe('mock-folder');
+ expect(getValueFromElement('folder-info-size')).toBe('APP.FOLDER_INFO.CALCULATING');
+ expect(getValueFromElement('folder-info-location')).toBe('mock-folder-path');
+ expect(getValueFromElement('folder-info-creation-date')).toBe('01/02/2024 11:11');
+ expect(getValueFromElement('folder-info-modify-date')).toBe('02/03/2024 22:22');
+ });
+
+ it('should make API call on init to start folder size calculation', () => {
+ fixture.detectChanges();
+ expect(initiateFolderSizeCalculationSpy).toHaveBeenCalledWith('mock-folder-id');
+ });
+
+ it('should fetch folder size only when the initial folder size calculation request is completed', () => {
+ fixture.detectChanges();
+ expect(initiateFolderSizeCalculationSpy).toHaveBeenCalledWith('mock-folder-id');
+ expect(getFolderSizeInfoSpy).not.toHaveBeenCalled();
+ mockSub.next({ entry: { jobId: 'mock-job-id' } });
+ expect(getFolderSizeInfoSpy).toHaveBeenCalled();
+ });
+
+ it('should make repeated calls to get folder size info, if the response returned from the API is IN_PROGRESS', fakeAsync(() => {
+ mockSizeDetailsEntry.entry.status = SizeDetails.StatusEnum.IN_PROGRESS;
+ getFolderSizeInfoSpy.and.returnValue(of(mockSizeDetailsEntry));
+ fixture.detectChanges();
+ expect(getFolderSizeInfoSpy).not.toHaveBeenCalled();
+ mockSub.next({ entry: { jobId: 'mock-job-id' } });
+ expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(1);
+ tick(5000);
+ expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(2);
+ tick(5000);
+ expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(3);
+ mockSizeDetailsEntry.entry.status = SizeDetails.StatusEnum.COMPLETE;
+ tick(5000);
+ expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(4);
+ tick(5000);
+ expect(getFolderSizeInfoSpy).not.toHaveBeenCalledTimes(5);
+ }));
+});
diff --git a/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.ts b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.ts
new file mode 100644
index 0000000000..65dc223065
--- /dev/null
+++ b/projects/aca-content/src/lib/dialogs/folder-details/folder-information.component.ts
@@ -0,0 +1,110 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
+import { CommonModule, NgOptimizedImage } from '@angular/common';
+import { DIALOG_COMPONENT_DATA, LocalizedDatePipe, TimeAgoPipe } from '@alfresco/adf-core';
+import { JobIdBodyEntry, Node, SizeDetails } from '@alfresco/js-api';
+import { MatDividerModule } from '@angular/material/divider';
+import { TranslateModule, TranslateService } from '@ngx-translate/core';
+import { ContentService, NodesApiService } from '@alfresco/adf-content-services';
+import { concatMap, expand, first, switchMap } from 'rxjs/operators';
+import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
+import { EMPTY, timer } from 'rxjs';
+
+const MEMORY_UNIT_LIST = ['bytes', 'KB', 'MB', 'GB', 'TB'];
+
+class FolderDetails {
+ name: string;
+ size: string;
+ location: string;
+ created: Date;
+ modified: Date;
+ icon: string;
+}
+
+@Component({
+ selector: 'app-folder-info',
+ standalone: true,
+ imports: [CommonModule, MatDividerModule, TimeAgoPipe, TranslateModule, LocalizedDatePipe, NgOptimizedImage],
+ templateUrl: './folder-information.component.html',
+ styleUrls: ['./folder-information.component.scss'],
+ encapsulation: ViewEncapsulation.None,
+ host: { class: 'app-folder-info' }
+})
+export class FolderInformationComponent implements OnInit {
+ readonly contentService = inject(ContentService);
+ readonly nodesService = inject(NodesApiService);
+ readonly translateService = inject(TranslateService);
+
+ private readonly destroyRef = inject(DestroyRef);
+
+ data: Node = inject(DIALOG_COMPONENT_DATA);
+ folderDetails: FolderDetails = new FolderDetails();
+
+ ngOnInit() {
+ this.folderDetails.name = this.data.name;
+ this.folderDetails.location = this.data.path.name;
+ this.folderDetails.created = this.data.createdAt;
+ this.folderDetails.modified = this.data.modifiedAt;
+ this.folderDetails.icon = this.contentService.getNodeIcon(this.data);
+ this.folderDetails.size = this.translateService.instant('APP.FOLDER_INFO.CALCULATING');
+
+ this.nodesService
+ .initiateFolderSizeCalculation(this.data.id)
+ .pipe(
+ first(),
+ switchMap((jobIdEntry: JobIdBodyEntry) => {
+ return this.nodesService.getFolderSizeInfo(this.data.id, jobIdEntry.entry.jobId).pipe(
+ expand((result) =>
+ result.entry.status === SizeDetails.StatusEnum.IN_PROGRESS
+ ? timer(5000).pipe(concatMap(() => this.nodesService.getFolderSizeInfo(this.data.id, jobIdEntry.entry.jobId)))
+ : EMPTY
+ ),
+ takeUntilDestroyed(this.destroyRef)
+ );
+ })
+ )
+ .subscribe((folderInfo) => {
+ let size = parseFloat(folderInfo.entry.sizeInBytes);
+ let unitIndex = 0;
+ let isMoreThanBytes = false;
+ while (size > 1000) {
+ isMoreThanBytes = true;
+ size = size / 1000;
+ unitIndex++;
+ }
+ const params = {
+ sizeInBytes: parseFloat(folderInfo.entry.sizeInBytes).toLocaleString('en'),
+ sizeInLargeUnit: size.toFixed(2),
+ unit: MEMORY_UNIT_LIST[unitIndex],
+ count: folderInfo.entry.numberOfFiles
+ };
+ this.folderDetails.size = this.translateService.instant(
+ isMoreThanBytes ? 'APP.FOLDER_INFO.CALCULATED_SIZE_LARGE' : 'APP.FOLDER_INFO.CALCULATED_SIZE_NORMAL',
+ params
+ );
+ });
+ }
+}
diff --git a/projects/aca-content/src/lib/services/content-management.service.spec.ts b/projects/aca-content/src/lib/services/content-management.service.spec.ts
index c0e6f0a88d..6f29e7127a 100644
--- a/projects/aca-content/src/lib/services/content-management.service.spec.ts
+++ b/projects/aca-content/src/lib/services/content-management.service.spec.ts
@@ -53,10 +53,10 @@ import { AppHookService, AppSettingsService, ContentApiService } from '@alfresco
import { Store } from '@ngrx/store';
import { ContentManagementService } from './content-management.service';
import { NodeActionsService } from './node-actions.service';
-import { NotificationService, TranslationService } from '@alfresco/adf-core';
+import { DialogComponent, DialogSize, NotificationService, TranslationService } from '@alfresco/adf-core';
import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatSnackBarModule, MatSnackBarRef, SimpleSnackBar } from '@angular/material/snack-bar';
-import { Node, NodeEntry, VersionPaging } from '@alfresco/js-api';
+import { Node, NodeEntry, UserInfo, VersionPaging } from '@alfresco/js-api';
import {
DocumentListService,
FileModel,
@@ -67,6 +67,7 @@ import {
NodesApiService,
ViewVersion
} from '@alfresco/adf-content-services';
+import { FolderInformationComponent } from '../dialogs/folder-details/folder-information.component';
describe('ContentManagementService', () => {
let dialog: MatDialog;
@@ -1847,4 +1848,38 @@ describe('ContentManagementService', () => {
expect(store.dispatch).toHaveBeenCalledWith(new NavigateRouteAction(['/libraries']));
}));
});
+
+ describe('folderInformationDialog', () => {
+ it('should open folder information dialog', () => {
+ spyOn(dialog, 'open');
+
+ const fakeNode: NodeEntry = {
+ entry: {
+ id: 'folder-node-id',
+ name: 'mock-folder-name',
+ nodeType: 'fake-node-type',
+ isFolder: true,
+ isFile: false,
+ modifiedAt: new Date(),
+ modifiedByUser: new UserInfo(),
+ createdAt: new Date(),
+ createdByUser: new UserInfo()
+ }
+ };
+
+ contentManagementService.showFolderInformation(fakeNode);
+ expect(dialog.open).toHaveBeenCalledWith(DialogComponent, {
+ data: {
+ title: 'APP.FOLDER_INFO.TITLE',
+ confirmButtonTitle: 'APP.FOLDER_INFO.DONE',
+ isCancelButtonHidden: true,
+ isCloseButtonHidden: false,
+ dialogSize: DialogSize.Large,
+ contentComponent: FolderInformationComponent,
+ componentData: fakeNode.entry
+ },
+ width: '700px'
+ });
+ });
+ });
});
diff --git a/projects/aca-content/src/lib/services/content-management.service.ts b/projects/aca-content/src/lib/services/content-management.service.ts
index 1d4142d50d..10b6cd8f89 100644
--- a/projects/aca-content/src/lib/services/content-management.service.ts
+++ b/projects/aca-content/src/lib/services/content-management.service.ts
@@ -54,7 +54,7 @@ import {
NodesApiService,
ShareDialogComponent
} from '@alfresco/adf-content-services';
-import { NotificationService, TranslationService, ConfirmDialogComponent } from '@alfresco/adf-core';
+import { NotificationService, TranslationService, ConfirmDialogComponent, DialogComponent, DialogSize } from '@alfresco/adf-core';
import { DeletedNodesPaging, Node, NodeEntry, PathInfo, SiteBodyCreate, SiteEntry } from '@alfresco/js-api';
import { inject, Injectable } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
@@ -63,6 +63,7 @@ import { forkJoin, Observable, of, zip } from 'rxjs';
import { catchError, map, mergeMap, take, tap } from 'rxjs/operators';
import { NodeActionsService } from './node-actions.service';
import { Router } from '@angular/router';
+import { FolderInformationComponent } from '../dialogs/folder-details/folder-information.component';
interface RestoredNode {
status: number;
@@ -1089,4 +1090,19 @@ export class ContentManagementService {
document.querySelector(focusedElementSelector)?.focus();
}
}
+
+ showFolderInformation(node: NodeEntry) {
+ this.dialogRef.open(DialogComponent, {
+ data: {
+ title: 'APP.FOLDER_INFO.TITLE',
+ confirmButtonTitle: 'APP.FOLDER_INFO.DONE',
+ isCancelButtonHidden: true,
+ isCloseButtonHidden: false,
+ dialogSize: DialogSize.Large,
+ contentComponent: FolderInformationComponent,
+ componentData: node.entry
+ },
+ width: '700px'
+ });
+ }
}
diff --git a/projects/aca-content/src/lib/store/effects/node.effects.spec.ts b/projects/aca-content/src/lib/store/effects/node.effects.spec.ts
index e2b8d38f75..e6d5696b37 100644
--- a/projects/aca-content/src/lib/store/effects/node.effects.spec.ts
+++ b/projects/aca-content/src/lib/store/effects/node.effects.spec.ts
@@ -34,6 +34,7 @@ import {
DeleteNodesAction,
EditFolderAction,
ExpandInfoDrawerAction,
+ FolderInformationAction,
FullscreenViewerAction,
ManageAspectsAction,
ManagePermissionsAction,
@@ -59,6 +60,7 @@ import { NavigationEnd, Router, ActivatedRoute } from '@angular/router';
import { of } from 'rxjs';
import { MatDialogModule } from '@angular/material/dialog';
import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { NodeEntry, UserInfo } from '@alfresco/js-api';
describe('NodeEffects', () => {
let store: Store;
@@ -564,4 +566,40 @@ describe('NodeEffects', () => {
expect(store.dispatch).toHaveBeenCalledWith(new NavigateUrlAction('personal-files/details/node-id?location=test-page'));
});
});
+
+ describe('folderInformation$', () => {
+ it('should call folder information dialog', () => {
+ const node: any = { entry: { isFile: true } };
+ spyOn(contentService, 'showFolderInformation').and.stub();
+
+ store.dispatch(new FolderInformationAction(node));
+
+ expect(contentService.showFolderInformation).toHaveBeenCalled();
+ });
+
+ it('should call folder information dialog from the active folder selection', fakeAsync(() => {
+ spyOn(contentService, 'showFolderInformation').and.stub();
+
+ const node: NodeEntry = {
+ entry: {
+ id: 'folder-node-id',
+ name: 'mock-folder-name',
+ nodeType: 'fake-node-type',
+ isFolder: true,
+ isFile: false,
+ modifiedAt: new Date(),
+ modifiedByUser: new UserInfo(),
+ createdAt: new Date(),
+ createdByUser: new UserInfo()
+ }
+ };
+ store.dispatch(new SetSelectedNodesAction([node]));
+
+ tick(100);
+
+ store.dispatch(new FolderInformationAction(null));
+
+ expect(contentService.showFolderInformation).toHaveBeenCalledWith(node);
+ }));
+ });
});
diff --git a/projects/aca-content/src/lib/store/effects/node.effects.ts b/projects/aca-content/src/lib/store/effects/node.effects.ts
index a2378beae9..c699cddaec 100644
--- a/projects/aca-content/src/lib/store/effects/node.effects.ts
+++ b/projects/aca-content/src/lib/store/effects/node.effects.ts
@@ -51,7 +51,8 @@ import {
ShowLoaderAction,
UndoDeleteNodesAction,
UnlockWriteAction,
- UnshareNodesAction
+ UnshareNodesAction,
+ FolderInformationAction
} from '@alfresco/aca-shared/store';
import { ContentManagementService } from '../../services/content-management.service';
import { RenditionService } from '@alfresco/adf-content-services';
@@ -460,4 +461,26 @@ export class NodeEffects {
),
{ dispatch: false }
);
+
+ folderInformation$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(NodeActionTypes.FolderInformation),
+ map((action) => {
+ if (action?.payload) {
+ this.contentService.showFolderInformation(action.payload);
+ } else {
+ this.store
+ .select(getAppSelection)
+ .pipe(take(1))
+ .subscribe((selection) => {
+ if (selection && !selection.isEmpty && selection.folder.entry) {
+ this.contentService.showFolderInformation(selection.folder);
+ }
+ });
+ }
+ })
+ ),
+ { dispatch: false }
+ );
}
diff --git a/projects/aca-shared/store/src/actions/node.actions.ts b/projects/aca-shared/store/src/actions/node.actions.ts
index ca39694761..da1174103d 100644
--- a/projects/aca-shared/store/src/actions/node.actions.ts
+++ b/projects/aca-shared/store/src/actions/node.actions.ts
@@ -39,6 +39,7 @@ export enum NodeActionTypes {
Unshare = 'UNSHARE_NODES',
Copy = 'COPY_NODES',
Move = 'MOVE_NODES',
+ FolderInformation = 'FOLDER_INFORMATION',
ManagePermissions = 'MANAGE_PERMISSIONS',
PrintFile = 'PRINT_FILE',
ManageVersions = 'MANAGE_VERSIONS',
@@ -180,3 +181,9 @@ export class ManageRulesAction implements Action {
constructor(public payload: NodeEntry) {}
}
+
+export class FolderInformationAction implements Action {
+ readonly type = NodeActionTypes.FolderInformation;
+
+ constructor(public payload: NodeEntry) {}
+}