mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +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:
committed by
GitHub
parent
1072c7d2f3
commit
f48fc8c2d7
@@ -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 {
|
||||
|
Reference in New Issue
Block a user