src/app/devices/module/moduleIdentityTwin/components/moduleIdentityTwin.tsx (116 lines of code) (raw):
/***********************************************************
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License
**********************************************************/
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { useLocation, useHistory } from 'react-router-dom';
import { CommandBar } from '@fluentui/react';
import { ResourceKeys } from '../../../../../localization/resourceKeys';
import { getDeviceIdFromQueryString, getModuleIdentityIdFromQueryString } from '../../../../shared/utils/queryStringHelper';
import { REFRESH, SAVE } from '../../../../constants/iconNames';
import { SynchronizationStatus } from '../../../../api/models/synchronizationStatus';
import { getModuleIdentityTwinAction, updateModuleIdentityTwinAction } from '../actions';
import { MultiLineShimmer } from '../../../../shared/components/multiLineShimmer';
import { useAsyncSagaReducer } from '../../../../shared/hooks/useAsyncSagaReducer';
import { MonacoEditorComponent } from '../../../../shared/components/monacoEditor';
import { moduleTwinReducer } from '../reducer';
import { moduleIdentityTwinSagas } from '../saga';
import { moduleTwinStateInitial } from '../state';
import { AppInsightsClient } from '../../../../shared/appTelemetry/appInsightsClient';
import { TELEMETRY_PAGE_NAMES, TELEMETRY_USER_ACTIONS } from '../../../../../app/constants/telemetry';
import '../../../../css/_deviceDetail.scss';
export const ModuleIdentityTwin: React.FC = () => {
const { t } = useTranslation();
const { search, pathname } = useLocation();
const history = useHistory();
const moduleId = getModuleIdentityIdFromQueryString(search);
const deviceId = getDeviceIdFromQueryString(search);
const [ localState, dispatch ] = useAsyncSagaReducer(moduleTwinReducer, moduleIdentityTwinSagas, moduleTwinStateInitial(), 'moduleIdentityTwinState');
const moduleIdentityTwin = localState.payload;
const moduleIdentityTwinSyncStatus = localState.synchronizationStatus;
const [ state, setState ] = React.useState({
isDirty: false,
isTwinValid: true,
twin: JSON.stringify(moduleIdentityTwin, null, '\t')
});
React.useEffect(() => {
retrieveData();
}, [deviceId, moduleId]);
React.useEffect(() => {
AppInsightsClient.getInstance()?.trackPageView({name: TELEMETRY_PAGE_NAMES.MODULE_TWIN});
}, []); // tslint:disable-line: align
const retrieveData = () => dispatch(getModuleIdentityTwinAction.started({ deviceId, moduleId }));
const handleSave = () => {
setState({
...state,
isDirty: false,
isTwinValid: true
});
AppInsightsClient.trackUserAction(TELEMETRY_USER_ACTIONS.UPDATE_MODULE_TWIN);
dispatch(updateModuleIdentityTwinAction.started(JSON.parse(state.twin)));
};
const showCommandBar = () => {
return (
<CommandBar
className="command device-detail-command"
items={[
{
ariaLabel: t(ResourceKeys.moduleIdentity.detail.command.refresh),
disabled: moduleIdentityTwinSyncStatus === SynchronizationStatus.working,
iconProps: {iconName: REFRESH},
key: REFRESH,
name: t(ResourceKeys.moduleIdentity.detail.command.refresh),
onClick: retrieveData
},
{
ariaLabel: t(ResourceKeys.moduleIdentity.detail.command.save),
disabled: !state.isDirty || !state.isTwinValid,
iconProps: {iconName: SAVE},
key: SAVE,
name: t(ResourceKeys.moduleIdentity.detail.command.save),
onClick: handleSave
}
]}
/>
);
};
const showModuleTwin = () => {
if (moduleIdentityTwinSyncStatus === SynchronizationStatus.working || moduleIdentityTwinSyncStatus === SynchronizationStatus.updating) {
return <MultiLineShimmer/>;
}
const editorHeight = 700;
return (
<article className="device-twin device-detail" style={{paddingTop: 10}}>
{moduleIdentityTwin &&
<MonacoEditorComponent
content={JSON.stringify(moduleIdentityTwin, null, '\t')}
height={editorHeight}
onChange={onChange}
ariaLabel={ResourceKeys.moduleIdentity.detail.twin}
/>
}
</article>
);
};
const onChange = (data: string) => {
let isTwinValid = true;
try {
JSON.parse(data);
}
catch {
isTwinValid = false;
}
setState({
...state,
isDirty: true,
isTwinValid,
twin: data
});
};
return (
<>
{showCommandBar()}
{moduleIdentityTwinSyncStatus === SynchronizationStatus.working ?
<MultiLineShimmer/> :
showModuleTwin()
}
</>
);
};