@niledatabase/react 2.4.2-alpha.4 → 3.0.0-alpha.0

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