mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACS-11973] Fix: context menu disappears during bulk upload (#5236)
* [11973] Fix: context menu disappears during bulk upload * sonar & copilot fix * [ACS-11973] cr fix
This commit is contained in:
@@ -31,7 +31,7 @@ import { AppTestingModule } from '../../testing/app-testing.module';
|
||||
import { AppService, ContentApiService } from '@alfresco/aca-shared';
|
||||
import { getTitleElementText } from '../../testing/test-utils';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { testHeader } from '../../testing/document-base-page-utils';
|
||||
import { testHeader, testUploadEvents } from '../../testing/document-base-page-utils';
|
||||
|
||||
describe('FavoritesComponent', () => {
|
||||
let fixture: ComponentFixture<FavoritesComponent>;
|
||||
@@ -143,4 +143,9 @@ describe('FavoritesComponent', () => {
|
||||
});
|
||||
|
||||
testHeader(FavoritesComponent);
|
||||
|
||||
testUploadEvents(
|
||||
() => component,
|
||||
() => fixture
|
||||
);
|
||||
});
|
||||
|
||||
@@ -80,8 +80,8 @@ export class FavoritesComponent extends PageComponent implements OnInit {
|
||||
super.ngOnInit();
|
||||
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reload()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reload())
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection())
|
||||
]);
|
||||
|
||||
this.columns = this.extensions.documentListPresets.favorites;
|
||||
|
||||
@@ -25,7 +25,14 @@
|
||||
import { TestBed, fakeAsync, tick, ComponentFixture } from '@angular/core/testing';
|
||||
import { NO_ERRORS_SCHEMA, SimpleChange, SimpleChanges } from '@angular/core';
|
||||
import { Router, ActivatedRoute, convertToParamMap, ParamMap } from '@angular/router';
|
||||
import { DocumentListService, FilterSearch, SearchHeaderQueryBuilderService, UploadService } from '@alfresco/adf-content-services';
|
||||
import {
|
||||
DocumentListService,
|
||||
FileUploadCompleteEvent,
|
||||
FileUploadDeleteEvent,
|
||||
FilterSearch,
|
||||
SearchHeaderQueryBuilderService,
|
||||
UploadService
|
||||
} from '@alfresco/adf-content-services';
|
||||
import { NodeActionsService } from '../../services/node-actions.service';
|
||||
import { FilesComponent } from './files.component';
|
||||
import { AppTestingModule } from '../../testing/app-testing.module';
|
||||
@@ -243,6 +250,7 @@ describe('FilesComponent', () => {
|
||||
describe('refresh on events', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(component, 'reload');
|
||||
spyOn(component, 'reloadWithoutResettingSelection');
|
||||
fixture.detectChanges();
|
||||
|
||||
spyOn(component.documentList, 'loadFolder').and.callFake(() => {});
|
||||
@@ -288,32 +296,34 @@ describe('FilesComponent', () => {
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call refresh on fileUploadComplete event if parent node match', fakeAsync(() => {
|
||||
const file: any = { file: { options: { parentId: 'parentId' } } };
|
||||
component.node = { id: 'parentId' } as any;
|
||||
it('should call reloadWithoutResettingSelection on fileUploadComplete event if parent node match', fakeAsync(() => {
|
||||
const file = { file: { options: { parentId: 'parentId' } } } as FileUploadCompleteEvent;
|
||||
component.node = { id: 'parentId' } as Node;
|
||||
|
||||
uploadService.fileUploadComplete.next(file);
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).toHaveBeenCalled();
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should not call reload on fileUploadComplete event if file parent folder already displayed', fakeAsync(() => {
|
||||
spyOn(component.documentList.data, 'getRows').and.returnValue([{ node: { entry: { isFolder: true, name: 'files' } } }] as any);
|
||||
const file: any = { file: { options: { parentId: 'parentId', path: '/files' } } };
|
||||
component.node = { id: 'parentId' } as any;
|
||||
const file = { file: { options: { parentId: 'parentId', path: '/files' } } } as FileUploadCompleteEvent;
|
||||
component.node = { id: 'parentId' } as Node;
|
||||
|
||||
uploadService.fileUploadComplete.next(file);
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
expect(component.reloadWithoutResettingSelection).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should not call refresh on fileUploadComplete event if parent mismatch', fakeAsync(() => {
|
||||
const file: any = { file: { options: { parentId: 'otherId' } } };
|
||||
component.node = { id: 'parentId' } as any;
|
||||
const file = { file: { options: { parentId: 'otherId' } } } as FileUploadCompleteEvent;
|
||||
component.node = { id: 'parentId' } as Node;
|
||||
|
||||
uploadService.fileUploadComplete.next(file);
|
||||
|
||||
@@ -322,26 +332,58 @@ describe('FilesComponent', () => {
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call refresh on fileUploadDeleted event if parent node match', fakeAsync(() => {
|
||||
const file: any = { file: { options: { parentId: 'parentId' } } };
|
||||
component.node = { id: 'parentId' } as any;
|
||||
|
||||
uploadService.fileUploadDeleted.next(file);
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should not call refresh on fileUploadDeleted event if parent mismatch', fakeAsync(() => {
|
||||
const file: any = { file: { options: { parentId: 'otherId' } } };
|
||||
component.node = { id: 'parentId' } as any;
|
||||
it('should call reloadWithoutResettingSelection on fileUploadDeleted event when folder parent uploaded to current folder', fakeAsync(() => {
|
||||
const file = { file: { options: { parentId: 'parentId' } } } as FileUploadDeleteEvent;
|
||||
component.node = { id: 'parentId' } as Node;
|
||||
|
||||
uploadService.fileUploadDeleted.next(file);
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should not call refresh on fileUploadDeleted event if parent mismatch', fakeAsync(() => {
|
||||
const file = { file: { options: { parentId: 'otherId' } } } as FileUploadDeleteEvent;
|
||||
component.node = { id: 'parentId' } as Node;
|
||||
|
||||
uploadService.fileUploadDeleted.next(file);
|
||||
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call reloadWithoutResettingSelection when uploaded file belongs to current folder', fakeAsync(() => {
|
||||
const file = { file: { data: { entry: { parentId: 'folder-id' } }, options: {} } } as FileUploadCompleteEvent;
|
||||
component.node = { id: 'folder-id' } as Node;
|
||||
|
||||
uploadService.fileUploadComplete.next(file);
|
||||
tick(500);
|
||||
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should NOT call reloadWithoutResettingSelection when uploaded file belongs to a different folder', fakeAsync(() => {
|
||||
const file = { file: { data: { entry: { parentId: 'other-folder-id' } }, options: {} } } as FileUploadCompleteEvent;
|
||||
component.node = { id: 'folder-id' } as Node;
|
||||
|
||||
uploadService.fileUploadComplete.next(file);
|
||||
tick(500);
|
||||
|
||||
expect(component.reloadWithoutResettingSelection).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call reloadWithoutResettingSelection on fileUploadDeleted when file belongs to current folder', fakeAsync(() => {
|
||||
const file = { file: { data: { entry: { parentId: 'folder-id' } }, options: {} } } as FileUploadDeleteEvent;
|
||||
component.node = { id: 'folder-id' } as Node;
|
||||
|
||||
uploadService.fileUploadDeleted.next(file);
|
||||
tick(500);
|
||||
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
@@ -271,7 +271,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
|
||||
// check root and child nodes
|
||||
if (node?.entry?.parentId === this.getParentNodeId()) {
|
||||
this.reload(this.selectedNode);
|
||||
this.reloadWithoutResettingSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
if (alreadyDisplayedParentFolder) {
|
||||
return;
|
||||
}
|
||||
this.reload(this.selectedNode);
|
||||
this.reloadWithoutResettingSelection();
|
||||
}
|
||||
|
||||
onContentAdded(nodes: NodeEntry[]) {
|
||||
|
||||
@@ -31,7 +31,7 @@ import { NodePaging, SearchApi } from '@alfresco/js-api';
|
||||
import { of } from 'rxjs';
|
||||
import { getTitleElementText } from '../../testing/test-utils';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { testHeader } from '../../testing/document-base-page-utils';
|
||||
import { testHeader, testUploadEvents } from '../../testing/document-base-page-utils';
|
||||
|
||||
describe('RecentFilesComponent', () => {
|
||||
let fixture: ComponentFixture<RecentFilesComponent>;
|
||||
@@ -113,4 +113,9 @@ describe('RecentFilesComponent', () => {
|
||||
});
|
||||
|
||||
testHeader(RecentFilesComponent);
|
||||
|
||||
testUploadEvents(
|
||||
() => component,
|
||||
() => fixture
|
||||
);
|
||||
});
|
||||
|
||||
@@ -77,8 +77,8 @@ export class RecentFilesComponent extends PageComponent implements OnInit {
|
||||
super.ngOnInit();
|
||||
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reload()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reload())
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection())
|
||||
]);
|
||||
|
||||
this.columns = this.extensions.documentListPresets.recent || [];
|
||||
|
||||
@@ -33,7 +33,7 @@ import { AppService } from '@alfresco/aca-shared';
|
||||
import { getTitleElementText } from '../../testing/test-utils';
|
||||
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { testHeader } from '../../testing/document-base-page-utils';
|
||||
import { testHeader, testUploadEvents } from '../../testing/document-base-page-utils';
|
||||
|
||||
describe('SharedFilesComponent', () => {
|
||||
let fixture: ComponentFixture<SharedFilesComponent>;
|
||||
@@ -108,4 +108,9 @@ describe('SharedFilesComponent', () => {
|
||||
});
|
||||
|
||||
testHeader(SharedFilesComponent);
|
||||
|
||||
testUploadEvents(
|
||||
() => component,
|
||||
() => fixture
|
||||
);
|
||||
});
|
||||
|
||||
@@ -81,8 +81,8 @@ export class SharedFilesComponent extends PageComponent implements OnInit {
|
||||
|
||||
this.subscriptions = this.subscriptions.concat([
|
||||
this.appHookService.linksUnshared.pipe(debounceTime(300)).subscribe(() => this.reload()),
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reload()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reload())
|
||||
this.uploadService.fileUploadComplete.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection()),
|
||||
this.uploadService.fileUploadDeleted.pipe(debounceTime(300)).subscribe(() => this.reloadWithoutResettingSelection())
|
||||
]);
|
||||
|
||||
this.columns = this.extensions.documentListPresets.shared || [];
|
||||
|
||||
@@ -23,11 +23,18 @@
|
||||
*/
|
||||
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { AgentService, SearchAiInputState, SearchAiService } from '@alfresco/adf-content-services';
|
||||
import {
|
||||
AgentService,
|
||||
FileUploadCompleteEvent,
|
||||
FileUploadDeleteEvent,
|
||||
SearchAiInputState,
|
||||
SearchAiService,
|
||||
UploadService
|
||||
} from '@alfresco/adf-content-services';
|
||||
import { DebugElement, Type } from '@angular/core';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { SearchAiInputContainerComponent } from '../components/knowledge-retrieval/search-ai/search-ai-input-container/search-ai-input-container.component';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { PageComponent } from '@alfresco/aca-shared';
|
||||
import { Agent } from '@alfresco/js-api/typings';
|
||||
|
||||
@@ -101,3 +108,30 @@ export const testHeader = <T extends PageComponent>(component: Type<T>, checkHea
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const testUploadEvents = <T extends PageComponent>(getComponent: () => T, getFixture: () => ComponentFixture<T>) => {
|
||||
describe('upload events', () => {
|
||||
beforeEach(() => {
|
||||
const component: PageComponent = getComponent();
|
||||
spyOn(component, 'reload');
|
||||
spyOn(component, 'reloadWithoutResettingSelection');
|
||||
getFixture().detectChanges();
|
||||
});
|
||||
|
||||
it('should call reloadWithoutResettingSelection and not reload on fileUploadComplete', fakeAsync(() => {
|
||||
TestBed.inject(UploadService).fileUploadComplete.next({} as FileUploadCompleteEvent);
|
||||
tick(300);
|
||||
const component = getComponent();
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should call reloadWithoutResettingSelection and not reload on fileUploadDeleted', fakeAsync(() => {
|
||||
TestBed.inject(UploadService).fileUploadDeleted.next({} as FileUploadDeleteEvent);
|
||||
tick(300);
|
||||
const component = getComponent();
|
||||
expect(component.reloadWithoutResettingSelection).toHaveBeenCalled();
|
||||
expect(component.reload).not.toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
+7
@@ -226,6 +226,13 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
reloadWithoutResettingSelection(): void {
|
||||
if (this.isOutletPreviewUrl()) {
|
||||
return;
|
||||
}
|
||||
this.documentListService.reloadSilently();
|
||||
}
|
||||
|
||||
trackByActionId(_: number, action: ContentActionRef) {
|
||||
return action.id;
|
||||
}
|
||||
|
||||
@@ -157,6 +157,23 @@ describe('PageComponent', () => {
|
||||
expect(store.dispatch['calls'].mostRecent().args[0]).toEqual(new SetSelectedNodesAction([node]));
|
||||
});
|
||||
|
||||
it('should call documentListService.reloadSilently()', () => {
|
||||
spyOn(documentListService, 'reloadSilently');
|
||||
|
||||
component.reloadWithoutResettingSelection();
|
||||
|
||||
expect(documentListService.reloadSilently).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should not call documentListService.reloadSilently() when url contains viewer outlet', () => {
|
||||
window.history.pushState({}, null, `${locationHref}#test(viewer:view)`);
|
||||
spyOn(documentListService, 'reloadSilently');
|
||||
|
||||
component.reloadWithoutResettingSelection();
|
||||
|
||||
expect(documentListService.reloadSilently).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call ViewNodeAction on showPreview for selected node', () => {
|
||||
spyOn(store, 'dispatch');
|
||||
const node = {
|
||||
|
||||
Reference in New Issue
Block a user