diff --git a/app/src/app/components/files/files.component.html b/app/src/app/components/files/files.component.html index da28fdc4f..e5e271b52 100644 --- a/app/src/app/components/files/files.component.html +++ b/app/src/app/components/files/files.component.html @@ -14,7 +14,7 @@ -
+
+ + + diff --git a/app/src/app/components/files/files.component.ts b/app/src/app/components/files/files.component.ts index fe24fcb36..7b6ff4af2 100644 --- a/app/src/app/components/files/files.component.ts +++ b/app/src/app/components/files/files.component.ts @@ -32,11 +32,12 @@ import { ContentManagementService } from '../../services/content-management.serv import { NodeActionsService } from '../../services/node-actions.service'; import { PageComponent } from '../page.component'; import { AppExtensionService, ContentApiService } from '@alfresco/aca-shared'; -import { SetCurrentFolderAction, isAdmin, AppStore, UploadFileVersionAction } from '@alfresco/aca-shared/store'; +import { SetCurrentFolderAction, isAdmin, AppStore, UploadFileVersionAction, showLoaderSelector } from '@alfresco/aca-shared/store'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { debounceTime, takeUntil } from 'rxjs/operators'; import { FilterSearch, ShareDataRow } from '@alfresco/adf-content-services'; import { DocumentListPresetRef } from '@alfresco/adf-extensions'; +import { Observable } from 'rxjs'; @Component({ templateUrl: './files.component.html' @@ -48,6 +49,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { selectedNode: MinimalNodeEntity; queryParams = null; + showLoader$: Observable; private nodePath: PathElement[]; columns: DocumentListPresetRef[] = []; @@ -74,6 +76,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { this.title = data.title; + this.showLoader$ = this.store.select(showLoaderSelector); route.queryParamMap.subscribe((queryMap: Params) => { this.queryParams = queryMap.params; }); diff --git a/app/src/app/services/content-management.service.ts b/app/src/app/services/content-management.service.ts index f3d171033..cff98c42e 100644 --- a/app/src/app/services/content-management.service.ts +++ b/app/src/app/services/content-management.service.ts @@ -35,6 +35,7 @@ import { NodeInfo, ReloadDocumentListAction, SetSelectedNodesAction, + ShowLoaderAction, SnackbarAction, SnackbarErrorAction, SnackbarInfoAction, @@ -678,6 +679,7 @@ export class ContentManagementService { this.appHookService.nodesDeleted.next(); this.store.dispatch(new ReloadDocumentListAction()); } + this.store.dispatch(new ShowLoaderAction(false)); }); } diff --git a/app/src/app/store/effects/node.effects.spec.ts b/app/src/app/store/effects/node.effects.spec.ts index 5c0925c27..b9f5094c5 100644 --- a/app/src/app/store/effects/node.effects.spec.ts +++ b/app/src/app/store/effects/node.effects.spec.ts @@ -47,7 +47,8 @@ import { PrintFileAction, SetCurrentFolderAction, ManageAspectsAction, - ManagePermissionsAction + ManagePermissionsAction, + ShowLoaderAction } from '@alfresco/aca-shared/store'; import { ViewUtilService } from '@alfresco/adf-core'; import { ViewerEffects } from './viewer.effects'; @@ -201,30 +202,37 @@ describe('NodeEffects', () => { describe('deleteNodes$', () => { it('should delete nodes from the payload', () => { spyOn(contentService, 'deleteNodes').and.stub(); - + spyOn(store, 'dispatch').and.callThrough(); const node: any = {}; store.dispatch(new DeleteNodesAction([node])); + expect(store.dispatch).toHaveBeenCalledWith(new DeleteNodesAction([node])); + expect(store.dispatch).toHaveBeenCalledWith(new ShowLoaderAction(true)); expect(contentService.deleteNodes).toHaveBeenCalledWith([node]); }); it('should delete nodes from the active selection', fakeAsync(() => { spyOn(contentService, 'deleteNodes').and.stub(); - + spyOn(store, 'dispatch').and.callThrough(); const node: any = { entry: { isFile: true } }; store.dispatch(new SetSelectedNodesAction([node])); tick(100); store.dispatch(new DeleteNodesAction(null)); + + expect(store.dispatch).toHaveBeenCalledWith(new DeleteNodesAction(null)); + expect(store.dispatch).toHaveBeenCalledWith(new ShowLoaderAction(true)); expect(contentService.deleteNodes).toHaveBeenCalledWith([node]); })); it('should do nothing if invoking delete with no data', () => { spyOn(contentService, 'deleteNodes').and.stub(); - + spyOn(store, 'dispatch').and.callThrough(); store.dispatch(new DeleteNodesAction(null)); + expect(store.dispatch).toHaveBeenCalledWith(new DeleteNodesAction(null)); + expect(store.dispatch).toHaveBeenCalledWith(new ShowLoaderAction(true)); expect(contentService.deleteNodes).not.toHaveBeenCalled(); }); }); diff --git a/app/src/app/store/effects/node.effects.ts b/app/src/app/store/effects/node.effects.ts index ea2da6837..3f5b907dd 100644 --- a/app/src/app/store/effects/node.effects.ts +++ b/app/src/app/store/effects/node.effects.ts @@ -49,7 +49,8 @@ import { ManageAspectsAction, NavigateRouteAction, ExpandInfoDrawerAction, - ManageRulesAction + ManageRulesAction, + ShowLoaderAction } from '@alfresco/aca-shared/store'; import { ContentManagementService } from '../../services/content-management.service'; import { ViewUtilService } from '@alfresco/adf-core'; @@ -156,6 +157,7 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.Delete), map((action) => { + this.store.dispatch(new ShowLoaderAction(true)); if (action && action.payload && action.payload.length > 0) { this.contentService.deleteNodes(action.payload); } else { diff --git a/app/src/app/store/initial-state.ts b/app/src/app/store/initial-state.ts index c70367ef9..464eff119 100644 --- a/app/src/app/store/initial-state.ts +++ b/app/src/app/store/initial-state.ts @@ -56,6 +56,7 @@ export const INITIAL_APP_STATE: AppState = { showFacetFilter: true, fileUploadingDialog: true, documentDisplayMode: 'list', + showLoader: false, repository: { status: { isQuickShareEnabled: true diff --git a/app/src/app/store/reducers/app.reducer.ts b/app/src/app/store/reducers/app.reducer.ts index 70fb42ac3..ea07bc509 100644 --- a/app/src/app/store/reducers/app.reducer.ts +++ b/app/src/app/store/reducers/app.reducer.ts @@ -39,7 +39,8 @@ import { SetCurrentNodeVersionAction, SetFileUploadingDialogAction, SetInfoDrawerPreviewStateAction, - AppActionTypes + AppActionTypes, + ShowLoaderAction } from '@alfresco/aca-shared/store'; import { INITIAL_APP_STATE } from '../initial-state'; @@ -95,6 +96,9 @@ export function appReducer(state: AppState = INITIAL_APP_STATE, action: Action): case AppActionTypes.SetInfoDrawerPreviewState: newState = setInfoDrawerPreview(state, action as SetInfoDrawerPreviewStateAction); break; + case AppActionTypes.ShowLoaderAction: + newState = showLoader(state, action as ShowLoaderAction); + break; default: newState = { ...state }; } @@ -257,3 +261,9 @@ function setUploadDialogVisibility(state: AppState, action: SetFileUploadingDial newState.fileUploadingDialog = action.payload; return newState; } + +function showLoader(state: AppState, action: ShowLoaderAction): AppState { + const newState = { ...state }; + newState.showLoader = action.payload; + return newState; +} diff --git a/projects/aca-shared/store/src/actions/app-action-types.ts b/projects/aca-shared/store/src/actions/app-action-types.ts index ed943f409..99ce6b475 100644 --- a/projects/aca-shared/store/src/actions/app-action-types.ts +++ b/projects/aca-shared/store/src/actions/app-action-types.ts @@ -42,5 +42,6 @@ export enum AppActionTypes { CloseModalDialogs = 'CLOSE_MODAL_DIALOGS', SetFileUploadingDialog = 'SET_FILE_UPLOADING_DIALOG', ShowInfoDrawerPreview = 'SHOW_INFO_DRAWER_PREVIEW', - SetInfoDrawerPreviewState = 'SET_INFO_DRAWER_PREVIEW_STATE' + SetInfoDrawerPreviewState = 'SET_INFO_DRAWER_PREVIEW_STATE', + ShowLoaderAction = 'SHOW_LOADER' } diff --git a/projects/aca-shared/store/src/actions/app.actions.ts b/projects/aca-shared/store/src/actions/app.actions.ts index 9eba1870c..585394759 100644 --- a/projects/aca-shared/store/src/actions/app.actions.ts +++ b/projects/aca-shared/store/src/actions/app.actions.ts @@ -125,3 +125,9 @@ export class SetInfoDrawerPreviewStateAction implements Action { constructor(public payload: boolean) {} } + +export class ShowLoaderAction implements Action { + readonly type = AppActionTypes.ShowLoaderAction; + + constructor(public payload: boolean) {} +} diff --git a/projects/aca-shared/store/src/selectors/app.selectors.ts b/projects/aca-shared/store/src/selectors/app.selectors.ts index 316249410..f228f0a3a 100644 --- a/projects/aca-shared/store/src/selectors/app.selectors.ts +++ b/projects/aca-shared/store/src/selectors/app.selectors.ts @@ -49,6 +49,7 @@ export const getRepositoryStatus = createSelector(selectApp, (state) => state.re export const isQuickShareEnabled = createSelector(getRepositoryStatus, (info) => info.status.isQuickShareEnabled); export const isAdmin = createSelector(selectApp, (state) => state.user.isAdmin); export const getFileUploadingDialog = createSelector(selectApp, (state) => state.fileUploadingDialog); +export const showLoaderSelector = createSelector(selectApp, (state) => state.showLoader); export const getSideNavState = createSelector(getAppSelection, getNavigationState, (selection, navigation) => ({ selection, diff --git a/projects/aca-shared/store/src/states/app.state.ts b/projects/aca-shared/store/src/states/app.state.ts index 6bae739a3..da6ffb032 100644 --- a/projects/aca-shared/store/src/states/app.state.ts +++ b/projects/aca-shared/store/src/states/app.state.ts @@ -46,6 +46,7 @@ export interface AppState { documentDisplayMode: string; repository: RepositoryInfo; fileUploadingDialog: boolean; + showLoader: boolean; } export interface AppStore {