UNPKG

@ibm-adw/skill-toolkit

Version:

Developing your own skills with IBM Automation Digital Worker Skill Toolkit

332 lines (303 loc) 15.6 kB
/* 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 { Link, Redirect, Route, Switch } from 'react-router-dom'; import intl from 'react-intl-universal'; import { LocaleContext, useLocale } from '../../common/locale'; import { Header, HeaderName, HeaderPanel, Switcher, SwitcherItem, SwitcherDivider, Icon, Button, ToastNotification, Loading, InlineLoading, TooltipDefinition } from 'carbon-components-react'; import { iconDocument, iconList, iconHelp, iconChevronLeft, iconChevronRight } from 'carbon-icons'; import { Restart32, CheckmarkFilled32, ErrorFilled32 } from '@carbon/icons-react'; import axios from 'axios'; import { MainView } from '../main/MainView'; import './App.scss'; const SWITCHER_VALUES = { INFO: 'info', CATALOG: 'catalog', README: 'readme' }; const SERVER_PORT = (process.env.REACT_APP_SERVER_PORT ? process.env.REACT_APP_SERVER_PORT : '8888'); const SERVER_URL = 'http://localhost:' + SERVER_PORT; const App = () => { const localeContext = useContext(LocaleContext); const nlsLoaded = useLocale(() => [ import(/* webpackChunkName: "nls" */ `./nls/${localeContext.currentLocale}.json`), import(/* webpackChunkName: "nls" */ `./nls/${localeContext.fallbackLocale}.json`) ]); const [ switcher, setSwitcher ] = useState(SWITCHER_VALUES.INFO); const [ isSidePanelExpanded, setIsSidePanelExpanded ] = useState(false); const [ lastUpdatedDate, setLastUpdatedDate ] = useState(''); const [ skillMetaData, setSkillMetaData ] = useState({}); const [ errorServer, setErrorServer ] = useState(false); const [ subtitleToaster, setSubtitleToaster ] = useState(''); const [ titleToaster, setTitleToaster ] = useState(''); const [ displaySuccessErrorRefresh, setDisplaySuccessErrorRefresh ] = useState(false); const [ displayToast, setDisplayToast ] = useState(true); const [ shouldRefreshSkillData, setShouldRefreshSkillData ] = useState(true); const setErrorToaster = useCallback((errorBoolean, title, subtitle) => { setErrorServer(errorBoolean); if (errorBoolean) { setDisplayToast(true); setSubtitleToaster(subtitle); setTitleToaster(title); } else { setDisplayToast(false); } },[]); const handleClick = useCallback((switchToView) => { return () => { setSwitcher(switchToView); setIsSidePanelExpanded(true); }; }, []); const sidePanelCallback = useCallback((value) => { setIsSidePanelExpanded(value); }, []); const refreshSkill = useCallback(() => { setDisplayToast(true); setShouldRefreshSkillData(true); }, []); useEffect(() => { if (nlsLoaded && shouldRefreshSkillData) { axios.get(`${SERVER_URL}/specs`, { params: { content: 'info' }}) .then(response => { setSkillMetaData(response.data); const today = new Date(); setLastUpdatedDate(today); setErrorToaster(false); setShouldRefreshSkillData(() => { return false; }); setDisplaySuccessErrorRefresh(true); setTimeout(() => { setDisplaySuccessErrorRefresh(false); }, 1500); }) .catch(error => { const today = new Date(); setLastUpdatedDate(today); setErrorToaster(true, intl.get('errors.LOADING_SKILL.TITLE'), intl.get('errors.LOADING_SKILL.CONTENT', { message : error.message })); setShouldRefreshSkillData(() => {return false;}); setDisplaySuccessErrorRefresh(true); setTimeout(() => { setDisplaySuccessErrorRefresh(false); }, 1500); }); } }, [ nlsLoaded, setErrorToaster, shouldRefreshSkillData ]); const renderContent = useCallback(() => { return ( <Switch> <Route exact path="/" render={(props) => { return <MainView {...props} switcher={switcher} isSidePanelExpanded={isSidePanelExpanded} setIsSidePanelExpanded={sidePanelCallback} setErrorToaster={setErrorToaster} lastUpdatedDate={lastUpdatedDate} skillMetaData={skillMetaData} serverUrl={SERVER_URL} />; }} /> <Route render={() => (<Redirect to="/" />)} /> </Switch> ); }, [ isSidePanelExpanded, lastUpdatedDate, setErrorToaster, sidePanelCallback, skillMetaData, switcher ]); if (nlsLoaded) { return ( <div className='adw--test'> <div className='adw--test-header'> <Header aria-label="IBM Platform Name"> <HeaderName element={Link} to="/" prefix={intl.get('app.PRODUCT_NAME_PREFIX')} className='adw--test-header-name adw--test-header-name-click' > {intl.get('app.PRODUCT_NAME')} </HeaderName> <HeaderName prefix={`${skillMetaData.package_name}`} className='adw--test-header-name' children={skillMetaData.package_version} > {skillMetaData.package_version} </HeaderName> <HeaderName prefix={intl.get('app.LAST_UPDATED_ON_DATE', { updateDate: lastUpdatedDate })} className='adw--test-header-name adw--test-header-name-click' > <Button className={`adw--test-button-notif ${errorServer ? 'adw--test-button-notif-red' : 'adw--test-button-notif-green'}`} size="default" renderIcon={errorServer ? ErrorFilled32 : CheckmarkFilled32} iconDescription={errorServer ? (displayToast ? intl.get('app.ICON_DESCRIPTION_HIDE_ERRORS') : intl.get('app.ICON_DESCRIPTION_DISPLAY_ERRORS')) : intl.get('app.ICON_DESCRIPTION_LOADING_SUCCESS')} tooltipPosition="bottom" tooltipAlignment="center" disabled={errorServer ? false : true} onClick={() => setDisplayToast(!displayToast)} kind='secondary' hasIconOnly /> </HeaderName> { shouldRefreshSkillData || displaySuccessErrorRefresh ? <InlineLoading style={{ width: 'auto' }} description={displaySuccessErrorRefresh ? `${errorServer ? intl.get('app.INLINE_LOADING_DESCRIPTION_ERROR') : intl.get('app.INLINE_LOADING_DESCRIPTION_SUCCESS')}` : intl.get('app.INLINE_LOADING_DESCRIPTION_LOADING')} iconDescription={intl.get('app.ICON_DESCRIPTION_LOADING')} onSuccess={function noRefCheck() { }} //success={shouldRefreshSkillData} // deprecated: changed to status status={displaySuccessErrorRefresh ? `${errorServer ? 'error' : 'finished'}` : 'active'} successDelay={1500} /> : <TooltipDefinition align="start" direction="bottom" tooltipText={intl.get('app.TOOLTIP_TEXT_REFRESH')} triggerClassName="" > <Button className='adw--test-refresh-button' onClick={refreshSkill} kind="secondary" renderIcon={Restart32} > {intl.get('app.BUTTON_REFRESH')} </Button> </TooltipDefinition> } <HeaderPanel aria-label="Header Panel" expanded className={`adw--test-header-panel ${isSidePanelExpanded ? '' : 'adw--test-header-panel-small'}`}> <Switcher role="menu" aria-label="Switcher Container"> <SwitcherItem onClick={() => setIsSidePanelExpanded(!isSidePanelExpanded)} isSelected={false} aria-label="Chevron" > <div className='adw--test-header-panel-link'> <Icon icon={isSidePanelExpanded ? iconChevronRight : iconChevronLeft} fill={switcher === SWITCHER_VALUES.INFO ? '#f3f3f3' : '#bebebe'} className="adw--test-header-panel-link-icon" description="" height="16px" width="16px" /> </div> </SwitcherItem> <SwitcherDivider /> <SwitcherItem onClick={handleClick(SWITCHER_VALUES.INFO)} isSelected={switcher === SWITCHER_VALUES.INFO} aria-label="Metadata" > <div className='adw--test-header-panel-link'> <Icon icon={iconHelp} fill={switcher === SWITCHER_VALUES.INFO ? '#f3f3f3' : '#bebebe'} className="adw--test-header-panel-link-icon" description="" height="16px" width="16px" /> {isSidePanelExpanded ? intl.get('app.PANEL_METADATA_HEADER') : ''} </div> </SwitcherItem> <SwitcherItem onClick={handleClick(SWITCHER_VALUES.README)} isSelected={switcher === SWITCHER_VALUES.README} aria-label="README" > <div className='adw--test-header-panel-link'> <Icon icon={iconDocument} fill={switcher === SWITCHER_VALUES.README ? '#f3f3f3' : '#bebebe'} className="adw--test-header-panel-link-icon" description="" height="16px" width="16px" /> {isSidePanelExpanded ? intl.get('app.PANEL_DOCUMENTATION_HEADER') : ''} </div> </SwitcherItem> <SwitcherDivider /> <SwitcherItem onClick={handleClick(SWITCHER_VALUES.CATALOG)} isSelected={switcher === SWITCHER_VALUES.CATALOG} aria-label="Catalog" > <div className='adw--test-header-panel-link'> <Icon icon={iconList} fill={switcher === SWITCHER_VALUES.CATALOG ? '#f3f3f3' : '#bebebe'} className="adw--test-header-panel-link-icon" description="" height="16px" width="16px" /> {isSidePanelExpanded ? intl.get('app.PANEL_WIDGETS_HEADER') : ''} </div> </SwitcherItem> </Switcher> </HeaderPanel> </Header> </div> <div className={`adw--test-content adw--test-content-panel ${isSidePanelExpanded ? '' : 'adw--test-content-panel-small'}`}> { errorServer && displayToast ? <ToastNotification className='adw--test-toast-notif' caption={intl.get('app.LAST_UPDATED_ON_DATE', { updateDate: lastUpdatedDate })} hideCloseButton={false} iconDescription={intl.get('app.ICON_DESCRIPTION_HIDE_NOTIFICATION')} kind="error" notificationType="toast" onCloseButtonClick={() => setDisplayToast(false)} role="alert" style={{ marginBottom: '.5rem', minWidth: '30rem' }} lowContrast={true} subtitle={subtitleToaster} title={titleToaster} /> : '' } { shouldRefreshSkillData ? <Loading withOverlay={false} className='adw--loading'/> : renderContent() } </div> </div> ); } else { return <div><Loading withOverlay={true} /></div>; } }; export { App };