Skip to content

Commit

Permalink
#1217 Support info icons in expression table headers with custom labe…
Browse files Browse the repository at this point in the history
…ls (#1219)
  • Loading branch information
caritaou authored Oct 24, 2022
1 parent 2953fdf commit 53be8ff
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 30 deletions.
17 changes: 17 additions & 0 deletions canvas_modules/common-canvas/__tests__/_utils_/intl-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import { IntlProvider } from "react-intl";
import { mount, shallow } from "enzyme";

import { getMessages } from "../../../harness/src/intl/intl-utils";
import * as HarnessBundles from "../../../harness/src/intl/locales";

const defaultLocale = "en-US";
const locale = defaultLocale;

Expand All @@ -31,6 +34,20 @@ export function mountWithIntl(node, inOptions) {
return mount(node, options);
}

// Allow for custom resources to be applied from the test harness
export function mountWithIntlMessages(node, inOptions) {
const messages = getMessages("en", [HarnessBundles]); // Allow test harness to override labels
const options = Object.assign({
wrappingComponent: IntlProvider,
wrappingComponentProps: {
locale,
defaultLocale,
messages
}
}, inOptions);
return mount(node, options);
}

export function shallowWithIntl(node) {
return shallow(node, {
wrappingComponent: IntlProvider,
Expand Down
48 changes: 47 additions & 1 deletion canvas_modules/common-canvas/__tests__/_utils_/property-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import React from "react";
import CommonProperties from "../../src/common-properties/common-properties.jsx";
import * as UiConditionsParser from "../../src/common-properties/ui-conditions/ui-conditions-parser.js";
import { mountWithIntl } from "./intl-utils";
import { mountWithIntl, mountWithIntlMessages } from "./intl-utils";
import { expect } from "chai";
import cloneDeep from "lodash/cloneDeep";

Expand Down Expand Up @@ -75,6 +75,51 @@ function flyoutEditorForm(paramDef, propertiesConfigOverrides, callbacksOverride
return { wrapper: wrapper, controller: renderedController, callbacks: callbacks };
}

// Uses 'mountWithIntlMessages()' to allow for custom resources to be applied from the test harness
function flyoutEditorFormWithIntl(paramDef, propertiesConfigOverrides, callbacksOverrides, propertiesInfoOverrides) {
const applyPropertyChanges = sinon.spy();
const closePropertiesDialog = sinon.spy();
let callbacks = {
applyPropertyChanges: applyPropertyChanges,
closePropertiesDialog: closePropertiesDialog,
controllerHandler: controllerHandler
};
if (callbacksOverrides) {
callbacks = Object.assign(callbacks, callbacksOverrides);
}

let propertiesInfo = {
parameterDef: cloneDeep(paramDef)
};

if (propertiesInfoOverrides) {
propertiesInfo = Object.assign(propertiesInfo, propertiesInfoOverrides);
}

let propertiesConfig = {
applyOnBlur: true,
rightFlyout: true,
containerType: "Custom"
};
if (propertiesConfigOverrides) {
propertiesConfig = Object.assign(propertiesConfig, propertiesConfigOverrides);
}

const wrapper = mountWithIntlMessages(
<div className="properties-right-flyout">
<CommonProperties
propertiesInfo={propertiesInfo}
propertiesConfig={propertiesConfig}
callbacks={callbacks}
customControls={[CustomTableControl, CustomToggleControl]}
customConditionOps={[CustomOpMax]}
/>
</div>
);

return { wrapper: wrapper, controller: renderedController, callbacks: callbacks };
}

function setControls(controller, controls) {
const parsedControls = [];
for (const control of controls) {
Expand Down Expand Up @@ -113,6 +158,7 @@ function getParameterFromParamDef(parameterId, paramDef) {

module.exports = {
flyoutEditorForm: flyoutEditorForm,
flyoutEditorFormWithIntl: flyoutEditorFormWithIntl,
setControls: setControls,
genLongString: genLongString,
openSummaryPanel: openSummaryPanel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import propertyUtils from "../../_utils_/property-utils";
import tableUtils from "./../../_utils_/table-utils";
import { MESSAGE_KEYS } from "../../../src/common-properties/constants/constants";
import * as messages from "./../../../locales/common-properties/locales/en.json";
import * as harnessMessages from "./../,,/../../../../harness/src/intl/locales/en.json";

import { mountWithIntl } from "../../_utils_/intl-utils";
import { expect } from "chai";
Expand Down Expand Up @@ -437,6 +438,33 @@ describe("expression-builder renders correctly", () => {
expect(expectedReturnType).to.eql(actualReturnType);
});
});

it("expression builder displays table header descriptions in info icon", () => {
propertiesInfo.expressionInfo = getCopy(ExpressionInfo.input);
const renderedObject = propertyUtils.flyoutEditorFormWithIntl(ExpressionParamdef, propertiesConfig, callbacks, propertiesInfo);
const wrapper = renderedObject.wrapper;
const expression = wrapper.find("div[data-id='properties-ctrl-expression']");
const expressionEditorBtn = expression.find("button.properties-expression-button");
expressionEditorBtn.simulate("click");

const valuesTable = wrapper.find("div.properties-value-table-container");
expect(valuesTable).to.have.length(1);

// Verify custom header label
const header = valuesTable.find("div[data-role='properties-header-row']");
const headerLabel = header.find(".properties-vt-label-tip-icon");
expect(headerLabel).to.have.length(1);
expect(header.text()).to.equal(harnessMessages[MESSAGE_KEYS.EXPRESSION_VALUE_COLUMN]);

// Verify info icon
const headerInfoIcon = header.find(".properties-vt-info-icon-tip");
expect(headerInfoIcon).to.have.length(1);
let infoTip = wrapper.find("div[data-id='properties-tooltip-Custom Value-info']");
expect(infoTip.props()).to.have.property("aria-hidden", true);
headerInfoIcon.find("div[data-id='properties-tooltip-Custom Value-info-trigger']").simulate("click");
infoTip = wrapper.find("div[data-id='properties-tooltip-Custom Value-info']");
expect(infoTip.props()).to.have.property("aria-hidden", false);
});
});

describe("expression-builder select from tables correctly", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -990,10 +990,14 @@
},
"field_columns": {
"field_column_info": {
"label": "Field"
},
"value_column_info": {
"label": "Value"
"label": {
"default": "Value"
},
"description": {
"default": "Globals value description"
}
}
}
},
Expand All @@ -1004,15 +1008,21 @@
},
"field_columns": {
"field_column_info": {
"label": "Group"
"label": {
"default": "Group"
}
},
"value_column_info": {
"label": "Counted Value"
"label": {
"default": "Counted Value"
}
},
"additional_column_info": [
{
"id": "type",
"label": "Type"
"label": {
"default": "Type"
}
}
]
}
Expand All @@ -1024,10 +1034,14 @@
},
"field_columns": {
"field_column_info": {
"label": "Parameter"
"label": {
"default": "Parameter"
}
},
"value_column_info": {
"label": "Current Value"
"label": {
"default": "Current Value"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@
"expression.fields.title": "Fields",
"expression.values.title": "Values",
"expression.field.column": "Field",
"expression.field.column.description": "",
"expression.storage.column": "Storage",
"expression.value.column": "Value",
"expression.value.column.description": "",
"expression.function.column": "Function",
"expression.return.column": "Return",
"expression.recently.used.column": "Item",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,14 @@ export const MESSAGE_KEYS = {
EXPRESSION_FIELDS_TITLE: "expression.fields.title",
EXPRESSION_VALUES_TITLE: "expression.values.title",
EXPRESSION_FIELD_COLUMN: "expression.field.column",
EXPRESSION_FIELD_COLUMN_DESCRIPTION: "expression.field.column.description",
EXPRESSION_STORAGE_COLUMN: "expression.storage.column",
EXPRESSION_VALUE_COLUMN: "expression.value.column",
EXPRESSION_VALUE_COLUMN_DESCRIPTION: "expression.value.column.description",
EXPRESSION_FUNCTION_COLUMN: "expression.function.column",
EXPRESSION_RETURN_COLUMN: "expression.return.column",
EXPRESSION_RECENTLY_USED_COLUMN: "expression.recently.used.column",
EXPRESSION_RECENTLY_USED_COLUMN_DESCRIPTION: "expression.recently.used.column.description",
EXPRESSION_FIELD_TAB: "expression.field.tab",
EXPRESSION_FUNCTIONS_TAB: "expression.functions.tab",
EXPRESSION_RECENTLY_USED: "expression.recently.used",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ export default class ExpressionSelectFieldOrFunction extends React.Component {
constructor(props) {
super(props);
this.reactIntl = props.controller.getReactIntl();
this.recentUseCat = formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_RECENTLY_USED);
this.valueColumn = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_VALUE_COLUMN);
this.valueColumnDesc = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_VALUE_COLUMN_DESCRIPTION);
this.recentUseCat = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_RECENTLY_USED);
this.recentUseCatInfo = {
id: this.recentUseCat,
locLabel: this.recentUseCat,
field_columns: {
field_column_info: {
locLabel: formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_RECENTLY_USED_COLUMN)
locLabel: formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_RECENTLY_USED_COLUMN)
},
value_column_info: {
locLabel: formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_VALUE_COLUMN)
locLabel: this.valueColumn,
descLabel: this.valueColumnDesc
}
}
};
Expand Down Expand Up @@ -256,23 +256,21 @@ export default class ExpressionSelectFieldOrFunction extends React.Component {
}

_makeDatasetFields(dataset, fieldDataset) {
const fieldColumn = formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_FIELD_COLUMN);
const storageColumn = formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_STORAGE_COLUMN);
const valueColumn = formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_VALUE_COLUMN);
const dropdownLabel = formatMessage(this.reactIntl,
MESSAGE_KEYS.EXPRESSION_FIELDS_DROPDOWN_TITLE);
const fieldColumn = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_FIELD_COLUMN);
const fieldColumnDesc = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_FIELD_COLUMN_DESCRIPTION);
const storageColumn = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_STORAGE_COLUMN);
const dropdownLabel = formatMessage(this.reactIntl, MESSAGE_KEYS.EXPRESSION_FIELDS_DROPDOWN_TITLE);
const fieldsCatInfo = {
id: "fields",
locLabel: dropdownLabel,
field_columns: {
field_column_info: {
locLabel: fieldColumn
locLabel: fieldColumn,
descLabel: fieldColumnDesc
},
value_column_info: {
locLabel: valueColumn
locLabel: this.valueColumn,
descLabel: this.valueColumnDesc
},
additional_column_info: [
{
Expand Down Expand Up @@ -369,8 +367,17 @@ export default class ExpressionSelectFieldOrFunction extends React.Component {
}

if (categoryInfo) {
fieldHeaders.push({ key: "fieldName", label: categoryInfo.field_columns.field_column_info.locLabel, resizable: true });
valueHeader.push({ key: "values", label: categoryInfo.field_columns.value_column_info.locLabel });
fieldHeaders.push({
key: "fieldName",
label: categoryInfo.field_columns.field_column_info.locLabel,
description: categoryInfo.field_columns.field_column_info.descLabel,
resizable: true
});
valueHeader.push({
key: "values",
label: categoryInfo.field_columns.value_column_info.locLabel,
description: categoryInfo.field_columns.value_column_info.descLabel
});
if (categoryInfo.field_columns.additional_column_info) {
for (let i = 0; i < categoryInfo.field_columns.additional_column_info.length; i++) {
sortable.push(categoryInfo.field_columns.additional_column_info[i].id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,19 @@ function setExpressionInfo(inExpressionInfo) {
if (inExpressionInfo.fields.field_categories) {
inExpressionInfo.fields.field_categories.forEach((fieldCat) => {
fieldCat.locLabel = l10nProvider.l10nLabel(fieldCat, fieldCat.id);

fieldCat.field_columns.field_column_info.locLabel = l10nProvider.l10nLabel(fieldCat.field_columns.field_column_info, fieldCat.id + ".field_column_info");
fieldCat.field_columns.value_column_info.locLabel = l10nProvider.l10nLabel(fieldCat.field_columns.value_column_info, fieldCat.id + ".value_column_info");

const fieldColInfoDesc = l10nProvider.l10nDesc(fieldCat.field_columns.field_column_info, fieldCat.id + ".field_column_info");
if (fieldColInfoDesc !== fieldCat.id + ".field_column_info") {
fieldCat.field_columns.field_column_info.descLabel = fieldColInfoDesc;
}
const valueColInfoDesc = l10nProvider.l10nDesc(fieldCat.field_columns.value_column_info, fieldCat.id + ".value_column_info");
if (valueColInfoDesc !== fieldCat.id + ".value_column_info") {
fieldCat.field_columns.value_column_info.descLabel = valueColInfoDesc;
}

if (fieldCat.field_columns.additional_column_info) {
fieldCat.field_columns.additional_column_info.forEach((col) => {
col.locLabel = l10nProvider.l10nLabel(col, fieldCat.id + ".additional_column_info." + col.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ function formatMessage(intl, key, substituteObj) {
const defaultMessages = { ...defaultMessages1, ...defaultMessages2 };
let formattedMessage;
if (typeof intl !== "undefined" && intl !== null) {
if (intl.messages[key] === "") {
return ""; // Allow empty strings
}
formattedMessage = intl.formatMessage({ id: key, defaultMessage: defaultMessages[key] }, substituteObj);
} else {
formattedMessage = defaultMessages[key];
Expand Down
5 changes: 3 additions & 2 deletions canvas_modules/harness/src/client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,9 @@ class App extends React.Component {

// Create messages here (not in the render) since that would cause
// unnecssary renders inside common-canvas and/or common-properties.
this.messages = getMessages(this.locale, [HarnessBundles,
CommandActionsBundles, CommonCanvasBundles, CommonPropsBundles, PaletteBundles, ToolbarBundles]);
this.messages = getMessages(this.locale, [
CommandActionsBundles, CommonCanvasBundles, CommonPropsBundles, PaletteBundles, ToolbarBundles,
HarnessBundles]); // Allow test harness to override labels
}

componentDidMount() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6343,6 +6343,9 @@
"value_column_info": {
"label": {
"default": "Value"
},
"description": {
"default": "Globals value description"
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions canvas_modules/harness/src/intl/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"dialog.nodePropertiesTitle": "Node Properties",
"canvas.emptyText": "Welcome to the Common Canvas test harness.{br}Your flow is empty!",
"canvas.emptyLink": "Click here to take a tour"
}
"canvas.emptyLink": "Click here to take a tour",
"expression.value.column": "Custom Value",
"expression.value.column.description": "Testing custom desc from app"
}

0 comments on commit 53be8ff

Please sign in to comment.