Skip to main content

Locations

A custom integration enables you to extend the Uniform dashboard with custom user interfaces from a web application you build. This section describes the different locations in the Uniform dashboard where your custom integration can be included.

Install

When a custom integration is installed, it is helpful to show the Canvas administrator a description of the custom integration.

You are able to provide one or more paragraphs of text that is displayed to the Canvas administrator when the custom integration is assigned to a project.

install-example
info

This is not an interactive location. The information provided in this location is displayed to the user, but the user cannot change it.

Settings

Each custom integration has project-specific settings that might need to be configured. For example, an integration that creates a connection to a commerce system might enable a Uniform user to specify credentials for Uniform to use to communicate with the commerce system.

When a custom integration is added to a project, its settings are available as a new link in the left menu on the Settings section of the Uniform dashboard.

settings-example
The custom integration name appears in the left menu. The page identified by the custom integration's settings location appears in the content area.

The user inteface displays the settings that are currently configured, and allows the user to make changes to those settings. You can implement this logic in your preferred framework.

The following describes the lifecycle of the settings page:

  1. Canvas injects your integration's user interface into the settings page using an iframe.
  2. Canvas user makes a change to the controls displayed in the iframe.
  3. This change is saved in memory. Custom logic from the integration handles this.
  4. Canvas user clicks the Save button.
  5. Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.

The following code demonstrates the custom logic required to save a change to memory. This value can be used in the other location pages.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="api-key"
type="text"
value={value?.key}
onChange={(e) => setValue({ key: e.target.value })}
/>
</div>
);
}

Canvas

Canvas locations allow you to define custom parameter types, and to provide a user interface for using these types. The following locations are supported.

Parameter configuration

Configuration happens when the parameter is added to a component definition. When a parameter is a simple value like text or a number, no additional options are necessary. But even a numeric type could have additional options, such as minimum and maximum values.

When you create a custom integration, you may want to allow the Canvas user who is adding the parameter to a component to be able to configure some additional settings. The parameter configuration location allows you to add form fields between the Type field and the OK button.

configure-parameter-example

The following describes the lifecycle of the parameter configuration page:

  1. Canvas injects your integration's user interface into the parameter configuration page using an iframe.
  2. Canvas user makes a change to the controls displayed in the iframe.
  3. This change is saved in memory. Custom logic from the integration handles this.
  4. Canvas user clicks the OK button.
  5. Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.

The following code demonstrates the custom logic required to save a change to memory. This value can be used in the parameter editing page to control the options presented to the editor.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) => setValue({ filter: e.target.value })}
/>
</div>
);
}

Parameter configuration validation

Your parameter configuration UI can participate in the parameter configuration validation process by passing along optional validation information when calling the setValue function. The setValue function accepts a second, optional, parameter with the following shape:

{
isValid: boolean;
validationMessage: string;
}

When the isValid property is false, the value of the validationMessage property will be displayed in the parameter configuration validation results.

Setting the isValid property to true will remove any previous validation error message that was provided and the validator will allow the configuration value to be saved.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterConfig() {
const { value, setValue } = useUniformMeshLocation();
return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) =>
setValue(
{ filter: e.target.value },
{
isValid: false,
validationMessage: 'Parameter configuration is invalid',
}
)
}
/>
</div>
);
}

You can also directly set a validation result without setting a configuration value. This is particularly useful on initial render of your configuration UI, when your configuration requires input from the user but no value has been set.

In this scenario, you can set your configuration as invalid by using the setValidationResult function available via the useUniformMeshLocation hook.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';
import { useEffect } from 'react';

export default function MyParameterConfig() {
const { value, setValue, setValidationResult } = useUniformMeshLocation();

useEffect(() => {
// Note: `isValid` is an arbitrary function you could implement to determine
// if `value` is indeed valid and then proceed accordingly.
if (!isValid(value)) {
const runEffect = async () => {
await setValidationResult({
isValid: false,
validationMessage: 'Parameter configuration is required',
});
};
runEffect();
}
}, []);

return (
<div>
<Input
id="my-filter"
type="text"
value={value?.filter}
onChange={(e) =>
setValue(
{ filter: e.target.value },
{
isValid: false,
validationMessage: 'Parameter configuration is invalid',
}
)
}
/>
</div>
);
}

Parameter editing

Editing happens when a Canvas user sets the value on a specific parameter on a specific component. If the parameter represents a product from a commerce system's product catalog, you might want to provide the Canvas user a visual representation of the product catalog to make it easier for the user to select the appropriate product.

The parameter editing location allows you to add form fields to the component parameters section.

edit-parameter-example

The following describes the lifecycle of the parameter editing page:

  1. Canvas injects your integration's user interface into the parameter editing page using an iframe.
  2. Canvas user makes a change to the controls displayed in the iframe.
  3. This change is saved in memory. Custom logic from the integration handles this.
  4. Canvas user clicks the Save button.
  5. Changes that were previously saved in memory are saved to persistent storage. Uniform does this automatically.

The following code demonstrates the custom logic required to load the settings that were added in the parameter configuration page, use that value to control the user interface available to the editor, and then save a change to memory.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterEditing() {
const { value, setValue, metadata } = useUniformMeshLocation();
const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) => setValue({ filtered: e.target.value })}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) => setValue({ unfiltered: e.target.value })}
/>
</div>
);
}

Parameter editing validation

Your Canvas parameter editor can participate in the Canvas validation process by passing along optional validation information when calling the setValue function. The setValue function accepts a second, optional, parameter with the following shape:

{
isValid: boolean;
validationMessage: string;
}

When the isValid property is false, the value of the validationMessage property will be displayed in the Canvas validation results.

Setting the isValid property to true will remove any previous validation error message that was provided and the Canvas validator will allow the parameter value to be saved.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterEditing() {
const { value, setValue, metadata } = useUniformMeshLocation();
const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) =>
setValue(
{ filtered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) =>
setValue(
{ unfiltered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}

You can also directly set a validation result without setting a parameter editor value. This is particularly useful on initial render of your editor UI, when your editor UI requires input from the user but no value has been set.

In this scenario, you can set your parameter value as invalid by using the setValidationResult function available via the useUniformMeshLocation hook.

import { Input } from '@uniformdev/design-system';
import { useUniformMeshLocation } from '@uniformdev/mesh-sdk-react';

export default function MyParameterEditing() {
const { value, setValue, metadata, setValidationResult } = useUniformMeshLocation();

useEffect(() => {
// Note: `isValid` is an arbitrary function you could implement to determine
// if `value` is indeed valid and then proceed accordingly.
if (!isValid(value)) {
const runEffect = async () => {
await setValidationResult({
isValid: false,
validationMessage: `Parameter value is invalid`,
});
};
runEffect();
}
}, []);

const filter = metadata?.parameterDefinition?.typeConfig?.filter;
if (filter) {
return (
<div>
<Input
id="input1"
type="text"
value={value?.filtered}
onChange={(e) =>
setValue(
{ filtered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}
return (
<div>
<Input
id="input2"
type="text"
value={value?.unfiltered}
onChange={(e) =>
setValue(
{ unfiltered: e.target.value },
{
isValid: false,
validationMessage: 'Parameter value is invalid',
}
)
}
/>
</div>
);
}