|
1 | 1 | import React from 'react'; |
2 | 2 | import { Button, Tooltip } from '@patternfly/react-core'; |
3 | | -import { ModelServingPlatform } from '../../concepts/useProjectServingPlatform'; |
| 3 | +import { ServingRuntimePlatform } from '@odh-dashboard/internal/types'; |
| 4 | +import { |
| 5 | + getSortedTemplates, |
| 6 | + getTemplateEnabled, |
| 7 | + getTemplateEnabledForPlatform, |
| 8 | +} from '@odh-dashboard/internal/pages/modelServing/customServingRuntimes/utils'; |
| 9 | +import ManageServingRuntimeModal from '@odh-dashboard/internal/pages/modelServing/screens/projects/ServingRuntimeModal/ManageServingRuntimeModal'; |
| 10 | +import ManageKServeModal from '@odh-dashboard/internal/pages/modelServing/screens/projects/kServeModal/ManageKServeModal'; |
| 11 | +import ManageNIMServingModal from '@odh-dashboard/internal/pages/modelServing/screens/projects/NIMServiceModal/ManageNIMServingModal'; |
| 12 | +import { byName, ProjectsContext } from '@odh-dashboard/internal/concepts/projects/ProjectsContext'; |
| 13 | +import { useParams } from 'react-router-dom'; |
| 14 | +import { useTemplates } from '@odh-dashboard/internal/api/k8s/templates'; |
| 15 | +import { useDashboardNamespace } from '@odh-dashboard/internal/redux/selectors/index'; |
| 16 | +import useTemplateOrder from '@odh-dashboard/internal/pages/modelServing/customServingRuntimes/useTemplateOrder'; |
| 17 | +import useTemplateDisablement from '@odh-dashboard/internal/pages/modelServing/customServingRuntimes/useTemplateDisablement'; |
| 18 | +import useConnections from '@odh-dashboard/internal/pages/projects/screens/detail/connections/useConnections'; |
| 19 | +import { ProjectKind } from '@odh-dashboard/internal/k8sTypes'; |
| 20 | +import { isProjectNIMSupported } from '@odh-dashboard/internal/pages/modelServing/screens/projects/nimUtils'; |
| 21 | +import { ModelDeploymentsContext } from '../../concepts/ModelDeploymentsContext'; |
| 22 | +import { |
| 23 | + useProjectServingPlatform, |
| 24 | + ModelServingPlatform, |
| 25 | +} from '../../concepts/useProjectServingPlatform'; |
| 26 | +import { useAvailableClusterPlatforms } from '../../concepts/useAvailableClusterPlatforms'; |
| 27 | + |
| 28 | +const DeployButtonModal: React.FC<{ |
| 29 | + platform: ServingRuntimePlatform; |
| 30 | + currentProject: ProjectKind; |
| 31 | + namespace?: string; |
| 32 | + onClose: (submit: boolean) => void; |
| 33 | +}> = ({ platform, currentProject, namespace, onClose }) => { |
| 34 | + const { dashboardNamespace } = useDashboardNamespace(); |
| 35 | + const [servingRuntimeTemplates] = useTemplates(dashboardNamespace); |
| 36 | + const servingRuntimeTemplateOrder = useTemplateOrder(dashboardNamespace, undefined); |
| 37 | + const servingRuntimeTemplateDisablement = useTemplateDisablement(dashboardNamespace, undefined); |
| 38 | + const connections = useConnections(namespace || ''); |
| 39 | + const templatesSorted = getSortedTemplates( |
| 40 | + servingRuntimeTemplates, |
| 41 | + servingRuntimeTemplateOrder.data, |
| 42 | + ); |
| 43 | + const templatesEnabled = templatesSorted.filter((template) => |
| 44 | + getTemplateEnabled(template, servingRuntimeTemplateDisablement.data), |
| 45 | + ); |
| 46 | + |
| 47 | + if (platform === ServingRuntimePlatform.MULTI) { |
| 48 | + return ( |
| 49 | + <ManageServingRuntimeModal |
| 50 | + currentProject={currentProject} |
| 51 | + servingRuntimeTemplates={templatesEnabled.filter((t) => |
| 52 | + getTemplateEnabledForPlatform(t, ServingRuntimePlatform.MULTI), |
| 53 | + )} |
| 54 | + onClose={onClose} |
| 55 | + /> |
| 56 | + ); |
| 57 | + } |
| 58 | + |
| 59 | + const isNIMSupported = isProjectNIMSupported(currentProject); |
| 60 | + if (isNIMSupported) { |
| 61 | + return <ManageNIMServingModal projectContext={{ currentProject }} onClose={onClose} />; |
| 62 | + } |
| 63 | + return ( |
| 64 | + <ManageKServeModal |
| 65 | + projectContext={{ currentProject, connections: connections.data }} |
| 66 | + servingRuntimeTemplates={templatesEnabled.filter((t) => |
| 67 | + getTemplateEnabledForPlatform(t, ServingRuntimePlatform.SINGLE), |
| 68 | + )} |
| 69 | + onClose={onClose} |
| 70 | + /> |
| 71 | + ); |
| 72 | +}; |
4 | 73 |
|
5 | 74 | export const DeployButton: React.FC<{ |
6 | 75 | platform?: ModelServingPlatform; |
7 | 76 | variant?: 'primary' | 'secondary'; |
8 | 77 | isDisabled?: boolean; |
9 | 78 | }> = ({ platform, variant = 'primary', isDisabled }) => { |
| 79 | + const [modalShown, setModalShown] = React.useState<boolean>(false); |
| 80 | + const [platformSelected, setPlatformSelected] = React.useState<ServingRuntimePlatform>(); |
| 81 | + const { namespace: modelNamespace } = useParams<{ namespace: string }>(); |
| 82 | + const { projects } = React.useContext(ProjectsContext); |
| 83 | + const { clusterPlatforms } = useAvailableClusterPlatforms(); |
| 84 | + const { projects: modelProjects } = React.useContext(ModelDeploymentsContext); |
| 85 | + const match = modelNamespace ? projects.find(byName(modelNamespace)) : undefined; |
| 86 | + const currentProject = modelProjects?.find(byName(modelNamespace)); |
| 87 | + const { activePlatform, projectPlatform } = useProjectServingPlatform(match, clusterPlatforms); |
| 88 | + |
| 89 | + const getServingRuntimePlatform = (platformId: string): ServingRuntimePlatform => |
| 90 | + platformId === 'modelmesh' ? ServingRuntimePlatform.MULTI : ServingRuntimePlatform.SINGLE; |
| 91 | + |
| 92 | + const onSubmit = () => { |
| 93 | + setModalShown(false); |
| 94 | + setPlatformSelected(undefined); |
| 95 | + }; |
| 96 | + |
| 97 | + const handleDeployClick = () => { |
| 98 | + if (platform) { |
| 99 | + setPlatformSelected(getServingRuntimePlatform(platform.properties.id)); |
| 100 | + } else { |
| 101 | + const currentPlatform = activePlatform || projectPlatform; |
| 102 | + if (currentProject && currentPlatform) { |
| 103 | + setPlatformSelected(getServingRuntimePlatform(currentPlatform.properties.id)); |
| 104 | + } |
| 105 | + } |
| 106 | + setModalShown(true); |
| 107 | + }; |
| 108 | + |
10 | 109 | const deployButton = ( |
11 | 110 | <Button |
12 | 111 | variant={variant} |
13 | 112 | data-testid="deploy-button" |
14 | | - // onClick={() => { |
15 | | - // do something |
16 | | - // }} |
17 | | - isAriaDisabled={isDisabled} |
| 113 | + onClick={handleDeployClick} |
| 114 | + isAriaDisabled={!currentProject} |
18 | 115 | > |
19 | 116 | Deploy model |
20 | 117 | </Button> |
21 | 118 | ); |
22 | | - if (!platform || isDisabled) { |
| 119 | + |
| 120 | + if (!currentProject || isDisabled) { |
23 | 121 | return ( |
24 | 122 | <Tooltip data-testid="deploy-model-tooltip" content="To deploy a model, select a project."> |
25 | 123 | {deployButton} |
26 | 124 | </Tooltip> |
27 | 125 | ); |
28 | 126 | } |
29 | | - return <>{deployButton}</>; |
| 127 | + |
| 128 | + return ( |
| 129 | + <> |
| 130 | + {deployButton} |
| 131 | + {modalShown && platformSelected ? ( |
| 132 | + <DeployButtonModal |
| 133 | + platform={platformSelected} |
| 134 | + currentProject={currentProject} |
| 135 | + namespace={modelNamespace} |
| 136 | + onClose={onSubmit} |
| 137 | + /> |
| 138 | + ) : null} |
| 139 | + </> |
| 140 | + ); |
30 | 141 | }; |
0 commit comments