mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-06-30 18:14:45 +00:00
[ACS-8746] use notification service instead of store, yellow warnings, warning on no library permission (#4577)
* [ACS-8746] use notification service instead of store, yellow warnings, warning on no library permissions * [ACS-8746] move snackbar bg styling to app level, review comments * [ACS-8746] change warning color for improved accessibility * [ACS-8746] fix wrong css class for copy and move notifications * [ACS-8746] completely replace SnackbarActions with notifications service, update warning color * [ACS-8746] improve copy and move nodes notifications * ACS-8746 fix undo delete notification action * ACS-8746 review comments * ACS-8746 review comments
This commit is contained in:
parent
1072c7d2f3
commit
f48fc8c2d7
@ -92,9 +92,7 @@ export const myExtensionLoader = (route: ActivatedRouteSnapshot) => {
|
||||
tap((status) => {
|
||||
if (!status) {
|
||||
// If the BE is down, let the user know what to expect
|
||||
store.dispatch(
|
||||
new SnackbarErrorAction("Backend error. My Extension's features are disabled.")
|
||||
);
|
||||
notificationService.showError("Backend error. My Extension's features are disabled.");
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "هذه المكتبة لم تعد موجودة.",
|
||||
"LIBRARY_NO_PERMISSIONS": "ليس لديك الإذن لعرض هذه المكتبة.",
|
||||
"LIBRARY_LOADING_ERROR": "حدثت بعض المشاكل أثناء تحميل هذه المكتبة."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "ليس لديك الإذن لعرض هذه المكتبة."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "الملفات المشتركة",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Tato knihovna již neexistuje.",
|
||||
"LIBRARY_NO_PERMISSIONS": "K zobrazení této knihovny nemáte oprávnění.",
|
||||
"LIBRARY_LOADING_ERROR": "Při načítání této knihovny došlo k problému."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "K zobrazení této knihovny nemáte oprávnění."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Sdílené soubory",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Dette bibliotek findes ikke mere.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Du har ikke tilladelse til at se dette bibliotek.",
|
||||
"LIBRARY_LOADING_ERROR": "Der var problemer under hentning af dette bibliotek."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Du har ikke tilladelse til at se dette bibliotek."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Delte filer",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Diese Bibliothek ist nicht länger vorhanden.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Sie haben keine Berechtigung, diese Bibliothek anzuzeigen.",
|
||||
"LIBRARY_LOADING_ERROR": "Beim Laden dieser Bibliothek ist ein Fehler aufgetreten."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Sie haben keine Berechtigung, diese Bibliothek anzuzeigen."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Freigegebene Dateien",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "This library no longer exists.",
|
||||
"LIBRARY_NO_PERMISSIONS": "You do not have permission to view this library.",
|
||||
"LIBRARY_LOADING_ERROR": "There was some problem during loading this library."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "You do not have permission to view this library."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Shared Files",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Esta biblioteca ya no existe.",
|
||||
"LIBRARY_NO_PERMISSIONS": "No tiene permiso para ver esta biblioteca.",
|
||||
"LIBRARY_LOADING_ERROR": "Ha habido un problema al cargar esta biblioteca."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "No tiene permiso para ver esta biblioteca."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Ficheros compartidos",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Tätä kirjastoa ei ole enää olemassa",
|
||||
"LIBRARY_NO_PERMISSIONS": "Sinulla ei ole oikeutta tarkastella tätä kirjastoa.",
|
||||
"LIBRARY_LOADING_ERROR": "Tämän kirjaston lataamisessa ilmeni ongelma."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Sinulla ei ole oikeutta tarkastella tätä kirjastoa."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Jaetut tiedostot",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Cette bibliothèque n'existe plus.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Vous n'avez pas la permission de consulter cette bibliothèque.",
|
||||
"LIBRARY_LOADING_ERROR": "Un problème s'est produit pendant le chargement de cette bibliothèque."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Vous n'avez pas la permission de consulter cette bibliothèque."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Fichiers partagés",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Questa libreria non esiste più.",
|
||||
"LIBRARY_NO_PERMISSIONS": "L'utente non dispone dell'autorizzazione per visualizzare questa libreria.",
|
||||
"LIBRARY_LOADING_ERROR": "Ci sono stati dei problemi nel caricamento di questa libreria."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "L'utente non dispone dell'autorizzazione per visualizzare questa libreria."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "File condivisi",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "このライブラリはもはや存在しません。",
|
||||
"LIBRARY_NO_PERMISSIONS": "このライブラリを閲覧する権限がありません。",
|
||||
"LIBRARY_LOADING_ERROR": "このライブラリのロード中に何らかの問題が発生しました。"
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "このライブラリを閲覧する権限がありません。"
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "共有ファイル",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Deze bibliotheek bestaat niet meer.",
|
||||
"LIBRARY_NO_PERMISSIONS": "U hebt geen machtiging om deze bibliotheek te bekijken.",
|
||||
"LIBRARY_LOADING_ERROR": "Er was een probleem bij het laden van deze bibliotheek."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "U hebt geen machtiging om deze bibliotheek te bekijken."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Gedeelde bestanden",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Dette biblioteket eksisterer ikke lenger.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Du har ikke tillatelse til å vise dette biblioteket.",
|
||||
"LIBRARY_LOADING_ERROR": "Det oppsto et problem under lasting av dette biblioteket."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Du har ikke tillatelse til å vise dette biblioteket."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Delte filer",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Ta biblioteka już nie istnieje.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Nie masz uprawnień do wyświetlenia tej biblioteki.",
|
||||
"LIBRARY_LOADING_ERROR": "Wystąpił problem podczas ładowania tej biblioteki."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Nie masz uprawnień do wyświetlenia tej biblioteki."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Udostępnione pliki",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Esta biblioteca já não existe.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Você não tem permissão para visualizar esta biblioteca.",
|
||||
"LIBRARY_LOADING_ERROR": "Ocorreu um problema ao carregar esta biblioteca."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Você não tem permissão para visualizar esta biblioteca."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Arquivos compartilhados",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Данная библиотека не существует.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Нет прав для просмотра данной библиотеки.",
|
||||
"LIBRARY_LOADING_ERROR": "Ошибка загрузки библиотеки."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Нет прав для просмотра данной библиотеки."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Общие файлы",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "Detta bibliotek finns inte längre.",
|
||||
"LIBRARY_NO_PERMISSIONS": "Du har inte behörighet att visa detta bibliotek.",
|
||||
"LIBRARY_LOADING_ERROR": "Ett problem uppstod när detta bibliotek skulle läsas in."
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "Du har inte behörighet att visa detta bibliotek."
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "Delade filer",
|
||||
|
@ -153,9 +153,9 @@
|
||||
},
|
||||
"ERRORS": {
|
||||
"LIBRARY_NOT_FOUND": "此收藏库不再存在。",
|
||||
"LIBRARY_NO_PERMISSIONS": "您无权查看此收藏库。",
|
||||
"LIBRARY_LOADING_ERROR": "加载此收藏库时出现了问题。"
|
||||
}
|
||||
},
|
||||
"LIBRARY_NO_PERMISSIONS_WARNING": "您无权查看此收藏库。"
|
||||
},
|
||||
"SHARED": {
|
||||
"TITLE": "共享文件",
|
||||
|
@ -548,7 +548,7 @@ describe('FilesComponent', () => {
|
||||
);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getGenericErrorText()).toBe('APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NO_PERMISSIONS');
|
||||
expect(getGenericErrorText()).toBe('APP.BROWSE.LIBRARIES.LIBRARY_NO_PERMISSIONS_WARNING');
|
||||
});
|
||||
|
||||
it('should have set text to library not found error if library does not exist and actual url is libraries', () => {
|
||||
@ -638,7 +638,7 @@ describe('FilesComponent', () => {
|
||||
);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getGenericErrorText()).toBe('APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NO_PERMISSIONS');
|
||||
expect(getGenericErrorText()).toBe('APP.BROWSE.LIBRARIES.LIBRARY_NO_PERMISSIONS_WARNING');
|
||||
});
|
||||
|
||||
it('should have set text to library not found error if library does not exist issue and actual url is libraries', () => {
|
||||
|
@ -409,7 +409,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy {
|
||||
if (this.router.url.includes('libraries')) {
|
||||
switch (error.status) {
|
||||
case 403:
|
||||
this._errorTranslationKey = 'APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NO_PERMISSIONS';
|
||||
this._errorTranslationKey = 'APP.BROWSE.LIBRARIES.LIBRARY_NO_PERMISSIONS_WARNING';
|
||||
break;
|
||||
case 404:
|
||||
this._errorTranslationKey = 'APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NOT_FOUND';
|
||||
|
@ -25,28 +25,30 @@
|
||||
import { LibraryMetadataFormComponent } from './library-metadata-form.component';
|
||||
import { TestBed, ComponentFixture, fakeAsync, tick } from '@angular/core/testing';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SnackbarAction, SnackbarErrorAction, SnackbarInfoAction, UpdateLibraryAction } from '@alfresco/aca-shared/store';
|
||||
import { UpdateLibraryAction } from '@alfresco/aca-shared/store';
|
||||
import { AppHookService } from '@alfresco/aca-shared';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { Site, SiteBodyCreate, SitePaging } from '@alfresco/js-api';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { Site, SiteBodyCreate, SiteEntry, SitePaging } from '@alfresco/js-api';
|
||||
import { of, Subject } from 'rxjs';
|
||||
|
||||
describe('LibraryMetadataFormComponent', () => {
|
||||
let fixture: ComponentFixture<LibraryMetadataFormComponent>;
|
||||
let component: LibraryMetadataFormComponent;
|
||||
let store: Store<any>;
|
||||
let actions$: Subject<SnackbarAction>;
|
||||
let siteEntryModel: SiteBodyCreate;
|
||||
let appHookService: AppHookService;
|
||||
|
||||
beforeEach(() => {
|
||||
actions$ = new Subject<SnackbarAction>();
|
||||
TestBed.configureTestingModule({
|
||||
imports: [AppTestingModule, LibraryMetadataFormComponent],
|
||||
providers: [
|
||||
{
|
||||
provide: Actions,
|
||||
useValue: actions$
|
||||
provide: AppHookService,
|
||||
useValue: {
|
||||
libraryUpdated: new Subject<SiteEntry>(),
|
||||
libraryUpdateFailed: new Subject<void>()
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: Store,
|
||||
@ -59,6 +61,7 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
});
|
||||
|
||||
appHookService = TestBed.inject(AppHookService);
|
||||
store = TestBed.inject(Store);
|
||||
|
||||
fixture = TestBed.createComponent(LibraryMetadataFormComponent);
|
||||
@ -120,24 +123,10 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
component.ngOnInit();
|
||||
component.form.setValue(entry);
|
||||
|
||||
actions$.next(new SnackbarInfoAction('LIBRARY.SUCCESS.LIBRARY_UPDATED'));
|
||||
appHookService.libraryUpdated.next({ entry: entry } as SiteEntry);
|
||||
expect(component.node.entry).toEqual(jasmine.objectContaining(entry));
|
||||
});
|
||||
|
||||
it('should not assign form value to node entry if info snackbar was displayed for different action than updating library', () => {
|
||||
const entry = {
|
||||
id: 'libraryId',
|
||||
title: 'some different title',
|
||||
description: 'some different description',
|
||||
visibility: Site.VisibilityEnum.PUBLIC
|
||||
} as Site;
|
||||
component.ngOnInit();
|
||||
component.form.setValue(entry);
|
||||
|
||||
actions$.next(new SnackbarInfoAction('Some different action'));
|
||||
expect(component.node.entry).not.toEqual(jasmine.objectContaining(entry));
|
||||
});
|
||||
|
||||
it('should call markAsDirty on form if updating of form is finished with error', () => {
|
||||
component.node = {
|
||||
entry: {
|
||||
@ -151,18 +140,10 @@ describe('LibraryMetadataFormComponent', () => {
|
||||
component.ngOnInit();
|
||||
spyOn(component.form, 'markAsDirty');
|
||||
|
||||
actions$.next(new SnackbarErrorAction('LIBRARY.ERRORS.LIBRARY_UPDATE_ERROR'));
|
||||
appHookService.libraryUpdateFailed.next();
|
||||
expect(component.form.markAsDirty).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not call markAsDirty on form if error snackbar was displayed for different action than updating library', () => {
|
||||
component.ngOnInit();
|
||||
spyOn(component.form, 'markAsDirty');
|
||||
|
||||
actions$.next(new SnackbarErrorAction('Some different action'));
|
||||
expect(component.form.markAsDirty).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update library node if form is valid', () => {
|
||||
component.node.entry.role = Site.RoleEnum.SiteManager;
|
||||
|
||||
|
@ -36,16 +36,9 @@ import {
|
||||
} from '@angular/forms';
|
||||
import { QueriesApi, SiteEntry, SitePaging } from '@alfresco/js-api';
|
||||
import { Store } from '@ngrx/store';
|
||||
import {
|
||||
AppStore,
|
||||
isAdmin,
|
||||
SnackbarAction,
|
||||
SnackbarActionTypes,
|
||||
SnackbarErrorAction,
|
||||
SnackbarInfoAction,
|
||||
UpdateLibraryAction
|
||||
} from '@alfresco/aca-shared/store';
|
||||
import { debounceTime, filter, mergeMap } from 'rxjs/operators';
|
||||
import { AppStore, isAdmin, UpdateLibraryAction } from '@alfresco/aca-shared/store';
|
||||
import { AppHookService } from '@alfresco/aca-shared';
|
||||
import { debounceTime, mergeMap } from 'rxjs/operators';
|
||||
import { AlfrescoApiService } from '@alfresco/adf-content-services';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { ErrorStateMatcher, MatOptionModule } from '@angular/material/core';
|
||||
@ -57,7 +50,6 @@ import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { Actions, ofType } from '@ngrx/effects';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export class InstantErrorStateMatcher implements ErrorStateMatcher {
|
||||
@ -127,7 +119,7 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
|
||||
constructor(
|
||||
private readonly alfrescoApiService: AlfrescoApiService,
|
||||
protected readonly store: Store<AppStore>,
|
||||
private readonly actions$: Actions
|
||||
private readonly appHookService: AppHookService
|
||||
) {}
|
||||
|
||||
toggleEdit() {
|
||||
@ -186,10 +178,12 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
|
||||
this.isAdmin = value;
|
||||
});
|
||||
this.canUpdateLibrary = this.node?.entry?.role === 'SiteManager' || this.isAdmin;
|
||||
this.handleUpdatingEvent<SnackbarInfoAction>(SnackbarActionTypes.Info, 'LIBRARY.SUCCESS.LIBRARY_UPDATED', () =>
|
||||
Object.assign(this.node.entry, this.form.value)
|
||||
);
|
||||
this.handleUpdatingEvent<SnackbarErrorAction>(SnackbarActionTypes.Error, 'LIBRARY.ERRORS.LIBRARY_UPDATE_ERROR', () => this.form.markAsDirty());
|
||||
this.appHookService.libraryUpdated.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
Object.assign(this.node.entry, this.form.value);
|
||||
});
|
||||
this.appHookService.libraryUpdateFailed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||
this.form.markAsDirty();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges() {
|
||||
@ -231,16 +225,6 @@ export class LibraryMetadataFormComponent implements OnInit, OnChanges {
|
||||
);
|
||||
}
|
||||
|
||||
private handleUpdatingEvent<T extends SnackbarAction>(actionType: SnackbarActionTypes, payload: string, handle: () => void): void {
|
||||
this.actions$
|
||||
.pipe(
|
||||
ofType<T>(actionType),
|
||||
filter((action) => action.payload === payload),
|
||||
takeUntilDestroyed(this.destroyRef)
|
||||
)
|
||||
.subscribe(handle);
|
||||
}
|
||||
|
||||
private validateEmptyName(control: FormControl<string>): ValidationErrors {
|
||||
return control.value.length && !control.value.trim() ? { empty: true } : null;
|
||||
}
|
||||
|
@ -26,14 +26,14 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
|
||||
import { SearchResultsComponent } from './search-results.component';
|
||||
import { AppConfigService, NotificationService, TranslationService } from '@alfresco/adf-core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { NavigateToFolder, SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { NavigateToFolder } from '@alfresco/aca-shared/store';
|
||||
import { Pagination, SearchRequest } from '@alfresco/js-api';
|
||||
import { SavedSearchesService, SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject, of, Subject, throwError } from 'rxjs';
|
||||
import { AppTestingModule } from '../../../testing/app-testing.module';
|
||||
import { AppService } from '@alfresco/aca-shared';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatSnackBarModule, MatSnackBarRef } from '@angular/material/snack-bar';
|
||||
import { Buffer } from 'buffer';
|
||||
import { testHeader } from '../../../testing/document-base-page-utils';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
@ -53,7 +53,8 @@ describe('SearchComponent', () => {
|
||||
let route: ActivatedRoute;
|
||||
const searchRequest = {} as SearchRequest;
|
||||
let params: BehaviorSubject<any>;
|
||||
let showErrorSpy: jasmine.Spy;
|
||||
let showErrorSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let showInfoSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let loader: HarnessLoader;
|
||||
|
||||
const editSavedSearchesSpy = jasmine.createSpy('editSavedSearch');
|
||||
@ -109,6 +110,7 @@ describe('SearchComponent', () => {
|
||||
|
||||
const notificationService = TestBed.inject(NotificationService);
|
||||
showErrorSpy = spyOn(notificationService, 'showError');
|
||||
showInfoSpy = spyOn(notificationService, 'showInfo');
|
||||
|
||||
config.config = {
|
||||
search: {}
|
||||
@ -290,19 +292,17 @@ describe('SearchComponent', () => {
|
||||
}));
|
||||
|
||||
it('should dispatch success snackbar action when editing saved search is successful', fakeAsync(() => {
|
||||
spyOn(store, 'dispatch').and.stub();
|
||||
editSavedSearchesSpy.and.returnValue(of({}));
|
||||
component.editSavedSearch({ name: 'test', encodedUrl: 'test', order: 0 });
|
||||
tick();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE'));
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE');
|
||||
}));
|
||||
|
||||
it('should dispatch error snackbar action when editing saved search failed', fakeAsync(() => {
|
||||
spyOn(store, 'dispatch').and.stub();
|
||||
editSavedSearchesSpy.and.returnValue(throwError(() => new Error('')));
|
||||
component.editSavedSearch({ name: 'test', encodedUrl: 'test', order: 0 });
|
||||
tick();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE'));
|
||||
expect(showErrorSpy).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE');
|
||||
}));
|
||||
|
||||
testHeader(SearchResultsComponent, false);
|
||||
|
@ -43,9 +43,7 @@ import {
|
||||
SetInfoDrawerPreviewStateAction,
|
||||
SetInfoDrawerStateAction,
|
||||
SetSearchItemsTotalCountAction,
|
||||
ShowInfoDrawerPreviewAction,
|
||||
SnackbarErrorAction,
|
||||
SnackbarInfoAction
|
||||
ShowInfoDrawerPreviewAction
|
||||
} from '@alfresco/aca-shared/store';
|
||||
import {
|
||||
CustomEmptyContentTemplateDirective,
|
||||
@ -333,10 +331,10 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
|
||||
.pipe(take(1))
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE'));
|
||||
this.notificationService.showInfo('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE');
|
||||
},
|
||||
error: () => {
|
||||
this.store.dispatch(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE'));
|
||||
this.notificationService.showError('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -24,18 +24,16 @@
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { SavedSearchDeleteDialogComponent } from './saved-search-delete-dialog.component';
|
||||
import { ContentTestingModule, SavedSearch, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { NotificationService } from '@alfresco/adf-core';
|
||||
import { AppTestingModule } from '../../../../../testing/app-testing.module';
|
||||
|
||||
describe('SaveSearchDeleteDialogComponent', () => {
|
||||
let fixture: ComponentFixture<SavedSearchDeleteDialogComponent>;
|
||||
let notificationService: NotificationService;
|
||||
let savedSearchesService: SavedSearchesService;
|
||||
let store: Store;
|
||||
let submitButton: HTMLButtonElement;
|
||||
let cancelButton: HTMLButtonElement;
|
||||
|
||||
@ -54,15 +52,14 @@ describe('SaveSearchDeleteDialogComponent', () => {
|
||||
imports: [ContentTestingModule, AppTestingModule],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef },
|
||||
provideMockStore(),
|
||||
{ provide: SavedSearchesService, useValue: { deleteSavedSearch: () => of() } },
|
||||
{ provide: SavedSearchesService, useValue: { deleteSavedSearch: () => of({}) } },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: savedSearchToDelete }
|
||||
]
|
||||
});
|
||||
dialogRef.close.calls.reset();
|
||||
fixture = TestBed.createComponent(SavedSearchDeleteDialogComponent);
|
||||
savedSearchesService = TestBed.inject(SavedSearchesService);
|
||||
store = TestBed.inject(Store);
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
|
||||
submitButton = fixture.nativeElement.querySelector('#aca-save-search-delete-dialog-submit-button');
|
||||
cancelButton = fixture.nativeElement.querySelector('#aca-save-search-delete-dialog-cancel-button');
|
||||
@ -79,17 +76,19 @@ describe('SaveSearchDeleteDialogComponent', () => {
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should delete search, show snackbar message and close modal if submit button clicked', fakeAsync(() => () => {
|
||||
it('should delete search, show snackbar message and close modal if submit button clicked', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'deleteSavedSearch').and.callThrough();
|
||||
spyOn(notificationService, 'showInfo');
|
||||
clickSubmitButton();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.SUCCESS_MESSAGE'));
|
||||
expect(notificationService.showInfo).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.SUCCESS_MESSAGE');
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should show snackbar error if there is delete error', fakeAsync(() => () => {
|
||||
spyOn(savedSearchesService, 'deleteSavedSearch').and.throwError('');
|
||||
it('should show snackbar error if there is delete error', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'deleteSavedSearch').and.returnValue(throwError(() => new Error('Error')));
|
||||
spyOn(notificationService, 'showError');
|
||||
clickSubmitButton();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.SUCCESS_MESSAGE'));
|
||||
expect(notificationService.showError).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.ERROR_MESSAGE');
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
|
@ -26,9 +26,7 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core';
|
||||
import { SavedSearch, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { AppStore, SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { CoreModule, NotificationService } from '@alfresco/adf-core';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@ -44,8 +42,8 @@ export class SavedSearchDeleteDialogComponent {
|
||||
|
||||
constructor(
|
||||
private readonly dialog: MatDialogRef<SavedSearchDeleteDialogComponent>,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly savedSearchesService: SavedSearchesService,
|
||||
private readonly store: Store<AppStore>,
|
||||
@Inject(MAT_DIALOG_DATA) private readonly data: SavedSearch
|
||||
) {}
|
||||
|
||||
@ -60,11 +58,11 @@ export class SavedSearchDeleteDialogComponent {
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.dialog.close(this.data);
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.SUCCESS_MESSAGE'));
|
||||
this.notificationService.showInfo('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.SUCCESS_MESSAGE');
|
||||
this.isLoading = false;
|
||||
},
|
||||
error: () => {
|
||||
this.store.dispatch(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.ERROR_MESSAGE'));
|
||||
this.notificationService.showError('APP.BROWSE.SEARCH.SAVE_SEARCH.DELETE_DIALOG.ERROR_MESSAGE');
|
||||
this.isLoading = false;
|
||||
}
|
||||
});
|
||||
|
@ -24,19 +24,18 @@
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { SavedSearchEditDialogComponent } from './saved-search-edit-dialog.component';
|
||||
import { ContentTestingModule, SavedSearch, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { NotificationService } from '@alfresco/adf-core';
|
||||
import { AppTestingModule } from '../../../../../testing/app-testing.module';
|
||||
|
||||
describe('SaveSearchEditDialogComponent', () => {
|
||||
let fixture: ComponentFixture<SavedSearchEditDialogComponent>;
|
||||
let component: SavedSearchEditDialogComponent;
|
||||
let notificationService: NotificationService;
|
||||
let savedSearchesService: SavedSearchesService;
|
||||
let store: Store;
|
||||
let submitButton: HTMLButtonElement;
|
||||
|
||||
const savedSearchToDelete: SavedSearch = {
|
||||
@ -55,15 +54,15 @@ describe('SaveSearchEditDialogComponent', () => {
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef },
|
||||
provideMockStore(),
|
||||
{ provide: SavedSearchesService, useValue: { editSavedSearch: () => of(), getSavedSearches: () => of([]) } },
|
||||
{ provide: SavedSearchesService, useValue: { editSavedSearch: () => of({}), getSavedSearches: () => of([]) } },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: savedSearchToDelete }
|
||||
]
|
||||
});
|
||||
dialogRef.close.calls.reset();
|
||||
fixture = TestBed.createComponent(SavedSearchEditDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
savedSearchesService = TestBed.inject(SavedSearchesService);
|
||||
store = TestBed.inject(Store);
|
||||
|
||||
submitButton = fixture.nativeElement.querySelector('#aca-saved-search-edit-dialog-submit-button');
|
||||
});
|
||||
@ -80,22 +79,23 @@ describe('SaveSearchEditDialogComponent', () => {
|
||||
expect(savedSearchesService.editSavedSearch).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should save search, show snackbar message and close modal if form is valid', fakeAsync(() => () => {
|
||||
it('should save search, show snackbar message and close modal if form is valid', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'editSavedSearch').and.callThrough();
|
||||
spyOn(notificationService, 'showInfo');
|
||||
setFormValuesAndSubmit();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE'));
|
||||
expect(notificationService.showInfo).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE');
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should show snackbar error if there is save error', fakeAsync(() => () => {
|
||||
spyOn(savedSearchesService, 'editSavedSearch').and.throwError('');
|
||||
it('should show snackbar error if there is save error', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'editSavedSearch').and.returnValue(throwError(() => new Error('Error')));
|
||||
spyOn(notificationService, 'showError');
|
||||
setFormValuesAndSubmit();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE'));
|
||||
expect(notificationService.showError).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE');
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
function setFormValuesAndSubmit() {
|
||||
spyOn(store, 'dispatch');
|
||||
component.form.controls['name'].setValue('ABCDEF');
|
||||
component.form.controls['description'].setValue('TEST');
|
||||
submitButton.click();
|
||||
|
@ -26,9 +26,7 @@ import { Component, Inject, ViewEncapsulation } from '@angular/core';
|
||||
import { AutoFocusDirective, forbidOnlySpaces, SavedSearch, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { AppStore, SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { CoreModule, NotificationService } from '@alfresco/adf-core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { UniqueSearchNameValidator } from '../unique-search-name-validator';
|
||||
import { SavedSearchForm } from '../saved-search-form.interface';
|
||||
@ -48,7 +46,7 @@ export class SavedSearchEditDialogComponent {
|
||||
|
||||
constructor(
|
||||
private readonly dialog: MatDialogRef<SavedSearchEditDialogComponent>,
|
||||
private readonly store: Store<AppStore>,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly savedSearchesService: SavedSearchesService,
|
||||
private readonly uniqueSearchNameValidator: UniqueSearchNameValidator,
|
||||
@Inject(MAT_DIALOG_DATA) private readonly data: SavedSearch
|
||||
@ -92,7 +90,7 @@ export class SavedSearchEditDialogComponent {
|
||||
this.isLoading = false;
|
||||
},
|
||||
error: () => {
|
||||
this.store.dispatch(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE'));
|
||||
this.notificationService.showError('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.ERROR_MESSAGE');
|
||||
this.isLoading = false;
|
||||
}
|
||||
});
|
||||
@ -100,6 +98,6 @@ export class SavedSearchEditDialogComponent {
|
||||
|
||||
private onEditSuccess(): void {
|
||||
this.dialog.close();
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE'));
|
||||
this.notificationService.showInfo('APP.BROWSE.SEARCH.SAVE_SEARCH.EDIT_DIALOG.SUCCESS_MESSAGE');
|
||||
}
|
||||
}
|
||||
|
@ -24,19 +24,18 @@
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { SaveSearchDialogComponent } from './save-search-dialog.component';
|
||||
import { ContentTestingModule, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { AppTestingModule } from '../../../../testing/app-testing.module';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { NotificationService } from '@alfresco/adf-core';
|
||||
|
||||
describe('SaveSearchDialogComponent', () => {
|
||||
let fixture: ComponentFixture<SaveSearchDialogComponent>;
|
||||
let component: SaveSearchDialogComponent;
|
||||
let notificationService: NotificationService;
|
||||
let savedSearchesService: SavedSearchesService;
|
||||
let store: Store;
|
||||
let submitButton: HTMLButtonElement;
|
||||
|
||||
const dialogRef = {
|
||||
@ -49,15 +48,15 @@ describe('SaveSearchDialogComponent', () => {
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef },
|
||||
provideMockStore(),
|
||||
{ provide: SavedSearchesService, useValue: { saveSearch: () => of(), getSavedSearches: () => of([]) } },
|
||||
{ provide: SavedSearchesService, useValue: { saveSearch: () => of({}), getSavedSearches: () => of([]) } },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: { searchUrl: 'abcdef' } }
|
||||
]
|
||||
});
|
||||
dialogRef.close.calls.reset();
|
||||
fixture = TestBed.createComponent(SaveSearchDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
savedSearchesService = TestBed.inject(SavedSearchesService);
|
||||
store = TestBed.inject(Store);
|
||||
|
||||
submitButton = fixture.nativeElement.querySelector('#aca-save-search-dialog-save-button');
|
||||
});
|
||||
@ -75,22 +74,22 @@ describe('SaveSearchDialogComponent', () => {
|
||||
expect(savedSearchesService.saveSearch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should save search, show snackbar message and close modal if form is valid', fakeAsync(() => () => {
|
||||
it('should save search, show snackbar message and close modal if form is valid', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'saveSearch').and.callThrough();
|
||||
spyOn(notificationService, 'showInfo');
|
||||
setFormValuesAndSubmit();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_SUCCESS'));
|
||||
expect(notificationService.showInfo).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_SUCCESS');
|
||||
expect(dialogRef.close).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should show snackbar error if there is save error', fakeAsync(() => () => {
|
||||
spyOn(savedSearchesService, 'saveSearch').and.throwError('');
|
||||
it('should show snackbar error if there is save error', fakeAsync(() => {
|
||||
spyOn(savedSearchesService, 'saveSearch').and.returnValue(throwError(() => new Error('Error')));
|
||||
spyOn(notificationService, 'showError');
|
||||
setFormValuesAndSubmit();
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_ERROR'));
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
expect(notificationService.showError).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_ERROR');
|
||||
}));
|
||||
|
||||
function setFormValuesAndSubmit() {
|
||||
spyOn(store, 'dispatch');
|
||||
component.form.controls['name'].setValue('ABCDEF');
|
||||
component.form.controls['description'].setValue('TEST');
|
||||
submitButton.click();
|
||||
|
@ -34,12 +34,10 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { FormControl, FormGroup, FormsModule, Validators } from '@angular/forms';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { CoreModule, NotificationService } from '@alfresco/adf-core';
|
||||
import { AutoFocusDirective, forbidOnlySpaces, SavedSearchesService } from '@alfresco/adf-content-services';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppStore, SnackbarErrorAction, SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { UniqueSearchNameValidator } from './unique-search-name-validator';
|
||||
import { SavedSearchForm } from './saved-search-form.interface';
|
||||
|
||||
@ -72,7 +70,7 @@ export class SaveSearchDialogComponent {
|
||||
|
||||
constructor(
|
||||
private readonly dialog: MatDialogRef<SaveSearchDialogComponent>,
|
||||
private readonly store: Store<AppStore>,
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly savedSearchesService: SavedSearchesService,
|
||||
private readonly uniqueSearchNameValidator: UniqueSearchNameValidator,
|
||||
@Inject(MAT_DIALOG_DATA) private readonly data: { searchUrl: string }
|
||||
@ -100,11 +98,11 @@ export class SaveSearchDialogComponent {
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.dialog.close();
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_SUCCESS'));
|
||||
this.notificationService.showInfo('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_SUCCESS');
|
||||
this.disableSubmitButton = false;
|
||||
},
|
||||
error: () => {
|
||||
this.store.dispatch(new SnackbarErrorAction('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_ERROR'));
|
||||
this.notificationService.showError('APP.BROWSE.SEARCH.SAVE_SEARCH.SAVE_ERROR');
|
||||
this.disableSubmitButton = false;
|
||||
}
|
||||
});
|
||||
|
@ -23,12 +23,11 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CoreTestingModule, DataCellEvent, DataTableComponent } from '@alfresco/adf-core';
|
||||
import { CoreTestingModule, DataCellEvent, DataTableComponent, NotificationService } from '@alfresco/adf-core';
|
||||
import { SavedSearchesListUiComponent } from './saved-searches-list.ui-component';
|
||||
import { SavedSearchesListUiService } from '../saved-searches-list-ui.service';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { SavedSearch } from '@alfresco/adf-content-services';
|
||||
import { provideMockStore } from '@ngrx/store/testing';
|
||||
import { Subject } from 'rxjs';
|
||||
import { Clipboard } from '@angular/cdk/clipboard';
|
||||
import { Router } from '@angular/router';
|
||||
@ -36,6 +35,7 @@ import { Router } from '@angular/router';
|
||||
describe('SavedSearchesListUiComponent ', () => {
|
||||
let fixture: ComponentFixture<SavedSearchesListUiComponent>;
|
||||
let component: SavedSearchesListUiComponent;
|
||||
let notificationService: NotificationService;
|
||||
let savedSearchesListUiService: SavedSearchesListUiService;
|
||||
let clipboard: Clipboard;
|
||||
let router: Router;
|
||||
@ -43,9 +43,10 @@ describe('SavedSearchesListUiComponent ', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, SavedSearchesListUiComponent],
|
||||
providers: [SavedSearchesListUiService, provideMockStore()]
|
||||
providers: [SavedSearchesListUiService]
|
||||
});
|
||||
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
savedSearchesListUiService = TestBed.inject(SavedSearchesListUiService);
|
||||
clipboard = TestBed.inject(Clipboard);
|
||||
router = TestBed.inject(Router);
|
||||
@ -196,6 +197,7 @@ describe('SavedSearchesListUiComponent ', () => {
|
||||
let actionData: any;
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(notificationService, 'showInfo');
|
||||
actionData = dataCellEvent.value.actions[0];
|
||||
actionData.subject.next(actionData);
|
||||
});
|
||||
@ -203,6 +205,10 @@ describe('SavedSearchesListUiComponent ', () => {
|
||||
it('should call copy to clipboard when selected delete option', () => {
|
||||
expect(clipboard.copy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should show snackbar message when selected delete option', () => {
|
||||
expect(notificationService.showInfo).toHaveBeenCalledWith('APP.BROWSE.SEARCH.SAVE_SEARCH.LIST.COPY_TO_CLIPBOARD_SUCCESS');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Execute search', () => {
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
DATATABLE_DIRECTIVES,
|
||||
DataTableComponent,
|
||||
DataTableSchema,
|
||||
NotificationService,
|
||||
ShowHeaderMode,
|
||||
TEMPLATE_DIRECTIVES
|
||||
} from '@alfresco/adf-core';
|
||||
@ -39,8 +40,6 @@ import { SavedSearchesListUiService } from '../saved-searches-list-ui.service';
|
||||
import { savedSearchesListSchema } from '../smart-list/saved-searches-list-schema';
|
||||
import { SavedSearch } from '@alfresco/adf-content-services';
|
||||
import { Clipboard } from '@angular/cdk/clipboard';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { SnackbarInfoAction } from '@alfresco/aca-shared/store';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
@ -61,6 +60,7 @@ export class SavedSearchesListUiComponent extends DataTableSchema implements Aft
|
||||
|
||||
readonly ShowHeaderMode = ShowHeaderMode;
|
||||
|
||||
private readonly notificationService = inject(NotificationService);
|
||||
private readonly savedSearchesListUiService = inject(SavedSearchesListUiService);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly contextMenuAction$ = new Subject<any>();
|
||||
@ -94,7 +94,6 @@ export class SavedSearchesListUiComponent extends DataTableSchema implements Aft
|
||||
constructor(
|
||||
protected appConfig: AppConfigService,
|
||||
private readonly clipboard: Clipboard,
|
||||
private readonly store: Store,
|
||||
private readonly router: Router
|
||||
) {
|
||||
super(appConfig, '', savedSearchesListSchema);
|
||||
@ -140,7 +139,7 @@ export class SavedSearchesListUiComponent extends DataTableSchema implements Aft
|
||||
|
||||
copyToClipboard(savedSearch: SavedSearch): void {
|
||||
this.clipboard.copy(this.getFullUrl(savedSearch.encodedUrl));
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.BROWSE.SEARCH.SAVE_SEARCH.LIST.COPY_TO_CLIPBOARD_SUCCESS'));
|
||||
this.notificationService.showInfo('APP.BROWSE.SEARCH.SAVE_SEARCH.LIST.COPY_TO_CLIPBOARD_SUCCESS');
|
||||
}
|
||||
|
||||
executeSearch(savedSearch: SavedSearch): void {
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
import { fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||
import { BehaviorSubject, EMPTY, of, Subject, throwError } from 'rxjs';
|
||||
import { Actions, EffectsModule, ofType } from '@ngrx/effects';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import {
|
||||
AppStore,
|
||||
CopyNodesAction,
|
||||
@ -32,21 +32,15 @@ import {
|
||||
MoveNodesAction,
|
||||
NavigateRouteAction,
|
||||
NavigateToParentFolder,
|
||||
NodeActionTypes,
|
||||
PurgeDeletedNodesAction,
|
||||
RefreshPreviewAction,
|
||||
RestoreDeletedNodesAction,
|
||||
SetSelectedNodesAction,
|
||||
ShareNodeAction,
|
||||
SnackbarActionTypes,
|
||||
SnackbarErrorAction,
|
||||
SnackbarInfoAction,
|
||||
SnackbarWarningAction,
|
||||
UnlockWriteAction,
|
||||
ViewNodeExtras,
|
||||
ViewNodeVersionAction
|
||||
} from '@alfresco/aca-shared/store';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { NodeEffects } from '../store/effects/node.effects';
|
||||
import { AppTestingModule } from '../testing/app-testing.module';
|
||||
import { AppHookService, AppSettingsService, ContentApiService } from '@alfresco/aca-shared';
|
||||
@ -56,7 +50,7 @@ import { NodeActionsService } from './node-actions.service';
|
||||
import { ConfirmDialogComponent, 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, UserInfo, VersionPaging } from '@alfresco/js-api';
|
||||
import { Node, NodeEntry, SiteBodyCreate, SiteEntry, UserInfo, VersionPaging } from '@alfresco/js-api';
|
||||
import {
|
||||
DocumentListService,
|
||||
FileModel,
|
||||
@ -71,7 +65,6 @@ import { FolderInformationComponent } from '../dialogs/folder-details/folder-inf
|
||||
|
||||
describe('ContentManagementService', () => {
|
||||
let dialog: MatDialog;
|
||||
let actions$: Actions;
|
||||
let contentApi: ContentApiService;
|
||||
let store: Store<AppStore>;
|
||||
let contentManagementService: ContentManagementService;
|
||||
@ -84,9 +77,10 @@ describe('ContentManagementService', () => {
|
||||
let appHookService: AppHookService;
|
||||
let newVersionUploaderService: NewVersionUploaderService;
|
||||
let appSettingsService: AppSettingsService;
|
||||
let showErrorSpy: jasmine.Spy;
|
||||
let showInfoSpy: jasmine.Spy;
|
||||
let showWarningSpy: jasmine.Spy;
|
||||
let showErrorSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let showInfoSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let showWarningSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
let openSnackMessageActionSpy: jasmine.Spy<(message: string, action?: string, interpolateArgs?: any, showAction?: boolean) => MatSnackBarRef<any>>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@ -94,13 +88,13 @@ describe('ContentManagementService', () => {
|
||||
});
|
||||
|
||||
contentApi = TestBed.inject(ContentApiService);
|
||||
actions$ = TestBed.inject(Actions);
|
||||
store = TestBed.inject(Store);
|
||||
contentManagementService = TestBed.inject(ContentManagementService);
|
||||
notificationService = TestBed.inject(NotificationService);
|
||||
showErrorSpy = spyOn(notificationService, 'showError');
|
||||
showInfoSpy = spyOn(notificationService, 'showInfo');
|
||||
showWarningSpy = spyOn(notificationService, 'showWarning');
|
||||
openSnackMessageActionSpy = spyOn(notificationService, 'openSnackMessageAction');
|
||||
nodeActions = TestBed.inject(NodeActionsService);
|
||||
documentListService = TestBed.inject(DocumentListService);
|
||||
translationService = TestBed.inject(TranslationService);
|
||||
@ -118,7 +112,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
subject = new Subject<string>();
|
||||
spyOn(notificationService, 'openSnackMessageAction').and.callThrough();
|
||||
openSnackMessageActionSpy.and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(() => subject.complete());
|
||||
@ -132,9 +126,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('notifies successful copy of multiple nodes', () => {
|
||||
@ -146,9 +142,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PLURAL');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PLURAL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('notifies partially copy of one node out of a multiple selection of nodes', () => {
|
||||
@ -160,9 +158,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PARTIAL_SINGULAR');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PARTIAL_SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies partially copy of more nodes out of a multiple selection of nodes', () => {
|
||||
@ -178,9 +178,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PARTIAL_PLURAL');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PARTIAL_PLURAL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies of failed copy of multiple nodes', () => {
|
||||
@ -196,9 +198,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.FAIL_PLURAL');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.FAIL_PLURAL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies of failed copy of one node', () => {
|
||||
@ -210,9 +214,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
subject.next('OPERATION.SUCCESS.CONTENT.COPY');
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.FAIL_SINGULAR');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.FAIL_SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies error if success message was not emitted', () => {
|
||||
@ -221,11 +227,13 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: 'node-to-copy-id', name: 'name' } }];
|
||||
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
nodeActions.contentCopied.next({} as any);
|
||||
subject.next('');
|
||||
nodeActions.contentCopied.next([] as any);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies permission error on copy of node', () => {
|
||||
@ -234,9 +242,11 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name' } }];
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
subject.error(new Error(JSON.stringify({ error: { statusCode: 403 } })));
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.PERMISSION');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.PERMISSION');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies generic error message on all errors, but 403', () => {
|
||||
@ -246,9 +256,11 @@ describe('ContentManagementService', () => {
|
||||
|
||||
store.dispatch(new CopyNodesAction(selection));
|
||||
subject.error(new Error(JSON.stringify({ error: { statusCode: 404 } })));
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
});
|
||||
|
||||
@ -259,7 +271,7 @@ describe('ContentManagementService', () => {
|
||||
subject = new Subject<string>();
|
||||
|
||||
spyOn(nodeActions, 'copyNodes').and.returnValue(subject);
|
||||
spyOn(notificationService, 'openSnackMessageAction').and.returnValue({
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => of(null)
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
});
|
||||
@ -275,7 +287,7 @@ describe('ContentManagementService', () => {
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
|
||||
expect(contentApi.deleteNode).toHaveBeenCalledWith(createdItems[0].entry.id, { permanent: true });
|
||||
});
|
||||
@ -312,7 +324,7 @@ describe('ContentManagementService', () => {
|
||||
nodeActions.contentCopied.next(createdItems);
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PLURAL');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_COPY.PLURAL');
|
||||
|
||||
expect(spyOnDeleteNode).toHaveBeenCalled();
|
||||
expect(spyOnDeleteNode.calls.allArgs()).toEqual([
|
||||
@ -333,7 +345,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(contentApi.deleteNode).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
});
|
||||
|
||||
it('notifies when some error of type Error occurs on Undo action', () => {
|
||||
@ -348,7 +360,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(contentApi.deleteNode).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
});
|
||||
|
||||
it('notifies permission error when it occurs on Undo action', () => {
|
||||
@ -363,7 +375,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
expect(nodeActions.copyNodes).toHaveBeenCalled();
|
||||
expect(contentApi.deleteNode).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toEqual('APP.MESSAGES.INFO.NODE_COPY.SINGULAR');
|
||||
});
|
||||
});
|
||||
|
||||
@ -386,7 +398,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
subject = new Subject<string>();
|
||||
spyOn(notificationService, 'openSnackMessageAction').and.callThrough();
|
||||
openSnackMessageActionSpy.and.callThrough();
|
||||
});
|
||||
|
||||
afterEach(() => subject.complete());
|
||||
@ -406,9 +418,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(selection));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('notifies successful move of multiple nodes', () => {
|
||||
@ -427,9 +441,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(selection));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PLURAL');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PLURAL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('notifies partial move of a node', () => {
|
||||
@ -446,9 +462,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.SINGULAR');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies partial move of multiple nodes', () => {
|
||||
@ -465,9 +483,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.PLURAL');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.PLURAL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies successful move and the number of nodes that could not be moved', () => {
|
||||
@ -484,11 +504,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe(
|
||||
'APP.MESSAGES.INFO.NODE_MOVE.SINGULAR APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.FAIL'
|
||||
);
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.FAIL');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies successful move and the number of partially moved ones', () => {
|
||||
@ -505,11 +525,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe(
|
||||
'APP.MESSAGES.INFO.NODE_MOVE.SINGULAR APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.SINGULAR'
|
||||
);
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR APP.MESSAGES.INFO.NODE_MOVE.PARTIAL.SINGULAR');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('notifies error if success message was not emitted', () => {
|
||||
@ -525,9 +545,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies permission error on move of node', () => {
|
||||
@ -536,9 +558,11 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name' } }];
|
||||
store.dispatch(new MoveNodesAction(selection));
|
||||
nodeActions.moveNodes(null).error(new Error(JSON.stringify({ error: { statusCode: 403 } })));
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.PERMISSION');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.PERMISSION');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies generic error message on all errors, but 403', () => {
|
||||
@ -547,9 +571,11 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name' } }];
|
||||
store.dispatch(new MoveNodesAction(selection));
|
||||
nodeActions.moveNodes(null).error(new Error(JSON.stringify({ error: { statusCode: 404 } })));
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies conflict error message on 409', () => {
|
||||
@ -558,9 +584,11 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name' } }];
|
||||
store.dispatch(new MoveNodesAction(selection));
|
||||
nodeActions.moveNodes(null).error(new Error(JSON.stringify({ error: { statusCode: 409 } })));
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.NODE_MOVE');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.NODE_MOVE');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('notifies error if move response has only failed items', () => {
|
||||
@ -577,9 +605,11 @@ describe('ContentManagementService', () => {
|
||||
store.dispatch(new MoveNodesAction(nodes));
|
||||
nodeActions.moveNodes(null).next('OPERATION.SUCCESS.CONTENT.MOVE');
|
||||
nodeActions.contentMoved.next(moveResponse);
|
||||
const snackMessageCall = openSnackMessageActionSpy.calls.argsFor(0);
|
||||
|
||||
expect(nodeActions.moveNodes).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[0]).toBe('APP.MESSAGES.ERRORS.GENERIC');
|
||||
expect(snackMessageCall[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
});
|
||||
|
||||
@ -604,8 +634,8 @@ describe('ContentManagementService', () => {
|
||||
subject = new Subject<string>();
|
||||
spyOn(nodeActions, 'moveNodes').and.returnValue(subject);
|
||||
|
||||
spyOn(notificationService, 'openSnackMessageAction').and.returnValue({
|
||||
onAction: () => of(null)
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => of(undefined)
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
});
|
||||
|
||||
@ -630,7 +660,7 @@ describe('ContentManagementService', () => {
|
||||
nodeActions.contentMoved.next(movedItems);
|
||||
|
||||
expect(nodeActions.moveNodeAction).toHaveBeenCalledWith(movedItems.succeeded[0].itemMoved.entry, movedItems.succeeded[0].initialParentId);
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
});
|
||||
|
||||
it('should move node back to initial parent, after succeeded move of a single file', () => {
|
||||
@ -658,7 +688,7 @@ describe('ContentManagementService', () => {
|
||||
nodeActions.contentMoved.next(movedItems);
|
||||
|
||||
expect(nodeActions.moveNodeAction).toHaveBeenCalledWith(node.entry, initialParent);
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
});
|
||||
|
||||
it('should restore deleted folder back to initial parent, after succeeded moving all its files', () => {
|
||||
@ -690,17 +720,12 @@ describe('ContentManagementService', () => {
|
||||
nodeActions.contentMoved.next(movedItems);
|
||||
|
||||
expect(contentApi.restoreNode).toHaveBeenCalled();
|
||||
expect(notificationService.openSnackMessageAction['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
expect(openSnackMessageActionSpy['calls'].argsFor(0)[0]).toBe('APP.MESSAGES.INFO.NODE_MOVE.SINGULAR');
|
||||
});
|
||||
|
||||
it('should notify when error occurs on Undo Move action', fakeAsync((done) => {
|
||||
it('should notify when error occurs on Undo Move action', fakeAsync(() => {
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(null));
|
||||
|
||||
actions$.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map(() => done())
|
||||
);
|
||||
|
||||
const initialParent = 'parent-id-0';
|
||||
const node = {
|
||||
entry: {
|
||||
@ -734,14 +759,9 @@ describe('ContentManagementService', () => {
|
||||
expect(contentApi.restoreNode).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should notify when some error of type Error occurs on Undo Move action', fakeAsync((done) => {
|
||||
it('should notify when some error of type Error occurs on Undo Move action', fakeAsync(() => {
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(new Error('oops!')));
|
||||
|
||||
actions$.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map(() => done())
|
||||
);
|
||||
|
||||
const initialParent = 'parent-id-0';
|
||||
const node: any = {
|
||||
entry: { id: 'node-to-move-id', name: 'name', parentId: initialParent }
|
||||
@ -766,14 +786,9 @@ describe('ContentManagementService', () => {
|
||||
expect(contentApi.restoreNode).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should notify permission error when it occurs on Undo Move action', fakeAsync((done) => {
|
||||
it('should notify permission error when it occurs on Undo Move action', fakeAsync(() => {
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(new Error(JSON.stringify({ error: { statusCode: 403 } }))));
|
||||
|
||||
actions$.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map(() => done())
|
||||
);
|
||||
|
||||
const initialParent = 'parent-id-0';
|
||||
const node = {
|
||||
entry: { id: 'node-to-move-id', name: 'name', parentId: initialParent }
|
||||
@ -801,67 +816,52 @@ describe('ContentManagementService', () => {
|
||||
});
|
||||
|
||||
describe('Delete action', () => {
|
||||
it('should raise info message on successful single file deletion', (done) => {
|
||||
beforeEach(() => {
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => of(null)
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
});
|
||||
|
||||
it('should raise info message on successful single file deletion', () => {
|
||||
spyOn(contentApi, 'deleteNode').and.returnValue(of(null));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('should raise error message on failed single file deletion', (done) => {
|
||||
spyOn(contentApi, 'deleteNode').and.returnValue(throwError(null));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showErrorSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should raise info message on successful multiple files deletion', (done) => {
|
||||
it('should raise info message on successful multiple files deletion', () => {
|
||||
spyOn(contentApi, 'deleteNode').and.returnValue(of(null));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('should raise error message failed multiple files deletion', (done) => {
|
||||
spyOn(contentApi, 'deleteNode').and.returnValue(throwError(null));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showErrorSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should raise warning message when only one file is successful', (done) => {
|
||||
it('should raise warning message when only one file is successful', () => {
|
||||
spyOn(contentApi, 'deleteNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return throwError(null);
|
||||
@ -869,20 +869,13 @@ describe('ContentManagementService', () => {
|
||||
return of(null);
|
||||
}
|
||||
});
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarWarningAction>(SnackbarActionTypes.Warning),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
|
||||
it('should raise warning message when some files are successfully deleted', (done) => {
|
||||
it('should raise warning message when some files are successfully deleted', () => {
|
||||
spyOn(contentApi, 'deleteNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return throwError(null);
|
||||
@ -898,17 +891,10 @@ describe('ContentManagementService', () => {
|
||||
|
||||
return of(null);
|
||||
});
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarWarningAction>(SnackbarActionTypes.Warning),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }, { entry: { id: '3', name: 'name3' } }];
|
||||
|
||||
store.dispatch(new DeleteNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-warning-snackbar');
|
||||
});
|
||||
});
|
||||
|
||||
@ -936,7 +922,7 @@ describe('ContentManagementService', () => {
|
||||
});
|
||||
|
||||
describe('notification', () => {
|
||||
it('raises warning on multiple fail and one success', () => {
|
||||
it('raises warning on multiple fail and one success', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return of({});
|
||||
@ -960,10 +946,13 @@ describe('ContentManagementService', () => {
|
||||
];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showWarningSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('raises warning on multiple success and multiple fail', () => {
|
||||
it('raises warning on multiple success and multiple fail', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return of({});
|
||||
@ -992,28 +981,37 @@ describe('ContentManagementService', () => {
|
||||
];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showWarningSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('raises info on one selected node success', () => {
|
||||
it('raises info on one selected node success', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.returnValue(of({}));
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showInfoSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('raises error on one selected node fail', () => {
|
||||
it('raises error on one selected node fail', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.returnValue(throwError({}));
|
||||
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showErrorSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('raises info on all nodes success', () => {
|
||||
it('raises info on all nodes success', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return of({});
|
||||
@ -1029,10 +1027,13 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showInfoSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('raises error on all nodes fail', () => {
|
||||
it('raises error on all nodes fail', (done) => {
|
||||
spyOn(contentApi, 'purgeDeletedNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return throwError({});
|
||||
@ -1048,7 +1049,10 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1' } }, { entry: { id: '2', name: 'name2' } }];
|
||||
|
||||
store.dispatch(new PurgeDeletedNodesAction(selection));
|
||||
setTimeout(() => {
|
||||
expect(showErrorSpy).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1098,7 +1102,9 @@ describe('ContentManagementService', () => {
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => of(null)
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
|
||||
expect(contentApi.restoreNode).toHaveBeenCalled();
|
||||
@ -1128,6 +1134,7 @@ describe('ContentManagementService', () => {
|
||||
|
||||
const selection: any[] = [
|
||||
{
|
||||
status: 1,
|
||||
entry: {
|
||||
id: '1',
|
||||
path
|
||||
@ -1135,9 +1142,14 @@ describe('ContentManagementService', () => {
|
||||
}
|
||||
];
|
||||
|
||||
const actionSubject = new Subject<void>();
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => actionSubject.asObservable()
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
actionSubject.next();
|
||||
|
||||
expect(store.dispatch['calls'].argsFor(1)[0].userAction.action instanceof NavigateToParentFolder).toBe(true);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new NavigateToParentFolder(selection[0]));
|
||||
});
|
||||
|
||||
describe('notification', () => {
|
||||
@ -1147,18 +1159,13 @@ describe('ContentManagementService', () => {
|
||||
list: { entries: [] }
|
||||
})
|
||||
);
|
||||
openSnackMessageActionSpy.and.returnValue({
|
||||
onAction: () => of(null)
|
||||
} as MatSnackBarRef<SimpleSnackBar>);
|
||||
});
|
||||
|
||||
it('should raise error message on partial multiple fail ', (done) => {
|
||||
it('should raise error message on partial multiple fail ', () => {
|
||||
const error = { message: '{ "error": {} }' };
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
spyOn(contentApi, 'restoreNode').and.callFake((id) => {
|
||||
if (id === '1') {
|
||||
return of({} as NodeEntry);
|
||||
@ -1191,19 +1198,12 @@ describe('ContentManagementService', () => {
|
||||
];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('should raise error message when restored node exist, error 409', (done) => {
|
||||
it('should raise error message when restored node exist, error 409', () => {
|
||||
const error = { message: '{ "error": { "statusCode": 409 } }' };
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
@ -1216,20 +1216,13 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1', path } }];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('should raise error message when restored node returns different statusCode', (done) => {
|
||||
it('should raise error message when restored node returns different statusCode', () => {
|
||||
const error = { message: '{ "error": { "statusCode": 404 } }' };
|
||||
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
@ -1242,20 +1235,13 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1', path } }];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('should raise error message when restored node location is missing', (done) => {
|
||||
it('should raise error message when restored node location is missing', () => {
|
||||
const error = { message: '{ "error": { } }' };
|
||||
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(throwError(error));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
@ -1268,9 +1254,10 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1', path } }];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-error-snackbar');
|
||||
});
|
||||
|
||||
it('should raise info message when restore multiple nodes', (done) => {
|
||||
it('should raise info message when restore multiple nodes', () => {
|
||||
spyOn(contentApi, 'restoreNode').and.callFake((id) => {
|
||||
const entry = {} as NodeEntry;
|
||||
if (id === '1') {
|
||||
@ -1283,14 +1270,6 @@ describe('ContentManagementService', () => {
|
||||
|
||||
return of(entry);
|
||||
});
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
@ -1303,18 +1282,11 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1', path } }, { entry: { id: '2', name: 'name2', path } }];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
|
||||
it('should raise info message when restore selected node', (done) => {
|
||||
it('should raise info message when restore selected node', () => {
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(of({} as NodeEntry));
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
|
||||
map((action) => expect(action).toBeDefined())
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
@ -1327,39 +1299,7 @@ describe('ContentManagementService', () => {
|
||||
const selection: any[] = [{ entry: { id: '1', name: 'name1', path } }];
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
});
|
||||
|
||||
it('navigate to restore selected node location onAction', (done) => {
|
||||
spyOn(contentApi, 'restoreNode').and.returnValue(of({} as NodeEntry));
|
||||
const path = {
|
||||
elements: [
|
||||
{
|
||||
id: '1-1',
|
||||
name: 'somewhere-over-the-rainbow'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const selection: any[] = [
|
||||
{
|
||||
entry: {
|
||||
id: '1',
|
||||
name: 'name1',
|
||||
path
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
actions$
|
||||
.pipe(
|
||||
ofType<RestoreDeletedNodesAction>(NodeActionTypes.RestoreDeleted),
|
||||
map((action) => {
|
||||
expect(action).toBeDefined();
|
||||
})
|
||||
)
|
||||
.subscribe(() => done());
|
||||
|
||||
store.dispatch(new RestoreDeletedNodesAction(selection));
|
||||
expect(openSnackMessageActionSpy.calls.argsFor(0)[2].panelClass).toBe('adf-info-snackbar');
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1440,7 +1380,6 @@ describe('ContentManagementService', () => {
|
||||
const elementToFocus = document.createElement(elementToFocusSelector);
|
||||
spyOn(elementToFocus, 'focus');
|
||||
spyOn(document, 'querySelector').withArgs(elementToFocusSelector).and.returnValue(elementToFocus);
|
||||
spyOn(store, 'select').and.returnValue(new BehaviorSubject(''));
|
||||
contentManagementService.shareNode(
|
||||
{
|
||||
entry: {}
|
||||
@ -1859,6 +1798,36 @@ describe('ContentManagementService', () => {
|
||||
}));
|
||||
});
|
||||
|
||||
describe('updateLibrary', () => {
|
||||
const siteId = 'mock-site-id';
|
||||
const siteBody: SiteBodyCreate = {
|
||||
title: 'Updated Library',
|
||||
description: 'Updated description',
|
||||
visibility: 'PUBLIC'
|
||||
};
|
||||
const mockSiteEntry = { entry: { id: siteId, ...siteBody } } as SiteEntry;
|
||||
|
||||
it('should call content api and dispatch success action on successful update', () => {
|
||||
spyOn(contentApi, 'updateLibrary').and.returnValue(of(mockSiteEntry));
|
||||
spyOn(appHookService.libraryUpdated, 'next');
|
||||
|
||||
contentManagementService.updateLibrary(siteId, siteBody);
|
||||
|
||||
expect(appHookService.libraryUpdated.next).toHaveBeenCalledWith(mockSiteEntry);
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('LIBRARY.SUCCESS.LIBRARY_UPDATED');
|
||||
});
|
||||
|
||||
it('should show error notification and dispatch failure action on update error', () => {
|
||||
spyOn(contentApi, 'updateLibrary').and.returnValue(throwError(() => new Error('error')));
|
||||
spyOn(appHookService.libraryUpdateFailed, 'next');
|
||||
|
||||
contentManagementService.updateLibrary(siteId, siteBody);
|
||||
|
||||
expect(appHookService.libraryUpdateFailed.next).toHaveBeenCalled();
|
||||
expect(showErrorSpy).toHaveBeenCalledWith('LIBRARY.ERRORS.LIBRARY_UPDATE_ERROR');
|
||||
});
|
||||
});
|
||||
|
||||
describe('folderInformationDialog', () => {
|
||||
it('should open folder information dialog', () => {
|
||||
spyOn(dialog, 'open');
|
||||
@ -1916,56 +1885,49 @@ describe('ContentManagementService', () => {
|
||||
|
||||
it('should call proper content api and display proper snackbar message if one node is provided for addFavorite', () => {
|
||||
spyOn(contentApi, 'addFavorite').and.returnValue(of({ entry: { targetGuid: '', target: '' } }));
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
contentManagementService.addFavorite([fakeNode1]);
|
||||
|
||||
expect(contentApi.addFavorite).toHaveBeenCalledWith([fakeNode1]);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODE_ADDED', { name: 'mock-folder1-name' }));
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('APP.MESSAGES.INFO.FAVORITE_NODE_ADDED', null, { name: 'mock-folder1-name' });
|
||||
});
|
||||
|
||||
it('should call proper content api and display proper snackbar message if more than one node is provided for addFavorite', () => {
|
||||
spyOn(contentApi, 'addFavorite').and.returnValue(of({ entry: { targetGuid: '', target: '' } }));
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
contentManagementService.addFavorite([fakeNode1, fakeNode2]);
|
||||
|
||||
expect(contentApi.addFavorite).toHaveBeenCalledWith([fakeNode1, fakeNode2]);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODES_ADDED', { number: 2 }));
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('APP.MESSAGES.INFO.FAVORITE_NODES_ADDED', null, { number: 2 });
|
||||
});
|
||||
|
||||
it('should call proper content api and display proper snackbar message if one node is provided for removeFavorite', () => {
|
||||
spyOn(contentApi, 'removeFavorite').and.returnValue(of({}));
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
contentManagementService.removeFavorite([fakeNode1]);
|
||||
|
||||
expect(contentApi.removeFavorite).toHaveBeenCalledWith([fakeNode1]);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODE_REMOVED', { name: 'mock-folder1-name' }));
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('APP.MESSAGES.INFO.FAVORITE_NODE_REMOVED', null, { name: 'mock-folder1-name' });
|
||||
});
|
||||
|
||||
it('should call proper content api and display proper snackbar message if more than one node is provided for removeFavorite', () => {
|
||||
spyOn(contentApi, 'removeFavorite').and.returnValue(of({}));
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
contentManagementService.removeFavorite([fakeNode1, fakeNode2]);
|
||||
|
||||
expect(contentApi.removeFavorite).toHaveBeenCalledWith([fakeNode1, fakeNode2]);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODES_REMOVED', { number: 2 }));
|
||||
expect(showInfoSpy).toHaveBeenCalledWith('APP.MESSAGES.INFO.FAVORITE_NODES_REMOVED', null, { number: 2 });
|
||||
});
|
||||
|
||||
it('should display snackbar error message when removeFavorite api fails', () => {
|
||||
spyOn(contentApi, 'removeFavorite').and.returnValue(
|
||||
throwError(() => new Error(JSON.stringify({ error: { statusCode: 404, briefSummary: ' relationship id of folder-node2-id' } })))
|
||||
);
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
contentManagementService.removeFavorite([fakeNode1, fakeNode2]);
|
||||
|
||||
expect(contentApi.removeFavorite).toHaveBeenCalledWith([fakeNode1, fakeNode2]);
|
||||
expect(store.dispatch).toHaveBeenCalledWith(
|
||||
new SnackbarErrorAction('APP.MESSAGES.INFO.FAVORITE_NODE_NOT_FOUND', { name: 'mock-folder2-name' })
|
||||
);
|
||||
expect(showErrorSpy).toHaveBeenCalledWith('APP.MESSAGES.ERRORS.FAVORITE_NODE_NOT_FOUND', null, { name: 'mock-folder2-name' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -34,12 +34,6 @@ import {
|
||||
RefreshPreviewAction,
|
||||
SetSelectedNodesAction,
|
||||
ShowLoaderAction,
|
||||
SnackbarAction,
|
||||
SnackbarErrorAction,
|
||||
SnackbarInfoAction,
|
||||
SnackbarUserAction,
|
||||
SnackbarWarningAction,
|
||||
UndoDeleteNodesAction,
|
||||
UnlockWriteAction,
|
||||
ViewNodeVersionAction
|
||||
} from '@alfresco/aca-shared/store';
|
||||
@ -71,6 +65,13 @@ interface RestoredNode {
|
||||
statusCode?: number;
|
||||
}
|
||||
|
||||
interface SnackbarMessageData {
|
||||
key: string;
|
||||
params: { [key: string]: any };
|
||||
userActionLabel?: string;
|
||||
type: 'info' | 'warning' | 'error';
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
@ -104,9 +105,9 @@ export class ContentManagementService {
|
||||
});
|
||||
|
||||
if (nodes.length > 1) {
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODES_ADDED', { number: nodes.length }));
|
||||
this.notificationService.showInfo('APP.MESSAGES.INFO.FAVORITE_NODES_ADDED', null, { number: nodes.length });
|
||||
} else {
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODE_ADDED', { name: nodes[0].entry.name }));
|
||||
this.notificationService.showInfo('APP.MESSAGES.INFO.FAVORITE_NODE_ADDED', null, { name: nodes[0].entry.name });
|
||||
}
|
||||
this.store.dispatch(new SetSelectedNodesAction(favoriteNodes));
|
||||
});
|
||||
@ -124,9 +125,9 @@ export class ContentManagementService {
|
||||
});
|
||||
|
||||
if (nodes.length > 1) {
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODES_REMOVED', { number: nodes.length }));
|
||||
this.notificationService.showInfo('APP.MESSAGES.INFO.FAVORITE_NODES_REMOVED', null, { number: nodes.length });
|
||||
} else {
|
||||
this.store.dispatch(new SnackbarInfoAction('APP.MESSAGES.INFO.FAVORITE_NODE_REMOVED', { name: nodes[0].entry.name }));
|
||||
this.notificationService.showInfo('APP.MESSAGES.INFO.FAVORITE_NODE_REMOVED', null, { name: nodes[0].entry.name });
|
||||
}
|
||||
this.store.dispatch(new SetSelectedNodesAction(favoriteNodes));
|
||||
},
|
||||
@ -134,7 +135,7 @@ export class ContentManagementService {
|
||||
if (JSON.parse(error.message).error.statusCode === 404) {
|
||||
const nodeId = JSON.parse(error.message).error.briefSummary.split('relationship id of ')[1];
|
||||
const nodeName = nodes.find((node) => node.entry.id === nodeId)?.entry.name;
|
||||
this.store.dispatch(new SnackbarErrorAction('APP.MESSAGES.INFO.FAVORITE_NODE_NOT_FOUND', { name: nodeName }));
|
||||
this.notificationService.showError('APP.MESSAGES.ERRORS.FAVORITE_NODE_NOT_FOUND', null, { name: nodeName });
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -353,6 +354,7 @@ export class ContentManagementService {
|
||||
this.notificationService.showInfo('LIBRARY.SUCCESS.LIBRARY_UPDATED');
|
||||
},
|
||||
() => {
|
||||
this.appHookService.libraryUpdateFailed.next();
|
||||
this.notificationService.showError('LIBRARY.ERRORS.LIBRARY_UPDATE_ERROR');
|
||||
}
|
||||
);
|
||||
@ -549,9 +551,18 @@ export class ContentManagementService {
|
||||
failed: failedItems
|
||||
});
|
||||
|
||||
let messageType: string;
|
||||
if (numberOfCopiedItems === 0) {
|
||||
messageType = 'adf-error-snackbar';
|
||||
} else if (failedItems > 0) {
|
||||
messageType = 'adf-warning-snackbar';
|
||||
} else {
|
||||
messageType = 'adf-info-snackbar';
|
||||
}
|
||||
|
||||
this.notificationService
|
||||
.openSnackMessageAction(message, undo, {
|
||||
panelClass: 'info-snackbar'
|
||||
panelClass: messageType
|
||||
})
|
||||
.onAction()
|
||||
.subscribe(() => this.undoCopyNodes(newItems));
|
||||
@ -690,13 +701,27 @@ export class ContentManagementService {
|
||||
|
||||
forkJoin(...batch).subscribe((data: DeletedNodeInfo[]) => {
|
||||
const status = this.processStatus(data);
|
||||
const message = this.getDeleteMessage(status);
|
||||
const messageData = this.getDeleteMessageData(status);
|
||||
|
||||
if (message && status.someSucceeded && allowUndo) {
|
||||
message.userAction = new SnackbarUserAction('APP.ACTIONS.UNDO', new UndoDeleteNodesAction([...status.success]));
|
||||
if (messageData && status.someSucceeded) {
|
||||
const translatedMessage: string = this.translation.instant(messageData.key, messageData.params);
|
||||
const action: string | null = allowUndo ? this.translation.instant('APP.ACTIONS.UNDO') : null;
|
||||
|
||||
const snackBarRef = this.notificationService.openSnackMessageAction(
|
||||
translatedMessage,
|
||||
action,
|
||||
{ panelClass: `adf-${messageData.type}-snackbar` },
|
||||
messageData.params
|
||||
);
|
||||
|
||||
if (action) {
|
||||
snackBarRef.onAction().subscribe(() => {
|
||||
this.undoDeleteNodes([...status.success]);
|
||||
});
|
||||
}
|
||||
} else if (messageData) {
|
||||
this.notificationService.showError(this.translation.instant(messageData.key, messageData.params));
|
||||
}
|
||||
|
||||
this.store.dispatch(message);
|
||||
|
||||
if (status.someSucceeded) {
|
||||
this.appHookService.nodesDeleted.next();
|
||||
@ -717,8 +742,7 @@ export class ContentManagementService {
|
||||
const processedData = this.processStatus(data);
|
||||
|
||||
if (processedData.fail.length) {
|
||||
const message = this.getUndoDeleteMessage(processedData);
|
||||
this.store.dispatch(message);
|
||||
this.showUndoDeleteMessage(processedData);
|
||||
}
|
||||
|
||||
if (processedData.someSucceeded) {
|
||||
@ -746,18 +770,14 @@ export class ContentManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
private getUndoDeleteMessage(status: DeleteStatus): SnackbarAction {
|
||||
private showUndoDeleteMessage(status: DeleteStatus): void {
|
||||
if (status.someFailed && !status.oneFailed) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.NODE_RESTORE_PLURAL', { number: status.fail.length });
|
||||
this.notificationService.showError('APP.MESSAGES.ERRORS.NODE_RESTORE.PLURAL', null, { number: status.fail.length });
|
||||
}
|
||||
|
||||
if (status.oneFailed) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.NODE_RESTORE', {
|
||||
name: status.fail[0].name
|
||||
});
|
||||
this.notificationService.showError('APP.MESSAGES.ERRORS.NODE_RESTORE', null, { name: status.fail[0].name });
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private restoreNode(node: NodeEntry): Observable<RestoredNode> {
|
||||
@ -895,27 +915,29 @@ export class ContentManagementService {
|
||||
}
|
||||
|
||||
private showRestoreNotification(status: DeleteStatus): void {
|
||||
const message = this.getRestoreMessage(status);
|
||||
const messageData = this.getRestoreMessageData(status);
|
||||
|
||||
if (message) {
|
||||
if (status.oneSucceeded && !status.someFailed) {
|
||||
if (messageData) {
|
||||
const translatedMessage: string = this.translation.instant(messageData.key, messageData.params);
|
||||
const action: string = messageData.userActionLabel ? this.translation.instant(messageData.userActionLabel) : '';
|
||||
const panelClass = messageData.type === 'error' ? 'adf-error-snackbar' : 'adf-info-snackbar';
|
||||
|
||||
const snackBarRef = this.notificationService.openSnackMessageAction(translatedMessage, action, { panelClass }, messageData.params);
|
||||
|
||||
if (messageData.userActionLabel && status.oneSucceeded && !status.someFailed) {
|
||||
snackBarRef.onAction().subscribe(() => {
|
||||
const isSite = this.isSite(status.success[0].entry);
|
||||
const path: PathInfo = status.success[0].entry.path;
|
||||
const parent = path.elements[path.elements.length - 1];
|
||||
const route = isSite ? ['/libraries', parent.id] : ['/personal-files', parent.id];
|
||||
|
||||
let navigate;
|
||||
|
||||
if (this.isLibraryContent(path)) {
|
||||
navigate = new NavigateToParentFolder(status.success[0]);
|
||||
this.store.dispatch(new NavigateToParentFolder(status.success[0]));
|
||||
} else {
|
||||
navigate = new NavigateRouteAction(route);
|
||||
this.store.dispatch(new NavigateRouteAction(route));
|
||||
}
|
||||
|
||||
message.userAction = new SnackbarUserAction('APP.ACTIONS.VIEW', navigate);
|
||||
});
|
||||
}
|
||||
|
||||
this.store.dispatch(message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -927,39 +949,49 @@ export class ContentManagementService {
|
||||
return path && path.elements.length >= 2 && path.elements[1].name === 'Sites';
|
||||
}
|
||||
|
||||
private getRestoreMessage(status: DeleteStatus): SnackbarAction {
|
||||
private getRestoreMessageData(status: DeleteStatus): SnackbarMessageData | null {
|
||||
if (status.someFailed && !status.oneFailed) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.PARTIAL_PLURAL', {
|
||||
number: status.fail.length
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.PARTIAL_PLURAL',
|
||||
params: { number: status.fail.length },
|
||||
type: 'error'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.oneFailed && status.fail[0].statusCode) {
|
||||
if (status.fail[0].statusCode === 409) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.NODE_EXISTS', {
|
||||
name: status.fail[0].entry.name
|
||||
});
|
||||
} else {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.GENERIC', {
|
||||
name: status.fail[0].entry.name
|
||||
});
|
||||
}
|
||||
return {
|
||||
key:
|
||||
status.fail[0].statusCode === 409
|
||||
? 'APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.NODE_EXISTS'
|
||||
: 'APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.GENERIC',
|
||||
params: { name: status.fail[0].entry.name },
|
||||
type: 'error'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.oneFailed && !status.fail[0].statusCode) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.LOCATION_MISSING', {
|
||||
name: status.fail[0].entry.name
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.ERRORS.TRASH.NODES_RESTORE.LOCATION_MISSING',
|
||||
params: { name: status.fail[0].entry.name },
|
||||
type: 'error'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.allSucceeded && !status.oneSucceeded) {
|
||||
return new SnackbarInfoAction('APP.MESSAGES.INFO.TRASH.NODES_RESTORE.PLURAL');
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.TRASH.NODES_RESTORE.PLURAL',
|
||||
params: {},
|
||||
type: 'info'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.allSucceeded && status.oneSucceeded) {
|
||||
return new SnackbarInfoAction('APP.MESSAGES.INFO.TRASH.NODES_RESTORE.SINGULAR', {
|
||||
name: status.success[0].entry.name
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.TRASH.NODES_RESTORE.SINGULAR',
|
||||
params: { name: status.success[0].entry.name },
|
||||
userActionLabel: 'APP.ACTIONS.VIEW',
|
||||
type: 'info'
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -997,39 +1029,53 @@ export class ContentManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
private getDeleteMessage(status: DeleteStatus): SnackbarAction {
|
||||
private getDeleteMessageData(status: DeleteStatus): SnackbarMessageData | null {
|
||||
if (status.allFailed && !status.oneFailed) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.NODE_DELETION_PLURAL', { number: status.fail.length });
|
||||
return {
|
||||
key: 'APP.MESSAGES.ERRORS.NODE_DELETION_PLURAL',
|
||||
params: { number: status.fail.length },
|
||||
type: 'error'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.allSucceeded && !status.oneSucceeded) {
|
||||
return new SnackbarInfoAction('APP.MESSAGES.INFO.NODE_DELETION.PLURAL', {
|
||||
number: status.success.length
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.NODE_DELETION.PLURAL',
|
||||
params: { number: status.success.length },
|
||||
type: 'info'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.someFailed && status.someSucceeded && !status.oneSucceeded) {
|
||||
return new SnackbarWarningAction('APP.MESSAGES.INFO.NODE_DELETION.PARTIAL_PLURAL', {
|
||||
success: status.success.length,
|
||||
failed: status.fail.length
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.NODE_DELETION.PARTIAL_PLURAL',
|
||||
params: { success: status.success.length, failed: status.fail.length },
|
||||
type: 'warning'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.someFailed && status.oneSucceeded) {
|
||||
return new SnackbarWarningAction('APP.MESSAGES.INFO.NODE_DELETION.PARTIAL_SINGULAR', {
|
||||
success: status.success.length,
|
||||
failed: status.fail.length
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.NODE_DELETION.PARTIAL_SINGULAR',
|
||||
params: { success: status.success.length, failed: status.fail.length },
|
||||
type: 'warning'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.oneFailed && !status.someSucceeded) {
|
||||
return new SnackbarErrorAction('APP.MESSAGES.ERRORS.NODE_DELETION', {
|
||||
name: status.fail[0].name
|
||||
});
|
||||
return {
|
||||
key: 'APP.MESSAGES.ERRORS.NODE_DELETION',
|
||||
params: { name: status.fail[0].name },
|
||||
type: 'error'
|
||||
};
|
||||
}
|
||||
|
||||
if (status.oneSucceeded && !status.someFailed) {
|
||||
return new SnackbarInfoAction('APP.MESSAGES.INFO.NODE_DELETION.SINGULAR', { name: status.success[0].name });
|
||||
return {
|
||||
key: 'APP.MESSAGES.INFO.NODE_DELETION.SINGULAR',
|
||||
params: { name: status.success[0].name },
|
||||
type: 'info'
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -1092,13 +1138,20 @@ export class ContentManagementService {
|
||||
partially: partiallySucceeded
|
||||
});
|
||||
|
||||
let notificationType = 'adf-warning-snackbar';
|
||||
if (partiallySucceeded === 0 && succeeded === 0) {
|
||||
notificationType = 'adf-error-snackbar';
|
||||
} else if (failures === 0 && partiallySucceeded === 0) {
|
||||
notificationType = 'adf-info-snackbar';
|
||||
}
|
||||
|
||||
// TODO: review in terms of i18n
|
||||
this.notificationService
|
||||
.openSnackMessageAction(
|
||||
messages[successMessage] + beforePartialSuccessMessage + messages[partialSuccessMessage] + beforeFailedMessage + messages[failedMessage],
|
||||
undo,
|
||||
{
|
||||
panelClass: 'info-snackbar'
|
||||
panelClass: notificationType
|
||||
}
|
||||
)
|
||||
.onAction()
|
||||
|
@ -27,7 +27,7 @@ import { StoreModule } from '@ngrx/store';
|
||||
import { appReducer } from './reducers/app.reducer';
|
||||
import { StoreRouterConnectingModule, FullRouterStateSerializer } from '@ngrx/router-store';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { RouterEffects, SnackbarEffects } from '@alfresco/aca-shared/store';
|
||||
import { RouterEffects } from '@alfresco/aca-shared/store';
|
||||
import {
|
||||
AppEffects,
|
||||
NodeEffects,
|
||||
@ -71,7 +71,6 @@ import { SearchAiEffects } from './effects/search-ai.effects';
|
||||
TemplateEffects,
|
||||
ContextMenuEffects,
|
||||
SearchAiEffects,
|
||||
SnackbarEffects,
|
||||
RouterEffects
|
||||
])
|
||||
]
|
||||
|
@ -55,10 +55,11 @@ describe('LibraryEffects', () => {
|
||||
spyOn(notificationService, 'showError');
|
||||
});
|
||||
|
||||
it('should display library no permission error if user does not have permission', () => {
|
||||
it('should display library no permission warning if user does not have permission', () => {
|
||||
spyOn(notificationService, 'showWarning');
|
||||
store.dispatch(new NavigateLibraryAction('libraryId'));
|
||||
node$.error(new HttpErrorResponse({ status: 403 }));
|
||||
expect(notificationService.showError).toHaveBeenCalledWith('APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NO_PERMISSIONS');
|
||||
expect(notificationService.showWarning).toHaveBeenCalledWith('APP.BROWSE.LIBRARIES.LIBRARY_NO_PERMISSIONS_WARNING');
|
||||
});
|
||||
|
||||
it('should display library not found error if library does not exist', () => {
|
||||
|
@ -120,18 +120,16 @@ export class LibraryEffects {
|
||||
this.store.dispatch(new NavigateRouteAction([route, id]));
|
||||
},
|
||||
(error: HttpErrorResponse) => {
|
||||
let errorTranslationKey: string;
|
||||
switch (error.status) {
|
||||
case 403:
|
||||
errorTranslationKey = 'APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NO_PERMISSIONS';
|
||||
this.notificationService.showWarning('APP.BROWSE.LIBRARIES.LIBRARY_NO_PERMISSIONS_WARNING');
|
||||
break;
|
||||
case 404:
|
||||
errorTranslationKey = 'APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NOT_FOUND';
|
||||
this.notificationService.showError('APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_NOT_FOUND');
|
||||
break;
|
||||
default:
|
||||
errorTranslationKey = 'APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_LOADING_ERROR';
|
||||
this.notificationService.showError('APP.BROWSE.LIBRARIES.ERRORS.LIBRARY_LOADING_ERROR');
|
||||
}
|
||||
this.notificationService.showError(errorTranslationKey);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ import {
|
||||
SetSelectedNodesAction,
|
||||
ShareNodeAction,
|
||||
ShowLoaderAction,
|
||||
SnackbarEffects,
|
||||
UndoDeleteNodesAction,
|
||||
UnlockWriteAction,
|
||||
UnshareNodesAction
|
||||
@ -71,12 +70,7 @@ describe('NodeEffects', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
AppTestingModule,
|
||||
EffectsModule.forRoot([NodeEffects, ViewerEffects, SnackbarEffects, RouterEffects]),
|
||||
MatDialogModule,
|
||||
MatSnackBarModule
|
||||
],
|
||||
imports: [AppTestingModule, EffectsModule.forRoot([NodeEffects, ViewerEffects, RouterEffects]), MatDialogModule, MatSnackBarModule],
|
||||
providers: [RenditionService, { provide: ActivatedRoute, useValue: { queryParams: of({ location: 'test-page' }) } }]
|
||||
});
|
||||
|
||||
|
@ -252,7 +252,7 @@ mat-snack-bar-container {
|
||||
}
|
||||
|
||||
.adf-warning-snackbar {
|
||||
--mdc-snackbar-container-color: var(--theme-accent-color);
|
||||
--mdc-snackbar-container-color: var(--theme-warning-snackbar-background);
|
||||
}
|
||||
|
||||
.adf-info-snackbar {
|
||||
|
@ -47,6 +47,7 @@ $disabled-chip-background-color: #f5f5f5;
|
||||
$contrast-gray: mat.m2-get-color-from-palette($foreground, 'secondary-tex');
|
||||
$search-highlight-background-color: #ffd180;
|
||||
$info-snackbar-background: #1f74db;
|
||||
$warning-snackbar-background: #8c7012;
|
||||
$text-light-color: rgba(33, 35, 40, 0.7);
|
||||
$card-background-grey-color: rgb(248, 248, 248);
|
||||
$light-grey-1: #d5d5d5;
|
||||
@ -79,6 +80,7 @@ $defaults: (
|
||||
--theme-grey-hover-background-color: $grey-hover-background,
|
||||
--theme-blue-button-color: $blue-save-button-background,
|
||||
--theme-info-snackbar-background: $info-snackbar-background,
|
||||
--theme-warning-snackbar-background: $warning-snackbar-background,
|
||||
--theme-blue-checkbox-color: $blue-checkbox-background,
|
||||
--theme-blue-active-table-row-color: $blue-active-table-row,
|
||||
--theme-heading-color: $black-heading,
|
||||
|
@ -50,6 +50,11 @@ export class AppHookService {
|
||||
*/
|
||||
libraryUpdated = new Subject<SiteEntry>();
|
||||
|
||||
/**
|
||||
* Gets emitted when library update fails
|
||||
*/
|
||||
libraryUpdateFailed = new Subject<void>();
|
||||
|
||||
/**
|
||||
* Gets emitted when user join the library
|
||||
*/
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*!
|
||||
* Copyright © 2005-2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
export enum SnackbarActionTypes {
|
||||
Info = 'SNACKBAR_INFO',
|
||||
Warning = 'SNACKBAR_WARNING',
|
||||
Error = 'SNACKBAR_ERROR'
|
||||
}
|
||||
|
||||
export interface SnackbarAction extends Action {
|
||||
payload: string;
|
||||
params?: any;
|
||||
userAction?: SnackbarUserAction;
|
||||
duration?: number;
|
||||
}
|
||||
|
||||
export class SnackbarUserAction {
|
||||
constructor(
|
||||
public title: string,
|
||||
public action: Action
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SnackbarInfoAction implements SnackbarAction {
|
||||
readonly type = SnackbarActionTypes.Info;
|
||||
|
||||
userAction?: SnackbarUserAction;
|
||||
|
||||
constructor(
|
||||
public payload: string,
|
||||
public params?: any
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SnackbarWarningAction implements SnackbarAction {
|
||||
readonly type = SnackbarActionTypes.Warning;
|
||||
|
||||
userAction?: SnackbarUserAction;
|
||||
|
||||
constructor(
|
||||
public payload: string,
|
||||
public params?: any
|
||||
) {}
|
||||
}
|
||||
|
||||
export class SnackbarErrorAction implements SnackbarAction {
|
||||
readonly type = SnackbarActionTypes.Error;
|
||||
|
||||
userAction?: SnackbarUserAction;
|
||||
|
||||
constructor(
|
||||
public payload: string,
|
||||
public params?: any
|
||||
) {}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
/*!
|
||||
* Copyright © 2005-2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { CoreTestingModule, SnackbarContentComponent } from '@alfresco/adf-core';
|
||||
import { SnackbarEffects } from './snackbar.effects';
|
||||
import { SnackbarErrorAction, SnackbarInfoAction, SnackbarWarningAction } from '../actions/snackbar.actions';
|
||||
import { AppStore } from '@alfresco/aca-shared/store';
|
||||
|
||||
describe('NodeEffects', () => {
|
||||
let store: Store<AppStore>;
|
||||
let matSnackBar: MatSnackBar;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, StoreModule.forRoot({}), EffectsModule.forRoot([SnackbarEffects])]
|
||||
});
|
||||
|
||||
store = TestBed.inject(Store);
|
||||
matSnackBar = TestBed.inject(MatSnackBar);
|
||||
spyOn(matSnackBar, 'openFromComponent');
|
||||
});
|
||||
|
||||
describe('infoEffect', () => {
|
||||
it('should open snackbar with adf-info-snackbar panel class', () => {
|
||||
store.dispatch(new SnackbarInfoAction('test-snackbar-message'));
|
||||
expect(matSnackBar.openFromComponent).toHaveBeenCalledWith(SnackbarContentComponent, {
|
||||
panelClass: 'adf-info-snackbar',
|
||||
data: {
|
||||
message: 'test-snackbar-message',
|
||||
actionLabel: null,
|
||||
actionIcon: 'close',
|
||||
actionIconAriaLabel: 'CLOSE',
|
||||
showAction: true,
|
||||
callActionOnIconClick: false
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('warningEffect', () => {
|
||||
it('should open snackbar with adf-info-snackbar panel class', () => {
|
||||
store.dispatch(new SnackbarWarningAction('test-snackbar-message'));
|
||||
expect(matSnackBar.openFromComponent).toHaveBeenCalledWith(SnackbarContentComponent, {
|
||||
panelClass: 'adf-warning-snackbar',
|
||||
data: {
|
||||
message: 'test-snackbar-message',
|
||||
actionLabel: null,
|
||||
actionIcon: 'close',
|
||||
actionIconAriaLabel: 'CLOSE',
|
||||
showAction: true,
|
||||
callActionOnIconClick: false
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('errorEffect', () => {
|
||||
it('should open snackbar with adf-info-snackbar panel class', () => {
|
||||
store.dispatch(new SnackbarErrorAction('test-snackbar-message'));
|
||||
expect(matSnackBar.openFromComponent).toHaveBeenCalledWith(SnackbarContentComponent, {
|
||||
panelClass: 'adf-error-snackbar',
|
||||
data: {
|
||||
message: 'test-snackbar-message',
|
||||
actionLabel: null,
|
||||
actionIcon: 'close',
|
||||
actionIconAriaLabel: 'CLOSE',
|
||||
showAction: true,
|
||||
callActionOnIconClick: false
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,104 +0,0 @@
|
||||
/*!
|
||||
* Copyright © 2005-2025 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { SnackbarContentComponent, SnackBarData, TranslationService } from '@alfresco/adf-core';
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Actions, createEffect, ofType } from '@ngrx/effects';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { AppStore } from '../states/app.state';
|
||||
import { SnackbarAction, SnackbarActionTypes, SnackbarErrorAction, SnackbarInfoAction, SnackbarWarningAction } from '../actions/snackbar.actions';
|
||||
|
||||
@Injectable()
|
||||
export class SnackbarEffects {
|
||||
private store = inject(Store<AppStore>);
|
||||
private actions$ = inject(Actions);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
private translationService = inject(TranslationService);
|
||||
|
||||
infoEffect = createEffect(
|
||||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType<SnackbarInfoAction>(SnackbarActionTypes.Info),
|
||||
map((action: SnackbarInfoAction) => {
|
||||
this.showSnackBar(action, 'adf-info-snackbar');
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
warningEffect = createEffect(
|
||||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType<SnackbarWarningAction>(SnackbarActionTypes.Warning),
|
||||
map((action: SnackbarWarningAction) => {
|
||||
this.showSnackBar(action, 'adf-warning-snackbar');
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
errorEffect = createEffect(
|
||||
() =>
|
||||
this.actions$.pipe(
|
||||
ofType<SnackbarErrorAction>(SnackbarActionTypes.Error),
|
||||
map((action: SnackbarErrorAction) => {
|
||||
this.showSnackBar(action, 'adf-error-snackbar');
|
||||
})
|
||||
),
|
||||
{ dispatch: false }
|
||||
);
|
||||
|
||||
private showSnackBar(action: SnackbarAction, panelClass: string) {
|
||||
const message = this.translate(action.payload, action.params);
|
||||
|
||||
let actionName: string = null;
|
||||
if (action.userAction) {
|
||||
actionName = this.translate(action.userAction.title);
|
||||
}
|
||||
const snackBarRef = this.snackBar.openFromComponent<SnackbarContentComponent, SnackBarData>(SnackbarContentComponent, {
|
||||
...(action.duration !== undefined && action.duration !== null && { duration: action.duration }),
|
||||
panelClass,
|
||||
data: {
|
||||
message,
|
||||
actionLabel: actionName,
|
||||
actionIcon: 'close',
|
||||
actionIconAriaLabel: 'CLOSE',
|
||||
showAction: true,
|
||||
callActionOnIconClick: false
|
||||
}
|
||||
});
|
||||
|
||||
if (action.userAction) {
|
||||
snackBarRef.onAction().subscribe(() => {
|
||||
this.store.dispatch(action.userAction.action);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private translate(message: string, params?: any): string {
|
||||
return this.translationService.instant(message, params);
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ export * from './actions/library.actions';
|
||||
export * from './actions/node.actions';
|
||||
export * from './actions/router.actions';
|
||||
export * from './actions/search.actions';
|
||||
export * from './actions/snackbar.actions';
|
||||
export * from './actions/upload.actions';
|
||||
export * from './actions/viewer.actions';
|
||||
export * from './actions/metadata-aspect.actions';
|
||||
@ -40,7 +39,6 @@ export * from './actions/contextmenu.actions';
|
||||
export * from './actions/search-ai.actions';
|
||||
|
||||
export * from './effects/router.effects';
|
||||
export * from './effects/snackbar.effects';
|
||||
|
||||
export * from './models/ai-search-by-term-payload';
|
||||
export * from './models/delete-status.model';
|
||||
|
Loading…
x
Reference in New Issue
Block a user