Загрузка данных


import { DisableMonitoringButton } from '@/entities/Monitoring';
import { ModelSelect } from '@/features/Settings/selects';
import { EquipmentModel } from '@/features/Settings/selects/ModelSelect';
import { DeviceModel } from '@/shared/api/controller/client';
import { TestIdsConsts } from '@/shared/consts/TestIdsConsts';
import { isMultilineValue } from '@/utils';
import { InterfaceSelect } from '@/widgets/Devices/ui/InterfaceSelect/InterfaceSelect';
import { EquipmentNetInterfaceListForm } from '@/widgets/Monitoring/components/EquipmentNetInterfaceListForm/EquipmentNetInterfaceListForm';
import {
  IpInput,
  SegmentButtonProps,
  Switch,
  TextField,
} from '@shared/components';
import { MonitoringConsts } from '@shared/consts/MonitoringConsts';
import { useFieldValidation } from '@shared/hooks';
import { InputMask } from '@shared/lib/InputMask';
import { ProtocolIpSelect } from '@widgets/Devices/ui/ProtocolIpSelect/ProtocolIpSelect';
import { Select8021X } from '@widgets/Devices/ui/Select802-1X/Select802-1X';
import { useEffect } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import {
  AVLAN_VALUES,
  BASIC_VALUES,
  ETHERNET_VALUES,
  OTHER_VALUES,
} from './model/formNames';
import { CreateDeviceFormData } from './model/types';
import { createDeviceFormSchema } from './validation/validator';

type Props = {
  setModel?: (model: DeviceModel | null) => void;
};

/**
 * @requires refactoring
 */
export const CreateDeviceForm = ({ setModel }: Props) => {
  const { t } = useTranslation();

  const { control, watch, setValue, trigger } =
    useFormContext<CreateDeviceFormData>();

  const { isRequiredField } = useFieldValidation(createDeviceFormSchema);

  const interfaceType = watch(OTHER_VALUES.type);
  const hasSipUri = watch(OTHER_VALUES.hasSipUri);
  const isEthernet = interfaceType === 'ethernet';
  const isAvLan = interfaceType === 'av-lan';

  useEffect(() => {
    if (interfaceType !== 'ethernet') {
      setValue(ETHERNET_VALUES.ip, '');
      setValue(ETHERNET_VALUES.port, undefined);
      setValue(ETHERNET_VALUES.ieee8021x, undefined);
      setValue(ETHERNET_VALUES.protocolIp, 'dhcp');
    }

    if (interfaceType !== 'av-lan') {
      setValue(AVLAN_VALUES.ipAvLan, '');
      setValue(OTHER_VALUES.netInterface, false);
      setValue(OTHER_VALUES.netInterfaceInfo, []);
    }

    if (interfaceType !== 'ethernet' && interfaceType !== 'av-lan') {
      setValue(ETHERNET_VALUES.mac, '');
      setValue(OTHER_VALUES.netInterface, false);
      setValue(OTHER_VALUES.netInterfaceInfo, []);
    }

    trigger(OTHER_VALUES.type);
  }, [interfaceType]);

  useEffect(() => {
    if (!hasSipUri) {
      setValue(OTHER_VALUES.sipUri, '');
    }
  }, [hasSipUri]);

  const getTestId = TestIdsConsts.getEquipmentTestId('create');

  return (
    <>
      {Object.values(BASIC_VALUES).map((inputName) => (
        <Controller
          key={inputName}
          name={inputName}
          control={control}
          render={({
            field: { value, name, ...rest },
            fieldState: { error },
          }) => (
            <TextField
              data-fui-tid={getTestId(inputName)}
              fullWidth
              label={t(`controller:${name}`)}
              error={!!error?.message}
              helperText={t(error?.message as string)}
              multiline={isMultilineValue(name)}
              inputProps={{
                'data-testid': name,
              }}
              required={isRequiredField(name)}
              value={value}
              limitedSymbols={
                MonitoringConsts.EQUIPMENT_FIELDS_LIMITS[name] ?? undefined
              }
              {...rest}
            />
          )}
        />
      ))}

      <Controller
        name={OTHER_VALUES.modelId}
        control={control}
        render={({ field: { name, ...rest }, fieldState: { error } }) => (
          <ModelSelect
            data-fui-tid={getTestId(name)}
            type={EquipmentModel.device}
            data-testid={name}
            error={!!error?.message}
            setModel={setModel}
            handleClearButtonClick={() => setModel?.(null)}
            helperText={t(error?.message as string)}
            required={isRequiredField(name)}
            {...rest}
          />
        )}
      />
      <Controller
        name={OTHER_VALUES.typeName}
        control={control}
        render={({ field: { value, name } }) => (
          <TextField
            data-fui-tid={getTestId(name)}
            label={t(`controller:${name}`)}
            value={value}
            readOnly
          />
        )}
      />
      {hasSipUri && (
        <Controller
          name={OTHER_VALUES.sipUri}
          control={control}
          render={({ field: { name, ...rest }, fieldState: { error } }) => (
            <TextField
              data-fui-tid={getTestId(name)}
              placeholder={t('equipment:sipUriPlaceholder')}
              fullWidth
              label='SIP URI'
              error={!!error?.message}
              helperText={t(error?.message as string)}
              inputProps={{
                'data-testid': name,
              }}
              required={isRequiredField(name)}
              limitedSymbols={
                MonitoringConsts.EQUIPMENT_FIELDS_LIMITS[name] ?? undefined
              }
              {...rest}
            />
          )}
        />
      )}
      <Controller
        name={OTHER_VALUES.manufacturerName}
        control={control}
        render={({ field: { value, name } }) => (
          <TextField
            data-fui-tid={getTestId(name)}
            label={t(`controller:${name}`)}
            value={value}
            readOnly
          />
        )}
      />
      <Controller
        name={OTHER_VALUES.bidirectional}
        control={control}
        render={({ field: { value, name, ...rest } }) => (
          <Switch
            data-fui-tid={getTestId(name)}
            inputProps={{
              'data-testid': name,
            }}
            label={t(`device:${name}`)}
            checked={!!value}
            required={isRequiredField(name)}
            {...rest}
          />
        )}
      />
      <Controller
        name={OTHER_VALUES.type}
        control={control}
        render={({ field: { name, ...rest }, fieldState: { error } }) => (
          <InterfaceSelect
            data-fui-tid={getTestId(name)}
            data-testid={name}
            required={isRequiredField(name)}
            error={!!error?.message}
            helperText={t(error?.message as string)}
            {...rest}
          />
        )}
      />

      {isEthernet && (
        <>
          {Object.values(ETHERNET_VALUES).map((inputName) => {
            const isIp = inputName === 'ip';
            const isMac = inputName === 'mac';
            const protocolIp = inputName === 'protocolIp';
            const ieee8021x = inputName === 'ieee8021x';

            const mask = (() => {
              if (isMac) {
                return InputMask.mac;
              }

              return undefined;
            })();

            if (protocolIp) {
              return (
                <Controller
                  name={ETHERNET_VALUES.protocolIp}
                  control={control}
                  render={({
                    field: { name, ...rest },
                    fieldState: { error },
                  }) => (
                    <ProtocolIpSelect
                      data-fui-tid={getTestId(inputName)}
                      error={!!error?.message}
                      helperText={t(error?.message as string)}
                      required
                      {...rest}
                    />
                  )}
                />
              );
            }

            if (ieee8021x) {
              return (
                <Controller
                  name={ETHERNET_VALUES.ieee8021x}
                  control={control}
                  render={({
                    field: { name, ...rest },
                    fieldState: { error },
                  }) => (
                    <Select8021X
                      data-fui-tid={getTestId(inputName)}
                      error={!!error?.message}
                      helperText={t(error?.message as string)}
                      required
                      {...rest}
                    />
                  )}
                />
              );
            }

            return (
              <Controller
                key={inputName}
                name={inputName}
                control={control}
                render={({
                  field: { value, name, ...rest },
                  fieldState: { error },
                }) => {
                  if (isIp) {
                    return (
                      <IpInput
                        data-fui-tid={getTestId(inputName)}
                        value={(value as string) ?? ''}
                        error={!!error?.message}
                        helperText={t(error?.message as string)}
                        label={name}
                        // HACK: use updateDeviceSchema to check required ip
                        required={(() => {
                          switch (inputName) {
                            case 'ip':
                              return true;

                            default:
                              isRequiredField(name);
                          }
                        })()}
                        {...rest}
                      />
                    );
                  }

                  return (
                    <TextField
                      data-fui-tid={getTestId(inputName)}
                      fullWidth
                      label={t(`controller:${name}`)}
                      error={!!error?.message}
                      helperText={t(error?.message as string)}
                      multiline={isMultilineValue(name)}
                      inputProps={{
                        'data-testid': name,
                      }}
                      // HACK: use updateDeviceSchema to check required mac
                      required={(() => {
                        switch (inputName) {
                          case 'mac':
                            return true;
                          default:
                            return isRequiredField(name);
                        }
                      })()}
                      value={value}
                      mask={mask}
                      limitedSymbols={
                        MonitoringConsts.EQUIPMENT_FIELDS_LIMITS[name] ??
                        undefined
                      }
                      {...rest}
                    />
                  );
                }}
              />
            );
          })}
        </>
      )}

      {isAvLan && (
        <>
          {Object.values(AVLAN_VALUES).map((inputName) => {
            const isMac = inputName === 'mac';
            const isIpAvLan = inputName === 'ipAvLan';

            return (
              <Controller
                key={inputName}
                name={inputName}
                control={control}
                render={({
                  field: { value, name, ...rest },
                  fieldState: { error },
                }) => {
                  if (isIpAvLan) {
                    return (
                      <IpInput
                        data-fui-tid={getTestId(inputName)}
                        value={(value as string) ?? ''}
                        error={!!error?.message}
                        helperText={t(error?.message as string)}
                        label={name}
                        required
                        {...rest}
                      />
                    );
                  }

                  return (
                    <TextField
                      data-fui-tid={getTestId(inputName)}
                      fullWidth
                      label={t(`controller:${name}`)}
                      error={!!error?.message}
                      helperText={t(error?.message as string)}
                      multiline={isMultilineValue(name)}
                      inputProps={{
                        'data-testid': name,
                      }}
                      // HACK: use updateDeviceSchema to check required mac
                      required={(() => {
                        switch (inputName) {
                          case 'mac':
                            return false;
                          default:
                            return isRequiredField(name);
                        }
                      })()}
                      value={value}
                      mask={isMac ? InputMask.mac : undefined}
                      {...rest}
                    />
                  );
                }}
              />
            );
          })}
        </>
      )}
      {isEthernet && (
        <>
          <Controller
            name={OTHER_VALUES.netInterface}
            control={control}
            render={({ field: { onChange, value, name } }) => (
              <Switch
                data-fui-tid={getTestId(name)}
                margin='normal'
                label={t(`controller:${name}`)}
                checked={!!value}
                onChange={onChange}
                required={isRequiredField(name)}
              />
            )}
          />
          <EquipmentNetInterfaceListForm
            name={OTHER_VALUES.netInterfaceInfo}
            netInterfaceName={OTHER_VALUES.netInterface}
            isRequiredField={isRequiredField}
          />
        </>
      )}
      <Controller
        name={OTHER_VALUES.disableMonitoring}
        control={control}
        render={({ field: { onChange, value } }) => {
          const handleChange: SegmentButtonProps['onChange'] = (
            _,
            newValue,
          ) => {
            onChange(newValue);
          };

          return (
            <DisableMonitoringButton value={!!value} onChange={handleChange} />
          );
        }}
      />
    </>
  );
};


import { Ieee8021X } from '@/widgets/Monitoring/model/networkEquipment.model';
import { Select, SelectProps } from '@shared/components';

export const Select8021X = ({ value, ...rest }: SelectProps) => {
  const options = [
    { label: 'MAB', value: Ieee8021X.MAB },
    { label: 'EAP-TLS', value: Ieee8021X.EAP_TLS },
    { label: 'NOT_SUPPORT', value: Ieee8021X.NOT_SUPPORT },
  ];

  const normalizedValue = value ?? '';

  console.log('Select8021X value:', value);
  console.log('Normalized value passed to Select:', normalizedValue);

  return (
    <Select
      options={options}
      label='802.1X'
      value={normalizedValue}
      {...rest}
    />
  );
};


import { InterfaceType } from '@/shared/api/controller/client';
import { Ieee8021X } from '@/widgets/Monitoring/model/networkEquipment.model';
import { Schema } from '@shared/lib/Schema';
import { SchemaMessage } from '@shared/lib/SchemaMessage';
import { Validator } from '@shared/lib/Validator';
import * as yup from 'yup';
import { array, boolean, object, string } from 'yup';
import { OTHER_VALUES } from '../model/formNames';

const validator = new Validator();
const schemaMessage = new SchemaMessage();

export const createDeviceFormSchema = object().shape(
  {
    name: string().required(schemaMessage.requiredMessage),
    description: string().notRequired(),
    bidirectional: boolean().notRequired(),
    modelId: string().required(schemaMessage.requiredMessage),
    sipUri: Schema.sipUriSchema,
    ip: string().when('type', ([type]: InterfaceType[], schema) => {
      if (type === 'ethernet') {
        return schema
          .required(schemaMessage.requiredMessage)
          .matches(validator.ipV4RegExp, schemaMessage.wrongFormatMessage);
      }
      return schema.notRequired().nullable();
    }),

    mac: string().when('type', ([type]: InterfaceType[], schema) => {
      if (type === 'ethernet') {
        return schema
          .required(schemaMessage.requiredMessage)
          .matches(validator.macRegExp, schemaMessage.wrongFormatMessage);
      }
      if (type === 'av-lan') {
        return schema.notRequired().nullable(); // или можно просто .optional()
      }
      return schema.notRequired().nullable();
    }),
    controlPage: string().when('controlPage', (controlPage, schema) => {
      if (!controlPage) {
        return schema.notRequired().nullable();
      }

      return schema
        .matches(validator.controlPageRegExp, schemaMessage.wrongFormatMessage)
        .notRequired();
    }),
    hardwareId: Schema.hardwareId,
    type: Schema.interfaceType,
    ieee8021x: yup
      .mixed<Ieee8021X>()
      .oneOf(
        [Ieee8021X.MAB, Ieee8021X.EAP_TLS, Ieee8021X.NOT_SUPPORT],
        schemaMessage.ieee8021XMessage,
      )
      .when('type', ([type]: InterfaceType[], schema) => {
        if (type === 'ethernet') {
          return schema.required(schemaMessage.requiredMessage);
        }
        return schema.notRequired().nullable();
      }),
    protocolIp: Schema.protocolIp.when('type', {
      is: 'ethernet',
      then: (schema) => schema.required(schemaMessage.requiredMessage),
      otherwise: (schema) => schema.notRequired(),
    }),
    firmware: string().nullable(),
    serialNumber: string().nullable(),
    inventoryNumber: string().nullable(),
    ipAvLan: string().when('type', ([type]: InterfaceType[], schema) => {
      if (type === 'av-lan') {
        return schema
          .matches(validator.ipV4RegExp, schemaMessage.wrongFormatMessage)
          .required();
      }

      return schema.notRequired().nullable();
    }),
    localAddress: Schema.localAddressCreateSchema,
    port: Schema.portNotRequired,
    netInterface: boolean().optional(),
    disableMonitoring: boolean().optional(),
    netInterfaceInfo: array().when(
      [OTHER_VALUES.netInterface, OTHER_VALUES.type],
      ([netInterface, type], schema) => {
        if (netInterface && type === 'ethernet') {
          return schema.of(
            object({
              nameId: string().required(schemaMessage.requiredMessage),
              ip: Schema.ipV4NotRequired,
              mac: Schema.macNotRequired,
              subnetMask: Schema.ipV4NotRequired,
              gateway: Schema.ipV4NotRequired,
            }),
          );
        } else {
          return schema.optional().default([]);
        }
      },
    ),
  },
  [
    ['mac', 'mac'],
    ['port', 'port'],
    ['controlPage', 'controlPage'],
    ['localAddress', 'localAddress'],
  ],
);


import { AppConsts } from '@/shared/consts';
import {
  Ieee8021X,
  ProtocolIp,
  Segment,
} from '@/widgets/Monitoring/model/networkEquipment.model';
import { InterfaceType } from '@shared/api/controller/client';
import { SchemaMessage } from '@shared/lib/SchemaMessage';
import { Validator } from '@shared/lib/Validator';
import * as yup from 'yup';
import { StringSchema, number, string } from 'yup';

export class Schema {
  private static validator: Validator = new Validator();

  private static schemaMessage: SchemaMessage = new SchemaMessage();

  public static ipV4Required = string()
    .required(Schema.schemaMessage.requiredMessage)
    .test('ip', this.schemaMessage.wrongFormatMessage, this.validator.ipV4);

  public static ipV4 = string().test(
    'ip',
    this.schemaMessage.wrongFormatMessage,
    this.validator.ipV4,
  );

  public static ipV4NotRequired = string()
    .nullable()
    .notRequired()
    .test('ip-validation', this.schemaMessage.wrongFormatMessage, (value) => {
      if (!value || value.trim() === '') return true;
      return this.validator.ipV4RegExp.test(value);
    });

  public static deviceIpV4 = string()
    .required(Schema.schemaMessage.requiredMessage)
    .matches(
      Schema.validator.ipV4RegExp,
      Schema.schemaMessage.wrongFormatMessage,
    );

  public static deviceMac = string()
    .required(Schema.schemaMessage.requiredMessage)
    .matches(
      Schema.validator.macRegExp,
      Schema.schemaMessage.wrongFormatMessage,
    );

  public static macNotRequired = string()
    .nullable()
    .notRequired()
    .test('mac-validation', this.schemaMessage.wrongFormatMessage, (value) => {
      if (!value || value.trim() === '') return true;
      return this.validator.macRegExp.test(value);
    });

  public static portNotRequired = number().when('port', ([port], schema) => {
    if (!port) {
      return schema
        .transform((value) => (Number.isNaN(value) ? null : value))
        .notRequired()
        .nullable();
    }

    return schema
      .transform((value) => (Number.isNaN(value) ? null : value))
      .test(
        'port',
        this.schemaMessage.interfacePortMessage,
        this.validator.port,
      );
  });

  public static portRequired = number()
    .required(this.schemaMessage.requiredMessage)
    .transform((value) => (isNaN(value) ? null : value))
    .test('port', this.schemaMessage.interfacePortMessage, this.validator.port);

  public static telnetPort = string().max(
    5,
    this.schemaMessage.getMaxMessage(5),
  );

  public static mac = string().when('port', (port: InterfaceType[], schema) => {
    if (port.includes('ethernet')) {
      return schema
        .required(this.schemaMessage.requiredMessage)
        .matches(
          this.validator.macRegExp,
          this.schemaMessage.wrongFormatMessage,
        );
    }

    return schema;
  });

  public static hardwareId: StringSchema = yup
    .string()
    .required(this.schemaMessage.requiredMessage)
    .max(50, this.schemaMessage.getMaxMessage(50));

  public static interfaceType = yup
    .mixed<InterfaceType>()
    .oneOf(
      ['serial', 'infrared', 'ethernet', 'av-lan'],
      this.schemaMessage.interfaceTypeMessage,
    )
    .required(this.schemaMessage.requiredMessage);

  public static protocolIp = yup
    .mixed<ProtocolIp>()
    .oneOf(
      [ProtocolIp.STATIC, ProtocolIp.DHCP],
      this.schemaMessage.protocolIpMessage,
    );

  public static ieee8021x = yup
    .mixed<Ieee8021X>()
    .oneOf(
      [Ieee8021X.MAB, Ieee8021X.EAP_TLS, Ieee8021X.NOT_SUPPORT],
      this.schemaMessage.ieee8021XMessage,
    );

  public static segment = yup
    .mixed<Segment>()
    .oneOf([Segment.SIGMA, Segment.OMEGA], this.schemaMessage.segmentMessage);

  public static controlPage = string().test(
    'controlPage',
    this.schemaMessage.wrongFormatMessage,
    this.validator.controlPage,
  );

  public static timeZoneSchema = string().test(
    'timeZone',
    this.schemaMessage.wrongFormatMessage,
    this.validator.timeZone,
  );

  public static ipV4FieldSchema = string().test(
    'ipV4Field',
    this.schemaMessage.wrongFormatMessage,
    this.validator.ipV4Field,
  );

  public static localAddressCreateSchema = string().when(
    'localAddress',
    ([localAddress], schema) => {
      if (!localAddress) {
        return schema
          .transform((value) => value || undefined)
          .notRequired()
          .nullable();
      }

      return schema.matches(
        this.validator.ipV4RegExp,
        this.schemaMessage.wrongFormatMessage,
      );
    },
  );

  public static sipUriSchema = string()
    .optional()
    .test('sipUri-format', this.schemaMessage.sipUriFormatMessage, (value) => {
      if (!value) {
        return true;
      }

      const match = value.match(AppConsts.SIP_URI_REGEX);

      return !!match;
    })
    .test('sipUri-domain', this.schemaMessage.sipUriDomainMessage, (value) => {
      if (!value) {
        return true;
      }

      const match = value.match(AppConsts.SIP_URI_REGEX);

      if (!match) {
        return true;
      }

      const { domain } = match.groups ?? {};

      const allowedDomains = [
        'sber.ru',
        'sberbank.ru',
        'voip.sigma.sbrf.ru',
        'sberbank-pb.ru',
        'sberbank-cib.ru',
        'ensys-edge.sber.ru',
      ];

      return allowedDomains.includes(domain);
    });
}

export enum ProtocolIp {
  DHCP = 'dhcp',
  STATIC = 'static',
}

export enum Ieee8021X {
  MAB = 'MAB',
  EAP_TLS = 'EAP-TLS',
  NOT_SUPPORT = 'NOT_SUPPORT',
}

export type EquipmentInterfaceDto = {
  protocolIp: ProtocolIp;
  port: number;
  ieee8021x: Ieee8021X;
};

export type EquipmentTypeDto = {
  id: string;
  name: string;
};

export type EquipmentManufacturerDto = {
  id: string;
  name: string;
};

export type EquipmentModelDto = {
  id: string;
  name: string;
  type: EquipmentTypeDto;
  manufacturer: EquipmentManufacturerDto;
};

export type SecondaryInterfaceDto = {
  id: string;
  nameId: string;
  ownerType: 'Controller';
  ownerId: string;
  IP: string;
  SubnetMask: string;
  Gateway: string;
  MAC: string;
};

export enum InterfaceType {
  'ETHERNET' = 'ethernet',
}

export enum Segment {
  SIGMA = 'sigma',
  OMEGA = 'omega',
}

export type NetworkEquipmentDto = {
  id: string;
  name: string;
  locationId: string;
  status: string;
  ip: string;
  mac: string;
  subnetMask: string;
  gateway: string;
  interface: EquipmentInterfaceDto;
  model: EquipmentModelDto;
  timeZone: string;
  segment: Segment;
  description?: string;
  controlPage?: string;
  telnetPort?: number;
  firmware?: string;
  serialNumber?: string;
  inventoryNumber?: string;
  interfaceType?: InterfaceType;
  sendNotifications?: boolean;
  netInterface?: boolean;
  netInterfaceInfo?: SecondaryInterfaceDto[];
  inventarisationOnly?: boolean;
};

после изменения интерфейса у меня Select8021X value: MAB
VM17457 Select802-1X.tsx:32 Normalized value passed to Select: MAB
CreateDeviceDrawer.tsx:139 {ip: {…}, mac: {…}, ieee8021x: {…}}ieee8021x: {message: 'common:messages.requiredMessage', type: 'optionality', ref: {…}}ip: {message: 'common:messages.requiredMessage', type: 'required', ref: {…}}mac: {message: 'common:messages.requiredMessage', type: 'required', ref: {…}}[[Prototype]]: Object
CreateDeviceDrawer.tsx:140 {name: '', description: '', ip: '', mac: '', controlPage: '', …}bidirectional: falsecontrolPage: ""description: ""disableMonitoring: falsefirmware: nullhardwareId: ""hasSipUri: nullieee8021x: undefinedinventoryNumber: nullip: ""ipAvLan: ""localAddress: undefinedmac: ""manufacturerName: ""modelId: ""name: ""netInterface: falsenetInterfaceInfo: []port: undefinedprotocolIp: "dhcp"serialNumber: nullsipUri: ""type: "ethernet"typeName: ""[[Prototype]]: Object
index.js:485 [webpack-dev-server] App updated. Recompiling...
index.js:485 [webpack-dev-server] App hot update...
log.js:39 [HMR] Checking for updates on the server...
log.js:39 [HMR] Updated modules:
log.js:39 [HMR]  - ./src/widgets/Devices/ui/Select802-1X/Select802-1X.tsx
log.js:39 [HMR] App is up to date.
Select802-1X.tsx:13 Select8021X value: MAB
Select802-1X.tsx:14 Normalized value passed to Select: MAB

и из ui не отчищается выбор поля селекта