mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-25 17:04:54 +00:00
* Fix the styling issue for the teams and user selection component in the alert form * Fix the incorrect field names in form error messages * Fix and modify cypress tests * Fix the incorrect util function import * update the field name in form validation message * Update proper assertions
This commit is contained in:
parent
fd942a27a6
commit
7a68ee30e0
@ -13,7 +13,7 @@
|
||||
import {
|
||||
DELETE_TERM,
|
||||
INVALID_NAMES,
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128,
|
||||
NAME_VALIDATION_ERROR,
|
||||
SEARCH_ENTITY_TABLE,
|
||||
} from '../constants/constants';
|
||||
@ -47,9 +47,10 @@ export const validateDomainForm = () => {
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.type(INVALID_NAMES.MAX_LENGTH);
|
||||
cy.get('#name_help')
|
||||
.should('be.visible')
|
||||
.contains(NAME_MAX_LENGTH_VALIDATION_ERROR);
|
||||
cy.get('#name_help').should(
|
||||
'contain',
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128
|
||||
);
|
||||
|
||||
// with special char validation
|
||||
cy.get('[data-testid="name"]')
|
||||
|
@ -14,7 +14,7 @@
|
||||
import {
|
||||
DELETE_TERM,
|
||||
INVALID_NAMES,
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128,
|
||||
NAME_VALIDATION_ERROR,
|
||||
} from '../constants/constants';
|
||||
import { SidebarItem } from '../constants/Entity.interface';
|
||||
@ -40,9 +40,10 @@ export const validateForm = () => {
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.type(INVALID_NAMES.MAX_LENGTH);
|
||||
cy.get('#name_help')
|
||||
.should('be.visible')
|
||||
.contains(NAME_MAX_LENGTH_VALIDATION_ERROR);
|
||||
cy.get('#name_help').should(
|
||||
'contain',
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128
|
||||
);
|
||||
|
||||
// with special char validation
|
||||
cy.get('[data-testid="name"]')
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { EXAMPLE_LONG_STRING } from '../../constants/constants';
|
||||
|
||||
export const validateFormNameFieldInput = ({
|
||||
fieldSelector = '#name',
|
||||
checkEmpty = true,
|
||||
checkLong = true,
|
||||
fieldName,
|
||||
errorDivSelector,
|
||||
value,
|
||||
}: {
|
||||
value: string;
|
||||
fieldName: string;
|
||||
errorDivSelector: string;
|
||||
fieldSelector?: string;
|
||||
checkEmpty?: boolean;
|
||||
checkLong?: boolean;
|
||||
}) => {
|
||||
if (checkEmpty) {
|
||||
// Check empty name field message
|
||||
cy.get(fieldSelector).type('test');
|
||||
cy.get(fieldSelector).clear();
|
||||
cy.get(`${errorDivSelector} .ant-form-item-explain-error`).contains(
|
||||
`${fieldName} is required`
|
||||
);
|
||||
}
|
||||
|
||||
if (checkLong) {
|
||||
// Check long name field message
|
||||
cy.get(fieldSelector).type(EXAMPLE_LONG_STRING);
|
||||
cy.get(`${errorDivSelector} .ant-form-item-explain-error`).contains(
|
||||
`${fieldName} size must be between 1 and 128`
|
||||
);
|
||||
cy.get(fieldSelector).clear();
|
||||
}
|
||||
|
||||
cy.get(fieldSelector).type(value);
|
||||
};
|
@ -17,6 +17,7 @@ import {
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../common';
|
||||
import { validateFormNameFieldInput } from './Form';
|
||||
|
||||
const TEAM_TYPES = ['Department', 'Division', 'Group'];
|
||||
|
||||
@ -179,7 +180,12 @@ export const addTeam = (
|
||||
verifyResponseStatusCode('@addTeam', 200);
|
||||
|
||||
// Entering team details
|
||||
cy.get('[data-testid="name"]').type(teamDetails.name);
|
||||
validateFormNameFieldInput({
|
||||
value: teamDetails.name,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="name"]',
|
||||
errorDivSelector: '#add-team-nest-messages_name_help',
|
||||
});
|
||||
|
||||
cy.get('[data-testid="display-name"]').type(teamDetails.name);
|
||||
|
||||
|
@ -621,9 +621,8 @@ export const NAME_VALIDATION_ERROR =
|
||||
|
||||
export const NAME_MIN_MAX_LENGTH_VALIDATION_ERROR =
|
||||
'Name size must be between 2 and 64';
|
||||
|
||||
export const NAME_MAX_LENGTH_VALIDATION_ERROR =
|
||||
'Name can be a maximum of 128 characters';
|
||||
export const NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128 =
|
||||
'Name size must be between 1 and 128';
|
||||
|
||||
export const DOMAIN_1 = {
|
||||
name: 'Cypress%Domain',
|
||||
@ -836,3 +835,5 @@ export const JWT_EXPIRY_TIME_MAP = {
|
||||
'1 hour': 3600,
|
||||
'2 hours': 7200,
|
||||
};
|
||||
|
||||
export const EXAMPLE_LONG_STRING = 'name'.repeat(33); // 132 characters
|
||||
|
@ -20,7 +20,7 @@ import { visitEntityDetailsPage } from '../../common/Utils/Entity';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import {
|
||||
INVALID_NAMES,
|
||||
NAME_MAX_LENGTH_VALIDATION_ERROR,
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128,
|
||||
NAME_VALIDATION_ERROR,
|
||||
uuid,
|
||||
} from '../../constants/constants';
|
||||
@ -53,7 +53,10 @@ const validateForm = (isColumnMetric = false) => {
|
||||
|
||||
// max length validation
|
||||
cy.get('#name').scrollIntoView().type(INVALID_NAMES.MAX_LENGTH);
|
||||
cy.get('#name_help').should('contain', NAME_MAX_LENGTH_VALIDATION_ERROR);
|
||||
cy.get('#name_help').should(
|
||||
'contain',
|
||||
NAME_MIN_MAX_LENGTH_VALIDATION_ERROR_1_128
|
||||
);
|
||||
|
||||
// with special char validation
|
||||
cy.get('#name')
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
uuid,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { BASE_URL } from '../../constants/constants';
|
||||
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
||||
|
||||
@ -44,7 +45,11 @@ describe(
|
||||
cy.get('[data-testid="inactive-link"]').should('contain', 'Add New Role');
|
||||
|
||||
// Entering name
|
||||
cy.get('#name').type(roleName);
|
||||
validateFormNameFieldInput({
|
||||
value: roleName,
|
||||
fieldName: 'Name',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
// Entering descrription
|
||||
cy.get(descriptionBox).type('description');
|
||||
// Select the policies
|
||||
|
@ -33,6 +33,7 @@ import {
|
||||
createSingleLevelEntity,
|
||||
hardDeleteService,
|
||||
} from '../../common/EntityUtils';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import {
|
||||
ALERT_DESCRIPTION,
|
||||
@ -155,7 +156,11 @@ describe(
|
||||
cy.get('[data-testid="create-notification"]').click();
|
||||
|
||||
// Enter alert name
|
||||
cy.get('#name').type(ALERT_NAME);
|
||||
validateFormNameFieldInput({
|
||||
value: ALERT_NAME,
|
||||
fieldName: 'Name',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
|
||||
// Enter description
|
||||
cy.get(descriptionBox).clear().type(ALERT_DESCRIPTION);
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { createEntityTable, hardDeleteService } from '../../common/EntityUtils';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import {
|
||||
ALERT_DESCRIPTION,
|
||||
@ -371,7 +372,11 @@ describe(
|
||||
cy.get('[data-testid="create-observability"]').click();
|
||||
|
||||
// Enter alert name
|
||||
cy.get('#name').type(ALERT_NAME);
|
||||
validateFormNameFieldInput({
|
||||
value: ALERT_NAME,
|
||||
fieldName: 'Name',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
|
||||
// Enter description
|
||||
cy.get(descriptionBox).clear().type(ALERT_DESCRIPTION);
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { getToken } from '../../common/Utils/LocalStorage';
|
||||
import { DELETE_TERM } from '../../constants/constants';
|
||||
import { PERSONA_DETAILS, USER_DETAILS } from '../../constants/EntityConstant';
|
||||
@ -41,7 +42,12 @@ const updatePersonaDisplayName = (displayName) => {
|
||||
};
|
||||
|
||||
describe('Persona operations', { tags: 'Settings' }, () => {
|
||||
const user = {};
|
||||
const user = {
|
||||
details: {
|
||||
id: '',
|
||||
name: '',
|
||||
},
|
||||
};
|
||||
const userSearchText = `${USER_DETAILS.firstName}${USER_DETAILS.lastName}`;
|
||||
before(() => {
|
||||
cy.login();
|
||||
@ -87,6 +93,12 @@ describe('Persona operations', { tags: 'Settings' }, () => {
|
||||
it('Persona creation should work properly', () => {
|
||||
cy.get('[data-testid="add-persona-button"]').scrollIntoView().click();
|
||||
cy.get('[data-testid="name"]').clear().type(PERSONA_DETAILS.name);
|
||||
validateFormNameFieldInput({
|
||||
value: PERSONA_DETAILS.name,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="name"]',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
cy.get('[data-testid="displayName"]')
|
||||
.clear()
|
||||
.type(PERSONA_DETAILS.displayName);
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
uuid,
|
||||
verifyResponseStatusCode,
|
||||
} from '../../common/common';
|
||||
import { validateFormNameFieldInput } from '../../common/Utils/Form';
|
||||
import { BASE_URL } from '../../constants/constants';
|
||||
import { GlobalSettingOptions } from '../../constants/settings.constant';
|
||||
|
||||
@ -58,7 +59,12 @@ const newRuledescription = `This is ${newRuleName} description`;
|
||||
const updatedRuleName = `New-Rule-test-${uuid()}-updated`;
|
||||
|
||||
const addRule = (rulename, ruleDescription, descriptionIndex) => {
|
||||
cy.get('[data-testid="rule-name"]').should('be.visible').type(rulename);
|
||||
validateFormNameFieldInput({
|
||||
value: rulename,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="rule-name"]',
|
||||
errorDivSelector: '#ruleName_help',
|
||||
});
|
||||
// Enter rule description
|
||||
cy.get('.toastui-editor-md-container > .toastui-editor > .ProseMirror')
|
||||
.eq(descriptionIndex)
|
||||
@ -127,6 +133,12 @@ describe('Policy page should work properly', { tags: 'Settings' }, () => {
|
||||
|
||||
// Enter policy name
|
||||
cy.get('[data-testid="policy-name"]').should('be.visible').type(policyName);
|
||||
validateFormNameFieldInput({
|
||||
value: policyName,
|
||||
fieldName: 'Name',
|
||||
fieldSelector: '[data-testid="policy-name"]',
|
||||
errorDivSelector: '#name_help',
|
||||
});
|
||||
|
||||
// Enter description
|
||||
cy.get(descriptionBox).eq(0).type(description);
|
||||
|
@ -123,7 +123,17 @@ const PopoverContent: FC<PopoverContentProps> = ({
|
||||
onFinish={handleEmbedImage}>
|
||||
<Row gutter={[8, 8]}>
|
||||
<Col span={24}>
|
||||
<Form.Item name="Url" rules={[{ required: true, type: 'url' }]}>
|
||||
<Form.Item
|
||||
name="Url"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
type: 'url',
|
||||
message: t('label.field-required', {
|
||||
field: t('label.url-uppercase'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Input
|
||||
autoFocus
|
||||
data-testid="embed-input"
|
||||
|
@ -15,7 +15,8 @@ import QueryString from 'qs';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants';
|
||||
import { VALIDATION_MESSAGES } from '../../../constants/constants';
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { CSMode } from '../../../enums/codemirror.enum';
|
||||
import { CustomMetric } from '../../../generated/entity/data/table';
|
||||
import { getEntityName } from '../../../utils/EntityUtils';
|
||||
@ -76,29 +77,13 @@ const CustomMetricForm = ({
|
||||
data-testid="custom-metric-form"
|
||||
form={form}
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={onFinish}>
|
||||
<Form.Item
|
||||
label={t('label.name')}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.name'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: `${t('message.entity-maximum-size', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
})}`,
|
||||
},
|
||||
...NAME_FIELD_RULES,
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (metricNames.includes(value) && !isEditMode) {
|
||||
@ -126,9 +111,6 @@ const CustomMetricForm = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.column'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Select
|
||||
@ -152,9 +134,6 @@ const CustomMetricForm = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.sql-uppercase-query'),
|
||||
}),
|
||||
},
|
||||
]}
|
||||
trigger="onChange">
|
||||
|
@ -28,6 +28,7 @@ import { getEntityReferenceFromEntity } from '../../../utils/EntityUtils';
|
||||
import { fetchOptions, generateOptions } from '../../../utils/TasksUtils';
|
||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
||||
|
||||
import { VALIDATION_MESSAGES } from '../../../constants/constants';
|
||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
||||
import { TestCaseStatusModalProps } from './TestCaseStatusModal.interface';
|
||||
|
||||
@ -162,6 +163,7 @@ export const TestCaseStatusModal = ({
|
||||
id="update-status-form"
|
||||
initialValues={data}
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleFormSubmit}>
|
||||
<Form.Item
|
||||
label={t('label.status')}
|
||||
@ -169,9 +171,6 @@ export const TestCaseStatusModal = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.status'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Select
|
||||
@ -193,9 +192,6 @@ export const TestCaseStatusModal = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.reason'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Select
|
||||
@ -217,9 +213,6 @@ export const TestCaseStatusModal = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.comment'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<RichTextEditor
|
||||
@ -252,9 +245,6 @@ export const TestCaseStatusModal = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.assignee'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Assignees
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
PAGE_SIZE_MEDIUM,
|
||||
VALIDATION_MESSAGES,
|
||||
} from '../../../../constants/constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../../../constants/regex.constants';
|
||||
import { NAME_FIELD_RULES } from '../../../../constants/Form.constants';
|
||||
import { TestSuite } from '../../../../generated/tests/testSuite';
|
||||
import { DataQualityPageTabs } from '../../../../pages/DataQuality/DataQualityPage.interface';
|
||||
import { getListTestSuites } from '../../../../rest/testAPI';
|
||||
@ -78,22 +78,7 @@ const AddTestSuiteForm: React.FC<AddTestSuiteFormProps> = ({
|
||||
label={t('label.name')}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 256,
|
||||
message: `${t('message.entity-size-in-between', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '256',
|
||||
min: '1',
|
||||
})}`,
|
||||
},
|
||||
...NAME_FIELD_RULES,
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (testSuites.some((suite) => suite.name === value)) {
|
||||
|
@ -17,10 +17,8 @@ import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { UserTag } from '../../../components/common/UserTag/UserTag.component';
|
||||
import { UserTagSize } from '../../../components/common/UserTag/UserTag.interface';
|
||||
import {
|
||||
ENTITY_NAME_REGEX,
|
||||
HEX_COLOR_CODE_REGEX,
|
||||
} from '../../../constants/regex.constants';
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { HEX_COLOR_CODE_REGEX } from '../../../constants/regex.constants';
|
||||
import { usePermissionProvider } from '../../../context/PermissionProvider/PermissionProvider';
|
||||
import { ResourceEntity } from '../../../context/PermissionProvider/PermissionProvider.interface';
|
||||
import { CreateDataProduct } from '../../../generated/api/domains/createDataProduct';
|
||||
@ -72,20 +70,7 @@ const AddDomainForm = ({
|
||||
props: {
|
||||
'data-testid': 'name',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: `${t('message.entity-maximum-size', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
})}`,
|
||||
},
|
||||
],
|
||||
rules: NAME_FIELD_RULES,
|
||||
},
|
||||
{
|
||||
name: 'displayName',
|
||||
|
@ -16,7 +16,6 @@ import { Button, Form, Space, Typography } from 'antd';
|
||||
import { FormProps, useForm } from 'antd/lib/form/Form';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants';
|
||||
import {
|
||||
CreateGlossary,
|
||||
EntityReference,
|
||||
@ -29,6 +28,7 @@ import {
|
||||
import { getEntityName } from '../../../utils/EntityUtils';
|
||||
import { generateFormFields, getField } from '../../../utils/formUtils';
|
||||
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { EntityType } from '../../../enums/entity.enum';
|
||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
||||
import ResizablePanels from '../../common/ResizablePanels/ResizablePanels';
|
||||
@ -104,20 +104,7 @@ const AddGlossary = ({
|
||||
props: {
|
||||
'data-testid': 'name',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: `${t('message.entity-maximum-size', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
})}`,
|
||||
},
|
||||
],
|
||||
rules: NAME_FIELD_RULES,
|
||||
},
|
||||
{
|
||||
name: 'displayName',
|
||||
|
@ -17,10 +17,7 @@ import { t } from 'i18next';
|
||||
import { isEmpty, isString } from 'lodash';
|
||||
import React, { useEffect } from 'react';
|
||||
import { ReactComponent as DeleteIcon } from '../../../assets/svg/ic-delete.svg';
|
||||
import {
|
||||
ENTITY_NAME_REGEX,
|
||||
HEX_COLOR_CODE_REGEX,
|
||||
} from '../../../constants/regex.constants';
|
||||
import { HEX_COLOR_CODE_REGEX } from '../../../constants/regex.constants';
|
||||
import { EntityReference } from '../../../generated/entity/type';
|
||||
import {
|
||||
FieldProp,
|
||||
@ -31,6 +28,7 @@ import { getEntityName } from '../../../utils/EntityUtils';
|
||||
import { generateFormFields, getField } from '../../../utils/formUtils';
|
||||
import { fetchGlossaryList } from '../../../utils/TagsUtils';
|
||||
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { useApplicationStore } from '../../../hooks/useApplicationStore';
|
||||
import { UserTeam } from '../../common/AssigneeList/AssigneeList.interface';
|
||||
import { UserTag } from '../../common/UserTag/UserTag.component';
|
||||
@ -167,20 +165,7 @@ const AddGlossaryTermForm = ({
|
||||
props: {
|
||||
'data-testid': 'name',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: `${t('message.entity-maximum-size', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
})}`,
|
||||
},
|
||||
],
|
||||
rules: NAME_FIELD_RULES,
|
||||
},
|
||||
{
|
||||
name: 'displayName',
|
||||
|
@ -15,10 +15,7 @@ import { Form, Modal, Select } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
API_RES_MAX_SIZE,
|
||||
VALIDATION_MESSAGES,
|
||||
} from '../../../constants/constants';
|
||||
import { API_RES_MAX_SIZE } from '../../../constants/constants';
|
||||
import { getGlossaryTerms } from '../../../rest/glossaryAPI';
|
||||
import { getEntityName } from '../../../utils/EntityUtils';
|
||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
||||
@ -90,7 +87,6 @@ const ChangeParentHierarchy = ({
|
||||
form={form}
|
||||
id="change-parent-hierarchy-modal"
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleSubmit}>
|
||||
<Form.Item
|
||||
label={t('label.select-field', {
|
||||
@ -100,6 +96,9 @@ const ChangeParentHierarchy = ({
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.parent'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
<Select
|
||||
|
@ -20,7 +20,7 @@ import { isEmpty } from 'lodash';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { VALIDATION_MESSAGES } from '../../../../constants/constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../../../constants/regex.constants';
|
||||
import { NAME_FIELD_RULES } from '../../../../constants/Form.constants';
|
||||
import { Persona } from '../../../../generated/entity/teams/persona';
|
||||
import { EntityReference } from '../../../../generated/entity/type';
|
||||
import {
|
||||
@ -85,12 +85,7 @@ export const AddEditPersonaForm = ({
|
||||
autoComplete: 'off',
|
||||
},
|
||||
placeholder: t('label.name'),
|
||||
rules: [
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.custom-property-name-validation'),
|
||||
},
|
||||
],
|
||||
rules: NAME_FIELD_RULES,
|
||||
},
|
||||
{
|
||||
name: 'displayName',
|
||||
|
@ -15,6 +15,7 @@ import { Button, Form, FormProps, Select, Space } from 'antd';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, { FC, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { VALIDATION_MESSAGES } from '../../../../constants/constants';
|
||||
import {
|
||||
PersonalAccessToken,
|
||||
TokenType,
|
||||
@ -85,67 +86,62 @@ const AuthMechanismForm: FC<Props> = ({
|
||||
}, [isBot, authenticationMechanism]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
id="update-auth-mechanism-form"
|
||||
initialValues={{ authType, tokenExpiry }}
|
||||
layout="vertical"
|
||||
onFinish={handleSave}>
|
||||
<Form.Item label={t('label.auth-mechanism')} name="authType">
|
||||
<Select
|
||||
disabled
|
||||
className="w-full"
|
||||
data-testid="auth-mechanism"
|
||||
placeholder={t('label.select-field', {
|
||||
field: t('label.auth-mechanism'),
|
||||
})}>
|
||||
<Option key={authOptions.value}>{authOptions.label}</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form
|
||||
id="update-auth-mechanism-form"
|
||||
initialValues={{ authType, tokenExpiry }}
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleSave}>
|
||||
<Form.Item label={t('label.auth-mechanism')} name="authType">
|
||||
<Select
|
||||
disabled
|
||||
className="w-full"
|
||||
data-testid="auth-mechanism"
|
||||
placeholder={t('label.select-field', {
|
||||
field: t('label.auth-mechanism'),
|
||||
})}>
|
||||
<Option key={authOptions.value}>{authOptions.label}</Option>
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('label.token-expiration')}
|
||||
name="tokenExpiry"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
},
|
||||
]}>
|
||||
<Select
|
||||
className="w-full"
|
||||
data-testid="token-expiry"
|
||||
placeholder={t('message.select-token-expiration')}>
|
||||
{isBot
|
||||
? getJWTTokenExpiryOptions().map((option) => (
|
||||
<Option key={option.value}>{option.label}</Option>
|
||||
))
|
||||
: getJWTTokenExpiryOptions()
|
||||
.filter((option) => option.value !== 'Unlimited')
|
||||
.map((filteredOption) => (
|
||||
<Option key={filteredOption.value}>
|
||||
{filteredOption.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label={t('label.token-expiration')}
|
||||
name="tokenExpiry"
|
||||
rules={[{ required: true }]}>
|
||||
<Select
|
||||
className="w-full"
|
||||
data-testid="token-expiry"
|
||||
placeholder={t('message.select-token-expiration')}>
|
||||
{isBot
|
||||
? getJWTTokenExpiryOptions().map((option) => (
|
||||
<Option key={option.value}>{option.label}</Option>
|
||||
))
|
||||
: getJWTTokenExpiryOptions()
|
||||
.filter((option) => option.value !== 'Unlimited')
|
||||
.map((filteredOption) => (
|
||||
<Option key={filteredOption.value}>
|
||||
{filteredOption.label}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
|
||||
<Space className="w-full justify-end" size={4}>
|
||||
{!isEmpty(authenticationMechanism) && (
|
||||
<Button data-testid="cancel-edit" type="link" onClick={onCancel}>
|
||||
{t('label.cancel')}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
data-testid="save-edit"
|
||||
form="update-auth-mechanism-form"
|
||||
htmlType="submit"
|
||||
loading={isUpdating}
|
||||
type="primary">
|
||||
{t('label.generate')}
|
||||
<Space className="w-full justify-end" size={4}>
|
||||
{!isEmpty(authenticationMechanism) && (
|
||||
<Button data-testid="cancel-edit" type="link" onClick={onCancel}>
|
||||
{t('label.cancel')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
data-testid="save-edit"
|
||||
form="update-auth-mechanism-form"
|
||||
htmlType="submit"
|
||||
loading={isUpdating}
|
||||
type="primary">
|
||||
{t('label.generate')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -549,6 +549,9 @@ const CronEditor: FC<CronEditorProp> = (props) => {
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.cron'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
validator: async (_, value) => {
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Rule } from 'antd/lib/form';
|
||||
import { t } from 'i18next';
|
||||
import { ENTITY_NAME_REGEX } from './regex.constants';
|
||||
|
||||
export const NAME_FIELD_RULES: Rule[] = [
|
||||
{
|
||||
required: true,
|
||||
message: t('label.field-required', {
|
||||
field: t('label.name'),
|
||||
}),
|
||||
},
|
||||
{
|
||||
min: 1,
|
||||
max: 128,
|
||||
message: t('message.entity-size-in-between', {
|
||||
entity: t('label.name'),
|
||||
min: 1,
|
||||
max: 128,
|
||||
}),
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
];
|
@ -21,9 +21,9 @@ import Loader from '../../components/common/Loader/Loader';
|
||||
import ResizablePanels from '../../components/common/ResizablePanels/ResizablePanels';
|
||||
import RichTextEditor from '../../components/common/RichTextEditor/RichTextEditor';
|
||||
import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { ROUTES } from '../../constants/constants';
|
||||
import { ROUTES, VALIDATION_MESSAGES } from '../../constants/constants';
|
||||
import { NAME_FIELD_RULES } from '../../constants/Form.constants';
|
||||
import { GlobalSettingsMenuCategory } from '../../constants/GlobalSettings.constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
||||
import { CreateEventSubscription } from '../../generated/events/api/createEventSubscription';
|
||||
import {
|
||||
AlertType,
|
||||
@ -212,6 +212,7 @@ const AddNotificationPage = () => {
|
||||
...alert,
|
||||
resources: alert?.filteringRules?.resources,
|
||||
}}
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleSave}>
|
||||
{loadingCount > 0 ? (
|
||||
<Skeleton title paragraph={{ rows: 8 }} />
|
||||
@ -222,13 +223,7 @@ const AddNotificationPage = () => {
|
||||
label={t('label.name')}
|
||||
labelCol={{ span: 24 }}
|
||||
name="name"
|
||||
rules={[
|
||||
{ required: true },
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
]}>
|
||||
rules={NAME_FIELD_RULES}>
|
||||
<Input
|
||||
disabled={isEditMode}
|
||||
placeholder={t('label.name')}
|
||||
|
@ -21,8 +21,8 @@ import Loader from '../../components/common/Loader/Loader';
|
||||
import ResizablePanels from '../../components/common/ResizablePanels/ResizablePanels';
|
||||
import RichTextEditor from '../../components/common/RichTextEditor/RichTextEditor';
|
||||
import TitleBreadcrumb from '../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { ROUTES } from '../../constants/constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
||||
import { ROUTES, VALIDATION_MESSAGES } from '../../constants/constants';
|
||||
import { NAME_FIELD_RULES } from '../../constants/Form.constants';
|
||||
import { CreateEventSubscription } from '../../generated/events/api/createEventSubscription';
|
||||
import {
|
||||
AlertType,
|
||||
@ -217,6 +217,7 @@ function AddObservabilityPage() {
|
||||
...alert,
|
||||
resources: alert?.filteringRules?.resources,
|
||||
}}
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleSave}>
|
||||
<Row gutter={[20, 20]}>
|
||||
<Col span={24}>
|
||||
@ -224,13 +225,7 @@ function AddObservabilityPage() {
|
||||
label={t('label.name')}
|
||||
labelCol={{ span: 24 }}
|
||||
name="name"
|
||||
rules={[
|
||||
{ required: true },
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
]}>
|
||||
rules={NAME_FIELD_RULES}>
|
||||
<Input
|
||||
disabled={isEditMode}
|
||||
placeholder={t('label.name')}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.team-user-select-dropdown {
|
||||
.ant-card.team-user-select-dropdown {
|
||||
padding: 8px;
|
||||
|
||||
.ant-card-body {
|
||||
@ -38,7 +38,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.select-trigger {
|
||||
.ant-btn.select-trigger {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
@ -21,8 +21,8 @@ import ResizablePanels from '../../../components/common/ResizablePanels/Resizabl
|
||||
import RichTextEditor from '../../../components/common/RichTextEditor/RichTextEditor';
|
||||
import TitleBreadcrumb from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { ERROR_MESSAGE } from '../../../constants/constants';
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { GlobalSettingOptions } from '../../../constants/GlobalSettings.constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants';
|
||||
import {
|
||||
CreatePolicy,
|
||||
Effect,
|
||||
@ -131,22 +131,7 @@ const AddPolicyPage = () => {
|
||||
<Form.Item
|
||||
label={`${t('label.name')}:`}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
max: 128,
|
||||
min: 1,
|
||||
message: `${t('message.entity-size-in-between', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
min: '1',
|
||||
})}`,
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
]}>
|
||||
rules={NAME_FIELD_RULES}>
|
||||
<Input
|
||||
data-testid="policy-name"
|
||||
placeholder={t('label.policy-name')}
|
||||
|
@ -19,7 +19,7 @@ import { capitalize, startCase, uniq, uniqBy } from 'lodash';
|
||||
import React, { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import RichTextEditor from '../../../components/common/RichTextEditor/RichTextEditor';
|
||||
import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants';
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import {
|
||||
Effect,
|
||||
Operation,
|
||||
@ -203,22 +203,7 @@ const RuleForm: FC<RuleFormProps> = ({ ruleData, setRuleData }) => {
|
||||
<Form.Item
|
||||
label={`${t('label.rule-name')}:`}
|
||||
name="ruleName"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
max: 128,
|
||||
min: 1,
|
||||
message: `${t('message.entity-size-in-between', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
min: '1',
|
||||
})}`,
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
]}>
|
||||
rules={NAME_FIELD_RULES}>
|
||||
<Input
|
||||
data-testid="rule-name"
|
||||
placeholder={t('label.rule-name')}
|
||||
|
@ -21,8 +21,8 @@ import ResizablePanels from '../../../components/common/ResizablePanels/Resizabl
|
||||
import RichTextEditor from '../../../components/common/RichTextEditor/RichTextEditor';
|
||||
import TitleBreadcrumb from '../../../components/common/TitleBreadcrumb/TitleBreadcrumb.component';
|
||||
import { ERROR_MESSAGE } from '../../../constants/constants';
|
||||
import { NAME_FIELD_RULES } from '../../../constants/Form.constants';
|
||||
import { GlobalSettingOptions } from '../../../constants/GlobalSettings.constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../../constants/regex.constants';
|
||||
import { Policy } from '../../../generated/entity/policies/policy';
|
||||
import { addRole, getPolicies } from '../../../rest/rolesAPIV1';
|
||||
import { getIsErrorMatch } from '../../../utils/CommonUtils';
|
||||
@ -132,22 +132,7 @@ const AddRolePage = () => {
|
||||
<Form.Item
|
||||
label={`${t('label.name')}:`}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
max: 128,
|
||||
min: 1,
|
||||
message: `${t('message.entity-size-in-between', {
|
||||
entity: `${t('label.name')}`,
|
||||
max: '128',
|
||||
min: '1',
|
||||
})}`,
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
]}>
|
||||
rules={NAME_FIELD_RULES}>
|
||||
<Input
|
||||
data-testid="name"
|
||||
placeholder={t('label.role-name')}
|
||||
|
@ -25,6 +25,7 @@ import TitleBreadcrumb from '../../../components/common/TitleBreadcrumb/TitleBre
|
||||
import ExploreSearchCard from '../../../components/ExploreV1/ExploreSearchCard/ExploreSearchCard';
|
||||
import { SearchedDataProps } from '../../../components/SearchedData/SearchedData.interface';
|
||||
import { FQN_SEPARATOR_CHAR } from '../../../constants/char.constants';
|
||||
import { VALIDATION_MESSAGES } from '../../../constants/constants';
|
||||
import { EntityField } from '../../../constants/Feeds.constants';
|
||||
import { TASK_SANITIZE_VALUE_REGEX } from '../../../constants/regex.constants';
|
||||
import { EntityTabs, EntityType } from '../../../enums/entity.enum';
|
||||
@ -108,9 +109,9 @@ const UpdateDescription = () => {
|
||||
|
||||
const getDescription = () => {
|
||||
if (!isEmpty(columnObject) && !isUndefined(columnObject)) {
|
||||
return columnObject.description || '';
|
||||
return columnObject.description ?? '';
|
||||
} else {
|
||||
return entityData.description || '';
|
||||
return entityData.description ?? '';
|
||||
}
|
||||
};
|
||||
|
||||
@ -225,6 +226,7 @@ const UpdateDescription = () => {
|
||||
data-testid="form-container"
|
||||
form={form}
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={onCreateTask}>
|
||||
<Form.Item
|
||||
data-testid="title"
|
||||
@ -241,14 +243,7 @@ const UpdateDescription = () => {
|
||||
data-testid="assignees"
|
||||
label={`${t('label.assignee-plural')}:`}
|
||||
name="assignees"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('message.field-text-is-required', {
|
||||
fieldText: t('label.assignee-plural'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
rules={[{ required: true }]}>
|
||||
<Assignees
|
||||
options={options}
|
||||
value={assignees}
|
||||
@ -262,14 +257,7 @@ const UpdateDescription = () => {
|
||||
data-testid="description-tabs"
|
||||
label={`${t('label.description')}:`}
|
||||
name="description"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: t('message.field-text-is-required', {
|
||||
fieldText: t('label.description'),
|
||||
}),
|
||||
},
|
||||
]}>
|
||||
rules={[{ required: true }]}>
|
||||
<DescriptionTabs
|
||||
suggestion={currentDescription}
|
||||
value={currentDescription}
|
||||
|
@ -19,7 +19,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import RichTextEditor from '../../components/common/RichTextEditor/RichTextEditor';
|
||||
import { EditorContentRef } from '../../components/common/RichTextEditor/RichTextEditor.interface';
|
||||
import { VALIDATION_MESSAGES } from '../../constants/constants';
|
||||
import { ENTITY_NAME_REGEX } from '../../constants/regex.constants';
|
||||
import { NAME_FIELD_RULES } from '../../constants/Form.constants';
|
||||
import { Team, TeamType } from '../../generated/entity/teams/team';
|
||||
import {
|
||||
FieldProp,
|
||||
@ -120,17 +120,7 @@ const AddTeamForm: React.FC<AddTeamFormType> = ({
|
||||
label={t('label.name')}
|
||||
name="name"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
type: 'string',
|
||||
min: 1,
|
||||
max: 128,
|
||||
whitespace: true,
|
||||
},
|
||||
{
|
||||
pattern: ENTITY_NAME_REGEX,
|
||||
message: t('message.entity-name-validation'),
|
||||
},
|
||||
...NAME_FIELD_RULES,
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
Switch,
|
||||
TooltipProps,
|
||||
} from 'antd';
|
||||
import { RuleObject } from 'antd/lib/form';
|
||||
import { TooltipPlacement } from 'antd/lib/tooltip';
|
||||
import classNames from 'classnames';
|
||||
import { compact, startCase } from 'lodash';
|
||||
@ -64,7 +65,12 @@ export const getField = (field: FieldProp) => {
|
||||
let internalFormItemProps: FormItemProps = {};
|
||||
let fieldElement: ReactNode = null;
|
||||
let fieldRules = [...rules];
|
||||
if (required) {
|
||||
// Check if required rule is already present to avoid rule duplication
|
||||
const isRequiredRulePresent = rules.some(
|
||||
(rule) => (rule as RuleObject).required ?? false
|
||||
);
|
||||
|
||||
if (required && !isRequiredRulePresent) {
|
||||
fieldRules = [
|
||||
...fieldRules,
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user