mirror of
https://github.com/langgenius/dify.git
synced 2026-05-09 04:36:31 +08:00
tweaks
This commit is contained in:
parent
f5a262817d
commit
b70c9d7835
@ -7,7 +7,7 @@ import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogTitle } from '@langgenius/dify-ui/dialog'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover'
|
||||
import { toast } from '@langgenius/dify-ui/toast'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { AppTypeIcon } from '@/app/components/app/type-selector'
|
||||
@ -15,7 +15,6 @@ import AppIcon from '@/app/components/base/app-icon'
|
||||
import Input from '@/app/components/base/input'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { useCreateDeploymentInstance } from '../hooks/use-deployment-mutations'
|
||||
import { useDeploymentsStore } from '../store'
|
||||
|
||||
const MAX_STUDIO_SOURCE_APPS = 100
|
||||
@ -208,7 +207,7 @@ export const AppPicker: FC<AppPickerProps> = ({ apps, isLoading, value, onChange
|
||||
const CreateInstanceForm: FC<{ onClose: () => void }> = ({ onClose }) => {
|
||||
const { t } = useTranslation('deployments')
|
||||
const router = useRouter()
|
||||
const createInstance = useCreateDeploymentInstance()
|
||||
const createInstance = useMutation(consoleQuery.enterprise.appDeploy.createAppInstance.mutationOptions())
|
||||
const { data: appList, isLoading } = useQuery(consoleQuery.apps.list.queryOptions({
|
||||
input: {
|
||||
query: {
|
||||
@ -225,31 +224,30 @@ const CreateInstanceForm: FC<{ onClose: () => void }> = ({ onClose }) => {
|
||||
const [appId, setAppId] = useState<string>('')
|
||||
const [name, setName] = useState('')
|
||||
const [description, setDescription] = useState('')
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
||||
const selectedApp = apps.find(a => a.id === appId)
|
||||
const canCreate = Boolean(appId && name.trim() && !isSubmitting)
|
||||
const canCreate = Boolean(appId && name.trim() && !createInstance.isPending)
|
||||
|
||||
const handleCreate = async () => {
|
||||
if (!canCreate)
|
||||
return
|
||||
|
||||
setIsSubmitting(true)
|
||||
try {
|
||||
const result = await createInstance.mutateAsync({
|
||||
sourceAppId: appId,
|
||||
name: name.trim(),
|
||||
description: description.trim() || undefined,
|
||||
body: {
|
||||
sourceAppId: appId,
|
||||
name: name.trim(),
|
||||
description: description.trim() || undefined,
|
||||
},
|
||||
})
|
||||
if (!result.appInstanceId)
|
||||
throw new Error('Create app instance did not return an appInstanceId.')
|
||||
onClose()
|
||||
router.push(`/deployments/${result.appInstanceId}/overview`)
|
||||
}
|
||||
catch {
|
||||
toast.error(t('createModal.createFailed'))
|
||||
}
|
||||
finally {
|
||||
setIsSubmitting(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -3,12 +3,11 @@
|
||||
import type { FC } from 'react'
|
||||
import { Dialog, DialogCloseButton, DialogContent } from '@langgenius/dify-ui/dialog'
|
||||
import { toast } from '@langgenius/dify-ui/toast'
|
||||
import { skipToken, useQuery } from '@tanstack/react-query'
|
||||
import { skipToken, useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { DEPLOYMENT_PAGE_SIZE } from '../data'
|
||||
import { useStartDeployment } from '../hooks/use-deployment-mutations'
|
||||
import { useDeploymentsStore } from '../store'
|
||||
import { environmentOptionsFromOptionsReply } from '../utils'
|
||||
import { DeployForm } from './deploy-drawer/form'
|
||||
@ -18,7 +17,7 @@ const DeployDrawer: FC = () => {
|
||||
const drawer = useDeploymentsStore(state => state.deployDrawer)
|
||||
const drawerAppInstanceId = drawer.appInstanceId
|
||||
const closeDeployDrawer = useDeploymentsStore(state => state.closeDeployDrawer)
|
||||
const startDeploy = useStartDeployment()
|
||||
const startDeploy = useMutation(consoleQuery.enterprise.appDeploy.createDeployment.mutationOptions())
|
||||
const open = drawer.open
|
||||
const { data: releaseHistory } = useQuery(consoleQuery.enterprise.appDeploy.listReleases.queryOptions({
|
||||
input: drawerAppInstanceId
|
||||
@ -75,10 +74,14 @@ const DeployDrawer: FC = () => {
|
||||
onSubmit={async ({ environmentId, releaseId, bindings }) => {
|
||||
try {
|
||||
await startDeploy.mutateAsync({
|
||||
appInstanceId: drawerAppInstanceId,
|
||||
environmentId,
|
||||
releaseId,
|
||||
bindings,
|
||||
params: {
|
||||
appInstanceId: drawerAppInstanceId,
|
||||
},
|
||||
body: {
|
||||
environmentId,
|
||||
releaseId,
|
||||
bindings,
|
||||
},
|
||||
})
|
||||
closeDeployDrawer()
|
||||
}
|
||||
|
||||
@ -9,12 +9,11 @@ import {
|
||||
AlertDialogDescription,
|
||||
AlertDialogTitle,
|
||||
} from '@langgenius/dify-ui/alert-dialog'
|
||||
import { skipToken, useQuery } from '@tanstack/react-query'
|
||||
import { skipToken, useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { DEPLOYMENT_PAGE_SIZE } from '../data'
|
||||
import { useStartDeployment } from '../hooks/use-deployment-mutations'
|
||||
import { useDeploymentsStore } from '../store'
|
||||
import {
|
||||
activeRelease,
|
||||
@ -40,7 +39,7 @@ const RollbackModal: FC = () => {
|
||||
const { t } = useTranslation('deployments')
|
||||
const modal = useDeploymentsStore(state => state.rollbackModal)
|
||||
const closeRollbackModal = useDeploymentsStore(state => state.closeRollbackModal)
|
||||
const rollbackDeployment = useStartDeployment()
|
||||
const rollbackDeployment = useMutation(consoleQuery.enterprise.appDeploy.createDeployment.mutationOptions())
|
||||
const appInput = modal.appInstanceId
|
||||
? { params: { appInstanceId: modal.appInstanceId } }
|
||||
: skipToken
|
||||
@ -87,10 +86,14 @@ const RollbackModal: FC = () => {
|
||||
return
|
||||
closeRollbackModal()
|
||||
rollbackDeployment.mutate({
|
||||
appInstanceId: modal.appInstanceId,
|
||||
environmentId: modal.environmentId,
|
||||
releaseId: modal.targetReleaseId,
|
||||
bindings: [],
|
||||
params: {
|
||||
appInstanceId: modal.appInstanceId,
|
||||
},
|
||||
body: {
|
||||
environmentId: modal.environmentId,
|
||||
releaseId: modal.targetReleaseId,
|
||||
bindings: [],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -6,16 +6,9 @@ import type {
|
||||
AccessSubject,
|
||||
ConsoleEnvironmentSummary,
|
||||
} from '@/features/deployments/types'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { consoleClient, consoleQuery } from '@/service/client'
|
||||
import {
|
||||
useGenerateDeploymentApiKey,
|
||||
useRevokeDeploymentApiKey,
|
||||
useSetEnvironmentAccessPolicy,
|
||||
useToggleDeploymentAccessChannel,
|
||||
useToggleDeploymentDeveloperAPI,
|
||||
} from '../hooks/use-deployment-mutations'
|
||||
import {
|
||||
deployedRows,
|
||||
} from '../utils'
|
||||
@ -50,11 +43,11 @@ const AccessTab: FC<AccessTabProps> = ({ instanceId: appId }) => {
|
||||
appId: string
|
||||
token: string
|
||||
}>()
|
||||
const generateApiKey = useGenerateDeploymentApiKey()
|
||||
const revokeApiKey = useRevokeDeploymentApiKey()
|
||||
const toggleAccessChannel = useToggleDeploymentAccessChannel()
|
||||
const toggleDeveloperAPI = useToggleDeploymentDeveloperAPI()
|
||||
const setEnvironmentAccessPolicy = useSetEnvironmentAccessPolicy()
|
||||
const generateApiKey = useMutation(consoleQuery.enterprise.appDeploy.createDeveloperApiKey.mutationOptions())
|
||||
const revokeApiKey = useMutation(consoleQuery.enterprise.appDeploy.deleteDeveloperApiKey.mutationOptions())
|
||||
const toggleAccessChannel = useMutation(consoleQuery.enterprise.appDeploy.updateAccessChannels.mutationOptions())
|
||||
const toggleDeveloperAPI = useMutation(consoleQuery.enterprise.appDeploy.updateDeveloperApi.mutationOptions())
|
||||
const setEnvironmentAccessPolicy = useMutation(consoleQuery.enterprise.appDeploy.updateEnvironmentAccessPolicy.mutationOptions())
|
||||
|
||||
const deploymentRows = useMemo(
|
||||
() => deployedRows(environmentDeployments?.data),
|
||||
|
||||
@ -8,11 +8,10 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@langgenius/dify-ui/dropdown-menu'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, 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 { useDeploymentsStore } from '../store'
|
||||
import {
|
||||
activeRelease,
|
||||
@ -46,7 +45,8 @@ const DeployTab: FC<DeployTabProps> = ({ instanceId: appInstanceId }) => {
|
||||
}))
|
||||
const { data: environmentOptionsReply } = useQuery(consoleQuery.enterprise.appDeploy.listDeploymentEnvironmentOptions.queryOptions())
|
||||
const openDeployDrawer = useDeploymentsStore(state => state.openDeployDrawer)
|
||||
const undeployDeployment = useUndeployDeployment()
|
||||
const cancelDeployment = useMutation(consoleQuery.enterprise.appDeploy.cancelRuntimeDeployment.mutationOptions())
|
||||
const undeployDeployment = useMutation(consoleQuery.enterprise.appDeploy.undeployRuntimeInstance.mutationOptions())
|
||||
const environmentOptions = useMemo(
|
||||
() => environmentOptionsFromOptionsReply(environmentOptionsReply),
|
||||
[environmentOptionsReply],
|
||||
@ -193,11 +193,33 @@ const DeployTab: FC<DeployTabProps> = ({ instanceId: appInstanceId }) => {
|
||||
<DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-[200px]">
|
||||
<DropdownMenuItem
|
||||
className="gap-2 px-3"
|
||||
onClick={() => undeployDeployment.mutate({
|
||||
appInstanceId,
|
||||
runtimeInstanceId: deploymentId(row),
|
||||
isDeploying: status === 'deploying',
|
||||
})}
|
||||
onClick={() => {
|
||||
const runtimeInstanceId = deploymentId(row)
|
||||
if (status === 'deploying') {
|
||||
cancelDeployment.mutate({
|
||||
params: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
body: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
undeployDeployment.mutate({
|
||||
params: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
body: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
})
|
||||
}}
|
||||
>
|
||||
<span className="system-sm-regular text-text-destructive">
|
||||
{status === 'deploying' ? t('deployTab.cancelDeployment') : t('deployTab.undeploy')}
|
||||
|
||||
@ -13,15 +13,11 @@ import {
|
||||
} from '@langgenius/dify-ui/alert-dialog'
|
||||
import { Button } from '@langgenius/dify-ui/button'
|
||||
import { toast } from '@langgenius/dify-ui/toast'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useRouter } from '@/next/navigation'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import {
|
||||
useDeleteDeploymentInstance,
|
||||
useUpdateDeploymentInstance,
|
||||
} from '../hooks/use-deployment-mutations'
|
||||
import {
|
||||
deployedRows,
|
||||
toAppInfoFromOverview,
|
||||
@ -181,8 +177,8 @@ const SettingsForm: FC<SettingsFormProps> = ({ app, settings, hasDeployments, on
|
||||
|
||||
const SettingsTab: FC<SettingsTabProps> = ({ instanceId }) => {
|
||||
const router = useRouter()
|
||||
const updateInstance = useUpdateDeploymentInstance()
|
||||
const deleteInstance = useDeleteDeploymentInstance()
|
||||
const updateInstance = useMutation(consoleQuery.enterprise.appDeploy.updateAppInstance.mutationOptions())
|
||||
const deleteInstance = useMutation(consoleQuery.enterprise.appDeploy.deleteAppInstance.mutationOptions())
|
||||
const appInput = { params: { appInstanceId: instanceId } }
|
||||
const { data: overview } = useQuery(consoleQuery.enterprise.appDeploy.getAppInstanceOverview.queryOptions({
|
||||
input: appInput,
|
||||
|
||||
@ -5,14 +5,13 @@ import { cn } from '@langgenius/dify-ui/cn'
|
||||
import { Dialog, DialogCloseButton, DialogContent, DialogDescription, DialogTitle } from '@langgenius/dify-ui/dialog'
|
||||
import { toast } from '@langgenius/dify-ui/toast'
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import Input from '@/app/components/base/input'
|
||||
import Textarea from '@/app/components/base/textarea'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { DEPLOYMENT_PAGE_SIZE } from '../data'
|
||||
import { useCreateDeploymentRelease } from '../hooks/use-deployment-mutations'
|
||||
import {
|
||||
deployedRows,
|
||||
formatDate,
|
||||
@ -47,7 +46,7 @@ const VersionsTab: FC<VersionsTabProps> = ({ instanceId: appId }) => {
|
||||
const { data: environmentDeployments } = useQuery(consoleQuery.enterprise.appDeploy.listRuntimeInstances.queryOptions({
|
||||
input,
|
||||
}))
|
||||
const createRelease = useCreateDeploymentRelease()
|
||||
const createRelease = useMutation(consoleQuery.enterprise.appDeploy.createRelease.mutationOptions())
|
||||
const [isCreating, setIsCreating] = useState(false)
|
||||
const [releaseName, setReleaseName] = useState('')
|
||||
const [releaseDescription, setReleaseDescription] = useState('')
|
||||
@ -68,11 +67,17 @@ const VersionsTab: FC<VersionsTabProps> = ({ instanceId: appId }) => {
|
||||
return
|
||||
|
||||
try {
|
||||
await createRelease.mutateAsync({
|
||||
appInstanceId: appId,
|
||||
name: trimmedReleaseName,
|
||||
description: releaseDescription.trim() || undefined,
|
||||
const response = await createRelease.mutateAsync({
|
||||
params: {
|
||||
appInstanceId: appId,
|
||||
},
|
||||
body: {
|
||||
name: trimmedReleaseName,
|
||||
description: releaseDescription.trim() || undefined,
|
||||
},
|
||||
})
|
||||
if (!response.release?.id)
|
||||
throw new Error('Create release did not return a release.')
|
||||
setReleaseName('')
|
||||
setReleaseDescription('')
|
||||
setIsCreating(false)
|
||||
|
||||
@ -1,376 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import type { DeploymentRuntimeBinding } from '@dify/contracts/enterprise/types.gen'
|
||||
import type { QueryClient, QueryKey } from '@tanstack/react-query'
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import { consoleClient, consoleQuery } from '@/service/client'
|
||||
import { SOURCE_APPS_PAGE_SIZE } from '../data'
|
||||
|
||||
export type CreateDeploymentInstanceResult = {
|
||||
appInstanceId: string
|
||||
}
|
||||
|
||||
type CreateDeploymentParams = {
|
||||
appInstanceId: string
|
||||
environmentId: string
|
||||
releaseId: string
|
||||
bindings: DeploymentRuntimeBinding[]
|
||||
}
|
||||
|
||||
type CreateReleaseParams = {
|
||||
appInstanceId: string
|
||||
name: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
type CreateInstanceParams = {
|
||||
sourceAppId: string
|
||||
name: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
type UndeployDeploymentParams = {
|
||||
appInstanceId: string
|
||||
runtimeInstanceId: string
|
||||
isDeploying?: boolean
|
||||
}
|
||||
|
||||
const DEPLOYMENT_READINESS_RETRY_DELAYS = [0, 300, 700, 1200]
|
||||
|
||||
const wait = (delay: number) => new Promise(resolve => setTimeout(resolve, delay))
|
||||
|
||||
const invalidateQueries = async (queryClient: QueryClient, queryKeys: readonly QueryKey[]): Promise<void> => {
|
||||
await Promise.all(queryKeys.map(queryKey => queryClient.invalidateQueries({ queryKey })))
|
||||
}
|
||||
|
||||
const removeQueries = (queryClient: QueryClient, queryKeys: readonly QueryKey[]): void => {
|
||||
queryKeys.forEach(queryKey => queryClient.removeQueries({ queryKey }))
|
||||
}
|
||||
|
||||
const invalidateInstanceList = (queryClient: QueryClient): Promise<void> => {
|
||||
return queryClient.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
})
|
||||
}
|
||||
|
||||
const invalidateInstanceIdentity = (queryClient: QueryClient, appInstanceId: string): Promise<void> => {
|
||||
return invalidateQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceSettings.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
const invalidateDeploymentState = (queryClient: QueryClient, appInstanceId: string): Promise<void> => {
|
||||
return invalidateQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
const invalidateAccessState = (queryClient: QueryClient, appInstanceId: string): Promise<void> => {
|
||||
return invalidateQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
const invalidateEnvironmentAccessPolicy = (
|
||||
queryClient: QueryClient,
|
||||
appInstanceId: string,
|
||||
environmentId: string,
|
||||
): Promise<void> => {
|
||||
return invalidateQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getEnvironmentAccessPolicy.key({
|
||||
type: 'query',
|
||||
input: {
|
||||
params: {
|
||||
appInstanceId,
|
||||
environmentId,
|
||||
},
|
||||
},
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
const removeDeletedInstanceState = (queryClient: QueryClient, appInstanceId: string): Promise<void> => {
|
||||
removeQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceSettings.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getEnvironmentAccessPolicy.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
])
|
||||
return invalidateInstanceList(queryClient)
|
||||
}
|
||||
|
||||
export const useCreateDeploymentInstance = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationKey: consoleQuery.enterprise.appDeploy.createAppInstance.mutationKey(),
|
||||
mutationFn: async (params: CreateInstanceParams): Promise<CreateDeploymentInstanceResult> => {
|
||||
const response = await consoleClient.enterprise.appDeploy.createAppInstance({
|
||||
body: {
|
||||
sourceAppId: params.sourceAppId,
|
||||
name: params.name,
|
||||
description: params.description,
|
||||
},
|
||||
})
|
||||
if (!response.appInstanceId)
|
||||
throw new Error('Create app instance did not return an appInstanceId.')
|
||||
|
||||
for (const delay of DEPLOYMENT_READINESS_RETRY_DELAYS) {
|
||||
if (delay > 0)
|
||||
await wait(delay)
|
||||
|
||||
const listResponse = await queryClient
|
||||
.fetchQuery(consoleQuery.enterprise.appDeploy.listAppInstances.queryOptions({
|
||||
input: {
|
||||
query: {
|
||||
pageNumber: 1,
|
||||
resultsPerPage: SOURCE_APPS_PAGE_SIZE,
|
||||
},
|
||||
},
|
||||
}))
|
||||
.catch(() => undefined)
|
||||
if (listResponse?.data?.some(app => app.id === response.appInstanceId))
|
||||
break
|
||||
}
|
||||
|
||||
return {
|
||||
appInstanceId: response.appInstanceId,
|
||||
}
|
||||
},
|
||||
onSuccess: () => {
|
||||
return invalidateInstanceList(queryClient)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useCreateDeploymentRelease = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationKey: consoleQuery.enterprise.appDeploy.createRelease.mutationKey(),
|
||||
mutationFn: async ({ appInstanceId, name, description }: CreateReleaseParams) => {
|
||||
const response = await consoleClient.enterprise.appDeploy.createRelease({
|
||||
params: {
|
||||
appInstanceId,
|
||||
},
|
||||
body: {
|
||||
name,
|
||||
description,
|
||||
},
|
||||
})
|
||||
if (!response.release?.id)
|
||||
throw new Error('Create release did not return a release.')
|
||||
|
||||
return response.release
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateQueries(queryClient, [
|
||||
consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId: variables.appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId: variables.appInstanceId } },
|
||||
}),
|
||||
])
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useUpdateDeploymentInstance = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.updateAppInstance.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateInstanceIdentity(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useDeleteDeploymentInstance = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.deleteAppInstance.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return removeDeletedInstanceState(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useStartDeployment = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationKey: consoleQuery.enterprise.appDeploy.createDeployment.mutationKey(),
|
||||
mutationFn: async ({
|
||||
appInstanceId,
|
||||
environmentId,
|
||||
releaseId,
|
||||
bindings,
|
||||
}: CreateDeploymentParams) => {
|
||||
if (!releaseId)
|
||||
throw new Error('releaseId is required to start a deployment.')
|
||||
|
||||
return consoleClient.enterprise.appDeploy.createDeployment({
|
||||
params: {
|
||||
appInstanceId,
|
||||
},
|
||||
body: {
|
||||
environmentId,
|
||||
releaseId,
|
||||
bindings,
|
||||
},
|
||||
})
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateDeploymentState(queryClient, variables.appInstanceId)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useUndeployDeployment = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationKey: consoleQuery.enterprise.appDeploy.undeployRuntimeInstance.mutationKey(),
|
||||
mutationFn: ({ appInstanceId, runtimeInstanceId, isDeploying }: UndeployDeploymentParams) => {
|
||||
if (!runtimeInstanceId)
|
||||
throw new Error('runtimeInstanceId is required to undeploy a deployment.')
|
||||
if (isDeploying) {
|
||||
return consoleClient.enterprise.appDeploy.cancelRuntimeDeployment({
|
||||
params: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
body: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
})
|
||||
}
|
||||
return consoleClient.enterprise.appDeploy.undeployRuntimeInstance({
|
||||
params: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
body: {
|
||||
appInstanceId,
|
||||
runtimeInstanceId,
|
||||
},
|
||||
})
|
||||
},
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateDeploymentState(queryClient, variables.appInstanceId)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export const useGenerateDeploymentApiKey = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.createDeveloperApiKey.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateAccessState(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useRevokeDeploymentApiKey = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.deleteDeveloperApiKey.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateAccessState(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useToggleDeploymentAccessChannel = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.updateAccessChannels.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateAccessState(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useToggleDeploymentDeveloperAPI = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.updateDeveloperApi.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateAccessState(queryClient, variables.params.appInstanceId)
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
export const useSetEnvironmentAccessPolicy = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation(consoleQuery.enterprise.appDeploy.updateEnvironmentAccessPolicy.mutationOptions({
|
||||
onSuccess: (_data, variables) => {
|
||||
return invalidateEnvironmentAccessPolicy(
|
||||
queryClient,
|
||||
variables.params.appInstanceId,
|
||||
variables.params.environmentId,
|
||||
)
|
||||
},
|
||||
}))
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import type { ContractRouterClient } from '@orpc/contract'
|
||||
import type { JsonifiedClient } from '@orpc/openapi-client'
|
||||
import type { RouterUtils } from '@orpc/tanstack-query'
|
||||
import { createORPCClient, onError } from '@orpc/client'
|
||||
import { OpenAPILink } from '@orpc/openapi-client/fetch'
|
||||
import { createTanstackQueryUtils } from '@orpc/tanstack-query'
|
||||
@ -64,6 +65,9 @@ const marketplaceLink = new OpenAPILink(marketplaceRouterContract, {
|
||||
export const marketplaceClient: JsonifiedClient<ContractRouterClient<typeof marketplaceRouterContract>> = createORPCClient(marketplaceLink)
|
||||
export const marketplaceQuery = createTanstackQueryUtils(marketplaceClient, { path: ['marketplace'] })
|
||||
|
||||
const APP_DEPLOY_SOURCE_APPS_PAGE_SIZE = 100
|
||||
const APP_DEPLOY_READINESS_RETRY_DELAYS = [0, 300, 700, 1200]
|
||||
|
||||
const consoleLink = new OpenAPILink(consoleRouterContract, {
|
||||
url: getBaseURL(API_PREFIX),
|
||||
fetch: (input, init) => {
|
||||
@ -84,7 +88,342 @@ const consoleLink = new OpenAPILink(consoleRouterContract, {
|
||||
})
|
||||
|
||||
export const consoleClient: JsonifiedClient<ContractRouterClient<typeof consoleRouterContract>> = createORPCClient(consoleLink)
|
||||
export const consoleQuery = createTanstackQueryUtils(consoleClient, {
|
||||
export const consoleQuery: RouterUtils<typeof consoleClient> = createTanstackQueryUtils(consoleClient, {
|
||||
path: ['console'],
|
||||
experimental_defaults: { },
|
||||
experimental_defaults: {
|
||||
enterprise: {
|
||||
appDeploy: {
|
||||
createAppInstance: {
|
||||
mutationOptions: {
|
||||
onSuccess: async (data, _variables, _result, context) => {
|
||||
if (data.appInstanceId) {
|
||||
for (const delay of APP_DEPLOY_READINESS_RETRY_DELAYS) {
|
||||
if (delay > 0)
|
||||
await new Promise(resolve => setTimeout(resolve, delay))
|
||||
|
||||
const listResponse = await context.client
|
||||
.fetchQuery(consoleQuery.enterprise.appDeploy.listAppInstances.queryOptions({
|
||||
input: {
|
||||
query: {
|
||||
pageNumber: 1,
|
||||
resultsPerPage: APP_DEPLOY_SOURCE_APPS_PAGE_SIZE,
|
||||
},
|
||||
},
|
||||
}))
|
||||
.catch(() => undefined)
|
||||
|
||||
if (listResponse?.data?.some(app => app.id === data.appInstanceId))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
await context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
updateAppInstance: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceSettings.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
deleteAppInstance: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
;[
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceSettings.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
consoleQuery.enterprise.appDeploy.getEnvironmentAccessPolicy.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
].forEach(queryKey => context.client.removeQueries({ queryKey }))
|
||||
|
||||
return context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
createRelease: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
createDeployment: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
cancelRuntimeDeployment: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
undeployRuntimeInstance: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listAppInstances.key({ type: 'query' }),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listRuntimeInstances.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.listReleases.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
createDeveloperApiKey: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
deleteDeveloperApiKey: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
updateAccessChannels: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
updateDeveloperApi: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const appInstanceId = variables.params.appInstanceId
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceOverview.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
updateEnvironmentAccessPolicy: {
|
||||
mutationOptions: {
|
||||
onSuccess: (_data, variables, _result, context) => {
|
||||
const { appInstanceId, environmentId } = variables.params
|
||||
return Promise.all([
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getAppInstanceAccess.key({
|
||||
type: 'query',
|
||||
input: { params: { appInstanceId } },
|
||||
}),
|
||||
}),
|
||||
context.client.invalidateQueries({
|
||||
queryKey: consoleQuery.enterprise.appDeploy.getEnvironmentAccessPolicy.key({
|
||||
type: 'query',
|
||||
input: {
|
||||
params: {
|
||||
appInstanceId,
|
||||
environmentId,
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
])
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Loading…
Reference in New Issue
Block a user