Support custom object renaming (#7504)
This PR was created by [GitStart](https://gitstart.com/) to address the requirements from this ticket: [TWNTY-5491](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-5491). This ticket was imported from: [TWNTY-5491](https://github.com/twentyhq/twenty/issues/5491) --- ### Description **How To Test:**\ 1. Reset db using `npx nx database:reset twenty-server` on this PR 1. Run both backend and frontend 2. Navigate to `settings/data-model/objects/ `page 3. Select a `Custom `object from the list or create a new `Custom `object 4. Navigate to custom object details page and click on edit button 5. Finally edit the object details. **Issues and bugs** The Typecheck is failing but we could not see this error locally There is a bug after updating the label of a custom object. View title is not updated till refreshing the page. We could not find a consistent way to update this, should we reload the page after editing an object? ### Demo <https://www.loom.com/share/64ecb57efad7498d99085cb11480b5dd?sid=28d0868c-e54f-454d-8432-3f789be9e2b7> ### Refs #5491 --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: gitstart-twenty <140154534+gitstart-twenty@users.noreply.github.com> Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu> Co-authored-by: Charles Bochet <charles@twenty.com> Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
committed by
GitHub
parent
c6ef14acc4
commit
414f2ac498
+35
@@ -1,3 +1,6 @@
|
||||
import toCamelCase from 'lodash.camelcase';
|
||||
import { slugify, transliterate } from 'transliteration';
|
||||
|
||||
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
||||
import { UpdateObjectPayload } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
|
||||
import {
|
||||
@@ -40,6 +43,8 @@ const reservedKeywords = [
|
||||
'addresses',
|
||||
];
|
||||
|
||||
const METADATA_NAME_VALID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
||||
|
||||
export const validateObjectMetadataInputOrThrow = <
|
||||
T extends UpdateObjectPayload | CreateObjectInput,
|
||||
>(
|
||||
@@ -58,6 +63,30 @@ export const validateObjectMetadataInputOrThrow = <
|
||||
validateNameIsNotTooLongThrow(objectMetadataInput.namePlural);
|
||||
};
|
||||
|
||||
export const transliterateAndFormatOrThrow = (string?: string): string => {
|
||||
if (!string) {
|
||||
throw new ObjectMetadataException(
|
||||
'Name is required',
|
||||
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
||||
);
|
||||
}
|
||||
let formattedString = string;
|
||||
|
||||
if (formattedString.match(METADATA_NAME_VALID_PATTERN) !== null) {
|
||||
return toCamelCase(formattedString);
|
||||
}
|
||||
|
||||
formattedString = toCamelCase(
|
||||
slugify(transliterate(formattedString, { trim: true })),
|
||||
);
|
||||
|
||||
if (!formattedString.match(METADATA_NAME_VALID_PATTERN)) {
|
||||
throw new Error(`"${string}" is not a valid name`);
|
||||
}
|
||||
|
||||
return formattedString;
|
||||
};
|
||||
|
||||
const validateNameIsNotReservedKeywordOrThrow = (name?: string) => {
|
||||
if (name) {
|
||||
if (reservedKeywords.includes(name)) {
|
||||
@@ -107,3 +136,9 @@ const validateNameCharactersOrThrow = (name?: string) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const computeMetadataNameFromLabelOrThrow = (label: string): string => {
|
||||
const formattedString = transliterateAndFormatOrThrow(label);
|
||||
|
||||
return formattedString;
|
||||
};
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
ObjectMetadataException,
|
||||
ObjectMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/object-metadata/object-metadata.exception';
|
||||
import { computeMetadataNameFromLabelOrThrow } from 'src/engine/metadata-modules/object-metadata/utils/validate-object-metadata-input.util';
|
||||
|
||||
export const validateNameAndLabelAreSyncOrThrow = (
|
||||
label: string,
|
||||
name: string,
|
||||
) => {
|
||||
const computedName = computeMetadataNameFromLabelOrThrow(label);
|
||||
|
||||
if (name !== computedName) {
|
||||
throw new ObjectMetadataException(
|
||||
`Name is not synced with label. Expected name: "${computedName}", got ${name}`,
|
||||
ObjectMetadataExceptionCode.INVALID_OBJECT_INPUT,
|
||||
);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user