@ibm-adw/skill-toolkit
Version:
Developing your own skills with IBM Automation Digital Worker Skill Toolkit
238 lines (211 loc) • 10.2 kB
JavaScript
/*
Licensed Materials - Property of IBM
5737-I23
Copyright IBM Corp. 2019, 2020. All Rights Reserved.
U.S. Government Users Restricted Rights:
Use, duplication or disclosure restricted by GSA ADP Schedule
Contract with IBM Corp.
*/
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { SkillFormManager } from '@adw/skill-form';
import { PanelView } from './panel/PanelView';
import './ConfigView.scss';
import axios from 'axios';
import { Button, Loading } from 'carbon-components-react';
import { Delete32, Checkmark32, ErrorFilled32 } from '@carbon/icons-react';
import { LocaleContext, useLocale } from '../../common/locale';
import intl from 'react-intl-universal';
const ConfigView = (props) => {
const localeContext = useContext(LocaleContext);
const nlsLoaded = useLocale(() => [
import(/* webpackChunkName: "nls" */ `./nls/${localeContext.currentLocale}.json`),
import(/* webpackChunkName: "nls" */ `./nls/${localeContext.fallbackLocale}.json`)
]);
const {
displayFormData,
serverUrl,
setIsSidePanelExpanded,
setErrorToaster
} = props;
const [ displayPanel, setDisplayPanel ] = useState(true);
const [ formData, setFormData ] = useState('');
const [ validationError, setValidationError ] = useState('');
const [ specSchema, setSpecSchema ] = useState('');
const [ errorClearSkillData, setErrorClearSkillData ] = useState(false);
const [ displaySuccessErrorClear, setDisplaySuccessErrorClear ] = useState(false);
const [ shouldClearFormData, setShouldClearFormData ] = useState(false);
const clearData = useCallback(() => {
setShouldClearFormData(true);
setDisplayPanel(false);
setFormData('');
}, []);
useEffect(() => {
if (shouldClearFormData) {
axios.delete(`${serverUrl}/form-configuration`)
.then(() => {
setTimeout(() => {
setErrorToaster(false);
setErrorClearSkillData(false);
setShouldClearFormData(() => {return false;});
setDisplaySuccessErrorClear(true);
setTimeout(() => {
setDisplaySuccessErrorClear(false);
}, 1500);
}, 2000);
})
.catch(error => {
setErrorToaster(true, intl.get('errors.CLEARING_FORM_DATA_TITLE'), intl.get('errors.CLEARING_FORM_DATA_CONTENT', { message: error.message }));
setErrorClearSkillData(true);
setShouldClearFormData(() => {return false;});
setDisplaySuccessErrorClear(true);
setTimeout(() => {
setDisplaySuccessErrorClear(false);
}, 1500);
});
}
}, [ serverUrl, setErrorToaster, shouldClearFormData ]);
// Form callbacks
const onSubmit = useCallback(({ formData }) => {
setDisplayPanel(true);
if (setIsSidePanelExpanded) {
setIsSidePanelExpanded(false);
}
setValidationError('');
setFormData(JSON.stringify(formData, null, 2));
axios.get(`${serverUrl}/specs`, { params: { content: 'spec' }})
.then(response => {
delete response.data['$async'];
setSpecSchema(JSON.stringify(response.data, null, 2));
})
.catch(() => {
// This catch case is very unlikely because if schema validation is in error, onError is triggered rather than onSubmit
setSpecSchema('error');
});
console.log(intl.get('config.SUBMITTED_FORMDATA',{ data: JSON.stringify(formData) }));
}, [ serverUrl, setIsSidePanelExpanded ]);
const onCancel = useCallback(() => {
window.alert(intl.get('config.ALERT_ONCANCEL'));
}, []);
const onError = useCallback((error) => {
setDisplayPanel(true);
if (setIsSidePanelExpanded) {
setIsSidePanelExpanded(false);
}
if (error.response) {
if (error.response.status && error.response.status === 501) {
setSpecSchema('undefined');
}
if (error.response.config.data) {
setFormData(JSON.stringify(JSON.parse(error.response.config.data), null, 2));
}
if (error.response.data.errors) {
setValidationError(JSON.stringify(error.response.data.errors, null, 2));
}
if (error.response.data.schema) {
setSpecSchema(JSON.stringify(error.response.data.schema, null, 2));
}
}
console.error(intl.get('config.SUBMIT_ERROR',{ data: JSON.stringify(error) }));
},[ setIsSidePanelExpanded ]);
const getLabels = useCallback(() => {
return {
'skillForm': {
'title': intl.get('config.skillForm.title'),
'buttons': {
'submit': intl.get('config.skillForm.buttons.SUBMIT'),
'next': intl.get('config.skillForm.buttons.NEXT'),
'cancel': intl.get('config.skillForm.buttons.CANCEL'),
'addItem': intl.get('config.skillForm.buttons.ADD_ITEM_LABEL'),
'moveItemUp': intl.get('config.skillForm.buttons.MOVE_ITEM_UP_LABEL'),
'moveItemDown': intl.get('config.skillForm.buttons.MOVE_ITEM_DOWN_LABEL'),
'removeItem': intl.get('config.skillForm.buttons.REMOVE_ITEM_LABEL')
},
'details': {
'header': intl.get('config.skillForm.details.HEADER'),
'description': intl.get('config.skillForm.details.DESCRIPTION')
},
'optional': intl.get('config.skillForm.OPTIONAL_FIELD'),
'password': {
'showPasswordLabel': intl.get('config.skillForm.password.SHOW_PASSWORD'),
'hidePasswordLabel': intl.get('config.skillForm.password.HIDE_PASSWORD')
},
'unsupportedField': intl.get('config.skillForm.UNSUPPORTED_FIELD'),
},
'skillFormLinks': {
'buttons': {
'skillDocumentation': intl.get('config.skillFormLinks.buttons.SKILL_DOCUMENTATION'),
'sampleInstructions': intl.get('config.skillFormLinks.buttons.SAMPLE_INSTRUCTIONS'),
'schemaInput': intl.get('config.skillFormLinks.buttons.SCHEMA_INPUT'),
'schemaOutput': intl.get('config.skillFormLinks.buttons.SCHEMA_OUTPUT')
}
}
};
}, []);
const transformErrors = useCallback((errors) => {
for (const error of errors) {
error.message = intl.get(`errors.formErrors.${error.name.toUpperCase()}`, error.params) || error.message;
}
return errors;
},[]);
if (nlsLoaded) {
return (
<div className='adw--test-content-config-wrapper'>
<PanelView
displayFormData={displayFormData}
formData={formData}
validationError={validationError}
specSchema={specSchema}
displayPanel={displayPanel}
setDisplayPanel={setDisplayPanel}
/>
<div className='adw--test-content-config'>
<div className="adw--test-content-config-clear-wrapper">
<div className="adw--test-content-config-clear">
{shouldClearFormData ?
''
:
<Button
className="adw--clear-data-button"
disabled={false}
hasIconOnly
iconDescription={intl.get('config.ICON_DESCRIPTION_RESET')}
kind={(displaySuccessErrorClear ? 'ghost' : 'danger')}
tooltipAlignment="center"
tooltipPosition="left"
type="button"
renderIcon={displaySuccessErrorClear ? (errorClearSkillData ? ErrorFilled32 : Checkmark32) : Delete32}
onClick={clearData}
/>
}
</div>
{shouldClearFormData ?
<div className="adw--test-content-config-clear-loader">
<Loading
withOverlay={false}
/>
</div>
:
<div className="adw--test-content-config-form">
<SkillFormManager
serverUrl={serverUrl}
supportedLocales={process.env.REACT_APP_SUPPORTED_LOCALES}
locales={localeContext.enforcedLocale ? { currentLocale: localeContext.currentLocale, fallbackLocale: localeContext.fallbackLocale } : {}}
onSubmit={onSubmit}
onCancel={onCancel}
onError={onError}
labels={getLabels()}
displayRightColumn={false}
shouldClearFormData={shouldClearFormData}
transformErrors={transformErrors}
/>
</div>
}
</div>
</div>
</div>
);
} else {
return <div><Loading withOverlay={false} /></div>;
}
};
export { ConfigView };