/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ import { Alert, Col, Modal, Row, Space, Spin, Table, Tabs, TabsProps, Tag, Typography } from 'antd'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import React, { FC, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useRequest } from '../api-client'; import { useStyles } from './style'; import { IPluginData } from './types'; dayjs.extend(relativeTime); type Author = | string | { name: string; email?: string; url?: string; }; interface PackageJSON { name: string; version: string; description?: string; repository?: string | { type: string; url: string }; homepage?: string; license?: string; author?: Author; devDependencies?: Record; dependencies?: Record; } interface DepCompatible { name: string; result: boolean; versionRange: string; packageVersion: string; } interface IPluginDetailData { packageJson: PackageJSON; homepage?: string; depsCompatible: DepCompatible[] | false; lastUpdated: string; } interface IPluginDetail { plugin: IPluginData; onCancel: () => void; } export const PluginDetail: FC = ({ plugin, onCancel }) => { const { t } = useTranslation(); const dependenciesCompatibleTableColumns = useMemo( () => [ { title: t('Name'), dataIndex: 'name', key: 'name', }, { title: t('Version range'), dataIndex: 'versionRange', key: 'versionRange', }, { title: t("Plugin's version"), dataIndex: 'packageVersion', key: 'packageVersion', }, { title: t('Result'), dataIndex: 'result', key: 'result', render: (result: boolean) => {result ? 'Yes' : 'No'}, }, ], [t], ); const { data, loading } = useRequest<{ data: IPluginDetailData }>( { url: `pm:get`, params: { filterByTk: plugin.name, }, }, { refreshDeps: [plugin.name], ready: !!plugin.name, }, ); const repository = useMemo(() => { if (!data?.data?.packageJson?.repository) return null; const repository = data?.data?.packageJson.repository; const url = typeof repository === 'string' ? repository : repository.url; return url.replace(/\.git$/, '').replace(/^git\+/, ''); }, [data]); const author = useMemo(() => { const author = data?.data?.packageJson.author; if (!author) return null; if (typeof author === 'string') return author; return author.name; }, [data]); const { styles, theme } = useStyles(); const tabItems: TabsProps['items'] = [ { key: 'readme', label: t('Readme'), children: ( {plugin.name && (
{t('Name')} {plugin.name}
)} {plugin.displayName && (
{t('DisplayName')} {plugin.displayName}
)}
{t('PackageName')} {plugin.packageName}
{repository && (
{t('Repository')} {repository}
)} {data?.data?.homepage && (
{t('Homepage')} {data?.data?.homepage}
)} {plugin.description && (
{t('Description')} {plugin.description}
)} {data?.data?.packageJson.license && (
{t('License')} {data?.data?.packageJson.license}
)} {author && (
{t('Author')} {author}
)}
{t('Version')} {plugin?.version}
), }, { key: 'dependencies', label: t('Dependencies compatibility check'), children: ( <> {data?.data?.depsCompatible === false ? ( {t('`dist/externalVersion.js` not found or failed to `require`. Please rebuild this plugin.')} ) : ( <> {!data?.data?.['isCompatible'] && ( )} )} ), }, // { // key: 'changelog', // label: t('Changelog'), // children: plugin?.changelogUrl ? : t('No CHANGELOG.md file'), // }, ]; return ( {loading ? ( ) : ( plugin && ( <> {plugin.packageName}  • }> {plugin.version} ) )} ); };