Fix/disable cancel button on save (#6204)
# This PR - Fix #5675 - Fix #6118 Similarly to #5673 I have improved the field creation time by re-fetching data on page redirection to the object page <img width="1511" alt="Screenshot 2024-07-10 at 16 06 37" src="https://github.com/twentyhq/twenty/assets/61581306/8ef8f4cb-4334-4f4c-b5d9-fea11fd5d99a"> @FellipeMTX @Bonapara --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6bc36635eb
commit
9917fb0f9e
@ -2,8 +2,19 @@ import { LightButton } from '@/ui/input/button/components/LightButton';
|
|||||||
|
|
||||||
type CancelButtonProps = {
|
type CancelButtonProps = {
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CancelButton = ({ onCancel }: CancelButtonProps) => {
|
export const CancelButton = ({
|
||||||
return <LightButton title="Cancel" accent="tertiary" onClick={onCancel} />;
|
onCancel,
|
||||||
|
disabled = false,
|
||||||
|
}: CancelButtonProps) => {
|
||||||
|
return (
|
||||||
|
<LightButton
|
||||||
|
title="Cancel"
|
||||||
|
accent="tertiary"
|
||||||
|
onClick={onCancel}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,16 +13,18 @@ type SaveAndCancelButtonsProps = {
|
|||||||
onSave?: () => void;
|
onSave?: () => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
isSaveDisabled?: boolean;
|
isSaveDisabled?: boolean;
|
||||||
|
isCancelDisabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SaveAndCancelButtons = ({
|
export const SaveAndCancelButtons = ({
|
||||||
onSave,
|
onSave,
|
||||||
onCancel,
|
onCancel,
|
||||||
isSaveDisabled,
|
isSaveDisabled,
|
||||||
|
isCancelDisabled,
|
||||||
}: SaveAndCancelButtonsProps) => {
|
}: SaveAndCancelButtonsProps) => {
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<CancelButton onCancel={onCancel} />
|
<CancelButton onCancel={onCancel} disabled={isCancelDisabled} />
|
||||||
<SaveButton onSave={onSave} disabled={isSaveDisabled} />
|
<SaveButton onSave={onSave} disabled={isSaveDisabled} />
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
|
||||||
import { H2Title, IconSettings } from 'twenty-ui';
|
import { H2Title, IconSettings } from 'twenty-ui';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ export const SettingsNewObject = () => {
|
|||||||
resolver: zodResolver(newObjectFormSchema),
|
resolver: zodResolver(newObjectFormSchema),
|
||||||
});
|
});
|
||||||
|
|
||||||
const canSave =
|
const { isValid, isSubmitting } = formConfig.formState;
|
||||||
formConfig.formState.isValid && !formConfig.formState.isSubmitting;
|
const canSave = isValid && !isSubmitting;
|
||||||
|
|
||||||
const handleSave = async (
|
const handleSave = async (
|
||||||
formValues: SettingsDataModelNewObjectFormValues,
|
formValues: SettingsDataModelNewObjectFormValues,
|
||||||
@ -84,6 +84,7 @@ export const SettingsNewObject = () => {
|
|||||||
/>
|
/>
|
||||||
<SaveAndCancelButtons
|
<SaveAndCancelButtons
|
||||||
isSaveDisabled={!canSave}
|
isSaveDisabled={!canSave}
|
||||||
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() => navigate(settingsObjectsPagePath)}
|
onCancel={() => navigate(settingsObjectsPagePath)}
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -124,6 +124,7 @@ export const SettingsObjectEdit = () => {
|
|||||||
{activeObjectMetadataItem.isCustom && (
|
{activeObjectMetadataItem.isCustom && (
|
||||||
<SaveAndCancelButtons
|
<SaveAndCancelButtons
|
||||||
isSaveDisabled={!canSave}
|
isSaveDisabled={!canSave}
|
||||||
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() =>
|
onCancel={() =>
|
||||||
navigate(`${settingsObjectsPagePath}/${objectSlug}`)
|
navigate(`${settingsObjectsPagePath}/${objectSlug}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
|
||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import omit from 'lodash.omit';
|
import omit from 'lodash.omit';
|
||||||
import pick from 'lodash.pick';
|
import pick from 'lodash.pick';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { H2Title, IconArchive, IconSettings } from 'twenty-ui';
|
import { H2Title, IconArchive, IconSettings } from 'twenty-ui';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@ -104,10 +104,8 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
|
|
||||||
if (!activeObjectMetadataItem || !activeMetadataField) return null;
|
if (!activeObjectMetadataItem || !activeMetadataField) return null;
|
||||||
|
|
||||||
const canSave =
|
const { isDirty, isValid, isSubmitting } = formConfig.formState;
|
||||||
formConfig.formState.isValid &&
|
const canSave = isDirty && isValid && !isSubmitting;
|
||||||
formConfig.formState.isDirty &&
|
|
||||||
!formConfig.formState.isSubmitting;
|
|
||||||
|
|
||||||
const isLabelIdentifier = isLabelIdentifierField({
|
const isLabelIdentifier = isLabelIdentifierField({
|
||||||
fieldMetadataItem: activeMetadataField,
|
fieldMetadataItem: activeMetadataField,
|
||||||
@ -190,6 +188,7 @@ export const SettingsObjectFieldEdit = () => {
|
|||||||
{shouldDisplaySaveAndCancel && (
|
{shouldDisplaySaveAndCancel && (
|
||||||
<SaveAndCancelButtons
|
<SaveAndCancelButtons
|
||||||
isSaveDisabled={!canSave}
|
isSaveDisabled={!canSave}
|
||||||
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { FormProvider, useForm } from 'react-hook-form';
|
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
|
||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import pick from 'lodash.pick';
|
import pick from 'lodash.pick';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { FormProvider, useForm } from 'react-hook-form';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { H2Title, IconSettings } from 'twenty-ui';
|
import { H2Title, IconSettings } from 'twenty-ui';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
@ -109,8 +109,8 @@ export const SettingsObjectNewFieldStep2 = () => {
|
|||||||
|
|
||||||
if (!activeObjectMetadataItem) return null;
|
if (!activeObjectMetadataItem) return null;
|
||||||
|
|
||||||
const canSave =
|
const { isValid, isSubmitting } = formConfig.formState;
|
||||||
formConfig.formState.isValid && !formConfig.formState.isSubmitting;
|
const canSave = isValid && !isSubmitting;
|
||||||
|
|
||||||
const handleSave = async (
|
const handleSave = async (
|
||||||
formValues: SettingsDataModelNewFieldFormValues,
|
formValues: SettingsDataModelNewFieldFormValues,
|
||||||
@ -134,26 +134,20 @@ export const SettingsObjectNewFieldStep2 = () => {
|
|||||||
objectMetadataId: relationFormValues.objectMetadataId,
|
objectMetadataId: relationFormValues.objectMetadataId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: fix optimistic update logic
|
|
||||||
// Forcing a refetch for now but it's not ideal
|
|
||||||
await apolloClient.refetchQueries({
|
|
||||||
include: ['FindManyViews', 'CombinedFindManyRecords'],
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
await createMetadataField({
|
await createMetadataField({
|
||||||
...formValues,
|
...formValues,
|
||||||
objectMetadataId: activeObjectMetadataItem.id,
|
objectMetadataId: activeObjectMetadataItem.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: fix optimistic update logic
|
|
||||||
// Forcing a refetch for now but it's not ideal
|
|
||||||
await apolloClient.refetchQueries({
|
|
||||||
include: ['FindManyViews', 'CombinedFindManyRecords'],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
navigate(`/settings/objects/${objectSlug}`);
|
navigate(`/settings/objects/${objectSlug}`);
|
||||||
|
|
||||||
|
// TODO: fix optimistic update logic
|
||||||
|
// Forcing a refetch for now but it's not ideal
|
||||||
|
await apolloClient.refetchQueries({
|
||||||
|
include: ['FindManyViews', 'CombinedFindManyRecords'],
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
enqueueSnackBar((error as Error).message, {
|
enqueueSnackBar((error as Error).message, {
|
||||||
variant: SnackBarVariant.Error,
|
variant: SnackBarVariant.Error,
|
||||||
@ -193,6 +187,7 @@ export const SettingsObjectNewFieldStep2 = () => {
|
|||||||
{!activeObjectMetadataItem.isRemote && (
|
{!activeObjectMetadataItem.isRemote && (
|
||||||
<SaveAndCancelButtons
|
<SaveAndCancelButtons
|
||||||
isSaveDisabled={!canSave}
|
isSaveDisabled={!canSave}
|
||||||
|
isCancelDisabled={isSubmitting}
|
||||||
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
||||||
onSave={formConfig.handleSubmit(handleSave)}
|
onSave={formConfig.handleSubmit(handleSave)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user