Merge pull request #4234 from 4Science/task/main/DURACOM-350

[DURACOM-350] fix cache issue after mydspace action
This commit is contained in:
Tim Donohue
2025-04-24 15:07:06 -05:00
committed by GitHub
6 changed files with 19 additions and 18 deletions

View File

@@ -101,17 +101,25 @@ export abstract class MyDSpaceActionsComponent<T extends DSpaceObject, TService
reload(): void { reload(): void {
this.router.navigated = false; this.router.navigated = false;
const url = decodeURIComponent(this.router.url);
// override the route reuse strategy // override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = () => { this.router.routeReuseStrategy.shouldReuseRoute = () => {
return false; return false;
}; };
// This assures that the search cache is empty before reloading mydspace. // This assures that the search cache is empty before reloading mydspace.
// See https://github.com/DSpace/dspace-angular/pull/468 // See https://github.com/DSpace/dspace-angular/pull/468
this.invalidateCacheForCurrentSearchUrl(true);
}
invalidateCacheForCurrentSearchUrl(shouldNavigate = false): void {
const url = decodeURIComponent(this.router.url);
this.searchService.getEndpoint().pipe( this.searchService.getEndpoint().pipe(
take(1), take(1),
tap((cachedHref: string) => this.requestService.removeByHrefSubstring(cachedHref)), tap((cachedHref: string) => this.requestService.removeByHrefSubstring(cachedHref)),
).subscribe(() => this.router.navigateByUrl(url)); ).subscribe(() => {
if (shouldNavigate) {
this.router.navigateByUrl(url);
}
});
} }
/** /**

View File

@@ -219,6 +219,7 @@ describe('MyDSpaceReloadableActionsComponent', () => {
spyOn(component, 'reloadObjectExecution').and.callThrough(); spyOn(component, 'reloadObjectExecution').and.callThrough();
spyOn(component, 'convertReloadedObject').and.callThrough(); spyOn(component, 'convertReloadedObject').and.callThrough();
spyOn(component.processCompleted, 'emit').and.callThrough(); spyOn(component.processCompleted, 'emit').and.callThrough();
spyOn(component, 'invalidateCacheForCurrentSearchUrl').and.callThrough();
(component as any).objectDataService = mockDataService; (component as any).objectDataService = mockDataService;
}); });
@@ -239,10 +240,11 @@ describe('MyDSpaceReloadableActionsComponent', () => {
}); });
}); });
it('should emit the reloaded object in case of success', (done) => { it('should emit the reloaded object and invalidate cache in case of success', (done) => {
component.startActionExecution().subscribe( (result) => { component.startActionExecution().subscribe( (result) => {
expect(component.processCompleted.emit).toHaveBeenCalledWith({ result: true, reloadedObject: result as any }); expect(component.processCompleted.emit).toHaveBeenCalledWith({ result: true, reloadedObject: result as any });
expect(component.invalidateCacheForCurrentSearchUrl).toHaveBeenCalled();
done(); done();
}); });
}); });

View File

@@ -105,6 +105,8 @@ export abstract class MyDSpaceReloadableActionsComponent<T extends DSpaceObject,
if (result) { if (result) {
if (reloadedObject) { if (reloadedObject) {
this.processCompleted.emit({ result, reloadedObject }); this.processCompleted.emit({ result, reloadedObject });
// Ensure that next time the page is requested the objects have the correct render type.
this.invalidateCacheForCurrentSearchUrl();
} else { } else {
this.reload(); this.reload();
} }

View File

@@ -25,7 +25,6 @@ import {
Subscription, Subscription,
switchMap, switchMap,
} from 'rxjs'; } from 'rxjs';
import { take } from 'rxjs/operators';
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { SearchService } from '../../../../core/shared/search/search.service'; import { SearchService } from '../../../../core/shared/search/search.service';
@@ -145,7 +144,7 @@ export class SearchFilterComponent implements OnInit, OnChanges, OnDestroy {
this.filterService.expand(this.filter.name); this.filterService.expand(this.filter.name);
} }
}), }),
this.getIsActive().pipe(take(1)).subscribe(() => { this.getIsActive().subscribe(() => {
this.isVisibilityComputed.emit(true); this.isVisibilityComputed.emit(true);
}), }),
); );

View File

@@ -5,14 +5,14 @@
} }
@if ((filters | async)?.hasSucceeded) { @if ((filters | async)?.hasSucceeded) {
<div [class.visually-hidden]="getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length"> <div [class.visually-hidden]="getCurrentFiltersComputed(this.currentConfiguration) < (filters | async)?.payload?.length">
@for (filter of (filters | async)?.payload; track filter.name) { @for (filter of (filters | async)?.payload; track filter.name) {
<ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter> <ds-search-filter (isVisibilityComputed)="countFiltersWithComputedVisibility($event)" [scope]="currentScope" [filter]="filter" [inPlaceSearch]="inPlaceSearch" [refreshFilters]="refreshFilters"></ds-search-filter>
} }
</div> </div>
} }
@if(getFinalFiltersComputed(this.currentConfiguration) !== (filters | async)?.payload?.length) { @if(getCurrentFiltersComputed(this.currentConfiguration) < (filters | async)?.payload?.length) {
<ngx-skeleton-loader [count]="defaultFilterCount"/> <ngx-skeleton-loader [count]="defaultFilterCount"/>
} }

View File

@@ -251,18 +251,8 @@ export class SearchFiltersComponent implements OnInit {
* @param configuration The configuration identifier to get the count for * @param configuration The configuration identifier to get the count for
* @returns The number of computed filters, or 0 if none found * @returns The number of computed filters, or 0 if none found
*/ */
private getCurrentFiltersComputed(configuration: string) { getCurrentFiltersComputed(configuration: string): number {
const configFilter = this.findConfigInCurrentFilters(configuration); const configFilter = this.findConfigInCurrentFilters(configuration);
return configFilter?.filtersComputed || 0; return configFilter?.filtersComputed || 0;
} }
/**
* Gets the final number of computed filters for a specific configuration
* @param configuration The configuration identifier to get the count for
* @returns The number of computed filters in the final state, or 0 if none found
*/
getFinalFiltersComputed(configuration: string): number {
const configFilter = this.findConfigInFinalFilters(configuration);
return configFilter?.filtersComputed || 0;
}
} }