Skip to content

Commit

Permalink
custom messages (#919)
Browse files Browse the repository at this point in the history
* add custom messages object to customization model

* use custom message in datacube not found view

* docs

* extract title

* message in example config
  • Loading branch information
adrianmroz-allegro authored Oct 20, 2022
1 parent 086156f commit 8215332
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 11 deletions.
3 changes: 3 additions & 0 deletions config-examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,9 @@ dataCubes:
pageMustLoadTimeout: 5000

customization:
messages:
dataCubeNotFound: |
Oh no! We looked hard but couldn't find your data cube. Sorry.
urlShortener: |
// also available: context.clientIp
return request.get('http://tinyurl.com/api-create.php?url=' + encodeURIComponent(url))
16 changes: 16 additions & 0 deletions docs/configuration-customizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,19 @@ Add Sentry DSN to report errors to Sentry. [Sentry documentation](https://docs.s
customization:
sentryDSN: https://<key>@sentry.io/<project>
```

## Messages

You can customize various messages that Turnilo displays in user interface.
All messages are optional and will be treated as markdown code.

```yaml
customization:
messages:
dataCubeNotFound: "**This DataCube does not exist**"
```

List of supported fields:

- `dataCubeNotFound` - message displayed when Turnilo cannot find DataCube.
Please note that if you have `guardDataCubes` setting turn on, Turnilo will treat cubes that are not in `x-turnilo-allow-datacubes` as not existing.
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export class TurniloApplication extends React.Component<TurniloApplicationProps,
{({ sources }) => {
const dataCube = NamedArray.findByName(sources.dataCubes, view.cubeName);
if (dataCube === undefined) {
return <DataCubeNotFound/>;
return <DataCubeNotFound customization={customization}/>;
}
return <CubeView
key={view.cubeName}
Expand Down
4 changes: 2 additions & 2 deletions src/client/components/message-panel/message-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import React from "react";
import React, { ReactNode } from "react";
import { Nullary } from "../../../common/utils/functional/functional";
import { Button } from "../button/button";
import "./message-panel.scss";
Expand All @@ -28,7 +28,7 @@ export const MessagePanelAction: React.FunctionComponent<ErrorViewActionProps> =
<Button type="primary" onClick={action} title={label} />;

interface ErrorViewProps {
message?: string;
message?: string | ReactNode;
title: string;
}

Expand Down
13 changes: 11 additions & 2 deletions src/client/components/no-data/data-cube-not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
*/

import React from "react";
import { ClientCustomization } from "../../../common/models/customization/customization";
import { navigateToHome } from "../../applications/turnilo-application/view";
import { STRINGS } from "../../config/constants";
import { MarkdownNode } from "../markdown-node/markdown-node";
import { MessagePanel, MessagePanelAction } from "../message-panel/message-panel";

export const DataCubeNotFound: React.FunctionComponent<{}> = () => {
return <MessagePanel title="DataCube not found">
interface DataCubeNotFoundProps {
customization: ClientCustomization;
}

export const DataCubeNotFound: React.FunctionComponent<DataCubeNotFoundProps> = ({ customization }) => {
const { dataCubeNotFound } = customization.messages;
const message = dataCubeNotFound && <MarkdownNode markdown={dataCubeNotFound} />;
return <MessagePanel title={STRINGS.noDataCube} message={message}>
<MessagePanelAction action={navigateToHome}
label="Go back to data cubes list"/>
</MessagePanel>;
Expand Down
1 change: 1 addition & 0 deletions src/client/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const STRINGS: any = {
create: "Create",
cubes: "cubes",
dataCubes: "Data Cubes",
noDataCube: "DataCube not found",
noDataCubes: "No Data Cubes present",
noDataCubesFound: "No Data Cubes found for query: ",
delete: "Delete",
Expand Down
3 changes: 2 additions & 1 deletion src/client/deserializers/customization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import { ClientCustomization, SerializedCustomization } from "../../common/model
import { deserialize as deserializeLocale } from "../../common/models/locale/locale";

export function deserialize(customization: SerializedCustomization): ClientCustomization {
const { headerBackground, locale, customLogoSvg, timezones, externalViews, hasUrlShortener, sentryDSN } = customization;
const { headerBackground, messages, locale, customLogoSvg, timezones, externalViews, hasUrlShortener, sentryDSN } = customization;
return {
headerBackground,
customLogoSvg,
externalViews,
hasUrlShortener,
sentryDSN,
messages,
locale: deserializeLocale(locale),
timezones: timezones.map(Timezone.fromJS)
};
Expand Down
6 changes: 4 additions & 2 deletions src/common/models/app-settings/app-settings.fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export const clientAppSettings: ClientAppSettings = {
hasUrlShortener: false,
externalViews: [],
timezones: [],
locale: LOCALES["en-US"]
locale: LOCALES["en-US"],
messages: {}
},
oauth: { status: "disabled" },
clientTimeout: 1000
Expand All @@ -36,7 +37,8 @@ export const appSettings: AppSettings = {
timezones: [],
locale: LOCALES["en-US"],
externalViews: [],
cssVariables: {}
cssVariables: {},
messages: {}
},
oauth: { status: "disabled" },
version: 0
Expand Down
17 changes: 14 additions & 3 deletions src/common/models/customization/customization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ const availableCssVariables = [
// Note: We could use some TS magick to link this type to availableCssVariables
type CssVariables = Record<string, string>;

interface Messages {
dataCubeNotFound?: string;
}

export interface Customization {
title?: string;
headerBackground?: string;
Expand All @@ -115,6 +119,7 @@ export interface Customization {
sentryDSN?: string;
cssVariables: CssVariables;
locale: Locale;
messages: Messages;
}

export interface CustomizationJS {
Expand All @@ -127,6 +132,7 @@ export interface CustomizationJS {
urlShortener?: UrlShortenerDef;
sentryDSN?: string;
cssVariables?: Record<string, string>;
messages?: Messages;
}

export interface SerializedCustomization {
Expand All @@ -137,6 +143,7 @@ export interface SerializedCustomization {
hasUrlShortener: boolean;
sentryDSN?: string;
locale: Locale;
messages: Messages;
}

export interface ClientCustomization {
Expand All @@ -147,6 +154,7 @@ export interface ClientCustomization {
hasUrlShortener: boolean;
sentryDSN?: string;
locale: Locale;
messages: Messages;
}

function verifyCssVariables(cssVariables: Record<string, string>): CssVariables {
Expand All @@ -173,7 +181,8 @@ export function fromConfig(config: CustomizationJS = {}): Customization {
urlShortener,
sentryDSN,
cssVariables = {},
locale
locale,
messages = {}
} = config;

const timezones = Array.isArray(configTimezones)
Expand All @@ -193,20 +202,22 @@ export function fromConfig(config: CustomizationJS = {}): Customization {
urlShortener: urlShortenerFromConfig(urlShortener),
timezones,
locale: localeFromConfig(locale),
messages,
externalViews
};
}

export function serialize(customization: Customization): SerializedCustomization {
const { customLogoSvg, timezones, headerBackground, locale, externalViews, sentryDSN, urlShortener } = customization;
const { customLogoSvg, timezones, headerBackground, locale, externalViews, sentryDSN, urlShortener, messages } = customization;
return {
customLogoSvg,
externalViews,
hasUrlShortener: isTruthy(urlShortener),
headerBackground,
sentryDSN,
locale: serializeLocale(locale),
timezones: timezones.map(t => t.toJS())
timezones: timezones.map(t => t.toJS()),
messages
};
}

Expand Down

0 comments on commit 8215332

Please sign in to comment.