diff --git a/clients/ui/bff/internal/api/model_registry_settings_handler.go b/clients/ui/bff/internal/api/model_registry_settings_handler.go index 95d35aa826..410929ca87 100644 --- a/clients/ui/bff/internal/api/model_registry_settings_handler.go +++ b/clients/ui/bff/internal/api/model_registry_settings_handler.go @@ -36,10 +36,33 @@ func (app *App) GetAllModelRegistriesSettingsHandler(w http.ResponseWriter, r *h Key: "ssl-secret-key", } + lastTransitionTime, _ := time.Parse(time.RFC3339, "2024-03-22T09:30:02Z") + deletionTime := lastTransitionTime registries := []models.ModelRegistryKind{ - createSampleModelRegistry("model-registry", namespace, &sslRootCertificateConfigMap, nil), - createSampleModelRegistry("model-registry-dora", namespace, nil, &sslRootCertificateSecret), - createSampleModelRegistry("model-registry-bella", namespace, nil, nil), + createSampleModelRegistry("model-registry", namespace, &sslRootCertificateConfigMap, nil, nil, nil), + createSampleModelRegistry("model-registry-dora", namespace, nil, &sslRootCertificateSecret, nil, nil), + createSampleModelRegistry("model-registry-bella", namespace, nil, nil, nil, nil), + createSampleModelRegistry("model-registry-ready", namespace, nil, nil, nil, + []models.Condition{ + {LastTransitionTime: lastTransitionTime, Message: "Deployment for custom resource model-registry-ready is available", Reason: "Available", Status: "True", Type: "Available"}, + }), + createSampleModelRegistry("model-registry-starting", namespace, nil, nil, nil, + []models.Condition{ + {LastTransitionTime: lastTransitionTime, Message: "Deployment for custom resource model-registry-starting was successfully created", Reason: "CreatedDeployment", Status: "True", Type: "Progressing"}, + }), + createSampleModelRegistry("model-registry-stopping", namespace, nil, nil, &deletionTime, + []models.Condition{ + {LastTransitionTime: lastTransitionTime, Message: "Deployment for custom resource model-registry-stopping is available", Reason: "Available", Status: "True", Type: "Available"}, + }), + createSampleModelRegistry("model-registry-degrading", namespace, nil, nil, nil, + []models.Condition{ + {LastTransitionTime: lastTransitionTime, Message: "Service is degrading", Reason: "Degraded", Status: "True", Type: "Degraded"}, + }), + createSampleModelRegistry("model-registry-unavailable", namespace, nil, nil, nil, + []models.Condition{ + {LastTransitionTime: lastTransitionTime, Message: "Service is unavailable", Reason: "Unavailable", Status: "False", Type: "Available"}, + {LastTransitionTime: lastTransitionTime, Message: "Istio resources are unavailable", Reason: "IstioUnavailable", Status: "False", Type: "IstioAvailable"}, + }), } modelRegistryRes := ModelRegistrySettingsListEnvelope{ @@ -62,7 +85,7 @@ func (app *App) GetModelRegistrySettingsHandler(w http.ResponseWriter, r *http.R } modelId := ps.ByName(ModelRegistryId) - registry := createSampleModelRegistry(modelId, namespace, nil, nil) + registry := createSampleModelRegistry(modelId, namespace, nil, nil, nil, nil) modelRegistryWithCreds := models.ModelRegistryAndCredentials{ ModelRegistry: registry, @@ -102,7 +125,7 @@ func (app *App) CreateModelRegistrySettingsHandler(w http.ResponseWriter, r *htt ctxLogger.Info("Creating model registry", "name", modelRegistryName) - registry := createSampleModelRegistry(modelRegistryName, namespace, nil, nil) + registry := createSampleModelRegistry(modelRegistryName, namespace, nil, nil, nil, nil) modelRegistryRes := ModelRegistrySettingsEnvelope{ Data: registry, @@ -125,7 +148,7 @@ func (app *App) UpdateModelRegistrySettingsHandler(w http.ResponseWriter, r *htt } modelId := ps.ByName(ModelRegistryId) - registry := createSampleModelRegistry(modelId, namespace, nil, nil) + registry := createSampleModelRegistry(modelId, namespace, nil, nil, nil, nil) modelRegistryRes := ModelRegistrySettingsEnvelope{ Data: registry, @@ -148,7 +171,7 @@ func (app *App) DeleteModelRegistrySettingsHandler(w http.ResponseWriter, r *htt // This is a temporary fix to handle frontend error (as it is expecting ModelRegistryKind response) until we have a real implementation modelId := ps.ByName(ModelRegistryId) - registry := createSampleModelRegistry(modelId, namespace, nil, nil) + registry := createSampleModelRegistry(modelId, namespace, nil, nil, nil, nil) modelRegistryRes := ModelRegistrySettingsEnvelope{ Data: registry, @@ -161,10 +184,9 @@ func (app *App) DeleteModelRegistrySettingsHandler(w http.ResponseWriter, r *htt } // This function is a temporary function to create a sample model registry kind until we have a real implementation -func createSampleModelRegistry(name string, namespace string, SSLRootCertificateConfigMap *models.Entry, SSLRootCertificateSecret *models.Entry) models.ModelRegistryKind { +func createSampleModelRegistry(name string, namespace string, SSLRootCertificateConfigMap *models.Entry, SSLRootCertificateSecret *models.Entry, deletionTimestamp *time.Time, conditions []models.Condition) models.ModelRegistryKind { creationTime, _ := time.Parse(time.RFC3339, "2024-03-14T08:01:42Z") - lastTransitionTime, _ := time.Parse(time.RFC3339, "2024-03-22T09:30:02Z") return models.ModelRegistryKind{ APIVersion: "modelregistry.io/v1alpha1", @@ -173,6 +195,7 @@ func createSampleModelRegistry(name string, namespace string, SSLRootCertificate Name: name, Namespace: namespace, CreationTimestamp: creationTime, + DeletionTimestamp: deletionTimestamp, Annotations: map[string]string{}, }, Spec: models.ModelRegistrySpec{ @@ -205,15 +228,7 @@ func createSampleModelRegistry(name string, namespace string, SSLRootCertificate }, }, Status: models.Status{ - Conditions: []models.Condition{ - { - LastTransitionTime: lastTransitionTime, - Message: "Deployment for custom resource " + name + " was successfully created", - Reason: "CreatedDeployment", - Status: "True", - Type: "Progressing", - }, - }, + Conditions: conditions, }, } } diff --git a/clients/ui/bff/internal/models/model_registry_kind.go b/clients/ui/bff/internal/models/model_registry_kind.go index f378b68751..ddc3e1998e 100644 --- a/clients/ui/bff/internal/models/model_registry_kind.go +++ b/clients/ui/bff/internal/models/model_registry_kind.go @@ -21,6 +21,7 @@ type Metadata struct { Name string `json:"name"` Namespace string `json:"namespace"` CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` Annotations map[string]string `json:"annotations,omitempty"` } diff --git a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelTransferJobs.cy.ts b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelTransferJobs.cy.ts index 0ef41f860b..4cc905df2d 100644 --- a/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelTransferJobs.cy.ts +++ b/clients/ui/frontend/src/__tests__/cypress/cypress/tests/mocked/modelRegistry/modelTransferJobs.cy.ts @@ -250,7 +250,7 @@ describe('Model transfer jobs', () => { failedRow.find().findByTestId('job-status').should('contain.text', 'Failed'); const cancelledRow = modelTransferJobsPage.getRow('job-cancelled'); - cancelledRow.find().findByTestId('job-status').should('contain.text', 'Cancelled'); + cancelledRow.find().findByTestId('job-status').should('contain.text', 'Canceled'); completedRow.find().findByTestId('job-status').click(); cy.findByTestId('transfer-job-status-modal').should('be.visible'); diff --git a/clients/ui/frontend/src/app/hooks/__tests__/useModelTransferJobs.spec.ts b/clients/ui/frontend/src/app/hooks/__tests__/useModelTransferJobs.spec.ts index 9aed13d1c6..7f7d4dae83 100644 --- a/clients/ui/frontend/src/app/hooks/__tests__/useModelTransferJobs.spec.ts +++ b/clients/ui/frontend/src/app/hooks/__tests__/useModelTransferJobs.spec.ts @@ -1,4 +1,4 @@ -import { waitFor } from '@testing-library/react'; +import { act, waitFor } from '@testing-library/react'; import { useFetchState, POLL_INTERVAL } from 'mod-arch-core'; import useModelTransferJobs from '~/app/hooks/useModelTransferJobs'; import { useModelRegistryAPI } from '~/app/hooks/useModelRegistryAPI'; @@ -129,10 +129,9 @@ describe('useModelTransferJobs', () => { // toggle hasActiveJobs to true and cause a re-render with refreshRate = POLL_INTERVAL. const capturedCallback = getCapturedCallback(); expect(capturedCallback).toBeDefined(); - await capturedCallback?.({}); - - // Wait for the hook to re-render after state update - await renderResult.waitForNextUpdate(); + await act(async () => { + await capturedCallback?.({}); + }); // The latest call to useFetchState should have refreshRate set to POLL_INTERVAL const lastCallOptions = optionsCalls[optionsCalls.length - 1]; @@ -234,7 +233,9 @@ describe('useModelTransferJobs', () => { // so refreshRate should remain undefined (no need to wait for another update). const capturedCallback = getCapturedCallback(); expect(capturedCallback).toBeDefined(); - await capturedCallback?.({}); + await act(async () => { + await capturedCallback?.({}); + }); const lastCallOptions = optionsCalls[optionsCalls.length - 1]; expect(lastCallOptions.refreshRate).toBeUndefined(); diff --git a/clients/ui/frontend/src/app/pages/modelCatalogSettings/components/CatalogSourceStatus.tsx b/clients/ui/frontend/src/app/pages/modelCatalogSettings/components/CatalogSourceStatus.tsx index afb1d181f6..9023ac48e3 100644 --- a/clients/ui/frontend/src/app/pages/modelCatalogSettings/components/CatalogSourceStatus.tsx +++ b/clients/ui/frontend/src/app/pages/modelCatalogSettings/components/CatalogSourceStatus.tsx @@ -38,6 +38,7 @@ const CatalogSourceStatus: React.FC = ({ catalogSource const startingOrUnknownLabel = (