diff --git a/canvas_modules/common-canvas/__tests__/common-canvas/common-canvas-toolbar-test.js b/canvas_modules/common-canvas/__tests__/common-canvas/common-canvas-toolbar-test.js index eb227c7ba4..eade6a5387 100644 --- a/canvas_modules/common-canvas/__tests__/common-canvas/common-canvas-toolbar-test.js +++ b/canvas_modules/common-canvas/__tests__/common-canvas/common-canvas-toolbar-test.js @@ -54,7 +54,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(5); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomIn-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomOut-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomToFit-action")).to.have.length(1); @@ -77,7 +77,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(5); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomIn-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomOut-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomToFit-action")).to.have.length(1); @@ -100,7 +100,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(2); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.toggleNotificationPanel-action")).to.have.length(1); }); @@ -128,7 +128,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(10); expect(wrapper.find(".toolbar-divider")).to.have.length(3); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.undo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.redo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.cut-action")).to.have.length(1); @@ -168,7 +168,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(7); expect(wrapper.find(".toolbar-divider")).to.have.length(3); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.undo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.redo-action")).to.have.length(1); @@ -207,7 +207,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(6); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(0); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(0); expect(wrapper.find(".toolbar-item.undo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.redo-action")).to.have.length(1); @@ -247,7 +247,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item")).to.have.length(6); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.undo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.redo-action")).to.have.length(1); @@ -294,7 +294,7 @@ describe("Common Canvas Toolbar renders correctly with config as OBJECT", () => expect(wrapper.find(".toolbar-item.palette-action")).to.have.length(0); // Should have a "togglePalette" action. - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.undo-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.redo-action")).to.have.length(1); @@ -371,7 +371,7 @@ describe("Common Canvas Toolbar renders correctly with config as ARRAY", () => { expect(wrapper.find(".toolbar-item")).to.have.length(5); expect(wrapper.find(".toolbar-divider")).to.have.length(2); - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomIn-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomOut-action")).to.have.length(1); expect(wrapper.find(".toolbar-item.zoomToFit-action")).to.have.length(1); @@ -391,6 +391,6 @@ describe("Common Canvas Toolbar renders correctly with config as ARRAY", () => { expect(wrapper.find(".toolbar-item.palette-action")).to.have.length(0); // Should have a "togglePalette" action. - expect(wrapper.find(".toolbar-item.paletteClose-action")).to.have.length(1); + expect(wrapper.find(".toolbar-item.closePalette-action")).to.have.length(1); }); }); diff --git a/canvas_modules/common-canvas/src/common-canvas/canvas-controller.js b/canvas_modules/common-canvas/src/common-canvas/canvas-controller.js index 7ed3edf1ea..6107441f10 100644 --- a/canvas_modules/common-canvas/src/common-canvas/canvas-controller.js +++ b/canvas_modules/common-canvas/src/common-canvas/canvas-controller.js @@ -2406,15 +2406,15 @@ export default class CanvasController { this.objectModel.setZoom(data.zoom, data.pipelineId); break; } - case "paletteToggle": { + case "togglePalette": { this.togglePalette(); break; } - case "paletteOpen": { + case "openPalette": { this.openPalette(); break; } - case "paletteClose": { + case "closePalette": { this.closePalette(); break; } diff --git a/canvas_modules/common-canvas/src/common-canvas/cc-toolbar.jsx b/canvas_modules/common-canvas/src/common-canvas/cc-toolbar.jsx index dc9ae6d81b..3a94f4a77c 100644 --- a/canvas_modules/common-canvas/src/common-canvas/cc-toolbar.jsx +++ b/canvas_modules/common-canvas/src/common-canvas/cc-toolbar.jsx @@ -99,6 +99,12 @@ class CommonCanvasToolbar extends React.Component { return className; } + // Returns the index of the action passed in, in the + // 'bar' passed in. + getToolIndexByAction(action, bar) { + return bar?.findIndex((a) => a.action === action); + } + generateToolbarConfig() { let config = this.copyConfig(); @@ -113,10 +119,8 @@ class CommonCanvasToolbar extends React.Component { config = this.getDefaultToolbar(); } - config = Object.assign({}, config, - { leftBar: this.optionallyAddPaletteTool(config.leftBar || []) }, - { rightBar: this.optionallyAddNotificationTool(config.rightBar || []) } - ); + config = this.optionallyAddPaletteTool(config); + config = this.optionallyAddNotificationTool(config); return config; } @@ -148,7 +152,10 @@ class CommonCanvasToolbar extends React.Component { this.props.canvasController.toolbarActionHandler(action); } - optionallyAddPaletteTool(leftBar) { + optionallyAddPaletteTool(config) { + const leftBar = config.leftBar || []; + const rightBar = config.rightBar || []; + let paletteLabel = this.getLabel("toolbar.palette"); // If the leftBar contains and old palette action and if followed by a @@ -163,57 +170,107 @@ class CommonCanvasToolbar extends React.Component { } } - // Add the new togglePalette icon if the palette is enabled. + // Add a new togglePalette icon if the palette is enabled and the app + // has not provided its own palette action. if (this.props.isPaletteEnabled) { // Applications may need to detect these legacy classes to detect which action // is to be performed. So add them as additional classes. Also, jest tests require them. - const className = this.props.isPaletteOpen ? "paletteClose-action" : "paletteOpen-action"; + // TODO - In next major release, remove "paletteClose-action" and "paletteOpen-action" + const className = this.props.isPaletteOpen ? "closePalette-action paletteClose-action" : "openPalette-action paletteOpen-action"; - const paletteOpenClose = + const togglePaletteAction = { action: TOOLBAR_TOGGLE_PALETTE, label: paletteLabel, enable: true, isSelected: this.props.isPaletteOpen, className }; - const paletteTools = [ - paletteOpenClose, - { divider: true } - ]; - return paletteTools.concat(newLeftBar); + const lbIdx = this.getToolIndexByAction(TOOLBAR_TOGGLE_PALETTE, leftBar); + const rbIdx = this.getToolIndexByAction(TOOLBAR_TOGGLE_PALETTE, rightBar); + + if (lbIdx > -1) { + const lbAction = leftBar[lbIdx]; + config.leftBar[lbIdx] = { + ...togglePaletteAction, + label: lbAction.label ? lbAction.label : paletteLabel, + iconEnabled: lbAction.iconEnabled ? lbAction.iconEnabled : null, // null means Icon provided by the toolbar + incLabelWithIcon: lbAction.incLabelWithIcon ? lbAction.incLabelWithIcon : null, + tooltip: lbAction.tooltip ? lbAction.tooltip : null + }; + + } else if (rbIdx > -1) { + const rbAction = rightBar[rbIdx]; + config.rightBar[rbIdx] = { + ...togglePaletteAction, + label: rbAction.label ? rbAction.label : paletteLabel, + iconEnabled: rbAction.iconEnabled ? rbAction.iconEnabled : null, // null means Icon provided by the toolbar + incLabelWithIcon: rbAction.incLabelWithIcon ? rbAction.incLabelWithIcon : null, + tooltip: rbAction.tooltip ? rbAction.tooltip : null + }; + + } else { + const paletteTools = [ + togglePaletteAction, + { divider: true } + ]; + config.leftBar = paletteTools.concat(newLeftBar); + } } - return newLeftBar; + return config; } - optionallyAddNotificationTool(rightBar) { + optionallyAddNotificationTool(config) { + const leftBar = config.leftBar || []; + const rightBar = config.rightBar || []; + + // Add a new toggleNotificationPanel icon if the notification panel exists + // and the app has not provided its own notification panel action. if (this.props.notificationConfigExists) { - const notificationTools = [ - { divider: true }, + const notificationCount = this.props.notificationMessages.length; + + const toggleNotificationAction = { action: TOOLBAR_TOGGLE_NOTIFICATION_PANEL, label: this.props.notificationConfigLabel, enable: this.props.notificationConfigEnable, extIsSubAreaDisplayed: this.props.isNotificationOpen, setExtIsSubAreaDisplayed: this.callExtIsSubAreaDisplayed.bind(this), className: this.getNotificationClassName(), - iconEnabled: this.props.notificationConfigIcon, - textContent: this.generateTextContent(), + textContent: (notificationCount > 9) ? "9+" : notificationCount.toString(), subPanel: NotificationPanel, subPanelData: { canvasController: this.props.canvasController }, leaveSubAreaOpenOnClickOutside: this.props.notificationConfigKeepOpen - } - ]; - return rightBar.concat(notificationTools); - } - return rightBar; - } - - // Returns a string to be displayed over the top of the default notification - // icon. The string shows the number of notification messages up to a maximum - // of nine. If the application provides its own icon in notificationConfigIcon, - // the 'text content' is not displayed so null is returned. - generateTextContent() { - if (this.props.notificationConfigIcon) { - return null; + }; + + const lbIdx = this.getToolIndexByAction(TOOLBAR_TOGGLE_NOTIFICATION_PANEL, leftBar); + const rbIdx = this.getToolIndexByAction(TOOLBAR_TOGGLE_NOTIFICATION_PANEL, rightBar); + + if (lbIdx > -1) { + const lbAction = leftBar[lbIdx]; + config.leftBar[lbIdx] = { + ...toggleNotificationAction, + iconEnabled: lbAction.iconEnabled ? lbAction.iconEnabled : null, // null means Icon provided by the toolbar + incLabelWithIcon: lbAction.incLabelWithIcon ? lbAction.incLabelWithIcon : null, + tooltip: lbAction.tooltip ? lbAction.tooltip : null, + textContent: null // Assume text conents is not needed with customized action + }; + + } else if (rbIdx > -1) { + const rbAction = rightBar[rbIdx]; + config.rightBar[rbIdx] = { + ...toggleNotificationAction, + iconEnabled: rbAction.iconEnabled ? rbAction.iconEnabled : null, // null means Icon provided by the toolbar + incLabelWithIcon: rbAction.incLabelWithIcon ? rbAction.incLabelWithIcon : null, + tooltip: rbAction.tooltip ? rbAction.tooltip : null, + textContent: null }; // Assume text conents is not needed with customized action + + + } else { + const notificationTools = [ + { divider: true }, + toggleNotificationAction + ]; + + config.rightBar = config.rightBar.concat(notificationTools); + } } - const notificationCount = this.props.notificationMessages.length; - return (notificationCount > 9) ? "9+" : notificationCount.toString(); + return config; } callExtIsSubAreaDisplayed(state) { @@ -335,7 +392,6 @@ CommonCanvasToolbar.propTypes = { notificationConfigExists: PropTypes.object, notificationConfigEnable: PropTypes.bool, notificationConfigLabel: PropTypes.string, - notificationConfigIcon: PropTypes.string, notificationConfigKeepOpen: PropTypes.bool, enableInternalObjectModel: PropTypes.bool, enableEditingActions: PropTypes.bool, @@ -360,7 +416,6 @@ const mapStateToProps = (state, ownProps) => ({ notificationConfigExists: state.notificationpanel?.config, notificationConfigEnable: state.notificationpanel?.config?.enable, notificationConfigLabel: state.notificationpanel?.config?.label, - notificationConfigIcon: state.notificationpanel?.config?.toolbarIcon, notificationConfigKeepOpen: state.notificationpanel?.config?.keepOpen, notificationMessages: state.notifications, enableInternalObjectModel: state.canvasconfig.enableInternalObjectModel, diff --git a/canvas_modules/common-canvas/src/common-canvas/constants/canvas-constants.js b/canvas_modules/common-canvas/src/common-canvas/constants/canvas-constants.js index 561319e751..621e2a4270 100644 --- a/canvas_modules/common-canvas/src/common-canvas/constants/canvas-constants.js +++ b/canvas_modules/common-canvas/src/common-canvas/constants/canvas-constants.js @@ -214,9 +214,9 @@ export const TOOLBAR_ZOOM_FIT = "zoomToFit"; export const TOOLBAR_ARRANGE_HORIZONALLY = "arrangeHorizontally"; export const TOOLBAR_ARRANGE_VERTICALLY = "arrangeVertically"; export const TOOLBAR_TOGGLE_NOTIFICATION_PANEL = "toggleNotificationPanel"; -export const TOOLBAR_OPEN_PALETTE = "paletteOpen"; -export const TOOLBAR_CLOSE_PALETTE = "paletteClose"; -export const TOOLBAR_TOGGLE_PALETTE = "paletteToggle"; +export const TOOLBAR_OPEN_PALETTE = "openPalette"; +export const TOOLBAR_CLOSE_PALETTE = "closePalette"; +export const TOOLBAR_TOGGLE_PALETTE = "togglePalette"; export const TOOLBAR_EXPAND_SUPERNODE_IN_PLACE = "expandSuperNodeInPlace"; export const TOOLBAR_COLLAPSE_SUPERNODE_IN_PLACE = "collapseSuperNodeInPlace"; export const TOOLBAR_EXPAND_SUPERNODE_FULL_PAGE = "displaySubPipeline"; diff --git a/canvas_modules/harness/cypress/e2e/canvas/toolbar.cy.js b/canvas_modules/harness/cypress/e2e/canvas/toolbar.cy.js index 36bffb0db6..0f486f9b53 100644 --- a/canvas_modules/harness/cypress/e2e/canvas/toolbar.cy.js +++ b/canvas_modules/harness/cypress/e2e/canvas/toolbar.cy.js @@ -305,6 +305,28 @@ describe("Test dual purpose toolbar button", function() { }); }); +describe("Test customized palette and notification panel buttons", function() { + beforeEach(() => { + cy.visit("/"); + cy.setCanvasConfig({ "selectedToolbarType": "CustomizeAutoItems" }); + }); + + it("Test clicking palette and notification panel buttons appear OK", function() { + + // Check the customized palette and notification panel buttons appear OK + cy.verifyToolbarButtonEnabled("togglePalette", true); + cy.verifyToolbarButtonEnabled("toggleNotificationPanel", true); + + // Click the customized palette button and make sure it opens the palette + cy.clickToolbarPaletteOpen(); + cy.verifyLeftPanelWidth(256); + + // Click the customized notification panel button and make sure it opens the notification panel + cy.clickToolbarNotifications(); + cy.verifyToolbarSubPanelIsOpen("toggleNotificationPanel"); + }); +}); + describe("Test overrideAutoEnableDisable toolbar config option", function() { beforeEach(() => { cy.visit("/"); diff --git a/canvas_modules/harness/cypress/support/canvas/verification-cmds.js b/canvas_modules/harness/cypress/support/canvas/verification-cmds.js index 724723ce26..29169a9089 100644 --- a/canvas_modules/harness/cypress/support/canvas/verification-cmds.js +++ b/canvas_modules/harness/cypress/support/canvas/verification-cmds.js @@ -875,6 +875,13 @@ Cypress.Commands.add("verifyTopPanelWidth", (width) => { }); }); +Cypress.Commands.add("verifyLeftPanelWidth", (width) => { + cy.get(".palette-flyout-div").should((element) => { + // Use compareCloseTo here because top-panel width is slighyly different + // on the build machine to its width when running tests on a local machine. + compareCloseTo(element[0].offsetWidth, width); + }); +}); Cypress.Commands.add("verifyCommentDimensions", (commentText, width, height) => { cy.getCommentWithText(commentText) diff --git a/canvas_modules/harness/src/client/App.js b/canvas_modules/harness/src/client/App.js index 2138c93ad7..64028abf6e 100644 --- a/canvas_modules/harness/src/client/App.js +++ b/canvas_modules/harness/src/client/App.js @@ -87,9 +87,9 @@ import BlankCanvasImage from "../../assets/images/blank_canvas.svg"; import AppSettingsPanel from "./app-x-settings-panel.jsx"; -import { Add, Api_1 as Api, Chat, ChatOff, ColorPalette, Download, Edit, FlowData, GuiManagement, +import { Add, AddAlt, SubtractAlt, Api_1 as Api, Chat, ChatOff, ColorPalette, Download, Edit, FlowData, GuiManagement, Help, OpenPanelFilledBottom, Play, Scale, Settings, SelectWindow, - StopFilledAlt, Subtract, TextScale, TouchInteraction } from "@carbon/react/icons"; + StopFilledAlt, Subtract, TextScale, TouchInteraction, Notification } from "@carbon/react/icons"; import { InlineLoading, Checkbox, Button, OverflowMenu, OverflowMenuItem, Toggle } from "@carbon/react"; @@ -126,6 +126,7 @@ import { TOOLBAR_TYPE_DEFAULT, TOOLBAR_TYPE_SUB_AREAS, TOOLBAR_TYPE_SINGLE_BAR, + TOOLBAR_TYPE_CUSTOMIZE_AUTO, TOOLBAR_TYPE_BEFORE_AFTER, TOOLBAR_TYPE_CUSTOM_RIGHT_SIDE, TOOLBAR_TYPE_CARBON_BUTTONS, @@ -311,7 +312,6 @@ class App extends React.Component { label: "Notifications", notificationHeader: "Notification Center", notificationSubtitle: "subtitle", - toolbarIcon: null, enable: true, emptyMessage: "You don't have any notifications right now.", clearAllMessage: "Clear all", @@ -325,7 +325,6 @@ class App extends React.Component { label: "Notifications", notificationHeader: "Notification Center Canvas 2", notificationSubtitle: "subtitle", - toolbarIcon: null, enable: true, emptyMessage: "You don't have any notifications right now.", clearAllMessage: "Clear all", @@ -2219,6 +2218,30 @@ class App extends React.Component { { divider: true } ]; + } else if (this.state.selectedToolbarType === TOOLBAR_TYPE_CUSTOMIZE_AUTO) { + toolbarConfig = [ + { action: "cut", label: "Cut" }, + { action: "copy", label: "Copy" }, + { action: "paste", label: "Paste" }, + { divider: true }, + { action: "undo", label: "Undo" }, + { action: "redo", label: "Redo" }, + { divider: true }, + { action: "togglePalette", + label: this.canvasController.isPaletteOpen() ? "Close Palette" : "Open Palette", + iconEnabled: this.canvasController.isPaletteOpen() ? () : (), + incLabelWithIcon: "after" + }, + { divider: true }, + { action: "toggleNotificationPanel", iconEnabled: () }, + { divider: true }, + { action: "deleteSelectedObjects", label: "Delete" }, + { divider: true }, + { action: "arrangeHorizontally", label: "Arrange Horizontally", enable: true }, + { action: "arrangeVertically", label: "Arrange Vertically", enable: true }, + { divider: true } + ]; + } else if (this.state.selectedToolbarType === TOOLBAR_TYPE_BEFORE_AFTER) { toolbarConfig = { leftBar: [ diff --git a/canvas_modules/harness/src/client/components/sidepanel/canvas/sidepanel-canvas.jsx b/canvas_modules/harness/src/client/components/sidepanel/canvas/sidepanel-canvas.jsx index 6de5162a19..92fff5b743 100644 --- a/canvas_modules/harness/src/client/components/sidepanel/canvas/sidepanel-canvas.jsx +++ b/canvas_modules/harness/src/client/components/sidepanel/canvas/sidepanel-canvas.jsx @@ -52,6 +52,7 @@ import { TIP_STATE_TAG, TOOLBAR_TYPE_DEFAULT, TOOLBAR_TYPE_SUB_AREAS, + TOOLBAR_TYPE_CUSTOMIZE_AUTO, TOOLBAR_TYPE_SINGLE_BAR, TOOLBAR_TYPE_BEFORE_AFTER, TOOLBAR_TYPE_CUSTOM_RIGHT_SIDE, @@ -103,8 +104,6 @@ import { TOOLBAR_LAYOUT_TOP } from "@elyra/canvas/src/common-canvas/constants/canvas-constants.js"; -import { Notification } from "@carbon/react/icons"; - import FormsService from "../../../services/FormsService"; export default class SidePanelForms extends React.Component { @@ -1402,6 +1401,10 @@ export default class SidePanelForms extends React.Component { value={TOOLBAR_TYPE_SUB_AREAS} labelText={TOOLBAR_TYPE_SUB_AREAS} /> + this.notificationConfigToggle("notificationConfig", "secondaryButtonDisabled", val)} /> - (val - ? this.notificationConfigToggle("notificationConfig", "toolbarIcon", ()) - : this.notificationConfigToggle("notificationConfig", "toolbarIcon", null)) - } - /> ); var configureNotificationCenter2 = (
diff --git a/canvas_modules/harness/src/client/constants/harness-constants.js b/canvas_modules/harness/src/client/constants/harness-constants.js index a3eae1a8a6..5545c33e38 100644 --- a/canvas_modules/harness/src/client/constants/harness-constants.js +++ b/canvas_modules/harness/src/client/constants/harness-constants.js @@ -58,6 +58,7 @@ _defineConstant("EDITING", "Editing"); _defineConstant("TOOLBAR_TYPE_DEFAULT", "Default"); _defineConstant("TOOLBAR_TYPE_SUB_AREAS", "SubAreas"); _defineConstant("TOOLBAR_TYPE_SINGLE_BAR", "SingleLeftBarArray"); +_defineConstant("TOOLBAR_TYPE_CUSTOMIZE_AUTO", "CustomizeAutoItems"); _defineConstant("TOOLBAR_TYPE_BEFORE_AFTER", "TextBeforeAndAfter"); _defineConstant("TOOLBAR_TYPE_CUSTOM_RIGHT_SIDE", "CustomizedRightSide"); _defineConstant("TOOLBAR_TYPE_CARBON_BUTTONS", "CarbonButtons"); diff --git a/docs/pages/03.02.02-toolbar-config.md b/docs/pages/03.02.02-toolbar-config.md index 42c3f46cb8..12954b6c2d 100644 --- a/docs/pages/03.02.02-toolbar-config.md +++ b/docs/pages/03.02.02-toolbar-config.md @@ -53,12 +53,7 @@ Where: * **overrideAutoEnableDisable** - a boolean. The default is false. By default Common Canvas has an auto-enablement feature that controls the enablement of common tools in the toolbar based on user actions (e.g enable the `Delete` icon when items are selected). If `overrideAutoEnableDisable` set to true it will switch off the auto-enablement feature. This is useful if the host application wants to disable all the nodes under certain circumstances. If set to true, the `enable` property in the action items for each tool is used to decide whether to display the icon as enabled or disabled. If set to false or omitted, Common Canvas will handle the auto-enablement of common actions. (See the `action`section below for more details.) -Two toolbar items are automatically added to the toolbar: - -- A palette action which is used for opening and closing the [palette](01.02-palette.md). This is added to the left side of the toolbar if the [`enablePaletteLayout`](03.02.01-canvas-config.md#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. -- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](03.02.01-canvas-config.md#notification-config-object) object is specified to the `` react object. - -The toolbar will display the objects in the same order they are defined in the arrays. +The toolbar will display the objects in the same order they are defined in the leftBar and rightBar arrays. ### Toolbar action object definition @@ -142,6 +137,38 @@ Here is an example of an action object which must contain a unique `action` fiel * **textContent** - This is an additional string that will be displayed on top of the action button. It can be used to specify adittional information to enahance the icon. For example, a count of messages could be displayed over a icon that, when clicked, shows a messages panel. +### Automatic toolbar items + +Two toolbar items are automatically added to the toolbar: + +- A palette action which is used for opening and closing the [palette](01.02-palette.md). This is added to the left side of the toolbar if the [`enablePaletteLayout`](03.02.01-canvas-config.md#enablepalettelayout) field is set to either "Flyout" (the default) or "Modal" in the canvas configuration. +- A notification panel action which is used to open and close the notifications panel. This will be added to the right side of the toolbar if a [notification configuration](03.02.01-canvas-config.md#notification-config-object) object is specified to the `` react object. + +The position and a subset of fields for these items can be customized by providing an appropriate object in either the leftBar or rightBar arrays. The `action` field for the items should be either "togglePalette" or "toggleNotificationPanel". Any of the following fields can be optionally provided to override the default values: label, iconEnabled, incLabelWithIcon and tooltip. + + For example, if the application provides the following in, say, the leftBar array: + ``` + import { AddAlt, SubtractAlt, Notification } from "@carbon/react/icons"; + ... + + const toolbarConfig = { + leftBar: [ + ... + { action: "togglePalette", + label: this.canvasController.isPaletteOpen() ? "Close Palette" : "Open Palette", + iconEnabled: this.canvasController.isPaletteOpen() ? () : (), + incLabelWithIcon: "after" }, + { divider: true }, + { action: "toggleNotificationPanel", iconEnabled: () }, + ... + ] + }; + ``` + + Will look like this: + + + #### Sub-area properties The toolbar button can show a 'sub-area' below the button when the button is clicked. This can be either a [sub-menu](01.05-toolbar.md/#sub-menu) which is a list of text options or a [sub-panel](01.05-toolbar.md/#sub-panel) which is a small window that can show whatever the application wants such as settings or messages. diff --git a/docs/pages/03.02.03-notification-config.md b/docs/pages/03.02.03-notification-config.md index 7752919bc7..4d4dcc2d74 100644 --- a/docs/pages/03.02.03-notification-config.md +++ b/docs/pages/03.02.03-notification-config.md @@ -15,7 +15,6 @@ The Notification Config object looks like this: notificationSubtitle: "subtitle", emptyMessage: "You don't have any notifications right now.", clearAllMessage: "Clear all", - toolbarIcon: null, keepOpen: true, clearAllCallback: () => { console.log("Clear All clicked"); } }; @@ -35,8 +34,6 @@ The Notification Config object looks like this: * **clearAllMessage** - String to be displayed on a button displayed at the bottom of the panel. The button can be clicked to clear all the messages from the panel. If omitted the button, and the footer area of the panel it appears in, will not be displayed. -* **toolbarIcon** - Either null or JSX. This specifies what icon should be shown in the toolbar button that opens the notification panel. The default is null which indicates that the default icon should be displayed. If JSX is provided, it should contain the icon to be displayed. For example, if `)` is specified, where `Notification` is imported from `"@carbon/react/icons"`, the Bell icon will be shown in the toolbar in place of the default. - * **keepOpen** - A boolean which indicates when the panel will close. The default is false. If set to false, the panel will close when the user clicks on the page somewhere outside the panel. If set to true the panel will remain open when the user clicks somewhere on the page outside of the panel. With the option the user must click the `x` icon in the top right of the panel, or click the notification toolbar icon, to close the panel. * **clearAllCallback** - An optional callback function that will be called every time the "clear all" button is clicked. diff --git a/docs/pages/assets/cc-toolbar-auto-customize.png b/docs/pages/assets/cc-toolbar-auto-customize.png new file mode 100644 index 0000000000..018b1db253 Binary files /dev/null and b/docs/pages/assets/cc-toolbar-auto-customize.png differ