diff --git a/frontend/src/components/Initializers/AdditionalInitializers.test.tsx b/frontend/src/components/Initializers/AdditionalInitializers.test.tsx index 74a909d626..02468d920a 100644 --- a/frontend/src/components/Initializers/AdditionalInitializers.test.tsx +++ b/frontend/src/components/Initializers/AdditionalInitializers.test.tsx @@ -174,6 +174,49 @@ describe('AdditionalInitializers', () => { expect(within(row).queryByRole('textbox', { name: 'Parameters JSON' })).not.toBeInTheDocument() }) + it('should disable Edit while the initializer catalog is unavailable', () => { + render( + + + , + ) + + const row = screen.getByTestId('initializer-row-additional-1') + const editButton = within(row).getByRole('button', { name: 'Edit' }) + expect(editButton).toBeDisabled() + expect( + within(row).getByText('Initializer catalog is unavailable. Edit is disabled until the catalog loads.'), + ).toBeInTheDocument() + // The saved parameters stay visible so operators can still see the stored value. + expect(within(row).getByText(/"tags"/)).toBeInTheDocument() + }) + + it('should disable Edit for a name that is no longer registered', () => { + render( + + + , + ) + + const row = screen.getByTestId('initializer-row-additional-1') + const editButton = within(row).getByRole('button', { name: 'Edit' }) + expect(editButton).toBeDisabled() + // No synthetic catalog entry is rendered: no env vars or parameter summary for the row. + expect(within(row).queryByText(/Required env vars:/)).not.toBeInTheDocument() + expect(within(row).queryByText(/tags \(list\[str\], optional\)/)).not.toBeInTheDocument() + expect( + within(row).queryByText('Initializer catalog is unavailable. Edit is disabled until the catalog loads.'), + ).not.toBeInTheDocument() + }) + it('should show the description as hover text on the initializer name', async () => { const user = userEvent.setup() diff --git a/frontend/src/components/Initializers/AdditionalInitializers.tsx b/frontend/src/components/Initializers/AdditionalInitializers.tsx index 992292ca3c..9bb07370bb 100644 --- a/frontend/src/components/Initializers/AdditionalInitializers.tsx +++ b/frontend/src/components/Initializers/AdditionalInitializers.tsx @@ -17,7 +17,11 @@ import type { import { toApiError } from '@/services/errors' import { useAdditionalInitializersStyles } from './AdditionalInitializers.styles' import { formatInitializerParameters, formatSupportedParameterSummary } from './initializerFormatting' -import { resolveRegisteredInitializer } from './initializerLookup' +import { + findRegisteredInitializer, + initializerFallbackDescription, + type CatalogStatus, +} from './initializerLookup' import InitializerParametersDialog from './InitializerParametersDialog' import { useInitializersStyles } from './Initializers.styles' import ConfirmDialog from '../ConfirmDialog' @@ -25,6 +29,7 @@ import ConfirmDialog from '../ConfirmDialog' interface AdditionalInitializersProps { items: AdditionalInitializerSetting[] registeredInitializers: RegisteredInitializer[] + catalogStatus?: CatalogStatus creating: boolean savingInitializerId?: string | null saveErrors?: Record @@ -39,7 +44,8 @@ interface AdditionalInitializersProps { interface AdditionalInitializerCardProps { item: AdditionalInitializerSetting - initializer: RegisteredInitializer + initializer: RegisteredInitializer | undefined + catalogStatus: CatalogStatus isSaving: boolean isApplying: boolean isDeleting: boolean @@ -53,6 +59,7 @@ interface AdditionalInitializerCardProps { function AdditionalInitializerCard({ item, initializer, + catalogStatus, isSaving, isApplying, isDeleting, @@ -81,28 +88,45 @@ function AdditionalInitializerCard({ } } + const canEdit = initializer !== undefined && catalogStatus === 'loaded' + return (
- + {item.initializer_name} - {initializer.required_env_vars.length > 0 && ( + {initializer && initializer.required_env_vars.length > 0 && ( Required env vars: {initializer.required_env_vars.join(', ')} )} + {catalogStatus === 'error' && ( + + Initializer catalog is unavailable. Edit is disabled until the catalog loads. + + )}
-
- {formatSupportedParameterSummary(initializer).map((summary: string) => ( - - {summary} - - ))} -
+ {initializer && ( +
+ {formatSupportedParameterSummary(initializer).map((summary: string) => ( + + {summary} + + ))} +
+ )}
Parameters @@ -110,7 +134,7 @@ function AdditionalInitializerCard({
-