diff --git a/packages/react/src/components/Table/StatefulTable.test.jsx b/packages/react/src/components/Table/StatefulTable.test.jsx
index f134ae5be1..d5cc41c749 100644
--- a/packages/react/src/components/Table/StatefulTable.test.jsx
+++ b/packages/react/src/components/Table/StatefulTable.test.jsx
@@ -4,9 +4,11 @@ import { merge, pick, cloneDeep } from 'lodash-es';
import { screen, render, fireEvent, act, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Screen16, ViewOff16 } from '@carbon/icons-react';
+import { BreadcrumbItem } from 'carbon-components-react';
import { settings } from '../../constants/Settings';
import { EMPTY_STRING_DISPLAY_VALUE } from '../../constants/Filters';
+import Breadcrumb from '../Breadcrumb/Breadcrumb';
import * as reducer from './baseTableReducer';
import StatefulTable from './StatefulTable';
@@ -218,6 +220,135 @@ describe('stateful table with real reducer', () => {
// Make sure we started the drags
expect(handleDrag).toHaveBeenCalledTimes(3);
});
+
+ it('does drop over breadcrumb node', () => {
+ // Reduce screen size to show overflow menu inside the breadcrumb
+ Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
+ writable: true,
+ configurable: true,
+ value: 400,
+ });
+ Object.defineProperty(HTMLElement.prototype, 'scrollWidth', {
+ writable: true,
+ configurable: true,
+ value: 500,
+ });
+
+ const data = [
+ {
+ id: '0',
+ values: {
+ string: 'row 0',
+ },
+ isDraggable: true,
+ },
+ {
+ id: '1',
+ values: {
+ string: 'row 1',
+ },
+ isDraggable: true,
+ },
+ ];
+
+ const handleDrag = jest.fn();
+ let lastDroppedOnNode;
+
+ const { container } = render(
+ <>
+
+
+
+ Folder with very long name is created for example
+
+
+ 2 Devices
+
+
+ A really long folder name
+
+
+ 4 Another folder
+
+
+ 5th level folder
+
+
+
+
+ >
+ );
+
+ const breadcrumbNodes = container.querySelectorAll(`.${prefix}--breadcrumb-item`);
+ // will return 3 as screen size is reduced
+ expect(breadcrumbNodes.length).toBe(3);
+
+ const dragHandles = container.querySelectorAll(`.${iotPrefix}--table-drag-handle`);
+ expect(dragHandles.length).toBe(2);
+
+ // mimicks drop over breadcrumb node
+ fireEvent.mouseDown(dragHandles[0]);
+ fireEvent.mouseMove(dragHandles[0], { buttons: 1, clientX: 0, clientY: 0 });
+ fireEvent.mouseMove(breadcrumbNodes[0], { buttons: 1, clientX: 100, clientY: 100 });
+ fireEvent.mouseEnter(breadcrumbNodes[0]);
+ fireEvent.mouseUp(breadcrumbNodes[0]);
+
+ expect(lastDroppedOnNode).toEqual(breadcrumbNodes[0]);
+ expect(lastDroppedOnNode.title).toEqual('Folder with very long name is created for example');
+
+ // mimicks hover over breadcrumb node but won't drop
+ fireEvent.mouseDown(dragHandles[0]);
+ fireEvent.mouseMove(dragHandles[0], { buttons: 1, clientX: 0, clientY: 0 });
+ fireEvent.mouseMove(breadcrumbNodes[0], { clientX: 100, clientY: 100 });
+ fireEvent.mouseEnter(breadcrumbNodes[0]);
+ fireEvent.mouseLeave(breadcrumbNodes[0]);
+ // Added to avoid warning of wrraping in act() in case of state change due to mouse events
+ fireEvent.keyDown(container, { key: 'a' }); // this is ignored, but needed for code coverage
+ fireEvent.keyDown(container, { key: 'Escape' });
+
+ const ellipsisNode = container.querySelectorAll(`.${prefix}--overflow-menu`);
+
+ userEvent.click(ellipsisNode[0]);
+ const overflowMenuNode = screen.getByText('A really long folder name').closest('li');
+
+ // mimicks drop over breadcrumb node inside overflow menu
+ fireEvent.mouseDown(dragHandles[0]);
+ fireEvent.mouseMove(dragHandles[0], { buttons: 1, clientX: 0, clientY: 0 });
+ fireEvent.mouseMove(overflowMenuNode, { clientX: 100, clientY: 100 });
+ fireEvent.mouseEnter(overflowMenuNode);
+ fireEvent.mouseUp(overflowMenuNode);
+
+ expect(lastDroppedOnNode).toEqual(overflowMenuNode);
+
+ // mimicks hover over breadcrumb node inside overflow menu but won't drop
+ fireEvent.mouseDown(dragHandles[0]);
+ fireEvent.mouseMove(dragHandles[0], { buttons: 1, clientX: 0, clientY: 0 });
+ fireEvent.mouseMove(overflowMenuNode, { clientX: 100, clientY: 100 });
+ fireEvent.mouseEnter(overflowMenuNode);
+ fireEvent.mouseLeave(overflowMenuNode);
+
+ delete HTMLElement.prototype.clientWidth;
+ delete HTMLElement.prototype.scrollWidth;
+ });
});
it('should clear filters', async () => {
diff --git a/packages/react/src/components/Table/Table.jsx b/packages/react/src/components/Table/Table.jsx
index fcfc125648..89a41fddef 100644
--- a/packages/react/src/components/Table/Table.jsx
+++ b/packages/react/src/components/Table/Table.jsx
@@ -164,6 +164,8 @@ const propTypes = {
* `actions.table.onDrag` and `actions.table.onDrop` callback props.
*/
hasDragAndDrop: PropTypes.bool,
+ /** Making this true in addition to hasDragAndDrop will consider breadcrumb nodes as drop targets */
+ hasBreadcrumbDrop: PropTypes.bool,
/** Freezes table header and footer */
pinHeaderAndFooter: PropTypes.bool,
}),
@@ -448,6 +450,7 @@ export const defaultProps = (baseProps) => ({
hasFilterRowIcon: false,
pinColumn: PIN_COLUMN.NONE,
hasDragAndDrop: false,
+ hasBreadcrumbDrop: false,
pinHeaderAndFooter: false,
},
size: undefined,
@@ -1205,7 +1208,8 @@ const Table = (props) => {
'shouldLazyRender',
'preserveCellWhiteSpace',
'useRadioButtonSingleSelect',
- 'hasDragAndDrop'
+ 'hasDragAndDrop',
+ 'hasBreadcrumbDrop'
)}
hideDragHandles={hideDragHandles}
hasRowExpansion={!!options.hasRowExpansion}
diff --git a/packages/react/src/components/Table/Table.main.story.jsx b/packages/react/src/components/Table/Table.main.story.jsx
index 211d313e9e..7c713fd284 100644
--- a/packages/react/src/components/Table/Table.main.story.jsx
+++ b/packages/react/src/components/Table/Table.main.story.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import { action } from '@storybook/addon-actions';
import { object, select, boolean, text, number } from '@storybook/addon-knobs';
import { cloneDeep, debounce, merge, uniqueId } from 'lodash-es';
-import { ToastNotification } from 'carbon-components-react';
+import { ToastNotification, BreadcrumbItem } from 'carbon-components-react';
import { SettingsAdjust16 } from '@carbon/icons-react';
import StoryNotice from '../../internal/StoryNotice';
@@ -12,6 +12,7 @@ import RuleBuilder from '../RuleBuilder/RuleBuilder';
import useStoryState from '../../internal/storyState';
import FlyoutMenu, { FlyoutMenuDirection } from '../FlyoutMenu/FlyoutMenu';
import { csvDownloadHandler } from '../../utils/componentUtilityFunctions';
+import Breadcrumb from '../Breadcrumb/Breadcrumb';
import TableREADME from './mdx/Table.mdx';
import SortingREADME from './mdx/Sorting.mdx';
@@ -520,6 +521,11 @@ function NaiveMultiRowDragPreview({ rows }) {
}
export function WithDragAndDrop() {
+ const { hasBreadcrumbDrop } = getTableKnobs({
+ knobsToCreate: ['hasBreadcrumbDrop'],
+ getDefaultValue: () => true,
+ });
+
const columns = [
{
id: 'type',
@@ -579,12 +585,32 @@ export function WithDragAndDrop() {
+
+
+
+ Folder with very long name is created for example
+
+
+ 2 Devices
+
+
+ A really long folder name
+
+
+ 4 Another folder
+
+
+ 5th level folder
+
+
+
,
};
},
- onDrop: (dragRowIds, dropRowId) => {
- action('onDrop')(dragRowIds, dropRowId);
-
+ onDrop: (dragRowIds, dropRowIdOrNode) => {
+ action('onDrop')(dragRowIds, dropRowIdOrNode);
const newData = data.filter((row) => !dragRowIds.includes(row.id));
- const folderRow = newData.find((row) => dropRowId === row.id);
- folderRow.values.count += dragRowIds.length;
- folderRow.values.name = `${folderRow.values.string} (${folderRow.values.count} inside)`;
+ if (typeof dropRowIdOrNode === 'string') {
+ const folderRow = newData.find((row) => dropRowIdOrNode === row.id);
+ folderRow.values.count += dragRowIds.length;
+ folderRow.values.name = `${folderRow.values.string} (${folderRow.values.count} inside)`;
+ } else if (
+ dropRowIdOrNode instanceof Element ||
+ (dropRowIdOrNode && dropRowIdOrNode.nodeType === Node.ELEMENT_NODE)
+ ) {
+ const name =
+ dropRowIdOrNode.title && dropRowIdOrNode.title !== ''
+ ? dropRowIdOrNode.title
+ : dropRowIdOrNode.innerText;
+ console.info(`>>> Dropped ${dragRowIds} onto breadcrumb node ${name}`);
+ }
setData(newData);
},
},
diff --git a/packages/react/src/components/Table/Table.story.helpers.jsx b/packages/react/src/components/Table/Table.story.helpers.jsx
index 328ba7c766..dbe1032b84 100644
--- a/packages/react/src/components/Table/Table.story.helpers.jsx
+++ b/packages/react/src/components/Table/Table.story.helpers.jsx
@@ -1667,6 +1667,13 @@ export const getTableKnobs = ({ knobsToCreate, getDefaultValue, useGroups = fals
hasDragAndDrop: shouldCreate('hasDragAndDrop')
? boolean('Drag and drop (hasDragAndDrop)', getDefaultValue('hasDragAndDrop'), DND_GROUP)
: null,
+ hasBreadcrumbDrop: shouldCreate('hasBreadcrumbDrop')
+ ? boolean(
+ 'Enable drop over breadcrumb (hasBreadcrumbDrop)',
+ getDefaultValue('hasBreadcrumbDrop'),
+ DND_GROUP
+ )
+ : null,
};
};
diff --git a/packages/react/src/components/Table/TableBody/TableBody.jsx b/packages/react/src/components/Table/TableBody/TableBody.jsx
index 1a421cc0c6..ae15ca81ba 100644
--- a/packages/react/src/components/Table/TableBody/TableBody.jsx
+++ b/packages/react/src/components/Table/TableBody/TableBody.jsx
@@ -106,6 +106,8 @@ const propTypes = {
size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
/** If room is reserved for drag handles at the start of rows. */
hasDragAndDrop: PropTypes.bool,
+ /** If true will pass it to DnD component so that breadcrumb items are considered as drop targets. */
+ hasBreadcrumbDrop: PropTypes.bool,
/** If all drag handles should be hidden. This happens when an undraggable row is in the selection. */
hideDragHandles: PropTypes.bool,
/** Optional base z-index for the drag image. See details on Table component. */
@@ -148,6 +150,7 @@ const defaultProps = {
actionFailedText: 'Action failed',
size: undefined,
hasDragAndDrop: false,
+ hasBreadcrumbDrop: false,
hideDragHandles: false,
zIndex: 0,
pinColumn: PIN_COLUMN.NONE,
@@ -194,6 +197,7 @@ const TableBody = ({
preserveCellWhiteSpace,
size,
hasDragAndDrop,
+ hasBreadcrumbDrop,
hideDragHandles,
zIndex,
pinColumn,
@@ -288,7 +292,7 @@ const TableBody = ({
handleStartPossibleDrag,
handleEnterRow,
handleLeaveRow,
- } = useTableDnd(rows, selectedIds, zIndex, actions.onDrag, actions.onDrop);
+ } = useTableDnd(rows, selectedIds, zIndex, actions.onDrag, actions.onDrop, hasBreadcrumbDrop);
const tableBodyClassNames = classnames(
pinColumnClassNames({ pinColumn, hasRowSelection, hasRowExpansion, hasRowNesting })
diff --git a/packages/react/src/components/Table/TableBody/_table-dnd.scss b/packages/react/src/components/Table/TableBody/_table-dnd.scss
index ba3ae25508..df85120f89 100644
--- a/packages/react/src/components/Table/TableBody/_table-dnd.scss
+++ b/packages/react/src/components/Table/TableBody/_table-dnd.scss
@@ -90,3 +90,21 @@ body.#{$iot-prefix}--is-dragging {
transition: none;
}
}
+
+// Additional styles for overlay in case of breadcrumb nodes to change the background color and show
+// border when drop is happening
+.#{$iot-prefix}--breadcrumb-drop-node-overlay {
+ background-color: $carbon--blue-10;
+ border: dashed 2px $carbon--blue-60;
+}
+
+// To hide default underline during drop which is shown on link hover of breadcrumb node
+.#{$prefix}--row--on--link--dropping {
+ text-decoration: none !important;
+}
+
+// Added to overflow menu for items which are shown in menu when breadcrumb length too big
+.#{$prefix}--breadcrumbmenu--on--row--dropping {
+ background-color: $carbon--blue-10 !important;
+ outline: dashed 2px $carbon--blue-60 !important;
+}
diff --git a/packages/react/src/components/Table/TableBody/useTableDnd.jsx b/packages/react/src/components/Table/TableBody/useTableDnd.jsx
index 41a0c83a1c..d5c9e4b609 100644
--- a/packages/react/src/components/Table/TableBody/useTableDnd.jsx
+++ b/packages/react/src/components/Table/TableBody/useTableDnd.jsx
@@ -91,7 +91,7 @@ function getRtlVerticalScrollbarWidth() {
* rows being dragged and the ID of the row being dropped on.
* @returns {UseTableDndResult} Values to mix into the table.
*/
-function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
+function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop, hasBreadcrumbDrop) {
// These are related. When the user "mousedown"s on a drag handle, we consider it a "possible"
// drag. At this point we add all the event listeners to track the drag. Put only after they move
// past some threshold do we actually set `isDragging`. At that point the drag is "real" and we'll
@@ -252,6 +252,9 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
[]
);
+ /** Ref to the root DOM element of the row overlay. Used to directly update its style. */
+ const overlayRef = useRef(null);
+
useEffect(
/**
* Once a drag appears to start (user "mousedown"s on a drag handle) this adds the needed event
@@ -283,6 +286,159 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
}
}
+ /**
+ * Callback when item drag mouse enters li of overflow menu
+ * @param {React.MouseEvent} e
+ */
+ function handleOverflowLiEnter(e) {
+ const node = e.currentTarget;
+ const hyperLink = node.querySelector(`.${prefix}--overflow-menu-options__btn`);
+ hyperLink.classList.add(`${prefix}--breadcrumbmenu--on--row--dropping`);
+ activeDropRowIdRef.current = node;
+ }
+
+ /**
+ * Callback when item drag mouse leaves li of overflow menu
+ * @param {React.MouseEvent} e
+ */
+ function handleOverflowLiLeave(e) {
+ const node = e.currentTarget;
+ if (activeDropRowIdRef.current === node) {
+ activeDropRowIdRef.current = null;
+ }
+ const hyperLink = node.querySelector(`.${prefix}--overflow-menu-options__btn`);
+ if (hyperLink) hyperLink.classList.remove(`${prefix}--breadcrumbmenu--on--row--dropping`);
+ }
+
+ /**
+ * Callback when the mouse enters a table row. The table needs to add this as an onmouseenter
+ * handler.
+ * @param {React.MouseEvent} e
+ * @returns
+ */
+ function handleEnterNode(e) {
+ /* istanbul ignore if */
+ if (!isPossibleDrag) {
+ // shouldn't happen
+ return;
+ }
+ const node = e.currentTarget;
+ // To have breadcrumb leaf node as disabled by specfying isCurrentPage prop which adds the below class
+ // and for the same page drop shouldn't be allowed hence the below condition
+ if (!node.classList.contains(`${prefix}--breadcrumb-item--current`)) {
+ const link = node.querySelector(`.${prefix}--link`);
+ const linkRect = link.getBoundingClientRect();
+ // There is another way to have breadcrumb leaf node as disabled by not setting the href,
+ // in any case it should be a enabled hyperlink to consider as drop target
+ // istanbul ignore else
+ if (link.nodeType === Node.ELEMENT_NODE && link.tagName.toLowerCase() === 'a') {
+ const verticalPadding = 5;
+ const horizontalPadding = 4;
+ const style = {
+ display: 'block',
+ top: `${linkRect.top - verticalPadding}px`,
+ left: `${linkRect.left - horizontalPadding}px`,
+ height: `${linkRect.height + 2 * verticalPadding}px`,
+ width: `${linkRect.width + 2 * horizontalPadding}px`,
+ zIndex: -1,
+ };
+ // istanbul ignore else
+ if (overlayRef.current) {
+ Object.assign(overlayRef.current.style, style);
+ overlayRef.current.classList.add(`${iotPrefix}--breadcrumb-drop-node-overlay`);
+ }
+
+ link.classList.add(`${prefix}--row--on--link--dropping`);
+ activeDropRowIdRef.current = node;
+ }
+ }
+ }
+
+ /**
+ * Callback when the mouse leaves a breadcrumb node. Removes the class added on mouse enter
+ * @param {React.MouseEvent} e
+ */
+ function handleLeaveNode(e) {
+ const node = e.currentTarget;
+ /* istanbul ignore else */
+ if (activeDropRowIdRef.current === node) {
+ activeDropRowIdRef.current = null;
+ const link = node.querySelector(`.${prefix}--link`);
+ link.classList.remove(`${prefix}--row--on--link--dropping`);
+ /* istanbul ignore else */
+ if (overlayRef.current) {
+ overlayRef.current.classList.remove(`${iotPrefix}--breadcrumb-drop-node-overlay`);
+ overlayRef.current.style.display = 'none';
+ }
+ }
+ }
+
+ /**
+ * Attaches event listeners to list nodes of overflow menu items of breadcrumb
+ */
+ function handleMenuItemEnter() {
+ const items = document.body.querySelectorAll(`.breadcrumb--overflow-items`);
+ /* istanbul ignore else */
+ if (items && items.length > 0) {
+ const listItems = items[0].querySelectorAll(`.${prefix}--overflow-menu-options__option`);
+ listItems.forEach((li) => {
+ li.addEventListener('mouseenter', handleOverflowLiEnter);
+ li.addEventListener('mouseleave', handleOverflowLiLeave);
+ });
+ }
+ }
+
+ /**
+ * Removes event listeners from list nodes of overflow menu items of breadcrumb
+ */
+ function handleMenuItemLeave() {
+ const items = document.body.querySelectorAll(`.breadcrumb--overflow-items`);
+ /* istanbul ignore else */
+ if (items && items.length > 0) {
+ const listItems = items[0].querySelectorAll(`.${prefix}--overflow-menu-options__option`);
+ listItems.forEach((li) => {
+ li.removeEventListener('mouseenter', handleOverflowLiEnter);
+ li.removeEventListener('mouseleave', handleOverflowLiLeave);
+ });
+ }
+ }
+
+ /**
+ * Finds and attaches event listeners to all kind of possible breadcrumb nodes upon drag start setUpDnd is invoked
+ */
+ function addBreadcrumbEventListners() {
+ // Nodes which are visible are selected using common class name
+ const elements = document.querySelectorAll(`.${prefix}--breadcrumb-item`);
+ elements.forEach((element) => {
+ element.addEventListener('mouseenter', handleEnterNode);
+ element.addEventListener('mouseleave', handleLeaveNode);
+ });
+
+ // Detects if overflow menu containing hidden nodes is open or not
+ const elementExist = !!document.querySelectorAll(`.breadcrumb--overflow-items`);
+ // istanbul ignore else
+ if (elementExist) {
+ handleMenuItemEnter();
+ }
+ }
+
+ /**
+ * Removes all the event listeners attached to breadcrumb nodes
+ */
+ function removeBreadcrumbEventListeners() {
+ const elements = document.querySelectorAll(`.${prefix}--breadcrumb-item`);
+ elements.forEach((element) => {
+ element.removeEventListener('mouseenter', handleEnterNode);
+ element.removeEventListener('mouseleave', handleLeaveNode);
+ });
+
+ const elementExist = !!document.querySelectorAll(`.breadcrumb--overflow-items`);
+ // istanbul ignore else
+ if (elementExist) {
+ handleMenuItemLeave();
+ }
+ }
+
/**
* Stops an event. This is used to stop click event during drag and drop, otherwise the
* mouseup can trigger a click on the row and the row click handler will be invoked. For
@@ -299,6 +455,10 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
document.body.addEventListener('mouseup', handleDrop);
document.body.addEventListener('mousemove', handleDragMove);
document.body.addEventListener('keydown', handleEscapeKey);
+ // istanbul ignore else
+ if (hasBreadcrumbDrop) {
+ addBreadcrumbEventListners();
+ }
// If the user goes to another window, cancel the dnd.
window.addEventListener('blur', cancel);
@@ -310,12 +470,20 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
document.body.classList.add(`${iotPrefix}--is-dragging`);
return function tearDown() {
- // console.debug('Clean up table DnD');
document.body.removeEventListener('click', stopEvent, true);
document.body.removeEventListener('mouseup', handleDrop);
document.body.removeEventListener('mousemove', handleDragMove);
document.body.removeEventListener('keydown', handleEscapeKey);
-
+ // istanbul ignore else
+ if (hasBreadcrumbDrop) {
+ removeBreadcrumbEventListeners();
+ // removes style override of hyperlink on drop which was added on drag start
+ // istanbul ignore else
+ if (activeDropRowIdRef.current && activeDropRowIdRef.current.children)
+ activeDropRowIdRef.current.children[0].classList.remove(
+ `${prefix}--row--on--link--dropping`
+ );
+ }
window.removeEventListener('blur', cancel);
document.body.classList.remove(`${iotPrefix}--is-dragging`);
@@ -326,7 +494,15 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
setIsDragging(false);
};
},
- [isPossibleDrag, handleDragMove, handleDrop, cancel, setIsDragging, setDragRowIds]
+ [
+ isPossibleDrag,
+ handleDragMove,
+ handleDrop,
+ cancel,
+ setIsDragging,
+ setDragRowIds,
+ hasBreadcrumbDrop,
+ ]
);
const handleStartPossibleDrag = useCallback(
@@ -355,9 +531,6 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
[setDragRowIds, selectedIds]
);
- /** Ref to the root DOM element of the row overlay. Used to directly update its style. */
- const overlayRef = useRef(null);
-
const handleEnterRow = useCallback(
/**
* Callback when the mouse enters a table row. The table needs to add this as an onmouseenter
@@ -422,7 +595,9 @@ function useTableDnd(rows, selectedIds, zIndex, onDrag, onDrop) {
{isDragging && }
{/* We can show the preview even if not isDragging during snapback time. */}
{dragPreview && (
-
+ // For breadcrumb overflow menu has zindex of 6000 hence to show the drag above it given
+ // value 6001 when breadcrumb drop is enabled.
+
{dragPreview}
)}
diff --git a/packages/react/src/components/Table/__snapshots__/Table.main.story.storyshot b/packages/react/src/components/Table/__snapshots__/Table.main.story.storyshot
index 6830ac1ace..25b6952cbe 100644
--- a/packages/react/src/components/Table/__snapshots__/Table.main.story.storyshot
+++ b/packages/react/src/components/Table/__snapshots__/Table.main.story.storyshot
@@ -32184,6 +32184,88 @@ exports[`Storybook Snapshot tests and console checks Storyshots 1 - Watson IoT/T
>
Reset Rows
+