diff --git a/src/app/[locale]/projects/components/DeleteProjectDialog.tsx b/src/app/[locale]/projects/components/DeleteProjectDialog.tsx index 58eb6e903..e075fb10e 100644 --- a/src/app/[locale]/projects/components/DeleteProjectDialog.tsx +++ b/src/app/[locale]/projects/components/DeleteProjectDialog.tsx @@ -10,24 +10,14 @@ 'use client' import { HttpStatus, Project } from '@/object-types' -import { ApiUtils } from '@/utils' -import { signOut, useSession } from 'next-auth/react' +import { ApiUtils, CommonUtils } from '@/utils' +import { signOut, getSession } from 'next-auth/react' import { useTranslations } from 'next-intl' import { useRouter } from 'next/navigation' -import { useCallback, useEffect, useState } from 'react' -import { Alert, Button, Form, Modal } from 'react-bootstrap' +import { ChangeEvent, useCallback, useEffect, useState } from 'react' +import { Alert, Button, Form, Modal, Spinner } from 'react-bootstrap' import { AiOutlineQuestionCircle } from 'react-icons/ai' -const DEFAULT_PROJECT_DATA: Project = { - name: '', - _embedded: { - 'sw360:releases': [], - 'sw360:projects': [], - 'sw360:attachments': [], - 'sw360:packages': [], - }, -} - interface Data { attachment?: number project?: number @@ -36,16 +26,15 @@ interface Data { } interface Props { - projectId?: string - show?: boolean - setShow?: React.Dispatch> + projectId: string + show: boolean + setShow: React.Dispatch> } -function DeleteProjectDialog ({ projectId, show, setShow }: Props) { - const { data: session } = useSession() +function DeleteProjectDialog ({ projectId, show, setShow }: Props): JSX.Element { const t = useTranslations('default') const router = useRouter() - const [project, setProject] = useState(DEFAULT_PROJECT_DATA) + const [project, setProject] = useState() const [internalData, setInternalData] = useState({ attachment: 0, project: 0, release: 0, package: 0 }) const [variant, setVariant] = useState('success') const [message, setMessage] = useState('') @@ -66,11 +55,12 @@ function DeleteProjectDialog ({ projectId, show, setShow }: Props) { }, [t]) const deleteProject = async () => { - if (CommonUtils.isNullEmptyOrUndefinedString(projectId)) - return - const response = await ApiUtils.DELETE(`projects/${projectId}`, session.user.access_token) try { - if (response.status == HttpStatus.OK) { + const session = await getSession() + if (CommonUtils.isNullOrUndefined(session)) + return + const response = await ApiUtils.DELETE(`projects/${projectId}`, session.user.access_token) + if (response.status === HttpStatus.OK) { displayMessage('success', t('Delete project successful!')) router.push('/projects') setReloadPage(true) @@ -90,27 +80,25 @@ function DeleteProjectDialog ({ projectId, show, setShow }: Props) { useEffect(() => { const fetchData = async (projectId: string) => { - if (CommonUtils.isNullEmptyOrUndefinedString(projectId)) + const session = await getSession() + if (CommonUtils.isNullOrUndefined(session)) return - if (session) { - const projectsResponse = await ApiUtils.GET(`projects/${projectId}`, session.user.access_token) - if (projectsResponse.status == HttpStatus.OK) { - const projectData = (await projectsResponse.json()) as Project - setProject(projectData) - handleInternalDataCount(projectData) - } else if (projectsResponse.status == HttpStatus.UNAUTHORIZED) { - await signOut() - } else { - setProject(DEFAULT_PROJECT_DATA) - handleError() - } + const projectsResponse = await ApiUtils.GET(`projects/${projectId}`, session.user.access_token) + if (projectsResponse.status == HttpStatus.OK) { + const projectData = (await projectsResponse.json()) as Project + setProject(projectData) + handleInternalDataCount(projectData) + } else if (projectsResponse.status == HttpStatus.UNAUTHORIZED) { + await signOut() + } else { + handleError() } } fetchData(projectId).catch((err) => { console.error(err) }) - }, [show, projectId, handleError, session]) + }, [show, projectId, handleError]) const handleSubmit = () => { deleteProject().catch((err) => { @@ -130,26 +118,26 @@ function DeleteProjectDialog ({ projectId, show, setShow }: Props) { const handleInternalDataCount = (projectData: Project) => { const dataCount: Data = {} - if (projectData._embedded['sw360:attachments']) { + if (projectData._embedded?.['sw360:attachments']) { dataCount.attachment = projectData._embedded['sw360:attachments'].length setVisuallyHideLinkedData(false) } - if (projectData._embedded['sw360:projects']) { + if (projectData._embedded?.['sw360:projects']) { dataCount.project = projectData._embedded['sw360:projects'].length setVisuallyHideLinkedData(false) } - if (projectData._embedded['sw360:releases']) { + if (projectData._embedded?.['sw360:releases']) { dataCount.release = projectData._embedded['sw360:releases'].length setVisuallyHideLinkedData(false) } - if (projectData._embedded['sw360:packages']) { + if (projectData._embedded?.['sw360:packages']) { dataCount.package = projectData._embedded['sw360:packages'].length setVisuallyHideLinkedData(false) } setInternalData(dataCount) } - const handleUserComment = (e: any) => { + const handleUserComment = (e: ChangeEvent) => { setComment(e.target.value) } @@ -162,42 +150,52 @@ function DeleteProjectDialog ({ projectId, show, setShow }: Props) { - setShowMessage(false)} dismissible show={showMessage}> - {message} - -
- - - {t.rich('Do you really want to delete the project?', { - name: project.name, - strong: (data) => {data}, - })} - -
- - {t.rich('This project contains', { - name: project.name, - strong: (data) => {data}, - visuallyHideLinkedData, - })} -
    - {Object.entries(internalData).map(([key, value]) => ( -
  • {`${value} linked ${key}`}
  • - ))} -
-
-
-
- - {t('Please comment your changes')} - - -
+ <> + { + project === undefined ? +
+ +
: + <> + setShowMessage(false)} dismissible show={showMessage}> + {message} + +
+ + + {t.rich('Do you really want to delete the project?', { + name: project.name, + strong: (data) => {data}, + })} + +
+ + {t.rich('This project contains', { + name: project.name, + strong: (data) => {data}, + visuallyHideLinkedData, + })} +
    + {Object.entries(internalData).map(([key, value]) => ( +
  • {`${value} linked ${key}`}
  • + ))} +
+
+
+
+ + {t('Please comment your changes')} + + +
+ + } +
diff --git a/src/app/[locale]/projects/detail/[id]/components/Changelog.tsx b/src/app/[locale]/projects/detail/[id]/components/Changelog.tsx index be44e6abc..b867d7caf 100644 --- a/src/app/[locale]/projects/detail/[id]/components/Changelog.tsx +++ b/src/app/[locale]/projects/detail/[id]/components/Changelog.tsx @@ -17,15 +17,17 @@ import { Nav, Tab } from 'react-bootstrap' import ChangeLogDetail from '@/components/ChangeLog/ChangeLogDetail/ChangeLogDetail' import ChangeLogList from '@/components/ChangeLog/ChangeLogList/ChangeLogList' -import { HttpStatus } from '@/object-types' +import { Changelogs, HttpStatus, Embedded } from '@/object-types' import { ApiUtils, CommonUtils } from '@/utils' +type EmbeddedChangeLogs = Embedded + function ChangeLog({ projectId, isCalledFromModerationRequestCurrentProject }: - { projectId: string, isCalledFromModerationRequestCurrentProject?: boolean }) { + { projectId: string, isCalledFromModerationRequestCurrentProject?: boolean }): JSX.Element { const t = useTranslations('default') const { data: session, status } = useSession() const [key, setKey] = useState('list-change') - const [changeLogList, setChangeLogList] = useState>([]) + const [changeLogList, setChangeLogList] = useState([]) const [changeLogIndex, setChangeLogIndex] = useState(-1) useEffect(() => { @@ -34,7 +36,7 @@ function ChangeLog({ projectId, isCalledFromModerationRequestCurrentProject }: const controller = new AbortController() const signal = controller.signal - ;(async () => { + void (async () => { try { const response = await ApiUtils.GET( `changelog/document/${projectId}`, @@ -47,7 +49,7 @@ function ChangeLog({ projectId, isCalledFromModerationRequestCurrentProject }: return notFound() } - const data = await response.json() + const data = await response.json() as EmbeddedChangeLogs setChangeLogList( CommonUtils.isNullOrUndefined(data['_embedded']['sw360:changeLogs']) @@ -64,7 +66,7 @@ function ChangeLog({ projectId, isCalledFromModerationRequestCurrentProject }: return ( <> - setKey(k)}> + setKey(k as string)}>