From 1fcb902715a6a3e9c2073174973242b6fc3b479d Mon Sep 17 00:00:00 2001 From: Yi Date: Fri, 11 Oct 2024 17:25:33 +0800 Subject: [PATCH] feat: add cards to "install from marketplace" --- web/app/components/plugins/card/index.tsx | 14 ++--- .../install-from-marketplace/index.tsx | 53 ++++++++++++++++--- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index b67c68c7e4..9b00284fd4 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,7 +1,6 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' -import Badge from '../../base/badge' import Icon from '../card/base/card-icon' import CornerMark from './base/corner-mark' import Title from './base/title' @@ -14,7 +13,7 @@ type Props = { className?: string payload: Plugin locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) - showVersion?: boolean + titleLeft?: React.ReactNode installed?: boolean descriptionLineRows?: number footer?: React.ReactNode @@ -24,7 +23,7 @@ type Props = { const Card = ({ className, payload, - showVersion, + titleLeft, installed, descriptionLineRows = 2, footer, @@ -42,9 +41,7 @@ const Card = ({
<RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - { - showVersion && <Badge className='ml-1' text={payload.latest_version} /> - } + {titleLeft} {/* This can be version badge */} </div> <OrgInfo className="mt-0.5" @@ -64,8 +61,3 @@ const Card = ({ } export default Card - -// export function ServerCard(props: Omit<Props, 'serverLocale'>) { -// const serverLocale = getLocaleOnServer() -// return <Card {...props} serverLocale={serverLocale} /> -// } diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 36e813bf68..524588132f 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -1,11 +1,14 @@ 'use client' -import React from 'react' +import React, { useState } from 'react' import { useContext } from 'use-context-selector' +import { RiInformation2Line } from '@remixicon/react' import Card from '../../card' import { extensionDallE, modelGPT4, toolNotion } from '../../card/card-mock' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' +import Checkbox from '@/app/components/base/checkbox' +import Badge, { BadgeState } from '@/app/components/base/badge/index' import I18n from '@/context/i18n' type InstallFromMarketplaceProps = { @@ -17,6 +20,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose // Mock a plugin list const plugins = [toolNotion, extensionDallE, modelGPT4] + const [selectedPlugins, setSelectedPlugins] = useState<Set<number>>(new Set()) return ( <Modal @@ -35,12 +39,49 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose </div> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - {plugins.map((plugin, index) => ( - <Card - key={index} - payload={plugin as any} + {plugins.length === 1 + && <Card + payload={plugins[0] as any} locale={locale} - /> + className='w-full' + > + </Card> + } + {plugins.length > 1 && plugins.map((plugin, index) => ( + <div className='flex pl-1 items-center gap-2 flex-grow' key={index}> + <Checkbox + checked={selectedPlugins.has(index)} + onCheck={() => { + const newSelectedPlugins = new Set(selectedPlugins) + if (newSelectedPlugins.has(index)) + newSelectedPlugins.delete(index) + else + newSelectedPlugins.add(index) + + setSelectedPlugins(newSelectedPlugins) + }} + /> + <Card + key={index} + payload={plugin as any} + locale={locale} + className='w-full' + titleLeft={plugin.version === plugin.latest_version + ? <Badge className='mx-1' size="s" state={BadgeState.Default}>{plugin.version}</Badge> + : <> + <Badge + className='mx-1' + size="s" + state={BadgeState.Warning}>{`${plugin.version} -> ${plugin.latest_version}`} + </Badge> + <div className='flex px-0.5 justify-center items-center gap-0.5'> + <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </div> + </> + } + /> + </div> ))} </div> </div>