Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Adding Deployment message details formatting and removing onRowClick #1117

Merged
merged 5 commits into from
Oct 5, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions public/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
"deployments": "Deployments"
},
"errorFormat": "Error: {{message}}",
"edgeAgentStatus": {
"200": "OK.",
"400": "The deployment configuration is malformed or invalid.",
"406": "The device is offline or not sending status reports.",
"412": "The deployment configuration schema version is invalid.",
"417": "The device's deployment configuration is not set.",
"500": "An error occurred in the IoT Edge runtime.",
"unknown": "An unknown code received."
},
"errorCode": {
"noResponse": "Oops, there was no response from the server.",
"notLoggedIn": "You need to login to call the service.",
Expand Down Expand Up @@ -209,6 +218,11 @@
"description": "To run a method on one or more devices, close this pane, select the checkbox for the device(s), click <1><0>{{jobs}}</0></1>, and then select <3><0>{{methods}}</0></3>.",
"noneExist": "No methods found for this device."
},
"modules": {
"title": "Deployment messages",
"description": "Edge module messages on the device",
"noneExist": "No messages found for this device"
},
"properties": {
"title": "Properties",
"description": "To change a property on one or more devices, close this pane, select the checkbox for the device(s), click <1><0>{{jobs}}</0></1>, and then select <3><0>{{properties}}</0></3>.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
getDeployedDevices,
getDeleteDeploymentError,
getDeleteDeploymentPendingStatus,
epics as deploymentsEpics
epics as deploymentsEpics,
redux as deploymentsRedux
} from 'store/reducers/deploymentsReducer';

// Pass the global info needed
Expand All @@ -32,6 +33,7 @@ const mapStateToProps = state => ({
// Wrap the dispatch methods
const mapDispatchToProps = dispatch => ({
fetchDeployment: id => dispatch(deploymentsEpics.actions.fetchDeployment(id)),
resetDeployedDevices: () => dispatch(deploymentsRedux.actions.resetDeployedDevices()),
deleteItem: deploymentId => dispatch(deploymentsEpics.actions.deleteDeployment(deploymentId))
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ export class DeploymentDetails extends Component {
props.fetchDeployment(props.match.params.id);
}

componentWillUnmount() {
this.props.resetDeployedDevices();
}

getOpenModal = () => {
const { t, deleteIsPending, deleteError, deleteItem } = this.props;
if (this.state.openModalName === 'delete-deployment' && this.props.currentDeployment) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,19 @@ export class DeploymentDetailsGrid extends Component {
}
};

getModuleStatus = data => ({
code: data.code,
description: data.description
});

onSoftSelectChange = (deviceRowId, rowEvent) => {
const { onSoftSelectChange } = this.props;
const rowData = (this.deployedDevicesGridApi.getDisplayedRowAtIndex(deviceRowId) || {}).data;
if (rowData && rowData.device) {
this.setState({
openFlyoutName: 'deviceDetails',
selectedDevice: rowData.device
selectedDevice: rowData.device,
moduleStatus: this.getModuleStatus(rowData)
});
} else {
this.closeFlyout();
Expand All @@ -55,38 +61,33 @@ export class DeploymentDetailsGrid extends Component {

closeFlyout = () => this.setState(closedFlyoutState);

getSoftSelectId = ({ id } = '') => id;

onRowClicked = (node, data) => {
node.setSelected(!node.isSelected());
if (data && data.device) {
this.setState({
openFlyoutName: 'deviceDetails',
selectedDevice: data.device
});
}
}
getSoftSelectId = ({ id = '' }) => id;

render() {
const gridProps = {
/* Grid Properties */
...defaultDeploymentDetailsGridProps,
t: this.props.t,
context: {
t: this.props.t,
},
rowData: this.props.deployedDevices,
getRowNodeId: ({ id }) => id,
columnDefs: translateColumnDefs(this.props.t, this.columnDefs),
onGridReady: this.onGridReady,
getSoftSelectId: this.getSoftSelectId,
onSoftSelectChange: this.onSoftSelectChange,
onRowClicked: ({ node, data }) => this.onRowClicked(node, data)
onSoftSelectChange: this.onSoftSelectChange
};

return (
<ComponentArray>
<PcsGrid {...gridProps} />
{
this.state.openFlyoutName === 'deviceDetails' &&
<DeviceDetailsContainer t={this.props.t} onClose={this.closeFlyout} device={this.state.selectedDevice} />
<DeviceDetailsContainer
t={this.props.t}
onClose={this.closeFlyout}
device={this.state.selectedDevice}
moduleStatus={this.state.moduleStatus} />
}
</ComponentArray>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import Config from 'app.config';
import { TimeRenderer, SoftSelectLinkRenderer } from 'components/shared/cellRenderers';
import { getEdgeAgentStatusCode } from 'utilities';
import { gridValueFormatters } from 'components/shared/pcsGrid/pcsGridConfig';

const { checkForEmpty } = gridValueFormatters;
Expand All @@ -25,8 +26,8 @@ export const deploymentDetailsColumnDefs = {
},
lastMessage: {
headerName: 'deployments.details.grid.lastMessage',
field: 'lastMessage',
valueFormatter: ({ value }) => checkForEmpty(value)
field: 'code',
valueFormatter: ({ value, context: { t } }) => getEdgeAgentStatusCode(value, t)
},
start: {
headerName: 'deployments.details.grid.start',
Expand Down
12 changes: 10 additions & 2 deletions src/components/pages/deployments/deploymentsHome/deployments.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,23 @@ export class Deployments extends Component {

onGridReady = gridReadyEvent => this.deploymentGridApi = gridReadyEvent.api;

getSoftSelectId = ({ id } = '') => id;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is what you meant ({ id = '' })

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


onSoftSelectChange = (deviceRowId) => {
const rowData = (this.deploymentGridApi.getDisplayedRowAtIndex(deviceRowId) || {}).data;
this.props.history.push(`/deployments/${rowData.id}`)
}

render() {
const { t, deployments, error, isPending, fetchDeployments, lastUpdated, history } = this.props;
const { t, deployments, error, isPending, fetchDeployments, lastUpdated } = this.props;
const gridProps = {
onGridReady: this.onGridReady,
rowData: isPending ? undefined : deployments || [],
refresh: fetchDeployments,
onContextMenuChange: this.onContextMenuChange,
t: t,
onRowClicked: ({ data: { id } }) => history.push(`/deployments/${id}`)
getSoftSelectId: this.getSoftSelectId,
onSoftSelectChange: this.onSoftSelectChange
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,9 @@ export class DeploymentsGrid extends Component {
/* Grid Properties */
...defaultDeploymentsGridProps,
columnDefs: translateColumnDefs(this.props.t, this.columnDefs),
sizeColumnsToFit: true,
deltaRowDataMode: true,
...this.props, // Allow default property overrides
onGridReady: event => this.onGridReady(event), // Wrap in a function to avoid closure issues
getRowNodeId: ({ id }) => id,
enableSorting: true,
unSortIcon: true,
context: {
t: this.props.t
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,9 @@ export const deploymentsColumnDefs = {
export const defaultDeploymentsGridProps = {
enableColResize: true,
pagination: true,
paginationPageSize: Config.paginationPageSize
paginationPageSize: Config.paginationPageSize,
enableSorting: true,
unSortIcon: true,
sizeColumnsToFit: true,
deltaRowDataMode: true
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import {
getRulesLastUpdated,
getRulesPendingStatus
} from 'store/reducers/rulesReducer';
import {
getDeviceModuleStatus,
getDeviceModuleStatusPendingStatus,
getDeviceModuleStatusError,
epics as devicesEpics,
redux as devicesRedux
} from 'store/reducers/devicesReducer';

// Pass the device details
const mapStateToProps = state => ({
Expand All @@ -18,12 +25,17 @@ const mapStateToProps = state => ({
rulesLastUpdated: getRulesLastUpdated(state),
deviceGroups: getDeviceGroups(state),
theme: getTheme(state),
timeSeriesExplorerUrl: getTimeSeriesExplorerUrl(state)
timeSeriesExplorerUrl: getTimeSeriesExplorerUrl(state),
deviceModuleStatus: getDeviceModuleStatus(state),
isDeviceModuleStatusPending: getDeviceModuleStatusPendingStatus(state),
deviceModuleStatusError: getDeviceModuleStatusError(state)
});

// Wrap the dispatch method
const mapDispatchToProps = dispatch => ({
fetchRules: () => dispatch(ruleEpics.actions.fetchRules()),
fetchModules: (deviceId) => dispatch(devicesEpics.actions.fetchEdgeAgent(deviceId)),
resetPendingAndError: () => dispatch(devicesRedux.actions.resetPendingAndError(devicesEpics.actions.fetchEdgeAgent))
});

export const DeviceDetailsContainer = translate()(connect(mapStateToProps, mapDispatchToProps)(DeviceDetails));
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import Flyout from 'components/shared/flyout';
import { TelemetryChart, chartColorObjects } from 'components/pages/dashboard/panels/telemetry';
import { transformTelemetryResponse } from 'components/pages/dashboard/panels';
import { getEdgeAgentStatusCode } from 'utilities';

import './deviceDetails.css';

Expand All @@ -50,9 +51,10 @@ export class DeviceDetails extends Component {
telemetryIsPending: true,
telemetryError: null,

showRawMessage: false
showRawMessage: false,
currentModuleStatus: undefined
};

this.baseState = this.state;
this.columnDefs = [
{
...rulesColumnDefs.ruleName,
Expand All @@ -65,6 +67,14 @@ export class DeviceDetails extends Component {

this.resetTelemetry$ = new Subject();
this.telemetryRefresh$ = new Subject();
if (this.props.moduleStatus) {
this.state = {
...this.state,
currentModuleStatus: this.props.moduleStatus
};
} else {
this.props.fetchModules(this.props.device.id);
}
}

componentDidMount() {
Expand Down Expand Up @@ -119,11 +129,52 @@ export class DeviceDetails extends Component {
}

componentWillReceiveProps(nextProps) {
if ((this.props.device || {}).id !== nextProps.device.id) {
const deviceId = (nextProps.device || {}).id;
const {
deviceModuleStatus,
isDeviceModuleStatusPending,
deviceModuleStatusError,
moduleStatus,
resetPendingAndError,
device,
fetchModules
} = nextProps;
let tempState = this.state;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{}

let updateFlag = false;
/*
deviceModuleStatus is a prop fetched by making fetchModules() API call through deviceDetails.container on demand.
moduleStatus is a prop sent from deploymentDetailsGrid which it already has in rowData.
Both deviceModuleStatus and moduleStatus have the same content,
but come from different sources based on the page that opens this flyout.
Depending on which one is available, currentModuleStatus is set in component state.
*/

// set deviceModuleStatus in state if moduleStatus doesn't exist and devicesReducer successfully received the API response
if (!moduleStatus && !isDeviceModuleStatusPending && !deviceModuleStatusError) {
tempState.currentModuleStatus = deviceModuleStatus;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tempState = {
  ...tempState,
  currentModuleStatus: deviceModuleStatus
}

updateFlag = true;
}

// Reset state if the device changes
if ((this.props.device || {}).id !== device.id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

else if

resetPendingAndError();
tempState = this.baseState;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tempState = {
  ...tempState,
  ...this.baseState
}

updateFlag = true;

// If moduleStatus exist in props, set it in state, otherwise make an API call to get deviceModuleStatus.
if (moduleStatus) {
tempState.currentModuleStatus = moduleStatus;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tempState = {
  ...tempState,
  ...currentModuleStatus: moduleStatus
}

} else {
fetchModules(device.id);
}

const deviceId = (device || {}).id;
this.resetTelemetry$.next(deviceId);
this.fetchAlerts(deviceId);
}

if (updateFlag) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (Object.keys(tempState).length) this.setState(tempState);

this.setState(tempState);
}
}

componentWillUnmount() {
Expand Down Expand Up @@ -162,8 +213,16 @@ export class DeviceDetails extends Component {
}

render() {
const { t, onClose, device, theme, timeSeriesExplorerUrl } = this.props;
const { telemetry, lastMessage } = this.state;
const {
t,
onClose,
device,
theme,
timeSeriesExplorerUrl,
isDeviceModuleStatusPending,
deviceModuleStatusError
} = this.props;
const { telemetry, lastMessage, currentModuleStatus } = this.state;
const lastMessageTime = (lastMessage || {}).time;
const isPending = this.state.isAlertsPending && this.props.isRulesPending;
const rulesGridProps = {
Expand All @@ -176,8 +235,12 @@ export class DeviceDetails extends Component {
};
const tags = Object.entries(device.tags || {});
const properties = Object.entries(device.properties || {});

const moduleQuerySuccessful = currentModuleStatus &&
currentModuleStatus !== {} &&
!isDeviceModuleStatusPending &&
!deviceModuleStatusError;
// Add parameters to Time Series Insights Url

const timeSeriesParamUrl =
timeSeriesExplorerUrl
? timeSeriesExplorerUrl +
Expand Down Expand Up @@ -391,6 +454,28 @@ export class DeviceDetails extends Component {

</Section.Content>
</Section.Container>

<Section.Container>
<Section.Header>{t('devices.flyouts.details.modules.title')}</Section.Header>
<Section.Content>
<SectionDesc>
{t("devices.flyouts.details.modules.description")}
</SectionDesc>
<div className="device-details-deployment-contentbox">
{
!moduleQuerySuccessful &&
t('devices.flyouts.details.modules.noneExist')
}
{
moduleQuerySuccessful &&
<ComponentArray >
<div>{currentModuleStatus.code}: {getEdgeAgentStatusCode(currentModuleStatus.code, t)}</div>
<div>{currentModuleStatus.description}</div>
</ComponentArray >
}
</div>
</Section.Content>
</Section.Container>
</div>
}
<BtnToolbar>
Expand Down
Loading