1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 08:19:40 +02:00

feat(namespace): migrate create ns to react [EE-2226] (#10377)

This commit is contained in:
Ali 2023-10-11 20:32:02 +01:00 committed by GitHub
parent 31bcba96c6
commit 7218eb0892
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 1869 additions and 358 deletions

View file

@ -1,86 +0,0 @@
import { ChangeEvent, ReactNode } from 'react';
import { Trash2 } from 'lucide-react';
import { FormError } from '@@/form-components/FormError';
import { Button } from '@@/buttons';
import { Annotation } from './types';
interface Props {
annotations: Annotation[];
handleAnnotationChange: (
index: number,
key: 'Key' | 'Value',
val: string
) => void;
removeAnnotation: (index: number) => void;
errors: Record<string, ReactNode>;
placeholder: string[];
}
export function Annotations({
annotations,
handleAnnotationChange,
removeAnnotation,
errors,
placeholder,
}: Props) {
return (
<>
{annotations.map((annotation, i) => (
<div className="row" key={annotation.ID}>
<div className="form-group col-sm-4 !m-0 !pl-0">
<div className="input-group input-group-sm">
<span className="input-group-addon required">Key</span>
<input
name={`annotation_key_${i}`}
type="text"
className="form-control form-control-sm"
placeholder={placeholder[0]}
defaultValue={annotation.Key}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
handleAnnotationChange(i, 'Key', e.target.value)
}
/>
</div>
{errors[`annotations.key[${i}]`] && (
<FormError className="!mb-0 mt-1">
{errors[`annotations.key[${i}]`]}
</FormError>
)}
</div>
<div className="form-group col-sm-4 !m-0 !pl-0">
<div className="input-group input-group-sm">
<span className="input-group-addon required">Value</span>
<input
name={`annotation_value_${i}`}
type="text"
className="form-control form-control-sm"
placeholder={placeholder[1]}
defaultValue={annotation.Value}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
handleAnnotationChange(i, 'Value', e.target.value)
}
/>
</div>
{errors[`annotations.value[${i}]`] && (
<FormError className="!mb-0 mt-1">
{errors[`annotations.value[${i}]`]}
</FormError>
)}
</div>
<div className="col-sm-3 !m-0 !pl-0">
<Button
size="small"
color="dangerlight"
className="btn-only-icon !ml-0"
type="button"
onClick={() => removeAnnotation(i)}
icon={Trash2}
/>
</div>
</div>
))}
</>
);
}

View file

@ -1,5 +0,0 @@
export interface Annotation {
Key: string;
Value: string;
ID: string;
}

View file

@ -1,11 +1,10 @@
import { useState, useEffect, useMemo, ReactNode, useCallback } from 'react';
import { useState, useEffect, useMemo, useCallback, ReactNode } from 'react';
import { useCurrentStateAndParams, useRouter } from '@uirouter/react';
import { v4 as uuidv4 } from 'uuid';
import { debounce } from 'lodash';
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
import { useConfigurations } from '@/react/kubernetes/configs/queries';
import { useNamespaces } from '@/react/kubernetes/namespaces/queries';
import { useNamespaceServices } from '@/react/kubernetes/networks/services/queries';
import { notifyError, notifySuccess } from '@/portainer/services/notifications';
import { useAuthorizations } from '@/react/hooks/useUser';
@ -15,6 +14,7 @@ import { PageHeader } from '@@/PageHeader';
import { Option } from '@@/form-components/Input/Select';
import { Button } from '@@/buttons';
import { useNamespacesQuery } from '../../namespaces/queries/useNamespacesQuery';
import { Ingress, IngressController } from '../types';
import {
useCreateIngress,
@ -22,8 +22,15 @@ import {
useUpdateIngress,
useIngressControllers,
} from '../queries';
import { Annotation } from '../../annotations/types';
import { Rule, Path, Host, GroupedServiceOptions } from './types';
import {
Rule,
Path,
Host,
GroupedServiceOptions,
IngressErrors,
} from './types';
import { IngressForm } from './IngressForm';
import {
prepareTLS,
@ -32,7 +39,6 @@ import {
prepareRuleFromIngress,
checkIfPathExistsWithHost,
} from './utils';
import { Annotation } from './Annotations/types';
export function CreateIngressView() {
const environmentId = useEnvironmentId();
@ -56,11 +62,10 @@ export function CreateIngressView() {
// 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>
);
const [errors, setErrors] = useState<IngressErrors>({});
const { data: namespaces, ...namespacesQuery } = useNamespaces(environmentId);
const { data: namespaces, ...namespacesQuery } =
useNamespacesQuery(environmentId);
const { data: allServices } = useNamespaceServices(environmentId, namespace);
const configResults = useConfigurations(environmentId, namespace);

View file

@ -1,4 +1,4 @@
import { ChangeEvent, ReactNode, useEffect } from 'react';
import { ChangeEvent, useEffect } from 'react';
import { Plus, RefreshCw, Trash2 } from 'lucide-react';
import Route from '@/assets/ico/route.svg?c';
@ -16,8 +16,14 @@ import { InputGroup } from '@@/form-components/InputGroup';
import { InlineLoader } from '@@/InlineLoader';
import { Select } from '@@/form-components/ReactSelect';
import { Annotations } from './Annotations';
import { GroupedServiceOptions, Rule, ServicePorts } from './types';
import { AnnotationsForm } from '../../annotations/AnnotationsForm';
import {
GroupedServiceOptions,
IngressErrors,
Rule,
ServicePorts,
} from './types';
import '../style.css';
@ -36,7 +42,7 @@ interface Props {
environmentID: number;
rule: Rule;
errors: Record<string, ReactNode>;
errors: IngressErrors;
isEdit: boolean;
namespace: string;
@ -298,12 +304,12 @@ export function IngressForm({
</div>
{rule?.Annotations && (
<Annotations
<AnnotationsForm
placeholder={placeholderAnnotation}
annotations={rule.Annotations}
handleAnnotationChange={handleAnnotationChange}
removeAnnotation={removeAnnotation}
errors={errors}
errors={errors.annotations}
/>
)}

View file

@ -1,6 +1,8 @@
import { ReactNode } from 'react';
import { Option } from '@@/form-components/Input/Select';
import { Annotation } from './Annotations/types';
import { Annotation, AnnotationErrors } from '../../annotations/types';
export interface Path {
Key: string;
@ -40,3 +42,7 @@ export type GroupedServiceOptions = {
label: string;
options: ServiceOption[];
}[];
export type IngressErrors = Record<string, ReactNode> & {
annotations?: AnnotationErrors;
};

View file

@ -3,8 +3,8 @@ import { v4 as uuidv4 } from 'uuid';
import { SupportedIngControllerTypes } from '@/react/kubernetes/cluster/ingressClass/types';
import { TLS, Ingress } from '../types';
import { Annotation } from '../../annotations/types';
import { Annotation } from './Annotations/types';
import { Host, Rule } from './types';
const ignoreAnnotationsForEdit = [