Skip to content

[DSpace-CRIS] Nested / Basic Hierarchical Metadata (Frontend)#5097

Merged
tdonohue merged 14 commits intoDSpace:mainfrom
4Science:task/main/DURACOM-444
Mar 26, 2026
Merged

[DSpace-CRIS] Nested / Basic Hierarchical Metadata (Frontend)#5097
tdonohue merged 14 commits intoDSpace:mainfrom
4Science:task/main/DURACOM-444

Conversation

@FrancescoMolinaro
Copy link
Copy Markdown
Contributor

@FrancescoMolinaro FrancescoMolinaro commented Feb 9, 2026

References

Fixes: DSpace/DSpace#12159
Require backend: DSpace/DSpace#11945

Description

This PR replace the standard group in submission with nested metdatata and UI forms.
The default group in submission will become a nested form and will be opened in a modal, to isolate the form and create connections between pairs of metadata.

Example of configuration:

<row>
                <relation-field>
                    <relationship-type>isAuthorOfPublication</relationship-type>
                    <search-configuration>person</search-configuration>
                    <repeatable>true</repeatable>
                    <label>Author</label>
                    <hint>Enter the author's name (Family name, Given names).</hint>
                    <linked-metadata-field>
                        <dc-schema>dc</dc-schema>
                        <dc-element>contributor</dc-element>
                        <dc-qualifier>author</dc-qualifier>
                        <input-type>group</input-type>
                    </linked-metadata-field>
                    <externalsources>orcid</externalsources>
                    <required></required>
                    <!-- You may choose to validate author names via a Regular Expression if it's appropriate for
                         your institution. The below regex requires a comma to be present in the author field.
                         However, this is disabled by default to support organizations as authors, etc. -->
                    <!--<regex>\w+(,)+\w+</regex>-->
                </relation-field>
            </row>

 <form name="publicationStep-dc-contributor-author">
          <row>
            <field>
              <dc-schema>dc</dc-schema>
              <dc-element>contributor</dc-element>
              <dc-qualifier>author</dc-qualifier>
              <label>Author</label>
              <input-type>onebox</input-type>
              <repeatable>false</repeatable>
              <required>You must enter at least the author.</required>
              <hint>Enter the names of the authors of this item in the form Lastname, Firstname [i.e. Smith, Josh or Smith, J].</hint>
            </field>
          </row>
          <row>
            <field>
              <dc-schema>oairecerif</dc-schema>
              <dc-element>author</dc-element>
              <dc-qualifier>affiliation</dc-qualifier>
              <label>Affiliation</label>
              <input-type>onebox</input-type>
              <repeatable>false</repeatable>
              <required />
              <hint>Enter the affiliation of the author as stated on the publication.</hint>
            </field>
          </row>
</form>       
image

A new group type called inline-group has been added to mantain the groups inside the main form and not in a modal, follows and example of config:

Please note that the inline-group as a limitation: all the fields needs to be configured inside one tag.
If you want to achieve a display on multiple rows, it can be don through styling, adding for example to each field the style tag as follows: <style>col-12</style>
This is a known limitation and should be added to the documentation as such.


 <row>
              <field>
                <dc-schema>dc</dc-schema>
                <dc-element>contributor</dc-element>
                <dc-qualifier>editor</dc-qualifier>
                <label>Editor group</label>
                <input-type>inline-group</input-type>
                <repeatable>true</repeatable>
                <required />
                <hint>Add the editor of this publication</hint>
              </field>
</row>

<form name="publicationStep-dc-contributor-editor">
          <row>
            <field>
              <dc-schema>dc</dc-schema>
              <dc-element>contributor</dc-element>
              <dc-qualifier>editor</dc-qualifier>
              <label>Editor</label>
              <input-type>onebox</input-type>
              <repeatable>false</repeatable>
              <required>You must enter at least the author.</required>
              <hint>The editors of this publication.</hint>
            </field>
            <field>
              <dc-schema>oairecerif</dc-schema>
              <dc-element>editor</dc-element>
              <dc-qualifier>affiliation</dc-qualifier>
              <label>Affiliation</label>
              <input-type>onebox</input-type>
              <repeatable>false</repeatable>
              <required />
              <hint>Enter the affiliation of the editor as stated on the publication.</hint>
            </field>
          </row>
</form>
image

**Please note that is not possible to add repeatable fields inside the nested forms, this would result in errors in the UI breaking the form. This is a known limitation and should be added to the documentation as such.

Input type specific configuration, as the regex, should be added inside the nested form configuration, as they don't work on input types which represent nested forms. (not an actual control in the form) **

Note: A custom layout option will follow in a different PR, wich will allow to group those metadata also on Item page (CRIS Layout)

Note: For inline groups is possible to configure an additional button with the property showInlineGroupDuplicateButton , which if true, will display under the form a button to duplicate the whole section, metadata values included.

Instructions for Reviewers

List of changes:

Added new inline-group field.
Adapted group field logic to use modal.
Adpated parsing and templates.

To test this feature follow the config and try to use the form groups in a submission.

Checklist

This checklist provides a reminder of what we are going to look for when reviewing your PR. You do not need to complete this checklist prior creating your PR (draft PRs are always welcome).
However, reviewers may request that you complete any actions in this list if you have not done so. If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!

  • My PR is created against the main branch of code (unless it is a backport or is fixing an issue specific to an older branch).
  • My PR is small in size (e.g. less than 1,000 lines of code, not including comments & specs/tests), or I have provided reasons as to why that's not possible.
  • My PR passes ESLint validation using npm run lint
  • My PR doesn't introduce circular dependencies (verified via npm run check-circ-deps)
  • My PR includes TypeDoc comments for all new (or modified) public methods and classes. It also includes TypeDoc for large or complex private methods.
  • My PR passes all specs/tests and includes new/updated specs or tests based on the Code Testing Guide.
  • My PR aligns with Accessibility guidelines if it makes changes to the user interface.
  • My PR uses i18n (internationalization) keys instead of hardcoded English text, to allow for translations.
  • My PR includes details on how to test it. I've provided clear instructions to reviewers on how to successfully test this fix or feature.
  • If my PR includes new libraries/dependencies (in package.json), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation.
  • If my PR includes new features or configurations, I've provided basic technical documentation in the PR itself.
  • If my PR fixes an issue ticket, I've linked them together.

@FrancescoMolinaro FrancescoMolinaro changed the title Task/main/duracom 444 [DSpace-CRIS] porting of Nested / Basic Hierarchical Metadata and related UI components Feb 19, 2026
@FrancescoMolinaro FrancescoMolinaro marked this pull request as ready for review February 19, 2026 14:04
@tdonohue tdonohue added DSpace-CRIS merger This ticket/PR relates to the merger of DSpace-CRIS into DSpace. component: configurable entities related to configurable entities new feature high priority labels Feb 19, 2026
@tdonohue tdonohue moved this to 🙋 Needs Reviewers Assigned in DSpace 10.0 Release Feb 19, 2026
@artlowel artlowel requested a review from KevinVdV March 12, 2026 16:59
@MarieVerdonck
Copy link
Copy Markdown
Contributor

inline-group only renders first input & doesn't enforce required beyond name field

The inline-group config only renders the first input of the affiliated nested form.
Screenshot 2026-03-13 at 04 48 17
Screenshot 2026-03-13 at 05 01 56
Screenshot 2026-03-13 at 05 03 14

Eg

        <form name="publicationStepGroup">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>editor</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Editor</label>
                    <input-type>inline-group</input-type>
                    <hint>The editors of this publication.</hint>
                    <required>You must enter at least the editor's name.</required>
                </field>
            </row>
        </form>
<form name="publicationStepGroup-dc-contributor-editor">
    <row>
        <field>
            <dc-schema>dc</dc-schema>
            <dc-element>contributor</dc-element>
            <dc-qualifier>editor</dc-qualifier>
            <repeatable>false</repeatable>
            <label>Editor name</label>
            <input-type>onebox</input-type>
            <hint>Enter the names of the editor.</hint>
            <required>You must enter at least the editor.</required>
        </field>
    </row>
    <row>
        <field>
            <dc-schema>oairecerif</dc-schema>
            <dc-element>editor</dc-element>
            <dc-qualifier>affiliation</dc-qualifier>
            <repeatable>false</repeatable>
            <label>Affiliation</label>
            <input-type>onebox</input-type>
            <hint>Enter the affiliation of the editor.</hint>
            <required>Enter the affiliation of the editor.</required>
        </field>
    </row>
</form>

If switch Editor name and Affiliation inputs, only affiliation is shown.

Even with both required, I can submit form with only the name filled in!

@MarieVerdonck
Copy link
Copy Markdown
Contributor

Regex on nested form breaks input

Adding regex on the author name field breaks input, can't add new authors, even when following the regex rules.

No validation of regex rule is shown.

Screenshot 2026-03-13 at 05 07 39 Screenshot 2026-03-13 at 05 08 15

Eg

        <form name="publicationStepGroup">
            <row>
                <relation-field>
                    <relationship-type>isAuthorOfPublication</relationship-type>
                    <search-configuration>person</search-configuration>
                    <repeatable>true</repeatable>
                    <label>Author</label>
                    <hint>Enter the author's name.</hint>
                    <linked-metadata-field>
                        <dc-schema>dc</dc-schema>
                        <dc-element>contributor</dc-element>
                        <dc-qualifier>author</dc-qualifier>
                        <input-type>group</input-type>
                    </linked-metadata-field>
                    <required>Enter at least one author</required>
                </relation-field>
            </row>
        </form>

        <form name="publicationStepGroup-dc-contributor-author">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>author</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Author</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the names of the authors.</hint>
                    <required>You must enter at least the author.</required>
                    <regex>\w+(,)+\w+</regex>
                </field>
            </row>
            <row>
                <field>
                    <dc-schema>oairecerif</dc-schema>
                    <dc-element>author</dc-element>
                    <dc-qualifier>affiliation</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Affiliation</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the affiliation of the author.</hint>
                </field>
            </row>
        </form>

Regex on top relation-field breaks form/validation

Adding regex on the top relation-field input:

  • can still add author name, not following regex
  • if form saved/refreshed, nothing renders & error in console
Screenshot 2026-03-13 at 05 09 46 Screenshot 2026-03-13 at 05 10 08

Eg

        <form name="publicationStepGroup">
            <row>
                <relation-field>
                    <relationship-type>isAuthorOfPublication</relationship-type>
                    <search-configuration>person</search-configuration>
                    <repeatable>true</repeatable>
                    <label>Author</label>
                    <hint>Enter the author's name.</hint>
                    <linked-metadata-field>
                        <dc-schema>dc</dc-schema>
                        <dc-element>contributor</dc-element>
                        <dc-qualifier>author</dc-qualifier>
                        <input-type>group</input-type>
                    </linked-metadata-field>
                    <required>Enter at least one author</required>
                    <regex>\w+(,)+\w+</regex>
                </relation-field>
            </row>
        </form>

        <form name="publicationStepGroup-dc-contributor-author">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>author</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Author</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the names of the authors.</hint>
                    <required>You must enter at least the author.</required>
                </field>
            </row>
            <row>
                <field>
                    <dc-schema>oairecerif</dc-schema>
                    <dc-element>author</dc-element>
                    <dc-qualifier>affiliation</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Affiliation</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the affiliation of the author.</hint>
                </field>
            </row>
        </form>

@MarieVerdonck
Copy link
Copy Markdown
Contributor

MarieVerdonck commented Mar 13, 2026

Putting repeatable=true on nested fields breaks form

If making a nested input repeatable (eg affiliation of author) this breaks the form (can't add/edit new authors)

 ERROR TypeError: Cannot read properties of undefined (reading 'forEach')
    at dynamic-relation-group-modal.components.ts:231:22
    at Array.forEach (<anonymous>)
    at DsDynamicRelationGroupModalComponent.getMandatoryFieldModel (dynamic-relation-group-modal.components.ts:229:20)
    at DsDynamicRelationGroupModalComponent.getHeader (dynamic-relation-group-modal.components.ts:149:17)
    at DsDynamicRelationGroupModalComponent_Template (dynamic-relation-group-modal.component.html:3:29)

-> this happens because angular isn’t prepared to handle null values for these fields and there’s a general lack of null / undefined safety in DsDynamicRelationGroupModalComponent

Eg.

        <form name="publicationStepGroup">
            <row>
                <relation-field>
                    <relationship-type>isAuthorOfPublication</relationship-type>
                    <search-configuration>person</search-configuration>
                    <repeatable>true</repeatable>
                    <label>Author</label>
                    <hint>Enter the author's name.</hint>
                    <linked-metadata-field>
                        <dc-schema>dc</dc-schema>
                        <dc-element>contributor</dc-element>
                        <dc-qualifier>author</dc-qualifier>
                        <input-type>group</input-type>
                    </linked-metadata-field>
                    <required>Enter at least one author</required>
                </relation-field>
            </row>
        </form>

        <form name="publicationStepGroup-dc-contributor-author">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>author</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Author</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the names of the authors.</hint>
                    <required>You must enter at least the author.</required>
                </field>
            </row>
            <row>
                <field>
                    <dc-schema>oairecerif</dc-schema>
                    <dc-element>author</dc-element>
                    <dc-qualifier>affiliation</dc-qualifier>
                    <repeatable>true</repeatable>
                    <label>Affiliation</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the affiliation of the author.</hint>
                </field>
            </row>
        </form>

Idem if adding repeatable = true on first (only visible) nested field of input-group input
Screenshot 2026-03-13 at 05 23 45

Eg

        <form name="publicationStepGroup">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>author</dc-qualifier>
                    <repeatable>false</repeatable>
                    <label>Author</label>
                    <input-type>inline-group</input-type>
                    <hint>The authors of this publication.</hint>
                    <required>You must enter at least the author's name.</required>
                </field>
            </row>
        </form>

        <form name="publicationStepGroup-dc-contributor-author">
            <row>
                <field>
                    <dc-schema>dc</dc-schema>
                    <dc-element>contributor</dc-element>
                    <dc-qualifier>author</dc-qualifier>
                    <repeatable>true</repeatable>
                    <label>Author</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the names of the authors.</hint>
                    <required>You must enter at least the author.</required>
                </field>
            </row>
            <row>
                <field>
                    <dc-schema>oairecerif</dc-schema>
                    <dc-element>author</dc-element>
                    <dc-qualifier>affiliation</dc-qualifier>
                    <repeatable>true</repeatable>
                    <label>Affiliation</label>
                    <input-type>onebox</input-type>
                    <hint>Enter the affiliation of the author.</hint>
                </field>
            </row>
        </form>

@github-actions
Copy link
Copy Markdown

Hi @FrancescoMolinaro,
Conflicts have been detected against the base branch.
Please resolve these conflicts as soon as you can. Thanks!

@tdonohue tdonohue changed the title [DSpace-CRIS] porting of Nested / Basic Hierarchical Metadata and related UI components [DSpace-CRIS] Nested / Basic Hierarchical Metadata (Frontend) Mar 13, 2026
@FrancescoMolinaro
Copy link
Copy Markdown
Contributor Author

Hi @MarieVerdonck, many thanks for the feedback, much appreciated.

Regarding the issue you reported with the repeatable fields, I have found out by checking the history of development on the CRIS code base, that the repeatable fields are not supported inside the nested forms.
I have update the description on the task, this information should be documented as a limitation of the feature in the documentation.

For the inline-group configuration there is an additional limitation, the form fields must be all inside a single row, if you want to achieve a layout on multiple rows, it can be done via the style attribute, I have updated the description accordingly.
Having the config inside a single row should also fix the issue whith the validation on multiple fields, e.g. multiple required fields should be validated separately.

About the regex issue instead I am not able to reproduce the problem with your configuration at #5097 (comment) (regex on single field inside nested form).
I have used the same config and I see the the validation of the regex without being able to add the field, if it is not matching the regex:

regex.webm

Might I please ask you to try again? It could be possible that the problem has been mitigated after aligning the PR with the latest changes from main.

The second configuration instead is not possible, adding a regex on the top level metadata breaks the UI because is not an actual input, instead the regex should be configured on the fields inside the nested form.
I have updated the description accordingly.

@lgeggleston lgeggleston moved this from 🙋 Needs Reviewers Assigned to 👀 Under Review in DSpace 10.0 Release Mar 19, 2026
Copy link
Copy Markdown
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@FrancescoMolinaro : Thanks for this PR. I reviewed this and tested it with the backend PR. Overall, the feature works well, and I haven't found any obvious bugs. I did however find some minor things to cleanup in the code (especially some disabled tests -- see inline below).

One other thing I did want to ask is whether the UI display for the inline-group is the same in this PR as in DSpace-CRIS? I find the display to be a bit odd looking because there's so much vertical space used for each "inline group" of fields. For example, here's what I'm seeing with the "Editor" field configured as an inline-group:

Image

Things that look odd to me include:

  • The drag & drop icon is appearing above the field. When this icon doesn't exist, it's empty space, so the field is always very tall.
  • The delete button appears below the field, again using vertical space.
  • I find the "Duplicate" and "+Add more" buttons to be a bit duplicative. I did finally figure out though that they have different behavior. I just find it odd to have both.

Overall, I expected this inline-group field to look a bit more like the existing series field (used for "Series/Report") where there delete button appears to the right of the fields & the drag & drop icon appears to the left of the fields.

In any case, this display issue is minor and we could move it to a follow-up ticket. I just wanted to ask if this is the expected display or if it appears differently in DSpace-CRIS.

Overall, I'm nearly a +1 (once my inline comments are addressed/answered). This all looks good to me. I do agree though that these new field types require more detailed documentation, especially since there's some invalid configurations that are possible (as pointed out by @MarieVerdonck in the above comments)

Comment thread src/config/default-app-config.ts
Comment thread src/app/shared/form/form.component.ts
@tdonohue
Copy link
Copy Markdown
Member

@MarieVerdonck : As we are nearing the deadline for 10.0 new features, I'd appreciate it if you can give this a followup review and explicitly note whether you are "+1" this being added to 10.0. It sounds like your prior feedback has either been fixed or will be documented as an "invalid configuration". I'll flag this PR as requiring docs now.

@tdonohue tdonohue added the needs documentation PR is missing documentation. All new features and config changes require documentation. label Mar 24, 2026
@FrancescoMolinaro
Copy link
Copy Markdown
Contributor Author

Hi @tdonohue, many thanks for the review, I have updated the code adding comments and documentation where needed and adapting the group layout as you suggested.
For the duplicate button i have added a new configuration property to make it optional, showInlineGroupDuplicateButton, by default is false and the button won't be displayed.
I have also cleaned the group modal test suite, removing the tests that weren't necessary as they were part of a feature not yet included in the code,.
Hopefully this PR is now in a cleaner state, thanks again for the feedback.

Copy link
Copy Markdown
Member

@tdonohue tdonohue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Thanks @FrancescoMolinaro ! All my prior review feedback has been addressed. I've also verified the new display for inline-group looks much better (& more compact):

Image

I also tested that setting form > showInlineGroupDuplicateButton: true will add the Duplicate buttons back into the display.

So, this looks good to me. Thanks again for the hard work on this PR!

(Obviously this still will require documentation to be added to the DSDOC10x space for this feature.)

@github-project-automation github-project-automation Bot moved this from 👀 Under Review to 👍 Reviewer Approved in DSpace 10.0 Release Mar 25, 2026
@tdonohue
Copy link
Copy Markdown
Member

@MarieVerdonck : If you could give this PR another look, I think all your feedback has been addressed. It also looks good to me now and I've officially given it a 👍

I'd like to merge this quickly as several other merger-related PRs build off this one (so it will make it easier to code review those others PRs). So, I plan to merge this tomorrow unless I hear from you sooner.

Copy link
Copy Markdown
Contributor

@MarieVerdonck MarieVerdonck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality seems to work as expected with adjustments to config & avoiding the repeatable/regex which is not allowed, added in REST review suggestion to do fail-fast parsing of submission forms config so can't build with invalid submission form config, but is not blocking issue.

Also tested showInlineGroupDuplicateButton => copies even authority controlled md, though I'm unsure what use case this functionality has, so user doesn't have to retype e.g. affiliation?

@tdonohue tdonohue added this to the 10.0 milestone Mar 26, 2026
@tdonohue
Copy link
Copy Markdown
Member

Thanks again @FrancescoMolinaro ! Merging as this is at +2. Reminder that this has the "needs documentation" label until docs are added to https://wiki.lyrasis.org/display/DSDOC10x.

@tdonohue tdonohue merged commit f8b8ac0 into DSpace:main Mar 26, 2026
18 of 19 checks passed
@github-project-automation github-project-automation Bot moved this from 👍 Reviewer Approved to ✅ Done in DSpace 10.0 Release Mar 26, 2026
@GraziaQuercia
Copy link
Copy Markdown

documentation ready https://wiki.lyrasis.org/display/DSDOC10x/Nested+metadata+in+DSpace+items

@tdonohue tdonohue removed the needs documentation PR is missing documentation. All new features and config changes require documentation. label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: configurable entities related to configurable entities DSpace-CRIS merger This ticket/PR relates to the merger of DSpace-CRIS into DSpace. high priority new feature

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

[DSpace-CRIS} Nested / Basic Hierarchical Metadata

5 participants