Skip to content

Commit

Permalink
✨ feat(translation): entity validations and selections
Browse files Browse the repository at this point in the history
  • Loading branch information
thrownullexception committed May 1, 2024
1 parent 75b4468 commit 56fc5c0
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 25 deletions.
8 changes: 6 additions & 2 deletions src/__tests__/_app.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { render, screen } from "@testing-library/react";

import MyApp from "pages/_app";
import { CustomNextPage } from "frontend/_layouts/types";
import { USE_ROUTER_PARAMS } from "./_/constants";

describe("pages/users", () => {
const useRouter = jest.spyOn(require("next/router"), "useRouter");

function Foo({ title }: { title: string }) {
// eslint-disable-next-line react/function-component-definition
const Foo: CustomNextPage = ({ title }: { title: string }) => {
return <p>{title}</p>;
}
};

Foo.useAppLayout = false;

it("should render components", async () => {
useRouter.mockImplementation(USE_ROUTER_PARAMS({}));
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/account/preferences.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe("pages/account/preferences", () => {
);

expect(await screen.findByRole("status")).toHaveTextContent(
"Account Preference Saved Successfully"
"Account Preferences Saved Successfully"
);
});

Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/admin/settings/theme.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("pages/admin/settings/theme", () => {
);

expect((await screen.findAllByRole("status"))[1]).toHaveTextContent(
"Account Preference Saved Successfully"
"Account Preferences Saved Successfully"
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,11 @@ const getNavigationTypeLink = (
case NavigationMenuItemType.Entities:
return NAVIGATION_LINKS.ENTITY.TABLE(link);
case NavigationMenuItemType.System:
return { ...SYSTEM_LINKS_CONFIG_MAP, ...PORTAL_SYSTEM_LINK_CONFIG_LINKS }[
link as SystemLinks
].link;
return (
{ ...SYSTEM_LINKS_CONFIG_MAP, ...PORTAL_SYSTEM_LINK_CONFIG_LINKS }[
link as SystemLinks
]?.link || "/"
);
}
};

Expand Down
32 changes: 28 additions & 4 deletions src/frontend/hooks/entity/entity.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,43 @@ export function useEntityFieldValidations(entity: string) {

return Object.fromEntries(
entityFields.data.map((entityField) => {
// The validation from the DB should override that of the config
// The validation from the DB should override that of the config but keep the configured error message
const preSelectedValidation =
entityValidationsMap.data[entityField.name] || [];

const preSelectedValidationMap = Object.fromEntries(
preSelectedValidation.map((validation) => [
validation.validationType,
validation,
])
);

const replaceWithCustomErrorMessages = (
validations: IFieldValidationItem[]
): IFieldValidationItem[] => {
return validations.map((validation) => {
return {
...validation,
errorMessage:
preSelectedValidationMap[validation.validationType]
.errorMessage || validation.errorMessage,
};
});
};

const uniqKey: keyof IFieldValidationItem = "validationType";
return [
entityField.name,
uniqBy(
[
...getFieldTypeBoundedValidations(
processedEntityFieldTypes[entityField.name]
...replaceWithCustomErrorMessages(
getFieldTypeBoundedValidations(
processedEntityFieldTypes[entityField.name]
)
),
...replaceWithCustomErrorMessages(
guessEntityValidations(entityField)
),
...guessEntityValidations(entityField),
...preSelectedValidation,
],
uniqKey
Expand Down
13 changes: 6 additions & 7 deletions src/frontend/views/account/Preferences/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,12 @@ export function UserPreferences() {

router.push({ pathname, query }, asPath, { locale: data.locale });

/*
const date = new Date()
const expireMs = 100 * 24 * 60 * 60 * 1000 // 100 days
date.setTime(date.getTime() + expireMs)
document.cookie = `NEXT_LOCALE=${locale};expires=${date.toUTCString()};path=/`
*/
// TODO set cookie to NEXT_LOCALE=the-locale
const date = new Date();
const expireMs = 100 * 24 * 60 * 60 * 1000; // 100 days
date.setTime(date.getTime() + expireMs);
document.cookie = `NEXT_LOCALE=${
data.locale
};expires=${date.toUTCString()};path=/`;
}}
initialValues={{ locale: router.locale || router.defaultLocale }}
buttonText={() => msg`Change Language`}
Expand Down
24 changes: 21 additions & 3 deletions src/frontend/views/entity/Fields/FieldsSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ interface IProps {
onSubmit: (values: IColorableSelection[]) => void;
}

const replaceForIntialValues = (selections: IColorableSelection[]) => {
return selections.map((selection) => ({
...selection,
label: { ...selection.label, message: selection.label.values[0] },
}));
};

const replaceForSubmission = (selections: IColorableSelection[]) => {
return selections.map((selection) => ({
...selection,
label: {
...selection.label,
message: "{0}",
values: { 0: selection.label.message },
},
}));
};

export function FieldSelectionCanvas({
field,
onSubmit,
Expand All @@ -62,12 +80,12 @@ export function FieldSelectionCanvas({
return (
<Form
onSubmit={(values: { selections: IColorableSelection[] }) => {
onSubmit(values.selections);
onSubmit(replaceForSubmission(values.selections));
}}
mutators={{
...arrayMutators,
}}
initialValues={{ selections }}
initialValues={{ selections: replaceForIntialValues(selections) }}
render={({ handleSubmit, values, pristine, form }) => (
<form onSubmit={handleSubmit}>
{entityType !== "boolean" && (
Expand Down Expand Up @@ -117,7 +135,7 @@ export function FieldSelectionCanvas({
)}
</Field>
<Field
name={`${name}.label`}
name={`${name}.label.message`}
validate={required}
validateFields={[]}
>
Expand Down
16 changes: 12 additions & 4 deletions src/frontend/views/entity/Fields/FieldsValidation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { DELETE_BUTTON_PROPS } from "frontend/design-system/components/Button/co
import { Fragment } from "react";
import { msg } from "@lingui/macro";
import { typescriptSafeObjectDotEntries } from "shared/lib/objects";
import { fakeMessageDescriptor } from "translations/fake";

interface IProps {
field: string;
Expand All @@ -38,7 +39,7 @@ interface IProps {
const ERROR_MESSAGE_LENGTH = 128;

// TODO: for contributors: Show the actuall error message not the template message
// TODO: make this work with i18n currently shows [object Object]

export function FieldValidationCanvas({
field,
onSubmit,
Expand All @@ -57,7 +58,14 @@ export function FieldValidationCanvas({
return (
<Form
onSubmit={(values: { validations: IFieldValidationItem[] }) => {
onSubmit(values.validations);
onSubmit(
values.validations.map((validation) => ({
...validation,
errorMessage: fakeMessageDescriptor(
validation.errorMessage.message
),
}))
);
}}
mutators={{
...arrayMutators,
Expand All @@ -79,7 +87,7 @@ export function FieldValidationCanvas({
return (
<Fragment key={name}>
<SectionBox
title={msg`${userFriendlyCase(validationType)}`}
title={ENTITY_VALIDATION_CONFIG[validationType].label}
actionButtons={
!isBoundToType && !fromSchema
? [
Expand Down Expand Up @@ -125,7 +133,7 @@ export function FieldValidationCanvas({
</>
)}
<Field
name={`${name}.errorMessage`}
name={`${name}.errorMessage.message`}
validate={composeValidators(
required,
maxLength(ERROR_MESSAGE_LENGTH)
Expand Down

0 comments on commit 56fc5c0

Please sign in to comment.