Skip to content

Commit

Permalink
[MNT-24575] Addressed Code review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
swapnil-verma-gl committed Dec 18, 2024
1 parent 40d3eee commit f26b34f
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
<div class="aca-folder-info-container">
<div class="aca-folder-info-header">
<div class="aca-folder-icon">
<img alt="{{ 'APP.FOLDER_INFO.ICON' | translate }}" src="{{ folderDetails.icon }}">
</div>
<div class="aca-folder-title" data-automation-id="folder-info-name">{{ folderDetails.name }}</div>
<div class="aca-folder-info-header">
<img alt="{{ 'APP.FOLDER_INFO.ICON' | translate }}" ngSrc="{{ folderDetails.icon }}" width="24" height="24">
<div class="aca-folder-title" data-automation-id="folder-info-name">{{ folderDetails.name }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-body">
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.SIZE' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-size">{{ folderDetails.size }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.LOCATION' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-location">{{ folderDetails.location }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.CREATED' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-creation-date"
[title]="folderDetails.created | adfLocalizedDate">{{ folderDetails.created | adfTimeAgo }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-body">
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.SIZE' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-size">{{ folderDetails.size }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.LOCATION' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-location">{{ folderDetails.location }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.CREATED' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-creation-date"
[title]="folderDetails.created | adfLocalizedDate">{{ folderDetails.created | adfTimeAgo }}</div>
</div>
<mat-divider/>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.MODIFIED' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-modify-date"
[title]="folderDetails.modified | adfLocalizedDate">{{ folderDetails.modified | adfTimeAgo }}</div>
</div>
<div class="aca-folder-info-item">
<div class="aca-folder-info-item-label">{{ 'APP.FOLDER_INFO.MODIFIED' | translate }}</div>
<div class="aca-folder-info-item-value"
data-automation-id="folder-info-modify-date"
[title]="folderDetails.modified | adfLocalizedDate">{{ folderDetails.modified | adfTimeAgo }}</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
.app-folder-info {
.aca-folder-info {
&-container {
display: flex;
flex-direction: column;
border: 1px solid var(--theme-border-color);
border-radius: 12px;
}
display: flex;
flex-direction: column;
border: 1px solid var(--theme-border-color);
border-radius: 12px;

.aca-folder-info {
&-header {
display: flex;
flex-direction: row;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ 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, of, Subject } from 'rxjs';
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<FolderInformationComponent>;
let nodeService: NodesApiService;
let initiateFolderSizeCalculationSpy: jasmine.Spy;
let getFolderSizeInfoSpy: jasmine.Spy;
const mockSub = new Subject<{ entry: { jobId: string } }>();
let initiateFolderSizeCalculationSpy: jasmine.Spy<(nodeId: string) => Observable<JobIdBodyEntry>>;
let getFolderSizeInfoSpy: jasmine.Spy<(nodeId: string, jobId: string) => Observable<SizeDetailsEntry>>;

const mockSub = new Subject<JobIdBodyEntry>();
const dialogData = {
name: 'mock-folder',
id: 'mock-folder-id',
Expand All @@ -45,9 +46,20 @@ describe('FolderInformationComponent', () => {
},
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],
Expand Down Expand Up @@ -86,7 +98,8 @@ describe('FolderInformationComponent', () => {
});

it('should make repeated calls to get folder size info, if the response returned from the API is IN_PROGRESS', fakeAsync(() => {
getFolderSizeInfoSpy.and.returnValue(of({ entry: { status: 'IN_PROGRESS' } }));
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' } });
Expand All @@ -95,7 +108,7 @@ describe('FolderInformationComponent', () => {
expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(2);
tick(5000);
expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(3);
getFolderSizeInfoSpy.and.returnValue(of({ entry: { status: 'COMPLETE' } }));
mockSizeDetailsEntry.entry.status = SizeDetails.StatusEnum.COMPLETE;
tick(5000);
expect(getFolderSizeInfoSpy).toHaveBeenCalledTimes(4);
tick(5000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@
*/

import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { CommonModule, NgIf } from '@angular/common';
import { CommonModule, NgOptimizedImage } from '@angular/common';
import { DIALOG_COMPONENT_DATA, LocalizedDatePipe, TimeAgoPipe } from '@alfresco/adf-core';
import { JobIdBodyEntry, Node, SizeDetailsEntry } from '@alfresco/js-api';
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 } from 'rxjs/operators';
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'];

interface FolderDetails {
class FolderDetails {
name: string;
size: string;
location: string;
Expand All @@ -47,7 +47,7 @@ interface FolderDetails {
@Component({
selector: 'app-folder-info',
standalone: true,
imports: [CommonModule, MatDividerModule, TimeAgoPipe, NgIf, TranslateModule, LocalizedDatePipe, LocalizedDatePipe],
imports: [CommonModule, MatDividerModule, TimeAgoPipe, TranslateModule, LocalizedDatePipe, NgOptimizedImage],
templateUrl: './folder-information.component.html',
styleUrls: ['./folder-information.component.scss'],
encapsulation: ViewEncapsulation.None,
Expand All @@ -61,7 +61,7 @@ export class FolderInformationComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);

data: Node = inject(DIALOG_COMPONENT_DATA);
folderDetails: FolderDetails;
folderDetails: FolderDetails = new FolderDetails();

ngOnInit() {
this.folderDetails.name = this.data.name;
Expand All @@ -73,38 +73,38 @@ export class FolderInformationComponent implements OnInit {

this.nodesService
.initiateFolderSizeCalculation(this.data.id)
.pipe(first())
.subscribe((jobIdEntry: JobIdBodyEntry) => {
this.nodesService
.getFolderSizeInfo(this.data.id, jobIdEntry.entry.jobId)
.pipe(
expand((result: SizeDetailsEntry) =>
result.entry.status === 'IN_PROGRESS'
.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: SizeDetailsEntry) => {
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
);
});
);
})
)
.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
);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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'
});
});
});
});
38 changes: 38 additions & 0 deletions projects/aca-content/src/lib/store/effects/node.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
DeleteNodesAction,
EditFolderAction,
ExpandInfoDrawerAction,
FolderInformationAction,
FullscreenViewerAction,
ManageAspectsAction,
ManagePermissionsAction,
Expand All @@ -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<any>;
Expand Down Expand Up @@ -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);
}));
});
});

0 comments on commit f26b34f

Please sign in to comment.