From b018f2b0a0b4b78ffb56dc85cdfe16e15b7c2078 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 23 Oct 2025 14:17:43 +0800 Subject: [PATCH] feat: can show app detail modal --- web/app/components/explore/app-card/index.tsx | 22 ++++++++---- web/app/components/explore/app-list/index.tsx | 10 ++++++ web/app/components/explore/index.tsx | 14 ++++++++ web/app/components/explore/try-app/index.tsx | 32 +++++++++++++++++ web/app/components/explore/try-app/tab.tsx | 34 +++++++++++++++++++ web/context/explore-context.ts | 10 ++++++ 6 files changed, 115 insertions(+), 7 deletions(-) create mode 100644 web/app/components/explore/try-app/index.tsx create mode 100644 web/app/components/explore/try-app/tab.tsx diff --git a/web/app/components/explore/app-card/index.tsx b/web/app/components/explore/app-card/index.tsx index 5b9d695947..a16a09f2c2 100644 --- a/web/app/components/explore/app-card/index.tsx +++ b/web/app/components/explore/app-card/index.tsx @@ -8,7 +8,10 @@ import AppIcon from '@/app/components/base/app-icon' import { AppTypeIcon } from '../../app/type-selector' import { useGlobalPublicStore } from '@/context/global-public-context' import { RiArrowRightUpLine } from '@remixicon/react' -import Link from 'next/link' +import { useCallback } from 'react' +import ExploreContext from '@/context/explore-context' +import { useContextSelector } from 'use-context-selector' + export type AppCardProps = { app: App canCreate: boolean @@ -26,6 +29,12 @@ const AppCard = ({ const { app: appBasicInfo } = app const { systemFeatures } = useGlobalPublicStore() const isTrialApp = app.can_trial && systemFeatures.enable_trial_app + const setShowTryAppPanel = useContextSelector(ExploreContext, ctx => ctx.setShowTryAppPanel) + const showTryAPPPanel = useCallback((appId: string) => { + return () => { + setShowTryAppPanel?.(true, { appId }) + } + }, [setShowTryAppPanel]) return (
@@ -71,12 +80,11 @@ const AppCard = ({ )} {isTrialApp && ( - - - + // /try/app/${app.app_id} + )}
)} diff --git a/web/app/components/explore/app-list/index.tsx b/web/app/components/explore/app-list/index.tsx index 58c850eb08..6292bc6aca 100644 --- a/web/app/components/explore/app-list/index.tsx +++ b/web/app/components/explore/app-list/index.tsx @@ -25,6 +25,8 @@ import DSLConfirmModal from '@/app/components/app/create-from-dsl-modal/dsl-conf import Banner from '@/app/components/explore/banner/banner' import { useGlobalPublicStore } from '@/context/global-public-context' import Button from '@/app/components/base/button' +import { useContextSelector } from 'use-context-selector' +import TryApp from '../try-app' type AppsProps = { onSuccess?: () => void @@ -141,6 +143,12 @@ const Apps = ({ }) }, [handleImportDSLConfirm, onSuccess]) + const isShowTryAppPanel = useContextSelector(ExploreContext, ctx => ctx.isShowTryAppPanel) + const setShowTryAppPanel = useContextSelector(ExploreContext, ctx => ctx.setShowTryAppPanel) + const hideTryAppPanel = useCallback(() => { + setShowTryAppPanel(false) + }, [setShowTryAppPanel]) + const appId = useContextSelector(ExploreContext, ctx => ctx.currentApp?.appId) as string if (!categories || categories.length === 0) { return (
@@ -235,6 +243,8 @@ const Apps = ({ /> ) } + + {isShowTryAppPanel && }
) } diff --git a/web/app/components/explore/index.tsx b/web/app/components/explore/index.tsx index e716de96f1..13b48b89dc 100644 --- a/web/app/components/explore/index.tsx +++ b/web/app/components/explore/index.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import React, { useEffect, useState } from 'react' import { useRouter } from 'next/navigation' +import type { CurrentTryAppParams } from '@/context/explore-context' import ExploreContext from '@/context/explore-context' import Sidebar from '@/app/components/explore/sidebar' import { useAppContext } from '@/context/app-context' @@ -42,6 +43,16 @@ const Explore: FC = ({ return router.replace('/datasets') }, [isCurrentWorkspaceDatasetOperator]) + const [currentTryAppParams, setCurrentTryAppParams] = useState({ appId: '47b94c61-5b0d-402b-b5bb-482ee406bc68' }) + const [isShowTryAppPanel, setIsShowTryAppPanel] = useState(true) + const setShowTryAppPanel = (showTryAppPanel: boolean, params?: CurrentTryAppParams) => { + if (showTryAppPanel) + setCurrentTryAppParams(params) + else + setCurrentTryAppParams(undefined) + setIsShowTryAppPanel(showTryAppPanel) + } + return (
= ({ setInstalledApps, isFetchingInstalledApps, setIsFetchingInstalledApps, + currentApp: currentTryAppParams, + isShowTryAppPanel, + setShowTryAppPanel, } } > diff --git a/web/app/components/explore/try-app/index.tsx b/web/app/components/explore/try-app/index.tsx new file mode 100644 index 0000000000..80b6f52568 --- /dev/null +++ b/web/app/components/explore/try-app/index.tsx @@ -0,0 +1,32 @@ +'use client' +import type { FC } from 'react' +import React, { useState } from 'react' +import Modal from '@/app/components/base/modal/index' +import Tab, { TypeEnum } from './tab' + +type Props = { + appId: string + onClose: () => void +} + +const TryApp: FC = ({ + appId, + onClose, +}) => { + const [type, setType] = useState(TypeEnum.TRY) + + return ( + + + {appId} + + ) +} +export default React.memo(TryApp) diff --git a/web/app/components/explore/try-app/tab.tsx b/web/app/components/explore/try-app/tab.tsx new file mode 100644 index 0000000000..bba049dd84 --- /dev/null +++ b/web/app/components/explore/try-app/tab.tsx @@ -0,0 +1,34 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import TabHeader from '../../base/tab-header' + +export enum TypeEnum { + TRY = 'try', + DETAIL = 'detail', +} + +type Props = { + value: TypeEnum + onChange: (value: TypeEnum) => void +} + +const Tab: FC = ({ + value, + onChange, +}) => { + const tabs = [ + { id: TypeEnum.TRY, name: 'Try App' }, + { id: TypeEnum.DETAIL, name: 'App Details' }, + ] + return ( +
+ void} + /> +
+ ) +} +export default React.memo(Tab) diff --git a/web/context/explore-context.ts b/web/context/explore-context.ts index d8d64fb34c..b7e1f9e0cd 100644 --- a/web/context/explore-context.ts +++ b/web/context/explore-context.ts @@ -2,6 +2,10 @@ import { createContext } from 'use-context-selector' import type { InstalledApp } from '@/models/explore' import { noop } from 'lodash-es' +export type CurrentTryAppParams = { + appId: string +} + type IExplore = { controlUpdateInstalledApps: number setControlUpdateInstalledApps: (controlUpdateInstalledApps: number) => void @@ -10,6 +14,9 @@ type IExplore = { setInstalledApps: (installedApps: InstalledApp[]) => void isFetchingInstalledApps: boolean setIsFetchingInstalledApps: (isFetchingInstalledApps: boolean) => void + currentApp?: CurrentTryAppParams + isShowTryAppPanel: boolean + setShowTryAppPanel: (showTryAppPanel: boolean, params?: CurrentTryAppParams) => void } const ExploreContext = createContext({ @@ -20,6 +27,9 @@ const ExploreContext = createContext({ setInstalledApps: noop, isFetchingInstalledApps: false, setIsFetchingInstalledApps: noop, + isShowTryAppPanel: false, + setShowTryAppPanel: noop, + currentApp: undefined, }) export default ExploreContext