@xyo-network/react-webapp 2.26.36 → 2.26.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/docs.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "fileName": "index.ts",
11
11
  "line": 1,
12
12
  "character": 0,
13
- "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/3b6a925/packages/webapp/src/index.ts#L1"
13
+ "url": "https://github.com/XYOracleNetwork/sdk-xyo-react-js/blob/413a933/packages/webapp/src/index.ts#L1"
14
14
  }
15
15
  ]
16
16
  }
package/package.json CHANGED
@@ -18,10 +18,10 @@
18
18
  "@xylabs/react-link": "^2.14.10",
19
19
  "@xylabs/react-pixel": "^2.14.10",
20
20
  "@xylabs/react-shared": "^2.14.10",
21
- "@xyo-network/react-app-settings": "^2.26.36",
22
- "@xyo-network/react-appbar": "^2.26.36",
23
- "@xyo-network/react-footer": "^2.26.36",
24
- "@xyo-network/react-shared": "^2.26.36",
21
+ "@xyo-network/react-app-settings": "^2.26.39",
22
+ "@xyo-network/react-appbar": "^2.26.39",
23
+ "@xyo-network/react-footer": "^2.26.39",
24
+ "@xyo-network/react-shared": "^2.26.39",
25
25
  "axios": "^0.27.2",
26
26
  "react": "^18.2.0",
27
27
  "react-dom": "^18.2.0",
@@ -86,5 +86,5 @@
86
86
  },
87
87
  "sideEffects": false,
88
88
  "types": "dist/esm/index.d.ts",
89
- "version": "2.26.36"
89
+ "version": "2.26.39"
90
90
  }
@@ -0,0 +1,67 @@
1
+ /* eslint-disable import/no-internal-modules */
2
+ import { Breadcrumbs, List } from '@mui/material'
3
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
4
+ import { FlexCol, FlexRow } from '@xylabs/react-flexbox'
5
+ import { LinkEx } from '@xylabs/react-link'
6
+ import { SiteMenuListItem } from '@xyo-network/react-appbar'
7
+ import { BrowserRouter } from 'react-router-dom'
8
+
9
+ import { WebAppChrome } from './Chrome'
10
+ import { WebAppPage } from './Page'
11
+
12
+ const StorybookEntry = {
13
+ argTypes: {},
14
+ component: WebAppChrome,
15
+ parameters: {
16
+ docs: {
17
+ page: null,
18
+ },
19
+ },
20
+ title: 'webapp/WebAppChrome',
21
+ } as ComponentMeta<typeof WebAppChrome>
22
+
23
+ const rowArray = [32, 64, 128, 256, 512, 1024]
24
+
25
+ const Template: ComponentStory<typeof WebAppChrome> = (args) => {
26
+ return (
27
+ <FlexCol height="80vh" alignItems="stretch" overflow="hidden">
28
+ <BrowserRouter>
29
+ <WebAppChrome
30
+ menuItems={
31
+ <List>
32
+ <SiteMenuListItem primary="Hello" />
33
+ </List>
34
+ }
35
+ {...args}
36
+ >
37
+ <WebAppPage
38
+ breadcrumbs={
39
+ <Breadcrumbs>
40
+ <LinkEx>BreadCrumbs</LinkEx>
41
+ </Breadcrumbs>
42
+ }
43
+ >
44
+ {rowArray.map((height) => {
45
+ return (
46
+ <FlexRow key={height} height={height}>
47
+ {height}
48
+ </FlexRow>
49
+ )
50
+ })}
51
+ </WebAppPage>
52
+ </WebAppChrome>
53
+ </BrowserRouter>
54
+ </FlexCol>
55
+ )
56
+ }
57
+
58
+ const Default = Template.bind({})
59
+ Default.args = {}
60
+
61
+ const DefaultSideBar = Template.bind({})
62
+ DefaultSideBar.args = { navigationType: 'sidebar' }
63
+
64
+ export { Default, DefaultSideBar }
65
+
66
+ // eslint-disable-next-line import/no-default-export
67
+ export default StorybookEntry
@@ -0,0 +1,47 @@
1
+ import { Divider, Paper } from '@mui/material'
2
+ import { FlexBoxProps, FlexCol, FlexGrowCol, FlexGrowRow } from '@xylabs/react-flexbox'
3
+ import { WebAppNavigationType } from '@xyo-network/react-app-settings'
4
+ import { ApplicationAppBar, SystemToolbar } from '@xyo-network/react-appbar'
5
+ import { Footer } from '@xyo-network/react-footer'
6
+ import { ErrorBoundary } from '@xyo-network/react-shared'
7
+ import { ReactNode } from 'react'
8
+ import { Helmet } from 'react-helmet'
9
+
10
+ import { WebAppErrorPage } from './ErrorPage'
11
+
12
+ export interface WebAppChromeProps extends FlexBoxProps {
13
+ appName: string
14
+ footer?: ReactNode
15
+ appbar?: ReactNode
16
+ errorPage?: ReactNode
17
+ footerElevation?: number
18
+ navigationType?: WebAppNavigationType
19
+ menuItems?: ReactNode
20
+ }
21
+
22
+ export const WebAppChrome: React.FC<WebAppChromeProps> = ({ menuItems, navigationType = 'menu', footerElevation = 4, errorPage, appbar, footer, children, appName, ...props }) => {
23
+ return (
24
+ <FlexCol alignItems="stretch" overflow="hidden" height="100vh" {...props}>
25
+ <Helmet defaultTitle={appName} titleTemplate={`%s | ${appName}`}>
26
+ <meta content="website" property="og:type" />
27
+ </Helmet>
28
+ {appbar ?? <ApplicationAppBar systemToolbar={<SystemToolbar menuItems={navigationType === 'menu' ? menuItems : undefined} />} />}
29
+ <FlexGrowRow overflow="hidden" alignItems="stretch">
30
+ {navigationType !== 'menu' ? (
31
+ <>
32
+ {menuItems}
33
+ <Divider orientation="vertical" />
34
+ </>
35
+ ) : null}
36
+ <FlexGrowCol justifyContent="flex-start" alignItems="stretch">
37
+ <ErrorBoundary fallback={errorPage ?? <WebAppErrorPage />}>{children}</ErrorBoundary>
38
+ </FlexGrowCol>
39
+ </FlexGrowRow>
40
+ <FlexCol alignItems="stretch">
41
+ <Paper elevation={footerElevation} square>
42
+ {footer ?? <Footer dynamicHeight />}
43
+ </Paper>
44
+ </FlexCol>
45
+ </FlexCol>
46
+ )
47
+ }
@@ -0,0 +1,15 @@
1
+ import { ButtonEx } from '@xylabs/react-button'
2
+
3
+ import { WebAppPage, WebAppPageProps } from './Page'
4
+
5
+ export const WebAppErrorPage: React.FC<WebAppPageProps> = (props) => (
6
+ <WebAppPage title="Oops! Something went wrong" {...props}>
7
+ <h1>Oops! Something went wrong!</h1>
8
+ <ButtonEx href="/" variant="contained">
9
+ Homepage
10
+ </ButtonEx>
11
+ </WebAppPage>
12
+ )
13
+
14
+ /** @deprecated use WebAppErrorPage instead */
15
+ export const ErrorPage = WebAppErrorPage
@@ -0,0 +1,15 @@
1
+ import { Typography } from '@mui/material'
2
+ import { FlexBoxProps, FlexGrowCol } from '@xylabs/react-flexbox'
3
+
4
+ const NotFound: React.FC<FlexBoxProps> = (props) => {
5
+ return (
6
+ <FlexGrowCol {...props}>
7
+ <Typography variant="h2">Sorry!</Typography>
8
+ <Typography marginY={3} variant="body2">
9
+ {"Can't find anything here"}
10
+ </Typography>
11
+ </FlexGrowCol>
12
+ )
13
+ }
14
+
15
+ export { NotFound }
@@ -0,0 +1,26 @@
1
+ import { ComponentMeta, ComponentStory } from '@storybook/react'
2
+
3
+ import { NotFound } from './NotFound'
4
+
5
+ const StorybookEntry = {
6
+ argTypes: {},
7
+ component: NotFound,
8
+ parameters: {
9
+ docs: {
10
+ page: null,
11
+ },
12
+ },
13
+ title: 'webapp/NotFound',
14
+ } as ComponentMeta<typeof NotFound>
15
+
16
+ const Template: ComponentStory<typeof NotFound> = () => {
17
+ return <NotFound />
18
+ }
19
+
20
+ const Default = Template.bind({})
21
+ Default.args = {}
22
+
23
+ export { Default }
24
+
25
+ // eslint-disable-next-line import/no-default-export
26
+ export default StorybookEntry
@@ -0,0 +1,11 @@
1
+ import { WebAppPage, WebAppPageProps } from '../Page'
2
+ import { NotFound } from './NotFound'
3
+
4
+ export const WebAppNotFoundPage: React.FC<WebAppPageProps> = ({ title, ...props }) => (
5
+ <WebAppPage title={title ?? 'Sorry! Page Not Found'} {...props}>
6
+ <NotFound />
7
+ </WebAppPage>
8
+ )
9
+
10
+ /** @deprecated use WebAppNotFoundPage instead */
11
+ export const NotFoundPage = WebAppNotFoundPage
@@ -0,0 +1,2 @@
1
+ export * from './NotFound'
2
+ export * from './Page'
@@ -0,0 +1,56 @@
1
+ import { Container, ContainerProps } from '@mui/material'
2
+ import { FlexBoxProps, FlexGrowCol, FlexRow } from '@xylabs/react-flexbox'
3
+ import { useUserEvents } from '@xylabs/react-pixel'
4
+ import { useAsyncEffect } from '@xylabs/react-shared'
5
+ import { ReactNode } from 'react'
6
+ import { Helmet } from 'react-helmet'
7
+ import { useLocation } from 'react-router-dom'
8
+ export interface WebAppPageProps extends FlexBoxProps {
9
+ container?: ContainerProps['maxWidth'] | 'none'
10
+ disableGutters?: boolean
11
+ breadcrumbs?: ReactNode
12
+ disableBreadcrumbGutter?: boolean
13
+ spacing?: string | number
14
+ }
15
+
16
+ export const WebAppPage: React.FC<WebAppPageProps> = ({ spacing = 1, disableBreadcrumbGutter, disableGutters, title, container, breadcrumbs, children, ...props }) => {
17
+ const userEvents = useUserEvents()
18
+ const { pathname } = useLocation()
19
+
20
+ useAsyncEffect(
21
+ // eslint-disable-next-line react-hooks/exhaustive-deps
22
+ async () => {
23
+ await userEvents?.viewContent({ name: title ?? 'NodeBasePage', path: location.pathname })
24
+ },
25
+ [pathname, title, userEvents]
26
+ )
27
+
28
+ const Body: React.FC<FlexBoxProps> = (props) => (
29
+ <FlexGrowCol gap={1} paddingY={spacing} justifyContent="flex-start" alignItems="stretch" {...props}>
30
+ <FlexRow justifyContent="flex-start" marginX={disableBreadcrumbGutter ? 0 : spacing}>
31
+ {breadcrumbs}
32
+ </FlexRow>
33
+ {children}
34
+ </FlexGrowCol>
35
+ )
36
+
37
+ return (
38
+ <FlexGrowCol alignItems="stretch" justifyContent="flex-start" minHeight={0} maxWidth="100vw" overflow="visible scroll">
39
+ <Helmet title={title} />
40
+ {container && container !== 'none' ? (
41
+ <Container
42
+ disableGutters={disableGutters}
43
+ style={{ alignItems: 'stretch', display: 'flex', flexDirection: 'column', flexGrow: 1, justifyContent: 'flex-start' }}
44
+ maxWidth={container}
45
+ >
46
+ <Body {...props} />
47
+ </Container>
48
+ ) : (
49
+ <Body paddingX={disableGutters ? 0 : 1} {...props} />
50
+ )}
51
+ </FlexGrowCol>
52
+ )
53
+ }
54
+
55
+ /** @deprecated use WebAppPagePage instead */
56
+ export const FlexPage = WebAppPage
@@ -0,0 +1,37 @@
1
+ /* eslint-disable import/no-internal-modules */
2
+ import { ComponentStory, Meta } from '@storybook/react'
3
+ import { AxiosError } from 'axios'
4
+
5
+ import { ResultLoader } from './ResultLoader'
6
+
7
+ const StorybookEntry: Meta = {
8
+ argTypes: {},
9
+ component: ResultLoader,
10
+ parameters: {
11
+ docs: {
12
+ page: null,
13
+ },
14
+ },
15
+ title: 'webapp/ResultLoader',
16
+ }
17
+
18
+ const Template: ComponentStory<typeof ResultLoader> = (props) => {
19
+ return <ResultLoader {...props} />
20
+ }
21
+
22
+ const Default = Template.bind({})
23
+ Default.args = {}
24
+
25
+ const NotFound = Template.bind({})
26
+ NotFound.args = { notFound: true }
27
+
28
+ const ApiError = Template.bind({})
29
+ ApiError.args = { apiError: new AxiosError(), children: <h1>Shown in case of error</h1> }
30
+
31
+ const SearchResult = Template.bind({})
32
+ SearchResult.args = { children: <h1>Shown when there is a valid result</h1>, searchResult: 'foo' }
33
+
34
+ export { ApiError, Default, NotFound, SearchResult }
35
+
36
+ // eslint-disable-next-line import/no-default-export
37
+ export default StorybookEntry
@@ -0,0 +1,27 @@
1
+ import { FlexGrowRow } from '@xylabs/react-flexbox'
2
+ import { AxiosError } from 'axios'
3
+ import { PropsWithChildren } from 'react'
4
+
5
+ import { NotFound } from './NotFoundPage'
6
+
7
+ export interface HandleItemDetailLoadingProps<T> {
8
+ apiError: AxiosError | undefined
9
+ notFound: boolean
10
+ searchResult: T | undefined
11
+ }
12
+
13
+ export function ResultLoader<T>(props: PropsWithChildren<HandleItemDetailLoadingProps<T>>) {
14
+ const { notFound, apiError, searchResult, children } = props
15
+ if (notFound) {
16
+ return <NotFound />
17
+ }
18
+ // Defer error handling to the children
19
+ if (apiError) {
20
+ return <>{children}</>
21
+ }
22
+ if (searchResult === undefined) {
23
+ return <FlexGrowRow busy minHeight="50px" />
24
+ } else {
25
+ return <>{children}</>
26
+ }
27
+ }
@@ -0,0 +1,5 @@
1
+ export * from './Chrome'
2
+ export * from './ErrorPage'
3
+ export * from './NotFoundPage'
4
+ export * from './Page'
5
+ export * from './ResultLoader'
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './components'