diff --git a/src/app/[locale]/components/detail/[id]/components/ComponentGeneral.tsx b/src/app/[locale]/components/detail/[id]/components/ComponentGeneral.tsx index cb0f44bec..dc06871c9 100644 --- a/src/app/[locale]/components/detail/[id]/components/ComponentGeneral.tsx +++ b/src/app/[locale]/components/detail/[id]/components/ComponentGeneral.tsx @@ -8,7 +8,7 @@ // SPDX-License-Identifier: EPL-2.0 // License-Filename: LICENSE -"use client" +'use client' import styles from '../detail.module.css' import AdditionalData from '@/components/AdditionalData/AdditionalData' import { useState } from 'react' @@ -16,103 +16,137 @@ import ExternalIds from '@/components/ExternalIds/ExternalIds' import { FaCopy } from 'react-icons/fa' import { useTranslations } from 'next-intl' import { COMMON_NAMESPACE } from '@/object-types/Constants' +import Component from '@/object-types/Component' -const ComponentGeneral = ({ component, componentId }: any) => { - const t = useTranslations(COMMON_NAMESPACE); - const [toggle, setToggle] = useState(false); - return ( - - { setToggle(!toggle) }}> - - - - - - - - - - - - - - - - - - - - - - - - {(component.categories) && ( - - )} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{t('General')}
- ) +interface Props { + component: Component + componentId: string } -export default ComponentGeneral \ No newline at end of file +const ComponentGeneral = ({ component, componentId }: Props) => { + const t = useTranslations(COMMON_NAMESPACE) + const [toggle, setToggle] = useState(false) + return ( + + { + setToggle(!toggle) + }} + > + + + + + + + + + + + + + + + + + + + + + + + + {component.categories && } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{t('General')}
+ ) +} + +export default ComponentGeneral diff --git a/src/app/[locale]/components/detail/[id]/components/DeleteReleaseModal.tsx b/src/app/[locale]/components/detail/[id]/components/DeleteReleaseModal.tsx index bbf0e6029..405588335 100644 --- a/src/app/[locale]/components/detail/[id]/components/DeleteReleaseModal.tsx +++ b/src/app/[locale]/components/detail/[id]/components/DeleteReleaseModal.tsx @@ -23,8 +23,10 @@ import { useTranslations } from 'next-intl' import { COMMON_NAMESPACE } from '@/object-types/Constants' import ActionType from '@/object-types/enums/ActionType' import { useRouter } from 'next/navigation' +import { Session } from '@/object-types/Session' +import ReleaseDetail from '@/object-types/ReleaseDetail' -const DEFAULT_RELEASE_INFO: any = { name: '', version: '', _embedded: { 'sw360:attachments': [] } } +const DEFAULT_RELEASE_INFO: ReleaseDetail = { name: '', version: '', _embedded: { 'sw360:attachments': [] } } interface Props { componentId?: string @@ -34,8 +36,13 @@ interface Props { setShow?: React.Dispatch> } +interface DeleteResponse { + resourceId: string + status: number +} + const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow }: Props) => { - const { data: session }: any = useSession() + const { data: session } = useSession() as { data: Session } const t = useTranslations(COMMON_NAMESPACE) const [release, setRelease] = useState(DEFAULT_RELEASE_INFO) const [variant, setVariant] = useState('success') @@ -55,11 +62,11 @@ const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow setReloadPage(true) }, []) - const deleteComponent: any = async () => { + const deleteComponent = async () => { const response = await ApiUtils.DELETE(`releases/${releaseId}`, session.user.access_token) try { if (response.status == HttpStatus.MULTIPLE_STATUS) { - const body = await response.json() + const body = (await response.json()) as Array const deleteStatus = body[0].status if (deleteStatus == HttpStatus.OK) { displayMessage('success', 'Delete release success!') @@ -75,7 +82,7 @@ const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow displayMessage('danger', 'Error when processing!') } } else if (response.status == HttpStatus.UNAUTHORIZED) { - signOut() + handleError() } else { handleError() } @@ -84,15 +91,15 @@ const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow } } - const fetchData: any = useCallback( - async (signal: any) => { + const fetchData = useCallback( + async (signal: AbortSignal) => { if (session) { const releaseResponse = await ApiUtils.GET(`releases/${releaseId}`, session.user.access_token, signal) if (releaseResponse.status == HttpStatus.OK) { - const release = await releaseResponse.json() + const release = (await releaseResponse.json()) as ReleaseDetail setRelease(release) } else if (releaseResponse.status == HttpStatus.UNAUTHORIZED) { - signOut() + await signOut() } else { setRelease(DEFAULT_RELEASE_INFO) handleError() @@ -103,7 +110,7 @@ const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow ) const handleSubmit = () => { - deleteComponent() + deleteComponent().catch((err) => console.error(err)) } const handleCloseDialog = () => { @@ -119,7 +126,7 @@ const DeleteReleaseModal = ({ componentId, actionType, releaseId, show, setShow useEffect(() => { const controller = new AbortController() const signal = controller.signal - fetchData(signal) + fetchData(signal).catch((err) => console.error(err)) return () => { controller.abort() diff --git a/src/app/[locale]/components/detail/[id]/components/DetailOverview.tsx b/src/app/[locale]/components/detail/[id]/components/DetailOverview.tsx index 7f128207a..8906630f1 100644 --- a/src/app/[locale]/components/detail/[id]/components/DetailOverview.tsx +++ b/src/app/[locale]/components/detail/[id]/components/DetailOverview.tsx @@ -22,14 +22,15 @@ import ApiUtils from '@/utils/api/api.util' import { Session } from '@/object-types/Session' import HttpStatus from '@/object-types/enums/HttpStatus' import { signOut } from 'next-auth/react' -import { notFound } from 'next/navigation' import CommonUtils from '@/utils/common.utils' import { useTranslations } from 'next-intl' import { COMMON_NAMESPACE } from '@/object-types/Constants' -import { LinkedVulnerability } from '@/object-types/LinkedVulnerability' +import { LinkedVulnerability, EmbeddedVulnerabilites } from '@/object-types/LinkedVulnerability' import { SideBar, PageButtonHeader } from '@/components/sw360' import DocumentTypes from '@/object-types/enums/DocumentTypes' import DownloadService from '@/services/download.service' +import Component from '@/object-types/Component' +import { ChangeLog, EmbeddedChangeLogs } from '@/object-types/ChangeLogs' interface Props { session: Session @@ -64,21 +65,22 @@ const DetailOverview = ({ session, componentId }: Props) => { const [selectedTab, setSelectedTab] = useState(CommonTabIds.SUMMARY) const [changesLogTab, setChangesLogTab] = useState('list-change') const [changeLogIndex, setChangeLogIndex] = useState(-1) - const [component, setComponent] = useState(undefined) - const [changeLogList, setChangeLogList] = useState>([]) + const [component, setComponent] = useState(undefined) + const [changeLogList, setChangeLogList] = useState>([]) const [vulnerData, setVulnerData] = useState>([]) const [attachmentNumber, setAttachmentNumber] = useState(0) - const fetchData: any = useCallback( + const fetchData = useCallback( async (url: string) => { const response = await ApiUtils.GET(url, session.user.access_token) if (response.status == HttpStatus.OK) { - const data = await response.json() + const data = (await response.json()) as Component & EmbeddedVulnerabilites & EmbeddedChangeLogs return data } else if (response.status == HttpStatus.UNAUTHORIZED) { - signOut() + await signOut() + return undefined } else { - notFound() + return undefined } }, [session.user.access_token] @@ -86,38 +88,47 @@ const DetailOverview = ({ session, componentId }: Props) => { const downloadBundle = () => { DownloadService.download( - `${DocumentTypes.COMPONENT}/${componentId}/attachments/download`, session, 'AttachmentBundle.zip') + `${DocumentTypes.COMPONENT}/${componentId}/attachments/download`, + session, + 'AttachmentBundle.zip' + ) } useEffect(() => { - fetchData(`components/${componentId}`).then((component: any) => { - setComponent(component) - if ( - !CommonUtils.isNullOrUndefined(component['_embedded']) && - !CommonUtils.isNullOrUndefined(component['_embedded']['sw360:attachments']) - ) { - setAttachmentNumber(component['_embedded']['sw360:attachments'].length) - } - }) + fetchData(`components/${componentId}`) + .then((component: Component) => { + setComponent(component) + if ( + !CommonUtils.isNullOrUndefined(component['_embedded']) && + !CommonUtils.isNullOrUndefined(component['_embedded']['sw360:attachments']) + ) { + setAttachmentNumber(component['_embedded']['sw360:attachments'].length) + } + }) + .catch((err) => console.error(err)) - fetchData(`changelog/document/${componentId}`).then((changeLogs: any) => { - setChangeLogList( - CommonUtils.isNullOrUndefined(changeLogs['_embedded']['sw360:changeLogs']) - ? [] - : changeLogs['_embedded']['sw360:changeLogs'] - ) - }) + fetchData(`changelog/document/${componentId}`) + .then((changeLogs: EmbeddedChangeLogs) => { + setChangeLogList( + CommonUtils.isNullOrUndefined(changeLogs['_embedded']['sw360:changeLogs']) + ? [] + : changeLogs['_embedded']['sw360:changeLogs'] + ) + }) + .catch((err) => console.error(err)) - fetchData(`components/${componentId}/vulnerabilities`).then((data: any) => { - if ( - !CommonUtils.isNullOrUndefined(data['_embedded']) && - !CommonUtils.isNullOrUndefined(data['_embedded']['sw360:vulnerabilityDTOes']) - ) { - setVulnerData(data['_embedded']['sw360:vulnerabilityDTOes']) - } else { - setVulnerData([]) - } - }) + fetchData(`components/${componentId}/vulnerabilities`) + .then((data: EmbeddedVulnerabilites) => { + if ( + !CommonUtils.isNullOrUndefined(data['_embedded']) && + !CommonUtils.isNullOrUndefined(data['_embedded']['sw360:vulnerabilityDTOes']) + ) { + setVulnerData(data['_embedded']['sw360:vulnerabilityDTOes']) + } else { + setVulnerData([]) + } + }) + .catch((err) => console.error(err)) }, [componentId, fetchData]) const headerButtons = { @@ -187,13 +198,17 @@ const DetailOverview = ({ session, componentId }: Props) => {