Skip to content

Manage guestbook page integration#992

Open
ChengShi-1 wants to merge 11 commits into
developfrom
ManageGuestbook
Open

Manage guestbook page integration#992
ChengShi-1 wants to merge 11 commits into
developfrom
ManageGuestbook

Conversation

@ChengShi-1

@ChengShi-1 ChengShi-1 commented May 12, 2026

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:

  • manage dataset guestbook table, with name, created date, usage, responses and action columns
  • create guestbook
  • include guestbooks from parent collection
  • edit actions: disable/enable, preview, copy, edit(not included), download, view responses(not included), delete(not included)

Which issue(s) this PR closes:

Special notes for your reviewer:

use js-dataverse IQSS/dataverse-client-javascript#449

Suggestions on how to test this:

In collection page Edit => Dataset Guestbook, then you arrive the Manage Guestbook Page,
If there is no guestbook, it should show text to guide users and a Create Guestbook button.
If there is one or more guestbook, it should show a table with info just like JSF.
image

  • all information in the table are shown, including guestbook name, created, usage, responses
  • create button works
  • Download All Responses button works
  • action buttons: enable/disable, view, download should work, (other action buttons are not implemented yet)
  • create a sub collection, toggle the checkbox "include guestbooks from parent collection", which should show or not show a list of guestbooks from parent collections
  • If the guestbook is disable, this guestbook cannot be chosen in Dataset -> Edit terms and guestbook -> guestbook tab (a list of available guestbooks will hide the disabled guestbook)
  • Create Dataset Guestbook should successfully submit and create with what you filled

Does this PR introduce a user interface change? If mockups are available, please link/include them here:

Create Dataset Guestbook
image
image
image
image

Is there a release notes or changelog update needed for this change?:

Yes

Additional documentation:

@github-actions github-actions Bot added FY26 Sprint 23 FY26 Sprint 23 (2026-05-06 - 2026-05-20) GREI Re-arch GREI re-architecture-related SPA labels May 12, 2026
@coveralls

coveralls commented May 12, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 97.287% (-0.1%) from 97.389% — ManageGuestbook into develop

@ChengShi-1 ChengShi-1 added the Size: 10 A percentage of a sprint. 7 hours. label May 19, 2026
@ChengShi-1 ChengShi-1 marked this pull request as ready for review May 19, 2026 17:09
@ChengShi-1 ChengShi-1 moved this to Ready for Review ⏩ in IQSS Dataverse Project May 19, 2026
@cmbz cmbz added the FY26 Sprint 24 FY26 Sprint 24 (2026-05-20 - 2026-06-03) label May 21, 2026
@cmbz cmbz added the FY26 Sprint 25 FY26 Sprint 25 (2026-06-03 - 2026-06-17) label Jun 3, 2026
@ekraffmiller ekraffmiller moved this from Ready for Review ⏩ to In Review 🔎 in IQSS Dataverse Project Jun 9, 2026
@ekraffmiller ekraffmiller self-assigned this Jun 9, 2026

@ekraffmiller ekraffmiller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've suggested some name changes to match the Guestbook js-dataverse use cases, will review again after checkbox logic is updated :)

"position": "Cargo"
}
},
"customQuestions": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like the Spanish translation is missing some keys that are in the English translation

guestbookId: number,
enabled: boolean
) => Promise<void>
downloadGuestbookResponsesByDataverseId: (dataverseId: number | string) => Promise<string>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Update to use collectionId

Suggested change
downloadGuestbookResponsesByDataverseId: (dataverseId: number | string) => Promise<string>
downloadGuestbookResponsesByCollectionId: (collectionId: number | string) => Promise<string>

) => Promise<void>
downloadGuestbookResponsesByDataverseId: (dataverseId: number | string) => Promise<string>
downloadGuestbookResponsesOfAGuestbook: (
dataverseId: number | string,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
dataverseId: number | string,
collectionId: number | string,


export function downloadGuestbookResponsesByDataverseId(
guestbookRepository: GuestbookRepository,
dataverseId: number | string

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
dataverseId: number | string
collectionId: number | string


export function downloadGuestbookResponsesOfAGuestbook(
guestbookRepository: GuestbookRepository,
dataverseId: number | string,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
dataverseId: number | string,
collectionId: number | string,

Comment on lines +44 to +52
downloadGuestbookResponsesByDataverseId(dataverseId: number | string): Promise<string> {
return downloadGuestbookResponsesByDataverseId.execute(dataverseId)
}

downloadGuestbookResponsesOfAGuestbook(
dataverseId: number | string,
guestbookId: number
): Promise<string> {
return downloadGuestbookResponsesOfAGuestbook.execute(dataverseId, guestbookId)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
downloadGuestbookResponsesByDataverseId(dataverseId: number | string): Promise<string> {
return downloadGuestbookResponsesByDataverseId.execute(dataverseId)
}
downloadGuestbookResponsesOfAGuestbook(
dataverseId: number | string,
guestbookId: number
): Promise<string> {
return downloadGuestbookResponsesOfAGuestbook.execute(dataverseId, guestbookId)
downloadGuestbookResponsesByCollectionId(collectionId: number | string): Promise<string> {
return downloadGuestbookResponsesByCollectionId.execute(collectionId)
}
downloadGuestbookResponsesOfAGuestbook(
collectionId: number | string,
guestbookId: number
): Promise<string> {
return downloadGuestbookResponsesOfAGuestbook.execute(collectionId, guestbookId)

answers.push({
id: resolveAnswerId(fieldName, question, guestbook),
value
value: question.type === 'textarea' ? value.split(/\r?\n/) : value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

When the API is updated to take either a string or an array, we won't have to do this extra logic of converting the string to an array, but good to keep for now.

}
])
const guestbooksGuideUrl =
'https://guides.dataverse.org/en/6.9/user/dataverse-management.html#dataset-guestbooks'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
'https://guides.dataverse.org/en/6.9/user/dataverse-management.html#dataset-guestbooks'
'https://guides.dataverse.org/en/latest/user/dataverse-management.html#dataset-guestbooks'


const generalInfoUrl = `/spa${RouteWithParams.EDIT_COLLECTION(collectionId)}`
const guestbooksGuideUrl =
'https://guides.dataverse.org/en/6.9/user/dataverse-management.html#dataset-guestbooks'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
'https://guides.dataverse.org/en/6.9/user/dataverse-management.html#dataset-guestbooks'
'https://guides.dataverse.org/en/latest/user/dataverse-management.html#dataset-guestbooks'

})
const rootCollectionNames = collection?.hierarchy?.toArray().map((node) => node.name) ?? []

const currentDataverseId = Number(collection?.id) || 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
const currentDataverseId = Number(collection?.id) || 1
const currentCollectionId = Number(collection?.id) || 1

@ChengShi-1

Copy link
Copy Markdown
Contributor Author

Hi @ekraffmiller 👋 Thanks for your review! I’ve just made some changes based on the feedback.

While working on the changes for this PR, I noticed that we were also missing an API for deleting a guestbook. I've created an issue in Dataverse for this IQSS/dataverse#12453.

Also, in another issue IQSS/dataverse#12451, I added a comment about an additional requirement: including inherited guestbooks in the GetDataset API response. (Maybe it's better to create another issue for this? )

@ekraffmiller

Copy link
Copy Markdown
Contributor

Hi @ekraffmiller 👋 Thanks for your review! I’ve just made some changes based on the feedback.

While working on the changes for this PR, I noticed that we were also missing an API for deleting a guestbook. I've created an issue in Dataverse for this IQSS/dataverse#12453.

Also, in another issue IQSS/dataverse#12451, I added a comment about an additional requirement: including inherited guestbooks in the GetDataset API response. (Maybe it's better to create another issue for this? )

Hi @ChengShi-1, thanks for adding the issue for delete API, good catch. For the other issue, I don't think we need an API change. In the Edit Guestbook section on the Dataset Page, The list of Guestbooks comes from getGuestbooksByCollectionId, not from GetDataset. So since IQSS/dataverse#12451 adds a parameter to get inherited guestbooks, we can use that, unless I'm missing something?

@ChengShi-1

Copy link
Copy Markdown
Contributor Author

Hi @ekraffmiller 👋 Thanks for your review! I’ve just made some changes based on the feedback.
While working on the changes for this PR, I noticed that we were also missing an API for deleting a guestbook. I've created an issue in Dataverse for this IQSS/dataverse#12453.
Also, in another issue IQSS/dataverse#12451, I added a comment about an additional requirement: including inherited guestbooks in the GetDataset API response. (Maybe it's better to create another issue for this? )

Hi @ChengShi-1, thanks for adding the issue for delete API, good catch. For the other issue, I don't think we need an API change. In the Edit Guestbook section on the Dataset Page, The list of Guestbooks comes from getGuestbooksByCollectionId, not from GetDataset. So since IQSS/dataverse#12451 adds a parameter to get inherited guestbooks, we can use that, unless I'm missing something?
Hi @ekraffmiller ,
That API I mean is slightly different: on the Dataset Edit Guestbook page, we need to know whether the dataset’s parent collection has “Include Guestbooks from Parent Collections” enabled(the status of the checkbox shown in the screenshotbelow), so we know what value to pass as includeInherited when calling getGuestbooksByCollectionId.

image

Right now the frontend can only infer that with something like Boolean(dataset?.parentCollectionNode?.parent), in EditGuestbook.tsx which only tells us that a parent collection exists. It does not tell us whether inherited guestbooks are actually enabled for this dataset’s collection.
So I don’t think we need GetDataset to return the inherited guestbooks themselves, but we do need some API field exposing that setting. For example, it could also be something lie includeInheritedGuestbooks: boolean on the collection metadata, or on dataset.parentCollectionNode in GetDataset.

@ekraffmiller

Copy link
Copy Markdown
Contributor

Right now the frontend can only infer that with something like Boolean(dataset?.parentCollectionNode?.parent), in EditGuestbook.tsx which only tells us that a parent collection exists. It does not tell us whether inherited guestbooks are actually enabled for this dataset’s collection. So I don’t think we need GetDataset to return the inherited guestbooks themselves, but we do need some API field exposing that setting. For example, it could also be something lie includeInheritedGuestbooks: boolean on the collection metadata, or on dataset.parentCollectionNode in GetDataset.

Ok, I see what you mean! So yes, we need to save that in the Collection object. In the Dataverse backend, the field is "guestbookRoot". So we need an API specifically for getting/setting this value, or update the Collection object to include this field, and use the get/update collection use cases to manage it. I think it's worth adding a new issue to address this. Thanks for catching this!

@ChengShi-1

Copy link
Copy Markdown
Contributor Author

Right now the frontend can only infer that with something like Boolean(dataset?.parentCollectionNode?.parent), in EditGuestbook.tsx which only tells us that a parent collection exists. It does not tell us whether inherited guestbooks are actually enabled for this dataset’s collection. So I don’t think we need GetDataset to return the inherited guestbooks themselves, but we do need some API field exposing that setting. For example, it could also be something lie includeInheritedGuestbooks: boolean on the collection metadata, or on dataset.parentCollectionNode in GetDataset.

Ok, I see what you mean! So yes, we need to save that in the Collection object. In the Dataverse backend, the field is "guestbookRoot". So we need an API specifically for getting/setting this value, or update the Collection object to include this field, and use the get/update collection use cases to manage it. I think it's worth adding a new issue to address this. Thanks for catching this!

Thanks, it's really helpful! I just created an issue to track this: IQSS/dataverse#12459

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

FY26 Sprint 23 FY26 Sprint 23 (2026-05-06 - 2026-05-20) FY26 Sprint 24 FY26 Sprint 24 (2026-05-20 - 2026-06-03) FY26 Sprint 25 FY26 Sprint 25 (2026-06-03 - 2026-06-17) GREI Re-arch GREI re-architecture-related Size: 10 A percentage of a sprint. 7 hours. SPA

Projects

Status: In Review 🔎

Development

Successfully merging this pull request may close these issues.

Feature Request: Manage Guestbook integration

4 participants