diff --git a/web/app/(commonLayout)/deployments/[instanceId]/access/page.tsx b/web/app/(commonLayout)/deployments/[instanceId]/access/page.tsx index 8963295f4f..23b0777fcc 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/access/page.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/access/page.tsx @@ -1,4 +1,4 @@ -import AccessTab from '@/app/components/deployments/instance-detail/access-tab' +import AccessTab from '@/features/deployments/detail/access-tab' type PageProps = { params: Promise<{ instanceId: string }> diff --git a/web/app/(commonLayout)/deployments/[instanceId]/deploy/page.tsx b/web/app/(commonLayout)/deployments/[instanceId]/deploy/page.tsx index 8f31bdd95d..04ac7b0da5 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/deploy/page.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/deploy/page.tsx @@ -1,4 +1,4 @@ -import DeployTab from '@/app/components/deployments/instance-detail/deploy-tab' +import DeployTab from '@/features/deployments/detail/deploy-tab' type PageProps = { params: Promise<{ instanceId: string }> diff --git a/web/app/(commonLayout)/deployments/[instanceId]/layout.tsx b/web/app/(commonLayout)/deployments/[instanceId]/layout.tsx index 366825ad32..10814783ee 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/layout.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/layout.tsx @@ -1,5 +1,5 @@ import type { ReactNode } from 'react' -import InstanceDetail from '@/app/components/deployments/instance-detail' +import InstanceDetail from '@/features/deployments/detail' type LayoutProps = { children: ReactNode diff --git a/web/app/(commonLayout)/deployments/[instanceId]/overview/page.tsx b/web/app/(commonLayout)/deployments/[instanceId]/overview/page.tsx index 994d2980d5..91931c2243 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/overview/page.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/overview/page.tsx @@ -1,9 +1,9 @@ 'use client' import type { FC } from 'react' -import type { InstanceDetailTabKey } from '@/app/components/deployments/instance-detail/tabs' +import type { InstanceDetailTabKey } from '@/features/deployments/detail/tabs' import * as React from 'react' import { use } from 'react' -import OverviewTab from '@/app/components/deployments/instance-detail/overview-tab' +import OverviewTab from '@/features/deployments/detail/overview-tab' import { useRouter } from '@/next/navigation' type PageProps = { diff --git a/web/app/(commonLayout)/deployments/[instanceId]/settings/page.tsx b/web/app/(commonLayout)/deployments/[instanceId]/settings/page.tsx index 94b43acb70..c3ae36697a 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/settings/page.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/settings/page.tsx @@ -1,4 +1,4 @@ -import SettingsTab from '@/app/components/deployments/instance-detail/settings-tab' +import SettingsTab from '@/features/deployments/detail/settings-tab' type PageProps = { params: Promise<{ instanceId: string }> diff --git a/web/app/(commonLayout)/deployments/[instanceId]/versions/page.tsx b/web/app/(commonLayout)/deployments/[instanceId]/versions/page.tsx index 15258c9975..7964a54087 100644 --- a/web/app/(commonLayout)/deployments/[instanceId]/versions/page.tsx +++ b/web/app/(commonLayout)/deployments/[instanceId]/versions/page.tsx @@ -1,4 +1,4 @@ -import VersionsTab from '@/app/components/deployments/instance-detail/versions-tab' +import VersionsTab from '@/features/deployments/detail/versions-tab' type PageProps = { params: Promise<{ instanceId: string }> diff --git a/web/app/(commonLayout)/deployments/page.tsx b/web/app/(commonLayout)/deployments/page.tsx index ef73c79dfc..585f4bb03e 100644 --- a/web/app/(commonLayout)/deployments/page.tsx +++ b/web/app/(commonLayout)/deployments/page.tsx @@ -1,7 +1,7 @@ 'use client' import * as React from 'react' import { useTranslation } from 'react-i18next' -import DeploymentsMain from '@/app/components/deployments' +import DeploymentsMain from '@/features/deployments/list' import useDocumentTitle from '@/hooks/use-document-title' const DeploymentsPage = () => { diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index d8d26b738d..511177c7eb 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -8,6 +8,7 @@ import { useAppContext } from '@/context/app-context' import { useModalContext } from '@/context/modal-context' import { useProviderContext } from '@/context/provider-context' import { WorkspaceProvider } from '@/context/workspace-context-provider' +import DeploymentsNav from '@/features/deployments/nav' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Link from '@/next/link' import { systemFeaturesQueryOptions } from '@/service/system-features' @@ -15,7 +16,6 @@ import { Plan } from '../billing/type' import AccountDropdown from './account-dropdown' import AppNav from './app-nav' import DatasetNav from './dataset-nav' -import DeploymentsNav from './deployments-nav' import EnvNav from './env-nav' import ExploreNav from './explore-nav' import LicenseNav from './license-env' diff --git a/web/app/components/deployments/create-instance-modal.tsx b/web/features/deployments/components/create-instance-modal.tsx similarity index 99% rename from web/app/components/deployments/create-instance-modal.tsx rename to web/features/deployments/components/create-instance-modal.tsx index a08cee78fc..941fdd9323 100644 --- a/web/app/components/deployments/create-instance-modal.tsx +++ b/web/features/deployments/components/create-instance-modal.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import type { AppInfo, AppMode } from './types' +import type { AppInfo, AppMode } from '../types' import type { App, AppModeEnum } from '@/types/app' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' @@ -14,7 +14,7 @@ import AppIcon from '@/app/components/base/app-icon' import Input from '@/app/components/base/input' import { useRouter } from '@/next/navigation' import { useAppList } from '@/service/use-apps' -import { useDeploymentsStore } from './store' +import { useDeploymentsStore } from '../store' const MAX_STUDIO_SOURCE_APPS = 100 diff --git a/web/app/components/deployments/deploy-drawer.tsx b/web/features/deployments/components/deploy-drawer.tsx similarity index 99% rename from web/app/components/deployments/deploy-drawer.tsx rename to web/features/deployments/components/deploy-drawer.tsx index b3fdefcda0..ccffc61850 100644 --- a/web/app/components/deployments/deploy-drawer.tsx +++ b/web/features/deployments/components/deploy-drawer.tsx @@ -11,9 +11,9 @@ import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Input from '@/app/components/base/input' import { consoleQuery } from '@/service/client' -import { environmentHealth, environmentMode, environmentName, releaseCommit, releaseLabel } from './api-utils' +import { useDeploymentsStore } from '../store' +import { environmentHealth, environmentMode, environmentName, releaseCommit, releaseLabel } from '../utils' import { HealthBadge, ModeBadge } from './status-badge' -import { useDeploymentsStore } from './store' type CredentialRequirement = { slot: string diff --git a/web/app/components/deployments/rollback-modal.tsx b/web/features/deployments/components/rollback-modal.tsx similarity index 97% rename from web/app/components/deployments/rollback-modal.tsx rename to web/features/deployments/components/rollback-modal.tsx index 5941967ed2..6d82ad903e 100644 --- a/web/app/components/deployments/rollback-modal.tsx +++ b/web/features/deployments/components/rollback-modal.tsx @@ -11,6 +11,8 @@ import { } from '@langgenius/dify-ui/alert-dialog' import * as React from 'react' import { useTranslation } from 'react-i18next' +import { useSourceApps } from '../hooks/use-source-apps' +import { useDeploymentsStore } from '../store' import { activeRelease, deployedRows, @@ -18,9 +20,7 @@ import { environmentName, releaseCommit, releaseLabel, -} from './api-utils' -import { useDeploymentsStore } from './store' -import { useSourceApps } from './use-source-apps' +} from '../utils' const InfoRow: FC<{ label: string, value: string }> = ({ label, value }) => { return ( diff --git a/web/app/components/deployments/status-badge.tsx b/web/features/deployments/components/status-badge.tsx similarity index 99% rename from web/app/components/deployments/status-badge.tsx rename to web/features/deployments/components/status-badge.tsx index 83e1c4d5c1..d537dafc3c 100644 --- a/web/app/components/deployments/status-badge.tsx +++ b/web/features/deployments/components/status-badge.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import type { DeployStatus, EnvironmentHealth, EnvironmentMode } from './types' +import type { DeployStatus, EnvironmentHealth, EnvironmentMode } from '../types' import { cn } from '@langgenius/dify-ui/cn' import * as React from 'react' import { useTranslation } from 'react-i18next' diff --git a/web/app/components/deployments/instance-detail/access-tab.tsx b/web/features/deployments/detail/access-tab.tsx similarity index 99% rename from web/app/components/deployments/instance-detail/access-tab.tsx rename to web/features/deployments/detail/access-tab.tsx index 4c3727ff73..2af7f2dde1 100644 --- a/web/app/components/deployments/instance-detail/access-tab.tsx +++ b/web/features/deployments/detail/access-tab.tsx @@ -25,14 +25,14 @@ import { useDebounce } from 'ahooks' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { consoleQuery } from '@/service/client' +import { useDeploymentsStore } from '../store' import { accessModeToPermissionKey, deployedRows, environmentName, permissionKeyToAccessMode, webappUrl, -} from '../api-utils' -import { useDeploymentsStore } from '../store' +} from '../utils' type SectionProps = { title: string diff --git a/web/app/components/deployments/instance-detail/deploy-tab.tsx b/web/features/deployments/detail/deploy-tab.tsx similarity index 99% rename from web/app/components/deployments/instance-detail/deploy-tab.tsx rename to web/features/deployments/detail/deploy-tab.tsx index f3bc7adbf8..aca4487c16 100644 --- a/web/app/components/deployments/instance-detail/deploy-tab.tsx +++ b/web/features/deployments/detail/deploy-tab.tsx @@ -12,6 +12,8 @@ import { import * as React from 'react' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import { HealthBadge, ModeBadge } from '../components/status-badge' +import { useDeploymentsStore } from '../store' import { activeRelease, deployedRows, @@ -26,9 +28,7 @@ import { releaseCommit, releaseLabel, targetRelease, -} from '../api-utils' -import { HealthBadge, ModeBadge } from '../status-badge' -import { useDeploymentsStore } from '../store' +} from '../utils' const GRID_TEMPLATE = 'lg:grid-cols-[1.2fr_0.8fr_1fr_auto]' diff --git a/web/app/components/deployments/instance-detail/index.tsx b/web/features/deployments/detail/index.tsx similarity index 97% rename from web/app/components/deployments/instance-detail/index.tsx rename to web/features/deployments/detail/index.tsx index 304fa02fdc..26b3c28573 100644 --- a/web/app/components/deployments/instance-detail/index.tsx +++ b/web/features/deployments/detail/index.tsx @@ -19,12 +19,12 @@ import { getKeyboardKeyCodeBySystem } from '@/app/components/workflow/utils' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import useDocumentTitle from '@/hooks/use-document-title' import { useRouter, useSelectedLayoutSegment } from '@/next/navigation' -import { deployedRows, deploymentStatus } from '../api-utils' -import DeployDrawer from '../deploy-drawer' -import RollbackModal from '../rollback-modal' +import DeployDrawer from '../components/deploy-drawer' +import RollbackModal from '../components/rollback-modal' +import { useDeploymentData } from '../hooks/use-deployment-data' +import { useSourceApps } from '../hooks/use-source-apps' import { useDeploymentsStore } from '../store' -import { useDeploymentData } from '../use-deployment-data' -import { useSourceApps } from '../use-source-apps' +import { deployedRows, deploymentStatus } from '../utils' import { isInstanceDetailTabKey } from './tabs' type TabDef = { diff --git a/web/app/components/deployments/instance-detail/overview-tab.tsx b/web/features/deployments/detail/overview-tab.tsx similarity index 97% rename from web/app/components/deployments/instance-detail/overview-tab.tsx rename to web/features/deployments/detail/overview-tab.tsx index b55ed715c4..de7fe3b705 100644 --- a/web/app/components/deployments/instance-detail/overview-tab.tsx +++ b/web/features/deployments/detail/overview-tab.tsx @@ -6,10 +6,10 @@ import * as React from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { getAppModeLabel } from '@/app/components/app-sidebar/app-info/app-mode-labels' -import { webappUrl } from '../api-utils' -import { StatusBadge } from '../status-badge' +import { StatusBadge } from '../components/status-badge' +import { useSourceApps } from '../hooks/use-source-apps' import { useDeploymentsStore } from '../store' -import { useSourceApps } from '../use-source-apps' +import { webappUrl } from '../utils' type OverviewTabProps = { instanceId: string diff --git a/web/app/components/deployments/instance-detail/settings-tab.tsx b/web/features/deployments/detail/settings-tab.tsx similarity index 97% rename from web/app/components/deployments/instance-detail/settings-tab.tsx rename to web/features/deployments/detail/settings-tab.tsx index 30f20c5b02..e4256d7283 100644 --- a/web/app/components/deployments/instance-detail/settings-tab.tsx +++ b/web/features/deployments/detail/settings-tab.tsx @@ -4,9 +4,9 @@ import type { AppInfo } from '../types' import { Button } from '@langgenius/dify-ui/button' import * as React from 'react' import { useTranslation } from 'react-i18next' -import { deployedRows } from '../api-utils' +import { useSourceApps } from '../hooks/use-source-apps' import { useDeploymentsStore } from '../store' -import { useSourceApps } from '../use-source-apps' +import { deployedRows } from '../utils' type SettingsTabProps = { instanceId: string diff --git a/web/app/components/deployments/instance-detail/tabs.ts b/web/features/deployments/detail/tabs.ts similarity index 100% rename from web/app/components/deployments/instance-detail/tabs.ts rename to web/features/deployments/detail/tabs.ts diff --git a/web/app/components/deployments/instance-detail/versions-tab.tsx b/web/features/deployments/detail/versions-tab.tsx similarity index 99% rename from web/app/components/deployments/instance-detail/versions-tab.tsx rename to web/features/deployments/detail/versions-tab.tsx index e71221387a..ff331355cd 100644 --- a/web/app/components/deployments/instance-detail/versions-tab.tsx +++ b/web/features/deployments/detail/versions-tab.tsx @@ -11,6 +11,7 @@ import { import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import { useDeploymentsStore } from '../store' import { activeRelease, deployedRows, @@ -22,8 +23,7 @@ import { releaseCommit, releaseLabel, targetRelease, -} from '../api-utils' -import { useDeploymentsStore } from '../store' +} from '../utils' const GRID_TEMPLATE = 'grid-cols-[0.9fr_1fr_0.8fr_1.5fr_auto]' diff --git a/web/app/components/deployments/use-deployment-data.ts b/web/features/deployments/hooks/use-deployment-data.ts similarity index 77% rename from web/app/components/deployments/use-deployment-data.ts rename to web/features/deployments/hooks/use-deployment-data.ts index 45c79ecf90..a7e25b053b 100644 --- a/web/app/components/deployments/use-deployment-data.ts +++ b/web/features/deployments/hooks/use-deployment-data.ts @@ -1,10 +1,10 @@ 'use client' -import type { AppInfo } from './types' +import type { AppInfo } from '../types' import { useQueries } from '@tanstack/react-query' import { useEffect, useRef } from 'react' -import { fetchDeploymentAppData } from '@/service/deployments' -import { useDeploymentsStore } from './store' +import { deploymentAppDataQueryOptions } from '@/service/deployments' +import { useDeploymentsStore } from '../store' type UseDeploymentDataOptions = { enabled?: boolean @@ -16,10 +16,8 @@ export function useDeploymentData(apps: AppInfo[], options: UseDeploymentDataOpt const queries = useQueries({ queries: apps.map(app => ({ - queryKey: ['deployments', 'app-data', app.id], - queryFn: () => fetchDeploymentAppData(app.id), + ...deploymentAppDataQueryOptions(app.id), enabled: enabled && Boolean(app.id), - staleTime: 30 * 1000, })), }) diff --git a/web/app/components/deployments/use-source-apps.ts b/web/features/deployments/hooks/use-source-apps.ts similarity index 96% rename from web/app/components/deployments/use-source-apps.ts rename to web/features/deployments/hooks/use-source-apps.ts index 2174241327..442ae7b18c 100644 --- a/web/app/components/deployments/use-source-apps.ts +++ b/web/features/deployments/hooks/use-source-apps.ts @@ -1,10 +1,10 @@ 'use client' -import type { AppInfo, AppMode } from './types' +import type { AppInfo, AppMode } from '../types' import type { AppDeploymentSummary, ConsoleAppSummary, EnvironmentOption } from '@/contract/console/deployments' import { useQuery } from '@tanstack/react-query' import { useEffect, useMemo } from 'react' import { consoleQuery } from '@/service/client' -import { useDeploymentsStore } from './store' +import { useDeploymentsStore } from '../store' const MAX_SOURCE_APPS = 100 diff --git a/web/app/components/deployments/index.tsx b/web/features/deployments/list/index.tsx similarity index 98% rename from web/app/components/deployments/index.tsx rename to web/features/deployments/list/index.tsx index cb6ddef11b..3b70978c34 100644 --- a/web/app/components/deployments/index.tsx +++ b/web/features/deployments/list/index.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import type { AppInfo } from './types' +import type { AppInfo } from '../types' import type { AppDeploymentSummary } from '@/contract/console/deployments' import type { DeploymentAppData } from '@/service/deployments' import type { AppModeEnum } from '@/types/app' @@ -23,12 +23,12 @@ import AppIcon from '@/app/components/base/app-icon' import Input from '@/app/components/base/input' import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now' import { useRouter } from '@/next/navigation' -import { deployedRows, deploymentStatus, environmentId, environmentName, releaseLabel } from './api-utils' -import CreateInstanceModal from './create-instance-modal' -import DeployDrawer from './deploy-drawer' -import RollbackModal from './rollback-modal' -import { useDeploymentsStore } from './store' -import { useSourceApps } from './use-source-apps' +import CreateInstanceModal from '../components/create-instance-modal' +import DeployDrawer from '../components/deploy-drawer' +import RollbackModal from '../components/rollback-modal' +import { useSourceApps } from '../hooks/use-source-apps' +import { useDeploymentsStore } from '../store' +import { deployedRows, deploymentStatus, environmentId, environmentName, releaseLabel } from '../utils' type NewInstanceCardProps = { onOpen: () => void diff --git a/web/app/components/header/deployments-nav/index.tsx b/web/features/deployments/nav/index.tsx similarity index 91% rename from web/app/components/header/deployments-nav/index.tsx rename to web/features/deployments/nav/index.tsx index 7137fefb48..658d041b2b 100644 --- a/web/app/components/header/deployments-nav/index.tsx +++ b/web/features/deployments/nav/index.tsx @@ -1,13 +1,13 @@ 'use client' -import type { NavItem } from '../nav/nav-selector' +import type { NavItem } from '@/app/components/header/nav/nav-selector' import type { AppIconType, AppModeEnum } from '@/types/app' import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { useDeploymentsStore } from '@/app/components/deployments/store' -import { useSourceApps } from '@/app/components/deployments/use-source-apps' +import Nav from '@/app/components/header/nav' import { useParams, useRouter, useSelectedLayoutSegment } from '@/next/navigation' -import Nav from '../nav' +import { useSourceApps } from '../hooks/use-source-apps' +import { useDeploymentsStore } from '../store' const DeploymentsNav = () => { const { t } = useTranslation() diff --git a/web/app/components/deployments/store.ts b/web/features/deployments/store.ts similarity index 100% rename from web/app/components/deployments/store.ts rename to web/features/deployments/store.ts diff --git a/web/app/components/deployments/types.ts b/web/features/deployments/types.ts similarity index 100% rename from web/app/components/deployments/types.ts rename to web/features/deployments/types.ts diff --git a/web/app/components/deployments/api-utils.ts b/web/features/deployments/utils.ts similarity index 100% rename from web/app/components/deployments/api-utils.ts rename to web/features/deployments/utils.ts diff --git a/web/service/deployments.ts b/web/service/deployments.ts index 89bbb339ff..be419963d6 100644 --- a/web/service/deployments.ts +++ b/web/service/deployments.ts @@ -7,9 +7,11 @@ import type { ListEnvironmentDeploymentsReply, ListReleaseHistoryReply, } from '@/contract/console/deployments' +import { queryOptions } from '@tanstack/react-query' import { consoleClient } from './client' const DEPLOYMENT_PAGE_SIZE = 100 +const DEPLOYMENT_APP_DATA_STALE_TIME = 30 * 1000 export type DeploymentAppData = { appId: string @@ -68,6 +70,13 @@ export const fetchDeploymentAppData = async (appId: string): Promise + queryOptions({ + queryKey: ['console', 'deployments', 'app-data', appId], + queryFn: () => fetchDeploymentAppData(appId), + staleTime: DEPLOYMENT_APP_DATA_STALE_TIME, + }) + export const createDeployment = async ({ appId, environmentId,