Skip to content

Instantly share code, notes, and snippets.

@naydav
Created October 1, 2021 16:29
Show Gist options
  • Save naydav/bdd04c9ade77640e01bbb30b6e7b31f2 to your computer and use it in GitHub Desktop.
Save naydav/bdd04c9ade77640e01bbb30b6e7b31f2 to your computer and use it in GitHub Desktop.
Customer App - ActionsForm.js
/*
* <license header>
*/
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import {
Flex,
Heading,
Form,
TextField,
Button,
StatusLight,
ProgressCircle,
Text,
View
} from '@adobe/react-spectrum'
import actions from '../config.json'
import actionWebInvoke from '../utils'
const ActionsForm = (props) => {
const [state, setState] = useState({
formValid: null,
actionResponse: null,
actionResponseError: null,
parkingSpaceNumber: '',
parkingSpaceNumberValid: null,
orderNumber: '',
orderNumberValid: null,
customerEmail: '',
customerEmailValid: null,
actionImHereInProgress: false,
actionResult: ''
})
return (
<View width="size-6000">
<Heading level={1}>Run your application backend actions</Heading>
<Form necessityIndicator="label">
<TextField
label="Parking space #"
placeholder='your parking space number'
validationState={state.parkingSpaceNumberValid}
isRequired
onChange={(input) =>
setNumberInput(input, 'parkingSpaceNumber', 'parkingSpaceNumberValid')
}
/>
<TextField
label="Order #"
placeholder='your order number'
validationState={state.orderNumberValid}
isRequired
onChange={(input) =>
setNumberInput(input, 'orderNumber', 'orderNumberValid')
}
/>
<TextField
type="email"
label="Email"
placeholder='customer email'
validationState={state.customerEmailValid}
isRequired
value={state.customerEmail}
onChange={(input) =>
setEmailInput(input, 'customerEmail', 'customerEmailValid')
}
/>
<Flex>
<Button
variant="primary"
type="button"
onPress={invokeAction.bind(this)}
width="100%"
isDisabled={!formValid()}
><Text>I'm here</Text></Button>
</Flex>
</Form>
{state.actionResponseError && (
<View padding={`size-100`} marginTop={`size-100`} marginBottom={`size-100`} borderRadius={`small `}>
<StatusLight variant="negative">Failure! See the complete error in your browser console.</StatusLight>
</View>
)}
{!state.actionResponseError && state.actionResponse && (
<View padding={`size-100`} marginTop={`size-100`} marginBottom={`size-100`} borderRadius={`small `}>
<StatusLight variant="positive">Success! See the complete response in your browser console.</StatusLight>
</View>
)}
</View>
)
// Methods
// parses a number input and adds it to the state
async function setNumberInput (input, stateNumber, stateValid) {
let content
let validStr = null
if (input) {
content = parseInt(input) || input
validStr = Number.isInteger(content) ? 'valid' : 'invalid'
}
setState({ ...state, [stateNumber]: content, [stateValid]: validStr })
}
// check the email input and adds it to the state
async function setEmailInput (input, stateName, stateValid) {
let validStr = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(input) ? 'valid' : 'invalid';
setState({ ...state, [stateName]: input, [stateValid]: validStr })
}
// checks if form is valid
function formValid () {
return !!(state.parkingSpaceNumberValid && state.orderNumberValid && state.customerEmailValid)
}
// invokes a the selected backend actions with input headers and params
async function invokeAction () {
setState({ ...state, actionInvokeInProgress: true, actionResult: 'calling action ... ' })
const actionName = 'i-am-here'
const headers = state.actionHeaders || {}
const params = state.actionParams || {}
const startTime = Date.now()
// all headers to lowercase
Object.keys(headers).forEach((h) => {
const lowercase = h.toLowerCase()
if (lowercase !== h) {
headers[lowercase] = headers[h]
headers[h] = undefined
delete headers[h]
}
})
// set the authorization header and org from the ims props object
if (props.ims.token && !headers.authorization) {
headers.authorization = `Bearer ${props.ims.token}`
}
if (props.ims.org && !headers['x-gw-ims-org-id']) {
headers['x-gw-ims-org-id'] = props.ims.org
}
let formattedResult = ""
try {
// invoke backend action
const actionResponse = await actionWebInvoke(actions[actionName], headers, params)
formattedResult = `time: ${Date.now() - startTime} ms\n` + JSON.stringify(actionResponse,0,2)
// store the response
setState({
...state,
actionResponse,
actionResult:formattedResult,
actionResponseError: null,
actionInvokeInProgress: false
})
console.log(`Response from ${actionName}:`, actionResponse)
} catch (e) {
// log and store any error message
formattedResult = `time: ${Date.now() - startTime} ms\n` + e.message
console.error(e)
setState({
...state,
actionResponse: null,
actionResult:formattedResult,
actionResponseError: e.message,
actionInvokeInProgress: false
})
}
}
}
ActionsForm.propTypes = {
runtime: PropTypes.any,
ims: PropTypes.any
}
export default ActionsForm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment