Skip to content

Commit

Permalink
Add description for Developers/webhook page (#6327)
Browse files Browse the repository at this point in the history
- Add optional description field to webhook page in developer settings.

Fix #6236

---------

Co-authored-by: Thomas Trompette <[email protected]>
  • Loading branch information
abdulqdaer-q and thomtrp authored Jul 31, 2024
1 parent ee4f1da commit 50f1cd3
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export type Webhook = {
id: string;
targetUrl: string;
description?: string;
operation: string;
__typename: 'Webhook';
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const meta: Meta<PageDecoratorArgs> = {
id: '1',
createdAt: '2021-08-27T12:00:00Z',
targetUrl: 'https://example.com/webhook',
description: 'A Sample Description',
updatedAt: '2021-08-27T12:00:00Z',
operation: 'create',
__typename: 'Webhook',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,72 @@
import { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { H2Title, IconSettings, IconTrash } from 'twenty-ui';

import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { Button } from '@/ui/input/button/components/Button';
import { TextArea } from '@/ui/input/components/TextArea';
import { TextInput } from '@/ui/input/components/TextInput';
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
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 { useState } from 'react';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import { H2Title, IconSettings, IconTrash } from 'twenty-ui';

type SettingsDevelopersWebhooksDetailForm = {
description?: string;
};

export const SettingsDevelopersWebhooksDetail = () => {
const [isDeleteWebhookModalOpen, setIsDeleteWebhookModalOpen] =
useState(false);
const navigate = useNavigate();
const { webhookId = '' } = useParams();
const { enqueueSnackBar } = useSnackBar();
const { record: webhookData } = useFindOneRecord({
objectNameSingular: CoreObjectNameSingular.Webhook,
objectRecordId: webhookId,
});
const { deleteOneRecord: deleteOneWebhook } = useDeleteOneRecord({
objectNameSingular: CoreObjectNameSingular.Webhook,
});
const { updateOneRecord } = useUpdateOneRecord({
objectNameSingular: CoreObjectNameSingular.Webhook,
});
const deleteWebhook = () => {
deleteOneWebhook(webhookId);
navigate('/settings/developers');
};
const formConfig = useForm<SettingsDevelopersWebhooksDetailForm>();

const { isDirty, isValid, isSubmitting } = formConfig.formState;
const canSave = isDirty && isValid && !isSubmitting;

const handleSave = async (
formValues: SettingsDevelopersWebhooksDetailForm,
) => {
try {
await updateOneRecord({
idToUpdate: webhookId,
updateOneRecordInput: formValues,
});
navigate('/settings/developers');
} catch (error) {
enqueueSnackBar((error as Error).message, {
variant: SnackBarVariant.Error,
});
}
};

return (
<>
// eslint-disable-next-line react/jsx-props-no-spreading
<FormProvider {...formConfig}>
{webhookData?.targetUrl && (
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
Expand All @@ -42,6 +77,11 @@ export const SettingsDevelopersWebhooksDetail = () => {
{ children: 'Webhook' },
]}
/>
<SaveAndCancelButtons
onCancel={() => navigate(`/settings/developers`)}
onSave={formConfig.handleSubmit(handleSave)}
isSaveDisabled={!canSave}
/>
</SettingsHeaderContainer>
<Section>
<H2Title
Expand All @@ -55,6 +95,25 @@ export const SettingsDevelopersWebhooksDetail = () => {
fullWidth
/>
</Section>
<Section>
<H2Title
title="Description"
description="An optional description"
/>
<Controller
name="description"
control={formConfig.control}
defaultValue={webhookData?.description ?? null}
render={({ field: { onChange, value } }) => (
<TextArea
placeholder="Write a description"
minRows={4}
value={value ?? undefined}
onChange={(nextValue) => onChange(nextValue ?? null)}
/>
)}
/>
</Section>
<Section>
<H2Title
title="Danger zone"
Expand Down Expand Up @@ -86,6 +145,6 @@ export const SettingsDevelopersWebhooksDetail = () => {
</SettingsPageContainer>
</SubMenuTopBarContainer>
)}
</>
</FormProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export const computeWebhooks = (
type: 'string',
example: 'https://example.com/incomingWebhook',
},
description: {
type: 'string',
example: 'A sample description',
},
eventType: {
type: 'string',
enum: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ export const VIEW_STANDARD_FIELD_IDS = {
export const WEBHOOK_STANDARD_FIELD_IDS = {
targetUrl: '20202020-1229-45a8-8cf4-85c9172aae12',
operation: '20202020-15b7-458e-bf30-74770a54410c',
description: '20202020-15b7-458e-bf30-74770a54410d',
};

export const WORKFLOW_EVENT_LISTENER_STANDARD_FIELD_IDS = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator';
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator';
import { WorkspaceIsNotAuditLogged } from 'src/engine/twenty-orm/decorators/workspace-is-not-audit-logged.decorator';
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator';
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator';
import { WEBHOOK_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
Expand Down Expand Up @@ -36,4 +37,14 @@ export class WebhookWorkspaceEntity extends BaseWorkspaceEntity {
icon: 'IconCheckbox',
})
operation: string;

@WorkspaceField({
standardId: WEBHOOK_STANDARD_FIELD_IDS.description,
type: FieldMetadataType.TEXT,
label: 'Description',
description: undefined,
icon: 'IconInfo',
})
@WorkspaceIsNullable()
description: string;
}

0 comments on commit 50f1cd3

Please sign in to comment.