diff --git a/canvas_modules/common-canvas/__tests__/common-properties/components/title-editor-test.js b/canvas_modules/common-canvas/__tests__/common-properties/components/title-editor-test.js
index 053de78ee4..5b234dae88 100644
--- a/canvas_modules/common-canvas/__tests__/common-properties/components/title-editor-test.js
+++ b/canvas_modules/common-canvas/__tests__/common-properties/components/title-editor-test.js
@@ -39,6 +39,7 @@ controller.setAppData(appData);
const helpClickHandler = sinon.spy();
const help = { data: "test-data" };
+const description = "test description";
const titleChangeHandlerFunction = function(title, callbackFunction) {
// If Title is valid. No need to send anything in callbackFunction
@@ -143,6 +144,52 @@ describe("title-editor renders correctly", () => {
const helpButton = container.querySelector(".properties-title-editor-btn[data-id='help']");
fireEvent.click(helpButton);
});
+ it("test description button callback", () => {
+ helpClickHandler.resetHistory();
+ const wrapper = renderWithIntl(
+
+ );
+ const { container } = wrapper;
+ const helpButton = container.querySelector(".properties-title-editor-desc-btn[data-id='desc-help']");
+ fireEvent.click(helpButton);
+ });
+ it("test description should not be visible if description is not present", () => {
+ helpClickHandler.resetHistory();
+ const wrapper = renderWithIntl(
+
+ );
+ const { container } = wrapper;
+ expect(container.querySelector(".properties-title-desc-icon")).to.not.exist;
+ });
+ it("test description should not be visible if showHeadingDesc is not present", () => {
+ helpClickHandler.resetHistory();
+ const wrapper = renderWithIntl(
+
+ );
+ const { container } = wrapper;
+ expect(container.querySelector(".properties-title-desc-icon")).to.not.exist;
+ const helpButton = container.querySelector(".properties-title-editor-btn[data-id='help']");
+ fireEvent.click(helpButton);
+ });
it("test edit link", () => {
helpClickHandler.resetHistory();
const wrapper = renderWithIntl(
diff --git a/canvas_modules/common-canvas/__tests__/common-properties/form/form-test.js b/canvas_modules/common-canvas/__tests__/common-properties/form/form-test.js
index f0bb07e328..a90ea677b4 100644
--- a/canvas_modules/common-canvas/__tests__/common-properties/form/form-test.js
+++ b/canvas_modules/common-canvas/__tests__/common-properties/form/form-test.js
@@ -94,10 +94,11 @@ describe("Correct form should be created", () => {
}
};
let help;
+ let description;
let pixelWidth; // Pass in an undefined pixelWidth to simulate it missing from ParamDefs.
let conditions;
let resources;
- const expectedForm = new Form("TestOp", "TestOp", true, help, "small", pixelWidth, [primaryTabs], buttons, data, conditions, resources, "./test.svg");
+ const expectedForm = new Form("TestOp", "TestOp", true, help, description, "small", pixelWidth, [primaryTabs], buttons, data, conditions, resources, "./test.svg");
const paramSpec = {
"current_parameters": {
diff --git a/canvas_modules/common-canvas/__tests__/test_resources/json/form-placement-test.json b/canvas_modules/common-canvas/__tests__/test_resources/json/form-placement-test.json
index 93521ff0ae..e27fd85687 100644
--- a/canvas_modules/common-canvas/__tests__/test_resources/json/form-placement-test.json
+++ b/canvas_modules/common-canvas/__tests__/test_resources/json/form-placement-test.json
@@ -150,6 +150,7 @@
"componentId": "org.apache.spark.ml.ibm.transformers.Distinct",
"label": "Form placement test",
"labelEditable": true,
+ "description": "Remove rows to leave only rows with distinct combinations of rows",
"editorSize": "small",
"uiItems": [
{
diff --git a/canvas_modules/common-canvas/__tests__/test_resources/json/form-structure2-test.json b/canvas_modules/common-canvas/__tests__/test_resources/json/form-structure2-test.json
index f682f00ee3..49269ec07b 100644
--- a/canvas_modules/common-canvas/__tests__/test_resources/json/form-structure2-test.json
+++ b/canvas_modules/common-canvas/__tests__/test_resources/json/form-structure2-test.json
@@ -191,6 +191,7 @@
"componentId": "sort",
"label": "Form structure2 test",
"labelEditable": false,
+ "description": "Sorts the data",
"editorSize": "large",
"uiItems": [
{
diff --git a/canvas_modules/common-canvas/locales/common-properties/locales/en.json b/canvas_modules/common-canvas/locales/common-properties/locales/en.json
index 644fe60889..6b41b9f958 100644
--- a/canvas_modules/common-canvas/locales/common-properties/locales/en.json
+++ b/canvas_modules/common-canvas/locales/common-properties/locales/en.json
@@ -33,7 +33,7 @@
"summary.longTable.placeholder": "More than ten fields...",
"alerts.tab.title": "Alerts",
"title.editor.label": "edit title",
- "title.editor.helpButton.label": "help",
+ "title.editor.helpButton.label": "Help",
"table.summary.error": "There are {errorMsgCount} error cells. ",
"table.summary.warning": "There are {warningMsgCount} warning cells. ",
"control.summary.error": "There are {errorMsgCount} parameters with errors. ",
diff --git a/canvas_modules/common-canvas/src/common-properties/components/title-editor/title-editor.jsx b/canvas_modules/common-canvas/src/common-properties/components/title-editor/title-editor.jsx
index 952a0b699c..59469bedb3 100644
--- a/canvas_modules/common-canvas/src/common-properties/components/title-editor/title-editor.jsx
+++ b/canvas_modules/common-canvas/src/common-properties/components/title-editor/title-editor.jsx
@@ -20,15 +20,15 @@ import { connect } from "react-redux";
import Isvg from "react-inlinesvg";
import { get } from "lodash";
import classNames from "classnames";
-import { Help, Edit, Close } from "@carbon/react/icons";
+import { Help, Edit, Close, Information } from "@carbon/react/icons";
import { TextInput, Button, Layer } from "@carbon/react";
+import { Toggletip, ToggletipButton, ToggletipContent, ToggletipActions } from "@carbon/react";
import { setTitle } from "./../../actions";
import { MESSAGE_KEYS, CONDITION_MESSAGE_TYPE } from "./../../constants/constants";
import * as PropertyUtils from "./../../util/property-utils";
import ActionFactory from "../../actions/action-factory.js";
-
class TitleEditor extends Component {
constructor(props) {
super(props);
@@ -137,19 +137,68 @@ class TitleEditor extends Component {
hasIconOnly
/>);
- const helpButton = this.props.help
- ? ()
- : null;
+ const renderTooltip = (isDescWithLink) => {
+ const { description } = this.props;
+ // If description is present and has a link, show help button
+ const tooltipButton = isDescWithLink ? (
+
+
+
+ ) : null;
+
+ return (
+
+
+
+
+
+
+ {description}
+ {tooltipButton}
+
+
+
+ );
+ };
+
+ const renderHelpButton = () => {
+ const { help } = this.props;
+
+ return help ? (
+
+ ) : null;
+ };
+
+ const renderHelpOrTooltipButton = () => {
+ const { showHeadingDesc, description, help } = this.props;
+
+ // If showHeadingDesc is true and description is present, show tooltip
+ if (showHeadingDesc && description) {
+ return renderTooltip(help);
+ }
+
+ // If description is not present, show help button
+ return renderHelpButton();
+ };
+
+ const helpButton = renderHelpOrTooltipButton();
const closeButton = this.props.closeHandler
? (
@@ -195,7 +244,8 @@ class TitleEditor extends Component {
);
@@ -666,6 +668,7 @@ PropertiesMain.propTypes = {
conditionReturnValueHandling: PropTypes.string,
returnValueFiltering: PropTypes.array,
heading: PropTypes.bool,
+ showHeadingDesc: PropTypes.bool,
buttonLabels: PropTypes.shape({
primary: PropTypes.string,
secondary: PropTypes.string
diff --git a/canvas_modules/harness/src/client/App.js b/canvas_modules/harness/src/client/App.js
index a782180aee..7d909c6945 100644
--- a/canvas_modules/harness/src/client/App.js
+++ b/canvas_modules/harness/src/client/App.js
@@ -287,6 +287,7 @@ class App extends React.Component {
trimSpaces: true,
displayAdditionalComponents: false,
heading: false,
+ showHeadingDesc: false,
light: true,
lightTheme: false,
showRequiredIndicator: true,
@@ -2072,6 +2073,7 @@ class App extends React.Component {
disableSaveOnRequiredErrors: this.state.disableSaveOnRequiredErrors,
trimSpaces: this.state.trimSpaces,
heading: this.state.heading,
+ showHeadingDesc: this.state.showHeadingDesc,
showRequiredIndicator: this.state.showRequiredIndicator,
showAlertsTab: this.state.showAlertsTab,
enableResize: this.state.enableResize,
@@ -2511,6 +2513,7 @@ class App extends React.Component {
expressionBuilder: this.state.expressionBuilder,
displayAdditionalComponents: this.state.displayAdditionalComponents,
heading: this.state.heading,
+ showHeadingDesc: this.state.showHeadingDesc,
light: this.state.light,
showRequiredIndicator: this.state.showRequiredIndicator,
showAlertsTab: this.state.showAlertsTab,
diff --git a/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties-param-def.json b/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties-param-def.json
index e27f3b99e2..a52cfa452b 100644
--- a/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties-param-def.json
+++ b/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties-param-def.json
@@ -12,6 +12,7 @@
"trimSpaces": true,
"displayAdditionalComponents": false,
"heading": false,
+ "showHeadingDesc": false,
"light": true,
"showRequiredIndicator": true,
"showAlertsTab": true,
@@ -105,6 +106,11 @@
"default": false,
"type": "boolean"
},
+ {
+ "id": "showHeadingDesc",
+ "default": false,
+ "type": "boolean"
+ },
{
"id": "light",
"default": false,
@@ -340,6 +346,16 @@
},
"control": "toggle"
},
+ {
+ "parameter_ref": "showHeadingDesc",
+ "label": {
+ "default": "showHeadingDesc"
+ },
+ "description": {
+ "default": "Show panel heading description"
+ },
+ "control": "toggle"
+ },
{
"parameter_ref": "light",
"label": {
@@ -713,6 +729,7 @@
"disableSaveOnRequiredErrors",
"trimSpaces",
"heading",
+ "showHeadingDesc",
"showRequiredIndicator",
"showAlertsTab",
"enableResize",
diff --git a/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties.jsx b/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties.jsx
index 7d889f9e6a..9a469f7b15 100644
--- a/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties.jsx
+++ b/canvas_modules/harness/src/client/components/sidepanel/properties/sidepanel-properties.jsx
@@ -80,6 +80,7 @@ export default class SidePanelProperties extends React.Component {
"trimSpaces": this.props.propertiesConfig.trimSpaces,
"displayAdditionalComponents": this.props.propertiesConfig.displayAdditionalComponents,
"heading": this.props.propertiesConfig.heading,
+ "showHeadingDesc": this.props.propertiesConfig.showHeadingDesc,
"light": this.props.propertiesConfig.light,
"showRequiredIndicator": this.props.propertiesConfig.showRequiredIndicator,
"showAlertsTab": this.props.propertiesConfig.showAlertsTab,
@@ -332,6 +333,7 @@ SidePanelProperties.propTypes = {
expressionBuilder: PropTypes.bool,
displayAdditionalComponents: PropTypes.bool,
heading: PropTypes.bool,
+ showHeadingDesc: PropTypes.bool,
light: PropTypes.bool,
showRequiredIndicator: PropTypes.bool,
showAlertsTab: PropTypes.bool,
diff --git a/canvas_modules/harness/test_resources/parameterDefs/readonly_paramDef.json b/canvas_modules/harness/test_resources/parameterDefs/readonly_paramDef.json
index ab6abeb21c..6ce3cd5b71 100644
--- a/canvas_modules/harness/test_resources/parameterDefs/readonly_paramDef.json
+++ b/canvas_modules/harness/test_resources/parameterDefs/readonly_paramDef.json
@@ -424,7 +424,11 @@
]
}
],
+ "description": {
+ "default": "Readonly description"
+ },
"help": {
+ "id": "link_for_description",
"data": {
"url": "randomUrl"
}
diff --git a/docs/pages/04.08-properties-config.md b/docs/pages/04.08-properties-config.md
index 41128c6c41..5f2d787b93 100644
--- a/docs/pages/04.08-properties-config.md
+++ b/docs/pages/04.08-properties-config.md
@@ -20,6 +20,8 @@ The Properties Config is an object passed as an optional prop to the `