Dear Gitlab users, due to maintenance reasons, Gitlab will not be available on Thursday 30.09.2021 from 5:00 pm to approximately 5:30 pm.

Commit ff220f1c authored by Stefan Probst's avatar Stefan Probst
Browse files

fix: always get latest draft

parent b28a9410
Pipeline #207543 passed with stages
in 10 minutes and 40 seconds
......@@ -2,27 +2,48 @@ import { useRouter } from 'next/router'
import type { PropsWithChildren } from 'react'
import { Fragment, useEffect } from 'react'
import type { UserDto } from '@/api/sshoc'
import { useGetLoggedInUser } from '@/api/sshoc'
import { useAuth } from '@/modules/auth/AuthContext'
export default function ProtectedScreen({
children,
}: PropsWithChildren<unknown>): JSX.Element | null {
roles,
}: PropsWithChildren<{
roles?: Array<'contributor' | 'moderator' | 'administrator'>
}>): JSX.Element | null {
const router = useRouter()
const { session } = useAuth()
const user = useGetLoggedInUser(
{ enabled: session?.accessToken != null },
{ token: session?.accessToken },
)
useEffect(() => {
if (session === null) {
if (session === null || !hasAppropriateRole(roles, user.data)) {
router.replace({
pathname: '/auth/sign-in',
query: { from: router.asPath },
})
}
}, [session, router])
}, [roles, user.data, session, router])
/**
* avoid flash of content, because the router (for redirecting) is only available on the client
*/
if (session === null) return null
if (session === null || !hasAppropriateRole(roles, user.data)) return null
return <Fragment>{children}</Fragment>
}
function hasAppropriateRole(
roles?: Array<'contributor' | 'moderator' | 'administrator'>,
user?: UserDto,
) {
if (Array.isArray(roles)) {
const role = user?.role
if (role == null || !(roles as Array<string>).includes(role)) return false
}
return true
}
import ProtectedScreen from '@/modules/auth/ProtectedScreen'
import ActorsScreen from '@/screens/account/ActorsScreen'
/**
* Actors.
*/
export default function ActorsPage(): JSX.Element {
return (
<ProtectedScreen>
<ActorsScreen />
</ProtectedScreen>
)
}
import ProtectedScreen from '@/modules/auth/ProtectedScreen'
import ContributedItemsScreen from '@/screens/account/ContributedItemsScreen'
/**
* My contributed items.
*/
export default function ContributedItemsPage(): JSX.Element {
return (
<ProtectedScreen>
<ContributedItemsScreen />
</ProtectedScreen>
)
}
import ProtectedScreen from '@/modules/auth/ProtectedScreen'
import ModerateItemsScreen from '@/screens/account/ModerateItemsScreen'
/**
* Items to moderate.
*/
export default function ModerateItemsPage(): JSX.Element {
return (
<ProtectedScreen>
<ModerateItemsScreen />
</ProtectedScreen>
)
}
import ProtectedScreen from '@/modules/auth/ProtectedScreen'
import SourcesScreen from '@/screens/account/SourcesScreen'
/**
* Sources.
*/
export default function SourcesPage(): JSX.Element {
return (
<ProtectedScreen>
<SourcesScreen />
</ProtectedScreen>
)
}
import ProtectedScreen from '@/modules/auth/ProtectedScreen'
import UsersScreen from '@/screens/account/UsersScreen'
/**
* Users.
*/
export default function UsersPage(): JSX.Element {
return (
<ProtectedScreen roles={['administrator']}>
<UsersScreen />
</ProtectedScreen>
)
}
/**
* Actors screen.
*/
export default function ActorsScreen(): JSX.Element {
return <main>Actors (WIP)</main>
}
/**
* Contributed items screen.
*/
export default function ContributedItemsScreen(): JSX.Element {
return <main>Contributed items (WIP)</main>
}
/**
* Moderate items screen.
*/
export default function ModerateItemsScreen(): JSX.Element {
return <main>Moderate items (WIP)</main>
}
/**
* Sources screen.
*/
export default function SourcesScreen(): JSX.Element {
return <main>Sources (WIP)</main>
}
/**
* Users screen.
*/
export default function UsersScreen(): JSX.Element {
return <main>Users (WIP)</main>
}
import { useRouter } from 'next/router'
import { Fragment } from 'react'
import { useGetDatasetVersion } from '@/api/sshoc'
import { useGetDataset } from '@/api/sshoc'
import { convertToInitialFormValues } from '@/api/sshoc/helpers'
import { ItemForm } from '@/components/item/DatasetEditForm/DatasetEditForm'
import { ProgressSpinner } from '@/elements/ProgressSpinner/ProgressSpinner'
import { toast } from '@/elements/Toast/useToast'
import { useAuth } from '@/modules/auth/AuthContext'
import { useErrorHandlers } from '@/modules/error/useErrorHandlers'
import ContentColumn from '@/modules/layout/ContentColumn'
import GridLayout from '@/modules/layout/GridLayout'
import Metadata from '@/modules/metadata/Metadata'
......@@ -17,13 +19,38 @@ import { Title } from '@/modules/ui/typography/Title'
export default function DatasetDraftEditScreen(): JSX.Element {
const router = useRouter()
const auth = useAuth()
const handleError = useErrorHandlers()
const id = router.query.id as string
const draftId = Number(router.query.draftId)
const dataset = useGetDatasetVersion(
{ id, versionId: draftId },
const id = router.query.id as string | undefined
// const draftId = Number(router.query.draftId) as number | undefined
// const dataset = useGetDatasetVersion(
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// { id: id!, versionId: draftId! },
// {
// enabled:
// id != null && draftId != null && auth.session?.accessToken != null,
// },
// { token: auth.session?.accessToken },
// )
// FIXME: Event though the version history screen lists multiple drafts for an item
// we can actually only get one draft (the latest) by setting `?draft=true`.
// The version endpoint above does not work because it explicitly does
// not handles drafts (only returns them for admins).
const dataset = useGetDataset(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ id: id! },
{ draft: true },
{
enabled: auth.session?.accessToken != null,
enabled: id != null && auth.session?.accessToken != null,
onError(error) {
toast.error('Failed to fetch draft dataset')
router.push('/')
if (error instanceof Error) {
handleError(error)
}
},
},
{ token: auth.session?.accessToken },
)
......@@ -37,18 +64,10 @@ export default function DatasetDraftEditScreen(): JSX.Element {
style={{ gridColumn: '4 / span 8' }}
>
<Title>Edit dataset</Title>
{dataset.data === undefined ? (
{dataset.data === undefined || id == null ? (
<div className="flex flex-col items-center justify-center">
<ProgressSpinner />
</div>
) : dataset.data.status !== 'draft' ? (
// FIXME: check if this is actually the intened behavior
<div>
<p>
You cannot only edit draft items by diretly specifying a version
id.
</p>
</div>
) : (
<ItemForm
id={id}
......
import { useRouter } from 'next/router'
import { Fragment } from 'react'
import { useGetPublicationVersion } from '@/api/sshoc'
import { useGetPublication } from '@/api/sshoc'
import { convertToInitialFormValues } from '@/api/sshoc/helpers'
import { ItemForm } from '@/components/item/DatasetEditForm/DatasetEditForm'
import { ItemForm } from '@/components/item/PublicationEditForm/PublicationEditForm'
import { ProgressSpinner } from '@/elements/ProgressSpinner/ProgressSpinner'
import { toast } from '@/elements/Toast/useToast'
import { useAuth } from '@/modules/auth/AuthContext'
import { useErrorHandlers } from '@/modules/error/useErrorHandlers'
import ContentColumn from '@/modules/layout/ContentColumn'
import GridLayout from '@/modules/layout/GridLayout'
import Metadata from '@/modules/metadata/Metadata'
......@@ -17,44 +19,61 @@ import { Title } from '@/modules/ui/typography/Title'
export default function PublicationDraftEditScreen(): JSX.Element {
const router = useRouter()
const auth = useAuth()
const handleError = useErrorHandlers()
const id = router.query.id as string
const draftId = Number(router.query.draftId)
const dataset = useGetPublicationVersion(
{ id, versionId: draftId },
const id = router.query.id as string | undefined
// const draftId = Number(router.query.draftId) as number | undefined
// const publication = useGetPublicationVersion(
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// { id: id!, versionId: draftId! },
// {
// enabled:
// id != null && draftId != null && auth.session?.accessToken != null,
// },
// { token: auth.session?.accessToken },
// )
// FIXME: Event though the version history screen lists multiple drafts for an item
// we can actually only get one draft (the latest) by setting `?draft=true`.
// The version endpoint above does not work because it explicitly does
// not handles drafts (only returns them for admins).
const publication = useGetPublication(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ id: id! },
{ draft: true },
{
enabled: auth.session?.accessToken != null,
enabled: id != null && auth.session?.accessToken != null,
onError(error) {
toast.error('Failed to fetch draft publication')
router.push('/')
if (error instanceof Error) {
handleError(error)
}
},
},
{ token: auth.session?.accessToken },
)
return (
<Fragment>
<Metadata noindex title="Edit dataset" />
<Metadata noindex title="Edit publication" />
<GridLayout style={{ alignContent: 'stretch ' }}>
<ContentColumn
className="px-6 py-12 space-y-12"
style={{ gridColumn: '4 / span 8' }}
>
<Title>Edit dataset</Title>
{dataset.data === undefined ? (
<Title>Edit publication</Title>
{publication.data === undefined || id == null ? (
<div className="flex flex-col items-center justify-center">
<ProgressSpinner />
</div>
) : dataset.data.status !== 'draft' ? (
// FIXME: check if this is actually the intened behavior
<div>
<p>
You cannot only edit draft items by diretly specifying a version
id.
</p>
</div>
) : (
<ItemForm
id={id}
category="dataset"
initialValues={convertToInitialFormValues(dataset.data)}
item={dataset.data}
category="publication"
initialValues={convertToInitialFormValues(publication.data)}
item={publication.data}
/>
)}
</ContentColumn>
......
import { useRouter } from 'next/router'
import { Fragment } from 'react'
import { useGetToolVersion } from '@/api/sshoc'
import { useGetTool } from '@/api/sshoc'
import { convertToInitialFormValues } from '@/api/sshoc/helpers'
import { ItemForm } from '@/components/item/DatasetEditForm/DatasetEditForm'
import { ItemForm } from '@/components/item/ToolEditForm/ToolEditForm'
import { ProgressSpinner } from '@/elements/ProgressSpinner/ProgressSpinner'
import { toast } from '@/elements/Toast/useToast'
import { useAuth } from '@/modules/auth/AuthContext'
import { useErrorHandlers } from '@/modules/error/useErrorHandlers'
import ContentColumn from '@/modules/layout/ContentColumn'
import GridLayout from '@/modules/layout/GridLayout'
import Metadata from '@/modules/metadata/Metadata'
......@@ -17,44 +19,61 @@ import { Title } from '@/modules/ui/typography/Title'
export default function ToolDraftEditScreen(): JSX.Element {
const router = useRouter()
const auth = useAuth()
const handleError = useErrorHandlers()
const id = router.query.id as string
const draftId = Number(router.query.draftId)
const dataset = useGetToolVersion(
{ id, versionId: draftId },
const id = router.query.id as string | undefined
// const draftId = Number(router.query.draftId) as number | undefined
// const tool = useGetToolVersion(
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// { id: id!, versionId: draftId! },
// {
// enabled:
// id != null && draftId != null && auth.session?.accessToken != null,
// },
// { token: auth.session?.accessToken },
// )
// FIXME: Event though the version history screen lists multiple drafts for an item
// we can actually only get one draft (the latest) by setting `?draft=true`.
// The version endpoint above does not work because it explicitly does
// not handles drafts (only returns them for admins).
const tool = useGetTool(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ id: id! },
{ draft: true },
{
enabled: auth.session?.accessToken != null,
enabled: id != null && auth.session?.accessToken != null,
onError(error) {
toast.error('Failed to fetch draft tool')
router.push('/')
if (error instanceof Error) {
handleError(error)
}
},
},
{ token: auth.session?.accessToken },
)
return (
<Fragment>
<Metadata noindex title="Edit dataset" />
<Metadata noindex title="Edit tool" />
<GridLayout style={{ alignContent: 'stretch ' }}>
<ContentColumn
className="px-6 py-12 space-y-12"
style={{ gridColumn: '4 / span 8' }}
>
<Title>Edit dataset</Title>
{dataset.data === undefined ? (
<Title>Edit tool</Title>
{tool.data === undefined || id == null ? (
<div className="flex flex-col items-center justify-center">
<ProgressSpinner />
</div>
) : dataset.data.status !== 'draft' ? (
// FIXME: check if this is actually the intened behavior
<div>
<p>
You cannot only edit draft items by diretly specifying a version
id.
</p>
</div>
) : (
<ItemForm
id={id}
category="dataset"
initialValues={convertToInitialFormValues(dataset.data)}
item={dataset.data}
category="tool-or-service"
initialValues={convertToInitialFormValues(tool.data)}
item={tool.data}
/>
)}
</ContentColumn>
......
import { useRouter } from 'next/router'
import { Fragment } from 'react'
import { useGetTrainingMaterialVersion } from '@/api/sshoc'
import { useGetTrainingMaterial } from '@/api/sshoc'
import { convertToInitialFormValues } from '@/api/sshoc/helpers'
import { ItemForm } from '@/components/item/DatasetEditForm/DatasetEditForm'
import { ItemForm } from '@/components/item/TrainingMaterialEditForm/TrainingMaterialEditForm'
import { ProgressSpinner } from '@/elements/ProgressSpinner/ProgressSpinner'
import { toast } from '@/elements/Toast/useToast'
import { useAuth } from '@/modules/auth/AuthContext'
import { useErrorHandlers } from '@/modules/error/useErrorHandlers'
import ContentColumn from '@/modules/layout/ContentColumn'
import GridLayout from '@/modules/layout/GridLayout'
import Metadata from '@/modules/metadata/Metadata'
......@@ -17,44 +19,61 @@ import { Title } from '@/modules/ui/typography/Title'
export default function TrainingMaterialDraftEditScreen(): JSX.Element {
const router = useRouter()
const auth = useAuth()
const handleError = useErrorHandlers()
const id = router.query.id as string
const draftId = Number(router.query.draftId)
const dataset = useGetTrainingMaterialVersion(
{ id, versionId: draftId },
const id = router.query.id as string | undefined
// const draftId = Number(router.query.draftId) as number | undefined
// const trainingMaterial = useGetTrainingMaterialVersion(
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// { id: id!, versionId: draftId! },
// {
// enabled:
// id != null && draftId != null && auth.session?.accessToken != null,
// },
// { token: auth.session?.accessToken },
// )
// FIXME: Event though the version history screen lists multiple drafts for an item
// we can actually only get one draft (the latest) by setting `?draft=true`.
// The version endpoint above does not work because it explicitly does
// not handles drafts (only returns them for admins).
const trainingMaterial = useGetTrainingMaterial(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ id: id! },
{ draft: true },
{
enabled: auth.session?.accessToken != null,
enabled: id != null && auth.session?.accessToken != null,
onError(error) {
toast.error('Failed to fetch draft trainingMaterial')
router.push('/')
if (error instanceof Error) {
handleError(error)
}
},
},
{ token: auth.session?.accessToken },
)
return (
<Fragment>
<Metadata noindex title="Edit dataset" />
<Metadata noindex title="Edit trainingMaterial" />
<GridLayout style={{ alignContent: 'stretch ' }}>
<ContentColumn
className="px-6 py-12 space-y-12"
style={{ gridColumn: '4 / span 8' }}
>
<Title>Edit dataset</Title>
{dataset.data === undefined ? (
<Title>Edit training material</Title>
{trainingMaterial.data === undefined || id == null ? (
<div className="flex flex-col items-center justify-center">
<ProgressSpinner />
</div>
) : dataset.data.status !== 'draft' ? (
// FIXME: check if this is actually the intened behavior
<div>
<p>
You cannot only edit draft items by diretly specifying a version
id.
</p>
</div>
) : (
<ItemForm
id={id}
category="dataset"
initialValues={convertToInitialFormValues(dataset.data)}
item={dataset.data}
category="training-material"
initialValues={convertToInitialFormValues(trainingMaterial.data)}
item={trainingMaterial.data}
/>
)}
</ContentColumn>
......
import { useRouter } from 'next/router'
import { Fragment } from 'react'
import { useGetWorkflowVersion } from '@/api/sshoc'
import { useGetWorkflow } from '@/api/sshoc'
import { convertToInitialFormValues } from '@/api/sshoc/helpers'
import { ItemForm } from '@/components/item/DatasetEditForm/DatasetEditForm'
import { ItemForm } from '@/components/item/WorkflowEditForm/WorkflowEditForm'
import { ProgressSpinner } from '@/elements/ProgressSpinner/ProgressSpinner'
import { toast } from '@/elements/Toast/useToast'
import { useAuth } from '@/modules/auth/AuthContext'
import { useErrorHandlers } from '@/modules/error/useErrorHandlers'
import ContentColumn from '@/modules/layout/ContentColumn'
import GridLayout from '@/modules/layout/GridLayout'
import Metadata from '@/modules/metadata/Metadata'
......@@ -17,44 +19,61 @@ import { Title } from '@/modules/ui/typography/Title'
export default function WorkflowDraftEditScreen(): JSX.Element {
const router = useRouter()
const auth = useAuth()
const handleError = useErrorHandlers()
const id = router.query.id as string
const draftId = Number(router.query.draftId)
const dataset = useGetWorkflowVersion(
{ workflowId: id, versionId: draftId },
const id = router.query.id as string | undefined
// const draftId = Number(router.query.draftId) as number | undefined
// const workflow = useGetWorkflowVersion(
// // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
// { workflowId: id!, versionId: draftId! },
// {
// enabled:
// id != null && draftId != null && auth.session?.accessToken != null,
// },
// { token: auth.session?.accessToken },
// )
// FIXME: Event though the version history screen lists multiple drafts for an item
// we can actually only get one draft (the latest) by setting `?draft=true`.
// The version endpoint above does not work because it explicitly does
// not handles drafts (only returns them for admins).
const workflow = useGetWorkflow(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
{ workflowId: id! },
{ draft: true },
{
enabled: auth.session?.accessToken != null,
enabled: id != null && auth.session?.accessToken != null,
onError(error) {
toast.error('Failed to fetch draft workflow')