Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
### Added

- Manage Guestbooks page integration, including:
- a guestbooks table with sorting, enable/disable actions, preview, and per-guestbook response download
- a guestbooks table with sorting, edit, enable/disable actions, preview, and per-guestbook response download
- Create Guestbook and Download All Responses actions
- the Create Guestbook page
- the Create and Edit Guestbook pages
- a checkbox for including guestbooks from parent collections
Comment thread
ChengShi-1 marked this conversation as resolved.
- Dataset Templates UI integration, including create/edit flows, previews, and skeleton states.

Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@dnd-kit/sortable": "8.0.0",
"@dnd-kit/utilities": "3.2.2",
"@faker-js/faker": "7.6.0",
"@iqss/dataverse-client-javascript": "v2.2.0-alpha.9",
"@iqss/dataverse-client-javascript": "2.2.0-alpha.11",
"@iqss/dataverse-design-system": "*",
"@istanbuljs/nyc-config-typescript": "1.0.2",
"@tanstack/react-table": "8.9.2",
Expand Down
2 changes: 1 addition & 1 deletion public/locales/en/datasetTemplates.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"create": "Create Dataset Template",
"makeDefault": "Make Default",
"default": "Default",
"view": "View",
"view": "Preview",
"copy": "Copy",
"edit": "Edit Template",
"delete": "Delete",
Comment thread
ChengShi-1 marked this conversation as resolved.
Expand Down
28 changes: 26 additions & 2 deletions public/locales/en/guestbooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@
"enable": "Enable",
"disable": "Disable",
"downloadAllResponses": "Download All Responses",
"view": "View",
"view": "Preview",
"copy": "Copy",
"edit": "Edit",
"delete": "Delete",
"downloadResponses": "Download responses",
"viewResponses": "View Responses"
},
"errors": {
"getGuestbook": "Something went wrong getting the guestbook. Try again later.",
"editGuestbook": "Something went wrong editing the guestbook. Try again later.",
"getGuestbookResponses": "Something went wrong getting guestbook responses. Try again later.",
"toggleEnabled": "Something went wrong updating the guestbook status. Try again later.",
"downloadResponses": "Something went wrong downloading guestbook responses. Try again later."
},
"alerts": {
"statusUpdated": "The guestbook status has been updated.",
"downloadStarted": "Your download has started."
"downloadStarted": "Your download has started.",
"updated": "The guestbook has been updated."
},
"preview": {
"title": "Preview Guestbook",
Expand Down Expand Up @@ -94,5 +98,25 @@
},
"submit": "Create Dataset Guestbook",
"cancel": "Cancel"
},
"edit": {
"title": "Edit Dataset Guestbook"
},
"responses": {
"title": "Guestbook Responses",
"info": "Click \"Download Responses\" to download all collected responses for this guestbook, as a CSV file. To navigate and analyze your collected responses, we recommend importing this CSV file into Excel, Google Sheets or similar software.",
"guestbookName": "Guestbook Name",
"downloadButton": "Download Responses",
"count_one": "{{count}} Response",
"count_other": "{{count}} Responses",
"noRecords": "No records found.",
"table": {
"dataset": "Dataset",
"date": "Date",
"type": "Type",
"file": "File",
"user": "User",
"customQuestions": "Custom Questions"
}
}
}
28 changes: 26 additions & 2 deletions public/locales/es/guestbooks.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@
"enable": "Habilitar",
"disable": "Deshabilitar",
"downloadAllResponses": "Descargar todas las respuestas",
"view": "Ver",
"view": "Vista previa",
"copy": "Copiar",
"edit": "Editar",
"delete": "Eliminar",
"downloadResponses": "Descargar respuestas",
"viewResponses": "Ver respuestas"
},
"errors": {
"getGuestbook": "Algo salió mal al obtener el libro de visitas. Inténtalo de nuevo más tarde.",
"editGuestbook": "Algo salió mal al editar el libro de visitas. Inténtalo de nuevo más tarde.",
"getGuestbookResponses": "Algo salió mal al obtener las respuestas del libro de visitas. Inténtalo de nuevo más tarde.",
"toggleEnabled": "Algo salió mal al actualizar el estado del libro de visitas. Inténtalo de nuevo más tarde.",
"downloadResponses": "Algo salió mal al descargar las respuestas del libro de visitas. Inténtalo de nuevo más tarde."
},
"alerts": {
"statusUpdated": "El estado del libro de visitas se ha actualizado.",
"downloadStarted": "La descarga ha comenzado."
"downloadStarted": "La descarga ha comenzado.",
"updated": "El libro de visitas se ha actualizado."
},
"preview": {
"title": "Vista previa del libro de visitas",
Expand Down Expand Up @@ -94,5 +98,25 @@
},
"submit": "Crear libro de visitas del dataset",
"cancel": "Cancelar"
},
"edit": {
"title": "Editar libro de visitas del dataset"
},
"responses": {
"title": "Respuestas del libro de visitas",
"info": "Haz clic en \"Descargar respuestas\" para descargar todas las respuestas recopiladas para este libro de visitas como archivo CSV. Para navegar y analizar las respuestas recopiladas, recomendamos importar este archivo CSV en Excel, Google Sheets o software similar.",
"guestbookName": "Nombre del libro de visitas",
"downloadButton": "Descargar respuestas",
"count_one": "{{count}} respuesta",
"count_other": "{{count}} respuestas",
"noRecords": "No se encontraron registros.",
"table": {
"dataset": "Dataset",
"date": "Fecha",
"type": "Tipo",
"file": "Fichero",
"user": "Usuario",
"customQuestions": "Preguntas personalizadas"
}
}
}
3 changes: 2 additions & 1 deletion src/guestbooks/domain/models/Guestbook.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
export type GuestbookQuestionType = 'text' | 'textarea' | 'options'

export interface GuestbookOption {
id?: number
value: string
displayOrder: number
}

export interface GuestbookCustomQuestion {
id?: number | string
id?: number
question: string
required: boolean
displayOrder: number
Expand Down
6 changes: 3 additions & 3 deletions src/guestbooks/domain/models/GuestbookResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ export interface GuestbookResponse {
datasetPid: string
date: string
type: EventType
fileName?: string
email?: string
fileId?: number
fileName?: string
filePid?: string
userName: string
email?: string
institution?: string
position?: string
userName: string
customQuestions?: GuestbookResponseCustomQuestion[]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { PaginationInfo } from '@/shared/pagination/domain/models/PaginationInfo'

export class GuestbookResponsesPaginationInfo extends PaginationInfo<GuestbookResponsesPaginationInfo> {
constructor(page = 1, pageSize = 10, totalItems = 0, itemName = 'Response') {
super(page, pageSize, totalItems, itemName)
}
}
5 changes: 3 additions & 2 deletions src/guestbooks/domain/repositories/GuestbookRepository.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { type CreateGuestbookDTO } from '@iqss/dataverse-client-javascript'
import { GuestbookDTO } from '../useCases/DTOs/GuestbookDTO'
import { Guestbook } from '../models/Guestbook'
import { GuestbookResponseSubset } from '../models/GuestbookResponse'

export interface GuestbookRepository {
createGuestbook: (
collectionIdOrAlias: number | string,
guestbook: CreateGuestbookDTO
guestbook: GuestbookDTO
) => Promise<number>
editGuestbook: (guestbookId: number, guestbook: GuestbookDTO) => Promise<void>
getGuestbook: (guestbookId: number) => Promise<Guestbook>
getGuestbooksByCollectionId: (
collectionIdOrAlias: number | string,
Expand Down
28 changes: 28 additions & 0 deletions src/guestbooks/domain/useCases/DTOs/GuestbookDTO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { GuestbookQuestionType } from '../../models/Guestbook'

export interface GuestbookDTO {
name: string
enabled: boolean
emailRequired: boolean
nameRequired: boolean
institutionRequired: boolean
positionRequired: boolean
createTime?: string
customQuestions?: GuestbookCustomQuestionDTO[]
}

export interface GuestbookCustomQuestionDTO {
id?: number
question: string
required: boolean
displayOrder: number
type: GuestbookQuestionType
hidden: boolean
optionValues?: GuestbookOptionDTO[]
}

export interface GuestbookOptionDTO {
id?: number
value: string
displayOrder: number
}
4 changes: 2 additions & 2 deletions src/guestbooks/domain/useCases/createGuestbook.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { type CreateGuestbookDTO } from '@iqss/dataverse-client-javascript'
import { GuestbookRepository } from '../repositories/GuestbookRepository'
import { GuestbookDTO } from './DTOs/GuestbookDTO'

export function createGuestbook(
guestbookRepository: GuestbookRepository,
collectionIdOrAlias: number | string,
guestbook: CreateGuestbookDTO
guestbook: GuestbookDTO
): Promise<number> {
return guestbookRepository.createGuestbook(collectionIdOrAlias, guestbook)
}
10 changes: 10 additions & 0 deletions src/guestbooks/domain/useCases/editGuestbook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GuestbookRepository } from '../repositories/GuestbookRepository'
import { GuestbookDTO } from './DTOs/GuestbookDTO'

export function editGuestbook(
guestbookRepository: GuestbookRepository,
guestbookId: number,
guestbook: GuestbookDTO
): Promise<void> {
return guestbookRepository.editGuestbook(guestbookId, guestbook)
}
15 changes: 15 additions & 0 deletions src/guestbooks/domain/useCases/getGuestbooksByCollectionId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Guestbook } from '../models/Guestbook'
import { GuestbookRepository } from '../repositories/GuestbookRepository'

export function getGuestbooksByCollectionId(
guestbookRepository: GuestbookRepository,
collectionIdOrAlias: number | string,
includeStats?: boolean,
includeInherited?: boolean
): Promise<Guestbook[]> {
return guestbookRepository.getGuestbooksByCollectionId(
collectionIdOrAlias,
includeStats,
includeInherited
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import {
createGuestbook,
downloadGuestbookResponsesByCollectionId,
downloadGuestbookResponsesOfAGuestbook as downloadGuestbookResponsesByGuestbookId,
type CreateGuestbookDTO,
type CreateGuestbookDTO as JSDataverseCreateGuestbookDTO,
editGuestbook,
type EditGuestbookDTO as JSDataverseEditGuestbookDTO,
type GuestbookResponseSubset,
getGuestbooksByCollectionId,
getGuestbook,
Expand All @@ -13,17 +15,26 @@ import {
} from '@iqss/dataverse-client-javascript'
import { GuestbookRepository } from '../../domain/repositories/GuestbookRepository'
import { Guestbook } from '../../domain/models/Guestbook'
import { GuestbookDTO } from '../../domain/useCases/DTOs/GuestbookDTO'

const normalizeGuestbook = (guestbook: Guestbook): Guestbook => ({
...guestbook,
customQuestions: guestbook.customQuestions ?? []
})

export class GuestbookJSDataverseRepository implements GuestbookRepository {
createGuestbook(
collectionIdOrAlias: number | string,
guestbook: CreateGuestbookDTO
): Promise<number> {
return createGuestbook.execute(guestbook, collectionIdOrAlias)
createGuestbook(collectionIdOrAlias: number | string, guestbook: GuestbookDTO): Promise<number> {
return createGuestbook.execute(guestbook as JSDataverseCreateGuestbookDTO, collectionIdOrAlias)
}

editGuestbook(guestbookId: number, guestbook: GuestbookDTO): Promise<void> {
return editGuestbook.execute(guestbookId, guestbook as JSDataverseEditGuestbookDTO)
}

getGuestbook(guestbookId: number): Promise<Guestbook> {
return getGuestbook.execute(guestbookId).then((guestbook) => guestbook as Guestbook)
return getGuestbook
.execute(guestbookId)
.then((guestbook) => normalizeGuestbook(guestbook as Guestbook))
}

getGuestbooksByCollectionId(
Expand All @@ -33,7 +44,7 @@ export class GuestbookJSDataverseRepository implements GuestbookRepository {
): Promise<Guestbook[]> {
return getGuestbooksByCollectionId
.execute(collectionIdOrAlias, includeStats, includeInherited)
.then((guestbooks) => guestbooks as Guestbook[])
.then((guestbooks) => (guestbooks as Guestbook[]).map(normalizeGuestbook))
}

getGuestbookResponsesByGuestbookId(
Expand Down
34 changes: 34 additions & 0 deletions src/router/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,22 @@ const CreateGuestbookPage = lazy(() =>
)
)

const EditGuestbookPage = lazy(() =>
import('../sections/guestbooks/edit-guestbook/EditGuestbookFactory').then(
({ EditGuestbookFactory }) => ({
default: () => EditGuestbookFactory.create()
})
)
)

const GuestbookResponsesPage = lazy(() =>
import('../sections/guestbooks/view-responses/GuestbookResponsesFactory').then(
({ GuestbookResponsesFactory }) => ({
default: () => GuestbookResponsesFactory.create()
})
)
)

const NotFoundPage = lazy(() =>
import('../sections/not-found-page/NotFoundPageFactory').then(({ NotFoundPageFactory }) => ({
default: () => NotFoundPageFactory.create()
Expand Down Expand Up @@ -356,6 +372,24 @@ export const routes: RouteObject[] = [
),
errorElement: <ErrorPage />
},
{
path: Route.GUESTBOOKS_EDIT,
element: (
<Suspense fallback={<GuestbookSkeleton />}>
<EditGuestbookPage />
</Suspense>
),
errorElement: <ErrorPage />
},
{
path: Route.GUESTBOOKS_RESPONSES,
element: (
<Suspense fallback={<GuestbookSkeleton />}>
<GuestbookResponsesPage />
</Suspense>
),
errorElement: <ErrorPage />
},
{
path: Route.TEMPLATES_CREATE,
element: (
Expand Down
Loading
Loading