fix: Fixed API typo and webhook checkerror (#6779)

## Issue
1.There was an Api typo with API under Developers section #6778
2. Webhook lacked an check method for the `TextInput` #6774

## After- 

<img width="649" alt="Screenshot 2024-08-29 at 2 13 21 AM"
src="https://github.com/user-attachments/assets/bc9595f8-533f-430e-bc18-56373983eec8">



https://github.com/user-attachments/assets/8e2b06bc-308a-48ad-8ecb-9d0a130877bc

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Harshit Singh 2024-08-31 22:47:14 +05:30 committed by GitHub
parent 96d659cf56
commit f8890689ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 6 deletions

View File

@ -136,7 +136,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
{apiKeyToken ? (
<>
<H2Title
title="Api Key"
title="API Key"
description="Copy this key as it will only be visible this one time"
/>
<ApiKeyInput apiKey={apiKeyToken} />
@ -147,8 +147,8 @@ export const SettingsDevelopersApiKeyDetail = () => {
) : (
<>
<H2Title
title="Api Key"
description="Regenerate an Api key"
title="API Key"
description="Regenerate an API key"
/>
<StyledInputContainer>
<Button
@ -213,7 +213,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
confirmationValue="yes"
isOpen={isDeleteApiKeyModalOpen}
setIsOpen={setIsDeleteApiKeyModalOpen}
title="Delete Api key"
title="Delete API key"
subtitle={
<>
Please type "yes" to confirm you want to delete this API Key. Be
@ -228,7 +228,7 @@ export const SettingsDevelopersApiKeyDetail = () => {
confirmationValue="yes"
isOpen={isRegenerateKeyModalOpen}
setIsOpen={setIsRegenerateKeyModalOpen}
title="Regenerate an Api key"
title="Regenerate an API key"
subtitle={
<>
If youve lost this key, you can regenerate it, but be aware that

View File

@ -11,6 +11,7 @@ import { TextInput } from '@/ui/input/components/TextInput';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section';
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
import { isValidUrl } from '~/utils/url/isValidUrl';
export const SettingsDevelopersWebhooksNew = () => {
const navigate = useNavigate();
@ -21,9 +22,18 @@ export const SettingsDevelopersWebhooksNew = () => {
targetUrl: '',
operation: '*.*',
});
const [isTargetUrlValid, setIsTargetUrlValid] = useState(true);
const { createOneRecord: createOneWebhook } = useCreateOneRecord<Webhook>({
objectNameSingular: CoreObjectNameSingular.Webhook,
});
const handleValidate = async (value: string) => {
const trimmedUrl = value.trim();
setIsTargetUrlValid(isValidUrl(trimmedUrl));
};
const handleSave = async () => {
const newWebhook = await createOneWebhook?.(formValues);
@ -32,7 +42,10 @@ export const SettingsDevelopersWebhooksNew = () => {
}
navigate(`/settings/developers/webhooks/${newWebhook.id}`);
};
const canSave = !!formValues.targetUrl && createOneWebhook;
const canSave =
!!formValues.targetUrl && isTargetUrlValid && createOneWebhook;
return (
<SubMenuTopBarContainer
Icon={IconCode}
@ -63,6 +76,7 @@ export const SettingsDevelopersWebhooksNew = () => {
<TextInput
placeholder="URL"
value={formValues.targetUrl}
error={!isTargetUrlValid ? 'Please enter a valid URL' : undefined}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleSave();
@ -73,6 +87,7 @@ export const SettingsDevelopersWebhooksNew = () => {
...prevState,
targetUrl: value,
}));
handleValidate(value);
}}
fullWidth
/>

View File

@ -0,0 +1,25 @@
import { isValidUrl } from '../isValidUrl';
describe('isValidUrl', () => {
it('test cases', () => {
// Truthy
expect(isValidUrl('https://www.example.com')).toBe(true);
expect(isValidUrl('http://192.168.2.0:3000')).toBe(true);
expect(isValidUrl('http://localhost')).toBe(true);
expect(isValidUrl('http://localhost:3000')).toBe(true);
expect(isValidUrl('http://subdomain.example.com')).toBe(true);
expect(isValidUrl('https://www.example.com/path')).toBe(true);
expect(isValidUrl('https://www.example.com/path/path2?query=123')).toBe(
true,
);
expect(isValidUrl('http://localhost:3000')).toBe(true);
expect(isValidUrl('example.com')).toBe(true);
expect(isValidUrl('www.subdomain.example.com')).toBe(true);
// Falsy
expect(isValidUrl('?o')).toBe(false);
expect(isValidUrl('')).toBe(false);
expect(isValidUrl('\\')).toBe(false);
expect(isValidUrl('wwwexamplecom')).toBe(false);
});
});

View File

@ -0,0 +1,8 @@
export const isValidUrl = (url: string) => {
const urlRegex =
/^(https?:\/\/)?((([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})|(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})|(localhost))(:\d+)?(\/[^\s]*)?(\?[^\s]*)?$/;
const urlPattern = new RegExp(urlRegex, 'i');
return !!urlPattern.test(url);
};