Skip to content

Commit

Permalink
Merge pull request #194 from webzard-io/bowen/validation
Browse files Browse the repository at this point in the history
feat: fix annotation validation rule
  • Loading branch information
MrWindlike authored Nov 4, 2024
2 parents ffb6633 + 24d1922 commit 0b0c6ce
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 46 deletions.
53 changes: 53 additions & 0 deletions packages/refine/__tests__/plugins/validation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { validateLabelKey, validateLabelValue } from '../../src/utils/validation';

describe('validation', () => {
it('validateLabelKey', async () => {
const validArray = ['a', 'a/b', 'x-io/a'];
const invalidArray = [
'',
'#$#$',
'#%/#$#',
'-sdsd',
'asda-',
'aa/sd.',
'-',
'.',
'/',
`${genStr(243)}/${genStr(64)}`,
];
expect(
validArray.every(str => {
return validateLabelKey(str).isValid;
})
).toBe(true);
expect(
invalidArray.every(str => {
return !validateLabelKey(str).isValid;
})
).toBe(true);
});
it('validateLabelValue', async () => {
const validArray = ['', 'a', 'a-._b'];
const invalidArray = ['-', '.', '_', '$#@(&', genStr(64)];
expect(
validArray.every(str => {
return validateLabelValue(str).isValid;
})
).toBe(true);
expect(
invalidArray.every(str => {
return !validateLabelValue(str).isValid;
})
).toBe(true);
});
});

function genStr(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
result += characters[randomIndex];
}
return result;
}
2 changes: 1 addition & 1 deletion packages/refine/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dovetail-v2/refine",
"version": "0.1.14-alpha.5",
"version": "0.1.14",
"type": "module",
"files": [
"dist",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const EditAnnotationForm = React.forwardRef<
defaultValue={defaultValue}
onSubmit={onSubmit}
addButtonText={t('dovetail.add_annotation')}
noValueValidation
/>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ interface KeyValueTableFormFormProps<T extends KeyValuePair> {
onSubmit: (value: T[]) => Promise<unknown> | undefined;
extraColumns?: TableFormColumn[];
addButtonText?: string;
noValueValidation?: boolean;
}

function _KeyValueTableFormForm<RowType extends KeyValuePair>(
props: KeyValueTableFormFormProps<RowType>,
ref: React.ForwardedRef<EditFieldFormHandler>
) {
const { defaultValue, onSubmit, extraColumns, addButtonText } = props;
const { defaultValue, onSubmit, extraColumns, addButtonText, noValueValidation } =
props;
const { t } = useTranslation();
const [value, setValue] = useState<RowType[]>([]);
const tableFormRef = useRef<TableFormHandle>(null);
Expand Down Expand Up @@ -105,6 +107,7 @@ function _KeyValueTableFormForm<RowType extends KeyValuePair>(
title: t('dovetail.value_optional'),
type: 'input',
validator: ({ value }) => {
if (noValueValidation) return;
const { isValid } = validateLabelValue(value || '');
if (!isValid) return t('dovetail.format_error');
},
Expand All @@ -116,14 +119,14 @@ function _KeyValueTableFormForm<RowType extends KeyValuePair>(
hideEmptyTable
rowAddConfig={{
addible: true,
text: () => addButtonText
text: () => addButtonText,
}}
defaultData={defaultValue}
row={{
deletable: true,
}}
/>
<LabelFormatPopover />
<LabelFormatPopover noValueValidation={noValueValidation} />
</Space>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,47 +54,55 @@ export const PodLabelFormatRulePopoverStyle = css`
}
`;

export const LabelFormatPopover: React.FC = () => {
export const LabelFormatPopover: React.FC<{
noValueValidation?: boolean;
}> = ({ noValueValidation }) => {
const { t } = useTranslation();

const data = [
{
object: t('dovetail.key'),
contains: t('dovetail.suffix'),
optional: t('dovetail.no'),
rule: [
t('dovetail.suffix_format_rule_1'),
t('dovetail.suffix_format_rule_2'),
t('dovetail.suffix_format_rule_3'),
],
},
{
object: t('dovetail.key'),
contains: t('dovetail.name'),
optional: t('dovetail.yes'),
rule: [
t('dovetail.name_format_rule_1'),
t('dovetail.name_format_rule_2'),
t('dovetail.name_format_rule_3'),
],
},
];

if (!noValueValidation) {
data.push({
object: t('dovetail.value'),
contains: t('dovetail.name'),
optional: t('dovetail.no'),
rule: [
t('dovetail.name_format_rule_1'),
t('dovetail.name_format_rule_2'),
t('dovetail.name_format_rule_3'),
],
});
}

return (
<Popover
overlayClassName={PodLabelFormatRulePopoverStyle}
placement="bottomRight"
content={
<AntdTable
bordered
dataSource={[
{
object: t('dovetail.key'),
contains: t('dovetail.suffix'),
optional: t('dovetail.no'),
rule: [
t('dovetail.suffix_format_rule_1'),
t('dovetail.suffix_format_rule_2'),
t('dovetail.suffix_format_rule_3'),
],
},
{
object: t('dovetail.key'),
contains: t('dovetail.name'),
optional: t('dovetail.yes'),
rule: [
t('dovetail.name_format_rule_1'),
t('dovetail.name_format_rule_2'),
t('dovetail.name_format_rule_3'),
],
},
{
object: t('dovetail.value'),
contains: t('dovetail.name'),
optional: t('dovetail.no'),
rule: [
t('dovetail.name_format_rule_1'),
t('dovetail.name_format_rule_2'),
t('dovetail.name_format_rule_3'),
],
},
]}
dataSource={data}
columns={[
{
key: 'object',
Expand Down
23 changes: 14 additions & 9 deletions packages/refine/src/utils/validation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export function validateLabelKey(key: string): { isValid: boolean; errorMessage?: string } {
const labelPrefixRegex = /(^[a-zA-Z0-9]$)|(^[a-zA-Z0-9][a-zA-Z0-9\.]*[a-zA-Z0-9]$)/;
const labelNameRegex = /(^[a-zA-Z0-9]$)|(^[a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9]$)/;

export function validateLabelKey(key: string): {
isValid: boolean;
errorMessage?: string;
} {
const labelRegex = /(^[a-zA-Z0-9]$)|(^[a-zA-Z0-9][a-zA-Z0-9\.\-\_]*[a-zA-Z0-9]$)/;

let prefix, name;
const splitResult = key.split('/');
if (splitResult.length === 1) {
Expand All @@ -15,10 +17,10 @@ export function validateLabelKey(key: string): { isValid: boolean; errorMessage?
return { isValid: false, errorMessage: 'EMPTY_PREFIX' };
}

if (prefix && !labelPrefixRegex.test(prefix)) {
if (prefix && !labelRegex.test(prefix)) {
return { isValid: false, errorMessage: 'INVALID_PREFIX' };
}
if (!labelNameRegex.test(name)) {
if (!labelRegex.test(name)) {
return { isValid: false, errorMessage: 'INVALID_NAME' };
}

Expand All @@ -33,12 +35,15 @@ export function validateLabelKey(key: string): { isValid: boolean; errorMessage?
return { isValid: true };
}

export function validateLabelValue(value: string): { isValid: boolean; errorMessage?: string } {
const labelValueRegex = /(^[a-zA-Z0-9]$)|(^[a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9]$)/;
export function validateLabelValue(value: string): {
isValid: boolean;
errorMessage?: string;
} {
const labelValueRegex = /(^[a-zA-Z0-9]$)|(^[a-zA-Z0-9][a-zA-Z0-9\.\-\_]*[a-zA-Z0-9]$)/;
if (value === '') {
return { isValid: true };
}

if (value.length > 63) {
return { isValid: false, errorMessage: 'MAX_63' };
}
Expand Down

0 comments on commit 0b0c6ce

Please sign in to comment.