react-error-boundary#ErrorBoundary TypeScript Examples
The following examples show how to use
react-error-boundary#ErrorBoundary.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExampleContainer.tsx From useDApp with MIT License | 6 votes |
function ExampleRenderer({ example }: ExampleRendererProps) {
const [Component = () => <></>] = useState(() => loadExample(example))
return (
<div style={{ borderRadius: 16, border: '1px solid rgb(190, 195, 201)', padding: 32 }}>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<Component />
</ErrorBoundary>
</div>
)
}
Example #2
Source File: index.tsx From react-pwa with MIT License | 6 votes |
function withErrorHandler<P extends object>(Component: FC<P>, Fallback: FC<FallbackProps>) {
function ComponentWithErrorHandling(props: P) {
return (
<ErrorBoundary FallbackComponent={Fallback}>
<Component {...(props as P)} />
</ErrorBoundary>
);
}
ComponentWithErrorHandling.displayName = `WithErrorHandling${getDisplayName(
Component as FC<unknown>,
)}`;
return ComponentWithErrorHandling;
}
Example #3
Source File: requestsTableWrapper.tsx From interactsh-web with MIT License | 6 votes |
RequestsTableWrapper = ({ data, handleRowClick, selectedInteraction, filter, }: RequestsTableWrapperP): JSX.Element => ( <div className="requests_table_container"> <ErrorBoundary FallbackComponent={({ resetErrorBoundary }) => ( <RepoSidebarListErrorFallback retry={resetErrorBoundary} /> )} > <Suspense fallback={<RepoSidebarListFallback />}> <RequestsTable data={[...data].reverse()} handleRowClick={handleRowClick} selectedInteraction={selectedInteraction} filter={filter} /> </Suspense> </ErrorBoundary> </div> )
Example #4
Source File: WithErrorBoundary.tsx From assisted-ui-lib with Apache License 2.0 | 6 votes |
WithErrorBoundary = ({
children,
...props
}: PropsWithChildren<WithErrorBoundaryProps>) => {
const { captureException } = useErrorMonitor();
const errorHandler = (error: Error) => {
captureException(error, props.title);
};
return (
<ErrorBoundary FallbackComponent={getErrorFallbackComponent(props)} onError={errorHandler}>
{children}
</ErrorBoundary>
);
}
Example #5
Source File: runtime.tsx From mui-toolpad with MIT License | 6 votes |
export function NodeRuntimeWrapper({ nodeId, componentConfig, children }: NodeRuntimeWrapperProps) {
const resetNodeErrorsKey = React.useContext(ResetNodeErrorsKeyContext);
return (
<ErrorBoundary
resetKeys={[resetNodeErrorsKey]}
fallbackRender={({ error }) => (
<NodeFiberHost
{...{
[RUNTIME_PROP_NODE_ID]: nodeId,
nodeError: error,
componentConfig,
}}
>
<NodeError error={error} />
</NodeFiberHost>
)}
>
<NodeRuntimeContext.Provider value={nodeId}>
<NodeFiberHost
{...{
[RUNTIME_PROP_NODE_ID]: nodeId,
componentConfig,
}}
>
{children}
</NodeFiberHost>
</NodeRuntimeContext.Provider>
</ErrorBoundary>
);
}
Example #6
Source File: ErrorWrapper.tsx From videotranscode.space with Apache License 2.0 | 6 votes |
GlobalErrorWrapper = () => {
const [globalError, setGlobalError] = useState({ state: false, message: '' })
useEffect(() => {
window.onerror = message => {
console.info(`Caught Error from Worker ${message}`)
setGlobalError({ state: true, message: message as string })
}
}, [])
if (globalError.state) {
return <ErrorScreen errorObj={new Error(globalError.message)} />
}
return (
<>
<ErrorBoundary
FallbackComponent={ErrorFallback}
onError={globalErrorHandler}>
<App />
</ErrorBoundary>
</>
)
}
Example #7
Source File: index.tsx From meshtastic-web with GNU General Public License v3.0 | 6 votes |
root.render( <StrictMode> <ErrorBoundary FallbackComponent={ErrorFallback}> <RouteProvider> <Provider store={store}> <LazyMotion features={domAnimation}> <App /> </LazyMotion> <ReloadPrompt /> </Provider> </RouteProvider> </ErrorBoundary> </StrictMode>, );
Example #8
Source File: Hub.tsx From dashboard with Apache License 2.0 | 6 votes |
Hub = () => {
document.title = "Jina Hub"
return (
<Provider store={store}>
<Router basename={"/"}>
<div>
{routes.map((route: HubRoute, index: number) => {
return (
<Route
key={index}
path={route.path}
exact={route.exact}
component={withTracker((props) => {
return (
<route.layout {...props} {...route.props}>
<ErrorBoundary FallbackComponent={FallbackPage}>
<route.component {...props} />
</ErrorBoundary>
</route.layout>
)
})}
/>
)
})}
</div>
</Router>
</Provider>
)
}
Example #9
Source File: Dashboard.tsx From dashboard with Apache License 2.0 | 6 votes |
Dashboard = () => {
document.title = "Jina Dashboard"
return (
<Provider store={store}>
<Router basename={"/"}>
<div>
{routes.map((route, idx: number) => {
return (
<Route
key={`${route.path}-${idx}`}
path={route.path}
exact={route.exact}
component={withTracker((props: any) => {
return (
<route.layout {...props} {...route.props}>
<ErrorBoundary FallbackComponent={FallbackPage}>
<route.component {...props} />
</ErrorBoundary>
</route.layout>
)
}, {})}
/>
)
})}
</div>
</Router>
</Provider>
)
}
Example #10
Source File: index.tsx From rari-dApp with GNU Affero General Public License v3.0 | 6 votes |
ReactDOM.render( <> <PWAPrompt timesToShow={2} permanentlyHideOnDismiss={false} copyTitle="Add Rari to your homescreen!" copyBody="The Rari Portal works best when added to your homescreen. Without doing this, you may have a degraded experience." copyClosePrompt="Close" /> <ChakraProvider theme={customTheme}> <ErrorBoundary FallbackComponent={ErrorPage}> <QueryClientProvider client={queryClient}> <ReactQueryDevtools initialIsOpen={false} /> <BrowserRouter> <RariProvider> <ScrollToTop /> <App /> </RariProvider> </BrowserRouter> </QueryClientProvider> </ErrorBoundary> </ChakraProvider> </>, document.getElementById("root") );
Example #11
Source File: App.tsx From TabMerger with GNU General Public License v3.0 | 5 votes |
App = (): JSX.Element => {
const dispatch = useDispatch();
const { filterChoice } = useSelector((state) => state.header);
const { active, available } = useSelector((state) => state.groups.present);
const { filteredGroups } = useFilter();
useInitState({ available, active });
useUpdateWindows();
useUpdateInfo();
useExecuteCommand();
const { onBeforeCapture, onDragStart, onDragEnd } = useDnd();
return (
<Container>
<GlobalStyle />
<ErrorBoundary
FallbackComponent={ErrorBoundaryFallback}
onReset={() => {
// Revert 2 steps back
dispatch(ActionCreators.jump(-2));
}}
>
<Header />
<DragDropContext onBeforeCapture={onBeforeCapture} onDragStart={onDragStart} onDragEnd={onDragEnd}>
{(filterChoice === "tab" || (filterChoice === "group" && filteredGroups.length > 0)) && (
<MainArea>
<SidePanel />
<Windows />
</MainArea>
)}
</DragDropContext>
</ErrorBoundary>
</Container>
);
}
Example #12
Source File: index.tsx From meshtastic-web with GNU General Public License v3.0 | 5 votes |
Layout = ({
title,
icon,
sidebarContents,
children,
}: LayoutProps): JSX.Element => {
const [settingsOpen, setSettingsOpen] = useState(false);
const route = useRoute();
const tabs: Omit<TabProps, 'activeLeft' | 'activeRight'>[] = [
{
title: 'Messages',
icon: <FiMessageCircle />,
link: routes.messages().link,
active: route.name === 'messages',
},
{
title: 'Map',
icon: <RiRoadMapLine />,
link: routes.map().link,
active: route.name === 'map',
},
{
title: 'Extensions',
icon: <VscExtensions />,
link: routes.extensions().link,
active: route.name === 'extensions',
},
];
return (
<div className="relative flex w-full overflow-hidden bg-white dark:bg-secondaryDark">
<div className="flex flex-grow">
<Sidebar settingsOpen={settingsOpen} setSettingsOpen={setSettingsOpen}>
<div className="bg-white px-1 pt-1 drop-shadow-md dark:bg-primaryDark">
<div className="flex h-10 gap-1">
<div className="my-auto">
<IconButton icon={icon} />
</div>
<div className="my-auto text-lg font-medium dark:text-white">
{title}
</div>
</div>
</div>
<div className="flex flex-col gap-2">{sidebarContents}</div>
</Sidebar>
</div>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<div className="flex h-full w-full flex-col bg-gray-300 dark:bg-secondaryDark">
<div className="flex w-full bg-white pt-1 dark:bg-primaryDark">
<div className="z-10 -mr-2 h-8">
<IconButton
className="m-1"
icon={<FiSettings />}
onClick={(): void => {
setSettingsOpen(!settingsOpen);
}}
active={settingsOpen}
/>
</div>
<Tabs tabs={tabs} />
</div>
<div className="flex flex-grow">{children}</div>
</div>
</ErrorBoundary>
</div>
);
}
Example #13
Source File: ToolpadApp.tsx From mui-toolpad with MIT License | 5 votes |
export default function ToolpadApp({ basename, appId, version, dom }: ToolpadAppProps) {
const root = appDom.getApp(dom);
const { pages = [], themes = [] } = appDom.getChildNodes(dom, root);
const theme = themes.length > 0 ? themes[0] : null;
const appContext = React.useMemo(() => ({ appId, version }), [appId, version]);
const queryClient = React.useMemo(
() =>
new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
}),
[],
);
const [resetNodeErrorsKey, setResetNodeErrorsKey] = React.useState(0);
React.useEffect(() => setResetNodeErrorsKey((key) => key + 1), [dom]);
return (
<AppRoot id={HTML_ID_APP_ROOT}>
<NoSsr>
<DomContextProvider value={dom}>
<AppThemeProvider node={theme}>
<CssBaseline />
<ErrorBoundary FallbackComponent={AppError}>
<ResetNodeErrorsKeyProvider value={resetNodeErrorsKey}>
<React.Suspense fallback={<AppLoading />}>
<JsRuntimeProvider>
<AppContextProvider value={appContext}>
<QueryClientProvider client={queryClient}>
<BrowserRouter basename={basename}>
<Routes>
<Route path="/" element={<Navigate replace to="/pages" />} />
<Route path="/pages" element={<AppOverview dom={dom} />} />
{pages.map((page) => (
<Route
key={page.id}
path={`/pages/${page.id}`}
element={
<ComponentsContext dom={dom} page={page}>
<RenderedPage nodeId={page.id} />
</ComponentsContext>
}
/>
))}
</Routes>
</BrowserRouter>
</QueryClientProvider>
</AppContextProvider>
</JsRuntimeProvider>
</React.Suspense>
</ResetNodeErrorsKeyProvider>
</ErrorBoundary>
</AppThemeProvider>
</DomContextProvider>
</NoSsr>
</AppRoot>
);
}
Example #14
Source File: viewer.tsx From nota with MIT License | 5 votes |
OutputView: React.FC<{ result: TranslationResult; imports?: any }> = ({
result,
imports,
}) => {
let [lastTranslation] = useState<{ t: JSX.Element | null }>({ t: null });
let DocResult = execute(result, imports || {});
let errored = false;
useEffect(
action(() => {
if (errored) {
errored = false;
return;
}
let Doc = resUnwrap(DocResult);
lastTranslation.t = <Doc key={counter++} editing />;
}),
[result]
);
let fallback = (err: JSX.Element) => {
errored = true;
return (
<>
<ErrorView>{err}</ErrorView>
{lastTranslation.t}
</>
);
};
return (
<>
{isOk(result) && result.value.css ? <style>{result.value.css}</style> : null}
<ErrorBoundary
resetKeys={[result]}
FallbackComponent={({ error }) => fallback(<>{error.stack}</>)}
>
{isOk(DocResult) ? <DocResult.value key={counter++} editing /> : fallback(DocResult.value)}
</ErrorBoundary>
</>
);
}
Example #15
Source File: Routes.tsx From vsinder-app with Apache License 2.0 | 5 votes |
Routes: React.FC<RoutesProps> = ({}) => {
const { editorBackground } = useTheme();
const { data, isLoading } = useQuery<MeResponse>("/me");
const routeNameRef = React.useRef<string | undefined>();
const navigationRef = React.useRef<NavigationContainerRef>(null);
let body: any = null;
if (isLoading) {
body = <FullscreenLoading />;
} else if (!data?.user) {
body = <AuthStack />;
} else if (data.user.goal && data.user.codeImgIds.length) {
body = <MainTabStack />;
} else {
body = <ProfileStack isNewUser />;
}
return (
<SafeAreaView style={{ flex: 1, backgroundColor: editorBackground }}>
<ReactQueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
FallbackComponent={ErrorFallback}
onError={myErrorHandler}
>
<NavigationContainer
ref={navigationRef}
onStateChange={() => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current?.getCurrentRoute()
?.name;
if (previousRouteName !== currentRouteName) {
if (
!["swiper", "viewProfile", "matchy"].includes(
currentRouteName || ""
)
) {
useShowTabs.getState().set({ show: false });
} else {
useShowTabs.getState().set({ show: true });
}
}
routeNameRef.current = currentRouteName;
}}
linking={linking}
fallback={<FullscreenLoading />}
>
{body}
</NavigationContainer>
</ErrorBoundary>
)}
</ReactQueryErrorResetBoundary>
</SafeAreaView>
);
}
Example #16
Source File: Members2.tsx From Riakuto-StartingReact-ja3.1 with Apache License 2.0 | 5 votes |
Members: VFC<Props> = ({ orgCodeList, prefetch = () => undefined }) => {
const [orgCode, setOrgCode] = useState('');
const [input, setInput] = useState('');
const [isPending, startTransition] = useTransition();
const { reset } = useQueryErrorResetBoundary();
const menuItems = orgCodeList.map((code) => ({
key: code,
name: capitalize(code),
onClick: () => {
setInput('');
if (orgCode) {
startTransition(() => setOrgCode(code));
} else {
setOrgCode(code);
}
},
onMouseOver: () => prefetch(code),
active: code === orgCode,
}));
const handleSubmit = (event: FormEvent<HTMLFormElement>): void => {
event.preventDefault();
setOrgCode(input.toLowerCase().trim());
};
return (
<>
<header className="app-header">
<h1>組織メンバーリスト</h1>
</header>
<form className="search-form" onSubmit={handleSubmit}>
<Input
placeholder="組織コードを入力..."
type="text"
value={input}
onChange={(_, data) => setInput(data.value)}
/>
<Button type="submit" disabled={isPending} primary>
検索
</Button>
</form>
<Menu items={menuItems} text />
<Divider />
<div className={isPending ? 'loading' : ''}>
<ErrorBoundary
fallbackRender={({ resetErrorBoundary }) => (
<>
<Message warning>
{orgCode} というコードの組織は見つかりません
</Message>
<Button color="olive" onClick={() => resetErrorBoundary()}>
エラーをリセット
</Button>
</>
)}
onReset={() => reset()}
>
<SuspenseList revealOrder="forwards">
<Suspense fallback={<Spinner size="small" />}>
<OrgInfo orgCode={orgCode} />
</Suspense>
<Suspense fallback={<Spinner size="large" />}>
<MemberList orgCode={orgCode} />
</Suspense>
</SuspenseList>
</ErrorBoundary>
</div>
</>
);
}
Example #17
Source File: requestDetailsWrapper.tsx From interactsh-web with MIT License | 5 votes |
RequestDetailsWrapper = (props: RequestDetailsWrapperP) => {
const { selectedInteractionData, view } = props;
return (
<div
className="detailed_request"
style={{ flexDirection: View.eq.equals(view, "up_and_down") ? "column" : "row" }}
>
<ErrorBoundary
FallbackComponent={({ resetErrorBoundary }) => (
<IssuesListErrorFallback retry={resetErrorBoundary} />
)}
>
<Suspense fallback={<IssuesListFallback />}>
{View.eq.equals(view, "request") ||
Protocol.eq.equals(selectedInteractionData.protocol, "smtp") ? (
<DetailedRequest
view={view}
data={`${selectedInteractionData["raw-request"]}`}
title="Request"
protocol={selectedInteractionData.protocol}
/>
) : View.eq.equals(view, "response") ? (
<DetailedRequest
view={view}
data={`${selectedInteractionData["raw-response"]}`}
title="Response"
protocol={selectedInteractionData.protocol}
/>
) : (
<>
<DetailedRequest
view={view}
data={`${selectedInteractionData["raw-request"]}`}
title="Request"
protocol={selectedInteractionData.protocol}
/>
<DetailedRequest
view={view}
data={`${selectedInteractionData["raw-response"]}`}
title="Response"
protocol={selectedInteractionData.protocol}
/>
</>
)}
</Suspense>
</ErrorBoundary>
</div>
);
}
Example #18
Source File: Routes.tsx From vsinder with Apache License 2.0 | 5 votes |
Routes: React.FC<RoutesProps> = ({}) => {
const { editorBackground } = useTheme();
const { data, isLoading } = useQuery<MeResponse>("/me");
const routeNameRef = React.useRef<string | undefined>();
const navigationRef = React.useRef<NavigationContainerRef>(null);
let body: any = null;
if (isLoading) {
body = <FullscreenLoading />;
} else if (!data?.user) {
body = <AuthStack />;
} else if (data.user.goal && data.user.codeImgIds.length) {
body = <MainTabStack />;
} else {
body = <ProfileStack isNewUser />;
}
return (
<SafeAreaView style={{ flex: 1, backgroundColor: editorBackground }}>
<ReactQueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
FallbackComponent={ErrorFallback}
onError={myErrorHandler}
>
<NavigationContainer
ref={navigationRef}
onStateChange={() => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef.current?.getCurrentRoute()
?.name;
if (previousRouteName !== currentRouteName) {
if (
!["swiper", "viewProfile", "matchy"].includes(
currentRouteName || ""
)
) {
useShowTabs.getState().set({ show: false });
} else {
useShowTabs.getState().set({ show: true });
}
}
routeNameRef.current = currentRouteName;
}}
linking={linking}
fallback={<FullscreenLoading />}
>
{body}
</NavigationContainer>
</ErrorBoundary>
)}
</ReactQueryErrorResetBoundary>
</SafeAreaView>
);
}
Example #19
Source File: showModal.tsx From yakit with GNU Affero General Public License v3.0 | 5 votes |
showModal = (props: ShowModalProps) => {
const div = document.createElement("div");
document.body.appendChild(div)
let setter: (r: boolean) => any = () => {
};
const render = (targetConfig: ShowModalProps) => {
setTimeout(() => {
ReactDOM.render(<>
<BaseModal
{...targetConfig as ModalProps}
onVisibleSetter={r => {
setter = r
}}
afterClose={() => {
const unmountResult = ReactDOM.unmountComponentAtNode(div);
if (unmountResult && div.parentNode) {
div.parentNode.removeChild(div);
}
}}
>
<ErrorBoundary FallbackComponent={({error, resetErrorBoundary}) => {
if (!error) {
return <div>未知错误</div>
}
return <div>
<p>弹框内逻辑性崩溃,请关闭重试!</p>
<pre>{error?.message}</pre>
</div>
}}>
{targetConfig.content}
</ErrorBoundary>
</BaseModal>
</>, div)
})
}
render(props);
return {
destroy: () => {
if (setter) {
setter(false)
}
setTimeout(() => {
const unmountResult = ReactDOM.unmountComponentAtNode(div);
if (unmountResult && div.parentNode) {
div.parentNode.removeChild(div)
}
}, 400)
}
}
}
Example #20
Source File: PipelineComponent.tsx From baleen3 with Apache License 2.0 | 4 votes |
PipelineComponent = React.forwardRef<
HTMLDivElement,
PipelineComponentProps
>(({ type, descriptor, setName, setSettings, onDelete, ...props }, ref) => {
const component = new PipelineComponentDescriptor(descriptor)
const editable = onDelete !== undefined
const {
name,
settings,
schema: settingsSchema,
info: componentInfo,
valid,
configured,
} = component
const componentClassName = Object.keys(descriptor)[0]
if (componentClassName === undefined) {
throw Error('Pipeline component does not define a type')
}
const [showSettingsDialog, openSettingsDialog, closeSettingsDialog] =
useDialog()
const [showNameDialog, openNameDialog, closeNameDialog] = useDialog()
const innerRef = useRef<HTMLDivElement>(null)
const [isHovering] = useHover<HTMLDivElement>(innerRef)
const [isFocus] = useFocus<HTMLDivElement>(innerRef)
const [hasSettings, setHasSettings] = useState(settingsSchema !== undefined)
const handleDelete = useCallback((): void => {
onDelete !== undefined && onDelete(component.id)
}, [component.id, onDelete])
const handleSetName = useCallback(
(name: string): void => {
setName !== undefined && setName(component.id, component.type, name)
},
[component.id, component.type, setName]
)
const handleSetSettings = useCallback(
(settings: object): void => {
setSettings !== undefined &&
setSettings(component.id, component.type, settings)
},
[component.id, component.type, setSettings]
)
const keyHandlers: {
[key: string]: (event?: KeyboardEvent | undefined) => void
} = useMemo(
() => ({
DELETE: (event?: KeyboardEvent | undefined): void => {
if (event !== undefined) {
event.preventDefault()
handleDelete()
}
},
OPEN_SETTINGS: (event?: KeyboardEvent | undefined): void => {
if (event !== undefined && hasSettings) {
event.preventDefault()
openSettingsDialog()
}
},
OPEN_NAME: (event?: KeyboardEvent | undefined): void => {
if (event !== undefined && setName !== undefined) {
event.preventDefault()
openNameDialog()
}
},
}),
[handleDelete, hasSettings, openNameDialog, openSettingsDialog, setName]
)
let message: React.ReactNode = null
if (componentInfo === undefined) {
message = (
<MessageBar severity="error" message="Component type not available" />
)
} else if (!valid) {
message = (
<MessageBar severity="error" message="Component settings not valid" />
)
} else if (setSettings !== undefined && hasSettings && !configured) {
message = (
<MessageBar
severity="warning"
message="Component has not been configured"
/>
)
}
const {
name: componentName,
description,
tags,
}: ComponentInfo = componentInfo ?? {
name: 'Missing',
componentClass: 'Missing',
artifact: '',
description: '',
tags: [],
}
const displayName = createDisplayName(name, componentName)
const displaySub = createDisplaySub(name, componentName)
return (
<Box ref={ref} width={1 / 2} minWidth={1 / 2} m={2} {...props}>
<HotKeys allowChanges keyMap={keyMap} handlers={keyHandlers}>
<Card ref={innerRef} tabIndex={0}>
{message}
{settingsSchema === undefined ? null : (
<ErrorBoundary
FallbackComponent={SettingsFallback}
onError={(error: Error, componentStack: string): void => {
setHasSettings(false)
errorHandler(error, componentStack)
}}
>
<Settings
title={`${displayName} Settings`}
open={showSettingsDialog}
settings={settings}
schema={settingsSchema}
onSubmit={handleSetSettings}
onClose={closeSettingsDialog}
editable={editable}
/>
</ErrorBoundary>
)}
<Header
displayName={displayName}
displaySub={displaySub}
isActive={isFocus || isHovering}
editable={editable}
hasSettings={hasSettings}
openNameDialog={openNameDialog}
openSettingsDialog={openSettingsDialog}
onDelete={handleDelete}
/>
<CardContent>
<Column>
<Box flexGrow="1" mb={2}>
<Typography size={-1}>
{description === undefined ? 'No description' : description}
</Typography>
</Box>
<Row flexWrap="none" pb={1} overflow="auto">
{(tags ?? []).map((tag) => (
<Chip mr={1} key={tag} size="small" label={tag} />
))}
</Row>
</Column>
</CardContent>
</Card>
</HotKeys>
{setName === undefined ? null : (
<NameDialog
title={`${type} Name`}
description="Set the name of the pipeline component."
current={displayName}
open={showNameDialog}
onSave={handleSetName}
onClose={closeNameDialog}
/>
)}
</Box>
)
})
Example #21
Source File: RelatedPage.tsx From covidex with MIT License | 4 votes |
RelatedPage = () => {
const {
params: { articleId },
} = useRouteMatch<any>();
const [loading, setLoading] = useState<boolean>(false);
const [notFound, setNotFound] = useState<boolean>(false);
const [hasMore, setHasMore] = useState<boolean>(true);
const [page, setPage] = useState<number>(1);
const [queryId, setQueryId] = useState<string>('');
const [originalArticle, setOriginalArticle] = useState<RelatedArticle | null>(null);
const [relatedArticles, setRelatedArticles] = useState<RelatedArticle[] | null>(null);
useEffect(() => {
const fetchData = async () => {
if (articleId === undefined || articleId === null || articleId === '') {
setLoading(false);
setNotFound(true);
setPage(1);
return;
}
try {
setLoading(true);
setRelatedArticles(null);
let response = await fetch(
`${API_BASE}${RELATED_ENDPOINT}/${articleId.toLowerCase()}?page_number=${1}`,
);
setLoading(false);
let data = await response.json();
const { query_id, response: responseArticles } = data;
const originalArticle = responseArticles
? responseArticles.find((a: RelatedArticle) => a.id === articleId)
: null;
setQueryId(query_id);
setOriginalArticle(originalArticle);
setRelatedArticles(responseArticles.filter((a: RelatedArticle) => a.id !== articleId));
setPage(2);
} catch {
setLoading(false);
setNotFound(true);
setPage(2);
}
};
fetchData();
}, [articleId]);
const loadMoreResults = async () => {
let response = await fetch(
`${API_BASE}${RELATED_ENDPOINT}/${articleId.toLowerCase()}?page_number=${page}`,
);
setPage(page + 1);
if (response.status > 400) {
setHasMore(false);
}
let data = await response.json();
const { response: responseArticles } = data;
const currentArticles = relatedArticles || [];
setRelatedArticles([...currentArticles, ...responseArticles]);
};
const TitleRow = (
<Row>
<RelatedTitle>
Related Articles <FileText size={24} style={{ marginLeft: '8px' }} />
</RelatedTitle>
<SearchLink to={HOME_ROUTE}>
<ArrowLeft size={16} style={{ marginRight: '4px' }} />
Search All Articles
</SearchLink>
</Row>
);
return (
<PageWrapper>
<PageContent>
<ErrorBoundary FallbackComponent={NotFoundComponent}>
<RelatedContent>
{loading && <Loading />}
{notFound && (
<>
{TitleRow}
<NotFoundComponent />
</>
)}
{originalArticle && relatedArticles && (
<>
{TitleRow}
<OriginalArticle>
<SmallTitle>Showing articles related to:</SmallTitle>
<ArticleInfo article={originalArticle} boldTitle />
{originalArticle.abstract && (
<>
<AbstractTitle className="hideCollapsed">Abstract</AbstractTitle>
<Paragraph>{parseAbstract(originalArticle.abstract)}</Paragraph>
</>
)}
</OriginalArticle>
<InfiniteScroll
pageStart={page}
loadMore={loadMoreResults}
hasMore={hasMore}
loader={
<Row>
<Loading />
</Row>
}
>
{relatedArticles.map((article, idx) => (
<RelatedResult
key={article.id}
article={article}
position={idx}
queryId={queryId}
/>
))}
</InfiniteScroll>
{relatedArticles.length === 0 && <NotFound>No related articles found</NotFound>}
</>
)}
</RelatedContent>
</ErrorBoundary>
</PageContent>
</PageWrapper>
);
}
Example #22
Source File: index.tsx From mui-toolpad with MIT License | 4 votes |
function CodeComponentEditorContent({ theme, codeComponentNode }: CodeComponentEditorContentProps) {
const domApi = useDomApi();
const [input, setInput] = React.useState<string>(codeComponentNode.attributes.code.value);
const frameRef = React.useRef<HTMLIFrameElement>(null);
const editorRef = React.useRef<monacoEditor.editor.IStandaloneCodeEditor>();
usePageTitle(`${codeComponentNode.name} | Toolpad editor`);
const updateInputExtern = React.useCallback((newInput) => {
const editor = editorRef.current;
if (!editor) {
return;
}
const model = editor.getModel();
if (!model) {
return;
}
// Used to restore cursor position
const state = editorRef.current?.saveViewState();
editor.executeEdits(null, [
{
range: model.getFullModelRange(),
text: newInput,
},
]);
if (state) {
editorRef.current?.restoreViewState(state);
}
}, []);
const handleSave = React.useCallback(() => {
const pretty = tryFormat(input);
updateInputExtern(pretty);
domApi.setNodeNamespacedProp(
codeComponentNode,
'attributes',
'code',
appDom.createConst(pretty),
);
}, [codeComponentNode, domApi, input, updateInputExtern]);
const allChangesAreCommitted = codeComponentNode.attributes.code.value === input;
usePrompt(
'Your code has unsaved changes. Are you sure you want to navigate away? All changes will be discarded.',
!allChangesAreCommitted,
);
useShortcut({ code: 'KeyS', metaKey: true }, handleSave);
const HandleEditorMount = React.useCallback(
(editor: monacoEditor.editor.IStandaloneCodeEditor, monaco: typeof monacoEditor) => {
editorRef.current = editor;
editor.updateOptions({
minimap: { enabled: false },
accessibilitySupport: 'off',
});
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
target: monaco.languages.typescript.ScriptTarget.Latest,
allowNonTsExtensions: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.CommonJS,
noEmit: true,
esModuleInterop: true,
jsx: monaco.languages.typescript.JsxEmit.React,
reactNamespace: 'React',
allowJs: true,
typeRoots: ['node_modules/@types'],
});
monaco.languages.typescript.typescriptDefaults.addExtraLib(`declare module "https://*";`);
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
noSemanticValidation: false,
noSyntaxValidation: false,
});
fetch('/typings.json')
.then((res) => res.json())
.then((typings) => {
Array.from(Object.entries(typings)).forEach(([path, content]) => {
monaco.languages.typescript.typescriptDefaults.addExtraLib(
content as string,
`file:///${path}`,
);
});
})
.catch((err) =>
console.error(`Failed to initialize typescript types on editor: ${err.message}`),
);
},
[],
);
const [iframeLoaded, onLoad] = React.useReducer(() => true, false);
React.useEffect(() => {
const document = frameRef.current?.contentDocument;
// When we hydrate the iframe then the load event is already dispatched
// once the iframe markup is parsed (maybe later but the important part is
// that it happens before React can attach event listeners).
// We need to check the readyState of the document once the iframe is mounted
// and "replay" the missed load event.
// See https://github.com/facebook/react/pull/13862 for ongoing effort in React
// (though not with iframes in mind).
if (document?.readyState === 'complete' && !iframeLoaded) {
onLoad();
}
}, [iframeLoaded]);
const frameDocument = frameRef.current?.contentDocument;
const { Component: GeneratedComponent, error: compileError } = useCodeComponent(input);
const CodeComponent: ToolpadComponent<any> = useLatest(GeneratedComponent) || Noop;
const { argTypes } = CodeComponent[TOOLPAD_COMPONENT];
const defaultProps = React.useMemo(
() => mapValues(argTypes, (argType) => argType?.defaultValue),
[argTypes],
);
return (
<React.Fragment>
<Stack sx={{ height: '100%' }}>
<Toolbar sx={{ mt: 2 }}>
<NodeNameEditor node={codeComponentNode} sx={{ maxWidth: 300 }} />
</Toolbar>
<Toolbar>
<Button disabled={allChangesAreCommitted} onClick={handleSave}>
Update
</Button>
</Toolbar>
<Box flex={1} display="flex">
<Box flex={1}>
<Editor
height="100%"
defaultValue={input}
onChange={(newValue) => setInput(newValue || '')}
path="./component.tsx"
language="typescript"
onMount={HandleEditorMount}
/>
</Box>
<Box sx={{ flex: 1, position: 'relative' }}>
<CanvasFrame ref={frameRef} title="Code component sandbox" onLoad={onLoad} />
</Box>
</Box>
</Stack>
{iframeLoaded && frameDocument
? ReactDOM.createPortal(
<FrameContent document={frameDocument}>
<React.Suspense fallback={null}>
<ErrorBoundary
resetKeys={[CodeComponent]}
fallbackRender={({ error: runtimeError }) => (
<React.Fragment>{runtimeError.message}</React.Fragment>
)}
>
<AppThemeProvider node={theme}>
<CodeComponent {...defaultProps} />
</AppThemeProvider>
</ErrorBoundary>
{compileError?.message}
</React.Suspense>
</FrameContent>,
frameDocument.body,
)
: null}
</React.Fragment>
);
}
Example #23
Source File: HomePage.tsx From covidex with MIT License | 4 votes |
HomePage = () => {
const urlParams = new URLSearchParams(useLocation().search);
const query = urlParams.get('query') || '';
const [loading, setLoading] = useState<Boolean>(false);
const [queryInputText, setQueryInputText] = useState<string>(query || '');
const [selectedVertical, setSelectedVertical] = useState<SearchVerticalOption>({
value: 'dataset',
label: Configuration[METADATA]['dataset'],
});
const [filters, setFilters] = useState<SearchFilters>({});
const [selectedFilters, setSelectedFilters] = useState<SearchFilters>({});
const [queryId, setQueryId] = useState<string>('');
const [searchResults, setSearchResults] = useState<SearchArticle[] | null>(null);
useEffect(() => {
setQueryInputText(query);
}, [query]);
useEffect(() => {
const fetchData = async (query: string | null) => {
if (query === null || query === '') {
setLoading(false);
setSearchResults([]);
return;
}
try {
setLoading(true);
setSearchResults(null);
let response = await fetch(`${API_BASE}${SEARCH_ENDPOINT}?query=${query.toLowerCase()}`);
setLoading(false);
let data = await response.json();
const { query_id, response: searchResults } = data;
const filters = getSearchFilters(searchResults);
// Set default filters
let defaultSelectedFilters: SearchFilters = {};
const fields = Object.keys(filterSchema);
fields.forEach((field) => {
if (filterSchema[field].type === 'year_slider') {
// Default to maximum range
defaultSelectedFilters[field] = filters[field];
} else if (filterSchema[field].type === 'selection') {
defaultSelectedFilters[field] = new Set([]);
}
});
setQueryId(query_id);
setSearchResults(searchResults);
setSelectedFilters(defaultSelectedFilters);
setFilters(filters);
} catch (err) {
setLoading(false);
setSearchResults([]);
}
};
fetchData(query);
}, [query]);
const queryTokens = tokenize(query);
const filteredResults =
searchResults === null
? null
: searchResults.filter((article) => filterArticle(selectedFilters, article));
return (
<PageWrapper>
<PageContent>
<SearchBar
query={queryInputText}
vertical={selectedVertical}
setQuery={setQueryInputText}
setVertical={setSelectedVertical}
/>
<ErrorBoundary FallbackComponent={() => <NoResults>Error retrieving results</NoResults>}>
{loading && <Loading />}
<HomeContent>
{!query && <HomeText />}
{query && searchResults !== null && searchResults.length > 0 && (
<Filters
filters={filters}
selectedFilters={selectedFilters}
setSelectedFilters={setSelectedFilters}
/>
)}
{query &&
filteredResults !== null &&
(searchResults === null || filteredResults.length === 0 ? (
<NoResults>No results found</NoResults>
) : (
<>
<SearchResults>
{filteredResults.map((article, i) => (
<SearchResult
key={i}
article={article}
position={i}
queryTokens={queryTokens}
queryId={queryId}
/>
))}
</SearchResults>
</>
))}
</HomeContent>
</ErrorBoundary>
</PageContent>
</PageWrapper>
);
}