mirror of
https://github.com/langgenius/dify.git
synced 2026-05-09 12:59:18 +08:00
/console/api/enterprise/deployment-environment-options
This commit is contained in:
parent
2c34f9849d
commit
2459b88114
@ -46,12 +46,6 @@ export type DeploymentStatusCount = {
|
||||
count?: number
|
||||
}
|
||||
|
||||
export type AppInstanceFilter = {
|
||||
id?: string
|
||||
name?: string
|
||||
kind?: 'all' | 'environment' | 'not_deployed' | (string & {})
|
||||
}
|
||||
|
||||
export type AppDeploymentSummary = {
|
||||
id?: string
|
||||
name?: string
|
||||
@ -73,7 +67,6 @@ export type Pagination = {
|
||||
}
|
||||
|
||||
export type ListAppDeploymentsReply = {
|
||||
filters?: AppInstanceFilter[]
|
||||
data?: AppDeploymentSummary[]
|
||||
pagination?: Pagination
|
||||
}
|
||||
@ -144,11 +137,20 @@ export type ListEnvironmentDeploymentsReply = {
|
||||
data?: EnvironmentDeploymentRow[]
|
||||
}
|
||||
|
||||
export type EnvironmentOption = ConsoleEnvironmentSummary & {
|
||||
disabled?: boolean
|
||||
export type DeploymentEnvironmentOption = ConsoleEnvironmentSummary & {
|
||||
managedBy?: string
|
||||
deployable?: boolean
|
||||
disabledReason?: string
|
||||
}
|
||||
|
||||
export type ListDeploymentEnvironmentOptionsReply = {
|
||||
environments?: DeploymentEnvironmentOption[]
|
||||
}
|
||||
|
||||
export type EnvironmentOption = DeploymentEnvironmentOption & {
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export type ReleaseRuntimePreviewReply = {
|
||||
release?: ConsoleReleaseSummary
|
||||
bindings?: RuntimeBindingDisplay[]
|
||||
@ -370,6 +372,13 @@ export const runtimeInstancesContract = base
|
||||
}>())
|
||||
.output(type<ListEnvironmentDeploymentsReply>())
|
||||
|
||||
export const deploymentEnvironmentOptionsContract = base
|
||||
.route({
|
||||
path: '/enterprise/deployment-environment-options',
|
||||
method: 'GET',
|
||||
})
|
||||
.output(type<ListDeploymentEnvironmentOptionsReply>())
|
||||
|
||||
export const previewReleaseContract = base
|
||||
.route({
|
||||
path: '/enterprise/app-instances/{appInstanceId}/releases:preview',
|
||||
|
||||
@ -12,6 +12,7 @@ import {
|
||||
createReleaseContract,
|
||||
deleteAppInstanceContract,
|
||||
deleteEnvironmentAPITokenContract,
|
||||
deploymentEnvironmentOptionsContract,
|
||||
deploymentOverviewContract,
|
||||
environmentAccessPolicyContract,
|
||||
listAppDeploymentsContract,
|
||||
@ -119,6 +120,7 @@ export const consoleRouterContract = {
|
||||
createInstance: createAppInstanceContract,
|
||||
overview: deploymentOverviewContract,
|
||||
environmentDeployments: runtimeInstancesContract,
|
||||
deploymentEnvironmentOptions: deploymentEnvironmentOptionsContract,
|
||||
previewRelease: previewReleaseContract,
|
||||
releaseHistory: releaseHistoryContract,
|
||||
accessConfig: accessConfigContract,
|
||||
|
||||
@ -10,9 +10,8 @@ import {
|
||||
DEPLOYMENT_PAGE_SIZE,
|
||||
} from '../data'
|
||||
import { useStartDeployment } from '../hooks/use-deployment-mutations'
|
||||
import { deploymentEnvironmentDeploymentsQueryOptions } from '../queries'
|
||||
import { useDeploymentsStore } from '../store'
|
||||
import { environmentOptionsFromDeploymentRows } from '../utils'
|
||||
import { environmentOptionsFromOptionsReply } from '../utils'
|
||||
import { DeployForm } from './deploy-drawer/form'
|
||||
|
||||
const DeployDrawer: FC = () => {
|
||||
@ -34,14 +33,14 @@ const DeployDrawer: FC = () => {
|
||||
: skipToken,
|
||||
enabled: open && Boolean(drawerAppId),
|
||||
}))
|
||||
const { data: environmentDeployments } = useQuery({
|
||||
...deploymentEnvironmentDeploymentsQueryOptions(drawerAppId),
|
||||
enabled: open && Boolean(drawerAppId),
|
||||
const { data: environmentOptionsReply } = useQuery({
|
||||
...consoleQuery.deployments.deploymentEnvironmentOptions.queryOptions(),
|
||||
enabled: open,
|
||||
})
|
||||
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromDeploymentRows(environmentDeployments?.data),
|
||||
[environmentDeployments?.data],
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
)
|
||||
const environments = environmentOptions
|
||||
const releases = releaseHistory?.data?.map(row => row.release ?? row).filter(release => release.id) ?? []
|
||||
@ -57,7 +56,7 @@ const DeployDrawer: FC = () => {
|
||||
<DialogCloseButton />
|
||||
{!drawerAppId
|
||||
? <div className="p-4 text-text-tertiary">{t('deployDrawer.notFound')}</div>
|
||||
: (!releaseHistory || !environmentDeployments)
|
||||
: (!releaseHistory || !environmentOptionsReply)
|
||||
? (
|
||||
<div className="flex items-center gap-2 p-4 system-sm-regular text-text-tertiary">
|
||||
<span className="h-4 w-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" />
|
||||
|
||||
@ -97,11 +97,12 @@ export const DeployForm: FC<DeployFormProps> = ({
|
||||
const isPromote = Boolean(presetReleaseId)
|
||||
|
||||
const [selectedEnvId, setSelectedEnvId] = useState<string>(
|
||||
() => lockedEnvId ?? environments[0]?.id ?? '',
|
||||
() => lockedEnvId ?? environments.find(env => !env.disabled)?.id ?? environments[0]?.id ?? '',
|
||||
)
|
||||
const selectedEnvironmentId = selectedEnvId || lockedEnvId || environments[0]?.id || ''
|
||||
const selectedEnvironment = environments.find(env => env.id === selectedEnvironmentId)
|
||||
const [releaseNote, setReleaseNote] = useState<string>('')
|
||||
const canDeploy = Boolean(selectedEnvironmentId && (!isPromote || displayedRelease?.id || defaultReleaseId))
|
||||
const canDeploy = Boolean(selectedEnvironmentId && selectedEnvironment && !selectedEnvironment.disabled && (!isPromote || displayedRelease?.id || defaultReleaseId))
|
||||
const previewReleaseId = isPromote ? displayedRelease?.id ?? defaultReleaseId : undefined
|
||||
const releasePreview = useQuery(consoleQuery.deployments.previewRelease.queryOptions({
|
||||
input: appId && (!isPromote || previewReleaseId)
|
||||
@ -193,6 +194,8 @@ export const DeployForm: FC<DeployFormProps> = ({
|
||||
options={environments.filter(env => env.id).map(env => ({
|
||||
value: env.id!,
|
||||
label: `${environmentName(env)} · ${t(environmentMode(env) === 'isolated' ? 'mode.isolated' : 'mode.shared')} · ${(env.type ?? 'env').toUpperCase()}`,
|
||||
disabled: env.disabled,
|
||||
disabledReason: env.disabledReason,
|
||||
}))}
|
||||
placeholder={t('deployDrawer.selectEnv')}
|
||||
/>
|
||||
|
||||
@ -24,7 +24,12 @@ export const Field: FC<FieldProps> = ({ label, hint, children }) => (
|
||||
</div>
|
||||
)
|
||||
|
||||
type SelectOption = { value: string, label: string }
|
||||
type SelectOption = {
|
||||
value: string
|
||||
label: string
|
||||
disabled?: boolean
|
||||
disabledReason?: string
|
||||
}
|
||||
|
||||
type SelectProps = {
|
||||
value: string
|
||||
@ -57,7 +62,12 @@ export const DeploymentSelect: FC<SelectProps> = ({ value, onChange, options, pl
|
||||
</SelectTrigger>
|
||||
<SelectContent popupClassName="w-(--anchor-width)">
|
||||
{options.map(opt => (
|
||||
<SelectItem key={opt.value} value={opt.value}>
|
||||
<SelectItem
|
||||
key={opt.value}
|
||||
value={opt.value}
|
||||
disabled={opt.disabled}
|
||||
title={opt.disabled ? opt.disabledReason : undefined}
|
||||
>
|
||||
<SelectItemText>{opt.label}</SelectItemText>
|
||||
<SelectItemIndicator />
|
||||
</SelectItem>
|
||||
|
||||
@ -27,7 +27,7 @@ import {
|
||||
deployedRows,
|
||||
environmentId,
|
||||
environmentName,
|
||||
environmentOptionsFromDeploymentRows,
|
||||
environmentOptionsFromOptionsReply,
|
||||
releaseCommit,
|
||||
releaseLabel,
|
||||
toAppInfoFromOverview,
|
||||
@ -67,13 +67,17 @@ const RollbackModal: FC = () => {
|
||||
...deploymentEnvironmentDeploymentsQueryOptions(modal.appId),
|
||||
enabled: modal.open && Boolean(modal.appId),
|
||||
})
|
||||
const { data: environmentOptionsReply } = useQuery({
|
||||
...consoleQuery.deployments.deploymentEnvironmentOptions.queryOptions(),
|
||||
enabled: modal.open,
|
||||
})
|
||||
const { data: releaseHistory } = useQuery(consoleQuery.deployments.releaseHistory.queryOptions({
|
||||
input: pagedInput ?? skipToken,
|
||||
enabled: modal.open && Boolean(modal.appId),
|
||||
}))
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromDeploymentRows(environmentDeployments?.data),
|
||||
[environmentDeployments?.data],
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
)
|
||||
|
||||
const currentRow = deployedRows(environmentDeployments?.data)
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { useUndeployDeployment } from '../hooks/use-deployment-mutations'
|
||||
import { deploymentEnvironmentDeploymentsQueryOptions } from '../queries'
|
||||
import { useDeploymentsStore } from '../store'
|
||||
@ -23,7 +24,7 @@ import {
|
||||
environmentId,
|
||||
environmentMode,
|
||||
environmentName,
|
||||
environmentOptionsFromDeploymentRows,
|
||||
environmentOptionsFromOptionsReply,
|
||||
isUndeployedDeploymentRow,
|
||||
releaseCommit,
|
||||
releaseLabel,
|
||||
@ -40,11 +41,12 @@ type DeployTabProps = {
|
||||
const DeployTab: FC<DeployTabProps> = ({ instanceId: appId }) => {
|
||||
const { t } = useTranslation('deployments')
|
||||
const { data: environmentDeployments } = useQuery(deploymentEnvironmentDeploymentsQueryOptions(appId))
|
||||
const { data: environmentOptionsReply } = useQuery(consoleQuery.deployments.deploymentEnvironmentOptions.queryOptions())
|
||||
const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
|
||||
const undeployDeployment = useUndeployDeployment()
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromDeploymentRows(environmentDeployments?.data),
|
||||
[environmentDeployments?.data],
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
)
|
||||
|
||||
const rows = useMemo(
|
||||
@ -118,7 +120,10 @@ const DeployTab: FC<DeployTabProps> = ({ instanceId: appId }) => {
|
||||
<DropdownMenuItem
|
||||
key={env.id}
|
||||
className="gap-2 px-3"
|
||||
disabled={env.disabled}
|
||||
onClick={() => {
|
||||
if (env.disabled)
|
||||
return
|
||||
setDeployMenuOpen(false)
|
||||
openDeployDrawer({ appId, environmentId: env.id })
|
||||
}}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { deploymentEnvironmentDeploymentsQueryOptions } from '../../queries'
|
||||
import { useDeploymentsStore } from '../../store'
|
||||
import {
|
||||
@ -20,7 +21,7 @@ import {
|
||||
deploymentStatus,
|
||||
environmentId,
|
||||
environmentName,
|
||||
environmentOptionsFromDeploymentRows,
|
||||
environmentOptionsFromOptionsReply,
|
||||
} from '../../utils'
|
||||
|
||||
type DeployReleaseMenuProps = {
|
||||
@ -37,10 +38,14 @@ export const DeployReleaseMenu: FC<DeployReleaseMenuProps> = ({ appId, releaseId
|
||||
...deploymentEnvironmentDeploymentsQueryOptions(appId),
|
||||
enabled: open,
|
||||
})
|
||||
const { data: environmentOptionsReply } = useQuery({
|
||||
...consoleQuery.deployments.deploymentEnvironmentOptions.queryOptions(),
|
||||
enabled: open,
|
||||
})
|
||||
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromDeploymentRows(environmentDeployments?.data),
|
||||
[environmentDeployments?.data],
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
)
|
||||
const environments = environmentOptions.filter(env => env.id)
|
||||
const deploymentRows = deployedRows(environmentDeployments?.data)
|
||||
|
||||
@ -7,6 +7,7 @@ import { debounce, parseAsString, useQueryState } from 'nuqs'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import CreateInstanceModal from '../components/create-instance-modal'
|
||||
import DeployDrawer from '../components/deploy-drawer'
|
||||
import RollbackModal from '../components/rollback-modal'
|
||||
@ -16,7 +17,7 @@ import {
|
||||
deploymentSummariesFromList,
|
||||
environmentId,
|
||||
environmentName,
|
||||
environmentOptionsFromList,
|
||||
environmentOptionsFromOptionsReply,
|
||||
sourceAppsFromList,
|
||||
} from '../utils'
|
||||
import { EnvironmentFilter } from './environment-filter'
|
||||
@ -52,9 +53,13 @@ const DeploymentsMain: FC = () => {
|
||||
...(envFilter === 'not-deployed' ? { notDeployed: true } : {}),
|
||||
...(queryKeywords.trim() ? { query: queryKeywords.trim() } : {}),
|
||||
}))
|
||||
const { data: environmentOptionsReply } = useQuery(consoleQuery.deployments.deploymentEnvironmentOptions.queryOptions())
|
||||
const apps = useMemo(() => sourceAppsFromList(listQuery.data), [listQuery.data])
|
||||
const summaries = useMemo(() => deploymentSummariesFromList(listQuery.data), [listQuery.data])
|
||||
const environmentOptions = useMemo(() => environmentOptionsFromList(listQuery.data), [listQuery.data])
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
)
|
||||
|
||||
const environments = useMemo(() => {
|
||||
return environmentOptions
|
||||
|
||||
@ -7,6 +7,7 @@ import type {
|
||||
EnvironmentDeploymentRow,
|
||||
EnvironmentOption,
|
||||
ListAppDeploymentsReply,
|
||||
ListDeploymentEnvironmentOptionsReply,
|
||||
RuntimeBindingDisplay,
|
||||
} from '@/contract/console/deployments'
|
||||
import { PUBLIC_API_PREFIX } from '@/config'
|
||||
@ -107,14 +108,6 @@ export const deployedRows = (rows?: EnvironmentDeploymentRow[]) =>
|
||||
&& (row.id || runtimeStatus || row.currentRelease || row.detail)
|
||||
}) ?? []
|
||||
|
||||
type DeploymentEnvironmentFilter = {
|
||||
id?: string
|
||||
name?: string
|
||||
kind?: string
|
||||
disabled?: boolean
|
||||
disabledReason?: string
|
||||
}
|
||||
|
||||
export function toAppInfoFromSummary(summary: AppDeploymentSummary): AppInfo | undefined {
|
||||
if (!summary.id || !summary.name)
|
||||
return undefined
|
||||
@ -158,22 +151,13 @@ export const deploymentSummariesFromList = (response?: ListAppDeploymentsReply):
|
||||
)
|
||||
}
|
||||
|
||||
export const environmentOptionsFromList = (response?: ListAppDeploymentsReply): EnvironmentOption[] => {
|
||||
return ((response?.filters ?? []) as DeploymentEnvironmentFilter[])
|
||||
.filter(filter => filter.kind === 'environment' && filter.id)
|
||||
.map(filter => ({
|
||||
id: filter.id,
|
||||
name: filter.name,
|
||||
disabled: filter.disabled,
|
||||
disabledReason: filter.disabledReason,
|
||||
}))
|
||||
}
|
||||
|
||||
export const environmentOptionsFromDeploymentRows = (rows?: EnvironmentDeploymentRow[]): EnvironmentOption[] => {
|
||||
return rows
|
||||
?.map(row => row.environment)
|
||||
.filter((environment): environment is ConsoleEnvironmentSummary => Boolean(environment?.id))
|
||||
.map(environment => ({ ...environment })) ?? []
|
||||
export const environmentOptionsFromOptionsReply = (response?: ListDeploymentEnvironmentOptionsReply): EnvironmentOption[] => {
|
||||
return response?.environments
|
||||
?.filter(environment => environment.id)
|
||||
.map(environment => ({
|
||||
...environment,
|
||||
disabled: environment.deployable === false,
|
||||
})) ?? []
|
||||
}
|
||||
|
||||
export const accessModeToPermissionKey = (mode?: string): AccessPermissionKind => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user