@niledatabase/react 1.0.0-alpha.195
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/LICENSE +21 -0
- package/README.md +151 -0
- package/dist/GoogleLoginButton/GoogleLoginButton.d.ts +13 -0
- package/dist/GoogleLoginButton/GoogleLoginButton.stories.d.ts +12 -0
- package/dist/GoogleLoginButton/index.d.ts +1 -0
- package/dist/LoginForm/LoginForm.d.ts +3 -0
- package/dist/LoginForm/SingleSignOn.d.ts +7 -0
- package/dist/LoginForm/UserLoginForm.stories.d.ts +5 -0
- package/dist/LoginForm/index.d.ts +2 -0
- package/dist/LoginForm/types.d.ts +16 -0
- package/dist/SSO/BaseSSOForm.d.ts +8 -0
- package/dist/SSO/Okta.d.ts +3 -0
- package/dist/SSO/SSO.stories.d.ts +6 -0
- package/dist/SSO/index.d.ts +3 -0
- package/dist/SSO/types.d.ts +8 -0
- package/dist/SignUpForm/NewUserSignUp.stories.d.ts +5 -0
- package/dist/SignUpForm/SignUpForm.d.ts +3 -0
- package/dist/SignUpForm/index.d.ts +1 -0
- package/dist/SignUpForm/types.d.ts +13 -0
- package/dist/UserTenantList/CreateUser.d.ts +9 -0
- package/dist/UserTenantList/UserList.d.ts +17 -0
- package/dist/UserTenantList/UserList.stories.d.ts +5 -0
- package/dist/UserTenantList/UserModal.d.ts +8 -0
- package/dist/UserTenantList/index.d.ts +1 -0
- package/dist/UserTenantList/useDataParser.d.ts +4 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/theme.d.ts +2 -0
- package/dist/context/types.d.ts +18 -0
- package/dist/hooks/useResults.d.ts +22 -0
- package/dist/hooks/useTextSizer.d.ts +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +8 -0
- package/dist/lib/SimpleForm/CheckGroup/index.d.ts +10 -0
- package/dist/lib/SimpleForm/index.d.ts +11 -0
- package/dist/lib/SimpleForm/types.d.ts +36 -0
- package/dist/react.cjs.development.js +2 -0
- package/dist/react.cjs.development.js.map +1 -0
- package/dist/react.cjs.production.min.js +2 -0
- package/dist/react.cjs.production.min.js.map +1 -0
- package/dist/react.esm.js +2 -0
- package/dist/react.esm.js.map +1 -0
- package/dist/utils/getColumnSize.d.ts +2 -0
- package/package.json +117 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 jrea
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# @niledatabase/react
|
|
2
|
+
|
|
3
|
+
## Storybook
|
|
4
|
+
|
|
5
|
+
[Storybook](https://storybook.thenile.dev)
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
In the root of your react application, add a Nile provider. This will add a [QueryClientProvider](https://tanstack.com/query/v4/docs/quick-start) and a [CssVarsProvider](https://mui.com/joy-ui/getting-started/usage/) to your application.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { NileProvider } from '@niledatabase/react';
|
|
13
|
+
|
|
14
|
+
function App() {
|
|
15
|
+
return (
|
|
16
|
+
<NileProvider>
|
|
17
|
+
<div>Welcome to my great app</div>
|
|
18
|
+
</NileProvider>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Once added, there is a hook and components available for use. It is recommended to place the `<NileProvider />` as high up in your render tree as possible, since it contains both stying and request wrappers.
|
|
24
|
+
|
|
25
|
+
## Dependencies
|
|
26
|
+
|
|
27
|
+
### React query
|
|
28
|
+
|
|
29
|
+
The components of this library use [react-query](https://react-query.tanstack.com/) to request data. The `<QueryClientProvider />` used can be customized via the optional `QueryProvider` prop of the `<NileProvider />`.
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { QueryClient, QueryClientProvider } from 'react-query';
|
|
33
|
+
|
|
34
|
+
const queryClient = new QueryClient({
|
|
35
|
+
defaultOptions: {
|
|
36
|
+
queries: {
|
|
37
|
+
retry: false,
|
|
38
|
+
refetchOnWindowFocus: false,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
function MyQueryProvider({ children }) {
|
|
44
|
+
return (
|
|
45
|
+
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function App() {
|
|
50
|
+
return (
|
|
51
|
+
<NileProvider QueryProvider={MyQueryProvider}>
|
|
52
|
+
<div>Welcome to my great app</div>
|
|
53
|
+
</NileProvider>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### @mui/joy
|
|
59
|
+
|
|
60
|
+
Out of the box [mui joy](https://mui.com/joy-ui/getting-started/overview/) is available for use. No set up is required, simply add the dependencies to your code, then use components and functions provided by those libraries.
|
|
61
|
+
|
|
62
|
+
A custom theme can be given to the `NileProvider`, which will theme all components:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
function App() {
|
|
66
|
+
return (
|
|
67
|
+
<NileProvider theme={theme}>
|
|
68
|
+
<div>Welcome to my great app</div>
|
|
69
|
+
</NileProvider>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### useNile
|
|
75
|
+
|
|
76
|
+
A method exposing the `@niledatabase/js` instance created in `<NileProvider />`. The methods on the instance can be found in [the client src readme](../../lib/nile/src/README.md), or found in the auto-complete of visual studio code.
|
|
77
|
+
|
|
78
|
+
### Making requests
|
|
79
|
+
|
|
80
|
+
[react-query](https://react-query.tanstack.com/) should be used used to handle loading, error, and cacheing of data.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import React, { useEffect } from 'react';
|
|
84
|
+
import { useNile, Queries } from '@niledatabase/react';
|
|
85
|
+
import { useQuery } from '@tanstack/react-query';
|
|
86
|
+
|
|
87
|
+
export default function UserTable() {
|
|
88
|
+
const nile = useNile();
|
|
89
|
+
const [users, setUsers] = useState();
|
|
90
|
+
const { data: users = [] } = useQuery(Queries.ListUsers, () => nile.users.listUsers());
|
|
91
|
+
// with multiple requests
|
|
92
|
+
// const [{ data: users = [] }, { data: invites = [] }] = useQueries([
|
|
93
|
+
// { queryKey: Queries.ListUsers, queryFn: () => nile.users.listUsers({}) },
|
|
94
|
+
// { queryKey: Queries.ListInvites, queryFn: () => nile.organizations.listInvites({}) },
|
|
95
|
+
// ]);
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
users.map((user) => {
|
|
99
|
+
return <div id={user.id}>{`Email: ${user.email}`</div>;
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### UI customization
|
|
106
|
+
|
|
107
|
+
For theming and display, A combination of [mui joy](https://mui.com/joy-ui/getting-started/overview/) and [material ui](https://mui.com/material-ui/getting-started/overview/) is used. As joy approaches feature parity with material, it will be removed from this codebase. For now, there are helper functions in the theme to support both, with the theming function preferring mui joy settings and colors over material.
|
|
108
|
+
|
|
109
|
+
For details on theming, see their [theming documentation](https://mui.com/joy-ui/customization/approaches/). You can pass a custom `theme` object to the `NileProvider` and it will merge it with the combined material and joy themes in the `<NileProvider />`.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { NileProvider } from '@niledatabase/react';
|
|
113
|
+
import { extendTheme } from '@mui/joy/styles';
|
|
114
|
+
const customTheme = extendTheme({
|
|
115
|
+
colorSchemes: {
|
|
116
|
+
light: {
|
|
117
|
+
palette: {
|
|
118
|
+
primary: {
|
|
119
|
+
solidBg: '#0078D4',
|
|
120
|
+
solidHoverBg: '#106EBE',
|
|
121
|
+
solidActiveBg: '#005A9E',
|
|
122
|
+
solidDisabledBg: '#F3F2F1',
|
|
123
|
+
solidDisabledColor: '#A19F9D',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
function App() {
|
|
131
|
+
return (
|
|
132
|
+
<NileProvider theme={customTheme}>
|
|
133
|
+
<div>Welcome to my great app</div>
|
|
134
|
+
</NileProvider>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Available components
|
|
140
|
+
|
|
141
|
+
[EntityForm](./src/components/EntityForm/README.md)
|
|
142
|
+
|
|
143
|
+
[InstanceList](./src/components/InstanceList/README.md)
|
|
144
|
+
|
|
145
|
+
[LoginForm](./src/components/LoginForm/README.md)
|
|
146
|
+
|
|
147
|
+
[Metrics](./src/components/Metrics/README.md)
|
|
148
|
+
|
|
149
|
+
[OrganizationForm](./src/components/OrganizationForm/README.md)
|
|
150
|
+
|
|
151
|
+
[SignUpForm](./src/components/SignUpForm/README.md)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A component for a Google login button, according to their design language.
|
|
4
|
+
* This works when an identity provider is configured in the admin dashboard.
|
|
5
|
+
* @param props href: a string to override the URL provided by the context
|
|
6
|
+
* @returns a JSX.Element to render
|
|
7
|
+
*/
|
|
8
|
+
export default function GoogleSSOButton(props: {
|
|
9
|
+
href?: string;
|
|
10
|
+
workspace?: string;
|
|
11
|
+
database?: string;
|
|
12
|
+
newTenantName?: string;
|
|
13
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import GoogleLoginButton from './GoogleLoginButton';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof GoogleLoginButton;
|
|
6
|
+
tags: string[];
|
|
7
|
+
};
|
|
8
|
+
export default meta;
|
|
9
|
+
export declare function Basic(): React.JSX.Element;
|
|
10
|
+
export declare function BasicWithTenantNameProvider(): React.JSX.Element;
|
|
11
|
+
export declare function AlphaVersionWithOutProvider(): React.JSX.Element;
|
|
12
|
+
export declare function AlphaVersionWithProvider(): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './GoogleLoginButton';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LoginRequest } from '@niledatabase/browser';
|
|
2
|
+
import { Attribute } from '../lib/SimpleForm/types';
|
|
3
|
+
export declare type AllowedAny = any;
|
|
4
|
+
export declare type LoginInfo = {
|
|
5
|
+
email: string;
|
|
6
|
+
password: string;
|
|
7
|
+
};
|
|
8
|
+
declare type LoginSuccess = (response: LoginRequest, formValues: LoginInfo, ...args: AllowedAny) => void;
|
|
9
|
+
export interface Props {
|
|
10
|
+
beforeMutate?: (data: AllowedAny) => AllowedAny;
|
|
11
|
+
onSuccess: LoginSuccess;
|
|
12
|
+
onError?: (error: Error, data: AllowedAny) => void;
|
|
13
|
+
attributes?: Attribute[];
|
|
14
|
+
disableSSO?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SSOProvider } from '@niledatabase/browser';
|
|
3
|
+
import { OktaProps } from './types';
|
|
4
|
+
export default function BaseSSOForm(props: Omit<OktaProps, 'callbackUrl' | 'providers'> & {
|
|
5
|
+
providerName: string;
|
|
6
|
+
configurationGuide: JSX.Element;
|
|
7
|
+
config: SSOProvider;
|
|
8
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './SignUpForm';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SignUp201Response } from '@niledatabase/browser';
|
|
2
|
+
import { Attribute } from '../lib/SimpleForm/types';
|
|
3
|
+
export declare type LoginInfo = SignUp201Response;
|
|
4
|
+
declare type SignInSuccess = (response: void | SignUp201Response, formValues: LoginInfo) => void;
|
|
5
|
+
export declare type AllowedAny = any;
|
|
6
|
+
export interface Props {
|
|
7
|
+
onSuccess: SignInSuccess;
|
|
8
|
+
onError?: (e: Error, info: LoginInfo) => void;
|
|
9
|
+
beforeMutate?: (data: AllowedAny) => AllowedAny;
|
|
10
|
+
attributes?: Attribute[];
|
|
11
|
+
buttonText?: string;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SignUp201Response } from '@niledatabase/browser';
|
|
3
|
+
declare type Props = {
|
|
4
|
+
allowCreation: boolean;
|
|
5
|
+
buttonText: string;
|
|
6
|
+
onUserCreateSuccess?: (user: SignUp201Response) => void;
|
|
7
|
+
};
|
|
8
|
+
export default function CreateUser(props: Props): React.JSX.Element | null;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IdentifyUser200Response, SignUp201Response } from '@niledatabase/browser';
|
|
3
|
+
import { SxProps } from '@mui/system/styleFunctionSx/styleFunctionSx';
|
|
4
|
+
import { Theme } from '@mui/system/createTheme';
|
|
5
|
+
declare type ColumnNames = string;
|
|
6
|
+
declare type Props = {
|
|
7
|
+
data: void | IdentifyUser200Response[];
|
|
8
|
+
allowCreation?: boolean;
|
|
9
|
+
buttonText?: string;
|
|
10
|
+
onUserCreateSuccess?: (user: SignUp201Response) => void;
|
|
11
|
+
slots?: {
|
|
12
|
+
dataGrid?: SxProps<Theme>;
|
|
13
|
+
};
|
|
14
|
+
include?: ColumnNames[];
|
|
15
|
+
};
|
|
16
|
+
export default function UserList(props: Props): React.JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SignUp201Response } from '@niledatabase/browser';
|
|
3
|
+
export declare type UserFormProps = {
|
|
4
|
+
open: boolean;
|
|
5
|
+
setOpen: (open: boolean) => void;
|
|
6
|
+
refetch?: (user: SignUp201Response) => void;
|
|
7
|
+
};
|
|
8
|
+
export default function AddUser(props: UserFormProps): React.JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './UserList';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { GridColDef, GridRowsProp } from '@mui/x-data-grid';
|
|
2
|
+
import { IdentifyUser200Response } from '@niledatabase/browser';
|
|
3
|
+
export declare const internalRowId = "_nile_data_grid_identifier";
|
|
4
|
+
export default function useDataParser(data: void | IdentifyUser200Response[], include: string[]): [GridColDef[], GridRowsProp];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Client } from '@niledatabase/browser';
|
|
3
|
+
import { NileProviderProps, NileReactConfig } from './types';
|
|
4
|
+
export declare const BaseQueryProvider: ({ children, }: {
|
|
5
|
+
children: JSX.Element;
|
|
6
|
+
}) => JSX.Element;
|
|
7
|
+
export declare const NileProvider: (props: NileProviderProps) => React.JSX.Element;
|
|
8
|
+
export declare const useNileConfig: () => NileReactConfig;
|
|
9
|
+
export declare const useApi: () => Client;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Client } from '@niledatabase/browser';
|
|
2
|
+
import { Theme } from '@mui/joy/styles';
|
|
3
|
+
export interface NileReactConfig {
|
|
4
|
+
tenantId?: string;
|
|
5
|
+
basePath?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare type NileContext = NileReactConfig & {
|
|
8
|
+
api: Client;
|
|
9
|
+
theme?: Theme;
|
|
10
|
+
};
|
|
11
|
+
export declare type NileProviderProps = NileReactConfig & {
|
|
12
|
+
children: JSX.Element | JSX.Element[];
|
|
13
|
+
theme?: Theme;
|
|
14
|
+
QueryProvider?: (props: {
|
|
15
|
+
children: JSX.Element;
|
|
16
|
+
}) => JSX.Element;
|
|
17
|
+
api?: Client;
|
|
18
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GridColDef, GridRowsProp } from '@mui/x-data-grid';
|
|
2
|
+
export declare const internalRowId = "_nile_data_grid_identifier";
|
|
3
|
+
declare enum Commands {
|
|
4
|
+
insert = "INSERT",
|
|
5
|
+
update = "UPDATE",
|
|
6
|
+
delete = "DELETE",
|
|
7
|
+
create = "CREATE",
|
|
8
|
+
drop = "DROP",
|
|
9
|
+
alter = "ALTER"
|
|
10
|
+
}
|
|
11
|
+
declare type Any = any;
|
|
12
|
+
declare type ResultSet = null | Record<string, never> | {
|
|
13
|
+
command: Commands;
|
|
14
|
+
rowCount: number;
|
|
15
|
+
oid: number;
|
|
16
|
+
rows: Any[];
|
|
17
|
+
fields: Any[];
|
|
18
|
+
RowCtor: null;
|
|
19
|
+
rowAsArray: boolean;
|
|
20
|
+
};
|
|
21
|
+
export default function useResults(resultSet: null | ResultSet): [GridColDef[], GridRowsProp];
|
|
22
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function useTextSizer(): CanvasRenderingContext2D | undefined;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { NileProvider } from './context';
|
|
2
|
+
export { default as GoogleLoginButton } from './GoogleLoginButton';
|
|
3
|
+
export * from './GoogleLoginButton';
|
|
4
|
+
export * from './SignUpForm';
|
|
5
|
+
export { default as UserSignupForm } from './SignUpForm';
|
|
6
|
+
export * from './LoginForm';
|
|
7
|
+
export { default as UserLoginForm } from './LoginForm';
|
|
8
|
+
export * from './UserTenantList';
|
|
9
|
+
export { default as UserTenantList } from './UserTenantList';
|
|
10
|
+
export * from './SSO';
|
|
11
|
+
export { default as SSOForm } from './SSO';
|
|
12
|
+
export { Attribute as FormAttribute, AttributeType as FormAttributeType, } from './lib/SimpleForm/types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Attribute, DisplayProps, Options } from '../types';
|
|
3
|
+
declare type Props = {
|
|
4
|
+
attribute: Attribute;
|
|
5
|
+
display: DisplayProps;
|
|
6
|
+
options: Options;
|
|
7
|
+
helperText: string;
|
|
8
|
+
};
|
|
9
|
+
export default function CheckGroup(props: Props): React.JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Attribute } from './types';
|
|
3
|
+
export declare const getAttributeDefault: (attribute: Attribute) => string | number | boolean | string[] | number[];
|
|
4
|
+
export default function SimpleForm(props: {
|
|
5
|
+
buttonText: string;
|
|
6
|
+
cancelButton?: React.ReactNode;
|
|
7
|
+
attributes: Attribute[];
|
|
8
|
+
mutation: any;
|
|
9
|
+
loading?: boolean;
|
|
10
|
+
successMessage?: JSX.Element;
|
|
11
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare enum AttributeType {
|
|
2
|
+
Text = "text",
|
|
3
|
+
Password = "password",
|
|
4
|
+
Select = "select",
|
|
5
|
+
Number = "number",
|
|
6
|
+
Float = "float",
|
|
7
|
+
Checkbox = "checkbox",
|
|
8
|
+
Switch = "switch"
|
|
9
|
+
}
|
|
10
|
+
declare type SimplePrimitive = number | string | boolean;
|
|
11
|
+
export declare type Options = {
|
|
12
|
+
label: string;
|
|
13
|
+
value?: SimplePrimitive;
|
|
14
|
+
}[];
|
|
15
|
+
export declare type Attribute = {
|
|
16
|
+
name: string;
|
|
17
|
+
type?: AttributeType;
|
|
18
|
+
defaultValue?: SimplePrimitive;
|
|
19
|
+
options?: Options;
|
|
20
|
+
allowMultiple?: boolean;
|
|
21
|
+
label?: string;
|
|
22
|
+
required?: boolean;
|
|
23
|
+
placeholder?: string;
|
|
24
|
+
helpText?: string;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export declare type DisplayProps = {
|
|
28
|
+
key: string;
|
|
29
|
+
id: string;
|
|
30
|
+
label: string;
|
|
31
|
+
placeholder: string;
|
|
32
|
+
error?: boolean;
|
|
33
|
+
color?: 'danger';
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
};
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),r=e(t),a=e(require("@niledatabase/browser")),n=require("@mui/joy/styles"),o=require("@tanstack/react-query"),l=e(require("@mui/joy/Box")),i=e(require("@mui/joy/Button")),s=e(require("@mui/joy/Stack")),c=e(require("@mui/joy/Typography")),u=e(require("@mui/joy/Alert")),m=require("react-hook-form"),d=e(require("@mui/joy/Input")),p=e(require("@mui/joy/FormControl")),b=e(require("@mui/joy/FormHelperText")),f=e(require("@mui/icons-material/Error")),g=e(require("@mui/joy/FormLabel")),h=e(require("@mui/joy/Select")),x=e(require("@mui/joy/Option")),E=e(require("@mui/joy/Tooltip")),y=require("@mui/joy"),w=e(require("@mui/joy/Checkbox")),T=e(require("@mui/joy/List")),v=e(require("@mui/joy/ListItem")),S=require("@mui/x-data-grid"),C=e(require("@mui/icons-material/Add")),q=e(require("lodash/isNull")),k=e(require("lodash/isUndefined")),F=e(require("@mui/icons-material/CopyAll")),j=e(require("@mui/icons-material/CheckCircleOutlined")),A=n.extendTheme({cssVarPrefix:"joy",colorSchemes:{light:{palette:{primary:{50:"#fff3e4",100:"#ffe1bc",200:"#ffcd92",300:"#ffb96a",400:"#feaa51",500:"#ff9c3f",600:"#f9913d",700:"#f28239",800:"#eb7435",900:"#e05c2e"},text:{tertiary:"rgba(0 0 0 / 0.56)"}}},dark:{palette:{primary:{50:"#fff3e4",100:"#ffe1bc",200:"#ffcd92",300:"#ffb96a",400:"#feaa51",500:"#ff9c3f",600:"#f9913d",700:"#f28239",800:"#eb7435",900:"#e05c2e"},text:{tertiary:"rgba(255 255 255 / 0.5)"}}}}});const P=new o.QueryClient,O={api:a({basePath:"https://prod.thenile.dev",credentials:"include"}),basePath:""},M=t.createContext(O),{Provider:U}=M,I=({children:e})=>r.createElement(o.QueryClientProvider,{client:P},e),R=()=>t.useContext(M),V=()=>R().api;var B;function L(){return L=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var a in r)Object.prototype.hasOwnProperty.call(r,a)&&(e[a]=r[a])}return e},L.apply(this,arguments)}var D=function(e){return t.createElement("svg",L({xmlns:"http://www.w3.org/2000/svg",width:18,height:18},e),B||(B=t.createElement("g",{fillRule:"evenodd"},t.createElement("path",{fill:"#EA4335",d:"M9 3.48c1.69 0 2.83.73 3.48 1.34l2.54-2.48C13.46.89 11.43 0 9 0 5.48 0 2.44 2.02.96 4.96l2.91 2.26C4.6 5.05 6.62 3.48 9 3.48z"}),t.createElement("path",{fill:"#4285F4",d:"M17.64 9.2c0-.74-.06-1.28-.19-1.84H9v3.34h4.96c-.1.83-.64 2.08-1.84 2.92l2.84 2.2c1.7-1.57 2.68-3.88 2.68-6.62z"}),t.createElement("path",{fill:"#FBBC05",d:"M3.88 10.78A5.54 5.54 0 0 1 3.58 9c0-.62.11-1.22.29-1.78L.96 4.96A9.008 9.008 0 0 0 0 9c0 1.45.35 2.82.96 4.04l2.92-2.26z"}),t.createElement("path",{fill:"#34A853",d:"M9 18c2.43 0 4.47-.8 5.96-2.18l-2.84-2.2c-.76.53-1.78.9-3.12.9-2.38 0-4.4-1.57-5.12-3.74L.97 13.04C2.45 15.98 5.48 18 9 18z"}),t.createElement("path",{fill:"none",d:"M0 0h18v18H0z"}))))};function z(e){const{options:r,attribute:a,display:n,helperText:o}=e,{watch:i,control:u}=m.useFormContext(),d=i(a.name),p={};return o&&(p.color="danger"),t.createElement(m.Controller,{name:a.name,rules:{required:Boolean(a.required)},control:u,render:({field:e})=>t.createElement(s,null,t.createElement(g,{htmlFor:`${e.name}`},n.label),t.createElement(l,{role:"group","aria-labelledby":a.name,sx:{borderRadius:"var(--joy-radius-sm)",p:.5,border:o?"1px solid var(--joy-palette-danger-outlinedBorder)":"none"}},t.createElement(T,{orientation:"horizontal",wrap:!0,sx:{"--List-gap":"8px"}},r.map((n=>(p.id=String(n.value),t.createElement(v,{key:`${n.value}-${n.label}`},t.createElement(w,Object.assign({overlay:r.length>1},p,{checked:d.includes(n.value),disableIcon:r.length>1,variant:"soft",label:n.label,onChange:t=>{if(a.allowMultiple)if(t.target.checked)d?e.onChange(d.concat(n.value)):e.onChange([n.value]);else{const t=d.filter((e=>e!==n.value));t.length>0?e.onChange(t):e.onChange("")}else t.target.checked?e.onChange(n.value):e.onChange("")}})))))))),t.createElement(c,{sx:{color:"var(--joy-palette-danger-500)"},level:"body-sm"},o))})}var $;($=exports.FormAttributeType||(exports.FormAttributeType={})).Text="text",$.Password="password",$.Select="select",$.Number="number",$.Float="float",$.Checkbox="checkbox",$.Switch="switch";const N=e=>!0===e.allowMultiple&&!Array.isArray(e.defaultValue)&&e.defaultValue?"number"==typeof e.defaultValue?[e.defaultValue]:[String(e.defaultValue)]:e.defaultValue??"";function G(e){const{error:t,attr:a}=e;return t?r.createElement(E,{title:t,color:"danger",sx:{cursor:"pointer"}},r.createElement(g,null,a.label??a.name,r.createElement(f,{sx:{ml:.5,"--Icon-color":"#c41c1c"},fontSize:"small"}))):r.createElement(g,null,a.label??a.name)}function H(e){const{mutation:t,buttonText:a,attributes:n,cancelButton:o,loading:c,successMessage:u}=e,f=r.useMemo((()=>n.reduce(((e,t)=>(e[t.name]=N(t),e)),{})),[n]),g=m.useForm({defaultValues:f}),{register:E,control:w,handleSubmit:T,formState:{errors:v}}=g,S=r.useCallback((e=>{t.mutate(e)}),[t]);return r.createElement(m.FormProvider,Object.assign({},g),r.createElement(s,{component:"form",onSubmit:T((e=>S(e))),spacing:2},n.map((e=>{const t={},a={key:e.name,label:e.label??e.name,id:e.label??e.name,placeholder:e.placeholder??e.label??e.name,error:Boolean(v[e.name]),disabled:Boolean(e.disabled)},n=e.options??[],o=e.helpText??"";let i="";switch(e.required&&(i=v[e.name]?`${e.label??e.name} is required`:"",t.required=!0),e.type){case exports.FormAttributeType.Switch:return r.createElement(p,{key:a.key,id:a.id,orientation:"horizontal",sx:{alignItems:"center"}},r.createElement(l,null,r.createElement(G,{error:i,attr:e}),r.createElement(b,{id:`${e.name}-helper-text`},o)),r.createElement(m.Controller,{control:w,rules:{required:Boolean(e.required)},name:e.name,render:({field:t})=>{const a={};return v[e.name]&&(a.color="danger"),r.createElement(y.Switch,Object.assign({id:`switch-field-${e.name}`},a,t,{checked:Boolean(t.value),onChange:e=>{t.onChange(e.target.checked)},color:t.value?"success":"neutral",endDecorator:t.value?n[0].label:n[1].label,sx:{"--Switch-thumbSize":"28px"}}))}}));case exports.FormAttributeType.Checkbox:return r.createElement(z,{key:a.key,attribute:e,display:a,options:n,helperText:o});case exports.FormAttributeType.Select:return r.createElement(p,{key:a.key,id:a.id},r.createElement(G,{error:i,attr:e}),r.createElement(m.Controller,{control:w,rules:{required:Boolean(e.required)},name:e.name,render:({field:t})=>{const l={};return v[e.name]&&(l.color="danger"),r.createElement(s,null,r.createElement(h,Object.assign({id:`select-field-${e.name}`,placeholder:`${a.placeholder}...`},l,t,{onChange:(e,r)=>{t.onChange(r)}}),n.map((e=>r.createElement(x,{key:String(e.value??""),value:e.value},e.label)))),r.createElement(b,{id:`${e.name}-helper-text`},o))}}));case exports.FormAttributeType.Password:return r.createElement(p,{key:a.key,id:a.id},r.createElement(G,{error:i,attr:e}),r.createElement(d,Object.assign({},a,E(e.name,t),{type:exports.FormAttributeType.Password})),r.createElement(b,{id:`${e.name}-helper-text`},o));case exports.FormAttributeType.Number:return r.createElement(p,{key:a.key,id:a.id},r.createElement(G,{error:i,attr:e}),r.createElement(d,Object.assign({},a,E(e.name,t),{type:exports.FormAttributeType.Number})),r.createElement(b,{id:`${e.name}-helper-text`},o));case exports.FormAttributeType.Text:default:return r.createElement(p,{key:a.key,id:a.id},r.createElement(G,{error:i,attr:e}),r.createElement(d,Object.assign({},a,E(e.name,t))),r.createElement(b,{id:`${e.name}-helper-text`},o))}})),o?r.createElement(s,{spacing:2,direction:"row"},o,r.createElement(l,null,r.createElement(i,{type:"submit"},a))):r.createElement(l,null,r.createElement(s,{direction:"row",gap:2},r.createElement(i,{type:"submit",loading:c},a),u))))}function W(e){const{open:t,setOpen:a,refetch:n}=e,l=V(),[i,s]=r.useState(),{watch:c,register:u,handleSubmit:d}=m.useForm(),p=c("email");r.useEffect((()=>{null!=i&&s()}),[p]);const b=o.useMutation((e=>l.users.createTenantUser({signUpRequest:e})),{onSuccess(e){n&&n(e),a(!1)},onError(e){e instanceof Error&&s(e.message)}}),f=r.useCallback((async e=>{s(""),b.mutate(e)}),[b]);return r.createElement(y.Modal,{open:t},r.createElement(y.ModalDialog,null,r.createElement(y.Stack,{spacing:2},r.createElement(y.Typography,{level:"h4"},"Create user"),r.createElement(r.Fragment,null,i&&r.createElement(y.Typography,{color:"danger"},i)),r.createElement(y.Stack,{component:"form",sx:{width:"40ch"},spacing:1,onSubmit:d((e=>f(e)))},r.createElement(y.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},r.createElement(y.FormLabel,{htmlFor:"email"},"Email"),r.createElement(y.Input,Object.assign({},u("email"),{fullWidth:!0,size:"lg",id:"email",name:"email",autoComplete:"current-email",required:!0,error:Boolean(i)}))),r.createElement(y.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},r.createElement(y.FormLabel,{htmlFor:"password"},"Password"),r.createElement(y.Input,Object.assign({},u("password"),{fullWidth:!0,size:"lg",id:"password",autoComplete:"current-password",type:"password",required:!0}))),r.createElement(y.Stack,{direction:"row",sx:{pt:2},spacing:2},r.createElement(y.Button,{onClick:()=>a(!1),variant:"plain"},"Cancel"),r.createElement(y.Button,{type:"submit"},"Create"))))))}function Q(e){const{allowCreation:a,buttonText:n,onUserCreateSuccess:o}=e,[l,c]=t.useState(!1);return a?r.createElement(s,{alignItems:"flex-end",gap:1},r.createElement(W,{open:l,setOpen:c,refetch:o}),r.createElement(i,{startDecorator:r.createElement(C,null),size:"sm",onClick:()=>c(!0)},n)):null}const _=e=>Object.keys(e).reduce(((t,r)=>{const a=e[r];return a instanceof Set?t[r]=Array.from(a).join(", "):Array.isArray(a)?t[r]=a.join(", "):t[r]=a,t}),{}),J=(e,t,r)=>{if(!e)return[[],[]];const a=e.map(_),n=Object.keys(a[0]),o={},l=n?.map((e=>{const n=function(e,t,r){let a=r&&e?r.measureText(String(e)).width:50;a+=27;let n=a;return n=16+Math.ceil(r?r.measureText(t.reduce(((t,r)=>{let a=r[String(e)];return(q(a)||k(a))&&(a=""),a=a?.toString(),t.length>a.length?t:a}),"")).width:50),n<a&&(n=a),n+=8,n}(e,a,t),l=e.slice();if(r.includes(l))return null==o[l]?o[l]=l.length:o[l]+=1,{field:l.padEnd(o[l]),headerName:l.padEnd(o[l]),width:n}})).filter(Boolean)??[];return[l,a]};function K(e,r){const a=function(){const[e,r]=t.useState();return t.useEffect((()=>{const e=document.createElement("canvas").getContext("2d");e&&(e.font="18px Roboto",r(e))}),[]),e}(),[n,o]=t.useMemo((()=>J(e,a,r)),[e,a,r]);return[n,o]}function X(e){const{config:t,providerName:a,onSuccess:n,onError:l,allowEdit:i=!0,configurationGuide:m}=e,d=V(),[p,b]=r.useState(!1),[f,g]=r.useState(!1),[h,x]=r.useState(t),E=r.useRef(),y=r.useMemo((()=>{const e=[{name:"enabled",label:"Allow Okta logins",type:exports.FormAttributeType.Switch,defaultValue:!0===h?.enabled,options:[{label:"Enabled"},{label:"Disabled"}],disabled:!i},{name:"clientId",label:"Client id",type:exports.FormAttributeType.Text,defaultValue:h?.clientId??"",required:!0,disabled:!i},{name:"configUrl",label:"Config url",type:exports.FormAttributeType.Text,defaultValue:h?.configUrl??"",helpText:"The URL of the .well-known/openid-configuration for the identity provider",required:!0,disabled:!i},{name:"emailDomains",label:"Email domains",type:exports.FormAttributeType.Text,defaultValue:h?.emailDomains?.join(", ")??"",required:!0,helpText:"A comma seperated list of email domains (yourDomain.com) to be used",disabled:!i}];return h?.clientId||e.splice(2,0,{name:"clientSecret",label:"Client secret",type:exports.FormAttributeType.Password,defaultValue:"",required:!0,disabled:!i}),e}),[i,h?.clientId,h?.configUrl,h?.emailDomains,h?.enabled]),w=o.useMutation((e=>{b(!0);const t={providerName:a.toLowerCase(),updateProviderRequest:{...e,emailDomains:e.emailDomains.split(",")}};return null!=h?d.auth.updateProvider(t):d.auth.createProvider(t)}),{onSuccess:(e,t)=>{x(e),g(!0),n&&n(e,t)},onError:l,onSettled:(e,t,r)=>{b(!1),E.current&&clearTimeout(E.current),E.current=setTimeout((()=>{g(!1)}),3e3),e||(t&&!t?.message.includes("Unterminated string")||x({enabled:r.enabled,clientId:r.clientId,configUrl:r.configUrl,emailDomains:r.emailDomains.split(", ")}),g(!0),n&&n(e,r))}});return r.useEffect((()=>{})),r.createElement(s,{gap:2,position:"relative"},r.createElement(c,{level:"h4"},"Step 1"),m,r.createElement(c,{level:"h4"},"Step 2"),r.createElement(H,{mutation:w,buttonText:"Update",attributes:y,loading:p,successMessage:r.createElement(u,{color:"success",sx:{opacity:f?1:0,transition:"opacity 200ms",height:"0.9rem"},startDecorator:r.createElement(j,null)},r.createElement(c,{textAlign:"center",fontSize:"sm"},"Provider updated"))}))}function Y({callbackUrl:e}){const[t,a]=r.useState(!1),n=r.useRef();return r.useEffect((()=>{n.current&&clearTimeout(n.current),n.current=setTimeout((()=>{a(!1)}),3250)}),[t]),r.createElement(s,{gap:2},r.createElement(c,null,"In order for Okta to redirect properly, provide the following URL as the"," ",r.createElement(l,{component:"span",sx:{fontFamily:"monospace"}},"Sign-in redirect URIs")," ","in the admin configuration of your application."),r.createElement(d,{onClick:async()=>{await navigator.clipboard.writeText(e),a(!0)},sx:e=>({input:{cursor:"pointer"},span:{cursor:"pointer"},"&:hover svg":{"--Icon-color":e.palette.primary[500]}}),value:e,readOnly:!0,endDecorator:r.createElement(E,{title:"Copy Okta redirect URL"},r.createElement(l,{position:"relative",width:t?"82px":"24px",height:"24px"},r.createElement(l,{position:"absolute",top:"0",left:"0",sx:{opacity:t?0:1,transition:"opacity 300ms"}},r.createElement(F,null)),r.createElement(l,{position:"absolute",top:"0",left:"0",sx:{opacity:t?1:0,transition:"opacity 300ms"}},r.createElement(s,{direction:"row",gap:1},r.createElement(j,null),r.createElement(c,{color:"primary"},"Copied!")))))}))}exports.GoogleLoginButton=function(e){const{workspace:a,database:n,newTenantName:o}=e,{basePath:u}=(()=>{const{basePath:e,tenantId:r}=R();return t.useMemo((()=>({tenantId:r,basePath:e})),[e,r])})(),m=`${u}/workspaces/${encodeURIComponent(a??"")}/databases/${encodeURIComponent(n??"")}/users/oidc/google/login`,d=o?"?newTenant="+encodeURIComponent(o):"",p=(e?.href??m)+d;return r.createElement(l,{component:"a",href:p,display:"flex",flex:1,sx:{textDecoration:"none"}},r.createElement(l,null,r.createElement(i,{sx:{padding:0,textTransform:"initial",flex:1},"aria-label":"log in with google"},r.createElement(s,{direction:"row",alignItems:"center",p:0,flex:1,fontFamily:"Roboto, sans-serif",fontSize:"14px",display:"inline-flex",color:"rgb(255 255, 255)",boxShadow:"rgb(0 0 0 / 24%) 0px 2px 2px 0px rgb(0 0 0 / 24%) 0px 0px 1px 0px",borderRadius:"4px",border:"1px solid transparent",fontWeight:"500",sx:{backgroundColor:"rgb(66 133, 244)"}},r.createElement(l,{padding:"11px",display:"flex",border:"1px solid rgb(66, 133, 244)",borderRadius:"4px",sx:{background:"rgb(255, 255, 255)"}},r.createElement(D,{"aria-hidden":"true"})),r.createElement(l,{padding:"10px",flex:1},r.createElement(c,{sx:{color:"white"},fontWeight:700,fontFamily:"Roboto, sans-serif",fontSize:"14px",height:"20px"},"Continue with Google"))))))},exports.NileProvider=e=>{const{children:o,theme:l,tenantId:i,QueryProvider:s=I,basePath:c="https://prod.thenile.dev",api:u}=e,m=t.useMemo((()=>({api:u??a({basePath:c,credentials:"include"}),tenantId:String(i),basePath:c})),[u,c,i]);return r.createElement(s,null,r.createElement(n.CssVarsProvider,{defaultMode:"system",theme:l??A},r.createElement(U,{value:m},o)))},exports.Okta=function(e){const{callbackUrl:t,providers:a,...n}=e;if(!a)return null;const o=a?.find((e=>"okta"===e.provider));return r.createElement(X,Object.assign({},n,{config:o,providerName:"Okta",configurationGuide:r.createElement(Y,{callbackUrl:t})}))},exports.SSOForm=X,exports.SingleSignOnForm=function(e){const{attributes:t,onSuccess:a,onError:n,beforeMutate:l,nextButtonText:i="Next",loginButtonText:s="Log in",disableSSO:c=!1}=e,u=V(),[m,d]=r.useState(c?s:i),p=o.useMutation((async e=>{const t=(l&&l(e))??e;return await u.auth.login({loginRequest:{email:t.email,password:t.password},sso:!c})}),{onSuccess:(e,t)=>{e&&(e?.redirectURI?window.location.href=e.redirectURI:m!==s?d(s):a&&a(e,t))},onError:(e,t)=>{m===s?n&&n(e,t):d(s)}}),b=r.useMemo((()=>{const e=[{name:"email",label:"Email",type:exports.FormAttributeType.Text,defaultValue:"",required:!0}];return m===s&&e.push({name:"password",label:"Password",type:exports.FormAttributeType.Password,defaultValue:"",required:!0}),t&&t.length>0?e.concat(t):e}),[t,m,s]);return r.createElement(H,{mutation:p,buttonText:m,attributes:b})},exports.UserLoginForm=function(e){const[t,a]=r.useState(),{attributes:n,onSuccess:l,onError:i,beforeMutate:c}=e,m=V(),d=o.useMutation((async e=>{a(void 0);const t=(c&&c(e))??e;return await m.auth.login({loginRequest:t})}),{onSuccess:l,onError:i}),p=r.useMemo((()=>{const e=[{name:"email",label:"Email",type:exports.FormAttributeType.Text,defaultValue:"",required:!0},{name:"password",label:"Password",type:exports.FormAttributeType.Password,defaultValue:"",required:!0}];return n&&n.length>0?e.concat(n):e}),[n]);return r.createElement(s,{gap:2},t?r.createElement(u,{color:"danger"},t):null,r.createElement(H,{mutation:d,buttonText:"Log in",attributes:p}))},exports.UserSignupForm=function(e){const[t,a]=r.useState(),{buttonText:n="Sign up",onSuccess:l,onError:i,attributes:c,beforeMutate:m}=e,d=V(),p=o.useMutation((async e=>{a(void 0);const t=(m&&m(e))??e,{email:r,password:n,preferredName:o,newTenant:l,...i}=t;return Object.keys(i).length>0&&console.warn("additional metadata not supported yet."),d.auth.signUp({signUpRequest:{email:r,password:n,preferredName:o,newTenant:l}})}),{onSuccess:l,onError:(e,t)=>{a(e.message),i&&i(e,t)}}),b=r.useMemo((()=>{const e=[{name:"email",label:"Email",type:exports.FormAttributeType.Text,defaultValue:"",required:!0},{name:"password",label:"Password",type:exports.FormAttributeType.Password,defaultValue:"",required:!0}];return c&&c.length>0?e.concat(c):e}),[c]);return r.createElement(s,{gap:2},t?r.createElement(u,{color:"danger"},t):null,r.createElement(H,{mutation:p,buttonText:n,attributes:b}))},exports.UserTenantList=function(e){const{data:t,allowCreation:a=!0,buttonText:n="Add a user",onUserCreateSuccess:o,slots:l,include:i=["email","preferedName"]}=e,c={width:"100%",height:"100%",...l?.dataGrid??{}},[u,m]=K(t,i);return r.createElement(s,{flex:1},r.createElement(Q,{allowCreation:a,buttonText:n,onUserCreateSuccess:o}),r.createElement(S.DataGrid,{sx:c,rows:m,columns:u,hideFooter:!0}))};
|
|
2
|
+
//# sourceMappingURL=react.cjs.development.js.map
|