This commit is contained in:
Stephen Zhou 2026-05-07 18:15:05 +08:00
parent 23ffbd2532
commit fe51c9fbdf
No known key found for this signature in database
26 changed files with 74 additions and 144 deletions

View File

@ -1,10 +1,8 @@
import { AccessTab } from '@/features/deployments/detail/access-tab'
type PageProps = {
export default async function InstanceDetailAccessPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailAccessPage({ params }: PageProps) {
}) {
const { instanceId } = await params
return <AccessTab instanceId={instanceId} />
}

View File

@ -1,10 +1,8 @@
import { DeployTab } from '@/features/deployments/detail/deploy-tab'
type PageProps = {
export default async function InstanceDetailDeployPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailDeployPage({ params }: PageProps) {
}) {
const { instanceId } = await params
return <DeployTab instanceId={instanceId} />
}

View File

@ -1,12 +1,10 @@
import type { ReactNode } from 'react'
import { InstanceDetail } from '@/features/deployments/detail'
type LayoutProps = {
export default async function InstanceDetailLayout({ children, params }: {
children: ReactNode
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailLayout({ children, params }: LayoutProps) {
}) {
const { instanceId } = await params
return (

View File

@ -1,10 +1,8 @@
import { OverviewTab } from '@/features/deployments/detail/overview-tab'
type PageProps = {
export default async function InstanceDetailOverviewPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailOverviewPage({ params }: PageProps) {
}) {
const { instanceId } = await params
return <OverviewTab instanceId={instanceId} />
}

View File

@ -1,10 +1,8 @@
import { redirect } from '@/next/navigation'
type PageProps = {
export default async function InstanceDetailPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailPage({ params }: PageProps) {
}) {
const { instanceId } = await params
redirect(`/deployments/${instanceId}/overview`)
}

View File

@ -1,10 +1,8 @@
import { SettingsTab } from '@/features/deployments/detail/settings-tab'
type PageProps = {
export default async function InstanceDetailSettingsPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailSettingsPage({ params }: PageProps) {
}) {
const { instanceId } = await params
return <SettingsTab instanceId={instanceId} />
}

View File

@ -1,10 +1,8 @@
import { VersionsTab } from '@/features/deployments/detail/versions-tab'
type PageProps = {
export default async function InstanceDetailVersionsPage({ params }: {
params: Promise<{ instanceId: string }>
}
export default async function InstanceDetailVersionsPage({ params }: PageProps) {
}) {
const { instanceId } = await params
return <VersionsTab instanceId={instanceId} />
}

View File

@ -203,11 +203,9 @@ export function AppPicker({ apps, isLoading, value, onChange }: AppPickerProps)
)
}
type CreateInstanceFormProps = {
function CreateInstanceForm({ onClose }: {
onClose: () => void
}
function CreateInstanceForm({ onClose }: CreateInstanceFormProps) {
}) {
const { t } = useTranslation('deployments')
const router = useRouter()
const createInstance = useMutation(consoleQuery.enterprise.appDeploy.createAppInstance.mutationOptions())

View File

@ -7,13 +7,11 @@ import { useTranslation } from 'react-i18next'
import { environmentHealth, environmentMode, environmentName } from '../../utils'
import { HealthBadge, ModeBadge } from '../status-badge'
type FieldProps = {
export function Field({ label, hint, children }: {
label: string
hint?: string
children: React.ReactNode
}
export function Field({ label, hint, children }: FieldProps) {
}) {
return (
<div className="flex flex-col gap-2">
<div className="flex items-center justify-between">
@ -78,9 +76,7 @@ export function DeploymentSelect({ value, onChange, options, placeholder }: Sele
)
}
type EnvironmentRowProps = { env: EnvironmentOption }
export function EnvironmentRow({ env }: EnvironmentRowProps) {
export function EnvironmentRow({ env }: { env: EnvironmentOption }) {
return (
<div className="flex items-center justify-between rounded-lg border border-components-panel-border bg-components-panel-bg-blur px-3 py-2">
<div className="flex items-center gap-2">

View File

@ -25,12 +25,10 @@ import {
toAppInfoFromOverview,
} from '../utils'
type InfoRowProps = {
function InfoRow({ label, value }: {
label: string
value: string
}
function InfoRow({ label, value }: InfoRowProps) {
}) {
return (
<div className="flex items-start justify-between gap-4">
<span className="system-xs-medium-uppercase text-text-tertiary">{label}</span>

View File

@ -3,11 +3,6 @@ import type { DeployStatus, EnvironmentHealth, EnvironmentMode } from '../types'
import { cn } from '@langgenius/dify-ui/cn'
import { useTranslation } from 'react-i18next'
type StatusBadgeProps = {
status: DeployStatus
className?: string
}
const statusStyles: Record<DeployStatus, string> = {
ready: 'border-util-colors-green-green-200 bg-util-colors-green-green-50 text-util-colors-green-green-700',
deploying: 'border-util-colors-warning-warning-200 bg-util-colors-warning-warning-50 text-util-colors-warning-warning-700',
@ -22,7 +17,10 @@ const statusKey = {
const baseBadge = 'inline-flex items-center gap-1 rounded-md border px-2 py-0.5 system-xs-medium whitespace-nowrap'
export function StatusBadge({ status, className }: StatusBadgeProps) {
export function StatusBadge({ status, className }: {
status: DeployStatus
className?: string
}) {
const { t } = useTranslation('deployments')
return (
<span className={cn(baseBadge, statusStyles[status], className)}>
@ -34,12 +32,10 @@ export function StatusBadge({ status, className }: StatusBadgeProps) {
)
}
type ModeBadgeProps = {
export function ModeBadge({ mode, className }: {
mode: EnvironmentMode
className?: string
}
export function ModeBadge({ mode, className }: ModeBadgeProps) {
}) {
const { t } = useTranslation('deployments')
const style = mode === 'shared'
? 'border-util-colors-green-green-200 bg-util-colors-green-green-50 text-util-colors-green-green-700'
@ -51,12 +47,10 @@ export function ModeBadge({ mode, className }: ModeBadgeProps) {
)
}
type HealthBadgeProps = {
export function HealthBadge({ health, className }: {
health: EnvironmentHealth
className?: string
}
export function HealthBadge({ health, className }: HealthBadgeProps) {
}) {
const { t } = useTranslation('deployments')
const style = health === 'ready'
? 'border-util-colors-green-green-200 bg-util-colors-green-green-50 text-util-colors-green-green-700'

View File

@ -26,11 +26,9 @@ function uniqueEnvironments(environments: (ConsoleEnvironmentSummary | undefined
})
}
type AccessTabProps = {
export function AccessTab({ instanceId: appId }: {
instanceId: string
}
export function AccessTab({ instanceId: appId }: AccessTabProps) {
}) {
const appInput = { params: { appInstanceId: appId } }
const { data: accessConfig } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceAccess.queryOptions({
input: appInput,

View File

@ -13,13 +13,11 @@ import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { environmentName } from '../../utils'
type ApiKeyRowProps = {
export function ApiKeyRow({ apiKey, onCopy, onRevoke }: {
apiKey: DeveloperAPIKeySummary
onCopy: (apiKeyId: string) => Promise<string>
onRevoke: () => void
}
export function ApiKeyRow({ apiKey, onCopy, onRevoke }: ApiKeyRowProps) {
}) {
const { t } = useTranslation('deployments')
const [copied, setCopied] = useState(false)
const displayValue = apiKey.maskedKey || apiKey.maskedPrefix || apiKey.id || '—'
@ -74,12 +72,10 @@ export function ApiKeyRow({ apiKey, onCopy, onRevoke }: ApiKeyRowProps) {
)
}
type ApiKeyGenerateMenuProps = {
export function ApiKeyGenerateMenu({ environments, onGenerate }: {
environments: ConsoleEnvironmentSummary[]
onGenerate: (environmentId: string) => void
}
export function ApiKeyGenerateMenu({ environments, onGenerate }: ApiKeyGenerateMenuProps) {
}) {
const { t } = useTranslation('deployments')
const [open, setOpen] = useState(false)
const selectableEnvironments = environments.filter(env => env.id)

View File

@ -36,13 +36,11 @@ const permissionIcon: Record<AccessPermissionKind, string> = {
const permissionOrder: AccessPermissionKind[] = ['organization', 'specific', 'anyone']
type PermissionPickerProps = {
function PermissionPicker({ value, disabled, onChange }: {
value: AccessPermissionKind
disabled?: boolean
onChange: (kind: AccessPermissionKind) => void
}
function PermissionPicker({ value, disabled, onChange }: PermissionPickerProps) {
}) {
const { t } = useTranslation('deployments')
const icon = permissionIcon[value]
const label = t(`access.permission.${value}`)
@ -135,13 +133,11 @@ function selectedSubjectsFromPolicy(policy?: AccessPolicyDetail) {
].map(normalizeSubject).filter((subject): subject is SelectableAccessSubject => Boolean(subject))
}
type SubjectPillProps = {
function SubjectPill({ subject, disabled, onRemove }: {
subject: SelectableAccessSubject
disabled?: boolean
onRemove: () => void
}
function SubjectPill({ subject, disabled, onRemove }: SubjectPillProps) {
}) {
const { t } = useTranslation('deployments')
const isGroup = subject.subjectType === 'group'

View File

@ -32,11 +32,9 @@ import { DeploymentStatusSummary } from './deploy-tab/deployment-status-summary'
const GRID_TEMPLATE = 'lg:grid-cols-[minmax(180px,1fr)_minmax(140px,0.75fr)_minmax(180px,0.85fr)_240px]'
type DeployTabProps = {
export function DeployTab({ instanceId: appInstanceId }: {
instanceId: string
}
export function DeployTab({ instanceId: appInstanceId }: DeployTabProps) {
}) {
const { t } = useTranslation('deployments')
const { data: environmentDeployments } = useQuery(consoleQuery.enterprise.appDeploy.listRuntimeInstances.queryOptions({
input: {

View File

@ -18,12 +18,10 @@ import {
runtimeBindingSummary,
} from '../../utils'
type InfoBlockProps = {
function InfoBlock({ title, children }: {
title: string
children: ReactNode
}
function InfoBlock({ title, children }: InfoBlockProps) {
}) {
return (
<div className="min-w-0 rounded-lg bg-background-default px-3 py-2.5">
<div className="mb-2 system-xs-medium-uppercase text-text-tertiary">{title}</div>
@ -51,11 +49,9 @@ function InfoRow({ label, value, mono, suffix }: InfoRowProps) {
)
}
type RuntimeBindingItemProps = {
function RuntimeBindingItem({ binding }: {
binding: RuntimeBindingDisplay
}
function RuntimeBindingItem({ binding }: RuntimeBindingItemProps) {
}) {
const summary = runtimeBindingSummary(binding)
return (
@ -67,11 +63,9 @@ function RuntimeBindingItem({ binding }: RuntimeBindingItemProps) {
)
}
type DeploymentPanelProps = {
export function DeploymentPanel({ row }: {
row: EnvironmentDeploymentRow
}
export function DeploymentPanel({ row }: DeploymentPanelProps) {
}) {
const { t } = useTranslation('deployments')
const observed = activeRelease(row)
const env = row.environment

View File

@ -9,11 +9,9 @@ import {
releaseLabel,
} from '../../utils'
type DeploymentStatusSummaryProps = {
export function DeploymentStatusSummary({ row }: {
row: EnvironmentDeploymentRow
}
export function DeploymentStatusSummary({ row }: DeploymentStatusSummaryProps) {
}) {
const { t } = useTranslation('deployments')
if (isUndeployedDeploymentRow(row)) {
return (

View File

@ -16,12 +16,10 @@ import { toAppInfoFromOverview } from '../utils'
import { DeploymentSidebar } from './deployment-sidebar'
import { isInstanceDetailTabKey } from './tabs'
type InstanceDetailProps = {
export function InstanceDetail({ instanceId, children }: {
instanceId: string
children: ReactNode
}
export function InstanceDetail({ instanceId, children }: InstanceDetailProps) {
}) {
const { t } = useTranslation('deployments')
const { t: tCommon } = useTranslation()
const router = useRouter()

View File

@ -17,19 +17,13 @@ import {
webappUrl,
} from '../utils'
type OverviewTabProps = {
instanceId: string
}
type SwitchableTab = 'deploy' | 'versions' | 'access' | 'settings'
type SectionProps = {
function Section({ title, action, children }: {
title: string
action?: ReactNode
children: ReactNode
}
function Section({ title, action, children }: SectionProps) {
}) {
return (
<div className="flex flex-col gap-3 rounded-xl border border-components-panel-border bg-components-panel-bg p-4">
<div className="flex items-center justify-between">
@ -41,13 +35,11 @@ function Section({ title, action, children }: SectionProps) {
)
}
type InfoRowProps = {
function InfoRow({ label, value, mono }: {
label: string
value: ReactNode
mono?: boolean
}
function InfoRow({ label, value, mono }: InfoRowProps) {
}) {
return (
<div className="flex items-start gap-3 py-1.5">
<span className="w-32 shrink-0 system-xs-regular text-text-tertiary">{label}</span>
@ -98,7 +90,9 @@ function overviewDeploymentStatus(status?: string) {
return 'ready'
}
export function OverviewTab({ instanceId }: OverviewTabProps) {
export function OverviewTab({ instanceId }: {
instanceId: string
}) {
const { t } = useTranslation('deployments')
const { t: tCommon } = useTranslation()
const router = useRouter()

View File

@ -22,10 +22,6 @@ import {
toAppInfoFromOverview,
} from '../utils'
type SettingsTabProps = {
instanceId: string
}
type SettingsFormProps = {
app: AppInfo
settings?: GetAppInstanceSettingsReply
@ -174,7 +170,9 @@ function SettingsForm({ app, settings, hasDeployments, onSave, onDelete }: Setti
)
}
export function SettingsTab({ instanceId }: SettingsTabProps) {
export function SettingsTab({ instanceId }: {
instanceId: string
}) {
const router = useRouter()
const updateInstance = useMutation(consoleQuery.enterprise.appDeploy.updateAppInstance.mutationOptions())
const deleteInstance = useMutation(consoleQuery.enterprise.appDeploy.deleteAppInstance.mutationOptions())

View File

@ -23,11 +23,9 @@ import { getReleaseDeployments } from './versions-tab/release-deployments'
const GRID_TEMPLATE = 'grid-cols-[minmax(0,0.9fr)_minmax(0,1fr)_minmax(0,0.8fr)_minmax(0,1.5fr)_96px]'
type VersionsTabProps = {
export function VersionsTab({ instanceId: appId }: {
instanceId: string
}
export function VersionsTab({ instanceId: appId }: VersionsTabProps) {
}) {
const { t } = useTranslation('deployments')
const input = { params: { appInstanceId: appId } }
const { data: overview } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({

View File

@ -21,12 +21,10 @@ import {
environmentOptionsFromOptionsReply,
} from '../../utils'
type DeployReleaseMenuProps = {
export function DeployReleaseMenu({ appInstanceId, releaseId }: {
appInstanceId: string
releaseId: string
}
export function DeployReleaseMenu({ appInstanceId, releaseId }: DeployReleaseMenuProps) {
}) {
const { t } = useTranslation('deployments')
const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
const [open, setOpen] = useState(false)

View File

@ -11,11 +11,9 @@ const RELEASE_DEPLOYMENT_STYLES: Record<ReleaseDeploymentState, string> = {
failed: 'border-util-colors-warning-warning-200 bg-util-colors-warning-warning-50 text-util-colors-warning-warning-700',
}
type DeployedToBadgeProps = {
export function DeployedToBadge({ item }: {
item: ReleaseDeployment
}
export function DeployedToBadge({ item }: DeployedToBadgeProps) {
}) {
const { t } = useTranslation('deployments')
const statusLabel = t(`versions.deployedStatus.${item.state}`)

View File

@ -18,13 +18,11 @@ export type EnvironmentFilterOption = {
disabledReason?: string
}
type EnvironmentFilterProps = {
export function EnvironmentFilter({ value, options, onChange }: {
value: string
options: EnvironmentFilterOption[]
onChange: (value: string) => void
}
export function EnvironmentFilter({ value, options, onChange }: EnvironmentFilterProps) {
}) {
const [open, setOpen] = useState(false)
const selectedOption = options.find(option => option.value === value) ?? options[0]

View File

@ -21,12 +21,10 @@ import { useFormatTimeFromNow } from '@/hooks/use-format-time-from-now'
import { useRouter } from '@/next/navigation'
import { useDeploymentsStore } from '../store'
type InstanceCardProps = {
export function InstanceCard({ app, summary }: {
app: AppInfo
summary?: AppDeploymentSummary
}
export function InstanceCard({ app, summary }: InstanceCardProps) {
}) {
const { t } = useTranslation('deployments')
const router = useRouter()
const { formatTimeFromNow } = useFormatTimeFromNow()

View File

@ -3,10 +3,6 @@
import { cn } from '@langgenius/dify-ui/cn'
import { useTranslation } from 'react-i18next'
type NewInstanceCardProps = {
onOpen: () => void
}
type NewInstanceActionProps = {
icon: string
label: string
@ -41,7 +37,9 @@ function NewInstanceAction({ icon, label, disabled, onClick }: NewInstanceAction
)
}
export function NewInstanceCard({ onOpen }: NewInstanceCardProps) {
export function NewInstanceCard({ onOpen }: {
onOpen: () => void
}) {
const { t } = useTranslation('deployments')
return (
<div className="relative col-span-1 inline-flex h-[160px] flex-col justify-between rounded-xl border-[0.5px] border-components-card-border bg-components-card-bg">