Skip to content

browse-by-date-component is using a wrong item metadata #5122

@xvThomas

Description

@xvThomas

DSpace Version: 9.2

Describe the bug

Here is a part of the browse request response I have at the begining of a frontend session with DSpace:

"browses" : [ {
      "id" : "datecreated",
      "browseType" : "flatBrowse",
      "dataType" : "date",
      "sortOptions" : [ {
        "name" : "datecreated",
        "metadata" : "dc.date.created"
      }, {
        "name" : "dateaccessioned",
        "metadata" : "dc.date.accessioned"
      } ],
      "order" : "DESC",
      "type" : "browse",
      "metadata" : [ "dc.date.created" ],
      ...

In my local.cfg, I have:

# webui.browse.index.<n> = <index name> : item : <sort option name> : (asc | desc)
webui.browse.index.1 = datecreated:item:datecreated:desc

When using the frontend route http://localhost:4000/browse/datecreated, the year select control is not populated by creation date but by issue date.

To Reproduce

  • Add webui.browse.index.1 = datecreated:item:datecreated:desc in local.cfg
  • Rerun the backend
  • Go to "All Dspace"
  • Choose "Creation date"
  • Open The year select

Expected behavior

The frontend (browse-by-date-component.ts) is unable to decode the browse item "datecreated" and unable to use "dc.date.created" in order to find the first and the last creation dates.

This is the workaround I applied:

Before:

  • params.browseDefinition is undefined,
  • dc.data.issued is used as a fallback : defaultMetadataKeys = ['dc.date.issued'];
  • if dc.date.issued not available in the browse definition, the current year is used. (see getLimit method)
 ngOnInit(): void {
    if (!this.renderOnServerSide && !environment.ssr.enableBrowseComponent && isPlatformServer(this.platformId)) {
      this.loading$ = of(false);
      return;
    }
    const sortConfig = new SortOptions('default', SortDirection.ASC);
    this.startsWithType = StartsWithType.date;
    this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
    this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
    const routeParams$: Observable<Params> = observableCombineLatest([
      this.route.params,
      this.route.queryParams,
    ]).pipe(
      map(([params, queryParams]: [Params, Params]) => Object.assign({}, params, queryParams)),
      distinctUntilChanged((prev: Params, curr: Params) => prev.id === curr.id && prev.startsWith === curr.startsWith),
    );
    this.subs.push(
      observableCombineLatest([
        routeParams$,
        this.scope$,
        this.currentPagination$,
        this.currentSort$,
      ]).subscribe(([params, scope, currentPage, currentSort]: [Params, string, PaginationComponentOptions, SortOptions]) => {
        const metadataKeys = params.browseDefinition ? params.browseDefinition.metadataKeys : this.defaultMetadataKeys;
        this.browseId = params.id || this.defaultBrowseId;
        this.startsWith = +params.startsWith || params.startsWith;
        const searchOptions = browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails);
        this.updatePageWithItems(searchOptions, this.value, undefined);
        this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
      }));
  }
...
private getLimit(itemRD: RemoteData<Item>, metadataKeys: string[], limit: number): number {
    if (hasValue(itemRD.payload)) {
      const date = itemRD.payload.firstMetadataValue(metadataKeys);
      if (isNotEmpty(date) && isValidDate(date)) {
        const dateObj = new Date(date);
        // TODO: it appears that getFullYear (based on local time) is sometimes unreliable. Switching to UTC.
        return isNaN(dateObj.getUTCFullYear()) ? limit : dateObj.getUTCFullYear();
      } else {
        return new Date().getUTCFullYear();
      }
    }
  }

After: Use BrowseDefinition from this.route.data

ngOnInit(): void {
    if (!this.renderOnServerSide && !environment.ssr.enableBrowseComponent && isPlatformServer(this.platformId)) {
      this.loading$ = of(false);
      return;
    }
    const sortConfig = new SortOptions('default', SortDirection.ASC);
    this.startsWithType = StartsWithType.date;
    this.currentPagination$ = this.paginationService.getCurrentPagination(this.paginationConfig.id, this.paginationConfig);
    this.currentSort$ = this.paginationService.getCurrentSort(this.paginationConfig.id, sortConfig);
    const browseDefinition$: Observable<BrowseDefinition | undefined> = observableCombineLatest([
      this.route.data,
      this.route.parent ? this.route.parent.data : of({} as Record<string, any>),
    ]).pipe(
      map(([data, parentData]) => (data?.browseDefinition ?? parentData?.browseDefinition) as BrowseDefinition | undefined),
      distinctUntilChanged((prev, curr) => prev?.id === curr?.id),
    );
    const routeParams$: Observable<Params> = observableCombineLatest([
      this.route.params,
      this.route.queryParams,
    ]).pipe(
      map(([params, queryParams]: [Params, Params]) => Object.assign({}, params, queryParams)),
      distinctUntilChanged((prev: Params, curr: Params) => prev.id === curr.id && prev.startsWith === curr.startsWith),
    );
    this.subs.push(
      observableCombineLatest([
        routeParams$,
        this.scope$,
        this.currentPagination$,
        this.currentSort$,
        browseDefinition$,
      ]).subscribe(([params, scope, currentPage, currentSort, browseDefinition]: [Params, string, PaginationComponentOptions, SortOptions, BrowseDefinition | undefined]) => {
        const metadataKeys = browseDefinition?.metadataKeys ?? this.defaultMetadataKeys;
        this.browseId = params.id || this.defaultBrowseId;
        this.startsWith = +params.startsWith || params.startsWith;
        const searchOptions = browseParamsToOptions(params, scope, currentPage, currentSort, this.browseId, this.fetchThumbnails);
        this.updatePageWithItems(searchOptions, this.value, undefined);
        this.updateStartsWithOptions(this.browseId, metadataKeys, params.scope);
      }));
  }

Any other suggestion ?

Metadata

Metadata

Assignees

Labels

Type

Projects

Status

🏗 In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions