@niledatabase/react 2.5.0-alpha.0 → 3.0.0-alpha.1

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/react.esm.js CHANGED
@@ -8,6 +8,8 @@ import Box from '@mui/joy/Box';
8
8
  import Button from '@mui/joy/Button';
9
9
  import Stack from '@mui/joy/Stack';
10
10
  import Typography from '@mui/joy/Typography';
11
+ import { signIn } from 'next-auth/react';
12
+ export * from 'next-auth/react';
11
13
  import Alert from '@mui/joy/Alert';
12
14
  import { useFormContext, Controller, useForm, FormProvider } from 'react-hook-form';
13
15
  import Input from '@mui/joy/Input';
@@ -24,9 +26,6 @@ import List from '@mui/joy/List';
24
26
  import ListItem from '@mui/joy/ListItem';
25
27
  import { DataGrid } from '@mui/x-data-grid';
26
28
  import Add from '@mui/icons-material/Add';
27
- import CopyAll from '@mui/icons-material/CopyAll';
28
- import CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';
29
- export * from 'next-auth/react';
30
29
 
31
30
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
32
31
  function Themer({
@@ -42,7 +41,6 @@ function Themer({
42
41
  }), children);
43
42
  }
44
43
 
45
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
46
44
  const queryClient = /*#__PURE__*/new QueryClient();
47
45
  const defaultContext = {
48
46
  api: /*#__PURE__*/new Browser({
@@ -80,7 +78,8 @@ const NileProvider = props => {
80
78
  credentials: 'include'
81
79
  }),
82
80
  tenantId: String(tenantId),
83
- apiUrl
81
+ apiUrl,
82
+ appUrl
84
83
  };
85
84
  }, [api, apiUrl, appUrl, tenantId]);
86
85
  return /*#__PURE__*/React__default.createElement(QueryProvider, null, /*#__PURE__*/React__default.createElement(Themer, {
@@ -136,7 +135,6 @@ var SvgGoogle = function SvgGoogle(props) {
136
135
  }))));
137
136
  };
138
137
 
139
- const LOGIN_PATH = 'users/oidc/google/login';
140
138
  /**
141
139
  * A component for a Google login button, according to their design language.
142
140
  * This works when an identity provider is configured in the admin dashboard.
@@ -145,25 +143,18 @@ const LOGIN_PATH = 'users/oidc/google/login';
145
143
  */
146
144
  function GoogleSSOButton(props) {
147
145
  const {
148
- newTenantName
146
+ callbackUrl
149
147
  } = props;
150
- const {
151
- apiUrl
152
- } = useNileConfig();
153
- if (!apiUrl) {
154
- // eslint-disable-next-line no-console
155
- console.error('apiUrl is missing from <NileProvider />');
156
- }
157
- const contextHref = `${apiUrl}/${LOGIN_PATH}`;
158
- const query = newTenantName ? '?newTenant=' + encodeURIComponent(newTenantName) : '';
159
- const href = contextHref + query;
160
148
  return /*#__PURE__*/React__default.createElement(Box, {
161
- component: "a",
162
- href: href,
163
149
  display: "flex",
164
150
  flex: 1,
165
151
  sx: {
166
152
  textDecoration: 'none'
153
+ },
154
+ onClick: () => {
155
+ signIn('google', {
156
+ callbackUrl
157
+ });
167
158
  }
168
159
  }, /*#__PURE__*/React__default.createElement(Box, null, /*#__PURE__*/React__default.createElement(Button, {
169
160
  sx: {
@@ -302,6 +293,7 @@ function CheckGroup(props) {
302
293
  var AttributeType;
303
294
  (function (AttributeType) {
304
295
  AttributeType["Text"] = "text";
296
+ AttributeType["Email"] = "email";
305
297
  AttributeType["Password"] = "password";
306
298
  AttributeType["Select"] = "select";
307
299
  AttributeType["Number"] = "number";
@@ -405,7 +397,8 @@ function SimpleForm(props) {
405
397
  orientation: "horizontal",
406
398
  sx: {
407
399
  alignItems: 'center'
408
- }
400
+ },
401
+ required: attr.required
409
402
  }, /*#__PURE__*/React__default.createElement(Box, null, /*#__PURE__*/React__default.createElement(Labler, {
410
403
  error: error,
411
404
  attr: attr
@@ -448,7 +441,8 @@ function SimpleForm(props) {
448
441
  case AttributeType.Select:
449
442
  return /*#__PURE__*/React__default.createElement(FormControl, {
450
443
  key: display.key,
451
- id: display.id
444
+ id: display.id,
445
+ required: attr.required
452
446
  }, /*#__PURE__*/React__default.createElement(Labler, {
453
447
  error: error,
454
448
  attr: attr
@@ -488,7 +482,8 @@ function SimpleForm(props) {
488
482
  case AttributeType.Password:
489
483
  return /*#__PURE__*/React__default.createElement(FormControl, {
490
484
  key: display.key,
491
- id: display.id
485
+ id: display.id,
486
+ required: attr.required
492
487
  }, /*#__PURE__*/React__default.createElement(Labler, {
493
488
  error: error,
494
489
  attr: attr
@@ -502,7 +497,8 @@ function SimpleForm(props) {
502
497
  case AttributeType.Number:
503
498
  return /*#__PURE__*/React__default.createElement(FormControl, {
504
499
  key: display.key,
505
- id: display.id
500
+ id: display.id,
501
+ required: attr.required
506
502
  }, /*#__PURE__*/React__default.createElement(Labler, {
507
503
  error: error,
508
504
  attr: attr
@@ -517,7 +513,8 @@ function SimpleForm(props) {
517
513
  default:
518
514
  return /*#__PURE__*/React__default.createElement(FormControl, {
519
515
  key: display.key,
520
- id: display.id
516
+ id: display.id,
517
+ required: attr.required
521
518
  }, /*#__PURE__*/React__default.createElement(Labler, {
522
519
  error: error,
523
520
  attr: attr
@@ -555,24 +552,33 @@ function SignUpForm(props) {
555
552
  const mutation = useMutation(async _data => {
556
553
  setError(undefined);
557
554
  const possibleData = beforeMutate && beforeMutate(_data);
558
- const data = possibleData ?? _data;
555
+ const data = {
556
+ ..._data,
557
+ ...possibleData
558
+ };
559
559
  const {
560
+ name,
561
+ givenName,
562
+ familyName,
563
+ picture,
560
564
  email,
561
565
  password,
562
- preferredName,
563
- newTenant,
566
+ newTenantName,
564
567
  ...metadata
565
568
  } = data;
566
569
  if (Object.keys(metadata).length > 0) {
567
570
  // eslint-disable-next-line no-console
568
571
  console.warn('additional metadata not supported yet.');
569
572
  }
570
- return api.auth.signUp({
571
- signUpRequest: {
573
+ return await api.users.createUser({
574
+ createBasicUserRequest: {
572
575
  email,
573
576
  password,
574
- preferredName,
575
- newTenant
577
+ name,
578
+ familyName,
579
+ picture,
580
+ givenName,
581
+ newTenantName
576
582
  }
577
583
  });
578
584
  }, {
@@ -586,7 +592,7 @@ function SignUpForm(props) {
586
592
  const mainAttributes = [{
587
593
  name: 'email',
588
594
  label: 'Email',
589
- type: AttributeType.Text,
595
+ type: AttributeType.Email,
590
596
  defaultValue: '',
591
597
  required: true
592
598
  }, {
@@ -612,7 +618,7 @@ function SignUpForm(props) {
612
618
  }));
613
619
  }
614
620
 
615
- function LoginForm(props) {
621
+ function SignInForm(props) {
616
622
  const [error, setError] = React__default.useState();
617
623
  const {
618
624
  attributes,
@@ -620,14 +626,11 @@ function LoginForm(props) {
620
626
  onError,
621
627
  beforeMutate
622
628
  } = props;
623
- const api = useApi();
624
629
  const mutation = useMutation(async _data => {
625
630
  setError(undefined);
626
631
  const possibleData = beforeMutate && beforeMutate(_data);
627
632
  const data = possibleData ?? _data;
628
- return await api.auth.login({
629
- loginRequest: data
630
- });
633
+ signIn('credentials', data);
631
634
  }, {
632
635
  onSuccess,
633
636
  onError
@@ -662,78 +665,7 @@ function LoginForm(props) {
662
665
  }));
663
666
  }
664
667
 
665
- function SingleSignOnForm(props) {
666
- const {
667
- attributes,
668
- onSuccess,
669
- onError,
670
- beforeMutate,
671
- nextButtonText = 'Next',
672
- loginButtonText = 'Log in',
673
- disableSSO = false
674
- } = props;
675
- const api = useApi();
676
- const [buttonText, setButtonText] = React__default.useState(disableSSO ? loginButtonText : nextButtonText);
677
- const mutation = useMutation(async _data => {
678
- const possibleData = beforeMutate && beforeMutate(_data);
679
- const data = possibleData ?? _data;
680
- return await api.auth.login({
681
- loginRequest: {
682
- email: data.email,
683
- password: data.password
684
- },
685
- sso: !disableSSO
686
- });
687
- }, {
688
- onSuccess: (token, data) => {
689
- if (token) {
690
- if (token?.redirectURI) {
691
- window.location.href = token.redirectURI;
692
- } else if (buttonText !== loginButtonText) {
693
- setButtonText(loginButtonText);
694
- } else {
695
- onSuccess && onSuccess(token, data);
696
- }
697
- }
698
- },
699
- onError: (error, data) => {
700
- // it is possible SSO failed, so only show errors on if the password is available
701
- if (buttonText === loginButtonText) {
702
- onError && onError(error, data);
703
- } else {
704
- setButtonText(loginButtonText);
705
- }
706
- }
707
- });
708
- const completeAttributes = React__default.useMemo(() => {
709
- const mainAttributes = [{
710
- name: 'email',
711
- label: 'Email',
712
- type: AttributeType.Text,
713
- defaultValue: '',
714
- required: true
715
- }];
716
- if (buttonText === loginButtonText) {
717
- mainAttributes.push({
718
- name: 'password',
719
- label: 'Password',
720
- type: AttributeType.Password,
721
- defaultValue: '',
722
- required: true
723
- });
724
- }
725
- if (attributes && attributes.length > 0) {
726
- return mainAttributes.concat(attributes);
727
- }
728
- return mainAttributes;
729
- }, [attributes, buttonText, loginButtonText]);
730
- return /*#__PURE__*/React__default.createElement(SimpleForm, {
731
- mutation: mutation,
732
- buttonText: buttonText,
733
- attributes: completeAttributes
734
- });
735
- }
736
-
668
+ /* eslint-disable @typescript-eslint/no-explicit-any */
737
669
  function AddUser(props) {
738
670
  const {
739
671
  open,
@@ -759,7 +691,7 @@ function AddUser(props) {
759
691
  // eslint-disable-next-line react-hooks/exhaustive-deps
760
692
  }, [email]);
761
693
  const mutation = useMutation(data => api.users.createTenantUser({
762
- signUpRequest: data,
694
+ createBasicUserRequest: data,
763
695
  tenantId: String(tenantId)
764
696
  }), {
765
697
  onSuccess(data) {
@@ -948,7 +880,7 @@ function UserList(props) {
948
880
  buttonText = 'Add a user',
949
881
  onUserCreateSuccess,
950
882
  slots,
951
- include = ['email', 'preferedName']
883
+ include = ['email', 'preferredName']
952
884
  } = props;
953
885
  const dataGridSx = {
954
886
  width: '100%',
@@ -970,233 +902,5 @@ function UserList(props) {
970
902
  }));
971
903
  }
972
904
 
973
- function BaseSSOForm(props) {
974
- const {
975
- config,
976
- providerName,
977
- onSuccess,
978
- onError,
979
- allowEdit = true,
980
- configurationGuide
981
- } = props;
982
- const api = useApi();
983
- const [loading, setLoading] = React__default.useState(false);
984
- const [success, setSuccess] = React__default.useState(false);
985
- const [optimisticConfig, setConfig] = React__default.useState(config);
986
- const timer = React__default.useRef();
987
- const attributes = React__default.useMemo(() => {
988
- const attributes = [{
989
- name: 'enabled',
990
- label: 'Allow Okta logins',
991
- type: AttributeType.Switch,
992
- defaultValue: optimisticConfig?.enabled === true,
993
- options: [{
994
- label: 'Enabled'
995
- }, {
996
- label: 'Disabled'
997
- }],
998
- disabled: !allowEdit
999
- }, {
1000
- name: 'clientId',
1001
- label: 'Client id',
1002
- type: AttributeType.Text,
1003
- defaultValue: optimisticConfig?.clientId ?? '',
1004
- required: true,
1005
- disabled: !allowEdit
1006
- }, {
1007
- name: 'configUrl',
1008
- label: 'Config url',
1009
- type: AttributeType.Text,
1010
- defaultValue: optimisticConfig?.configUrl ?? '',
1011
- helpText: 'The URL of the .well-known/openid-configuration for the identity provider',
1012
- required: true,
1013
- disabled: !allowEdit
1014
- }, {
1015
- name: 'emailDomains',
1016
- label: 'Email domains',
1017
- type: AttributeType.Text,
1018
- defaultValue: optimisticConfig?.emailDomains?.join(', ') ?? '',
1019
- required: true,
1020
- helpText: 'A comma seperated list of email domains (yourDomain.com) to be used',
1021
- disabled: !allowEdit
1022
- }];
1023
- if (!optimisticConfig?.clientId) {
1024
- attributes.splice(2, 0, {
1025
- name: 'clientSecret',
1026
- label: 'Client secret',
1027
- type: AttributeType.Password,
1028
- defaultValue: '',
1029
- required: true,
1030
- disabled: !allowEdit
1031
- });
1032
- }
1033
- return attributes;
1034
- }, [allowEdit, optimisticConfig?.clientId, optimisticConfig?.configUrl, optimisticConfig?.emailDomains, optimisticConfig?.enabled]);
1035
- const handleTimer = () => {
1036
- if (timer.current) {
1037
- clearTimeout(timer.current);
1038
- }
1039
- timer.current = setTimeout(() => {
1040
- setSuccess(false);
1041
- }, 3000);
1042
- };
1043
- const mutation = useMutation(ssoRequest => {
1044
- setLoading(true);
1045
- const payload = {
1046
- providerName: providerName.toLowerCase(),
1047
- updateProviderRequest: {
1048
- ...ssoRequest,
1049
- emailDomains: ssoRequest.emailDomains.split(',')
1050
- }
1051
- };
1052
- if (optimisticConfig != null) {
1053
- return api.auth.updateProvider(payload);
1054
- } else {
1055
- return api.auth.createProvider(payload);
1056
- }
1057
- }, {
1058
- onSuccess: (data, vars) => {
1059
- setConfig(data);
1060
- setSuccess(true);
1061
- onSuccess && onSuccess(data, vars);
1062
- },
1063
- onError,
1064
- onSettled: (data, error, vars) => {
1065
- setLoading(false);
1066
- handleTimer();
1067
- if (!data) {
1068
- if (!error || error?.message.includes('Unterminated string')) {
1069
- // something unexpected happened on the BE, but it's non-fatal
1070
- setConfig({
1071
- enabled: vars.enabled,
1072
- clientId: vars.clientId,
1073
- configUrl: vars.configUrl,
1074
- emailDomains: vars.emailDomains.split(', ')
1075
- });
1076
- }
1077
- setSuccess(true);
1078
- onSuccess && onSuccess(data, vars);
1079
- }
1080
- }
1081
- });
1082
- React__default.useEffect(() => {
1083
- });
1084
- return /*#__PURE__*/React__default.createElement(Stack, {
1085
- gap: 2,
1086
- position: "relative"
1087
- }, /*#__PURE__*/React__default.createElement(Typography, {
1088
- level: "h4"
1089
- }, "Step 1"), configurationGuide, /*#__PURE__*/React__default.createElement(Typography, {
1090
- level: "h4"
1091
- }, "Step 2"), /*#__PURE__*/React__default.createElement(SimpleForm, {
1092
- mutation: mutation,
1093
- buttonText: "Update",
1094
- attributes: attributes,
1095
- loading: loading,
1096
- successMessage: /*#__PURE__*/React__default.createElement(Alert, {
1097
- color: "success",
1098
- sx: {
1099
- opacity: success ? 1 : 0,
1100
- transition: 'opacity 200ms',
1101
- height: '0.9rem'
1102
- },
1103
- startDecorator: /*#__PURE__*/React__default.createElement(CheckCircleOutlined, null)
1104
- }, /*#__PURE__*/React__default.createElement(Typography, {
1105
- textAlign: "center",
1106
- fontSize: "sm"
1107
- }, "Provider updated"))
1108
- }));
1109
- }
1110
-
1111
- function ConfigGuide({
1112
- callbackUrl
1113
- }) {
1114
- const [copied, setCopied] = React__default.useState(false);
1115
- const timer = React__default.useRef();
1116
- React__default.useEffect(() => {
1117
- if (timer.current) {
1118
- clearTimeout(timer.current);
1119
- }
1120
- timer.current = setTimeout(() => {
1121
- setCopied(false);
1122
- }, 3250);
1123
- }, [copied]);
1124
- return /*#__PURE__*/React__default.createElement(Stack, {
1125
- gap: 2
1126
- }, /*#__PURE__*/React__default.createElement(Typography, null, "In order for Okta to redirect properly, provide the following URL as the", ' ', /*#__PURE__*/React__default.createElement(Box, {
1127
- component: "span",
1128
- sx: {
1129
- fontFamily: 'monospace'
1130
- }
1131
- }, "Sign-in redirect URIs"), ' ', "in the admin configuration of your application."), /*#__PURE__*/React__default.createElement(Input, {
1132
- onClick: async () => {
1133
- if (callbackUrl) {
1134
- await navigator.clipboard.writeText(callbackUrl);
1135
- setCopied(true);
1136
- }
1137
- },
1138
- sx: theme => ({
1139
- input: {
1140
- cursor: 'pointer'
1141
- },
1142
- span: {
1143
- cursor: 'pointer'
1144
- },
1145
- '&:hover svg': {
1146
- '--Icon-color': theme.palette.primary[500]
1147
- }
1148
- }),
1149
- value: callbackUrl,
1150
- readOnly: true,
1151
- endDecorator: /*#__PURE__*/React__default.createElement(Tooltip, {
1152
- title: "Copy Okta redirect URL"
1153
- }, /*#__PURE__*/React__default.createElement(Box, {
1154
- position: "relative",
1155
- width: copied ? '82px' : '24px',
1156
- height: "24px"
1157
- }, /*#__PURE__*/React__default.createElement(Box, {
1158
- position: "absolute",
1159
- top: "0",
1160
- left: "0",
1161
- sx: {
1162
- opacity: copied ? 0 : 1,
1163
- transition: 'opacity 300ms'
1164
- }
1165
- }, /*#__PURE__*/React__default.createElement(CopyAll, null)), /*#__PURE__*/React__default.createElement(Box, {
1166
- position: "absolute",
1167
- top: "0",
1168
- left: "0",
1169
- sx: {
1170
- opacity: !copied ? 0 : 1,
1171
- transition: 'opacity 300ms'
1172
- }
1173
- }, /*#__PURE__*/React__default.createElement(Stack, {
1174
- direction: "row",
1175
- gap: 1
1176
- }, /*#__PURE__*/React__default.createElement(CheckCircleOutlined, null), /*#__PURE__*/React__default.createElement(Typography, {
1177
- color: "primary"
1178
- }, "Copied!")))))
1179
- }));
1180
- }
1181
- function Okta(props) {
1182
- const {
1183
- callbackUrl,
1184
- providers,
1185
- ...remaining
1186
- } = props;
1187
- if (!providers) {
1188
- return null;
1189
- }
1190
- const config = providers?.find(provider => provider.provider === 'okta');
1191
- return /*#__PURE__*/React__default.createElement(BaseSSOForm, {
1192
- ...remaining,
1193
- config: config,
1194
- providerName: "Okta",
1195
- configurationGuide: /*#__PURE__*/React__default.createElement(ConfigGuide, {
1196
- callbackUrl: callbackUrl
1197
- })
1198
- });
1199
- }
1200
-
1201
- export { AttributeType as FormAttributeType, GoogleSSOButton as GoogleLoginButton, NileProvider, Okta, BaseSSOForm as SSOForm, SingleSignOnForm, LoginForm as UserLoginForm, SignUpForm as UserSignupForm, UserList as UserTenantList };
905
+ export { AttributeType as FormAttributeType, GoogleSSOButton as Google, NileProvider, SignInForm, SignUpForm, UserList as UserTenantList, useApi };
1202
906
  //# sourceMappingURL=react.esm.js.map