fix: fix field select options positions after option removal (#5350)
- Adds an util `toSpliced`. We cannot used the native Javascript `Array.prototype.toSpliced` method as Chromatic servers don't support it. - Makes sure Select field options have sequential positions after removing an option (form validation schema checks that positions are sequential and considers options invalid otherwise).
This commit is contained in:
@ -19,6 +19,7 @@ import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableIt
|
||||
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { moveArrayItem } from '~/utils/array/moveArrayItem';
|
||||
import { toSpliced } from '~/utils/array/toSpliced';
|
||||
import { applySimpleQuotesToString } from '~/utils/string/applySimpleQuotesToString';
|
||||
import { simpleQuotesStringSchema } from '~/utils/validation-schemas/simpleQuotesStringSchema';
|
||||
|
||||
@ -198,8 +199,12 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
key={option.id}
|
||||
option={option}
|
||||
onChange={(nextOption) => {
|
||||
const nextOptions = [...options];
|
||||
nextOptions.splice(index, 1, nextOption);
|
||||
const nextOptions = toSpliced(
|
||||
options,
|
||||
index,
|
||||
1,
|
||||
nextOption,
|
||||
);
|
||||
onChange(nextOptions);
|
||||
|
||||
// Update option value in defaultValue if value has changed
|
||||
@ -211,15 +216,17 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
handleSetOptionAsDefault(nextOption.value);
|
||||
}
|
||||
}}
|
||||
onRemove={
|
||||
options.length > 1
|
||||
? () => {
|
||||
const nextOptions = [...options];
|
||||
nextOptions.splice(index, 1);
|
||||
onChange(nextOptions);
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
onRemove={() => {
|
||||
const nextOptions = toSpliced(
|
||||
options,
|
||||
index,
|
||||
1,
|
||||
).map((option, nextOptionIndex) => ({
|
||||
...option,
|
||||
position: nextOptionIndex,
|
||||
}));
|
||||
onChange(nextOptions);
|
||||
}}
|
||||
isDefault={isOptionDefaultValue(option.value)}
|
||||
onSetAsDefault={() =>
|
||||
handleSetOptionAsDefault(option.value)
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutsideV2';
|
||||
import { ClickOutsideListenerCallback } from '@/ui/utilities/pointer-event/types/ClickOutsideListenerCallback';
|
||||
import { getScopeIdFromComponentId } from '@/ui/utilities/recoil-scope/utils/getScopeIdFromComponentId';
|
||||
import { toSpliced } from '~/utils/array/toSpliced';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const useClickOutsideListener = (componentId: string) => {
|
||||
@ -117,8 +118,11 @@ export const useClickOutsideListener = (componentId: string) => {
|
||||
const callbackToUnsubscribeIsFound = indexOfCallbackToUnsubscribe > -1;
|
||||
|
||||
if (callbackToUnsubscribeIsFound) {
|
||||
const newCallbacksWithoutCallbackToUnsubscribe =
|
||||
existingCallbacks.toSpliced(indexOfCallbackToUnsubscribe, 1);
|
||||
const newCallbacksWithoutCallbackToUnsubscribe = toSpliced(
|
||||
existingCallbacks,
|
||||
indexOfCallbackToUnsubscribe,
|
||||
1,
|
||||
);
|
||||
|
||||
set(
|
||||
getClickOutsideListenerCallbacksState,
|
||||
|
||||
Reference in New Issue
Block a user