From b8d05a1acefddd72c5b639e4eb4e1d0e8fd10e9e Mon Sep 17 00:00:00 2001 From: eric-burel Date: Fri, 17 Dec 2021 16:43:17 +0100 Subject: [PATCH] FormattedMessage shows at least i18n key when no message is found --- packages/graphql/extendModel.server.ts | 44 ++++++++++++++++--- packages/graphql/extendModel.ts | 11 ++++- .../i18n/lib/modules/FormattedMessage.tsx | 2 +- .../tests/FormattedMessage.stories.tsx | 28 ++++++++++++ .../react-ui/components/MutationButton.tsx | 1 + 5 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 packages/i18n/lib/modules/tests/FormattedMessage.stories.tsx diff --git a/packages/graphql/extendModel.server.ts b/packages/graphql/extendModel.server.ts index 3504aa18..2969c746 100644 --- a/packages/graphql/extendModel.server.ts +++ b/packages/graphql/extendModel.server.ts @@ -31,18 +31,23 @@ import { } from "./server/resolvers"; // don't forget to reexport common code export * from "./extendModel"; -import extendModel, { GraphqlModelOptions } from "./extendModel"; +import extendModel, { + GraphqlModelDefinition, + GraphqlModelOptions, +} from "./extendModel"; import cloneDeep from "lodash/cloneDeep"; import isEmpty from "lodash/isEmpty"; + +import merge from "lodash/merge"; /** * This type is meant to be exposed server side *  @server-only */ export interface GraphqlModelOptionsServer extends GraphqlModelOptions { /** Custom query resolvers (single, multi). Set to "null" if you don't want Vulcan to set any resolvers. Leave undefined if you want to use default resolvers. */ - queryResolvers?: Partial; + queryResolvers?: Partial | null; /** Custom mutation resolvers (create, update, delete). Set to "null" if you don't want Vulcan to set any resolvers. Leave undefined if you want to use default resolvers. */ - mutationResolvers?: Partial; + mutationResolvers?: Partial | null; callbacks?: MutationCallbackDefinitions; } @@ -99,9 +104,10 @@ const extendSchemaServer = ( }; /** - * Adds server-only fields as well - * @param options - * @returns + * Plugin function that adds graphql options to a generic model, + * including server-side fields + * + * NOTE: should not be used directly, prefer calling "createGraphqlModelServer" */ export const extendModelServer = ( @@ -145,8 +151,13 @@ export interface CreateGraphqlModelOptionsServer extends CreateModelOptions { graphql: GraphqlModelOptionsServer; } +/** + * Server-side definition of a model + */ +export type GraphqlModelDefinitionServer = CreateGraphqlModelOptionsServer; /** + * Create a graphql model, accepting server-options * @server-only */ export const createGraphqlModelServer = ( @@ -161,6 +172,27 @@ export const createGraphqlModelServer = ( return model; }; +/** + * Adds server only options to a model + * @param fullModelDef + * @param extensionModelDef + * @returns + */ +export const mergeModelDefinitionServer = ( + fullModelDef: GraphqlModelDefinition, + /** + * Partial model definition, adding some server-only options to an existing model + */ + extensionModelDef: Omit, "graphql"> & { + graphql?: Partial; + } +) => { + return merge({}, fullModelDef, extensionModelDef); +}; + +/** + */ + //// CODE FROM CREATE COLLECTION //import { Mongo } from "meteor/mongo"; //import SimpleSchema from "simpl-schema"; diff --git a/packages/graphql/extendModel.ts b/packages/graphql/extendModel.ts index 5acb82dc..968eba2f 100644 --- a/packages/graphql/extendModel.ts +++ b/packages/graphql/extendModel.ts @@ -41,7 +41,11 @@ export interface GraphqlModelOptionsShared extends GraphqlModelOptions { callbacks?: never; } -// Reusable model extension function +/** + * Plugin function that adds graphql options to a generic model + * + * NOTE: should not be used directly, prefer calling "createGraphqlModel" + */ const extendModel = (options: GraphqlModelOptions) /*: ExtendModelFunc*/ => (model: VulcanModel): VulcanGraphqlModel => { @@ -93,6 +97,11 @@ export interface CreateGraphqlModelOptionsShared // => it will display nicer messages when you try to mistakenly use a server-only field graphql: GraphqlModelOptionsShared; } +/** + * Definition of a model, to be passed to "createGraphqlModel" + */ +export type GraphqlModelDefinition = CreateGraphqlModelOptionsShared; + /** * Let's you create a full-fledged graphql model * diff --git a/packages/i18n/lib/modules/FormattedMessage.tsx b/packages/i18n/lib/modules/FormattedMessage.tsx index 4bd5e6e4..4916c272 100644 --- a/packages/i18n/lib/modules/FormattedMessage.tsx +++ b/packages/i18n/lib/modules/FormattedMessage.tsx @@ -25,7 +25,7 @@ export const FormattedMessage = ({ const cssClass = `i18n-message ${className}`; // if message is empty (no message found AND no default message), use [id] - if (message === "") { + if (!message /* === ""*/) { message = `[${id}]`; } diff --git a/packages/i18n/lib/modules/tests/FormattedMessage.stories.tsx b/packages/i18n/lib/modules/tests/FormattedMessage.stories.tsx new file mode 100644 index 00000000..87d27ca5 --- /dev/null +++ b/packages/i18n/lib/modules/tests/FormattedMessage.stories.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { Story, Meta } from "@storybook/react"; +import { FormattedMessage, FormattedMessageProps } from "../FormattedMessage"; + +export default { + component: FormattedMessage, + title: "FormattedMessage", + decorators: [ + (Story) => ( + // Replace by VulcanComponents if you need them +
+ +
+ ), + ], + args: {}, + parameters: { actions: { argTypesRegex: "^.*Callback$" } }, +} as Meta; + +const FormattedMessageTemplate: Story = (args) => ( + +); +export const DefaultFormattedMessage = FormattedMessageTemplate.bind({}); + +export const UnknownId = FormattedMessageTemplate.bind({}); +UnknownId.args = { + id: "unknown-id-should-be-displayed-as-is", +}; diff --git a/packages/react-ui/components/MutationButton.tsx b/packages/react-ui/components/MutationButton.tsx index c9a4cdb5..d004322c 100644 --- a/packages/react-ui/components/MutationButton.tsx +++ b/packages/react-ui/components/MutationButton.tsx @@ -113,6 +113,7 @@ export const MutationButton = (props: MutationButtonProps) => { await successCallback(result); } } catch (error) { + // TODO: may not work because the mutationFunc may not throw in case of error setError(error); if (errorCallback) { await errorCallback(error);