/******************************************************************************** * Copyright (c) 2020 TypeFox and others * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 ********************************************************************************/ import type { MouseEvent, ReactNode } from "react"; import { useContext, FunctionComponent, useState, useEffect, useRef } from 'react'; import { Extension } from '../../extension-registry-types'; import { Paper, Typography, Box, styled, IconButton } from '@mui/material'; import { Link as RouteLink, useNavigate } from 'react-router-dom'; import { MainContext } from '../../context'; import { createRoute } from '../../utils'; import { Timestamp } from '../../components/timestamp'; import { ExtensionDetailRoutes } from '../extension-detail/extension-detail-routes'; import DeleteIcon from '@mui/icons-material/Delete'; import { UserSettingsRoutes } from './user-settings-routes'; const getOpacity = (extension: Extension) => { if (extension.deprecated) { return 0.5; } else if (extension.active === false) { return 0.75; } else { return 1; } }; const noOverflow = { whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', ml: 0.5 }; const Paragraph = styled(Box)({ display: 'flex', justifyContent: 'space-between', }); export const UserNamespaceExtensionListItem: FunctionComponent = props => { const { pageSettings, service } = useContext(MainContext); const [icon, setIcon] = useState(undefined); const { extension } = props; const route = extension && createRoute([ExtensionDetailRoutes.ROOT, extension.namespace, extension.name]) || ''; const deleteRoute = extension && createRoute([UserSettingsRoutes.EXTENSIONS, extension.namespace, extension.name, 'delete']) || ''; const inactive = extension.active === false; const abortController = useRef(new AbortController()); const navigate = useNavigate(); useEffect(() => { return () => { abortController.current.abort(); }; }, []); useEffect(() => { if (icon) { URL.revokeObjectURL(icon); } service.getExtensionIcon(abortController.current, extension).then(setIcon); }, [extension]); const renderStatus = (): ReactNode => { if (extension.reviewStatus === 'under_review') { return Under review {extension.reviewMessage ?? 'Your extension is being reviewed. Please contact support for details.'} ; } if (extension.reviewStatus === 'rejected') { return Rejected {extension.reviewMessage ?? 'Your extension could not be published.'} ; } if (inactive) { return Deactivated ; } if (extension.timestamp) { return Published: ; } return null; }; const status = renderStatus(); const gotoDeleteRoute = (e: MouseEvent) => { e.preventDefault(); navigate(deleteRoute); }; return ( extension ? ( {extension.displayName ?? extension.name} {props.canDelete && deleteRoute && } Version: {extension.version} {status} ) : null ); }; export interface UserNamespaceExtensionListItemProps { extension: Extension; canDelete?: boolean }