From 7fec4a928f4b3a1274d5e16336f2d7f4117958a5 Mon Sep 17 00:00:00 2001 From: NFish Date: Tue, 10 Jun 2025 15:37:41 +0800 Subject: [PATCH] wip: plugin install item supports show limited message --- web/app/components/plugins/card/index.tsx | 59 +++++++++++-------- .../hooks/use-install-plugin-limit.tsx | 9 ++- .../install-bundle/item/loaded-item.tsx | 4 ++ .../steps/install.tsx | 2 +- 4 files changed, 46 insertions(+), 28 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 7f7cc79021..bdb3705f6f 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -15,6 +15,7 @@ import { renderI18nObject } from '@/i18n' import { useMixedTranslation } from '@/app/components/plugins/marketplace/hooks' import Partner from '../base/badges/partner' import Verified from '../base/badges/verified' +import { RiAlertFill } from '@remixicon/react' export type Props = { className?: string @@ -28,7 +29,7 @@ export type Props = { isLoading?: boolean loadingFileName?: string locale?: string - showLimitWarning?: boolean + limitedInstall?: boolean } const Card = ({ @@ -43,7 +44,7 @@ const Card = ({ isLoading = false, loadingFileName, locale: localeFromProps, - showLimitWarning = false, + limitedInstall = false, }: Props) => { const defaultLocale = useGetLanguage() const locale = localeFromProps ? getLanguage(localeFromProps) : defaultLocale @@ -56,7 +57,7 @@ const Card = ({ obj ? renderI18nObject(obj, locale) : '' const isPartner = badges.includes('partner') - const wrapClassName = cn('hover-bg-components-panel-on-panel-item-bg relative rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg p-4 pb-3 shadow-xs', className) + const wrapClassName = cn('hover-bg-components-panel-on-panel-item-bg relative overflow-hidden rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs', className) if (isLoading) { return ( - {!hideCornerMark && } - {/* Header */} -
- -
-
- - {isPartner && <Partner className='ml-0.5 h-4 w-4' text={t('plugin.marketplace.partnerTip')} />} - {verified && <Verified className='ml-0.5 h-4 w-4' text={t('plugin.marketplace.verifiedTip')} />} - {titleLeft} {/* This can be version badge */} + <div className={cn('p-4 pb-3', limitedInstall && 'pb-1')}> + {!hideCornerMark && <CornerMark text={cornerMark} />} + {/* Header */} + <div className="flex"> + <Icon src={icon} installed={installed} installFailed={installFailed} /> + <div className="ml-3 w-0 grow"> + <div className="flex h-5 items-center"> + <Title title={getLocalizedText(label)} /> + {isPartner && <Partner className='ml-0.5 h-4 w-4' text={t('plugin.marketplace.partnerTip')} />} + {verified && <Verified className='ml-0.5 h-4 w-4' text={t('plugin.marketplace.verifiedTip')} />} + {titleLeft} {/* This can be version badge */} + </div> + <OrgInfo + className="mt-0.5" + orgName={org} + packageName={name} + /> </div> - <OrgInfo - className="mt-0.5" - orgName={org} - packageName={name} - /> </div> + <Description + className="mt-3" + text={getLocalizedText(brief)} + descriptionLineRows={descriptionLineRows} + /> + {footer && <div>{footer}</div>} </div> - <Description - className="mt-3" - text={getLocalizedText(brief)} - descriptionLineRows={descriptionLineRows} - /> - {showLimitWarning && <div>{t('plugin.installModal.installWarning')}</div>} - {footer && <div>{footer}</div>} + {limitedInstall + && <div className='relative flex h-8 items-center gap-x-2 px-3 after:absolute after:bottom-0 after:left-0 after:right-0 after:top-0 after:bg-toast-warning-bg after:opacity-40'> + <RiAlertFill className='h-3 w-3 shrink-0 text-text-warning-secondary' /> + <p className='system-xs-regular z-10 grow text-text-secondary'> + {t('plugin.installModal.installWarning')} + </p> + </div>} </div> ) } diff --git a/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx b/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx index 6618dceb91..1f91efc3af 100644 --- a/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx +++ b/web/app/components/plugins/install-plugin/hooks/use-install-plugin-limit.tsx @@ -1,9 +1,9 @@ import { useGlobalPublicStore } from '@/context/global-public-context' +import type { SystemFeatures } from '@/types/feature' import { InstallationScope } from '@/types/feature' import type { Plugin, PluginManifestInMarket } from '../../types' -export default function usePluginInstallLimit(plugin: Plugin | PluginManifestInMarket) { - const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) +export function pluginInstallLimit(plugin: Plugin | PluginManifestInMarket, systemFeatures: SystemFeatures) { if (systemFeatures.plugin_installation_permission.restrict_to_marketplace_only) { return { canInstall: false } } @@ -37,3 +37,8 @@ export default function usePluginInstallLimit(plugin: Plugin | PluginManifestInM } } } + +export default function usePluginInstallLimit(plugin: Plugin | PluginManifestInMarket) { + const systemFeatures = useGlobalPublicStore(s => s.systemFeatures) + return pluginInstallLimit(plugin, systemFeatures) +} diff --git a/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx index 5eb4c94abe..cf336ae682 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/item/loaded-item.tsx @@ -8,6 +8,7 @@ import useGetIcon from '../../base/use-get-icon' import { MARKETPLACE_API_PREFIX } from '@/config' import Version from '../../base/version' import type { VersionProps } from '../../../types' +import usePluginInstallLimit from '../../hooks/use-install-plugin-limit' type Props = { checked: boolean @@ -29,9 +30,11 @@ const LoadedItem: FC<Props> = ({ ...particleVersionInfo, toInstallVersion: payload.version, } + const { canInstall } = usePluginInstallLimit(payload) return ( <div className='flex items-center space-x-2'> <Checkbox + disabled={!canInstall} className='shrink-0' checked={checked} onCheck={() => onCheckedChange(payload)} @@ -43,6 +46,7 @@ const LoadedItem: FC<Props> = ({ icon: isFromMarketPlace ? `${MARKETPLACE_API_PREFIX}/plugins/${payload.org}/${payload.name}/icon` : getIconUrl(payload.icon), }} titleLeft={payload.version ? <Version {...versionInfo} /> : null} + limitedInstall={!canInstall} /> </div> ) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index 70a37b27a4..58ae488ab8 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -149,7 +149,7 @@ const Installed: FC<Props> = ({ installedVersion={installedVersion} toInstallVersion={toInstallVersion} />} - showLimitWarning={!canInstall} + limitedInstall={!canInstall} /> </div> </div>