From 96a7abbaec8905b6b48a444cbc035e510ef09ec4 Mon Sep 17 00:00:00 2001 From: CTomlyn Date: Wed, 25 Sep 2024 07:42:43 -0700 Subject: [PATCH] #2176 Add button to node palette (#2177) Signed-off-by: CTomlyn --- .../__tests__/palette/palette-flyout-test.js | 15 ++++++++++++++ .../src/object-model/config-utils.js | 1 + .../src/palette/palette-flyout-content.jsx | 6 ++++++ .../src/palette/palette-flyout.jsx | 2 ++ .../common-canvas/src/palette/palette.jsx | 3 +++ .../common-canvas/src/palette/palette.scss | 20 +++++++++++++------ canvas_modules/harness/src/client/App.js | 12 +++++++++++ .../sidepanel/canvas/sidepanel-canvas.jsx | 11 ++++++++++ docs/pages/01.02-palette.md | 1 + docs/pages/03.02.01-canvas-config.md | 3 +++ 10 files changed, 68 insertions(+), 6 deletions(-) diff --git a/canvas_modules/common-canvas/__tests__/palette/palette-flyout-test.js b/canvas_modules/common-canvas/__tests__/palette/palette-flyout-test.js index 512c8d1223..68ef06926b 100644 --- a/canvas_modules/common-canvas/__tests__/palette/palette-flyout-test.js +++ b/canvas_modules/common-canvas/__tests__/palette/palette-flyout-test.js @@ -369,12 +369,26 @@ describe("Palette renders correctly", () => { const category2 = findCategoryElement(container, "category-image"); expect(category2.querySelectorAll("img")).to.have.length(1); }); + + + it("should display a header area when one is specified in the config", async() => { + const config = { + showPalette: true, + palette: testPalette3NoDesc, + paletteHeader: (
Test text
) + }; + const { container } = createMountedPalette(config); + + expect(container.getElementsByClassName("test-header")).to.have.length(1); + + }); }); function createMountedPalette(config) { const canvasController = (config && config.canvasController) ? config.canvasController : new CanvasController(); const palette = (config && config.palette) ? config.palette : testPalette2; const isEditingEnabled = (config && config.isEditingEnabled) ? config.isEditingEnabled : true; + const paletteHeader = (config && config.paletteHeader) ? config.paletteHeader : null; canvasController.setPipelineFlowPalette(palette); @@ -383,6 +397,7 @@ function createMountedPalette(config) { paletteJSON={palette} canvasController={canvasController} isEditingEnabled={isEditingEnabled} + paletteHeader={paletteHeader} isPaletteWide /> ); diff --git a/canvas_modules/common-canvas/src/object-model/config-utils.js b/canvas_modules/common-canvas/src/object-model/config-utils.js index 87ec8e0ab8..208ddd201c 100644 --- a/canvas_modules/common-canvas/src/object-model/config-utils.js +++ b/canvas_modules/common-canvas/src/object-model/config-utils.js @@ -69,6 +69,7 @@ export default class ConfigUtils { enableDragWithoutSelect: false, enableInternalObjectModel: true, enablePaletteLayout: PALETTE_LAYOUT_FLYOUT, + enablePaletteHeader: null, enableToolbarLayout: "Top", enableImageDisplay: "SVGInline", enableResizableNodes: false, diff --git a/canvas_modules/common-canvas/src/palette/palette-flyout-content.jsx b/canvas_modules/common-canvas/src/palette/palette-flyout-content.jsx index 5774bf6ba7..c7c7be4b7a 100644 --- a/canvas_modules/common-canvas/src/palette/palette-flyout-content.jsx +++ b/canvas_modules/common-canvas/src/palette/palette-flyout-content.jsx @@ -141,9 +141,14 @@ class PaletteFlyoutContent extends React.Component { /> ); + const paletteHeader = this.props.paletteHeader && !this.state.searchString && this.props.isPaletteWide + ? this.props.paletteHeader + : null; + return (
{contentSearch} + {paletteHeader} {contentCategories}
); @@ -153,6 +158,7 @@ class PaletteFlyoutContent extends React.Component { PaletteFlyoutContent.propTypes = { canvasController: PropTypes.object.isRequired, paletteJSON: PropTypes.object.isRequired, + paletteHeader: PropTypes.object, isEditingEnabled: PropTypes.bool.isRequired, isPaletteWide: PropTypes.bool }; diff --git a/canvas_modules/common-canvas/src/palette/palette-flyout.jsx b/canvas_modules/common-canvas/src/palette/palette-flyout.jsx index e53b4231c2..92cdaecbcc 100644 --- a/canvas_modules/common-canvas/src/palette/palette-flyout.jsx +++ b/canvas_modules/common-canvas/src/palette/palette-flyout.jsx @@ -44,6 +44,7 @@ class PaletteFlyout extends React.Component { @@ -57,6 +58,7 @@ PaletteFlyout.propTypes = { intl: PropTypes.object.isRequired, canvasController: PropTypes.object.isRequired, paletteJSON: PropTypes.object.isRequired, + paletteHeader: PropTypes.object, isEditingEnabled: PropTypes.bool.isRequired, isPaletteWide: PropTypes.bool }; diff --git a/canvas_modules/common-canvas/src/palette/palette.jsx b/canvas_modules/common-canvas/src/palette/palette.jsx index 41dae85be9..8adc5eb750 100644 --- a/canvas_modules/common-canvas/src/palette/palette.jsx +++ b/canvas_modules/common-canvas/src/palette/palette.jsx @@ -37,6 +37,7 @@ class Palette extends React.Component { @@ -50,6 +51,7 @@ Palette.propTypes = { // Provided by redux paletteJSON: PropTypes.object, + paletteHeader: PropTypes.object, isEditingEnabled: PropTypes.bool, isPaletteWide: PropTypes.bool }; @@ -57,6 +59,7 @@ Palette.propTypes = { const mapStateToProps = (state, ownProps) => ({ paletteJSON: state.palette.content, isEditingEnabled: state.canvasconfig.enableEditingActions, + paletteHeader: state.canvasconfig.enablePaletteHeader, isPaletteWide: state.canvasconfig.enablePaletteLayout === PALETTE_LAYOUT_NONE || (state.canvasconfig.enablePaletteLayout === PALETTE_LAYOUT_FLYOUT && state.palette.isOpen) diff --git a/canvas_modules/common-canvas/src/palette/palette.scss b/canvas_modules/common-canvas/src/palette/palette.scss index 1baff9f799..c6012352af 100644 --- a/canvas_modules/common-canvas/src/palette/palette.scss +++ b/canvas_modules/common-canvas/src/palette/palette.scss @@ -38,18 +38,26 @@ $palette-search-container-height: 41px; .palette-flyout-div-open { width: 256px; + + .palette-flyout-content { + grid-template-columns: 256px; + } } .palette-flyout-div-narrow { width: 72px; -} -.palette-nav { - height: 100%; + .palette-flyout-content { + grid-template-columns: 72px; + } } .palette-flyout-content { - height: calc(100% - $palette-search-container-height); + position: absolute; // Needed to allow the scroll of categories/nodes to work. + height: 100%; + display: grid; + grid-template-rows: $palette-search-container-height auto 1fr; + // grid-template-columns is set based on narrow or open palette .palette-scroll { overflow-y: hidden; /*prevents multiple scroll bars in flyout*/ @@ -190,8 +198,6 @@ $palette-search-container-height: 41px; .palette-flyout-categories { overflow-x: hidden; overflow-y: auto; - min-height:100%; - height:0; li .cds--accordion__arrow { margin: 15px; @@ -297,6 +303,8 @@ $palette-search-container-height: 41px; .palette-flyout-search-container { height: $palette-search-container-height; + width: calc(100% - 1px); + .palette-flyout-search { height: 100%; overflow: hidden; diff --git a/canvas_modules/harness/src/client/App.js b/canvas_modules/harness/src/client/App.js index 64028abf6e..c004e50911 100644 --- a/canvas_modules/harness/src/client/App.js +++ b/canvas_modules/harness/src/client/App.js @@ -214,6 +214,7 @@ class App extends React.Component { selectedCanvasUnderlay: UNDERLAY_NONE, selectedExampleApp: EXAMPLE_APP_NONE, selectedPaletteLayout: PALETTE_LAYOUT_FLYOUT, + selectedPaletteHeader: false, selectedStateTag: STATE_TAG_NONE, selectedTipConfig: { "palette": { @@ -463,6 +464,16 @@ class App extends React.Component { this.locale = "en"; this.initLocale(); + // Sample palette header object for display below the Search bar and above + // the scrollable area for categories and nodes. + this.paletteHeader = ( +
+ +
+ ); + // Create the empty canvas div so we don't create a new object on each render // which would cause a refresh. this.emptyCanvasDiv = ( @@ -2078,6 +2089,7 @@ class App extends React.Component { enableWYSIWYGComments: this.state.selectedWYSIWYGComments, enableContextToolbar: this.state.selectedContextToolbar, enablePaletteLayout: this.state.selectedPaletteLayout, + enablePaletteHeader: this.state.selectedPaletteHeader ? this.paletteHeader : null, enableStateTag: this.state.selectedStateTag, enableToolbarLayout: this.state.selectedToolbarLayout, enableResizableNodes: this.state.selectedResizableNodes, 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 92fff5b743..6fe322aacd 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 @@ -718,6 +718,15 @@ export default class SidePanelForms extends React.Component { /> ); + var enablePaletteHeader = (
+ this.setStateValue(val, "selectedPaletteHeader")} + /> +
); + var enableAutoLinkOnlyFromSelNodes = (
Nodes
diff --git a/docs/pages/01.02-palette.md b/docs/pages/01.02-palette.md index 15d66f6066..317ec6d5d3 100644 --- a/docs/pages/01.02-palette.md +++ b/docs/pages/01.02-palette.md @@ -27,6 +27,7 @@ There are a number of configuration options that control the palette that are sp * [enablePaletteLayout](03.02.01-canvas-config.md#enablepalettelayout) * [enableNarrowPalette](03.02.01-canvas-config.md#enablenarrowpalette) * [enableAutoLinkOnlyFromSelNodes](03.02.01-canvas-config.md#enableautolinkonlyfromselnodes) +* [enablePaletteHeader](03.02.01-canvas-config.md#enablepaletteheader) ## Palette operation diff --git a/docs/pages/03.02.01-canvas-config.md b/docs/pages/03.02.01-canvas-config.md index a4b8e27795..f44f67983e 100644 --- a/docs/pages/03.02.01-canvas-config.md +++ b/docs/pages/03.02.01-canvas-config.md @@ -187,6 +187,9 @@ This can be: "Modal" or "Flyout" or "None". The default is "Flyout". "Flyout" di #### **enableAutoLinkOnlyFromSelNodes** This is a boolean. The default is false. When set to true the auto-add function (where double clicking a node in the palette automatically adds it to the canvas) will only link up nodes when a node is already selected on the canvas and then, only if the selected node can be linked to the node that was double clicked. If false, the auto-add function will make a best guess at which node the double-clicked node should be added to. +#### **enablePaletteHeader** +This is a JSX object that will displayed in an open, wide palette. It is positioned below the Seach bar and above the categories and nodes. The default is null, which means nothing will be displayed. This option can be used by the application to add application specific function into the palette, for example, a button could be added. + #### **enableNarrowPalette** This is a boolean. true is the default. If true when the palette is closed the narrow palette will be shown. When false the palette completely closes.