Skip to content

Commit

Permalink
fix(card-editor): allow initial data items
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Armendariz authored and Joel Armendariz committed Oct 29, 2020
1 parent 0352901 commit 6a3f585
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 30 deletions.
17 changes: 15 additions & 2 deletions src/components/CardEditor/CardEditForm/CardEditForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,20 @@ const propTypes = {
* getValidDataItems(card, selectedTimeRange)
*/
getValidDataItems: PropTypes.func,
/** an array of dataItem string names to be included on each card
/** if provided, returns an array of strings which are the timeRanges to be allowed
* on each card
* getValidTimeRanges(card, selectedDataItems)
*/
getValidTimeRanges: PropTypes.func,
/** an array of dataItems to be included on each card
* this prop will be ignored if getValidDataItems is defined
*/
dataItems: PropTypes.arrayOf(PropTypes.string),
dataItems: PropTypes.arrayOf(
PropTypes.shape({
dataSourceId: PropTypes.string,
label: PropTypes.string,
})
),
/** If provided, runs the function when the user clicks submit in the Card code JSON editor
* onValidateCardJson(cardJson)
* @returns Array<string> error strings. return empty array if there is no errors
Expand Down Expand Up @@ -78,6 +88,7 @@ const defaultProps = {
// additional card type names can be provided using the convention of `cardType_TYPE`
},
getValidDataItems: null,
getValidTimeRanges: null,
dataItems: [],
onValidateCardJson: null,
};
Expand Down Expand Up @@ -154,6 +165,7 @@ const CardEditForm = ({
dataItems,
onValidateCardJson,
getValidDataItems,
getValidTimeRanges,
}) => {
const mergedI18n = { ...defaultProps.i18n, ...i18n };
const [showEditor, setShowEditor] = useState(false);
Expand Down Expand Up @@ -195,6 +207,7 @@ const CardEditForm = ({
i18n={mergedI18n}
dataItems={dataItems}
getValidDataItems={getValidDataItems}
getValidTimeRanges={getValidTimeRanges}
/>
</Tab>
<Tab label={mergedI18n.settingsTabLabel}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ const propTypes = {
* getValidDataItems(card, selectedTimeRange)
*/
getValidDataItems: PropTypes.func,
/** an array of dataItem string names to be included on each card
/** an array of dataItems to be included on each card
* this prop will be ignored if getValidDataItems is defined
*/
dataItems: PropTypes.arrayOf(PropTypes.string),
dataItems: PropTypes.arrayOf(
PropTypes.shape({
dataSourceId: PropTypes.string,
label: PropTypes.string,
})
),
};

const defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ const propTypes = {
* getValidDataItems(card, selectedTimeRange)
*/
getValidDataItems: PropTypes.func,
/** an array of dataItem string names to be included on each card
/** an array of dataItems to be included on each card
* this prop will be ignored if getValidDataItems is defined
*/
dataItems: PropTypes.arrayOf(PropTypes.string),
dataItems: PropTypes.arrayOf(
PropTypes.shape({
dataSourceId: PropTypes.string,
label: PropTypes.string,
})
),
setSelectedDataItems: PropTypes.func.isRequired,
selectedTimeRange: PropTypes.string.isRequired,
};
Expand Down Expand Up @@ -106,14 +111,14 @@ const DATAITEM_COLORS_OPTIONS = [
* @param {object} cardJson
*/
export const formatSeries = (selectedItems, cardJson) => {
const cardSeries = cardJson.content.series;
const series = selectedItems.map(({ id }, i) => {
const cardSeries = cardJson?.content?.series;
const series = selectedItems.map(({ id, text }, i) => {
const color =
cardSeries.find((dataItem) => dataItem.label === id)?.color ??
cardSeries?.find((dataItem) => dataItem.label === id)?.color ??
DATAITEM_COLORS_OPTIONS[i % DATAITEM_COLORS_OPTIONS.length];
return {
dataSourceId: id.toLowerCase(),
label: id,
dataSourceId: id,
label: text,
color,
};
});
Expand All @@ -136,6 +141,12 @@ const DataSeriesFormItem = ({

const baseClassName = `${iotPrefix}--card-edit-form`;

const initialSelectedItems =
cardJson?.content?.series?.map(({ dataSourceId, label }) => ({
id: dataSourceId,
text: label || dataSourceId,
})) || [];

const validDataItems = getValidDataItems
? getValidDataItems(cardJson, selectedTimeRange)
: dataItems;
Expand Down Expand Up @@ -214,11 +225,12 @@ const DataSeriesFormItem = ({
label={mergedI18n.selectDataItems}
direction="bottom"
itemToString={(item) => item.text}
initialSelectedItems={initialSelectedItems}
items={
validDataItems
? validDataItems.map((dataItem) => ({
id: dataItem,
text: dataItem,
? validDataItems.map(({ dataSourceId, label }) => ({
id: dataSourceId,
text: label || dataSourceId,
}))
: []
}
Expand All @@ -235,7 +247,7 @@ const DataSeriesFormItem = ({
// need to force an empty "empty state"
emptyState={<div />}
title=""
items={cardJson.content.series.map((series) => ({
items={cardJson.content.series.map((series, i) => ({
id: series.dataSourceId,
content: {
value: series.label,
Expand All @@ -244,7 +256,9 @@ const DataSeriesFormItem = ({
style={{
width: '1rem',
height: '1rem',
backgroundColor: series.color,
backgroundColor:
series.color ||
DATAITEM_COLORS_OPTIONS[i % DATAITEM_COLORS_OPTIONS.length],
}}
/>
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ const cardJson = {
interval: 'day',
};

const dataItems = ['Temperature', 'Pressure'];
const dataItems = [
{ dataSourceId: 'temperature', label: 'Temperature' },
{ dataSourceId: 'pressure', label: 'Pressure' },
];

const mockOnChange = jest.fn();
const mockGetValidDataItems = jest.fn();
Expand All @@ -57,11 +60,14 @@ describe('DataSeriesFormItem', () => {
],
},
};
const selectedItems = [{ id: 'Temperature' }, { id: 'Pressure' }];
const selectedItems = [
{ id: 'temperature', text: 'Temperature' },
{ id: 'pressure', text: 'Pressure' },
];
it('should correctly format the card series', () => {
expect(formatSeries(selectedItems, cardJson)).toEqual([
{ dataSourceId: 'temperature', label: 'Temperature', color: 'red' },
{ dataSourceId: 'pressure', label: 'Pressure', color: 'blue' },
{ dataSourceId: 'temperature', label: 'Temperature', color: '#6929c4' },
{ dataSourceId: 'pressure', label: 'Pressure', color: '#1192e8' },
]);
});
it('should correctly generate colors for dataItems with no color defined', () => {
Expand Down
17 changes: 15 additions & 2 deletions src/components/CardEditor/CardEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,20 @@ const propTypes = {
* getValidDataItems(card, selectedTimeRange)
*/
getValidDataItems: PropTypes.func,
/** an array of dataItem string names to be included on each card
/** if provided, returns an array of strings which are the timeRanges to be allowed
* on each card
* getValidTimeRanges(card, selectedDataItems)
*/
getValidTimeRanges: PropTypes.func,
/** an array of dataItems to be included on each card
* this prop will be ignored if getValidDataItems is defined
*/
dataItems: PropTypes.arrayOf(PropTypes.string),
dataItems: PropTypes.arrayOf(
PropTypes.shape({
dataSourceId: PropTypes.string,
label: PropTypes.string,
})
),
/** If provided, runs the function when the user clicks submit in the Card code JSON editor
* onValidateCardJson(cardJson)
* @returns Array<string> error strings. return empty array if there is no errors
Expand All @@ -76,6 +86,7 @@ const defaultProps = {
searchPlaceholderText: 'Enter a search',
},
getValidDataItems: null,
getValidTimeRanges: null,
dataItems: [],
supportedCardTypes: Object.keys(DASHBOARD_EDITOR_CARD_TYPES),
onValidateCardJson: null,
Expand All @@ -89,6 +100,7 @@ const CardEditor = ({
onChange,
onAddCard,
getValidDataItems,
getValidTimeRanges,
dataItems,
onValidateCardJson,
supportedCardTypes,
Expand Down Expand Up @@ -126,6 +138,7 @@ const CardEditor = ({
onChange={onChange}
dataItems={dataItems}
getValidDataItems={getValidDataItems}
getValidTimeRanges={getValidTimeRanges}
onValidateCardJson={onValidateCardJson}
i18n={mergedI18n}
/>
Expand Down
8 changes: 7 additions & 1 deletion src/components/CardEditor/CardEditor.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ storiesOf('Watson IoT Experimental/CardEditor', module)
errors={{}}
onShowGallery={action('onShowGallery')}
onChange={action('onChange')}
dataItems={['Torque Max', 'Torque Min', 'Torque Mean']}
dataItems={[
{ dataSourceId: 'torque_max', label: 'Torque Max' },
{ dataSourceId: 'torque_min', label: 'Torque Min' },
{ dataSourceId: 'torque_mean', label: 'Torque Mean' },
{ dataSourceId: 'temperature', label: 'Temperature' },
{ dataSourceId: 'pressure', label: 'Pressure' },
]}
onAddCard={action('onAddCard')}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ exports[`Storybook Snapshot tests and console checks Storyshots Watson IoT Exper
Data item
</label>
<div
className="bx--multi-select bx--list-box bx--list-box--light"
className="bx--multi-select bx--multi-select--selected bx--list-box bx--list-box--light"
id="timeseries_dataSourceIds"
onClick={[Function]}
onKeyDown={[Function]}
Expand All @@ -871,6 +871,31 @@ exports[`Storybook Snapshot tests and console checks Storyshots Watson IoT Exper
onKeyDown={[Function]}
type="button"
>
<div
aria-label="Clear Selection"
className="bx--list-box__selection bx--tag--filter bx--list-box__selection--multi"
onClick={[Function]}
onKeyDown={[Function]}
role="button"
tabIndex={0}
title="Clear all selected items"
>
2
<svg
aria-hidden={true}
fill="currentColor"
focusable="false"
height={16}
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 32 32"
width={16}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24 9.4L22.6 8 16 14.6 9.4 8 8 9.4 14.6 16 8 22.6 9.4 24 16 17.4 22.6 24 24 22.6 17.4 16 24 9.4z"
/>
</svg>
</div>
<span
className="bx--list-box__label"
id="multiselect-field-label-1"
Expand Down
27 changes: 24 additions & 3 deletions src/components/DashboardEditor/DashboardEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,22 @@ const propTypes = {
* getValidDataItems(card, selectedTimeRange)
*/
getValidDataItems: PropTypes.func,
/** an array of dataItem string names to be included on each card
/** if provided, returns an array of strings which are the timeRanges to be allowed
* on each card
* getValidTimeRanges(card, selectedDataItems)
*/
getValidTimeRanges: PropTypes.func,
/** an array of dataItems to be included on each card
* this prop will be ignored if getValidDataItems is defined
*/
dataItems: PropTypes.arrayOf(PropTypes.string),
dataItems: PropTypes.arrayOf(
PropTypes.shape({
dataSourceId: PropTypes.string,
label: PropTypes.string,
})
),
/** if provided, will update the dashboard json according to its own logic */
onCardChange: PropTypes.func,
/** if provided, renders import button linked to this callback
* onImport(data, setNotification?)
*/
Expand Down Expand Up @@ -98,7 +110,9 @@ const defaultProps = {
title: null,
onEditTitle: null,
getValidDataItems: null,
getValidTimeRanges: null,
dataItems: [],
onCardChange: null,
onDelete: null,
onImport: null,
onExport: null,
Expand Down Expand Up @@ -132,9 +146,11 @@ const DashboardEditor = ({
renderHeader,
renderCardPreview,
getValidDataItems,
getValidTimeRanges,
dataItems,
headerBreadcrumbs,
notification,
onCardChange,
onEditTitle,
onImport,
onExport,
Expand Down Expand Up @@ -274,11 +290,16 @@ const DashboardEditor = ({
setDashboardJson({
...dashboardJson,
cards: dashboardJson.cards.map((card) =>
card.id === cardData.id ? cardData : card
card.id === cardData.id
? onCardChange
? onCardChange(cardData, dashboardJson)
: cardData
: card
),
})
}
getValidDataItems={getValidDataItems}
getValidTimeRanges={getValidTimeRanges}
dataItems={dataItems}
onAddCard={addCard}
onValidateCardJson={onValidateCardJson}
Expand Down
Loading

0 comments on commit 6a3f585

Please sign in to comment.