@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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/GoogleLoginButton/GoogleLoginButton.d.ts +13 -0
  4. package/dist/GoogleLoginButton/GoogleLoginButton.stories.d.ts +12 -0
  5. package/dist/GoogleLoginButton/index.d.ts +1 -0
  6. package/dist/LoginForm/LoginForm.d.ts +3 -0
  7. package/dist/LoginForm/SingleSignOn.d.ts +7 -0
  8. package/dist/LoginForm/UserLoginForm.stories.d.ts +5 -0
  9. package/dist/LoginForm/index.d.ts +2 -0
  10. package/dist/LoginForm/types.d.ts +16 -0
  11. package/dist/SSO/BaseSSOForm.d.ts +8 -0
  12. package/dist/SSO/Okta.d.ts +3 -0
  13. package/dist/SSO/SSO.stories.d.ts +6 -0
  14. package/dist/SSO/index.d.ts +3 -0
  15. package/dist/SSO/types.d.ts +8 -0
  16. package/dist/SignUpForm/NewUserSignUp.stories.d.ts +5 -0
  17. package/dist/SignUpForm/SignUpForm.d.ts +3 -0
  18. package/dist/SignUpForm/index.d.ts +1 -0
  19. package/dist/SignUpForm/types.d.ts +13 -0
  20. package/dist/UserTenantList/CreateUser.d.ts +9 -0
  21. package/dist/UserTenantList/UserList.d.ts +17 -0
  22. package/dist/UserTenantList/UserList.stories.d.ts +5 -0
  23. package/dist/UserTenantList/UserModal.d.ts +8 -0
  24. package/dist/UserTenantList/index.d.ts +1 -0
  25. package/dist/UserTenantList/useDataParser.d.ts +4 -0
  26. package/dist/context/index.d.ts +9 -0
  27. package/dist/context/theme.d.ts +2 -0
  28. package/dist/context/types.d.ts +18 -0
  29. package/dist/hooks/useResults.d.ts +22 -0
  30. package/dist/hooks/useTextSizer.d.ts +1 -0
  31. package/dist/index.d.ts +12 -0
  32. package/dist/index.js +8 -0
  33. package/dist/lib/SimpleForm/CheckGroup/index.d.ts +10 -0
  34. package/dist/lib/SimpleForm/index.d.ts +11 -0
  35. package/dist/lib/SimpleForm/types.d.ts +36 -0
  36. package/dist/react.cjs.development.js +2 -0
  37. package/dist/react.cjs.development.js.map +1 -0
  38. package/dist/react.cjs.production.min.js +2 -0
  39. package/dist/react.cjs.production.min.js.map +1 -0
  40. package/dist/react.esm.js +2 -0
  41. package/dist/react.esm.js.map +1 -0
  42. package/dist/utils/getColumnSize.d.ts +2 -0
  43. 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,3 @@
1
+ import React from 'react';
2
+ import { Props } from './types';
3
+ export default function LoginForm(props: Props): React.JSX.Element;
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { Props } from './types';
3
+ export default function SingleSignOnForm(props: Props & {
4
+ nextButtonText?: string;
5
+ loginButtonText?: string;
6
+ onSuccess: () => void;
7
+ }): React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { Meta } from '@storybook/react';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare function Basic(): React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ export { default } from './LoginForm';
2
+ export { default as SingleSignOnForm } from './SingleSignOn';
@@ -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,3 @@
1
+ import React from 'react';
2
+ import { OktaProps } from './types';
3
+ export default function Okta(props: OktaProps): React.JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { Meta } from '@storybook/react';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare function BasicSSO(): React.JSX.Element;
6
+ export declare function OktaSSO(): React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ export { default as Okta } from './Okta';
2
+ export { default } from './BaseSSOForm';
3
+ export * from './types';
@@ -0,0 +1,8 @@
1
+ import { SSOProvider } from '@niledatabase/browser';
2
+ export declare type OktaProps = {
3
+ providers: SSOProvider[];
4
+ callbackUrl: string;
5
+ onSuccess?: (data: unknown, variables: unknown) => void;
6
+ onError?: (e: Error) => void;
7
+ allowEdit?: boolean;
8
+ };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { Meta } from '@storybook/react';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare function Basic(): React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { Props } from './types';
3
+ export default function SignUpForm(props: Props): 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,5 @@
1
+ import React from 'react';
2
+ import { Meta } from '@storybook/react';
3
+ declare const meta: Meta;
4
+ export default meta;
5
+ export declare function Basic(): React.JSX.Element;
@@ -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,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -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;
@@ -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,8 @@
1
+
2
+ 'use strict'
3
+
4
+ if (process.env.NODE_ENV === 'production') {
5
+ module.exports = require('./react.cjs.production.min.js')
6
+ } else {
7
+ module.exports = require('./react.cjs.development.js')
8
+ }
@@ -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