src/app/devices/pnp/components/deviceSettings/deviceSettings.tsx (102 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 { CommandBar, Label } from '@fluentui/react';
import { useLocation, useHistory } from 'react-router-dom';
import { DeviceSettingsPerInterface } from './deviceSettingsPerInterface';
import { ResourceKeys } from '../../../../../localization/resourceKeys';
import { getDeviceIdFromQueryString, getInterfaceIdFromQueryString, getComponentNameFromQueryString, getModuleIdentityIdFromQueryString } from '../../../../shared/utils/queryStringHelper';
import { updateDeviceTwinAction, updateModuleTwinAction } from '../../actions';
import { REFRESH, NAVIGATE_BACK } from '../../../../constants/iconNames';
import { MultiLineShimmer } from '../../../../shared/components/multiLineShimmer';
import { usePnpStateContext } from '../../context/pnpStateContext';
import { SynchronizationStatus } from '../../../../api/models/synchronizationStatus';
import { generateTwinSchemaAndInterfaceTuple } from './dataHelper';
import { Twin } from '../../../../api/models/device';
import { dispatchGetTwinAction, getBackUrl } from '../../utils';
import { AppInsightsClient } from '../../../../shared/appTelemetry/appInsightsClient';
import { TELEMETRY_PAGE_NAMES, TELEMETRY_USER_ACTIONS } from '../../../../../app/constants/telemetry';
// tslint:disable-next-line:cyclomatic-complexity
export const DeviceSettings: React.FC = () => {
const { t } = useTranslation();
const { search, pathname } = useLocation();
const history = useHistory();
const deviceId = getDeviceIdFromQueryString(search);
const moduleId = getModuleIdentityIdFromQueryString(search);
const componentName = getComponentNameFromQueryString(search);
const interfaceId = getInterfaceIdFromQueryString(search);
const { pnpState, dispatch, getModelDefinition } = usePnpStateContext();
const isLoading = (pnpState.twin.synchronizationStatus === SynchronizationStatus.working)
|| (pnpState.modelDefinitionWithSource.synchronizationStatus === SynchronizationStatus.working);
const modelDefinitionWithSource = pnpState.modelDefinitionWithSource && pnpState.modelDefinitionWithSource.payload;
const modelDefinition = modelDefinitionWithSource && modelDefinitionWithSource.modelDefinition;
const extendedModelDefinition = modelDefinitionWithSource && modelDefinitionWithSource.extendedModel;
const twin = pnpState.twin.payload;
const twinWithSchema = React.useMemo(() => {
return generateTwinSchemaAndInterfaceTuple(extendedModelDefinition || modelDefinition, twin, componentName);
}, [modelDefinition, twin, extendedModelDefinition]);
const patchTwin = (parameters: Twin) => {
AppInsightsClient.trackUserAction(TELEMETRY_USER_ACTIONS.PNP_UPDATE_PROPERTY);
if (moduleId) {
dispatch(updateModuleTwinAction.started(parameters));
}
else {
dispatch(updateDeviceTwinAction.started(parameters));
}
};
const renderProperties = () => {
return (
<>
{!twinWithSchema || twinWithSchema.length === 0 ?
<Label className="no-pnp-content">{t(ResourceKeys.deviceSettings.noSettings, {componentName})}</Label> :
<DeviceSettingsPerInterface
componentName={componentName}
patchTwin={patchTwin}
interfaceId={interfaceId}
twinWithSchema={twinWithSchema}
deviceId={deviceId}
moduleId={moduleId}
/>
}
</>
);
};
const onRefresh = () => {
dispatchGetTwinAction(search, dispatch);
getModelDefinition();
};
const handleClose = () => {
const path = pathname.replace(/\/ioTPlugAndPlayDetail\/settings\/.*/, ``);
history.push(getBackUrl(path, search));
};
React.useEffect(() => {
AppInsightsClient.getInstance()?.trackPageView({name: TELEMETRY_PAGE_NAMES.PNP_DEVICE_SETTINGS});
}, []); // tslint:disable-line: align
if (isLoading) {
return (
<MultiLineShimmer/>
);
}
return (
<>
<CommandBar
className="command"
items={[
{
ariaLabel: t(ResourceKeys.deviceSettings.command.refresh),
iconProps: {iconName: REFRESH},
key: REFRESH,
name: t(ResourceKeys.deviceSettings.command.refresh),
onClick: onRefresh
}
]}
farItems={[
{
ariaLabel: t(ResourceKeys.deviceSettings.command.close),
iconProps: {iconName: NAVIGATE_BACK},
key: NAVIGATE_BACK,
name: t(ResourceKeys.deviceSettings.command.close),
onClick: handleClose
}
]}
/>
{renderProperties()}
</>
);
};