Fix select field options update (#5736)

Update of select fields options was failing if we deleted an option that
was used for at least one row: former code would not update the value to
null but leave it to the no-longer-allowed value.
This commit is contained in:
Marie
2024-06-05 11:06:22 +02:00
committed by GitHub
parent 1bbfc0b715
commit 6d869297b5
2 changed files with 40 additions and 6 deletions

View File

@ -1,6 +1,7 @@
import { useEffect } from 'react'; import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form'; import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
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';
@ -16,6 +17,7 @@ import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput'; import { formatFieldMetadataItemInput } from '@/object-metadata/utils/formatFieldMetadataItemInput';
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug'; import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField'; import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons'; import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer'; import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
@ -73,6 +75,20 @@ export const SettingsObjectFieldEdit = () => {
const getRelationMetadata = useGetRelationMetadata(); const getRelationMetadata = useGetRelationMetadata();
const { updateOneFieldMetadataItem } = useUpdateOneFieldMetadataItem(); const { updateOneFieldMetadataItem } = useUpdateOneFieldMetadataItem();
const apolloClient = useApolloClient();
const { findManyRecordsQuery } = useFindManyRecordsQuery({
objectNameSingular: activeObjectMetadataItem?.nameSingular || '',
});
const refetchRecords = async () => {
if (!activeObjectMetadataItem) return;
await apolloClient.query({
query: findManyRecordsQuery,
fetchPolicy: 'network-only',
});
};
const formConfig = useForm<SettingsDataModelFieldEditFormValues>({ const formConfig = useForm<SettingsDataModelFieldEditFormValues>({
mode: 'onTouched', mode: 'onTouched',
resolver: zodResolver(settingsFieldFormSchema), resolver: zodResolver(settingsFieldFormSchema),
@ -135,6 +151,8 @@ export const SettingsObjectFieldEdit = () => {
} }
navigate(`/settings/objects/${objectSlug}`); navigate(`/settings/objects/${objectSlug}`);
refetchRecords();
} catch (error) { } catch (error) {
enqueueSnackBar((error as Error).message, { enqueueSnackBar((error as Error).message, {
variant: SnackBarVariant.Error, variant: SnackBarVariant.Error,

View File

@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { QueryRunner, TableColumn } from 'typeorm'; import { QueryRunner, TableColumn } from 'typeorm';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { isDefined } from 'class-validator';
import { import {
WorkspaceMigrationColumnAlter, WorkspaceMigrationColumnAlter,
@ -117,10 +118,17 @@ export class WorkspaceMigrationEnumService {
private migrateEnumValue( private migrateEnumValue(
value: string, value: string,
renamedEnumValues?: WorkspaceMigrationRenamedEnum[], renamedEnumValues?: WorkspaceMigrationRenamedEnum[],
allEnumValues?: string[],
) { ) {
return ( if (renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to) {
renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to || value return renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to;
); }
if (allEnumValues?.includes(value)) {
return value;
}
return null;
} }
private async migrateEnumValues( private async migrateEnumValues(
@ -147,11 +155,19 @@ export class WorkspaceMigrationEnumService {
.slice(1, -1) .slice(1, -1)
.split(',') .split(',')
.map((v: string) => v.trim()) .map((v: string) => v.trim())
.map((v: string) => this.migrateEnumValue(v, renamedEnumValues)) .map((v: string) =>
.filter((v: string) => enumValues.includes(v)), this.migrateEnumValue(v, renamedEnumValues, enumValues),
)
.filter((v: string | null) => isDefined(v)),
); );
} else if (typeof val === 'string') { } else if (typeof val === 'string') {
val = `'${this.migrateEnumValue(val, renamedEnumValues)}'`; const migratedValue = this.migrateEnumValue(
val,
renamedEnumValues,
enumValues,
);
val = isDefined(migratedValue) ? `'${migratedValue}'` : null;
} }
await queryRunner.query(` await queryRunner.query(`