Skip to content

Commit

Permalink
Add infobox to new types, add description for decision context, add b…
Browse files Browse the repository at this point in the history
…eta badges, move decisionContext to be inside personalization object.
  • Loading branch information
jonsnyder committed Oct 27, 2023
1 parent 5928bd6 commit 258f0ef
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 41 deletions.
43 changes: 31 additions & 12 deletions scripts/helpers/createExtensionManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,20 @@ const createExtensionManifest = ({ version }) => {
},
includeRenderedPropositions: {
type: "boolean"
},
decisionContext: {
anyOf: [
{
type: "string",
pattern: "^%[^%]+%$"
},
{
type: "object",
additionalProperties: {
type: "string"
}
}
]
}
},
additionalProperties: false
Expand Down Expand Up @@ -774,19 +788,24 @@ const createExtensionManifest = ({ version }) => {
renderDecisions: {
type: "boolean"
},
decisionContext: {
anyOf: [
{
type: "string",
pattern: "^%[^%]+%$"
},
{
type: "object",
additionalProperties: {
type: "string"
}
personalization: {
type: "object",
properties: {
decisionContext: {
anyOf: [
{
type: "string",
pattern: "^%[^%]+%$"
},
{
type: "object",
additionalProperties: {
type: "string"
}
}
]
}
]
}
}
},
libPath: "dist/lib/actions/evaluateRulesets/index.js",
Expand Down
78 changes: 56 additions & 22 deletions src/view/actions/evaluateRulesets.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,62 @@ import form from "../forms/form";
import instancePicker from "../forms/instancePicker";
import checkbox from "../forms/checkbox";
import simpleMap from "../forms/simpleMap";
import notice from "../forms/notice";

const evaluateRulesetsForm = form({}, [
instancePicker({ name: "instanceName" }),
checkbox({
name: "renderDecisions",
label: "Render decisions",
description:
"Select this option to render decisions. If you do not select this option, decisions will not be rendered.",
defaultValue: false
}),
simpleMap({
name: "decisionContext",
label: "Decision context",
singularLabel: "Context item",
dataElementDescription:
"Provide a data element that resolves to a map of strings",
keyLabel: "Key",
keyLabelPlural: "Keys",
keyDescription: "Enter the context key",
valueLabel: "Value",
valueDescription: "Enter the context value"
})
]);
const wrapGetInitialValues = getInitialValues => ({ initInfo }) => {
const { personalization = {}, ...otherSettings } = initInfo.settings || {};
return getInitialValues({
initInfo: {
...initInfo,
settings: { ...personalization, ...otherSettings }
}
});
};

const wrapGetSettings = getSettings => ({ values }) => {
const { decisionContext, ...settings } = getSettings({ values });
if (decisionContext) {
settings.personalization = {};
settings.personalization.decisionContext = decisionContext;
}
return settings;
};

const evaluateRulesetsForm = form(
{
wrapGetInitialValues,
wrapGetSettings
},
[
notice({
title: "Evaluate rulesets action",
description:
"This action manually triggers ruleset evaluation. Rulesets are returned from Adobe Journey Optimizer in-browser-messages.",
beta: true
}),
instancePicker({ name: "instanceName" }),
checkbox({
name: "renderDecisions",
label: "Render visual personalization decisions",
description:
"Check this to render visual personalization decisions for the ruleset items that match.",
defaultValue: false
}),
simpleMap({
name: "decisionContext",
label: "Decision context",
singularLabel: "Context item",
description:
"Provide the keys and values that the rulesets will use to determine which experience to deliver.",
dataElementDescription:
"Provide a data element that resolves to a map of key/value pairs.",
keyLabel: "Key",
keyLabelPlural: "Keys",
keyDescription: "Enter the context key.",
valueLabel: "Value",
valueDescription: "Enter the context value."
})
]
);

renderForm(evaluateRulesetsForm);
16 changes: 12 additions & 4 deletions src/view/actions/sendEvent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ const wrapGetSettings = getSettings => ({ values }) => {
surfaces,
sendDisplayEvent,
includeRenderedPropositions,
decisionContext,
...settings
} = getSettings({ values });
if (
decisionScopes ||
surfaces ||
sendDisplayEvent === false ||
includeRenderedPropositions
includeRenderedPropositions ||
decisionContext
) {
settings.personalization = {};
}
Expand All @@ -102,6 +104,9 @@ const wrapGetSettings = getSettings => ({ values }) => {
if (includeRenderedPropositions) {
settings.personalization.includeRenderedPropositions = includeRenderedPropositions;
}
if (decisionContext) {
settings.personalization.decisionContext = decisionContext;
}
return settings;
};

Expand Down Expand Up @@ -238,13 +243,16 @@ const decisionContext = simpleMap({
name: "decisionContext",
label: "Decision context",
singularLabel: "Context item",
description:
"Provide the keys and values that the rulesets will use to determine which experience to deliver.",
dataElementDescription:
"Provide a data element that resolves to a map of strings",
"Provide a data element that resolves to a map of key/value pairs.",
keyLabel: "Key",
keyLabelPlural: "Keys",
keyDescription: "Enter the context key",
keyDescription: "Enter the context key.",
valueLabel: "Value",
valueDescription: "Enter the context value"
valueDescription: "Enter the context value.",
beta: true
});

const configOverrideFields = configOverrides();
Expand Down
7 changes: 7 additions & 0 deletions src/view/events/subscribeRulesetItems.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,15 @@ import form from "../forms/form";
import instancePicker from "../forms/instancePicker";
import fieldArray from "../forms/fieldArray";
import { validateSurface } from "../utils/surfaceUtils";
import notice from "../forms/notice";

const subscribeRulesetItemsForm = form({}, [
notice({
title: "Subscribe ruleset items",
description:
"This event will trigger the rule whenever there are ruleset items that have matched. This is a good place to add an action to render the ruleset items. You can use the data element `%event.propositions%` to access the propositions. Or within a custom code action it is available as `event.propositions`.",
beta: true
}),
instancePicker({ name: "instanceName" }),
fieldArray({
name: "schemas",
Expand Down
43 changes: 43 additions & 0 deletions src/view/forms/notice.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright 2023 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import React from "react";
import BetaBadge from "../components/betaBadge";
import Alert from "../components/alert";

/** @typedef {import("./form").Form} Form */
/**
* This create a notice as part of a form
* @param {object} options - Options for the notice
* @param {string} options.title - The title of the notice
* @param {string} options.description - The description of the notice
* @param {boolean} [options.beta] - Whether or not this is a beta feature.
* @returns {Form} A notice form element.
*/
export default function notice({ title, description, beta }) {
const titleElement = (
<>
{title}
{beta && <BetaBadge />}
</>
);

return {
Component: () => {
return (
<Alert variant="informative" title={titleElement} width="size-5000">
{description}
</Alert>
);
}
};
}
19 changes: 16 additions & 3 deletions src/view/forms/simpleMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import DataElementSelector from "../components/dataElementSelector";
import singleDataElementRegex from "../constants/singleDataElementRegex";
import { DATA_ELEMENT_REQUIRED } from "../constants/validationErrorMessages";
import FormElementContainer from "../components/formElementContainer";
import BetaBadge from "../components/betaBadge";

const FORM = "form";
const DATA_ELEMENT = "dataElement";
Expand All @@ -36,6 +37,8 @@ const DATA_ELEMENT = "dataElement";
* @param {string} options.label - The label to use for the field.
* @param {string} options.singularLabel - The singular label to use for the add
* button. (i.e. "entry" for "Add entry")
* @param {string} options.description - The description to use for the field.
* This appears just below the radio buttons and above the array items.
* @param {string} [options.dataElementDescription] - The description to use for
* the data element field. Usually you would use this to describe the type the
* data element should be.
Expand All @@ -45,18 +48,22 @@ const DATA_ELEMENT = "dataElement";
* @param {string} [options.valueLabel] - The label to use for the value field.
* @param {string} [options.valueDescription] - The description to use for the
* value field.
* @param {boolean} [options.beta] - If true, a beta badge will be shown next to
* the label.
* @returns {Form} A form field for an array of strings.
*/
export default function simpleMap({
name,
label,
singularLabel,
description,
dataElementDescription,
keyLabel,
keyLabelPlural,
keyDescription,
valueLabel,
valueDescription
valueDescription,
beta
}) {
const itemSchema = object()
.shape({
Expand Down Expand Up @@ -157,13 +164,19 @@ export default function simpleMap({
const [{ value: items }, , { setValue: setItems }] = useField(
`${namePrefix}${name}`
);

const labelElement = (
<>
{label}
{beta && <BetaBadge />}
</>
);
return (
<>
<FormikRadioGroup
name={`${namePrefix}${name}InputMethod`}
orientation="horizontal"
label={label}
label={labelElement}
description={description}
>
<Radio data-test-id={`${namePrefix}${name}FormOption`} value={FORM}>
Manually enter {label.toLowerCase()}.
Expand Down

0 comments on commit 258f0ef

Please sign in to comment.