Creating Relations During Submission (DSpace 8)

208 views
Skip to first unread message

Peter

unread,
Aug 21, 2024, 1:57:24 PM8/21/24
to DSpace Technical Support
Hi,

I'd like to find out where can I set up a pop up window for adding a relation during item submission? Like this one from DSpace demo for adding an existing author:

Screenshot from 2024-08-21 18-10-51.png

I'd like to customize side facets and only show specific entity types in the search results. I have custom entities and relations in my DSpace instance, and the analogous window shows all available items/communities/collections, and facets unrelated to the entities I need to attach to the submission.

By studying documentation and configuration files, I have learnt that adding a relation in submission form needs a <relation-field> like this one from submission-forms.xml:

            <row>
                <relation-field>
                    <relationship-type>isAuthorOfPublication</relationship-type>
                    <search-configuration>personOrOrgunit</search-configuration>
                    <repeatable>true</repeatable>
                    <name-variants>true</name-variants>
                    <label>Author</label>
                    <hint>Add an author</hint>
                    <linked-metadata-field>
                        <dc-schema>dc</dc-schema>
                        <dc-element>contributor</dc-element>
                        <dc-qualifier>author</dc-qualifier>
                        <input-type>name</input-type>
                    </linked-metadata-field>
                    <externalsources>orcid</externalsources>
                    <required>At least one author (plain text or relationship) is required</required>
                </relation-field>
            </row>

The important part here is <search-configuration>, pointing to a bean in discovery.xml. I have included a search config in this file, where only specific facets are included in <property name="sidebarFacets">, as well as filter queries in <property name="defaultFilterQueries">. Nevertheless, this does not seem to have any effects.

Should this be configured somewhere else additionally?

Thanks
Peter

Peter

unread,
Aug 21, 2024, 2:31:35 PM8/21/24
to DSpace Technical Support
Now I see I made a mistake in linking <search-configuration> with discovery.xml:
I was linking to <bean>'s id, while this should be <entry>'s key value included in submission-forms.xml's <search-configuration>.

However, upon selecting the entity, in the submission form I only see a blank space, with a bin on the right, while there should be something there like dc.title or whatever. So the question is, which configuration is responsible for showing this in submission form?

Peter

unread,
Aug 23, 2024, 4:20:03 PM8/23/24
to DSpace Technical Support
I couldn't find many resources on this issue, so through a trial-and-error approach, I have come up with the following code and files.

Assuming I am developing "mytheme" custom theme and "myentity" custom entity:


1. Add mytheme/app/entity-groups/some-entity-group/metadata-representations/my-entity/my-entity-item-metadata-list-element.component.ts, something like:

import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';

import { metadataRepresentationComponent } from 'src/app/shared/metadata-representation/metadata-representation.decorator';
import { MetadataRepresentationType } from 'src/app/core/shared/metadata-representation/metadata-representation.model';
import { ItemMetadataRepresentationListElementComponent } from 'src/app/shared/object-list/metadata-representation-list-element/item/item-metadata-representation-list-element.component';
import { TruncatableComponent } from 'src/app/shared/truncatable/truncatable.component';

@metadataRepresentationComponent('myentity', MetadataRepresentationType.Item)
@Component({
  selector: 'ds-my-entity-item-metadata-list-element',
  templateUrl: './my-entity-item-metadata-list-element.component.html',
  standalone: true,
  imports: [TruncatableComponent, RouterLink, NgbTooltipModule],
})

export class MyEntityItemMetadataListElementComponent extends ItemMetadataRepresentationListElementComponent {
}


2. Add mytheme/app/entity-groups/some-entity-group/metadata-representations/my-entity/my-entity-item-metadata-list-element.component.spec.ts, something like:

import {
  ChangeDetectionStrategy,
  NO_ERRORS_SCHEMA,
} from '@angular/core';
import {
  ComponentFixture,
  TestBed,
  waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { RouterLink } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

import { Item } from 'src/app/core/shared/item.model';
import { MetadataValue } from 'src/app/core/shared/metadata.models';
import { ItemMetadataRepresentation } from 'src/app/core/shared/metadata-representation/item/item-metadata-representation.model';
import { TruncatableComponent } from 'src/app/shared/truncatable/truncatable.component';
import { MyEntityItemMetadataListElementComponent } from './my-entity-item-metadata-list-element.component';

const displayName = 'Display Name';
const mockItem = Object.assign(new Item(), { metadata: { 'dc.title': [{ value: displayName }]  } });
const virtMD = Object.assign(new MetadataValue(), { value: displayName });

const mockItemMetadataRepresentation = Object.assign(new ItemMetadataRepresentation(virtMD), mockItem);

describe('MyEntityItemMetadataListElementComponent', () => {
  let comp: MyEntityItemMetadataListElementComponent;
  let fixture: ComponentFixture<MyEntityItemMetadataListElementComponent>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [
        NgbModule,
        MyEntityItemMetadataListElementComponent,
      ],
      schemas: [NO_ERRORS_SCHEMA],
    }).overrideComponent(MyEntityItemMetadataListElementComponent, {
      remove: {
        imports: [TruncatableComponent, RouterLink],
      },
      add: { changeDetection: ChangeDetectionStrategy.Default },
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyEntityItemMetadataListElementComponent);
    comp = fixture.componentInstance;
    comp.mdRepresentation = mockItemMetadataRepresentation;
    fixture.detectChanges();
  });

  it('should show the entity\'s name as a link', () => {
    const linkText = fixture.debugElement.query(By.css('a')).nativeElement.textContent;
    expect(linkText).toBe(displayName);
  });

  it('should show the description on hover over the link in a tooltip', () => {
    const link = fixture.debugElement.query(By.css('a'));
    link.triggerEventHandler('mouseenter', null);
    fixture.detectChanges();
    const tooltip = fixture.debugElement.query(By.css('.item-list-display-name')).nativeElement.textContent;
    expect(tooltip).toBe(displayName);
  });
});


3. Add mytheme/app/entity-groups/some-entity-group/metadata-representations/my-entity/my-entity-item-metadata-list-element.component.html, something like:

<ng-template #descTemplate>
  <span class="text-muted">
      <span class="item-list-display-name">
        <span [innerHTML]="mdRepresentation.firstMetadataValue(['dc.title'])"></span>
      </span>
  </span>
</ng-template>
<ds-truncatable [id]="mdRepresentation.id">
  <a [routerLink]="[itemPageRoute]"
     [innerHTML]="mdRepresentation.getValue()"
     [ngbTooltip]="mdRepresentation.allMetadata(['dc.title']).length > 0 ? descTemplate : null"></a>
</ds-truncatable>


4. In the mytheme/eager-theme.module.ts add:

import { MyEntityItemMetadataListElementComponent } from './app/entity-groups/some-entity-group/metadata-representations/my-entity/my-entity-item-metadata-list-element.component';

const ENTRY_COMPONENTS = [
  MyEntityItemMetadataListElementComponent,
];


This basically works, and custom metadata should obviously be applied where necessary depending on the entity structure. However, I am not familiar with the functionality of all the components imported into the files mentioned above, so if anyone could provide more details on this part (which components are missing, required, useful, etc.), it would be greatly appreciated.
Reply all
Reply to author
Forward
0 new messages