Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#2256 Add ability to display text description next to heading label #2263

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
<TitleEditor
store={controller.getStore()}
controller={controller}
labelEditable
help={help}
description={description}
showHeadingDesc
/>
);
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(
<TitleEditor
store={controller.getStore()}
controller={controller}
labelEditable
help={help}
showHeadingDesc
/>
);
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(
<TitleEditor
store={controller.getStore()}
controller={controller}
labelEditable
help={help}
description={description}
/>
);
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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
"componentId": "sort",
"label": "Form structure2 test",
"labelEditable": false,
"description": "Sorts the data",
"editorSize": "large",
"uiItems": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -137,19 +137,68 @@ class TitleEditor extends Component {
hasIconOnly
/>);

const helpButton = this.props.help
? (<Button
kind="ghost"
className="properties-title-editor-btn help"
data-id="help"
onClick={this.helpClickHandler}
tooltipPosition="bottom"
renderIcon={Help}
size="sm"
iconDescription={helpButtonLabel}
hasIconOnly
/>)
: null;
const renderTooltip = (isDescWithLink) => {
const { description } = this.props;
// If description is present and has a link, show help button
const tooltipButton = isDescWithLink ? (
<ToggletipActions>
<Button
className="properties-title-editor-desc-btn desc-help"
onClick={this.helpClickHandler}
data-id="desc-help"
size="sm"
>
{helpButtonLabel}
</Button>
</ToggletipActions>
) : null;

return (
<span className="properties-title-desc-icon">
<Toggletip className="properties-title-desc-tooltip" align="bottom" autoAlign>
<ToggletipButton label="Additional information">
<Information />
</ToggletipButton>
<ToggletipContent>
<p className="properties-title-editor-desc">{description}</p>
{tooltipButton}
</ToggletipContent>
</Toggletip>
</span>
);
};

const renderHelpButton = () => {
const { help } = this.props;

return help ? (
<Button
kind="ghost"
className="properties-title-editor-btn help"
data-id="help"
onClick={this.helpClickHandler}
tooltipPosition="bottom"
renderIcon={Help}
size="sm"
iconDescription={helpButtonLabel}
hasIconOnly
/>
) : 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
? (<div className="properties-close-button">
Expand Down Expand Up @@ -195,7 +244,8 @@ class TitleEditor extends Component {
<div className={classNames(
"properties-title-editor-input",
{
"properties-title-editor-with-help": this.props.help && !this.headingEnabled && !titleValidationTypes.includes(get(this.state.titleValidation, "type")),
"properties-title-editor-with-help": (this.props.help || this.props.description) &&
!this.headingEnabled && !titleValidationTypes.includes(get(this.state.titleValidation, "type")),
"properties-title-editor-with-warning": titleWithWarning,
"properties-title-editor-with-error": titleWithErrror
}
Expand Down Expand Up @@ -239,8 +289,10 @@ TitleEditor.propTypes = {
icon: PropTypes.string,
heading: PropTypes.string,
showHeading: PropTypes.bool,
showHeadingDesc: PropTypes.bool,
rightFlyoutTabsView: PropTypes.bool,
titleInfo: PropTypes.object,
description: PropTypes.object,
title: PropTypes.string, // set by redux
setTitle: PropTypes.func // set by redux
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@
margin-left: $spacing-02; // spacing between heading label and help button
}
}
.properties-title-desc-icon {
position: relative;
margin-left: $spacing-04; // spacing between desc tooltip and heading label
}
}
.properties-title-editor-input {
width: calc(100% - #{$spacing-03}); // subtract 8px to align with Close icon when applyOnBlur is set
Expand Down Expand Up @@ -152,3 +156,15 @@
justify-content: center;
padding: 0;
}

.properties-title-desc-icon {
position: absolute;
margin: $spacing-03 0 0 $spacing-03; // spacing between desc tooltip and heading label
}

.properties-title-editor {
.tooltip-container {
height: $spacing-05;
cursor: pointer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import { Size } from "../constants/form-constants";
import { CONTAINER_TYPE } from "../constants/constants";

export default class Form {
constructor(componentId, label, labelEditable, help, editorSize, pixelWidth, uiItems, buttons, data, conditions, resources, icon, heading, title, titleUiItems) {
constructor(componentId, label, labelEditable, help, description, editorSize, pixelWidth, uiItems, buttons, data, conditions, resources, icon, heading, title, titleUiItems) {
this.componentId = componentId;
this.label = label;
this.labelEditable = labelEditable;
this.help = help;
this.description = description;
this.editorSize = editorSize;
this.pixelWidth = pixelWidth;
this.uiItems = uiItems;
Expand Down Expand Up @@ -81,6 +82,7 @@ export default class Form {
propDef.label,
propDef.labelEditable,
propDef.help,
l10nProvider.l10nResource(propDef.description),
propDef.editorSizeHint(editorSizeDefault),
propDef.pixelWidth,
[UIItem.makePrimaryTabs(tabs)],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,14 @@ class PropertiesMain extends React.Component {
propertiesTitle = (<TitleEditor
labelEditable={formData.labelEditable}
help={formData.help}
description={formData.description}
controller={this.propertiesController}
helpClickHandler={this.props.callbacks.helpClickHandler}
closeHandler={applyOnBlurEnabled ? this.applyPropertiesEditing.bind(this, true) : null}
icon={formData.icon}
heading={formData.heading}
showHeading={this.props.propertiesConfig.heading}
showHeadingDesc={this.props.propertiesConfig.showHeadingDesc}
titleInfo={formData.title}
rightFlyoutTabsView={this.props.propertiesConfig.categoryView === CATEGORY_VIEW.TABS}
/>);
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions canvas_modules/harness/src/client/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ class App extends React.Component {
trimSpaces: true,
displayAdditionalComponents: false,
heading: false,
showHeadingDesc: false,
light: true,
lightTheme: false,
showRequiredIndicator: true,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"trimSpaces": true,
"displayAdditionalComponents": false,
"heading": false,
"showHeadingDesc": false,
"light": true,
"showRequiredIndicator": true,
"showAlertsTab": true,
Expand Down Expand Up @@ -105,6 +106,11 @@
"default": false,
"type": "boolean"
},
{
"id": "showHeadingDesc",
"default": false,
"type": "boolean"
},
{
"id": "light",
"default": false,
Expand Down Expand Up @@ -340,6 +346,16 @@
},
"control": "toggle"
},
{
"parameter_ref": "showHeadingDesc",
"label": {
"default": "headingDesc"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the label to showHeadingDesc. Label should match with the config option.

},
"description": {
"default": "Show panel heading description"
},
"control": "toggle"
},
{
"parameter_ref": "light",
"label": {
Expand Down Expand Up @@ -713,6 +729,7 @@
"disableSaveOnRequiredErrors",
"trimSpaces",
"heading",
"showHeadingDesc",
"showRequiredIndicator",
"showAlertsTab",
"enableResize",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,11 @@
]
}
],
"description": {
"default": "Readonly description"
},
"help": {
"id": "link_for_description",
"data": {
"url": "randomUrl"
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nmgokhale Is it okay if the help object is updated like this in paramDef to fetch description and link ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should be using https://github.com/elyra-ai/pipeline-schemas/blob/main/common-pipeline/operators/uihints-v3-schema.json#L23. I don't think we need to add another description object.

We'd need a config option though that would allow users to determine if descriptions are included or not.

Copy link
Contributor Author

@srikant-ch5 srikant-ch5 Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthoward366 I have updated PR to use description. Could you please have a look and let me know if the usage is fine ? (few changes pending, such as updating description.link.propertyId and description.default, and I will make those updates soon.). I have also included a config option headingDesc to switch between help button and tooltip.

Expand Down
2 changes: 2 additions & 0 deletions docs/pages/04.08-properties-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The Properties Config is an object passed as an optional prop to the `<CommonPro

* heading `boolean`: show heading and heading icon in right-side fly-out panels. default: `false`

* showHeadingDesc `boolean`: When set to true, it will display a tooltip containing a description and a button that redirects to the provided URL in `help`. The default value is false.

* schemaValidation `boolean`: If set to true, schema validation will be enabled when a parameter definition has been set in CommonProperties. Any errors found will be reported on the browser dev console. It is recommended you run with schema validation switched on while in development mode.

* applyPropertiesWithoutEdit `boolean`: When true, will always call `applyPropertyChanges` even if no changes were made. default: `false`
Expand Down
Loading