Skip to content

Commit 1125f8c

Browse files
committed
Introduce Exit To AppsDashboard Menu
1 parent 9facbdd commit 1125f8c

9 files changed

+103
-18
lines changed

packages/ra-no-code/src/Admin.spec.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import userEvents from '@testing-library/user-event';
44
import fs from 'fs';
55
import path from 'path';
66
import { Admin } from './Admin';
7+
import { ApplicationContext } from './ApplicationContext';
78

89
describe('Admin', () => {
910
it('should be functional', async () => {
@@ -30,7 +31,14 @@ describe('Admin', () => {
3031
type: 'text/csv',
3132
});
3233
const { getByLabelText, getByText, getByDisplayValue } = render(
33-
<Admin application={{ name: 'test', created_at: new Date() }} />
34+
<ApplicationContext.Provider
35+
value={{
36+
application: { name: 'test', created_at: new Date() },
37+
onExit: () => {},
38+
}}
39+
>
40+
<Admin />
41+
</ApplicationContext.Provider>
3442
);
3543

3644
userEvents.upload(getByLabelText('CSV File'), file);

packages/ra-no-code/src/Admin.tsx

+13-13
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import React from 'react';
2-
import {
3-
Admin as RaAdmin,
4-
AdminProps as RaAdminProps,
5-
Resource,
6-
} from 'react-admin';
2+
import { Admin as RaAdmin, AdminProps, Resource } from 'react-admin';
73
import localStorageDataProvider from 'ra-data-local-storage';
84
import { Create, Edit, List } from './builders';
95
import {
106
useResourcesConfiguration,
117
ResourceConfigurationProvider,
128
} from './ResourceConfiguration';
139
import { Layout, Ready } from './ui';
14-
import { Application } from './ApplicationsDashboard';
10+
import { useApplication } from './ApplicationContext';
1511

16-
export const Admin = ({ application, ...props }: AdminProps) => {
12+
export const Admin = (props: Omit<AdminProps, 'dataProvider'>) => {
13+
const { application } = useApplication();
14+
if (!application) {
15+
return null;
16+
}
1717
const dataProvider = localStorageDataProvider({
1818
localStorageKey: `@@ra-no-code/${application.name}/data`,
1919
});
@@ -22,12 +22,16 @@ export const Admin = ({ application, ...props }: AdminProps) => {
2222
dataProvider={dataProvider}
2323
storageKey={`@@ra-no-code/${application.name}`}
2424
>
25-
<InnerAdmin {...props} dataProvider={dataProvider} />
25+
<InnerAdmin
26+
{...props}
27+
title={application.name}
28+
dataProvider={dataProvider}
29+
/>
2630
</ResourceConfigurationProvider>
2731
);
2832
};
2933

30-
const InnerAdmin = (props: RaAdminProps) => {
34+
const InnerAdmin = (props: AdminProps) => {
3135
const [resources] = useResourcesConfiguration();
3236
const hasResources = !!resources && Object.keys(resources).length > 0;
3337
return (
@@ -47,7 +51,3 @@ const InnerAdmin = (props: RaAdminProps) => {
4751
</RaAdmin>
4852
);
4953
};
50-
51-
interface AdminProps extends Omit<RaAdminProps, 'dataProvider'> {
52-
application: Application;
53-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createContext, useContext } from 'react';
2+
import { Application } from './ApplicationsDashboard';
3+
4+
export type ApplicationContextValue = {
5+
application: Application;
6+
onExit: () => void;
7+
};
8+
9+
export const ApplicationContext = createContext<ApplicationContextValue>(
10+
undefined
11+
);
12+
13+
export const useApplication = () => useContext(ApplicationContext);

packages/ra-no-code/src/Root.tsx

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
11
import * as React from 'react';
2-
import { useState } from 'react';
2+
import { useMemo, useState } from 'react';
33
import { Admin } from './Admin';
4+
import { ApplicationContext } from './ApplicationContext';
45
import { ApplicationsDashboard } from './ApplicationsDashboard';
56

67
export const Root = () => {
78
const [application, setApplication] = useState();
89

10+
const handleExitApplication = () => {
11+
setApplication(undefined);
12+
};
13+
914
const handleApplicationSelected = selectedApplication => {
1015
setApplication(selectedApplication);
1116
};
1217

13-
if (application) {
14-
return <Admin application={application} />;
18+
const context = useMemo(
19+
() => ({
20+
application,
21+
onExit: handleExitApplication,
22+
}),
23+
[application]
24+
);
25+
26+
if (context.application) {
27+
return (
28+
<ApplicationContext.Provider value={context}>
29+
<Admin />
30+
</ApplicationContext.Provider>
31+
);
1532
}
1633

1734
return (

packages/ra-no-code/src/ui/Appbar.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as React from 'react';
2+
import { AppBar as RaAppBar, AppBarProps } from 'react-admin';
3+
import { UserMenu } from './UserMenu';
4+
5+
export const AppBar = (props: AppBarProps) => (
6+
<RaAppBar {...props} userMenu={<UserMenu />} />
7+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from 'react';
2+
import { forwardRef } from 'react';
3+
import { MenuItemLink, MenuItemLinkProps } from 'react-admin';
4+
import ExitToAppIcon from '@material-ui/icons/ExitToApp';
5+
import { useApplication } from '../ApplicationContext';
6+
7+
export const ExitApplicationMenu = forwardRef<HTMLLIElement>(
8+
({ onClick, ...props }: MenuItemLinkProps, ref) => {
9+
const { onExit } = useApplication();
10+
11+
const handleClick = () => {
12+
onExit();
13+
};
14+
15+
return (
16+
<MenuItemLink
17+
ref={ref}
18+
to="/"
19+
primaryText="Exit application"
20+
leftIcon={<ExitToAppIcon />}
21+
onClick={handleClick}
22+
{...props}
23+
/>
24+
);
25+
}
26+
);

packages/ra-no-code/src/ui/Layout.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
22
import { Layout as RaLayout, LayoutProps } from 'react-admin';
3+
import { AppBar } from './Appbar';
34
import Menu from './Menu';
45

56
export const Layout = (props: LayoutProps) => (
6-
<RaLayout {...props} menu={Menu} />
7+
<RaLayout {...props} appBar={AppBar} menu={Menu} />
78
);
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import * as React from 'react';
2+
import { UserMenu as RaUserMenu } from 'react-admin';
3+
import { ExitApplicationMenu } from './ExitApplicationMenu';
4+
5+
export const UserMenu = props => {
6+
return (
7+
<RaUserMenu {...props}>
8+
<ExitApplicationMenu />
9+
</RaUserMenu>
10+
);
11+
};

packages/ra-no-code/src/ui/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export * from './Layout';
22
export * from './Menu';
3+
export * from './UserMenu';
4+
export * from './ExitApplicationMenu';
35
export * from './Ready';
46
export * from './ImportResourceDialog';

0 commit comments

Comments
 (0)