mirror of https://github.com/portainer/portainer
fix(ingress): empty initial selection + fixes [EE-5852] (#10066)
Co-authored-by: testa113 <testa113>pull/10071/head
parent
26074437ca
commit
2b4cb1b7b4
|
@ -53,6 +53,8 @@ export function CreateIngressView() {
|
|||
|
||||
const [namespace, setNamespace] = useState<string>(params.namespace || '');
|
||||
const [ingressRule, setIngressRule] = useState<Rule>({} as Rule);
|
||||
// isEditClassNameSet is used to prevent premature validation of the classname in the edit view
|
||||
const [isEditClassNameSet, setIsEditClassNameSet] = useState<boolean>(false);
|
||||
|
||||
const [errors, setErrors] = useState<Record<string, ReactNode>>(
|
||||
{} as Record<string, string>
|
||||
|
@ -243,14 +245,21 @@ export function CreateIngressView() {
|
|||
[ingressControllers]
|
||||
);
|
||||
|
||||
// when the ingress class options update the value to an available one
|
||||
// when them selected ingress class option update is no longer available set to an empty value
|
||||
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]);
|
||||
if (
|
||||
!ingressClasses.includes(ingressRule.IngressClassName) &&
|
||||
ingressControllersQuery.isSuccess
|
||||
) {
|
||||
handleIngressChange('IngressClassName', '');
|
||||
}
|
||||
}, [handleIngressChange, ingressClassOptions, ingressRule.IngressClassName]);
|
||||
}, [
|
||||
handleIngressChange,
|
||||
ingressClassOptions,
|
||||
ingressControllersQuery.isSuccess,
|
||||
ingressRule.IngressClassName,
|
||||
]);
|
||||
|
||||
const matchedConfigs = configResults?.data?.filter(
|
||||
(config) =>
|
||||
|
@ -289,6 +298,7 @@ export function CreateIngressView() {
|
|||
const r = prepareRuleFromIngress(ing, type);
|
||||
r.IngressType = type || r.IngressType;
|
||||
setIngressRule(r);
|
||||
setIsEditClassNameSet(true);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
@ -365,12 +375,15 @@ export function CreateIngressView() {
|
|||
errors.ingressName = 'Ingress name already exists';
|
||||
}
|
||||
|
||||
if (!ingressClassOptions.length && ingressControllersQuery.isSuccess) {
|
||||
if (
|
||||
(!ingressClassOptions.length || !rule.IngressClassName) &&
|
||||
ingressControllersQuery.isSuccess
|
||||
) {
|
||||
errors.className = 'Ingress class is required';
|
||||
}
|
||||
}
|
||||
|
||||
if (isEdit && !ingressRule.IngressClassName) {
|
||||
if (isEdit && !ingressRule.IngressClassName && isEditClassNameSet) {
|
||||
errors.className =
|
||||
'No ingress class is currently set for this ingress - use of the Portainer UI requires one to be set.';
|
||||
}
|
||||
|
@ -513,7 +526,8 @@ export function CreateIngressView() {
|
|||
},
|
||||
[
|
||||
isEdit,
|
||||
ingressClassOptions,
|
||||
isEditClassNameSet,
|
||||
ingressClassOptions.length,
|
||||
ingressControllersQuery.isSuccess,
|
||||
environmentId,
|
||||
ingresses,
|
||||
|
@ -583,6 +597,8 @@ export function CreateIngressView() {
|
|||
handleNamespaceChange={handleNamespaceChange}
|
||||
namespacesOptions={namespaceOptions}
|
||||
isNamespaceOptionsLoading={namespacesQuery.isLoading}
|
||||
// wait for ingress results too to set a name that's not taken with handleNamespaceChange()
|
||||
isIngressNamesLoading={ingressesResults.isLoading}
|
||||
/>
|
||||
</div>
|
||||
{namespace && (
|
||||
|
@ -688,6 +704,7 @@ export function CreateIngressView() {
|
|||
Namespace: namespace,
|
||||
IngressName: newKey,
|
||||
IngressClassName: ingressRule.IngressClassName || '',
|
||||
IngressType: ingressRule.IngressType || '',
|
||||
Hosts: [host],
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ interface Props {
|
|||
tlsOptions: Option<string>[];
|
||||
namespacesOptions: Option<string>[];
|
||||
isNamespaceOptionsLoading: boolean;
|
||||
isIngressNamesLoading: boolean;
|
||||
|
||||
removeIngressRoute: (hostIndex: number, pathIndex: number) => void;
|
||||
removeIngressHost: (hostIndex: number) => void;
|
||||
|
@ -102,6 +103,7 @@ export function IngressForm({
|
|||
errors,
|
||||
namespacesOptions,
|
||||
isNamespaceOptionsLoading,
|
||||
isIngressNamesLoading,
|
||||
handleNamespaceChange,
|
||||
namespace,
|
||||
}: Props) {
|
||||
|
@ -114,10 +116,21 @@ export function IngressForm({
|
|||
// when the namespace options update the value to an available one
|
||||
useEffect(() => {
|
||||
const namespaces = namespacesOptions.map((option) => option.value);
|
||||
if (!namespaces.includes(namespace) && namespaces.length > 0) {
|
||||
if (
|
||||
!namespaces.includes(namespace) &&
|
||||
namespaces.length > 0 &&
|
||||
(!isIngressNamesLoading || isEdit)
|
||||
) {
|
||||
handleNamespaceChange(namespaces[0]);
|
||||
}
|
||||
}, [namespacesOptions, namespace, handleNamespaceChange]);
|
||||
}, [
|
||||
namespacesOptions,
|
||||
namespace,
|
||||
handleNamespaceChange,
|
||||
isNamespaceOptionsLoading,
|
||||
isEdit,
|
||||
isIngressNamesLoading,
|
||||
]);
|
||||
|
||||
return (
|
||||
<Widget>
|
||||
|
@ -526,7 +539,7 @@ export function IngressForm({
|
|||
)}
|
||||
</div>
|
||||
|
||||
<div className="form-group col-sm-2 col-xl-2 !m-0 !pl-0">
|
||||
<div className="form-group col-sm-2 col-xl-2 !m-0 min-w-[170px] !pl-0">
|
||||
{servicePorts && (
|
||||
<>
|
||||
<InputGroup size="small">
|
||||
|
@ -669,7 +682,7 @@ export function IngressForm({
|
|||
|
||||
<div className="form-group col-sm-1 !m-0 !pl-0">
|
||||
<Button
|
||||
className="btn-only-icon vertical-center !ml-0"
|
||||
className="!ml-0 h-[30px]"
|
||||
color="dangerlight"
|
||||
type="button"
|
||||
data-cy={`k8sAppCreate-rmPortButton_${hostIndex}-${pathIndex}`}
|
||||
|
|
Loading…
Reference in New Issue