Skip to content

Commit b85055e

Browse files
Merge pull request #1963 from carbon-design-system/fix-hotspoteditormodal-ux
fix(hotspoteditormodal): 3 small ux improvements
2 parents 233d449 + bc0bead commit b85055e

5 files changed

Lines changed: 47 additions & 5 deletions

File tree

packages/react/src/components/CardEditor/CardEditForm/CardEditFormItems/ImageCardFormItems/ImageCardFormContent.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const defaultProps = {
6363
dataSeriesItemLinks: null,
6464
dataItems: [],
6565
availableDimensions: {},
66-
onFetchDynamicDemoHotspots: () => Promise.resolve([{ x: 50, y: 50 }]),
66+
onFetchDynamicDemoHotspots: null,
6767
};
6868

6969
const ImageCardFormItems = ({

packages/react/src/components/DashboardEditor/DashboardEditor.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ const propTypes = {
256256
table: PropTypes.string,
257257
image: PropTypes.string,
258258
}),
259+
/** return demo hotspots while we're editing image cards */
260+
onFetchDynamicDemoHotspots: PropTypes.func,
259261
};
260262

261263
const defaultProps = {
@@ -312,6 +314,7 @@ const defaultProps = {
312314
searchPlaceHolderText: 'Enter a value',
313315
},
314316
dataSeriesItemLinks: null,
317+
onFetchDynamicDemoHotspots: () => Promise.resolve([{ x: 50, y: 50, type: 'fixed' }]),
315318
};
316319

317320
const LAYOUTS = {
@@ -534,6 +537,7 @@ const DashboardEditor = ({
534537
{...cardProps}
535538
dataItems={dataItemsForCard}
536539
availableDimensions={availableDimensions}
540+
onFetchDynamicDemoHotspots={onFetchDynamicDemoHotspots}
537541
/>
538542
)
539543
);
@@ -545,6 +549,7 @@ const DashboardEditor = ({
545549
dataItems,
546550
duplicateCard,
547551
getValidDataItems,
552+
onFetchDynamicDemoHotspots,
548553
removeCard,
549554
renderCardPreview,
550555
selectedCardId,

packages/react/src/components/DashboardEditor/DashboardEditorCardRenderer.jsx

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable react/prop-types */
22
/* eslint-disable react/destructuring-assignment */
3-
import React from 'react';
3+
import React, { useState, useEffect } from 'react';
44
import omit from 'lodash/omit';
55
import find from 'lodash/find';
66
import isEqual from 'lodash/isEqual';
@@ -108,7 +108,12 @@ const renderTableCard = (props) => (
108108
*/
109109
const renderImageCard = (props) => (
110110
<ImageCard
111+
{...props}
111112
isEditable // render the icon in the right color in the card preview
113+
values={{
114+
...props.values,
115+
hotspots: props.values?.hotspots?.filter((hotspot) => hotspot.type !== 'dynamic') || [],
116+
}}
112117
renderIconByName={(iconName, iconProps) => {
113118
// first search the validHotspot Icons
114119
const matchingHotspotIcon = validHotspotIcons.find((icon) => icon.id === iconName);
@@ -133,7 +138,6 @@ const renderImageCard = (props) => (
133138
// eslint-disable-next-line react/prop-types
134139
return <div style={{ color: iconProps.fill }}>{iconToRender}</div>;
135140
}}
136-
{...props}
137141
/>
138142
);
139143

@@ -170,6 +174,26 @@ const renderCustomCard = (props) => {
170174
* @returns {Node}
171175
*/
172176
const DashboardEditorCardRenderer = ({ dataItems, availableDimensions, ...others }) => {
177+
const [dynamicHotspots, setDynamicHotspots] = useState([]);
178+
179+
useEffect(() => {
180+
const originalDynamicHotspot = others.values?.hotspots?.find(
181+
(hotspot) => hotspot.type === 'dynamic'
182+
);
183+
// if we have dynamic hotspots and a way to fetch them, fetch them
184+
if (originalDynamicHotspot && others.onFetchDynamicDemoHotspots) {
185+
others.onFetchDynamicDemoHotspots().then((hotspots) =>
186+
setDynamicHotspots(
187+
hotspots.map((hotspot) => ({
188+
...hotspot,
189+
...omit(originalDynamicHotspot, 'type', 'x', 'y'),
190+
}))
191+
)
192+
);
193+
}
194+
// eslint-disable-next-line react-hooks/exhaustive-deps
195+
}, [others.values?.hotspots?.length, others.onFetchDynamicDemoHotspots]);
196+
173197
if (!isCardJsonValid(others)) {
174198
return renderDefaultCard(others);
175199
}
@@ -190,7 +214,10 @@ const DashboardEditorCardRenderer = ({ dataItems, availableDimensions, ...others
190214
case CARD_TYPES.TABLE:
191215
return renderTableCard(others);
192216
case CARD_TYPES.IMAGE:
193-
return renderImageCard(others);
217+
return renderImageCard({
218+
...others,
219+
values: { ...others.values, hotspots: others.values?.hotspots?.concat(dynamicHotspots) },
220+
});
194221
case CARD_TYPES.LIST:
195222
return renderListCard(others);
196223
case CARD_TYPES.CUSTOM:

packages/react/src/components/HotspotEditorModal/HotspotEditorModal.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useEffect, useMemo } from 'react';
22
import PropTypes from 'prop-types';
33
import { ContentSwitcher, Switch, Tabs, Tab, InlineNotification } from 'carbon-components-react';
44
import pick from 'lodash/pick';
5+
import sortBy from 'lodash/sortBy';
56
import withSize from 'react-sizeme';
67
import update from 'immutability-helper';
78
import { gray50, red50, green50, blue50 } from '@carbon/colors';
@@ -256,7 +257,11 @@ const HotspotEditorModal = ({
256257
translateWithId,
257258
}) => {
258259
const initialHotspots = cardConfig.values?.hotspots || [];
259-
const myDataItems = getValidDataItems ? getValidDataItems(cardConfig) : dataItems;
260+
const myDataItems = useMemo(
261+
() => sortBy(getValidDataItems ? getValidDataItems(cardConfig) : dataItems, 'label'),
262+
// eslint-disable-next-line react-hooks/exhaustive-deps
263+
[getValidDataItems, dataItems] // watching the card config for changes will simply load this too many times
264+
);
260265
const {
261266
currentType,
262267
hotspots,
@@ -374,6 +379,7 @@ const HotspotEditorModal = ({
374379
type: hotspotTypes.DYNAMIC,
375380
}))
376381
);
382+
setSelectedHotspot(demoHotspots?.[0]);
377383
setLoadingDynamicHotspots(false);
378384
}
379385
};

packages/react/src/utils/__tests__/__snapshots__/publicAPI.test.js.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8619,6 +8619,7 @@ Map {
86198619
"onDelete": null,
86208620
"onEditTitle": null,
86218621
"onExport": null,
8622+
"onFetchDynamicDemoHotspots": [Function],
86228623
"onImageDelete": null,
86238624
"onImport": null,
86248625
"onLayoutChange": null,
@@ -9150,6 +9151,9 @@ Map {
91509151
"onExport": Object {
91519152
"type": "func",
91529153
},
9154+
"onFetchDynamicDemoHotspots": Object {
9155+
"type": "func",
9156+
},
91539157
"onImageDelete": Object {
91549158
"type": "func",
91559159
},

0 commit comments

Comments
 (0)