// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { I18n, Logger } from '@aws-amplify/core'; import React, { FormEvent, useState } from 'react'; import { LinkContainer } from 'react-router-bootstrap'; import { useParams } from 'react-router-dom'; import Alert from 'react-bootstrap/Alert'; import Breadcrumb from 'react-bootstrap/Breadcrumb'; import Button from 'react-bootstrap/Button'; import ButtonGroup from 'react-bootstrap/ButtonGroup'; import Card from 'react-bootstrap/Card'; import Container from 'react-bootstrap/Container'; import Form from 'react-bootstrap/Form'; import Row from 'react-bootstrap/Row'; import Col from 'react-bootstrap/Col'; import OpcDaForm from './OpcDaForm'; import OpcUaForm from './OpcUaForm'; import { checkErrors, handleValueChange } from './connection-form-utils'; import EmptyRow from '../../components/EmptyRow'; import EmptyCol from '../../components/EmptyCol'; import { LoadingSpinner } from '../../components/Loading'; import MessageModal from '../../components/MessageModal'; import { requestApi } from '../../util/apis'; import { ConnectionControl, ConnectionDefinition, CreateUpdateConnectionResponse, FormControlElement, GetConnectionResponse, KeyStringValue, MachineProtocol, MessageModalType } from '../../util/types'; import { INIT_CONNECTION, buildConnectionDefinition, getConditionalValue, getErrorMessage } from '../../util/utils'; import { ConnectionHook } from '../../hooks/ConnectionHook'; import OsiPiForm from './OsiPiForm'; import ModbusTcpForm from './ModbusTcpForm'; const logger = new Logger('ConnectionForm'); /** * Renders the connection form. * @returns The connection form */ export default function ConnectionForm(): JSX.Element { const { connectionName } = useParams<{ connectionName: string }>(); const [loading, setLoading] = useState(false); const [connection, setConnection] = useState(INIT_CONNECTION); const [params, setParams] = useState(); const [errors, setErrors] = useState({}); const [showConfirmMessageModal, setShowConfirmMessageModal] = useState(false); const [showMessageMessageModal, setShowMessageMessageModal] = useState(false); const [messageModalMessage, setMessageModalMessage] = useState(''); const { close, greengrassCoreDevices } = ConnectionHook({ setConnection, setMessageModalMessage, setShowMessageMessageModal, connectionName }); const change = (event: React.ChangeEvent) => { handleValueChange({ connection, errors, event, setConnection, setErrors }); }; /** * Handles an error to create or update a connection. * @param error The error */ function handleError(error: unknown): void { const errorMessage = getErrorMessage(error); logger.error(errorMessage); setShowConfirmMessageModal(false); setShowMessageMessageModal(true); setMessageModalMessage( {getConditionalValue( connectionName, I18n.get('error.message.update.connection'), I18n.get('error.message.create.connection') )}
{I18n.get('error')}: {JSON.stringify(errorMessage)}

{I18n.get('error.message.implementation.guide')}
); } /** * Handles the connection deployment and update. * @param event The connection handle form event */ async function handleConnection(event: FormEvent): Promise { event.preventDefault(); try { const connectionDefinition: ConnectionDefinition = { control: getConditionalValue( connectionName, ConnectionControl.UPDATE, ConnectionControl.DEPLOY ), connectionName: connection.connectionName, area: connection.area, greengrassCoreDeviceName: connection.greengrassCoreDeviceName, machineName: connection.machineName, process: connection.process, protocol: connection.protocol, sendDataToIoTSiteWise: connection.sendDataToIoTSiteWise, sendDataToIoTTopic: connection.sendDataToIoTTopic, sendDataToKinesisDataStreams: connection.sendDataToKinesisDataStreams, sendDataToTimestream: connection.sendDataToTimestream, sendDataToHistorian: connection.sendDataToHistorian, historianKinesisDatastreamName: connection.historianKinesisDatastreamName, siteName: connection.siteName, logLevel: connection.logLevel }; const newErrors = await checkErrors({ connection, connectionDefinition }); if (Object.keys(newErrors).length > 0) { setErrors(newErrors); } else { setErrors({}); setParams(connectionDefinition); setShowConfirmMessageModal(true); } } catch (error) { handleError(error); } } /** * Manages to create or update a connection. * @param buildParams The build connection definition request parameters */ async function manageConnection(buildParams: ConnectionDefinition): Promise { setLoading(true); try { const connectionDefinition = buildConnectionDefinition(buildParams); const response = (await requestApi({ method: 'post', path: '/connections', options: { body: connectionDefinition } })) as CreateUpdateConnectionResponse; const message = I18n.get( getConditionalValue(connectionName, 'info.message.update.connection', 'info.message.create.connection') ).replace('{}', response.connectionName); setShowMessageMessageModal(true); setMessageModalMessage( <> {message}
{I18n.get('info.message.background.running')} ); } catch (error) { handleError(error); } setLoading(false); } return ( {I18n.get('manage.connections')} {getConditionalValue( connectionName, `${I18n.get('update.connection')}: ${connectionName}`, I18n.get('create.connection') )}
{I18n.get('greengrass.core.device.name')} * {I18n.get('description.existing.greengrass.core.device.name')} {greengrassCoreDevices.map(greengrassCoreDevice => ( ))} {errors.greengrassCoreDeviceName} {I18n.get('connection.name')} * {I18n.get('description.connection.name')} {errors.connectionName} {I18n.get('site.name')} * {I18n.get('description.site.name')} {errors.siteName} {I18n.get('area')} * {I18n.get('description.area')} {errors.area} {I18n.get('process')} * {I18n.get('description.process')} {errors.process} {I18n.get('machine.name')} * {I18n.get('description.machine.name')} {errors.machineName} {I18n.get('connector.log.level')} * {I18n.get('description.logLevel')} {I18n.get('send.data.to')} * {I18n.get('description.send.data.to')} {errors.sendDataTo} {connection.sendDataToHistorian && ( {I18n.get('description.historian.kinesisStream.name')} )} {I18n.get('protocol')} * {I18n.get('description.protocol')} {connection.protocol === MachineProtocol.OPCDA && ( )} {connection.protocol === MachineProtocol.OPCUA && ( )} {connection.protocol === MachineProtocol.OSIPI && ( )} {connection.protocol === MachineProtocol.MODBUSTCP && ( )}
setShowConfirmMessageModal(false)} message={getConditionalValue( connectionName, I18n.get('info.message.update.connection.confirm'), I18n.get('info.message.create.connection.confirm') )} modalType={MessageModalType.CONFIRM} confirmAction={() => manageConnection(params as ConnectionDefinition)} /> setShowMessageMessageModal(false)} message={messageModalMessage} modalType={MessageModalType.MESSAGE} confirmAction={() => close()} />
); }