Redirect to select option creation when no result (#14460)
fix:Ability to add a new option for a multi-select on the fly Issues:#13877 --------- Co-authored-by: ehconitin <nitinkoche03@gmail.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
+3
-1
@@ -18,6 +18,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { MAX_OPTIONS_TO_DISPLAY } from 'twenty-shared/constants';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -145,6 +146,7 @@ export const ObjectFilterDropdownOptionSelect = ({
|
||||
);
|
||||
|
||||
const showNoResult = optionsInDropdown?.length === 0;
|
||||
|
||||
const objectRecordsIds = optionsInDropdown.map((option) => option.id);
|
||||
|
||||
return (
|
||||
@@ -155,7 +157,7 @@ export const ObjectFilterDropdownOptionSelect = ({
|
||||
>
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{showNoResult ? (
|
||||
<MenuItem text="No results" />
|
||||
<MenuItem text={t`No results`} />
|
||||
) : (
|
||||
optionsInDropdown?.map((option) => (
|
||||
<MenuItemMultiSelect
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||
import { shouldNavigateBackToMemorizedUrlOnSaveState } from '@/ui/navigation/states/shouldNavigateBackToMemorizedUrlOnSaveState';
|
||||
import { useCallback } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
|
||||
export const useAddSelectOption = (fieldName: string) => {
|
||||
const { objectNamePlural } = useParams();
|
||||
const navigateSettings = useNavigateSettings();
|
||||
const setNavigationMemorizedUrl = useSetRecoilState(
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
const setShouldNavigateBackToMemorizedUrlOnSave = useSetRecoilState(
|
||||
shouldNavigateBackToMemorizedUrlOnSaveState,
|
||||
);
|
||||
|
||||
const addSelectOption = useCallback(
|
||||
(optionName: string) => {
|
||||
if (!fieldName || !objectNamePlural) return;
|
||||
|
||||
setNavigationMemorizedUrl(
|
||||
window.location.pathname + window.location.search,
|
||||
);
|
||||
setShouldNavigateBackToMemorizedUrlOnSave(true);
|
||||
|
||||
navigateSettings(
|
||||
SettingsPath.ObjectFieldEdit,
|
||||
{ objectNamePlural, fieldName },
|
||||
{ newOption: optionName },
|
||||
);
|
||||
},
|
||||
[
|
||||
fieldName,
|
||||
objectNamePlural,
|
||||
navigateSettings,
|
||||
setNavigationMemorizedUrl,
|
||||
setShouldNavigateBackToMemorizedUrlOnSave,
|
||||
],
|
||||
);
|
||||
|
||||
return { addSelectOption };
|
||||
};
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { PermissionFlagType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useCanAddSelectOption = (fieldName: string) => {
|
||||
const { objectNamePlural } = useParams();
|
||||
|
||||
const userHasPermissionToEditDataModel = useHasPermissionFlag(
|
||||
PermissionFlagType.DATA_MODEL,
|
||||
);
|
||||
|
||||
const canAddSelectOption =
|
||||
userHasPermissionToEditDataModel &&
|
||||
isNonEmptyString(fieldName) &&
|
||||
isNonEmptyString(objectNamePlural);
|
||||
|
||||
return { canAddSelectOption };
|
||||
};
|
||||
+16
-1
@@ -1,15 +1,22 @@
|
||||
import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext';
|
||||
import { useAddSelectOption } from '@/object-record/record-field/ui/meta-types/hooks/useAddSelectOption';
|
||||
import { useCanAddSelectOption } from '@/object-record/record-field/ui/meta-types/hooks/useCanAddSelectOption';
|
||||
import { useMultiSelectField } from '@/object-record/record-field/ui/meta-types/hooks/useMultiSelectField';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/ui/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext';
|
||||
import { type FieldMultiSelectValue } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
|
||||
import { MultiSelectInput } from '@/ui/field/input/components/MultiSelectInput';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export const MultiSelectFieldInput = () => {
|
||||
const { fieldDefinition, draftValue, setDraftValue } = useMultiSelectField();
|
||||
const { addSelectOption } = useAddSelectOption(
|
||||
fieldDefinition?.metadata?.fieldName,
|
||||
);
|
||||
const { canAddSelectOption } = useCanAddSelectOption(
|
||||
fieldDefinition?.metadata?.fieldName,
|
||||
);
|
||||
|
||||
const { onSubmit } = useContext(FieldInputEventContext);
|
||||
|
||||
@@ -25,6 +32,13 @@ export const MultiSelectFieldInput = () => {
|
||||
onSubmit?.({ newValue: draftValue });
|
||||
};
|
||||
|
||||
const handleAddSelectOption = (optionName: string) => {
|
||||
if (!canAddSelectOption) {
|
||||
return;
|
||||
}
|
||||
addSelectOption(optionName);
|
||||
};
|
||||
|
||||
return (
|
||||
<MultiSelectInput
|
||||
selectableListComponentInstanceId={
|
||||
@@ -35,6 +49,7 @@ export const MultiSelectFieldInput = () => {
|
||||
onCancel={handleCancel}
|
||||
onOptionSelected={handleOptionSelected}
|
||||
values={draftValue}
|
||||
onAddSelectOption={handleAddSelectOption}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+16
@@ -1,5 +1,7 @@
|
||||
import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext';
|
||||
import { useClearField } from '@/object-record/record-field/ui/hooks/useClearField';
|
||||
import { useAddSelectOption } from '@/object-record/record-field/ui/meta-types/hooks/useAddSelectOption';
|
||||
import { useCanAddSelectOption } from '@/object-record/record-field/ui/meta-types/hooks/useCanAddSelectOption';
|
||||
import { useSelectField } from '@/object-record/record-field/ui/meta-types/hooks/useSelectField';
|
||||
import { SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID } from '@/object-record/record-field/ui/meta-types/input/constants/SelectFieldInputSelectableListComponentInstanceId';
|
||||
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext';
|
||||
@@ -14,6 +16,12 @@ import { type SelectOption } from 'twenty-ui/input';
|
||||
|
||||
export const SelectFieldInput = () => {
|
||||
const { fieldDefinition, fieldValue } = useSelectField();
|
||||
const { addSelectOption } = useAddSelectOption(
|
||||
fieldDefinition?.metadata?.fieldName,
|
||||
);
|
||||
const { canAddSelectOption } = useCanAddSelectOption(
|
||||
fieldDefinition?.metadata?.fieldName,
|
||||
);
|
||||
|
||||
const { onCancel, onSubmit } = useContext(FieldInputEventContext);
|
||||
|
||||
@@ -37,6 +45,13 @@ export const SelectFieldInput = () => {
|
||||
onCancel?.();
|
||||
};
|
||||
|
||||
const handleAddSelectOption = (optionName: string) => {
|
||||
if (!canAddSelectOption) {
|
||||
return;
|
||||
}
|
||||
addSelectOption(optionName);
|
||||
};
|
||||
|
||||
const handleSubmit = (option: SelectOption) => {
|
||||
onSubmit?.({ newValue: option.value });
|
||||
|
||||
@@ -82,6 +97,7 @@ export const SelectFieldInput = () => {
|
||||
fieldDefinition.metadata.isNullable ? handleClearField : undefined
|
||||
}
|
||||
clearLabel={fieldDefinition.label}
|
||||
onAddSelectOption={handleAddSelectOption}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
|
||||
type AddSelectOptionMenuItemProps = {
|
||||
name: string;
|
||||
onAddSelectOption?: (optionName: string) => void;
|
||||
};
|
||||
|
||||
export const AddSelectOptionMenuItem = ({
|
||||
name,
|
||||
onAddSelectOption,
|
||||
}: AddSelectOptionMenuItemProps) => {
|
||||
const trimmedName = name.trim();
|
||||
const showAddOption =
|
||||
isNonEmptyString(trimmedName) && isDefined(onAddSelectOption);
|
||||
|
||||
const handleClick = () => {
|
||||
if (isDefined(onAddSelectOption)) {
|
||||
onAddSelectOption(trimmedName);
|
||||
}
|
||||
};
|
||||
|
||||
if (!showAddOption) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
onClick={handleClick}
|
||||
LeftIcon={IconPlus}
|
||||
text={t`Add "${trimmedName}" to options`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
+21
@@ -20,7 +20,10 @@ import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToStr
|
||||
import { AdvancedSettingsWrapper } from '@/settings/components/AdvancedSettingsWrapper';
|
||||
import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/states/isAdvancedModeEnabledState';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconPlus, IconPoint } from 'twenty-ui/display';
|
||||
import { LightButton } from 'twenty-ui/input';
|
||||
import { CardContent, CardFooter } from 'twenty-ui/layout';
|
||||
@@ -114,8 +117,11 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
useSelectSettingsFormInitialValues({
|
||||
fieldMetadataId: existingFieldMetadataId,
|
||||
});
|
||||
|
||||
const isAdvancedModeEnabled = useRecoilValue(isAdvancedModeEnabledState);
|
||||
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const {
|
||||
control,
|
||||
setValue: setFormValue,
|
||||
@@ -123,6 +129,21 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
getValues,
|
||||
} = useFormContext<SettingsDataModelFieldSelectFormValues>();
|
||||
|
||||
const [hasAppliedNewOption, setHasAppliedNewOption] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const newOptionValue = searchParams.get('newOption');
|
||||
|
||||
if (isDefined(newOptionValue) && !hasAppliedNewOption) {
|
||||
const newOption = generateNewSelectOption(initialOptions, newOptionValue);
|
||||
|
||||
const optionsWithNew = [...initialOptions, newOption];
|
||||
|
||||
setFormValue('options', optionsWithNew, { shouldDirty: true });
|
||||
setHasAppliedNewOption(true);
|
||||
}
|
||||
}, [searchParams, hasAppliedNewOption, initialOptions, setFormValue]);
|
||||
|
||||
const handleDragEnd = (
|
||||
values: FieldMetadataItemOption[],
|
||||
result: DropResult,
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@ import { computeOptionValueFromLabel } from '~/pages/settings/data-model/utils/c
|
||||
|
||||
export const generateNewSelectOption = (
|
||||
options: FieldMetadataItemOption[],
|
||||
label?: string,
|
||||
): FieldMetadataItemOption => {
|
||||
const newOptionLabel = generateNewSelectOptionLabel(options);
|
||||
|
||||
const newOptionLabel = label ?? generateNewSelectOptionLabel(options);
|
||||
return {
|
||||
color: getNextThemeColor(options[options.length - 1]?.color),
|
||||
id: v4(),
|
||||
|
||||
@@ -7,6 +7,7 @@ import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/Dropdow
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
|
||||
import { AddSelectOptionMenuItem } from '@/settings/data-model/fields/forms/select/components/AddSelectOptionMenuItem';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
@@ -14,7 +15,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type SelectOption } from 'twenty-ui/input';
|
||||
import { MenuItem, MenuItemMultiSelectTag } from 'twenty-ui/navigation';
|
||||
@@ -29,6 +30,7 @@ type MultiSelectInputProps = {
|
||||
options: SelectOption[];
|
||||
onOptionSelected: (value: FieldMultiSelectValue) => void;
|
||||
dropdownWidth?: number;
|
||||
onAddSelectOption?: (optionName: string) => void;
|
||||
};
|
||||
|
||||
export const MultiSelectInput = ({
|
||||
@@ -39,9 +41,8 @@ export const MultiSelectInput = ({
|
||||
onCancel,
|
||||
onOptionSelected,
|
||||
dropdownWidth,
|
||||
onAddSelectOption,
|
||||
}: MultiSelectInputProps) => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { resetSelectedItem } = useSelectableList(
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
@@ -50,6 +51,7 @@ export const MultiSelectInput = ({
|
||||
selectedItemIdComponentState,
|
||||
selectableListComponentInstanceId,
|
||||
);
|
||||
|
||||
const [searchFilter, setSearchFilter] = useState('');
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -129,7 +131,7 @@ export const MultiSelectInput = ({
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredOptionsInDropDown.length === 0 ? (
|
||||
<MenuItem disabled text={t`No option found`} accent="placeholder" />
|
||||
<MenuItem text={t`No option found`} />
|
||||
) : (
|
||||
filteredOptionsInDropDown.map((option) => {
|
||||
return (
|
||||
@@ -156,6 +158,19 @@ export const MultiSelectInput = ({
|
||||
})
|
||||
)}
|
||||
</DropdownMenuItemsContainer>
|
||||
{onAddSelectOption &&
|
||||
searchFilter &&
|
||||
filteredOptionsInDropDown.length === 0 && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
<AddSelectOptionMenuItem
|
||||
name={searchFilter}
|
||||
onAddSelectOption={onAddSelectOption}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
)}
|
||||
</DropdownContent>
|
||||
</SelectableList>
|
||||
);
|
||||
|
||||
@@ -14,6 +14,7 @@ type SelectInputProps = {
|
||||
onFilterChange?: ((filteredOptions: SelectOption[]) => void) | undefined;
|
||||
onClear?: (() => void) | undefined;
|
||||
clearLabel?: string;
|
||||
onAddSelectOption?: (optionName: string) => void;
|
||||
};
|
||||
|
||||
export const SelectInput = ({
|
||||
@@ -27,6 +28,7 @@ export const SelectInput = ({
|
||||
onFilterChange,
|
||||
onClear,
|
||||
clearLabel,
|
||||
onAddSelectOption,
|
||||
}: SelectInputProps) => {
|
||||
return (
|
||||
<SelectableList
|
||||
@@ -43,6 +45,7 @@ export const SelectInput = ({
|
||||
onClear={onClear}
|
||||
clearLabel={clearLabel}
|
||||
focusId={focusId}
|
||||
onAddSelectOption={onAddSelectOption}
|
||||
/>
|
||||
</SelectableList>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { AddSelectOptionMenuItem } from '@/settings/data-model/fields/forms/select/components/AddSelectOptionMenuItem';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
@@ -24,6 +25,7 @@ interface SelectInputProps {
|
||||
onClear?: () => void;
|
||||
clearLabel?: string;
|
||||
focusId: string;
|
||||
onAddSelectOption?: (optionName: string) => void;
|
||||
}
|
||||
|
||||
export const SelectInput = ({
|
||||
@@ -34,6 +36,7 @@ export const SelectInput = ({
|
||||
onCancel,
|
||||
defaultOption,
|
||||
onFilterChange,
|
||||
onAddSelectOption,
|
||||
}: SelectInputProps) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -144,6 +147,17 @@ export const SelectInput = ({
|
||||
);
|
||||
})}
|
||||
</DropdownMenuItemsContainer>
|
||||
{onAddSelectOption && searchFilter && optionsToSelect.length === 0 && (
|
||||
<>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer scrollable={false}>
|
||||
<AddSelectOptionMenuItem
|
||||
name={searchFilter}
|
||||
onAddSelectOption={onAddSelectOption}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</>
|
||||
)}
|
||||
</DropdownContent>
|
||||
);
|
||||
};
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { createState } from 'twenty-ui/utilities';
|
||||
|
||||
export const shouldNavigateBackToMemorizedUrlOnSaveState = createState<boolean>(
|
||||
{
|
||||
key: 'shouldNavigateBackToMemorizedUrlOnSaveState',
|
||||
defaultValue: false,
|
||||
},
|
||||
);
|
||||
@@ -3,7 +3,7 @@ import omit from 'lodash.omit';
|
||||
import pick from 'lodash.pick';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { type z } from 'zod';
|
||||
|
||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
||||
@@ -23,8 +23,11 @@ import { settingsFieldFormSchema } from '@/settings/data-model/fields/forms/vali
|
||||
import { type SettingsFieldType } from '@/settings/data-model/types/SettingsFieldType';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/components/SubMenuTopBarContainer';
|
||||
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||
import { shouldNavigateBackToMemorizedUrlOnSaveState } from '@/ui/navigation/states/shouldNavigateBackToMemorizedUrlOnSaveState';
|
||||
import { ApolloError } from '@apollo/client';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { AppPath, SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
import { H2Title, IconArchive, IconArchiveOff } from 'twenty-ui/display';
|
||||
@@ -45,6 +48,17 @@ export const SettingsObjectFieldEdit = () => {
|
||||
const navigateApp = useNavigateApp();
|
||||
const { t } = useLingui();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [navigationMemorizedUrl, setNavigationMemorizedUrl] = useRecoilState(
|
||||
navigationMemorizedUrlState,
|
||||
);
|
||||
|
||||
const [
|
||||
shouldNavigateBackToMemorizedUrlOnSave,
|
||||
setShouldNavigateBackToMemorizedUrlOnSave,
|
||||
] = useRecoilState(shouldNavigateBackToMemorizedUrlOnSaveState);
|
||||
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
|
||||
const { objectNamePlural = '', fieldName = '' } = useParams();
|
||||
@@ -141,9 +155,7 @@ export const SettingsObjectFieldEdit = () => {
|
||||
updatePayload: formattedInput,
|
||||
});
|
||||
|
||||
navigateSettings(SettingsPath.ObjectDetail, {
|
||||
objectNamePlural,
|
||||
});
|
||||
navigateBackOrToSettings();
|
||||
}
|
||||
} catch (error) {
|
||||
enqueueErrorSnackBar({
|
||||
@@ -152,6 +164,28 @@ export const SettingsObjectFieldEdit = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const navigateBackOrToSettings = () => {
|
||||
if (
|
||||
shouldNavigateBackToMemorizedUrlOnSave &&
|
||||
isDefined(navigationMemorizedUrl)
|
||||
) {
|
||||
navigate(navigationMemorizedUrl, { replace: true });
|
||||
|
||||
setShouldNavigateBackToMemorizedUrlOnSave(false);
|
||||
setNavigationMemorizedUrl('/');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
navigateSettings(SettingsPath.ObjectDetail, {
|
||||
objectNamePlural,
|
||||
});
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
navigateBackOrToSettings();
|
||||
};
|
||||
|
||||
const handleDeactivate = async () => {
|
||||
await deactivateMetadataField(fieldMetadataItem.id, objectMetadataItem.id);
|
||||
navigateSettings(SettingsPath.ObjectDetail, {
|
||||
@@ -196,11 +230,7 @@ export const SettingsObjectFieldEdit = () => {
|
||||
isLoading={isSubmitting}
|
||||
isSaveDisabled={!canSave}
|
||||
isCancelDisabled={isSubmitting}
|
||||
onCancel={() =>
|
||||
navigateSettings(SettingsPath.ObjectDetail, {
|
||||
objectNamePlural,
|
||||
})
|
||||
}
|
||||
onCancel={handleCancel}
|
||||
onSave={formConfig.handleSubmit(handleSave)}
|
||||
/>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user