refactor, clean up

This commit is contained in:
FrancescoMolinaro
2024-01-25 13:22:17 +01:00
parent 66cd035f87
commit d4bf3a519a
12 changed files with 72 additions and 193 deletions

View File

@@ -1,84 +1,85 @@
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngrx/store';
import { Operation } from 'fast-json-patch';
import { AsyncSubject, combineLatest, from as observableFrom, Observable, of as observableOf } from 'rxjs';
import { AsyncSubject, from as observableFrom, Observable } from 'rxjs';
import {
distinctUntilChanged,
filter,
find,
map,
mergeMap,
skipWhile,
switchMap,
take,
takeWhile,
tap,
toArray
} from 'rxjs/operators';
import { hasValue, isNotEmpty, isNotEmptyOperator } from '../../shared/empty.util';
import { NotificationOptions } from '../../shared/notifications/models/notification-options.model';
import { hasValue } from '../../shared/empty.util';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { getClassForType } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestParam } from '../cache/models/request-param.model';
import { ObjectCacheEntry } from '../cache/object-cache.reducer';
import { ObjectCacheService } from '../cache/object-cache.service';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { getFirstCompletedRemoteData, getFirstSucceededRemoteData, getRemoteDataPayload } from '../shared/operators';
import { URLCombiner } from '../url-combiner/url-combiner';
import { ChangeAnalyzer } from './change-analyzer';
import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data';
import {
CreateRequest,
DeleteByIDRequest,
DeleteRequest,
GetRequest,
PatchRequest,
PostRequest,
PutRequest
PostRequest
} from './request.models';
import { RequestService } from './request.service';
import { RestRequestMethod } from './rest-request-method';
import { GenericConstructor } from '../shared/generic-constructor';
import { NoContent } from '../shared/NoContent.model';
import { CacheableObject } from '../cache/cacheable-object.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
import { BaseDataService } from "./base/base-data.service";
import { FindAllData, FindAllDataImpl } from "./base/find-all-data";
import { SearchData, SearchDataImpl } from "./base/search-data";
import { CreateData, CreateDataImpl } from "./base/create-data";
import { FindAllData, FindAllDataImpl } from './base/find-all-data';
import { SearchData, SearchDataImpl } from './base/search-data';
import { CreateData, CreateDataImpl } from './base/create-data';
import { PatchData, PatchDataImpl } from './base/patch-data';
import { IdentifiableDataService } from './base/identifiable-data.service';
import { PutData, PutDataImpl } from './base/put-data';
import { DeleteData, DeleteDataImpl } from './base/delete-data';
/**
* Interface to list the methods used by the injected service in components
*/
export interface UpdateDataService<T> {
patch(dso: T, operations: Operation[]): Observable<RemoteData<T>>;
update(object: T): Observable<RemoteData<T>>;
commitUpdates(method?: RestRequestMethod);
commitUpdates(method?: RestRequestMethod): void;
}
/**
* Specific functionalities that not all services would need.
* Goal of the class is to update remote objects, handling custom methods that don't belong to BaseDataService
* The class implements also the following common interfaces
*
* findAllData: FindAllData<T>;
* searchData: SearchData<T>;
* createData: CreateData<T>;
* patchData: PatchData<T>;
* putData: PutData<T>;
* deleteData: DeleteData<T>;
*
* Custom methods are:
*
* patch - Sends a patch request to modify current object
* update - Add a new patch to the object cache, diff between given object and cache
* commitUpdates - Sends the updates to the server
* deleteOnRelated - delete all related objects to the given one
* postOnRelated - post all the related objects to the given one
* invalidate - invalidate the DSpaceObject making all requests as stale
* invalidateByHref - invalidate the href making all requests as stale
*/
export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends BaseDataService<T> implements UpdateDataService<T>, FindAllData<T>, SearchData<T>, CreateData<T> {
export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends IdentifiableDataService<T> implements FindAllData<T>, SearchData<T>, CreateData<T>, PatchData<T>, PutData<T>, DeleteData<T> {
protected abstract store: Store<CoreState>;
protected abstract http: HttpClient;
protected abstract comparator: ChangeAnalyzer<T>;
private findAllData: FindAllDataImpl<T>;
private searchData: SearchDataImpl<T>;
private createData: CreateData<T>;
private createData: CreateDataImpl<T>;
private patchData: PatchDataImpl<T>;
private putData: PutDataImpl<T>;
private deleteData: DeleteDataImpl<T>;
constructor(
@@ -88,12 +89,16 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
protected comparator: ChangeAnalyzer<T>,
protected responseMsToLive: number,
) {
super(linkPath, requestService, rdbService, objectCache, halService, responseMsToLive);
this.findAllData = new FindAllDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService ,this.responseMsToLive);
this.patchData = new PatchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, comparator ,this.responseMsToLive, this.constructIdEndpoint);
this.putData = new PutDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService ,this.responseMsToLive, this.constructIdEndpoint);
}
@@ -107,7 +112,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getFindAllHref(options: FindListOptions = {}, linkPath?: string, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.findAllData.getFindAllHref(options, linkPath, ...linksToFollow)
return this.findAllData.getFindAllHref(options, linkPath, ...linksToFollow);
}
/**
@@ -120,7 +125,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public getSearchByHref(searchMethod: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow)
return this.searchData.getSearchByHref(searchMethod, options, ...linksToFollow);
}
/**
@@ -138,27 +143,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* Return an observable that emits object list
*/
findAll(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> {
return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)
}
/**
* Create the HREF for a specific object based on its identifier; with possible embed query params based on linksToFollow
* @param endpoint The base endpoint for the type of object
* @param resourceID The identifier for the object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getIDHref(endpoint, resourceID, ...linksToFollow: FollowLinkConfig<T>[]): string {
return this.buildHrefFromFindOptions(endpoint + '/' + resourceID, {}, [], ...linksToFollow);
}
/**
* Create an observable for the HREF of a specific object based on its identifier
* @param resourceID The identifier for the object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
getIDHrefObs(resourceID: string, ...linksToFollow: FollowLinkConfig<T>[]): Observable<string> {
return this.getEndpoint().pipe(
map((endpoint: string) => this.getIDHref(endpoint, resourceID, ...linksToFollow)));
return this.findAllData.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}
/**
@@ -177,29 +162,6 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}
/**
* An operator that will call the given function if the incoming RemoteData is stale and
* shouldReRequest is true
*
* @param shouldReRequest Whether or not to call the re-request function if the RemoteData is stale
* @param requestFn The function to call if the RemoteData is stale and shouldReRequest is
* true
*/
protected reRequestStaleRemoteData<O>(shouldReRequest: boolean, requestFn: () => Observable<RemoteData<O>>) {
return (source: Observable<RemoteData<O>>): Observable<RemoteData<O>> => {
if (shouldReRequest === true) {
return source.pipe(
tap((remoteData: RemoteData<O>) => {
if (hasValue(remoteData) && remoteData.isStale) {
requestFn();
}
})
);
} else {
return source;
}
};
}
/**
* Make a new FindListRequest with given search method
@@ -216,7 +178,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* Return an observable that emits response from the server
*/
searchBy(searchMethod: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}
/**
@@ -225,30 +187,11 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param {Operation[]} operations The patch operations to be performed
*/
patch(object: T, operations: Operation[]): Observable<RemoteData<T>> {
const requestId = this.requestService.generateRequestId();
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, object.uuid)));
hrefObs.pipe(
find((href: string) => hasValue(href)),
).subscribe((href: string) => {
const request = new PatchRequest(requestId, href, operations);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request);
});
return this.rdbService.buildFromRequestUUID(requestId);
return this.patchData.patch(object, operations);
}
createPatchFromCache(object: T): Observable<Operation[]> {
const oldVersion$ = this.findByHref(object._links.self.href, true, false);
return oldVersion$.pipe(
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
map((oldVersion: T) => this.comparator.diff(oldVersion, object)));
return this.patchData.createPatchFromCache(object);
}
/**
@@ -257,17 +200,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param object The object to send a put request for.
*/
put(object: T): Observable<RemoteData<T>> {
const requestId = this.requestService.generateRequestId();
const serializedObject = new DSpaceSerializer(object.constructor as GenericConstructor<{}>).serialize(object);
const request = new PutRequest(requestId, object._links.self.href, serializedObject);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request);
return this.rdbService.buildFromRequestUUID(requestId);
return this.putData.put(object);
}
/**
@@ -276,16 +209,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param {DSpaceObject} object The given object
*/
update(object: T): Observable<RemoteData<T>> {
return this.createPatchFromCache(object)
.pipe(
mergeMap((operations: Operation[]) => {
if (isNotEmpty(operations)) {
this.objectCache.addPatch(object._links.self.href, operations);
}
return this.findByHref(object._links.self.href, true, true);
}
)
);
return this.patchData.update(object);
}
/**
@@ -298,7 +222,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* Array with additional params to combine with query string
*/
create(object: T, ...params: RequestParam[]): Observable<RemoteData<T>> {
return this.createData.create(object, ...params)
return this.createData.create(object, ...params);
}
/**
@@ -390,9 +314,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* errorMessage, timeCompleted, etc
*/
delete(objectId: string, copyVirtualMetadata?: string[]): Observable<RemoteData<NoContent>> {
return this.getIDHrefObs(objectId).pipe(
switchMap((href: string) => this.deleteByHref(href, copyVirtualMetadata))
);
return this.deleteData.delete(objectId, copyVirtualMetadata);
}
/**
@@ -405,43 +327,7 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* Only emits once all request related to the DSO has been invalidated.
*/
deleteByHref(href: string, copyVirtualMetadata?: string[]): Observable<RemoteData<NoContent>> {
const requestId = this.requestService.generateRequestId();
if (copyVirtualMetadata) {
copyVirtualMetadata.forEach((id) =>
href += (href.includes('?') ? '&' : '?')
+ 'copyVirtualMetadata='
+ id
);
}
const request = new DeleteRequest(requestId, href);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request);
const response$ = this.rdbService.buildFromRequestUUID(requestId);
const invalidated$ = new AsyncSubject<boolean>();
response$.pipe(
getFirstCompletedRemoteData(),
switchMap((rd: RemoteData<NoContent>) => {
if (rd.hasSucceeded) {
return this.invalidateByHref(href);
} else {
return [true];
}
})
).subscribe(() => {
invalidated$.next(true);
invalidated$.complete();
});
return combineLatest([response$, invalidated$]).pipe(
filter(([_, invalidated]) => invalidated),
map(([response, _]) => response),
);
return this.deleteData.deleteByHref(href, copyVirtualMetadata);
}
/**
@@ -449,6 +335,6 @@ export abstract class UpdateDataServiceImpl<T extends CacheableObject> extends B
* @param method The RestRequestMethod for which de server sync buffer should be committed
*/
commitUpdates(method?: RestRequestMethod) {
this.requestService.commit(method);
this.patchData.commitUpdates(method);
}
}

View File

@@ -58,7 +58,7 @@ export class SuggestionDataServiceImpl extends UpdateDataServiceImpl<Suggestion>
protected comparator: ChangeAnalyzer<Suggestion>,
protected responseMsToLive: number,
) {
super('suggestions', requestService, rdbService, objectCache, halService, notificationsService ,responseMsToLive);
super('suggestions', requestService, rdbService, objectCache, halService, notificationsService, comparator ,responseMsToLive);
}
}
@@ -99,7 +99,6 @@ export class SuggestionsDataService {
* @param {DefaultChangeAnalyzer<Suggestion>} comparatorSuggestions
* @param {DefaultChangeAnalyzer<SuggestionSource>} comparatorSources
* @param {DefaultChangeAnalyzer<SuggestionTarget>} comparatorTargets
* @param responseMsToLive
*/
constructor(
protected requestService: RequestService,

View File

@@ -21,7 +21,7 @@ import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analy
import { DATA_SERVICE_FACTORY } from '../../core/data/base/data-service.decorator';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { HALDataService } from '../../core/data/base/hal-data-service.interface';
import { UpdateDataService } from "../../core/data/update-data-service";
import { UpdateDataService } from '../../core/data/update-data-service';
@Component({
selector: 'ds-dso-edit-metadata',

View File

@@ -2,7 +2,7 @@ import { ThemedComponent } from '../../shared/theme-support/themed.component';
import { DsoEditMetadataComponent } from './dso-edit-metadata.component';
import { Component, Input } from '@angular/core';
import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { UpdateDataService } from "../../core/data/update-data-service";
import { UpdateDataService } from '../../core/data/update-data-service';
@Component({
selector: 'ds-themed-dso-edit-metadata',

View File

@@ -541,7 +541,7 @@ export class MenuResolver implements Resolve<boolean> {
{
id: 'notifications',
active: false,
visible: authorized && true,
visible: authorized && canSeeQA,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.notifications'

View File

@@ -86,10 +86,10 @@ export class SuggestionActionsComponent {
}
ignoreSuggestionLabel(): string {
return this.isBulk ? 'reciter.suggestion.ignoreSuggestion.bulk' : 'reciter.suggestion.ignoreSuggestion' ;
return this.isBulk ? 'suggestion.ignoreSuggestion.bulk' : 'suggestion.ignoreSuggestion' ;
}
approveAndImportLabel(): string {
return this.isBulk ? 'reciter.suggestion.approveAndImport.bulk' : 'reciter.suggestion.approveAndImport';
return this.isBulk ? 'suggestion.approveAndImport.bulk' : 'suggestion.approveAndImport';
}
}

View File

@@ -55,7 +55,7 @@ export class SuggestionTargetsEffects {
retrieveAllTargetsErrorAction$ = createEffect(() => this.actions$.pipe(
ofType(SuggestionTargetActionTypes.RETRIEVE_TARGETS_BY_SOURCE_ERROR),
tap(() => {
this.notificationsService.error(null, this.translate.get('reciter.suggestion.target.error.service.retrieve'));
this.notificationsService.error(null, this.translate.get('suggestion.target.error.service.retrieve'));
})
), { dispatch: false });
@@ -64,7 +64,7 @@ export class SuggestionTargetsEffects {
*/
refreshUserSuggestionsAction$ = createEffect(() => this.actions$.pipe(
ofType(SuggestionTargetActionTypes.REFRESH_USER_SUGGESTIONS),
switchMap((action: RefreshUserSuggestionsAction) => {
switchMap(() => {
return this.store$.select((state: any) => state.core.auth.userId)
.pipe(
switchMap((userId: string) => {

View File

@@ -169,18 +169,18 @@ describe('SuggestionsService test', () => {
it('should get suggestion interpolation', () => {
const result = service.getNotificationSuggestionInterpolation(suggestionTarget as SuggestionTarget);
expect(result.count).toEqual(suggestionTarget.total);
expect(result.source).toEqual('reciter.suggestion.source.' + suggestionTarget.source);
expect(result.type).toEqual('reciter.suggestion.type.' + suggestionTarget.source);
expect(result.source).toEqual('suggestion.source.' + suggestionTarget.source);
expect(result.type).toEqual('suggestion.type.' + suggestionTarget.source);
expect(result.suggestionId).toEqual(suggestionTarget.id);
expect(result.displayName).toEqual(suggestionTarget.display);
});
it('should translate suggestion type', () => {
expect(service.translateSuggestionType('source')).toEqual('reciter.suggestion.type.source');
expect(service.translateSuggestionType('source')).toEqual('suggestion.type.source');
});
it('should translate suggestion source', () => {
expect(service.translateSuggestionSource('source')).toEqual('reciter.suggestion.source.source');
expect(service.translateSuggestionSource('source')).toEqual('suggestion.source.source');
});
it('should resolve collection id', () => {

View File

@@ -51,17 +51,14 @@ export class SuggestionsService {
/**
* Initialize the service variables.
* @param {AuthService} authService
* @param {ResearcherProfileDataService} researcherProfileService
* @param {SuggestionSourceDataService} suggestionSourceDataService
* @param {SuggestionTargetDataService} suggestionTargetDataService
* @param {SuggestionsDataService} suggestionsDataService
* @param translateService
*/
constructor(
private authService: AuthService,
private researcherProfileService: ResearcherProfileDataService,
private suggestionsDataService: SuggestionsDataService,
private suggestionSourceDataService: SuggestionSourceDataService,
private suggestionTargetDataService: SuggestionTargetDataService,
private translateService: TranslateService
) {
@@ -194,7 +191,7 @@ export class SuggestionsService {
return workspaceitemService.importExternalSourceEntry(suggestion.externalSourceUri, resolvedCollectionId)
.pipe(
getFirstSucceededRemoteDataPayload(),
catchError((error) => of(null))
catchError(() => of(null))
);
}
@@ -204,7 +201,7 @@ export class SuggestionsService {
*/
public ignoreSuggestion(suggestionId): Observable<RemoteData<NoContent>> {
return this.deleteReviewedSuggestion(suggestionId).pipe(
catchError((error) => of(null))
catchError(() => of(null))
);
}
@@ -268,11 +265,11 @@ export class SuggestionsService {
}
public translateSuggestionType(source: string): string {
return 'reciter.suggestion.type.' + source;
return 'suggestion.type.' + source;
}
public translateSuggestionSource(source: string): string {
return 'reciter.suggestion.source.' + source;
return 'suggestion.source.' + source;
}
/**

View File

@@ -13,8 +13,6 @@ import {
} from '../suggestion-notifications/suggestion-list-element/suggestion-list-element.component';
import { SuggestionsService } from '../suggestion-notifications/suggestions.service';
import { getMockSuggestionNotificationsStateService, getMockSuggestionsService } from '../shared/mocks/suggestion.mock';
import { buildPaginatedList, PaginatedList } from '../core/data/paginated-list.model';
import { Suggestion } from '../core/suggestion-notifications/models/suggestion.model';
import { mockSuggestionPublicationOne, mockSuggestionPublicationTwo } from '../shared/mocks/publication-claim.mock';
import { SuggestionEvidencesComponent } from '../suggestion-notifications/suggestion-list-element/suggestion-evidences/suggestion-evidences.component';
import { ObjectKeysPipe } from '../shared/utils/object-keys-pipe';
@@ -29,7 +27,6 @@ import { getMockTranslateService } from '../shared/mocks/translate.service.mock'
import { SuggestionTargetsStateService } from '../suggestion-notifications/suggestion-targets/suggestion-targets.state.service';
import { WorkspaceitemDataService } from '../core/submission/workspaceitem-data.service';
import { createSuccessfulRemoteDataObject } from '../shared/remote-data.utils';
import { PageInfo } from '../core/shared/page-info.model';
import { TestScheduler } from 'rxjs/testing';
import { getTestScheduler } from 'jasmine-marbles';
import { PaginationServiceStub } from '../shared/testing/pagination-service.stub';

View File

@@ -152,7 +152,7 @@ export class SuggestionsPageComponent implements OnInit {
* @suggestionId
*/
ignoreSuggestion(suggestionId) {
this.suggestionService.ignoreSuggestion(suggestionId).subscribe((res) => {
this.suggestionService.ignoreSuggestion(suggestionId).subscribe(() => {
this.suggestionTargetsStateService.dispatchRefreshUserSuggestionsAction();
this.updatePage();
});
@@ -172,12 +172,12 @@ export class SuggestionsPageComponent implements OnInit {
this.selectedSuggestions = {};
if (results.success > 0) {
this.notificationService.success(
this.translateService.get('reciter.suggestion.notMine.bulk.success',
this.translateService.get('suggestion.notMine.bulk.success',
{count: results.success}));
}
if (results.fails > 0) {
this.notificationService.error(
this.translateService.get('reciter.suggestion.notMine.bulk.error',
this.translateService.get('suggestion.notMine.bulk.error',
{count: results.fails}));
}
});
@@ -190,7 +190,7 @@ export class SuggestionsPageComponent implements OnInit {
approveAndImport(event: SuggestionApproveAndImport) {
this.suggestionService.approveAndImport(this.workspaceItemService, event.suggestion, event.collectionId)
.subscribe((workspaceitem: WorkspaceItem) => {
const content = this.translateService.instant('reciter.suggestion.approveAndImport.success', { workspaceItemId: workspaceitem.id });
const content = this.translateService.instant('suggestion.approveAndImport.success', { workspaceItemId: workspaceitem.id });
this.notificationService.success('', content, {timeOut:0}, true);
this.suggestionTargetsStateService.dispatchRefreshUserSuggestionsAction();
this.updatePage();
@@ -212,12 +212,12 @@ export class SuggestionsPageComponent implements OnInit {
this.selectedSuggestions = {};
if (results.success > 0) {
this.notificationService.success(
this.translateService.get('reciter.suggestion.approveAndImport.bulk.success',
this.translateService.get('suggestion.approveAndImport.bulk.success',
{count: results.success}));
}
if (results.fails > 0) {
this.notificationService.error(
this.translateService.get('reciter.suggestion.approveAndImport.bulk.error',
this.translateService.get('suggestion.approveAndImport.bulk.error',
{count: results.fails}));
}
});

View File

@@ -1,4 +1,4 @@
import { Config } from "./config.interface";
import { Config } from './config.interface';
export interface SuggestionConfig extends Config {
source: string;