Skip to content

Commit

Permalink
feat(dashboard): fit and finish for model-based-queries
Browse files Browse the repository at this point in the history
  • Loading branch information
jmbuss authored and diehbria committed Nov 21, 2023
1 parent b0cbbad commit 1a2bbaf
Show file tree
Hide file tree
Showing 25 changed files with 159 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ test('can load resource explorer', async ({ page }) => {

test('can load configure a widget with an asset model', async ({ page }) => {
await page.goto(TEST_PAGE);
await page.evaluate(() => {
// enable feature flag for model based query
window.localStorage.setItem('USE_MODEL_BASED_QUERY', 'true');
});
// need to reload the page so that local storage is applied.
await page.reload();

const grid = gridUtil(page);
const resourceExplorer = resourceExplorerUtil(page);
Expand Down
6 changes: 3 additions & 3 deletions packages/dashboard/e2e/tests/utils/resourceExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const resourceExplorerUtil = (page: Page) => {
* @returns void
*/
selectAssetModel: async (label: string) => {
await frame.getByText('Select an asset model').click();
await frame.getByLabel('Asset model', { exact: true }).click();
const searchBox = await frame.getByPlaceholder('Find an asset model');
await searchBox.click();
await searchBox.fill(label);
Expand All @@ -39,7 +39,7 @@ export const resourceExplorerUtil = (page: Page) => {
* @returns void
*/
selectAsset: async (label: string) => {
await frame.getByText('Select an asset').click();
await frame.getByLabel('Default asset').click();
await frame.getByText(label).click();
},
/**
Expand All @@ -48,7 +48,7 @@ export const resourceExplorerUtil = (page: Page) => {
* @returns void
*/
saveAssetModel: async () => {
await frame.getByText('Save').click();
await frame.getByText('Set asset model').click();
},
/**
* select an asset model property from the table
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';

import { AssetForAssetModelSelect } from '../queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/assetForAssetModelSelect';
import { IoTSiteWiseClient } from '@aws-sdk/client-iotsitewise';
import FormField from '@cloudscape-design/components/form-field';

import { AssetForAssetModelSelect } from '../queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/assetForAssetModelSelect';
import { useAssetsForAssetModel } from '../queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/assetsForAssetModelSelect/useAssetsForAssetModel/useAssetsForAssetModel';
import { useModelBasedQuery } from '../queryEditor/iotSiteWiseQueryEditor/assetModelDataStreamExplorer/modelBasedQuery/useModelBasedQuery';

type AssetModelSelectOptions = {
client: IoTSiteWiseClient;
assetModelId: string;
selectedAssetId: string;
selectedAssetId?: string;
};
export const AssetModelSelect = ({ client, assetModelId, selectedAssetId }: AssetModelSelectOptions) => {
const { updateSelectedAsset } = useModelBasedQuery();
Expand All @@ -18,11 +20,13 @@ export const AssetModelSelect = ({ client, assetModelId, selectedAssetId }: Asse
const selectedAsset = assetSummaries.find(({ id }) => id === selectedAssetId);

return (
<AssetForAssetModelSelect
assetModelId={assetModelId}
selectedAsset={selectedAsset}
onSelectAsset={updateSelectedAsset}
client={client}
/>
<FormField label='Asset'>
<AssetForAssetModelSelect
assetModelId={assetModelId}
selectedAsset={selectedAsset}
onSelectAsset={updateSelectedAsset}
client={client}
/>
</FormField>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const AssetModelSelection = ({ client }: AssetModelSelectionOptions) => {
const { assetModelId, assetIds, hasModelBasedQuery } = useModelBasedQuery();
const selectedAssetId = assetIds?.at(0);

if (!hasModelBasedQuery || !assetModelId || !selectedAssetId) return null;
if (!hasModelBasedQuery || !assetModelId) return null;

return <AssetModelSelect assetModelId={assetModelId} selectedAssetId={selectedAssetId} client={client} />;
};
10 changes: 0 additions & 10 deletions packages/dashboard/src/components/internalDashboard/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@
position: relative;
}

.dashboard-toolbar-asset-model-selection-container {
/* temporary class for style patch while dashboard header is being fixed */
float: left;
display: flex;
height: 100%;
align-items: center;
margin-top: 4px;
margin-left: 12px;
}

.dashboard .dashboard-toolbar,
.dashboard .dashboard-toolbar-read-only {
background-color: var(--colors-white);
Expand Down
4 changes: 2 additions & 2 deletions packages/dashboard/src/components/internalDashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ const InternalDashboard: React.FC<InternalDashboardProperties> = ({ onSave, edit
const ReadOnlyComponent = (
<div className='dashboard'>
<div style={dashboardToolbarBottomBorder} className='dashboard-toolbar-read-only'>
<div className='dashboard-toolbar-asset-model-selection-container'>
<Box float='left' padding='s'>
<AssetModelSelection client={iotSiteWiseClient} />
</div>
</Box>
<Box float='right' padding='s'>
<SpaceBetween size='s' direction='horizontal'>
<TimeSelection />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { AssetModelPropertiesExplorer } from './assetModelPropertiesExplorer/ass
import { createInitialAssetModelSummary, useSelectedAssetModel } from './useSelectedAssetModel';
import { HorizontalDivider } from '~/components/divider/horizontalDivider';
import { createInitialAssetModelProperties, useSelectedAssetModelProperties } from './useSelectedAssetModelProperties';
import { AssetModelDataStreamSave } from './assetModelDataStreamSave';
import { createInitialAsset, useSelectedAsset } from './useSelectedAsset';
import { createAssetModelQuery } from './createAssetModelQuery';
import { createNonNullableList } from '~/helpers/lists/createNonNullableList';
Expand Down Expand Up @@ -79,12 +78,10 @@ export const AssetModelDataStreamExplorer = ({ client }: AssetModelDataStreamExp
selectedAssetModelProperties={selectedAssetModelProperties}
selectedAssetModel={selectedAssetModel}
client={client}
onSave={onSave}
saveDisabled={!modelBasedWidgetsSelected}
onSelect={(assetModelProperties) => selectAssetModelProperties(assetModelProperties)}
/>
<Box padding={{ top: 's' }}>
<HorizontalDivider />
</Box>
<AssetModelDataStreamSave onSave={onSave} disabled={!modelBasedWidgetsSelected} />
</>
)}
</Box>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import React from 'react';

import Box from '@cloudscape-design/components/box';

import CustomOrangeButton from '~/components/customOrangeButton';
import Button from '@cloudscape-design/components/button';

type AssetModelSaveOptions = {
onSave: () => void;
disabled?: boolean;
};

export const AssetModelSave = ({ onSave }: AssetModelSaveOptions) => {
export const AssetModelSave = ({ onSave, disabled }: AssetModelSaveOptions) => {
return (
<Box float='right'>
<CustomOrangeButton title='Save' handleClick={onSave} />
<Button disabled={disabled} onClick={onSave}>
Set asset model
</Button>
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const AssetModelSelect = ({ client, selectedAssetModel, onSelectAssetMode
return (
<FormField
label='Asset model'
description='Once you have selected an asset model, you may add its properties to a chart.'
description='Select an asset model to add the associated properties into your dynamic display.'
>
<Select
virtualScroll={assetModelOptions.length > 500}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { spaceScaledXxs } from '@cloudscape-design/design-tokens';
import { VerticalDivider } from '~/components/divider/verticalDivider';
import { SelectedAssetModel } from '../../useSelectedAssetModel';
import { AssetSummary, DescribeAssetCommandOutput, IoTSiteWiseClient } from '@aws-sdk/client-iotsitewise';
import { AssetForAssetModelSelect } from '../../assetsForAssetModelSelect/assetForAssetModelSelect';
// import { AssetForAssetModelSelect } from '../../assetsForAssetModelSelect/assetForAssetModelSelect';
import { AssetForAssetModelSelectForm } from '../../assetsForAssetModelSelect/assetForAssetModelSelectForm';
import { SelectedAsset, UpdateSelectedAsset } from '../../useSelectedAsset';
import { useAssetModel } from '~/hooks/useAssetModel/useAssetModel';
import { useAsset } from '../../../modeledDataStreamQueryEditor/assetExplorer/useAsset';
Expand Down Expand Up @@ -68,15 +69,15 @@ export const AssetModelSelected = ({
<img src={assetModelSvg} alt='Selected asset model icon' />
<VerticalDivider classNames={['reset-selected-asset-model-vertical-divider']} />
<Box fontWeight='bold' variant='span'>
Asset Model:
Asset model:
</Box>
<Box variant='span'>{assetModel?.assetModelName}</Box>
<div className='reset-selected-asset-model-container'>
<Button onClick={onShow}>Reset</Button>
</div>
</div>
<Box padding={{ top: 's' }}>
<AssetForAssetModelSelect
<AssetForAssetModelSelectForm
assetModelId={selectedAssetModel?.id}
selectedAsset={describedAssetToAssetSummary(asset)}
onSelectAsset={setSelectedAsset}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';

import SpaceBetween from '@cloudscape-design/components/space-between';
import Box from '@cloudscape-design/components/box';
import Link from '@cloudscape-design/components/link';

import { AssetModelSelectionNotice } from './assetModelSelectionNotice';
import { AssetModelSelect } from './assetModelSelect';
import { HorizontalDivider } from '~/components/divider/horizontalDivider';
import { AssetModelSave } from './assetModelSave';
Expand Down Expand Up @@ -36,7 +37,13 @@ export const AssetModelSelection = ({

return (
<SpaceBetween size='s' direction='vertical'>
<AssetModelSelectionNotice />
<Box variant='p'>
Dynamic asset visualizations allow you to build one visualization to represent any asset of a specified asset
model.{' '}
<Link external href='https://docs.aws.amazon.com/iot-sitewise/latest/userguide/industrial-asset-models.html'>
Learn more
</Link>
</Box>
<AssetModelSelect
selectedAssetModel={currentSelectedAssetModel}
onSelectAssetModel={selectCurrentAssetModel}
Expand All @@ -49,7 +56,7 @@ export const AssetModelSelection = ({
client={client}
/>
<HorizontalDivider />
<AssetModelSave onSave={onSave} />
<AssetModelSave disabled={!currentSelectedAssetModel} onSave={onSave} />
</SpaceBetween>
);
};

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const ResetAssetModelModal = ({
</SpaceBetween>
</Box>
}
header='Reset asset model?'
header='Reset asset model'
>
<Alert
statusIconAriaLabel='Warning'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export interface AssetExplorerProps {
selectedAssetModelProperties: SelectedAssetModelProperties;
onSelect: (assetModelProperties: AssetModelPropertySummary[]) => void;
isWithoutHeader?: boolean;
onSave?: () => void;
saveDisabled?: boolean;
client: IoTSiteWiseClient;
}

Expand All @@ -19,27 +21,32 @@ export const AssetModelPropertiesExplorer = ({
selectedAssetModel,
selectedAssetModelProperties,
onSelect,
onSave,
saveDisabled,
}: AssetExplorerProps) => {
const assetModelId = selectedAssetModel?.id ?? '';
const {
assetModelPropertySummaries,
hasNextPage = false,
isFetching,
isLoading,
// isError,
isError,
fetchNextPage,
// refetch,
refetch,
} = useAssetModelProperties({ client, assetModelId });

// TODO: implement empty state with error retry logic
return (
<AssetModelPropertiesTable
onClickNextPage={fetchNextPage}
onSelectAssetModelProperties={onSelect}
assetModelProperties={assetModelPropertySummaries}
selectedAssetModelProperties={selectedAssetModelProperties}
isLoading={isLoading || isFetching}
isError={isError}
retry={refetch}
hasNextPage={hasNextPage}
onSave={onSave}
saveDisabled={saveDisabled}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { AssetModelPropertiesTableHeader } from './assetModelPropertiesTableHead
import { SelectedAssetModelProperties } from '../../useSelectedAssetModelProperties';
import { useCustomCompareEffect } from 'react-use';
import { isEqual } from 'lodash';
import { ResourceExplorerFooter } from '../../../footer/footer';

export interface AssetTableProps {
onClickNextPage: () => void;
Expand All @@ -24,6 +25,10 @@ export interface AssetTableProps {
isLoading: boolean;
hasNextPage: boolean;
isWithoutHeader?: boolean;
onSave?: () => void;
saveDisabled?: boolean;
isError: boolean;
retry: () => void;
}

export function AssetModelPropertiesTable({
Expand All @@ -33,6 +38,10 @@ export function AssetModelPropertiesTable({
onSelectAssetModelProperties,
isLoading,
hasNextPage,
onSave,
saveDisabled,
isError,
retry,
}: AssetTableProps) {
const [preferences, updatePreferences] = useExplorerPreferences({
defaultVisibleContent: ['name'],
Expand Down Expand Up @@ -72,7 +81,12 @@ export function AssetModelPropertiesTable({
return (
<Table
{...collectionProps}
items={items}
/**
* retry button is part of the empty table state
* cloudscape doesn't have any native configuration option for
* triggering retries
*/
items={isError ? [] : items}
columnDefinitions={columnDefinitionFactory.create()}
trackBy={({ id = '' }) => id}
variant='embedded'
Expand All @@ -92,8 +106,16 @@ export function AssetModelPropertiesTable({
stripedRows={preferences.stripedRows}
visibleColumns={preferences.visibleContent}
wrapLines={preferences.wrapLines}
empty={<AssetModelPropertiesTableEmptyState />}
empty={<AssetModelPropertiesTableEmptyState isError={isError} retry={retry} />}
filter={<AssetModelPropertiesTablePropertyFilter {...propertyFilterProps} />}
footer={
<ResourceExplorerFooter
addDisabled={saveDisabled || collectionProps.selectedItems?.length === 0}
onAdd={onSave}
onReset={() => actions.setSelectedItems([])}
resetDisabled={collectionProps.selectedItems?.length === 0}
/>
}
header={
<AssetModelPropertiesTableHeader
selectedItemCount={collectionProps.selectedItems?.length}
Expand Down

0 comments on commit 1a2bbaf

Please sign in to comment.