diff --git a/app/react/kubernetes/cluster/ingressClass/IngressClassDatatable/IngressClassDatatable.tsx b/app/react/kubernetes/cluster/ingressClass/IngressClassDatatable/IngressClassDatatable.tsx index 5ff5c6750..cc5b462da 100644 --- a/app/react/kubernetes/cluster/ingressClass/IngressClassDatatable/IngressClassDatatable.tsx +++ b/app/react/kubernetes/cluster/ingressClass/IngressClassDatatable/IngressClassDatatable.tsx @@ -199,7 +199,7 @@ export function IngressClassDatatable({

diff --git a/app/react/kubernetes/ingresses/CreateIngressView/CreateIngressView.tsx b/app/react/kubernetes/ingresses/CreateIngressView/CreateIngressView.tsx index 6250b0f1d..79b3f545e 100644 --- a/app/react/kubernetes/ingresses/CreateIngressView/CreateIngressView.tsx +++ b/app/react/kubernetes/ingresses/CreateIngressView/CreateIngressView.tsx @@ -66,10 +66,8 @@ export function CreateIngressView() { environmentId, namespaces ? Object.keys(namespaces || {}) : [] ); - const ingressControllersQuery = useIngressControllers( - environmentId, - namespace - ); + const { data: ingressControllers, ...ingressControllersQuery } = + useIngressControllers(environmentId, namespace); const createIngressMutation = useCreateIngress(); const updateIngressMutation = useUpdateIngress(); @@ -171,39 +169,84 @@ export function CreateIngressView() { const existingIngressClass = useMemo( () => - ingressControllersQuery.data?.find( - (i) => - i.ClassName === ingressRule.IngressClassName || - (i.Type === 'custom' && ingressRule.IngressClassName === '') + ingressControllers?.find( + (controller) => + controller.ClassName === ingressRule.IngressClassName || + (controller.Type === 'custom' && ingressRule.IngressClassName === '') ), - [ingressControllersQuery.data, ingressRule.IngressClassName] + [ingressControllers, ingressRule.IngressClassName] ); - const ingressClassOptions: Option[] = useMemo( - () => - ingressControllersQuery.data - ?.filter((cls) => cls.Availability) + const ingressClassOptions: Option[] = useMemo(() => { + const allowedIngressClassOptions = + ingressControllers + ?.filter((controller) => !!controller.Availability) .map((cls) => ({ label: cls.ClassName, value: cls.ClassName, - })) || [], - [ingressControllersQuery.data] + })) || []; + + // if the ingress class is not set, return only the allowed ingress classes + if (ingressRule.IngressClassName === '' || !isEdit) { + return allowedIngressClassOptions; + } + + // if the ingress class is set and it exists (even if disallowed), return the allowed ingress classes + the disallowed option + const disallowedIngressClasses = + ingressControllers + ?.filter( + (controller) => + !controller.Availability && + existingIngressClass?.ClassName === controller.ClassName + ) + .map((controller) => ({ + label: `${controller.ClassName} - DISALLOWED`, + value: controller.ClassName, + })) || []; + + const existingIngressClassFound = ingressControllers?.find( + (controller) => existingIngressClass?.ClassName === controller.ClassName + ); + if (existingIngressClassFound) { + return [...allowedIngressClassOptions, ...disallowedIngressClasses]; + } + + // if the ingress class is set and it doesn't exist, return the allowed ingress classes + the not found option + const notFoundIngressClassOption = { + label: `${ingressRule.IngressClassName} - NOT FOUND`, + value: ingressRule.IngressClassName || '', + }; + return [...allowedIngressClassOptions, notFoundIngressClassOption]; + }, [ + existingIngressClass?.ClassName, + ingressControllers, + ingressRule.IngressClassName, + isEdit, + ]); + + const handleIngressChange = useCallback( + (key: string, val: string) => { + setIngressRule((prevRules) => { + const rule = { ...prevRules, [key]: val }; + if (key === 'IngressClassName') { + rule.IngressType = ingressControllers?.find( + (c) => c.ClassName === val + )?.Type; + } + return rule; + }); + }, + [ingressControllers] ); - if ( - (!existingIngressClass || - (existingIngressClass && !existingIngressClass.Availability)) && - ingressRule.IngressClassName && - !ingressControllersQuery.isLoading - ) { - const optionLabel = !ingressRule.IngressType - ? `${ingressRule.IngressClassName} - NOT FOUND` - : `${ingressRule.IngressClassName} - DISALLOWED`; - ingressClassOptions.push({ - label: optionLabel, - value: ingressRule.IngressClassName, - }); - } + // when the ingress class options update the value to an available one + useEffect(() => { + const ingressClasses = ingressClassOptions.map((option) => option.value); + if (!ingressClasses.includes(ingressRule.IngressClassName)) { + // setting to the first available option (or undefined when there are no options) + handleIngressChange('IngressClassName', ingressClasses[0]); + } + }, [handleIngressChange, ingressClassOptions, ingressRule.IngressClassName]); const matchedConfigs = configResults?.data?.filter( (config) => @@ -234,7 +277,7 @@ export function CreateIngressView() { (ing) => ing.Name === params.name && ing.Namespace === params.namespace ); if (ing) { - const type = ingressControllersQuery.data?.find( + const type = ingressControllers?.find( (c) => c.ClassName === ing.ClassName || (c.Type === 'custom' && !ing.ClassName) @@ -248,7 +291,7 @@ export function CreateIngressView() { }, [ params.name, ingressesResults.data, - ingressControllersQuery.data, + ingressControllers, ingressRule.IngressName, params.namespace, ]); @@ -559,18 +602,6 @@ export function CreateIngressView() { } } - function handleIngressChange(key: string, val: string) { - setIngressRule((prevRules) => { - const rule = { ...prevRules, [key]: val }; - if (key === 'IngressClassName') { - rule.IngressType = ingressControllersQuery.data?.find( - (c) => c.ClassName === val - )?.Type; - } - return rule; - }); - } - function handleTLSChange(hostIndex: number, tls: string) { setIngressRule((prevRules) => { const rule = { ...prevRules }; diff --git a/app/react/kubernetes/ingresses/CreateIngressView/IngressForm.tsx b/app/react/kubernetes/ingresses/CreateIngressView/IngressForm.tsx index 383c1ba25..6759f4f8b 100644 --- a/app/react/kubernetes/ingresses/CreateIngressView/IngressForm.tsx +++ b/app/react/kubernetes/ingresses/CreateIngressView/IngressForm.tsx @@ -119,17 +119,6 @@ export function IngressForm({ } }, [namespacesOptions, namespace, handleNamespaceChange]); - // when the ingress class options update update the value to an available one - useEffect(() => { - const ingressClasses = ingressClassOptions.map((option) => option.value); - if ( - !ingressClasses.includes(rule.IngressClassName) && - ingressClasses.length > 0 - ) { - handleIngressChange('IngressClassName', ingressClasses[0]); - } - }, [ingressClassOptions, rule.IngressClassName, handleIngressChange]); - return ( @@ -157,12 +146,22 @@ export function IngressForm({ ) : ( handleIngressChange( 'IngressClassName', ingressClassOption?.value || '' ) } + noOptionsMessage={() => 'No ingress classes available'} /> {errors.className && ( @@ -242,11 +250,6 @@ export function IngressForm({ )} )} - {errors.className && ( - - {errors.className} - - )} @@ -401,13 +404,23 @@ export function IngressForm({