@niledatabase/react 2.3.2 → 2.4.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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("@niledatabase/browser"),r=require("@tanstack/react-query"),n=require("@mui/material/CssBaseline"),a=require("@mui/joy/styles"),o=require("@mui/joy/Box"),l=require("@mui/joy/Button"),i=require("@mui/joy/Stack"),c=require("@mui/joy/Typography"),s=require("@mui/joy/Alert"),u=require("react-hook-form"),m=require("@mui/joy/Input"),d=require("@mui/joy/FormControl"),p=require("@mui/joy/FormHelperText"),b=require("@mui/icons-material/Error"),g=require("@mui/joy/FormLabel"),f=require("@mui/joy/Select"),h=require("@mui/joy/Option"),E=require("@mui/joy/Tooltip"),x=require("@mui/joy"),y=require("@mui/joy/Checkbox"),w=require("@mui/joy/List"),v=require("@mui/joy/ListItem"),T=require("@mui/x-data-grid"),S=require("@mui/icons-material/Add"),C=require("@mui/icons-material/CopyAll"),q=require("@mui/icons-material/CheckCircleOutlined");function k(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,t}var F=k(e);function A({theme:t,children:r,slotProps:o}){return e.createElement(a.CssVarsProvider,{...o,theme:t},e.createElement(n,{enableColorScheme:!0}),r)}const j=new r.QueryClient,P=e.createContext({api:new t({basePath:"https://api.thenile.dev",credentials:"include"}),basePath:""}),{Provider:I}=P,M=({children:t})=>e.createElement(r.QueryClientProvider,{client:j},t),U=()=>e.useContext(P),O=()=>{const{basePath:t,tenantId:r}=U();return e.useMemo((()=>({tenantId:r,basePath:t})),[t,r])},R=()=>U().api;var B;function V(){return V=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},V.apply(this,arguments)}var D,L=function(e){return F.createElement("svg",V({xmlns:"http://www.w3.org/2000/svg",width:18,height:18},e),B||(B=F.createElement("g",{fillRule:"evenodd"},F.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.48"}),F.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.62"}),F.createElement("path",{fill:"#FBBC05",d:"M3.88 10.78A5.5 5.5 0 0 1 3.58 9c0-.62.11-1.22.29-1.78L.96 4.96A9 9 0 0 0 0 9c0 1.45.35 2.82.96 4.04z"}),F.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 18"}),F.createElement("path",{fill:"none",d:"M0 0h18v18H0z"}))))};function $(e){const{options:t,attribute:r,display:n,helperText:a}=e,{watch:l,control:s}=u.useFormContext(),m=l(r.name),d={};return a&&(d.color="danger"),F.createElement(u.Controller,{name:r.name,rules:{required:Boolean(r.required)},control:s,render:({field:e})=>F.createElement(i,null,F.createElement(g,{htmlFor:`${e.name}`},n.label),F.createElement(o,{role:"group","aria-labelledby":r.name,sx:{borderRadius:"var(--joy-radius-sm)",p:.5,border:a?"1px solid var(--joy-palette-danger-outlinedBorder)":"none"}},F.createElement(w,{orientation:"horizontal",wrap:!0,sx:{"--List-gap":"8px"}},t.map((n=>(d.id=String(n.value),F.createElement(v,{key:`${n.value}-${n.label}`},F.createElement(y,{overlay:t.length>1,...d,checked:m.includes(n.value),disableIcon:t.length>1,variant:"soft",label:n.label,onChange:t=>{if(r.allowMultiple)if(t.target.checked)e.onChange(m?m.concat(n.value):[n.value]);else{const t=m.filter((e=>e!==n.value));e.onChange(t.length>0?t:"")}else e.onChange(t.target.checked?n.value:"")}}))))))),F.createElement(c,{sx:{color:"var(--joy-palette-danger-500)"},level:"body-sm"},a))})}exports.FormAttributeType=void 0,(D=exports.FormAttributeType||(exports.FormAttributeType={})).Text="text",D.Password="password",D.Select="select",D.Number="number",D.Float="float",D.Checkbox="checkbox",D.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 z(t){const{error:r,attr:n}=t;return r?e.createElement(E,{title:r,color:"danger",sx:{cursor:"pointer"}},e.createElement(g,null,n.label??n.name,e.createElement(b,{sx:{ml:.5,"--Icon-color":"#c41c1c"},fontSize:"small"}))):e.createElement(g,null,n.label??n.name)}function G(t){const{mutation:r,buttonText:n,attributes:a,cancelButton:c,loading:s,successMessage:b}=t,g=e.useMemo((()=>a.reduce(((e,t)=>(e[t.name]=N(t),e)),{})),[a]),E=u.useForm({defaultValues:g}),{register:y,control:w,handleSubmit:v,formState:{errors:T}}=E,S=e.useCallback((e=>{r.mutate(e)}),[r]);return e.createElement(u.FormProvider,{...E},e.createElement(i,{component:"form",onSubmit:v((e=>S(e))),spacing:2},a.map((t=>{const r={},n={key:t.name,label:t.label??t.name,id:t.label??t.name,placeholder:t.placeholder??t.label??t.name,error:Boolean(T[t.name]),disabled:Boolean(t.disabled)},a=t.options??[],l=t.helpText??"";let c="";switch(t.required&&(c=T[t.name]?`${t.label??t.name} is required`:"",r.required=!0),t.type){case exports.FormAttributeType.Switch:return e.createElement(d,{key:n.key,id:n.id,orientation:"horizontal",sx:{alignItems:"center"}},e.createElement(o,null,e.createElement(z,{error:c,attr:t}),e.createElement(p,{id:`${t.name}-helper-text`},l)),e.createElement(u.Controller,{control:w,rules:{required:Boolean(t.required)},name:t.name,render:({field:r})=>{const n={};return T[t.name]&&(n.color="danger"),e.createElement(x.Switch,{id:`switch-field-${t.name}`,...n,...r,checked:Boolean(r.value),onChange:e=>{r.onChange(e.target.checked)},color:r.value?"success":"neutral",endDecorator:r.value?a[0].label:a[1].label})}}));case exports.FormAttributeType.Checkbox:return e.createElement($,{key:n.key,attribute:t,display:n,options:a,helperText:l});case exports.FormAttributeType.Select:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(u.Controller,{control:w,rules:{required:Boolean(t.required)},name:t.name,render:({field:r})=>{const o={};T[t.name]&&(o.color="danger");const c=String(r.value);return e.createElement(i,null,e.createElement(f,{id:`select-field-${t.name}`,placeholder:`${n.placeholder}...`,...o,...r,value:c,onChange:(e,t)=>{r.onChange(t)}},a.map((t=>e.createElement(h,{key:String(t.value??""),value:t.value},t.label)))),e.createElement(p,{id:`${t.name}-helper-text`},l))}}));case exports.FormAttributeType.Password:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r),type:exports.FormAttributeType.Password}),e.createElement(p,{id:`${t.name}-helper-text`},l));case exports.FormAttributeType.Number:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r),type:exports.FormAttributeType.Number}),e.createElement(p,{id:`${t.name}-helper-text`},l));case exports.FormAttributeType.Text:default:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r)}),e.createElement(p,{id:`${t.name}-helper-text`},l))}})),c?e.createElement(i,{spacing:2,direction:"row"},c,e.createElement(o,null,e.createElement(l,{type:"submit"},n))):e.createElement(o,null,e.createElement(i,{direction:"row",gap:2},e.createElement(l,{type:"submit",loading:s},n),b))))}function H(t){const{open:n,setOpen:a,refetch:o}=t,{tenantId:l}=O(),i=R(),[c,s]=e.useState(),{watch:m,register:d,handleSubmit:p}=u.useForm(),b=m("email");e.useEffect((()=>{null!=c&&s()}),[b]);const g=r.useMutation((e=>i.users.createTenantUser({signUpRequest:e,tenantId:String(l)})),{onSuccess(e){o&&o(e),a(!1)},onError(e){e instanceof Error&&s(e.message)}}),f=e.useCallback((async e=>{s(""),g.mutate(e)}),[g]);return e.createElement(x.Modal,{open:n},e.createElement(x.ModalDialog,null,e.createElement(x.Stack,{spacing:2},e.createElement(x.Typography,{level:"h4"},"Create user"),e.createElement(e.Fragment,null,c&&e.createElement(x.Typography,{color:"danger"},c)),e.createElement(x.Stack,{component:"form",sx:{width:"40ch"},spacing:1,onSubmit:p((e=>f(e)))},e.createElement(x.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},e.createElement(x.FormLabel,{htmlFor:"email"},"Email"),e.createElement(x.Input,{...d("email"),fullWidth:!0,size:"lg",id:"email",name:"email",autoComplete:"current-email",required:!0,error:Boolean(c)})),e.createElement(x.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},e.createElement(x.FormLabel,{htmlFor:"password"},"Password"),e.createElement(x.Input,{...d("password"),fullWidth:!0,size:"lg",id:"password",autoComplete:"current-password",type:"password",required:!0})),e.createElement(x.Stack,{direction:"row",sx:{pt:2},spacing:2},e.createElement(x.Button,{onClick:()=>a(!1),variant:"plain"},"Cancel"),e.createElement(x.Button,{type:"submit"},"Create"))))))}function W(t){const{allowCreation:r,buttonText:n,onUserCreateSuccess:a}=t,[o,c]=e.useState(!1);return r?e.createElement(i,{alignItems:"flex-end",gap:1},e.createElement(H,{open:o,setOpen:c,refetch:a}),e.createElement(l,{startDecorator:e.createElement(S,null),size:"sm",onClick:()=>c(!0)},n)):null}const Q=e=>Object.keys(e).reduce(((t,r)=>{const n=e[r];return t[r]=n instanceof Set?Array.from(n).join(", "):Array.isArray(n)?n.join(", "):n,t}),{});function _(t){const{config:n,providerName:a,onSuccess:o,onError:l,allowEdit:u=!0,configurationGuide:m}=t,d=R(),[p,b]=e.useState(!1),[g,f]=e.useState(!1),[h,E]=e.useState(n),x=e.useRef(),y=e.useMemo((()=>{const e=[{name:"enabled",label:"Allow Okta logins",type:exports.FormAttributeType.Switch,defaultValue:!0===h?.enabled,options:[{label:"Enabled"},{label:"Disabled"}],disabled:!u},{name:"clientId",label:"Client id",type:exports.FormAttributeType.Text,defaultValue:h?.clientId??"",required:!0,disabled:!u},{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:!u},{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:!u}];return h?.clientId||e.splice(2,0,{name:"clientSecret",label:"Client secret",type:exports.FormAttributeType.Password,defaultValue:"",required:!0,disabled:!u}),e}),[u,h?.clientId,h?.configUrl,h?.emailDomains,h?.enabled]),w=r.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)=>{E(e),f(!0),o&&o(e,t)},onError:l,onSettled:(e,t,r)=>{b(!1),x.current&&clearTimeout(x.current),x.current=setTimeout((()=>{f(!1)}),3e3),e||(t&&!t?.message.includes("Unterminated string")||E({enabled:r.enabled,clientId:r.clientId,configUrl:r.configUrl,emailDomains:r.emailDomains.split(", ")}),f(!0),o&&o(e,r))}});return e.useEffect((()=>{})),e.createElement(i,{gap:2,position:"relative"},e.createElement(c,{level:"h4"},"Step 1"),m,e.createElement(c,{level:"h4"},"Step 2"),e.createElement(G,{mutation:w,buttonText:"Update",attributes:y,loading:p,successMessage:e.createElement(s,{color:"success",sx:{opacity:g?1:0,transition:"opacity 200ms",height:"0.9rem"},startDecorator:e.createElement(q,null)},e.createElement(c,{textAlign:"center",fontSize:"sm"},"Provider updated"))}))}function J({callbackUrl:t}){const[r,n]=e.useState(!1),a=e.useRef();return e.useEffect((()=>{a.current&&clearTimeout(a.current),a.current=setTimeout((()=>{n(!1)}),3250)}),[r]),e.createElement(i,{gap:2},e.createElement(c,null,"In order for Okta to redirect properly, provide the following URL as the"," ",e.createElement(o,{component:"span",sx:{fontFamily:"monospace"}},"Sign-in redirect URIs")," ","in the admin configuration of your application."),e.createElement(m,{onClick:async()=>{t&&(await navigator.clipboard.writeText(t),n(!0))},sx:e=>({input:{cursor:"pointer"},span:{cursor:"pointer"},"&:hover svg":{"--Icon-color":e.palette.primary[500]}}),value:t,readOnly:!0,endDecorator:e.createElement(E,{title:"Copy Okta redirect URL"},e.createElement(o,{position:"relative",width:r?"82px":"24px",height:"24px"},e.createElement(o,{position:"absolute",top:"0",left:"0",sx:{opacity:r?0:1,transition:"opacity 300ms"}},e.createElement(C,null)),e.createElement(o,{position:"absolute",top:"0",left:"0",sx:{opacity:r?1:0,transition:"opacity 300ms"}},e.createElement(i,{direction:"row",gap:1},e.createElement(q,null),e.createElement(c,{color:"primary"},"Copied!")))))}))}exports.GoogleLoginButton=function(t){const{databaseId:r,newTenantName:n}=t,{basePath:a}=O(),s=`${a}/databases/${encodeURIComponent(r??"")}/users/oidc/google/login`,u=n?"?newTenant="+encodeURIComponent(n):"";return e.createElement(o,{component:"a",href:(t?.href??s)+u,display:"flex",flex:1,sx:{textDecoration:"none"}},e.createElement(o,null,e.createElement(l,{sx:{padding:0,textTransform:"initial",flex:1},"aria-label":"log in with google"},e.createElement(i,{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)"}},e.createElement(o,{padding:"11px",display:"flex",border:"1px solid rgb(66, 133, 244)",borderRadius:"4px",sx:{background:"rgb(255, 255, 255)"}},e.createElement(L,{"aria-hidden":"true"})),e.createElement(o,{padding:"10px",flex:1},e.createElement(c,{sx:{color:"white"},fontWeight:700,fontFamily:"Roboto, sans-serif",fontSize:"14px",height:"20px"},"Continue with Google"))))))},exports.NileProvider=r=>{const{children:n,theme:a,slotProps:o,tenantId:l,QueryProvider:i=M,basePath:c="https://api.thenile.dev",api:s}=r,u=e.useMemo((()=>({api:s??new t({basePath:c,credentials:"include"}),tenantId:String(l),basePath:c})),[s,c,l]);return e.createElement(i,null,e.createElement(A,{slotProps:o?.provider,theme:a},e.createElement(I,{value:u},n)))},exports.Okta=function(t){const{callbackUrl:r,providers:n,...a}=t;if(!n)return null;const o=n?.find((e=>"okta"===e.provider));return e.createElement(_,{...a,config:o,providerName:"Okta",configurationGuide:e.createElement(J,{callbackUrl:r})})},exports.SSOForm=_,exports.SingleSignOnForm=function(t){const{attributes:n,onSuccess:a,onError:o,beforeMutate:l,nextButtonText:i="Next",loginButtonText:c="Log in",disableSSO:s=!1}=t,u=R(),[m,d]=e.useState(s?c:i),p=r.useMutation((async e=>{const t=(l&&l(e))??e;return await u.auth.login({loginRequest:{email:t.email,password:t.password},sso:!s})}),{onSuccess:(e,t)=>{e&&(e?.redirectURI?window.location.href=e.redirectURI:m!==c?d(c):a&&a(e,t))},onError:(e,t)=>{m===c?o&&o(e,t):d(c)}}),b=e.useMemo((()=>{const e=[{name:"email",label:"Email",type:exports.FormAttributeType.Text,defaultValue:"",required:!0}];return m===c&&e.push({name:"password",label:"Password",type:exports.FormAttributeType.Password,defaultValue:"",required:!0}),n&&n.length>0?e.concat(n):e}),[n,m,c]);return e.createElement(G,{mutation:p,buttonText:m,attributes:b})},exports.UserLoginForm=function(t){const[n,a]=e.useState(),{attributes:o,onSuccess:l,onError:c,beforeMutate:u}=t,m=R(),d=r.useMutation((async e=>{a(void 0);const t=(u&&u(e))??e;return await m.auth.login({loginRequest:t})}),{onSuccess:l,onError:c}),p=e.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 o&&o.length>0?e.concat(o):e}),[o]);return e.createElement(i,{gap:2},n?e.createElement(s,{color:"danger"},n):null,e.createElement(G,{mutation:d,buttonText:"Log in",attributes:p}))},exports.UserSignupForm=function(t){const[n,a]=e.useState(),{buttonText:o="Sign up",onSuccess:l,onError:c,attributes:u,beforeMutate:m}=t,d=R(),p=r.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),c&&c(e,t)}}),b=e.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 u&&u.length>0?e.concat(u):e}),[u]);return e.createElement(i,{gap:2},n?e.createElement(s,{color:"danger"},n):null,e.createElement(G,{mutation:p,buttonText:o,attributes:b}))},exports.UserTenantList=function(t){const{data:r,allowCreation:n=!0,buttonText:a="Add a user",onUserCreateSuccess:o,slots:l,include:c=["email","preferedName"]}=t,s={width:"100%",height:"100%",...l?.dataGrid??{}},[u,m]=function(t,r){const n=function(){const[t,r]=e.useState();return e.useEffect((()=>{const e=document.createElement("canvas").getContext("2d");e&&(e.font="18px Roboto",r(e))}),[]),t}(),[a,o]=e.useMemo((()=>((e,t,r)=>{if(!e)return[[],[]];const n=e.map(Q),a=Object.keys(n[0]),o={},l=a?.map((e=>{const a=function(e,t,r){let n=r&&e?r.measureText(String(e)).width:50;n+=27;let a=n;return a=16+Math.ceil(r?r.measureText(t.reduce(((t,r)=>{let n=r[String(e)];return null==n&&(n=""),n=n?.toString(),t.length>n.length?t:n}),"")).width:50),a<n&&(a=n),a+=8,a}(e,n,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:a}})).filter(Boolean)??[];return[l,n]})(t,n,r)),[t,n,r]);return[a,o]}(r,c);return e.createElement(i,{flex:1},e.createElement(W,{allowCreation:n,buttonText:a,onUserCreateSuccess:o}),e.createElement(T.DataGrid,{sx:s,rows:m,columns:u,hideFooter:!0}))};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("@niledatabase/browser"),r=require("@tanstack/react-query"),n=require("@mui/material/CssBaseline"),a=require("@mui/joy/styles"),o=require("@mui/joy/Box"),l=require("@mui/joy/Button"),i=require("@mui/joy/Stack"),c=require("@mui/joy/Typography"),s=require("@mui/joy/Alert"),u=require("react-hook-form"),m=require("@mui/joy/Input"),d=require("@mui/joy/FormControl"),p=require("@mui/joy/FormHelperText"),b=require("@mui/icons-material/Error"),g=require("@mui/joy/FormLabel"),f=require("@mui/joy/Select"),E=require("@mui/joy/Option"),h=require("@mui/joy/Tooltip"),x=require("@mui/joy"),y=require("@mui/joy/Checkbox"),w=require("@mui/joy/List"),v=require("@mui/joy/ListItem"),T=require("@mui/x-data-grid"),S=require("@mui/icons-material/Add"),C=require("@mui/icons-material/CopyAll"),q=require("@mui/icons-material/CheckCircleOutlined");function k(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,t}var F=k(e);function A({theme:t,children:r,slotProps:o}){return e.createElement(a.CssVarsProvider,{...o,theme:t},e.createElement(n,{enableColorScheme:!0}),r)}const U=new r.QueryClient,j=e.createContext({api:new t({basePath:"https://api.thenile.dev",credentials:"include"}),apiUrl:""}),{Provider:P}=j,M=({children:t})=>e.createElement(r.QueryClientProvider,{client:U},t),I=()=>e.useContext(j),O=()=>{const{apiUrl:t,tenantId:r,appUrl:n}=I();return e.useMemo((()=>({tenantId:r,apiUrl:t,appUrl:n})),[t,r,n])},R=()=>I().api;var B;function V(){return V=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},V.apply(this,arguments)}var D,L=function(e){return F.createElement("svg",V({xmlns:"http://www.w3.org/2000/svg",width:18,height:18},e),B||(B=F.createElement("g",{fillRule:"evenodd"},F.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.48"}),F.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.62"}),F.createElement("path",{fill:"#FBBC05",d:"M3.88 10.78A5.5 5.5 0 0 1 3.58 9c0-.62.11-1.22.29-1.78L.96 4.96A9 9 0 0 0 0 9c0 1.45.35 2.82.96 4.04z"}),F.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 18"}),F.createElement("path",{fill:"none",d:"M0 0h18v18H0z"}))))};function N(e){const{options:t,attribute:r,display:n,helperText:a}=e,{watch:l,control:s}=u.useFormContext(),m=l(r.name),d={};return a&&(d.color="danger"),F.createElement(u.Controller,{name:r.name,rules:{required:Boolean(r.required)},control:s,render:({field:e})=>F.createElement(i,null,F.createElement(g,{htmlFor:`${e.name}`},n.label),F.createElement(o,{role:"group","aria-labelledby":r.name,sx:{borderRadius:"var(--joy-radius-sm)",p:.5,border:a?"1px solid var(--joy-palette-danger-outlinedBorder)":"none"}},F.createElement(w,{orientation:"horizontal",wrap:!0,sx:{"--List-gap":"8px"}},t.map((n=>(d.id=String(n.value),F.createElement(v,{key:`${n.value}-${n.label}`},F.createElement(y,{overlay:t.length>1,...d,checked:m.includes(n.value),disableIcon:t.length>1,variant:"soft",label:n.label,onChange:t=>{if(r.allowMultiple)if(t.target.checked)e.onChange(m?m.concat(n.value):[n.value]);else{const t=m.filter((e=>e!==n.value));e.onChange(t.length>0?t:"")}else e.onChange(t.target.checked?n.value:"")}}))))))),F.createElement(c,{sx:{color:"var(--joy-palette-danger-500)"},level:"body-sm"},a))})}exports.FormAttributeType=void 0,(D=exports.FormAttributeType||(exports.FormAttributeType={})).Text="text",D.Password="password",D.Select="select",D.Number="number",D.Float="float",D.Checkbox="checkbox",D.Switch="switch";const $=e=>!0===e.allowMultiple&&!Array.isArray(e.defaultValue)&&e.defaultValue?"number"==typeof e.defaultValue?[e.defaultValue]:[String(e.defaultValue)]:e.defaultValue??"";function z(t){const{error:r,attr:n}=t;return r?e.createElement(h,{title:r,color:"danger",sx:{cursor:"pointer"}},e.createElement(g,null,n.label??n.name,e.createElement(b,{sx:{ml:.5,"--Icon-color":"#c41c1c"},fontSize:"small"}))):e.createElement(g,null,n.label??n.name)}function G(t){const{mutation:r,buttonText:n,attributes:a,cancelButton:c,loading:s,successMessage:b}=t,g=e.useMemo((()=>a.reduce(((e,t)=>(e[t.name]=$(t),e)),{})),[a]),h=u.useForm({defaultValues:g}),{register:y,control:w,handleSubmit:v,formState:{errors:T}}=h,S=e.useCallback((e=>{r.mutate(e)}),[r]);return e.createElement(u.FormProvider,{...h},e.createElement(i,{component:"form",onSubmit:v((e=>S(e))),spacing:2},a.map((t=>{const r={},n={key:t.name,label:t.label??t.name,id:t.label??t.name,placeholder:t.placeholder??t.label??t.name,error:Boolean(T[t.name]),disabled:Boolean(t.disabled)},a=t.options??[],l=t.helpText??"";let c="";switch(t.required&&(c=T[t.name]?`${t.label??t.name} is required`:"",r.required=!0),t.type){case exports.FormAttributeType.Switch:return e.createElement(d,{key:n.key,id:n.id,orientation:"horizontal",sx:{alignItems:"center"}},e.createElement(o,null,e.createElement(z,{error:c,attr:t}),e.createElement(p,{id:`${t.name}-helper-text`},l)),e.createElement(u.Controller,{control:w,rules:{required:Boolean(t.required)},name:t.name,render:({field:r})=>{const n={};return T[t.name]&&(n.color="danger"),e.createElement(x.Switch,{id:`switch-field-${t.name}`,...n,...r,checked:Boolean(r.value),onChange:e=>{r.onChange(e.target.checked)},color:r.value?"success":"neutral",endDecorator:r.value?a[0].label:a[1].label})}}));case exports.FormAttributeType.Checkbox:return e.createElement(N,{key:n.key,attribute:t,display:n,options:a,helperText:l});case exports.FormAttributeType.Select:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(u.Controller,{control:w,rules:{required:Boolean(t.required)},name:t.name,render:({field:r})=>{const o={};T[t.name]&&(o.color="danger");const c=String(r.value);return e.createElement(i,null,e.createElement(f,{id:`select-field-${t.name}`,placeholder:`${n.placeholder}...`,...o,...r,value:c,onChange:(e,t)=>{r.onChange(t)}},a.map((t=>e.createElement(E,{key:String(t.value??""),value:t.value},t.label)))),e.createElement(p,{id:`${t.name}-helper-text`},l))}}));case exports.FormAttributeType.Password:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r),type:exports.FormAttributeType.Password}),e.createElement(p,{id:`${t.name}-helper-text`},l));case exports.FormAttributeType.Number:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r),type:exports.FormAttributeType.Number}),e.createElement(p,{id:`${t.name}-helper-text`},l));case exports.FormAttributeType.Text:default:return e.createElement(d,{key:n.key,id:n.id},e.createElement(z,{error:c,attr:t}),e.createElement(m,{...n,...y(t.name,r)}),e.createElement(p,{id:`${t.name}-helper-text`},l))}})),c?e.createElement(i,{spacing:2,direction:"row"},c,e.createElement(o,null,e.createElement(l,{type:"submit"},n))):e.createElement(o,null,e.createElement(i,{direction:"row",gap:2},e.createElement(l,{type:"submit",loading:s},n),b))))}function H(t){const{open:n,setOpen:a,refetch:o}=t,{tenantId:l}=O(),i=R(),[c,s]=e.useState(),{watch:m,register:d,handleSubmit:p}=u.useForm(),b=m("email");e.useEffect((()=>{null!=c&&s()}),[b]);const g=r.useMutation((e=>i.users.createTenantUser({signUpRequest:e,tenantId:String(l)})),{onSuccess(e){o&&o(e),a(!1)},onError(e){e instanceof Error&&s(e.message)}}),f=e.useCallback((async e=>{s(""),g.mutate(e)}),[g]);return e.createElement(x.Modal,{open:n},e.createElement(x.ModalDialog,null,e.createElement(x.Stack,{spacing:2},e.createElement(x.Typography,{level:"h4"},"Create user"),e.createElement(e.Fragment,null,c&&e.createElement(x.Typography,{color:"danger"},c)),e.createElement(x.Stack,{component:"form",sx:{width:"40ch"},spacing:1,onSubmit:p((e=>f(e)))},e.createElement(x.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},e.createElement(x.FormLabel,{htmlFor:"email"},"Email"),e.createElement(x.Input,{...d("email"),fullWidth:!0,size:"lg",id:"email",name:"email",autoComplete:"current-email",required:!0,error:Boolean(c)})),e.createElement(x.FormControl,{sx:{"--FormHelperText-color":"var(--joy-palette-danger-500)"}},e.createElement(x.FormLabel,{htmlFor:"password"},"Password"),e.createElement(x.Input,{...d("password"),fullWidth:!0,size:"lg",id:"password",autoComplete:"current-password",type:"password",required:!0})),e.createElement(x.Stack,{direction:"row",sx:{pt:2},spacing:2},e.createElement(x.Button,{onClick:()=>a(!1),variant:"plain"},"Cancel"),e.createElement(x.Button,{type:"submit"},"Create"))))))}function W(t){const{allowCreation:r,buttonText:n,onUserCreateSuccess:a}=t,[o,c]=e.useState(!1);return r?e.createElement(i,{alignItems:"flex-end",gap:1},e.createElement(H,{open:o,setOpen:c,refetch:a}),e.createElement(l,{startDecorator:e.createElement(S,null),size:"sm",onClick:()=>c(!0)},n)):null}const Q=e=>Object.keys(e).reduce(((t,r)=>{const n=e[r];return t[r]=n instanceof Set?Array.from(n).join(", "):Array.isArray(n)?n.join(", "):n,t}),{});function _(t){const{config:n,providerName:a,onSuccess:o,onError:l,allowEdit:u=!0,configurationGuide:m}=t,d=R(),[p,b]=e.useState(!1),[g,f]=e.useState(!1),[E,h]=e.useState(n),x=e.useRef(),y=e.useMemo((()=>{const e=[{name:"enabled",label:"Allow Okta logins",type:exports.FormAttributeType.Switch,defaultValue:!0===E?.enabled,options:[{label:"Enabled"},{label:"Disabled"}],disabled:!u},{name:"clientId",label:"Client id",type:exports.FormAttributeType.Text,defaultValue:E?.clientId??"",required:!0,disabled:!u},{name:"configUrl",label:"Config url",type:exports.FormAttributeType.Text,defaultValue:E?.configUrl??"",helpText:"The URL of the .well-known/openid-configuration for the identity provider",required:!0,disabled:!u},{name:"emailDomains",label:"Email domains",type:exports.FormAttributeType.Text,defaultValue:E?.emailDomains?.join(", ")??"",required:!0,helpText:"A comma seperated list of email domains (yourDomain.com) to be used",disabled:!u}];return E?.clientId||e.splice(2,0,{name:"clientSecret",label:"Client secret",type:exports.FormAttributeType.Password,defaultValue:"",required:!0,disabled:!u}),e}),[u,E?.clientId,E?.configUrl,E?.emailDomains,E?.enabled]),w=r.useMutation((e=>{b(!0);const t={providerName:a.toLowerCase(),updateProviderRequest:{...e,emailDomains:e.emailDomains.split(",")}};return null!=E?d.auth.updateProvider(t):d.auth.createProvider(t)}),{onSuccess:(e,t)=>{h(e),f(!0),o&&o(e,t)},onError:l,onSettled:(e,t,r)=>{b(!1),x.current&&clearTimeout(x.current),x.current=setTimeout((()=>{f(!1)}),3e3),e||(t&&!t?.message.includes("Unterminated string")||h({enabled:r.enabled,clientId:r.clientId,configUrl:r.configUrl,emailDomains:r.emailDomains.split(", ")}),f(!0),o&&o(e,r))}});return e.useEffect((()=>{})),e.createElement(i,{gap:2,position:"relative"},e.createElement(c,{level:"h4"},"Step 1"),m,e.createElement(c,{level:"h4"},"Step 2"),e.createElement(G,{mutation:w,buttonText:"Update",attributes:y,loading:p,successMessage:e.createElement(s,{color:"success",sx:{opacity:g?1:0,transition:"opacity 200ms",height:"0.9rem"},startDecorator:e.createElement(q,null)},e.createElement(c,{textAlign:"center",fontSize:"sm"},"Provider updated"))}))}function J({callbackUrl:t}){const[r,n]=e.useState(!1),a=e.useRef();return e.useEffect((()=>{a.current&&clearTimeout(a.current),a.current=setTimeout((()=>{n(!1)}),3250)}),[r]),e.createElement(i,{gap:2},e.createElement(c,null,"In order for Okta to redirect properly, provide the following URL as the"," ",e.createElement(o,{component:"span",sx:{fontFamily:"monospace"}},"Sign-in redirect URIs")," ","in the admin configuration of your application."),e.createElement(m,{onClick:async()=>{t&&(await navigator.clipboard.writeText(t),n(!0))},sx:e=>({input:{cursor:"pointer"},span:{cursor:"pointer"},"&:hover svg":{"--Icon-color":e.palette.primary[500]}}),value:t,readOnly:!0,endDecorator:e.createElement(h,{title:"Copy Okta redirect URL"},e.createElement(o,{position:"relative",width:r?"82px":"24px",height:"24px"},e.createElement(o,{position:"absolute",top:"0",left:"0",sx:{opacity:r?0:1,transition:"opacity 300ms"}},e.createElement(C,null)),e.createElement(o,{position:"absolute",top:"0",left:"0",sx:{opacity:r?1:0,transition:"opacity 300ms"}},e.createElement(i,{direction:"row",gap:1},e.createElement(q,null),e.createElement(c,{color:"primary"},"Copied!")))))}))}exports.GoogleLoginButton=function(t){const{newTenantName:r}=t,{apiUrl:n}=O();n||console.error("apiUrl is missing from <NileProvider />");const a=`${n}/users/oidc/google/login`,s=r?"?newTenant="+encodeURIComponent(r):"";return e.createElement(o,{component:"a",href:a+s,display:"flex",flex:1,sx:{textDecoration:"none"}},e.createElement(o,null,e.createElement(l,{sx:{padding:0,textTransform:"initial",flex:1},"aria-label":"log in with google"},e.createElement(i,{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)"}},e.createElement(o,{padding:"11px",display:"flex",border:"1px solid rgb(66, 133, 244)",borderRadius:"4px",sx:{background:"rgb(255, 255, 255)"}},e.createElement(L,{"aria-hidden":"true"})),e.createElement(o,{padding:"10px",flex:1},e.createElement(c,{sx:{color:"white"},fontWeight:700,fontFamily:"Roboto, sans-serif",fontSize:"14px",height:"20px"},"Continue with Google"))))))},exports.NileProvider=r=>{const{children:n,theme:a,slotProps:o,tenantId:l,QueryProvider:i=M,appUrl:c,apiUrl:s="https://api.thenile.dev",api:u}=r,m=e.useMemo((()=>({api:u??new t({basePath:c,credentials:"include"}),tenantId:String(l),apiUrl:s})),[u,s,c,l]);return e.createElement(i,null,e.createElement(A,{slotProps:o?.provider,theme:a},e.createElement(P,{value:m},n)))},exports.Okta=function(t){const{callbackUrl:r,providers:n,...a}=t;if(!n)return null;const o=n?.find((e=>"okta"===e.provider));return e.createElement(_,{...a,config:o,providerName:"Okta",configurationGuide:e.createElement(J,{callbackUrl:r})})},exports.SSOForm=_,exports.SingleSignOnForm=function(t){const{attributes:n,onSuccess:a,onError:o,beforeMutate:l,nextButtonText:i="Next",loginButtonText:c="Log in",disableSSO:s=!1}=t,u=R(),[m,d]=e.useState(s?c:i),p=r.useMutation((async e=>{const t=(l&&l(e))??e;return await u.auth.login({loginRequest:{email:t.email,password:t.password},sso:!s})}),{onSuccess:(e,t)=>{e&&(e?.redirectURI?window.location.href=e.redirectURI:m!==c?d(c):a&&a(e,t))},onError:(e,t)=>{m===c?o&&o(e,t):d(c)}}),b=e.useMemo((()=>{const e=[{name:"email",label:"Email",type:exports.FormAttributeType.Text,defaultValue:"",required:!0}];return m===c&&e.push({name:"password",label:"Password",type:exports.FormAttributeType.Password,defaultValue:"",required:!0}),n&&n.length>0?e.concat(n):e}),[n,m,c]);return e.createElement(G,{mutation:p,buttonText:m,attributes:b})},exports.UserLoginForm=function(t){const[n,a]=e.useState(),{attributes:o,onSuccess:l,onError:c,beforeMutate:u}=t,m=R(),d=r.useMutation((async e=>{a(void 0);const t=(u&&u(e))??e;return await m.auth.login({loginRequest:t})}),{onSuccess:l,onError:c}),p=e.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 o&&o.length>0?e.concat(o):e}),[o]);return e.createElement(i,{gap:2},n?e.createElement(s,{color:"danger"},n):null,e.createElement(G,{mutation:d,buttonText:"Log in",attributes:p}))},exports.UserSignupForm=function(t){const[n,a]=e.useState(),{buttonText:o="Sign up",onSuccess:l,onError:c,attributes:u,beforeMutate:m}=t,d=R(),p=r.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),c&&c(e,t)}}),b=e.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 u&&u.length>0?e.concat(u):e}),[u]);return e.createElement(i,{gap:2},n?e.createElement(s,{color:"danger"},n):null,e.createElement(G,{mutation:p,buttonText:o,attributes:b}))},exports.UserTenantList=function(t){const{data:r,allowCreation:n=!0,buttonText:a="Add a user",onUserCreateSuccess:o,slots:l,include:c=["email","preferedName"]}=t,s={width:"100%",height:"100%",...l?.dataGrid??{}},[u,m]=function(t,r){const n=function(){const[t,r]=e.useState();return e.useEffect((()=>{const e=document.createElement("canvas").getContext("2d");e&&(e.font="18px Roboto",r(e))}),[]),t}(),[a,o]=e.useMemo((()=>((e,t,r)=>{if(!e)return[[],[]];const n=e.map(Q),a=Object.keys(n[0]),o={},l=a?.map((e=>{const a=function(e,t,r){let n=r&&e?r.measureText(String(e)).width:50;n+=27;let a=n;return a=16+Math.ceil(r?r.measureText(t.reduce(((t,r)=>{let n=r[String(e)];return null==n&&(n=""),n=n?.toString(),t.length>n.length?t:n}),"")).width:50),a<n&&(a=n),a+=8,a}(e,n,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:a}})).filter(Boolean)??[];return[l,n]})(t,n,r)),[t,n,r]);return[a,o]}(r,c);return e.createElement(i,{flex:1},e.createElement(W,{allowCreation:n,buttonText:a,onUserCreateSuccess:o}),e.createElement(T.DataGrid,{sx:s,rows:m,columns:u,hideFooter:!0}))};
2
2
  //# sourceMappingURL=react.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.cjs.production.min.js","sources":["../src/context/theme.tsx","../src/context/index.tsx","../src/GoogleLoginButton/google.svg","../src/lib/SimpleForm/types.ts","../src/lib/SimpleForm/CheckGroup/index.tsx","../src/lib/SimpleForm/index.tsx","../src/UserTenantList/UserModal.tsx","../src/UserTenantList/CreateUser.tsx","../src/UserTenantList/useDataParser.ts","../src/SSO/BaseSSOForm.tsx","../src/SSO/Okta.tsx","../src/GoogleLoginButton/GoogleLoginButton.tsx","../src/LoginForm/SingleSignOn.tsx","../src/LoginForm/LoginForm.tsx","../src/SignUpForm/SignUpForm.tsx","../src/UserTenantList/UserList.tsx","../src/hooks/useTextSizer.ts","../src/utils/getColumnSize.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nimport React from 'react';\nimport CssBaseline from '@mui/material/CssBaseline';\nimport { Theme } from '@mui/joy/styles';\nimport { CssVarsProvider as JoyCssVarsProvider } from '@mui/joy/styles';\n\nexport default function Themer({\n theme,\n children,\n slotProps,\n}: {\n theme?: Theme;\n children: JSX.Element;\n slotProps?: Record<string, string>;\n}) {\n return (\n <JoyCssVarsProvider {...slotProps} theme={theme}>\n <CssBaseline enableColorScheme />\n {children}\n </JoyCssVarsProvider>\n );\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nimport React, { useMemo, createContext, useContext } from 'react';\nimport Browser from '@niledatabase/browser';\nimport { QueryClientProvider, QueryClient } from '@tanstack/react-query';\n\nimport ThemeProvider from './theme';\nimport { NileContext, NileProviderProps, NileReactConfig } from './types';\n\nconst queryClient = new QueryClient();\n\nconst defaultContext: NileContext = {\n api: new Browser({\n basePath: 'https://api.thenile.dev',\n credentials: 'include',\n }),\n basePath: '',\n};\n\nconst context = createContext<NileContext>(defaultContext);\n\nconst { Provider } = context;\n\nexport const BaseQueryProvider = ({\n children,\n}: {\n children: JSX.Element;\n}): JSX.Element => {\n return (\n <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n );\n};\n\nexport const NileProvider = (props: NileProviderProps) => {\n const {\n children,\n theme,\n slotProps,\n tenantId,\n QueryProvider = BaseQueryProvider,\n basePath = 'https://api.thenile.dev',\n api,\n } = props;\n\n const values = useMemo<NileContext>((): NileContext => {\n return {\n api:\n api ??\n new Browser({\n basePath,\n credentials: 'include',\n }),\n tenantId: String(tenantId),\n basePath,\n };\n }, [api, basePath, tenantId]);\n\n return (\n <QueryProvider>\n <ThemeProvider slotProps={slotProps?.provider} theme={theme}>\n <Provider value={values}>{children}</Provider>\n </ThemeProvider>\n </QueryProvider>\n );\n};\n\nconst useNileContext = (): NileContext => {\n return useContext(context);\n};\n\nexport const useNileConfig = (): NileReactConfig => {\n const { basePath, tenantId } = useNileContext();\n return useMemo(\n () => ({\n tenantId,\n basePath,\n }),\n [basePath, tenantId]\n );\n};\n\nexport const useApi = (): Browser => {\n return useNileContext().api;\n};\n","<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\">\n <g fill=\"#000\" fill-rule=\"evenodd\">\n <path 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\" fill=\"#EA4335\" />\n <path 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\" fill=\"#4285F4\" />\n <path 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\" fill=\"#FBBC05\" />\n <path 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\" fill=\"#34A853\" />\n <path fill=\"none\" d=\"M0 0h18v18H0z\" />\n </g>\n</svg>","export enum AttributeType {\n Text = 'text',\n Password = 'password',\n Select = 'select',\n Number = 'number',\n Float = 'float',\n Checkbox = 'checkbox',\n Switch = 'switch',\n}\ntype SimplePrimitive = number | string | boolean;\n\n// possibly no value for `<Switch/>`\nexport type Options = { label: string; value?: SimplePrimitive }[];\nexport type Attribute = {\n name: string;\n type?: AttributeType;\n defaultValue?: SimplePrimitive;\n options?: Options;\n allowMultiple?: boolean;\n label?: string;\n required?: boolean;\n placeholder?: string;\n helpText?: string;\n disabled?: boolean;\n};\n\nexport type DisplayProps = {\n key: string;\n id: string;\n label: string;\n placeholder: string;\n error?: boolean;\n color?: 'danger';\n disabled?: boolean;\n};\n","import * as React from 'react';\nimport Box from '@mui/joy/Box';\nimport Checkbox from '@mui/joy/Checkbox';\nimport List from '@mui/joy/List';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport Stack from '@mui/joy/Stack';\nimport FormLabel from '@mui/joy/FormLabel';\nimport ListItem from '@mui/joy/ListItem';\nimport Typography from '@mui/joy/Typography';\n\nimport { Attribute, DisplayProps, Options } from '../types';\n\ntype Props = {\n attribute: Attribute;\n display: DisplayProps;\n options: Options;\n helperText: string;\n};\nexport default function CheckGroup(props: Props) {\n const { options, attribute, display, helperText } = props;\n const { watch, control } = useFormContext();\n const currentVals = watch(attribute.name);\n const checkProps: { color?: 'danger'; id?: string } = {};\n if (helperText) {\n checkProps.color = 'danger';\n }\n return (\n <Controller\n name={attribute.name}\n rules={{ required: Boolean(attribute.required) }}\n control={control}\n render={({ field }) => {\n return (\n <Stack>\n <FormLabel htmlFor={`${field.name}`}>{display.label}</FormLabel>\n <Box\n role=\"group\"\n aria-labelledby={attribute.name}\n sx={{\n borderRadius: 'var(--joy-radius-sm)',\n p: 0.5,\n border: helperText\n ? '1px solid var(--joy-palette-danger-outlinedBorder)'\n : 'none',\n }}\n >\n <List\n orientation=\"horizontal\"\n wrap\n sx={{\n '--List-gap': '8px',\n }}\n >\n {options.map((item) => {\n checkProps.id = String(item.value);\n return (\n <ListItem key={`${item.value}-${item.label}`}>\n <Checkbox\n overlay={options.length > 1}\n {...checkProps}\n checked={currentVals.includes(item.value)}\n disableIcon={options.length > 1}\n variant=\"soft\"\n label={item.label}\n onChange={(event) => {\n if (attribute.allowMultiple) {\n if (event.target.checked) {\n if (!currentVals) {\n field.onChange([item.value]);\n } else {\n field.onChange(currentVals.concat(item.value));\n }\n } else {\n const remaining = currentVals.filter(\n (val: string | number) => val !== item.value\n );\n if (remaining.length > 0) {\n field.onChange(remaining);\n } else {\n field.onChange('');\n }\n }\n } else {\n if (event.target.checked) {\n field.onChange(item.value);\n } else {\n field.onChange('');\n }\n }\n }}\n />\n </ListItem>\n );\n })}\n </List>\n </Box>\n <Typography\n sx={{ color: 'var(--joy-palette-danger-500)' }}\n level=\"body-sm\"\n >\n {helperText}\n </Typography>\n </Stack>\n );\n }}\n />\n );\n}\n","import React from 'react';\nimport Button from '@mui/joy/Button';\nimport { Controller, FormProvider, useForm } from 'react-hook-form';\nimport Stack from '@mui/joy/Stack';\nimport Input from '@mui/joy/Input';\nimport FormControl from '@mui/joy/FormControl';\nimport FormHelperText from '@mui/joy/FormHelperText';\nimport Error from '@mui/icons-material/Error';\nimport FormLabel from '@mui/joy/FormLabel';\nimport Select from '@mui/joy/Select';\nimport Option from '@mui/joy/Option';\nimport Box from '@mui/joy/Box';\nimport Tooltip from '@mui/joy/Tooltip';\nimport { Switch } from '@mui/joy';\n\nimport CheckGroup from './CheckGroup';\nimport { Attribute, AttributeType, DisplayProps } from './types';\n\ntype AttrMap = {\n [key: string]: string | number | boolean | string[] | number[];\n};\n\ntype FieldConfig = {\n required?: boolean;\n};\n\nexport const getAttributeDefault = (\n attribute: Attribute\n): string | number | boolean | string[] | number[] => {\n // have to look to see if it is an enum\n if (attribute.allowMultiple === true) {\n if (!Array.isArray(attribute.defaultValue) && attribute.defaultValue) {\n if (typeof attribute.defaultValue === 'number') {\n return [attribute.defaultValue];\n }\n return [String(attribute.defaultValue)];\n }\n }\n return attribute.defaultValue ?? '';\n};\n\nfunction Labler(props: { error?: string; attr: Attribute }) {\n const { error, attr } = props;\n if (error) {\n return (\n <Tooltip title={error} color=\"danger\" sx={{ cursor: 'pointer' }}>\n <FormLabel>\n {attr.label ?? attr.name}\n <Error sx={{ ml: 0.5, '--Icon-color': '#c41c1c' }} fontSize=\"small\" />\n </FormLabel>\n </Tooltip>\n );\n }\n return <FormLabel>{attr.label ?? attr.name}</FormLabel>;\n}\nexport default function SimpleForm(props: {\n buttonText: string;\n cancelButton?: React.ReactNode;\n attributes: Attribute[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mutation: any;\n loading?: boolean;\n successMessage?: JSX.Element;\n}) {\n const {\n mutation,\n buttonText,\n attributes,\n cancelButton,\n loading,\n successMessage,\n } = props;\n\n const defaultValues = React.useMemo(\n () =>\n attributes.reduce((accum: AttrMap, attr: Attribute) => {\n accum[attr.name] = getAttributeDefault(attr);\n return accum;\n }, {}),\n [attributes]\n );\n\n const methods = useForm({\n defaultValues,\n });\n\n const {\n register,\n control,\n handleSubmit,\n formState: { errors },\n } = methods;\n const onSubmit = React.useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (data: any) => {\n mutation.mutate(data);\n },\n [mutation]\n );\n\n return (\n <FormProvider {...methods}>\n <Stack\n component=\"form\"\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onSubmit={handleSubmit((data) => onSubmit(data as any))}\n spacing={2}\n >\n {attributes.map((attr: Attribute): React.ReactNode => {\n const fieldConfig: FieldConfig = {};\n const display: DisplayProps = {\n key: attr.name,\n label: attr.label ?? attr.name,\n id: attr.label ?? attr.name,\n placeholder: attr.placeholder ?? attr.label ?? attr.name,\n error: Boolean(errors[attr.name]),\n disabled: Boolean(attr.disabled),\n };\n const options = attr.options ?? [];\n const helperText = attr.helpText ?? '';\n let error = '';\n\n if (attr.required) {\n error = errors[attr.name]\n ? `${attr.label ?? attr.name} is required`\n : '';\n fieldConfig.required = true;\n }\n\n switch (attr.type) {\n case AttributeType.Switch:\n return (\n <FormControl\n key={display.key}\n id={display.id}\n orientation=\"horizontal\"\n sx={{ alignItems: 'center' }}\n >\n <Box>\n <Labler error={error} attr={attr} />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </Box>\n <Controller\n control={control}\n rules={{ required: Boolean(attr.required) }}\n name={attr.name}\n render={({ field }) => {\n const color: { color?: 'danger' } = {};\n if (errors[attr.name]) {\n color.color = 'danger';\n }\n return (\n <Switch\n id={`switch-field-${attr.name}`}\n {...color}\n {...field}\n checked={Boolean(field.value)}\n onChange={(event) => {\n field.onChange(event.target.checked);\n }}\n color={field.value ? 'success' : 'neutral'}\n endDecorator={\n field.value ? options[0].label : options[1].label\n }\n />\n );\n }}\n />\n </FormControl>\n );\n case AttributeType.Checkbox:\n return (\n <CheckGroup\n key={display.key}\n attribute={attr}\n display={display}\n options={options}\n helperText={helperText}\n />\n );\n case AttributeType.Select:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Controller\n control={control}\n rules={{ required: Boolean(attr.required) }}\n name={attr.name}\n render={({ field }) => {\n const color: { color?: 'danger' } = {};\n if (errors[attr.name]) {\n color.color = 'danger';\n }\n const value = String(field.value);\n return (\n <Stack>\n <Select\n id={`select-field-${attr.name}`}\n placeholder={`${display.placeholder}...`}\n {...color}\n {...field}\n value={value}\n onChange={(_, newValue) => {\n field.onChange(newValue);\n }}\n >\n {options.map((option) => {\n return (\n <Option\n key={String(option.value ?? '')}\n value={option.value}\n >\n {option.label}\n </Option>\n );\n })}\n </Select>\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </Stack>\n );\n }}\n />\n </FormControl>\n );\n case AttributeType.Password:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input\n {...display}\n {...register(attr.name, fieldConfig)}\n type={AttributeType.Password}\n />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n case AttributeType.Number:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input\n {...display}\n {...register(attr.name, fieldConfig)}\n type={AttributeType.Number}\n />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n\n case AttributeType.Text:\n default:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input {...display} {...register(attr.name, fieldConfig)} />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n }\n })}\n {cancelButton ? (\n <Stack spacing={2} direction=\"row\">\n {cancelButton}\n <Box>\n <Button type=\"submit\">{buttonText}</Button>\n </Box>\n </Stack>\n ) : (\n <Box>\n <Stack direction=\"row\" gap={2}>\n <Button type=\"submit\" loading={loading}>\n {buttonText}\n </Button>\n {successMessage}\n </Stack>\n </Box>\n )}\n </Stack>\n </FormProvider>\n );\n}\n","import React from 'react';\nimport {\n Button,\n Stack,\n Typography,\n FormControl,\n FormLabel,\n Input,\n Modal,\n ModalDialog,\n} from '@mui/joy';\nimport { useForm } from 'react-hook-form';\nimport { useMutation } from '@tanstack/react-query';\nimport { SignUp201Response, SignUpRequest } from '@niledatabase/browser';\n\nimport { useApi, useNileConfig } from '../context';\n\nexport type UserFormProps = {\n open: boolean;\n setOpen: (open: boolean) => void;\n refetch?: (user: SignUp201Response) => void;\n};\n\nexport default function AddUser(props: UserFormProps) {\n const { open, setOpen, refetch } = props;\n const { tenantId } = useNileConfig();\n const api = useApi();\n const [errorText, setErrorText] = React.useState<void | string>();\n const { watch, register, handleSubmit } = useForm<SignUpRequest>();\n const email = watch('email');\n\n React.useEffect(() => {\n if (errorText != null) {\n setErrorText();\n }\n // if email changes, no more error\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [email]);\n\n const mutation = useMutation(\n (data: SignUpRequest) =>\n api.users.createTenantUser({\n signUpRequest: data,\n tenantId: String(tenantId),\n }),\n {\n onSuccess(data) {\n refetch && refetch(data);\n setOpen(false);\n },\n onError(e) {\n if (e instanceof Error) {\n setErrorText(e.message);\n }\n },\n }\n );\n\n const handleUpdate = React.useCallback(\n async (data: SignUpRequest) => {\n setErrorText('');\n mutation.mutate(data);\n },\n [mutation]\n );\n\n return (\n <Modal open={open}>\n <ModalDialog>\n <Stack spacing={2}>\n <Typography level=\"h4\">Create user</Typography>\n <>\n {errorText && <Typography color=\"danger\">{errorText}</Typography>}\n </>\n <Stack\n component=\"form\"\n sx={{\n width: '40ch',\n }}\n spacing={1}\n onSubmit={handleSubmit((data) =>\n handleUpdate(data as SignUpRequest)\n )}\n >\n <FormControl\n sx={{\n '--FormHelperText-color': 'var(--joy-palette-danger-500)',\n }}\n >\n <FormLabel htmlFor=\"email\">Email</FormLabel>\n <Input\n {...register('email')}\n fullWidth\n size=\"lg\"\n id=\"email\"\n name=\"email\"\n autoComplete=\"current-email\"\n required\n error={Boolean(errorText)}\n />\n </FormControl>\n <FormControl\n sx={{\n '--FormHelperText-color': 'var(--joy-palette-danger-500)',\n }}\n >\n <FormLabel htmlFor=\"password\">Password</FormLabel>\n <Input\n {...register('password')}\n fullWidth\n size=\"lg\"\n id=\"password\"\n autoComplete=\"current-password\"\n type=\"password\"\n required\n />\n </FormControl>\n <Stack direction=\"row\" sx={{ pt: 2 }} spacing={2}>\n <Button onClick={() => setOpen(false)} variant=\"plain\">\n Cancel\n </Button>\n <Button type=\"submit\">Create</Button>\n </Stack>\n </Stack>\n </Stack>\n </ModalDialog>\n </Modal>\n );\n}\n","import React from 'react';\nimport Button from '@mui/joy/Button';\nimport Stack from '@mui/joy/Stack';\nimport { useState } from 'react';\nimport Add from '@mui/icons-material/Add';\nimport { SignUp201Response } from '@niledatabase/browser';\n\nimport UserModal from './UserModal';\n\ntype Props = {\n allowCreation: boolean;\n buttonText: string;\n onUserCreateSuccess?: (user: SignUp201Response) => void;\n};\nexport default function CreateUser(props: Props) {\n const { allowCreation, buttonText, onUserCreateSuccess } = props;\n const [open, setOpen] = useState(false);\n if (!allowCreation) {\n return null;\n }\n\n return (\n <Stack alignItems=\"flex-end\" gap={1}>\n <UserModal open={open} setOpen={setOpen} refetch={onUserCreateSuccess} />\n <Button startDecorator={<Add />} size=\"sm\" onClick={() => setOpen(true)}>\n {buttonText}\n </Button>\n </Stack>\n );\n}\n","import { useMemo } from 'react';\nimport { GridColDef, GridRowsProp } from '@mui/x-data-grid';\nimport { User } from '@niledatabase/browser';\n\nimport getColumnSize from '../utils/getColumnSize';\nimport useTextSizer from '../hooks/useTextSizer';\n\nexport const internalRowId = '_nile_data_grid_identifier';\n\ntype Cleaned = { [key: string]: string | Set<string> };\n\nconst makeRenderable = (vals: User) => {\n return Object.keys(vals).reduce((cleaned: Cleaned, key) => {\n const val = (vals as Cleaned)[key];\n if (val instanceof Set) {\n cleaned[key] = Array.from(val).join(', ');\n } else if (Array.isArray(val)) {\n cleaned[key] = val.join(', ');\n } else {\n cleaned[key] = val;\n }\n return cleaned;\n }, {});\n};\n\nconst parseResults = (\n data: void | User[],\n ctx: CanvasRenderingContext2D | void,\n include: string[]\n): [GridColDef[], GridRowsProp] => {\n if (!data) {\n return [[], []];\n }\n const rows = data.map(makeRenderable);\n const fields = Object.keys(rows[0]);\n\n const existentCols: { [key: string]: number } = {};\n\n const mapCols = (col: string): GridColDef | void => {\n const width = getColumnSize(col, rows, ctx);\n const name = col.slice();\n if (include.includes(name)) {\n // add spaces to the end of column names so they are not duplicated in the UI\n if (existentCols[name] == null) {\n existentCols[name] = name.length;\n } else {\n existentCols[name] += 1;\n }\n return {\n field: name.padEnd(existentCols[name]),\n headerName: name.padEnd(existentCols[name]),\n width,\n };\n }\n };\n const cols = fields?.map(mapCols).filter(Boolean) ?? [];\n\n return [cols as GridColDef[], rows];\n};\n\nexport default function useDataParser(\n data: void | User[],\n include: string[]\n): [GridColDef[], GridRowsProp] {\n const ctx = useTextSizer();\n const [cols, rows] = useMemo(\n () => parseResults(data, ctx, include),\n [data, ctx, include]\n );\n return [cols, rows];\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport { UpdateProviderRequest, SSOProvider } from '@niledatabase/browser';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\nimport Alert from '@mui/joy/Alert';\nimport CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';\n\nimport SimpleForm from '../lib/SimpleForm';\nimport { useApi } from '../context';\nimport { Attribute, AttributeType } from '../lib/SimpleForm/types';\n\nimport { OktaProps } from './types';\n\ntype SSOFormRequest = Omit<UpdateProviderRequest, 'emailDomains'> & {\n emailDomains: string;\n};\nexport default function BaseSSOForm(\n props: Omit<OktaProps, 'callbackUrl' | 'providers'> & {\n providerName: string;\n configurationGuide?: JSX.Element;\n config?: SSOProvider;\n }\n) {\n const {\n config,\n providerName,\n onSuccess,\n onError,\n allowEdit = true,\n configurationGuide,\n } = props;\n\n const api = useApi();\n const [loading, setLoading] = React.useState(false);\n const [success, setSuccess] = React.useState(false);\n const [optimisticConfig, setConfig] = React.useState<SSOProvider | void>(\n config\n );\n const timer = React.useRef<NodeJS.Timeout>();\n const attributes = React.useMemo(() => {\n const attributes: Attribute[] = [\n {\n name: 'enabled',\n label: 'Allow Okta logins',\n type: AttributeType.Switch,\n defaultValue: optimisticConfig?.enabled === true,\n options: [\n {\n label: 'Enabled',\n },\n {\n label: 'Disabled',\n },\n ],\n disabled: !allowEdit,\n },\n {\n name: 'clientId',\n label: 'Client id',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.clientId ?? '',\n required: true,\n disabled: !allowEdit,\n },\n {\n name: 'configUrl',\n label: 'Config url',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.configUrl ?? '',\n helpText:\n 'The URL of the .well-known/openid-configuration for the identity provider',\n required: true,\n disabled: !allowEdit,\n },\n {\n name: 'emailDomains',\n label: 'Email domains',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.emailDomains?.join(', ') ?? '',\n required: true,\n helpText:\n 'A comma seperated list of email domains (yourDomain.com) to be used',\n disabled: !allowEdit,\n },\n ];\n if (!optimisticConfig?.clientId) {\n attributes.splice(2, 0, {\n name: 'clientSecret',\n label: 'Client secret',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n disabled: !allowEdit,\n });\n }\n return attributes;\n }, [\n allowEdit,\n optimisticConfig?.clientId,\n optimisticConfig?.configUrl,\n optimisticConfig?.emailDomains,\n optimisticConfig?.enabled,\n ]);\n\n const handleTimer = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n timer.current = setTimeout(() => {\n setSuccess(false);\n }, 3000);\n };\n\n const mutation = useMutation(\n (ssoRequest: SSOFormRequest) => {\n setLoading(true);\n const payload = {\n providerName: providerName.toLowerCase(),\n updateProviderRequest: {\n ...ssoRequest,\n emailDomains: ssoRequest.emailDomains.split(','),\n },\n };\n if (optimisticConfig != null) {\n return api.auth.updateProvider(payload);\n } else {\n return api.auth.createProvider(payload);\n }\n },\n {\n onSuccess: (data, vars) => {\n setConfig(data);\n setSuccess(true);\n onSuccess && onSuccess(data, vars);\n },\n onError,\n onSettled: (data, error, vars) => {\n setLoading(false);\n handleTimer();\n if (!data) {\n if (!error || error?.message.includes('Unterminated string')) {\n // something unexpected happened on the BE, but it's non-fatal\n setConfig({\n enabled: vars.enabled,\n clientId: vars.clientId,\n configUrl: vars.configUrl,\n emailDomains: vars.emailDomains.split(', '),\n } as SSOProvider);\n }\n setSuccess(true);\n onSuccess && onSuccess(data, vars);\n }\n },\n }\n );\n\n React.useEffect(() => {\n () => {\n clearTimeout(timer.current);\n };\n });\n\n return (\n <Stack gap={2} position=\"relative\">\n <Typography level=\"h4\">Step 1</Typography>\n {configurationGuide}\n <Typography level=\"h4\">Step 2</Typography>\n <SimpleForm\n mutation={mutation}\n buttonText=\"Update\"\n attributes={attributes}\n loading={loading}\n successMessage={\n <Alert\n color=\"success\"\n sx={{\n opacity: success ? 1 : 0,\n transition: 'opacity 200ms',\n height: '0.9rem',\n }}\n startDecorator={<CheckCircleOutlined />}\n >\n <Typography textAlign=\"center\" fontSize=\"sm\">\n Provider updated\n </Typography>\n </Alert>\n }\n />\n </Stack>\n );\n}\n","import React from 'react';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\nimport Box from '@mui/joy/Box';\nimport Input from '@mui/joy/Input';\nimport CopyAll from '@mui/icons-material/CopyAll';\nimport { Theme } from '@mui/joy/styles';\nimport Tooltip from '@mui/joy/Tooltip';\nimport CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';\nimport { SSOProvider } from '@niledatabase/browser';\n\nimport BaseSSOForm from './BaseSSOForm';\nimport { OktaProps } from './types';\n\nfunction ConfigGuide({ callbackUrl }: { callbackUrl?: string }) {\n const [copied, setCopied] = React.useState(false);\n\n const timer = React.useRef<NodeJS.Timeout>();\n React.useEffect(() => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n timer.current = setTimeout(() => {\n setCopied(false);\n }, 3250);\n () => {\n clearTimeout(timer.current);\n };\n }, [copied]);\n return (\n <Stack gap={2}>\n <Typography>\n In order for Okta to redirect properly, provide the following URL as the{' '}\n <Box component=\"span\" sx={{ fontFamily: 'monospace' }}>\n Sign-in redirect URIs\n </Box>{' '}\n in the admin configuration of your application.\n </Typography>\n <Input\n onClick={async () => {\n if (callbackUrl) {\n await navigator.clipboard.writeText(callbackUrl);\n setCopied(true);\n }\n }}\n sx={(theme: Theme) => ({\n input: {\n cursor: 'pointer',\n },\n span: {\n cursor: 'pointer',\n },\n '&:hover svg': {\n '--Icon-color': theme.palette.primary[500],\n },\n })}\n value={callbackUrl}\n readOnly={true}\n endDecorator={\n <Tooltip title=\"Copy Okta redirect URL\">\n <Box\n position=\"relative\"\n width={copied ? '82px' : '24px'}\n height=\"24px\"\n >\n <Box\n position=\"absolute\"\n top=\"0\"\n left=\"0\"\n sx={{\n opacity: copied ? 0 : 1,\n transition: 'opacity 300ms',\n }}\n >\n <CopyAll />\n </Box>\n <Box\n position=\"absolute\"\n top=\"0\"\n left=\"0\"\n sx={{ opacity: !copied ? 0 : 1, transition: 'opacity 300ms' }}\n >\n <Stack direction=\"row\" gap={1}>\n <CheckCircleOutlined />\n <Typography color=\"primary\">Copied!</Typography>\n </Stack>\n </Box>\n </Box>\n </Tooltip>\n }\n />\n </Stack>\n );\n}\n\nexport default function Okta(props: OktaProps) {\n const { callbackUrl, providers, ...remaining } = props;\n if (!providers) {\n return null;\n }\n const config = providers?.find((provider) => provider.provider === 'okta');\n return (\n <BaseSSOForm\n {...remaining}\n config={config as SSOProvider}\n providerName=\"Okta\"\n configurationGuide={<ConfigGuide callbackUrl={callbackUrl} />}\n />\n );\n}\n","import React from 'react';\nimport Box from '@mui/joy/Box';\nimport Button from '@mui/joy/Button';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\n\nimport { useNileConfig } from '../context';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport GoogleLogo from './google.svg';\n\nconst LOGIN_PATH = 'users/oidc/google/login';\n\n/**\n * A component for a Google login button, according to their design language.\n * This works when an identity provider is configured in the admin dashboard.\n * @param props href: a string to override the URL provided by the context\n * @returns a JSX.Element to render\n */\nexport default function GoogleSSOButton(props: {\n href?: string;\n databaseId?: string;\n newTenantName?: string;\n}) {\n const { databaseId, newTenantName } = props;\n const { basePath } = useNileConfig();\n const encodedDatabase = encodeURIComponent(databaseId ?? '');\n const contextHref = `${basePath}/databases/${encodedDatabase}/${LOGIN_PATH}`;\n const query = newTenantName\n ? '?newTenant=' + encodeURIComponent(newTenantName)\n : '';\n const href = (props?.href ?? contextHref) + query;\n return (\n <Box\n component=\"a\"\n href={href}\n display=\"flex\"\n flex={1}\n sx={{ textDecoration: 'none' }}\n >\n <Box>\n <Button\n sx={{ padding: 0, textTransform: 'initial', flex: 1 }}\n aria-label=\"log in with google\"\n >\n <Stack\n direction=\"row\"\n alignItems=\"center\"\n p={0}\n flex={1}\n fontFamily=\"Roboto, sans-serif\"\n fontSize=\"14px\"\n display=\"inline-flex\"\n color=\"rgb(255 255, 255)\"\n boxShadow=\"rgb(0 0 0 / 24%) 0px 2px 2px 0px rgb(0 0 0 / 24%) 0px 0px 1px 0px\"\n borderRadius=\"4px\"\n border=\"1px solid transparent\"\n fontWeight=\"500\"\n sx={{\n backgroundColor: 'rgb(66 133, 244)',\n }}\n >\n <Box\n padding=\"11px\"\n display=\"flex\"\n border=\"1px solid rgb(66, 133, 244)\"\n borderRadius=\"4px\"\n sx={{\n background: 'rgb(255, 255, 255)',\n }}\n >\n <GoogleLogo aria-hidden=\"true\" />\n </Box>\n <Box padding=\"10px\" flex={1}>\n <Typography\n sx={{ color: 'white' }}\n fontWeight={700}\n fontFamily=\"Roboto, sans-serif\"\n fontSize=\"14px\"\n height=\"20px\"\n >\n Continue with Google\n </Typography>\n </Box>\n </Stack>\n </Button>\n </Box>\n </Box>\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\n\nimport { Attribute } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\nimport SimpleForm from '../lib/SimpleForm';\nimport { AttributeType } from '../lib/SimpleForm/types';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function SingleSignOnForm(\n props: Props & {\n nextButtonText?: string;\n loginButtonText?: string;\n onSuccess: () => void;\n }\n) {\n const {\n attributes,\n onSuccess,\n onError,\n beforeMutate,\n nextButtonText = 'Next',\n loginButtonText = 'Log in',\n disableSSO = false,\n } = props;\n const api = useApi();\n const [buttonText, setButtonText] = React.useState(\n disableSSO ? loginButtonText : nextButtonText\n );\n\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n return await api.auth.login({\n loginRequest: { email: data.email, password: data.password },\n sso: !disableSSO,\n });\n },\n {\n onSuccess: (token, data) => {\n if (token) {\n if (token?.redirectURI) {\n window.location.href = token.redirectURI;\n } else if (buttonText !== loginButtonText) {\n setButtonText(loginButtonText);\n } else {\n onSuccess && onSuccess(token, data);\n }\n }\n },\n onError: (error, data) => {\n // it is possible SSO failed, so only show errors on if the password is available\n if (buttonText === loginButtonText) {\n onError && onError(error as Error, data);\n } else {\n setButtonText(loginButtonText);\n }\n },\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n ];\n if (buttonText === loginButtonText) {\n mainAttributes.push({\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n });\n }\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes, buttonText, loginButtonText]);\n\n return (\n <SimpleForm\n mutation={mutation}\n buttonText={buttonText}\n attributes={completeAttributes}\n />\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport Alert from '@mui/joy/Alert';\nimport Stack from '@mui/joy/Stack';\n\nimport { Attribute } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\nimport SimpleForm from '../lib/SimpleForm';\nimport { AttributeType } from '../lib/SimpleForm/types';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function LoginForm(props: Props) {\n const [error, setError] = React.useState<string | void>();\n const { attributes, onSuccess, onError, beforeMutate } = props;\n const api = useApi();\n\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n setError(undefined);\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n return await api.auth.login({\n loginRequest: data,\n });\n },\n {\n onSuccess,\n onError,\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n {\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n },\n ];\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes]);\n\n return (\n <Stack gap={2}>\n {error ? <Alert color=\"danger\">{error}</Alert> : null}\n <SimpleForm\n mutation={mutation}\n buttonText=\"Log in\"\n attributes={completeAttributes}\n />\n </Stack>\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport Stack from '@mui/joy/Stack';\nimport Alert from '@mui/joy/Alert';\n\nimport UserForm from '../lib/SimpleForm';\nimport { Attribute, AttributeType } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function SignUpForm(props: Props) {\n const [error, setError] = React.useState<string | void>();\n const {\n buttonText = 'Sign up',\n onSuccess,\n onError,\n attributes,\n beforeMutate,\n } = props;\n const api = useApi();\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n setError(undefined);\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n const { email, password, preferredName, newTenant, ...metadata } = data;\n if (Object.keys(metadata).length > 0) {\n // eslint-disable-next-line no-console\n console.warn('additional metadata not supported yet.');\n }\n return api.auth.signUp({\n signUpRequest: { email, password, preferredName, newTenant },\n });\n },\n {\n onSuccess,\n onError: (e: Error, vars) => {\n setError(e.message);\n onError && onError(e as Error, vars);\n },\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n {\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n },\n ];\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes]);\n\n return (\n <Stack gap={2}>\n {error ? <Alert color=\"danger\">{error}</Alert> : null}\n <UserForm\n mutation={mutation}\n buttonText={buttonText}\n attributes={completeAttributes}\n />\n </Stack>\n );\n}\n","import { DataGrid } from '@mui/x-data-grid';\nimport React from 'react';\nimport Stack from '@mui/joy/Stack';\nimport { SxProps } from '@mui/system/styleFunctionSx/styleFunctionSx';\nimport { Theme } from '@mui/system/createTheme';\nimport { SignUp201Response, User } from '@niledatabase/browser';\n\nimport CreateUser from './CreateUser';\nimport useDataParser from './useDataParser';\n\ntype ColumnNames = string;\n\ntype Props = {\n data: void | User[];\n allowCreation?: boolean;\n buttonText?: string;\n onUserCreateSuccess?: (user: SignUp201Response) => void;\n slots?: {\n dataGrid?: SxProps<Theme>;\n };\n // white list of columns to show\n include?: ColumnNames[];\n};\n\nexport default function UserList(props: Props) {\n const {\n data,\n allowCreation = true,\n buttonText = 'Add a user',\n onUserCreateSuccess,\n slots,\n include = ['email', 'preferedName'],\n } = props;\n\n const dataGridSx = {\n width: '100%',\n height: '100%',\n ...(slots?.dataGrid ?? {}),\n };\n\n const [columns, rows] = useDataParser(data, include);\n return (\n <Stack flex={1}>\n <CreateUser\n allowCreation={allowCreation}\n buttonText={buttonText}\n onUserCreateSuccess={onUserCreateSuccess}\n />\n <DataGrid\n sx={dataGridSx}\n rows={rows}\n columns={columns}\n hideFooter={true}\n />\n </Stack>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport default function useTextSizer() {\n const [ctx, setCtx] = useState<CanvasRenderingContext2D>();\n useEffect(() => {\n const canvas = document.createElement('canvas');\n const canvasContext = canvas.getContext('2d');\n if (canvasContext) {\n canvasContext.font = '18px Roboto';\n setCtx(canvasContext);\n }\n }, []);\n return ctx;\n}\n","import { GridRowsProp } from '@mui/x-data-grid';\n\nexport default function getColumnSize(\n column: unknown,\n rows: GridRowsProp,\n canvasContext: void | CanvasRenderingContext2D\n) {\n const dataWidthReducer = (\n longest: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nextRow: { [key: string]: any }\n ) => {\n let value = nextRow[String(column)];\n if (value == null) {\n value = '';\n }\n value = value?.toString();\n return longest.length > value.length ? longest : value;\n };\n\n let columnHeaderLen =\n canvasContext && column\n ? canvasContext.measureText(String(column)).width\n : 50;\n /* padding 12, icon-width 15 */\n columnHeaderLen += 15 + 12;\n\n let width = columnHeaderLen;\n width =\n 16 +\n Math.ceil(\n canvasContext\n ? canvasContext.measureText(rows.reduce(dataWidthReducer, '')).width\n : 50\n );\n if (width < columnHeaderLen) {\n width = columnHeaderLen;\n }\n /* Gracefull */\n width += 8;\n return width;\n}\n"],"names":["Themer","theme","children","slotProps","React","JoyCssVarsProvider","createElement","CssBaseline","enableColorScheme","queryClient","QueryClient","context","createContext","api","Browser","basePath","credentials","Provider","BaseQueryProvider","QueryClientProvider","client","useNileContext","useContext","useNileConfig","tenantId","useMemo","useApi","_g","_extends","Object","assign","bind","target","i","arguments","length","source","key","prototype","hasOwnProperty","call","apply","this","AttributeType","SvgGoogle","props","xmlns","width","height","fillRule","fill","d","CheckGroup","options","attribute","display","helperText","watch","control","useFormContext","currentVals","name","checkProps","color","Controller","rules","required","Boolean","render","field","Stack","FormLabel","htmlFor","label","Box","role","sx","borderRadius","p","border","List","orientation","wrap","map","item","id","String","value","ListItem","Checkbox","overlay","checked","includes","disableIcon","variant","onChange","event","allowMultiple","concat","remaining","filter","val","Typography","level","FormAttributeType","getAttributeDefault","Array","isArray","defaultValue","Labler","error","attr","Tooltip","title","cursor","Error","ml","fontSize","SimpleForm","mutation","buttonText","attributes","cancelButton","loading","successMessage","defaultValues","reduce","accum","methods","useForm","register","handleSubmit","formState","errors","onSubmit","useCallback","data","mutate","FormProvider","component","spacing","fieldConfig","placeholder","disabled","helpText","type","Switch","FormControl","alignItems","FormHelperText","endDecorator","Select","_","newValue","option","Option","Password","Input","Number","Text","direction","Button","gap","AddUser","open","setOpen","refetch","errorText","setErrorText","useState","email","useEffect","useMutation","users","createTenantUser","signUpRequest","onSuccess","onError","e","message","handleUpdate","async","Modal","ModalDialog","Fragment","fullWidth","size","autoComplete","pt","onClick","CreateUser","allowCreation","onUserCreateSuccess","UserModal","startDecorator","Add","makeRenderable","vals","keys","cleaned","Set","from","join","BaseSSOForm","config","providerName","allowEdit","configurationGuide","setLoading","success","setSuccess","optimisticConfig","setConfig","timer","useRef","enabled","clientId","configUrl","emailDomains","splice","ssoRequest","payload","toLowerCase","updateProviderRequest","split","auth","updateProvider","createProvider","vars","onSettled","current","clearTimeout","setTimeout","position","Alert","opacity","transition","CheckCircleOutlined","textAlign","ConfigGuide","callbackUrl","copied","setCopied","fontFamily","navigator","clipboard","writeText","input","span","palette","primary","readOnly","top","left","CopyAll","databaseId","newTenantName","contextHref","encodeURIComponent","query","href","flex","textDecoration","padding","textTransform","boxShadow","fontWeight","backgroundColor","background","GoogleLogo","QueryProvider","values","ThemeProvider","provider","providers","find","beforeMutate","nextButtonText","loginButtonText","disableSSO","setButtonText","_data","login","loginRequest","password","sso","token","redirectURI","window","location","completeAttributes","mainAttributes","push","setError","undefined","preferredName","newTenant","metadata","console","warn","signUp","UserForm","slots","include","dataGridSx","dataGrid","columns","rows","ctx","setCtx","canvasContext","document","getContext","font","useTextSizer","cols","parseResults","fields","existentCols","col","column","columnHeaderLen","measureText","Math","ceil","dataWidthReducer","longest","nextRow","toString","getColumnSize","slice","padEnd","headerName","useDataParser","DataGrid","hideFooter"],"mappings":"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"}
1
+ {"version":3,"file":"react.cjs.production.min.js","sources":["../src/context/theme.tsx","../src/context/index.tsx","../src/GoogleLoginButton/google.svg","../src/lib/SimpleForm/types.ts","../src/lib/SimpleForm/CheckGroup/index.tsx","../src/lib/SimpleForm/index.tsx","../src/UserTenantList/UserModal.tsx","../src/UserTenantList/CreateUser.tsx","../src/UserTenantList/useDataParser.ts","../src/SSO/BaseSSOForm.tsx","../src/SSO/Okta.tsx","../src/GoogleLoginButton/GoogleLoginButton.tsx","../src/LoginForm/SingleSignOn.tsx","../src/LoginForm/LoginForm.tsx","../src/SignUpForm/SignUpForm.tsx","../src/UserTenantList/UserList.tsx","../src/hooks/useTextSizer.ts","../src/utils/getColumnSize.ts"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nimport React from 'react';\nimport CssBaseline from '@mui/material/CssBaseline';\nimport { Theme } from '@mui/joy/styles';\nimport { CssVarsProvider as JoyCssVarsProvider } from '@mui/joy/styles';\n\nexport default function Themer({\n theme,\n children,\n slotProps,\n}: {\n theme?: Theme;\n children: JSX.Element;\n slotProps?: Record<string, string>;\n}) {\n return (\n <JoyCssVarsProvider {...slotProps} theme={theme}>\n <CssBaseline enableColorScheme />\n {children}\n </JoyCssVarsProvider>\n );\n}\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\nimport React, { useMemo, createContext, useContext } from 'react';\nimport Browser from '@niledatabase/browser';\nimport { QueryClientProvider, QueryClient } from '@tanstack/react-query';\n\nimport ThemeProvider from './theme';\nimport { NileContext, NileProviderProps, NileReactConfig } from './types';\n\nconst queryClient = new QueryClient();\n\nconst defaultContext: NileContext = {\n api: new Browser({\n basePath: 'https://api.thenile.dev',\n credentials: 'include',\n }),\n apiUrl: '',\n};\n\nconst context = createContext<NileContext>(defaultContext);\n\nconst { Provider } = context;\n\nexport const BaseQueryProvider = ({\n children,\n}: {\n children: JSX.Element;\n}): JSX.Element => {\n return (\n <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>\n );\n};\n\nexport const NileProvider = (props: NileProviderProps) => {\n const {\n children,\n theme,\n slotProps,\n tenantId,\n QueryProvider = BaseQueryProvider,\n appUrl,\n apiUrl = 'https://api.thenile.dev',\n api,\n } = props;\n\n const values = useMemo<NileContext>((): NileContext => {\n return {\n api:\n api ??\n new Browser({\n basePath: appUrl,\n credentials: 'include',\n }),\n tenantId: String(tenantId),\n apiUrl,\n };\n }, [api, apiUrl, appUrl, tenantId]);\n\n return (\n <QueryProvider>\n <ThemeProvider slotProps={slotProps?.provider} theme={theme}>\n <Provider value={values}>{children}</Provider>\n </ThemeProvider>\n </QueryProvider>\n );\n};\n\nconst useNileContext = (): NileContext => {\n return useContext(context);\n};\n\nexport const useNileConfig = (): NileReactConfig => {\n const { apiUrl, tenantId, appUrl } = useNileContext();\n return useMemo(\n () => ({\n tenantId,\n apiUrl,\n appUrl,\n }),\n [apiUrl, tenantId, appUrl]\n );\n};\n\nexport const useApi = (): Browser => {\n return useNileContext().api;\n};\n","<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\">\n <g fill=\"#000\" fill-rule=\"evenodd\">\n <path 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\" fill=\"#EA4335\" />\n <path 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\" fill=\"#4285F4\" />\n <path 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\" fill=\"#FBBC05\" />\n <path 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\" fill=\"#34A853\" />\n <path fill=\"none\" d=\"M0 0h18v18H0z\" />\n </g>\n</svg>","export enum AttributeType {\n Text = 'text',\n Password = 'password',\n Select = 'select',\n Number = 'number',\n Float = 'float',\n Checkbox = 'checkbox',\n Switch = 'switch',\n}\ntype SimplePrimitive = number | string | boolean;\n\n// possibly no value for `<Switch/>`\nexport type Options = { label: string; value?: SimplePrimitive }[];\nexport type Attribute = {\n name: string;\n type?: AttributeType;\n defaultValue?: SimplePrimitive;\n options?: Options;\n allowMultiple?: boolean;\n label?: string;\n required?: boolean;\n placeholder?: string;\n helpText?: string;\n disabled?: boolean;\n};\n\nexport type DisplayProps = {\n key: string;\n id: string;\n label: string;\n placeholder: string;\n error?: boolean;\n color?: 'danger';\n disabled?: boolean;\n};\n","import * as React from 'react';\nimport Box from '@mui/joy/Box';\nimport Checkbox from '@mui/joy/Checkbox';\nimport List from '@mui/joy/List';\nimport { Controller, useFormContext } from 'react-hook-form';\nimport Stack from '@mui/joy/Stack';\nimport FormLabel from '@mui/joy/FormLabel';\nimport ListItem from '@mui/joy/ListItem';\nimport Typography from '@mui/joy/Typography';\n\nimport { Attribute, DisplayProps, Options } from '../types';\n\ntype Props = {\n attribute: Attribute;\n display: DisplayProps;\n options: Options;\n helperText: string;\n};\nexport default function CheckGroup(props: Props) {\n const { options, attribute, display, helperText } = props;\n const { watch, control } = useFormContext();\n const currentVals = watch(attribute.name);\n const checkProps: { color?: 'danger'; id?: string } = {};\n if (helperText) {\n checkProps.color = 'danger';\n }\n return (\n <Controller\n name={attribute.name}\n rules={{ required: Boolean(attribute.required) }}\n control={control}\n render={({ field }) => {\n return (\n <Stack>\n <FormLabel htmlFor={`${field.name}`}>{display.label}</FormLabel>\n <Box\n role=\"group\"\n aria-labelledby={attribute.name}\n sx={{\n borderRadius: 'var(--joy-radius-sm)',\n p: 0.5,\n border: helperText\n ? '1px solid var(--joy-palette-danger-outlinedBorder)'\n : 'none',\n }}\n >\n <List\n orientation=\"horizontal\"\n wrap\n sx={{\n '--List-gap': '8px',\n }}\n >\n {options.map((item) => {\n checkProps.id = String(item.value);\n return (\n <ListItem key={`${item.value}-${item.label}`}>\n <Checkbox\n overlay={options.length > 1}\n {...checkProps}\n checked={currentVals.includes(item.value)}\n disableIcon={options.length > 1}\n variant=\"soft\"\n label={item.label}\n onChange={(event) => {\n if (attribute.allowMultiple) {\n if (event.target.checked) {\n if (!currentVals) {\n field.onChange([item.value]);\n } else {\n field.onChange(currentVals.concat(item.value));\n }\n } else {\n const remaining = currentVals.filter(\n (val: string | number) => val !== item.value\n );\n if (remaining.length > 0) {\n field.onChange(remaining);\n } else {\n field.onChange('');\n }\n }\n } else {\n if (event.target.checked) {\n field.onChange(item.value);\n } else {\n field.onChange('');\n }\n }\n }}\n />\n </ListItem>\n );\n })}\n </List>\n </Box>\n <Typography\n sx={{ color: 'var(--joy-palette-danger-500)' }}\n level=\"body-sm\"\n >\n {helperText}\n </Typography>\n </Stack>\n );\n }}\n />\n );\n}\n","import React from 'react';\nimport Button from '@mui/joy/Button';\nimport { Controller, FormProvider, useForm } from 'react-hook-form';\nimport Stack from '@mui/joy/Stack';\nimport Input from '@mui/joy/Input';\nimport FormControl from '@mui/joy/FormControl';\nimport FormHelperText from '@mui/joy/FormHelperText';\nimport Error from '@mui/icons-material/Error';\nimport FormLabel from '@mui/joy/FormLabel';\nimport Select from '@mui/joy/Select';\nimport Option from '@mui/joy/Option';\nimport Box from '@mui/joy/Box';\nimport Tooltip from '@mui/joy/Tooltip';\nimport { Switch } from '@mui/joy';\n\nimport CheckGroup from './CheckGroup';\nimport { Attribute, AttributeType, DisplayProps } from './types';\n\ntype AttrMap = {\n [key: string]: string | number | boolean | string[] | number[];\n};\n\ntype FieldConfig = {\n required?: boolean;\n};\n\nexport const getAttributeDefault = (\n attribute: Attribute\n): string | number | boolean | string[] | number[] => {\n // have to look to see if it is an enum\n if (attribute.allowMultiple === true) {\n if (!Array.isArray(attribute.defaultValue) && attribute.defaultValue) {\n if (typeof attribute.defaultValue === 'number') {\n return [attribute.defaultValue];\n }\n return [String(attribute.defaultValue)];\n }\n }\n return attribute.defaultValue ?? '';\n};\n\nfunction Labler(props: { error?: string; attr: Attribute }) {\n const { error, attr } = props;\n if (error) {\n return (\n <Tooltip title={error} color=\"danger\" sx={{ cursor: 'pointer' }}>\n <FormLabel>\n {attr.label ?? attr.name}\n <Error sx={{ ml: 0.5, '--Icon-color': '#c41c1c' }} fontSize=\"small\" />\n </FormLabel>\n </Tooltip>\n );\n }\n return <FormLabel>{attr.label ?? attr.name}</FormLabel>;\n}\nexport default function SimpleForm(props: {\n buttonText: string;\n cancelButton?: React.ReactNode;\n attributes: Attribute[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mutation: any;\n loading?: boolean;\n successMessage?: JSX.Element;\n}) {\n const {\n mutation,\n buttonText,\n attributes,\n cancelButton,\n loading,\n successMessage,\n } = props;\n\n const defaultValues = React.useMemo(\n () =>\n attributes.reduce((accum: AttrMap, attr: Attribute) => {\n accum[attr.name] = getAttributeDefault(attr);\n return accum;\n }, {}),\n [attributes]\n );\n\n const methods = useForm({\n defaultValues,\n });\n\n const {\n register,\n control,\n handleSubmit,\n formState: { errors },\n } = methods;\n const onSubmit = React.useCallback(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (data: any) => {\n mutation.mutate(data);\n },\n [mutation]\n );\n\n return (\n <FormProvider {...methods}>\n <Stack\n component=\"form\"\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onSubmit={handleSubmit((data) => onSubmit(data as any))}\n spacing={2}\n >\n {attributes.map((attr: Attribute): React.ReactNode => {\n const fieldConfig: FieldConfig = {};\n const display: DisplayProps = {\n key: attr.name,\n label: attr.label ?? attr.name,\n id: attr.label ?? attr.name,\n placeholder: attr.placeholder ?? attr.label ?? attr.name,\n error: Boolean(errors[attr.name]),\n disabled: Boolean(attr.disabled),\n };\n const options = attr.options ?? [];\n const helperText = attr.helpText ?? '';\n let error = '';\n\n if (attr.required) {\n error = errors[attr.name]\n ? `${attr.label ?? attr.name} is required`\n : '';\n fieldConfig.required = true;\n }\n\n switch (attr.type) {\n case AttributeType.Switch:\n return (\n <FormControl\n key={display.key}\n id={display.id}\n orientation=\"horizontal\"\n sx={{ alignItems: 'center' }}\n >\n <Box>\n <Labler error={error} attr={attr} />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </Box>\n <Controller\n control={control}\n rules={{ required: Boolean(attr.required) }}\n name={attr.name}\n render={({ field }) => {\n const color: { color?: 'danger' } = {};\n if (errors[attr.name]) {\n color.color = 'danger';\n }\n return (\n <Switch\n id={`switch-field-${attr.name}`}\n {...color}\n {...field}\n checked={Boolean(field.value)}\n onChange={(event) => {\n field.onChange(event.target.checked);\n }}\n color={field.value ? 'success' : 'neutral'}\n endDecorator={\n field.value ? options[0].label : options[1].label\n }\n />\n );\n }}\n />\n </FormControl>\n );\n case AttributeType.Checkbox:\n return (\n <CheckGroup\n key={display.key}\n attribute={attr}\n display={display}\n options={options}\n helperText={helperText}\n />\n );\n case AttributeType.Select:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Controller\n control={control}\n rules={{ required: Boolean(attr.required) }}\n name={attr.name}\n render={({ field }) => {\n const color: { color?: 'danger' } = {};\n if (errors[attr.name]) {\n color.color = 'danger';\n }\n const value = String(field.value);\n return (\n <Stack>\n <Select\n id={`select-field-${attr.name}`}\n placeholder={`${display.placeholder}...`}\n {...color}\n {...field}\n value={value}\n onChange={(_, newValue) => {\n field.onChange(newValue);\n }}\n >\n {options.map((option) => {\n return (\n <Option\n key={String(option.value ?? '')}\n value={option.value}\n >\n {option.label}\n </Option>\n );\n })}\n </Select>\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </Stack>\n );\n }}\n />\n </FormControl>\n );\n case AttributeType.Password:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input\n {...display}\n {...register(attr.name, fieldConfig)}\n type={AttributeType.Password}\n />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n case AttributeType.Number:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input\n {...display}\n {...register(attr.name, fieldConfig)}\n type={AttributeType.Number}\n />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n\n case AttributeType.Text:\n default:\n return (\n <FormControl key={display.key} id={display.id}>\n <Labler error={error} attr={attr} />\n <Input {...display} {...register(attr.name, fieldConfig)} />\n <FormHelperText id={`${attr.name}-helper-text`}>\n {helperText}\n </FormHelperText>\n </FormControl>\n );\n }\n })}\n {cancelButton ? (\n <Stack spacing={2} direction=\"row\">\n {cancelButton}\n <Box>\n <Button type=\"submit\">{buttonText}</Button>\n </Box>\n </Stack>\n ) : (\n <Box>\n <Stack direction=\"row\" gap={2}>\n <Button type=\"submit\" loading={loading}>\n {buttonText}\n </Button>\n {successMessage}\n </Stack>\n </Box>\n )}\n </Stack>\n </FormProvider>\n );\n}\n","import React from 'react';\nimport {\n Button,\n Stack,\n Typography,\n FormControl,\n FormLabel,\n Input,\n Modal,\n ModalDialog,\n} from '@mui/joy';\nimport { useForm } from 'react-hook-form';\nimport { useMutation } from '@tanstack/react-query';\nimport { SignUp201Response, SignUpRequest } from '@niledatabase/browser';\n\nimport { useApi, useNileConfig } from '../context';\n\nexport type UserFormProps = {\n open: boolean;\n setOpen: (open: boolean) => void;\n refetch?: (user: SignUp201Response) => void;\n};\n\nexport default function AddUser(props: UserFormProps) {\n const { open, setOpen, refetch } = props;\n const { tenantId } = useNileConfig();\n const api = useApi();\n const [errorText, setErrorText] = React.useState<void | string>();\n const { watch, register, handleSubmit } = useForm<SignUpRequest>();\n const email = watch('email');\n\n React.useEffect(() => {\n if (errorText != null) {\n setErrorText();\n }\n // if email changes, no more error\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [email]);\n\n const mutation = useMutation(\n (data: SignUpRequest) =>\n api.users.createTenantUser({\n signUpRequest: data,\n tenantId: String(tenantId),\n }),\n {\n onSuccess(data) {\n refetch && refetch(data);\n setOpen(false);\n },\n onError(e) {\n if (e instanceof Error) {\n setErrorText(e.message);\n }\n },\n }\n );\n\n const handleUpdate = React.useCallback(\n async (data: SignUpRequest) => {\n setErrorText('');\n mutation.mutate(data);\n },\n [mutation]\n );\n\n return (\n <Modal open={open}>\n <ModalDialog>\n <Stack spacing={2}>\n <Typography level=\"h4\">Create user</Typography>\n <>\n {errorText && <Typography color=\"danger\">{errorText}</Typography>}\n </>\n <Stack\n component=\"form\"\n sx={{\n width: '40ch',\n }}\n spacing={1}\n onSubmit={handleSubmit((data) =>\n handleUpdate(data as SignUpRequest)\n )}\n >\n <FormControl\n sx={{\n '--FormHelperText-color': 'var(--joy-palette-danger-500)',\n }}\n >\n <FormLabel htmlFor=\"email\">Email</FormLabel>\n <Input\n {...register('email')}\n fullWidth\n size=\"lg\"\n id=\"email\"\n name=\"email\"\n autoComplete=\"current-email\"\n required\n error={Boolean(errorText)}\n />\n </FormControl>\n <FormControl\n sx={{\n '--FormHelperText-color': 'var(--joy-palette-danger-500)',\n }}\n >\n <FormLabel htmlFor=\"password\">Password</FormLabel>\n <Input\n {...register('password')}\n fullWidth\n size=\"lg\"\n id=\"password\"\n autoComplete=\"current-password\"\n type=\"password\"\n required\n />\n </FormControl>\n <Stack direction=\"row\" sx={{ pt: 2 }} spacing={2}>\n <Button onClick={() => setOpen(false)} variant=\"plain\">\n Cancel\n </Button>\n <Button type=\"submit\">Create</Button>\n </Stack>\n </Stack>\n </Stack>\n </ModalDialog>\n </Modal>\n );\n}\n","import React from 'react';\nimport Button from '@mui/joy/Button';\nimport Stack from '@mui/joy/Stack';\nimport { useState } from 'react';\nimport Add from '@mui/icons-material/Add';\nimport { SignUp201Response } from '@niledatabase/browser';\n\nimport UserModal from './UserModal';\n\ntype Props = {\n allowCreation: boolean;\n buttonText: string;\n onUserCreateSuccess?: (user: SignUp201Response) => void;\n};\nexport default function CreateUser(props: Props) {\n const { allowCreation, buttonText, onUserCreateSuccess } = props;\n const [open, setOpen] = useState(false);\n if (!allowCreation) {\n return null;\n }\n\n return (\n <Stack alignItems=\"flex-end\" gap={1}>\n <UserModal open={open} setOpen={setOpen} refetch={onUserCreateSuccess} />\n <Button startDecorator={<Add />} size=\"sm\" onClick={() => setOpen(true)}>\n {buttonText}\n </Button>\n </Stack>\n );\n}\n","import { useMemo } from 'react';\nimport { GridColDef, GridRowsProp } from '@mui/x-data-grid';\nimport { User } from '@niledatabase/browser';\n\nimport getColumnSize from '../utils/getColumnSize';\nimport useTextSizer from '../hooks/useTextSizer';\n\nexport const internalRowId = '_nile_data_grid_identifier';\n\ntype Cleaned = { [key: string]: string | Set<string> };\n\nconst makeRenderable = (vals: User) => {\n return Object.keys(vals).reduce((cleaned: Cleaned, key) => {\n const val = (vals as Cleaned)[key];\n if (val instanceof Set) {\n cleaned[key] = Array.from(val).join(', ');\n } else if (Array.isArray(val)) {\n cleaned[key] = val.join(', ');\n } else {\n cleaned[key] = val;\n }\n return cleaned;\n }, {});\n};\n\nconst parseResults = (\n data: void | User[],\n ctx: CanvasRenderingContext2D | void,\n include: string[]\n): [GridColDef[], GridRowsProp] => {\n if (!data) {\n return [[], []];\n }\n const rows = data.map(makeRenderable);\n const fields = Object.keys(rows[0]);\n\n const existentCols: { [key: string]: number } = {};\n\n const mapCols = (col: string): GridColDef | void => {\n const width = getColumnSize(col, rows, ctx);\n const name = col.slice();\n if (include.includes(name)) {\n // add spaces to the end of column names so they are not duplicated in the UI\n if (existentCols[name] == null) {\n existentCols[name] = name.length;\n } else {\n existentCols[name] += 1;\n }\n return {\n field: name.padEnd(existentCols[name]),\n headerName: name.padEnd(existentCols[name]),\n width,\n };\n }\n };\n const cols = fields?.map(mapCols).filter(Boolean) ?? [];\n\n return [cols as GridColDef[], rows];\n};\n\nexport default function useDataParser(\n data: void | User[],\n include: string[]\n): [GridColDef[], GridRowsProp] {\n const ctx = useTextSizer();\n const [cols, rows] = useMemo(\n () => parseResults(data, ctx, include),\n [data, ctx, include]\n );\n return [cols, rows];\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport { UpdateProviderRequest, SSOProvider } from '@niledatabase/browser';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\nimport Alert from '@mui/joy/Alert';\nimport CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';\n\nimport SimpleForm from '../lib/SimpleForm';\nimport { useApi } from '../context';\nimport { Attribute, AttributeType } from '../lib/SimpleForm/types';\n\nimport { OktaProps } from './types';\n\ntype SSOFormRequest = Omit<UpdateProviderRequest, 'emailDomains'> & {\n emailDomains: string;\n};\nexport default function BaseSSOForm(\n props: Omit<OktaProps, 'callbackUrl' | 'providers'> & {\n providerName: string;\n configurationGuide?: JSX.Element;\n config?: SSOProvider;\n }\n) {\n const {\n config,\n providerName,\n onSuccess,\n onError,\n allowEdit = true,\n configurationGuide,\n } = props;\n\n const api = useApi();\n const [loading, setLoading] = React.useState(false);\n const [success, setSuccess] = React.useState(false);\n const [optimisticConfig, setConfig] = React.useState<SSOProvider | void>(\n config\n );\n const timer = React.useRef<NodeJS.Timeout>();\n const attributes = React.useMemo(() => {\n const attributes: Attribute[] = [\n {\n name: 'enabled',\n label: 'Allow Okta logins',\n type: AttributeType.Switch,\n defaultValue: optimisticConfig?.enabled === true,\n options: [\n {\n label: 'Enabled',\n },\n {\n label: 'Disabled',\n },\n ],\n disabled: !allowEdit,\n },\n {\n name: 'clientId',\n label: 'Client id',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.clientId ?? '',\n required: true,\n disabled: !allowEdit,\n },\n {\n name: 'configUrl',\n label: 'Config url',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.configUrl ?? '',\n helpText:\n 'The URL of the .well-known/openid-configuration for the identity provider',\n required: true,\n disabled: !allowEdit,\n },\n {\n name: 'emailDomains',\n label: 'Email domains',\n type: AttributeType.Text,\n defaultValue: optimisticConfig?.emailDomains?.join(', ') ?? '',\n required: true,\n helpText:\n 'A comma seperated list of email domains (yourDomain.com) to be used',\n disabled: !allowEdit,\n },\n ];\n if (!optimisticConfig?.clientId) {\n attributes.splice(2, 0, {\n name: 'clientSecret',\n label: 'Client secret',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n disabled: !allowEdit,\n });\n }\n return attributes;\n }, [\n allowEdit,\n optimisticConfig?.clientId,\n optimisticConfig?.configUrl,\n optimisticConfig?.emailDomains,\n optimisticConfig?.enabled,\n ]);\n\n const handleTimer = () => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n\n timer.current = setTimeout(() => {\n setSuccess(false);\n }, 3000);\n };\n\n const mutation = useMutation(\n (ssoRequest: SSOFormRequest) => {\n setLoading(true);\n const payload = {\n providerName: providerName.toLowerCase(),\n updateProviderRequest: {\n ...ssoRequest,\n emailDomains: ssoRequest.emailDomains.split(','),\n },\n };\n if (optimisticConfig != null) {\n return api.auth.updateProvider(payload);\n } else {\n return api.auth.createProvider(payload);\n }\n },\n {\n onSuccess: (data, vars) => {\n setConfig(data);\n setSuccess(true);\n onSuccess && onSuccess(data, vars);\n },\n onError,\n onSettled: (data, error, vars) => {\n setLoading(false);\n handleTimer();\n if (!data) {\n if (!error || error?.message.includes('Unterminated string')) {\n // something unexpected happened on the BE, but it's non-fatal\n setConfig({\n enabled: vars.enabled,\n clientId: vars.clientId,\n configUrl: vars.configUrl,\n emailDomains: vars.emailDomains.split(', '),\n } as SSOProvider);\n }\n setSuccess(true);\n onSuccess && onSuccess(data, vars);\n }\n },\n }\n );\n\n React.useEffect(() => {\n () => {\n clearTimeout(timer.current);\n };\n });\n\n return (\n <Stack gap={2} position=\"relative\">\n <Typography level=\"h4\">Step 1</Typography>\n {configurationGuide}\n <Typography level=\"h4\">Step 2</Typography>\n <SimpleForm\n mutation={mutation}\n buttonText=\"Update\"\n attributes={attributes}\n loading={loading}\n successMessage={\n <Alert\n color=\"success\"\n sx={{\n opacity: success ? 1 : 0,\n transition: 'opacity 200ms',\n height: '0.9rem',\n }}\n startDecorator={<CheckCircleOutlined />}\n >\n <Typography textAlign=\"center\" fontSize=\"sm\">\n Provider updated\n </Typography>\n </Alert>\n }\n />\n </Stack>\n );\n}\n","import React from 'react';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\nimport Box from '@mui/joy/Box';\nimport Input from '@mui/joy/Input';\nimport CopyAll from '@mui/icons-material/CopyAll';\nimport { Theme } from '@mui/joy/styles';\nimport Tooltip from '@mui/joy/Tooltip';\nimport CheckCircleOutlined from '@mui/icons-material/CheckCircleOutlined';\nimport { SSOProvider } from '@niledatabase/browser';\n\nimport BaseSSOForm from './BaseSSOForm';\nimport { OktaProps } from './types';\n\nfunction ConfigGuide({ callbackUrl }: { callbackUrl?: string }) {\n const [copied, setCopied] = React.useState(false);\n\n const timer = React.useRef<NodeJS.Timeout>();\n React.useEffect(() => {\n if (timer.current) {\n clearTimeout(timer.current);\n }\n timer.current = setTimeout(() => {\n setCopied(false);\n }, 3250);\n () => {\n clearTimeout(timer.current);\n };\n }, [copied]);\n return (\n <Stack gap={2}>\n <Typography>\n In order for Okta to redirect properly, provide the following URL as the{' '}\n <Box component=\"span\" sx={{ fontFamily: 'monospace' }}>\n Sign-in redirect URIs\n </Box>{' '}\n in the admin configuration of your application.\n </Typography>\n <Input\n onClick={async () => {\n if (callbackUrl) {\n await navigator.clipboard.writeText(callbackUrl);\n setCopied(true);\n }\n }}\n sx={(theme: Theme) => ({\n input: {\n cursor: 'pointer',\n },\n span: {\n cursor: 'pointer',\n },\n '&:hover svg': {\n '--Icon-color': theme.palette.primary[500],\n },\n })}\n value={callbackUrl}\n readOnly={true}\n endDecorator={\n <Tooltip title=\"Copy Okta redirect URL\">\n <Box\n position=\"relative\"\n width={copied ? '82px' : '24px'}\n height=\"24px\"\n >\n <Box\n position=\"absolute\"\n top=\"0\"\n left=\"0\"\n sx={{\n opacity: copied ? 0 : 1,\n transition: 'opacity 300ms',\n }}\n >\n <CopyAll />\n </Box>\n <Box\n position=\"absolute\"\n top=\"0\"\n left=\"0\"\n sx={{ opacity: !copied ? 0 : 1, transition: 'opacity 300ms' }}\n >\n <Stack direction=\"row\" gap={1}>\n <CheckCircleOutlined />\n <Typography color=\"primary\">Copied!</Typography>\n </Stack>\n </Box>\n </Box>\n </Tooltip>\n }\n />\n </Stack>\n );\n}\n\nexport default function Okta(props: OktaProps) {\n const { callbackUrl, providers, ...remaining } = props;\n if (!providers) {\n return null;\n }\n const config = providers?.find((provider) => provider.provider === 'okta');\n return (\n <BaseSSOForm\n {...remaining}\n config={config as SSOProvider}\n providerName=\"Okta\"\n configurationGuide={<ConfigGuide callbackUrl={callbackUrl} />}\n />\n );\n}\n","import React from 'react';\nimport Box from '@mui/joy/Box';\nimport Button from '@mui/joy/Button';\nimport Stack from '@mui/joy/Stack';\nimport Typography from '@mui/joy/Typography';\n\nimport { useNileConfig } from '../context';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport GoogleLogo from './google.svg';\n\nconst LOGIN_PATH = 'users/oidc/google/login';\n\n/**\n * A component for a Google login button, according to their design language.\n * This works when an identity provider is configured in the admin dashboard.\n * @param props href: a string to override the URL provided by the context\n * @returns a JSX.Element to render\n */\nexport default function GoogleSSOButton(props: { newTenantName?: string }) {\n const { newTenantName } = props;\n const { apiUrl } = useNileConfig();\n if (!apiUrl) {\n // eslint-disable-next-line no-console\n console.error('apiUrl is missing from <NileProvider />');\n }\n const contextHref = `${apiUrl}/${LOGIN_PATH}`;\n const query = newTenantName\n ? '?newTenant=' + encodeURIComponent(newTenantName)\n : '';\n const href = contextHref + query;\n return (\n <Box\n component=\"a\"\n href={href}\n display=\"flex\"\n flex={1}\n sx={{ textDecoration: 'none' }}\n >\n <Box>\n <Button\n sx={{ padding: 0, textTransform: 'initial', flex: 1 }}\n aria-label=\"log in with google\"\n >\n <Stack\n direction=\"row\"\n alignItems=\"center\"\n p={0}\n flex={1}\n fontFamily=\"Roboto, sans-serif\"\n fontSize=\"14px\"\n display=\"inline-flex\"\n color=\"rgb(255 255, 255)\"\n boxShadow=\"rgb(0 0 0 / 24%) 0px 2px 2px 0px rgb(0 0 0 / 24%) 0px 0px 1px 0px\"\n borderRadius=\"4px\"\n border=\"1px solid transparent\"\n fontWeight=\"500\"\n sx={{\n backgroundColor: 'rgb(66 133, 244)',\n }}\n >\n <Box\n padding=\"11px\"\n display=\"flex\"\n border=\"1px solid rgb(66, 133, 244)\"\n borderRadius=\"4px\"\n sx={{\n background: 'rgb(255, 255, 255)',\n }}\n >\n <GoogleLogo aria-hidden=\"true\" />\n </Box>\n <Box padding=\"10px\" flex={1}>\n <Typography\n sx={{ color: 'white' }}\n fontWeight={700}\n fontFamily=\"Roboto, sans-serif\"\n fontSize=\"14px\"\n height=\"20px\"\n >\n Continue with Google\n </Typography>\n </Box>\n </Stack>\n </Button>\n </Box>\n </Box>\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\n\nimport { Attribute } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\nimport SimpleForm from '../lib/SimpleForm';\nimport { AttributeType } from '../lib/SimpleForm/types';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function SingleSignOnForm(\n props: Props & {\n nextButtonText?: string;\n loginButtonText?: string;\n onSuccess: () => void;\n }\n) {\n const {\n attributes,\n onSuccess,\n onError,\n beforeMutate,\n nextButtonText = 'Next',\n loginButtonText = 'Log in',\n disableSSO = false,\n } = props;\n const api = useApi();\n const [buttonText, setButtonText] = React.useState(\n disableSSO ? loginButtonText : nextButtonText\n );\n\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n return await api.auth.login({\n loginRequest: { email: data.email, password: data.password },\n sso: !disableSSO,\n });\n },\n {\n onSuccess: (token, data) => {\n if (token) {\n if (token?.redirectURI) {\n window.location.href = token.redirectURI;\n } else if (buttonText !== loginButtonText) {\n setButtonText(loginButtonText);\n } else {\n onSuccess && onSuccess(token, data);\n }\n }\n },\n onError: (error, data) => {\n // it is possible SSO failed, so only show errors on if the password is available\n if (buttonText === loginButtonText) {\n onError && onError(error as Error, data);\n } else {\n setButtonText(loginButtonText);\n }\n },\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n ];\n if (buttonText === loginButtonText) {\n mainAttributes.push({\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n });\n }\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes, buttonText, loginButtonText]);\n\n return (\n <SimpleForm\n mutation={mutation}\n buttonText={buttonText}\n attributes={completeAttributes}\n />\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport Alert from '@mui/joy/Alert';\nimport Stack from '@mui/joy/Stack';\n\nimport { Attribute } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\nimport SimpleForm from '../lib/SimpleForm';\nimport { AttributeType } from '../lib/SimpleForm/types';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function LoginForm(props: Props) {\n const [error, setError] = React.useState<string | void>();\n const { attributes, onSuccess, onError, beforeMutate } = props;\n const api = useApi();\n\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n setError(undefined);\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n return await api.auth.login({\n loginRequest: data,\n });\n },\n {\n onSuccess,\n onError,\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n {\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n },\n ];\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes]);\n\n return (\n <Stack gap={2}>\n {error ? <Alert color=\"danger\">{error}</Alert> : null}\n <SimpleForm\n mutation={mutation}\n buttonText=\"Log in\"\n attributes={completeAttributes}\n />\n </Stack>\n );\n}\n","import React from 'react';\nimport { useMutation } from '@tanstack/react-query';\nimport Stack from '@mui/joy/Stack';\nimport Alert from '@mui/joy/Alert';\n\nimport UserForm from '../lib/SimpleForm';\nimport { Attribute, AttributeType } from '../lib/SimpleForm/types';\nimport { useApi } from '../context';\n\nimport { Props, LoginInfo } from './types';\n\nexport default function SignUpForm(props: Props) {\n const [error, setError] = React.useState<string | void>();\n const {\n buttonText = 'Sign up',\n onSuccess,\n onError,\n attributes,\n beforeMutate,\n } = props;\n const api = useApi();\n const mutation = useMutation(\n async (_data: LoginInfo) => {\n setError(undefined);\n const possibleData = beforeMutate && beforeMutate(_data);\n const data = possibleData ?? _data;\n const { email, password, preferredName, newTenant, ...metadata } = data;\n if (Object.keys(metadata).length > 0) {\n // eslint-disable-next-line no-console\n console.warn('additional metadata not supported yet.');\n }\n return api.auth.signUp({\n signUpRequest: { email, password, preferredName, newTenant },\n });\n },\n {\n onSuccess,\n onError: (e: Error, vars) => {\n setError(e.message);\n onError && onError(e as Error, vars);\n },\n }\n );\n\n const completeAttributes = React.useMemo(() => {\n const mainAttributes: Attribute[] = [\n {\n name: 'email',\n label: 'Email',\n type: AttributeType.Text,\n defaultValue: '',\n required: true,\n },\n {\n name: 'password',\n label: 'Password',\n type: AttributeType.Password,\n defaultValue: '',\n required: true,\n },\n ];\n if (attributes && attributes.length > 0) {\n return mainAttributes.concat(attributes);\n }\n return mainAttributes;\n }, [attributes]);\n\n return (\n <Stack gap={2}>\n {error ? <Alert color=\"danger\">{error}</Alert> : null}\n <UserForm\n mutation={mutation}\n buttonText={buttonText}\n attributes={completeAttributes}\n />\n </Stack>\n );\n}\n","import { DataGrid } from '@mui/x-data-grid';\nimport React from 'react';\nimport Stack from '@mui/joy/Stack';\nimport { SxProps } from '@mui/system/styleFunctionSx/styleFunctionSx';\nimport { Theme } from '@mui/system/createTheme';\nimport { SignUp201Response, User } from '@niledatabase/browser';\n\nimport CreateUser from './CreateUser';\nimport useDataParser from './useDataParser';\n\ntype ColumnNames = string;\n\ntype Props = {\n data: void | User[];\n allowCreation?: boolean;\n buttonText?: string;\n onUserCreateSuccess?: (user: SignUp201Response) => void;\n slots?: {\n dataGrid?: SxProps<Theme>;\n };\n // white list of columns to show\n include?: ColumnNames[];\n};\n\nexport default function UserList(props: Props) {\n const {\n data,\n allowCreation = true,\n buttonText = 'Add a user',\n onUserCreateSuccess,\n slots,\n include = ['email', 'preferedName'],\n } = props;\n\n const dataGridSx = {\n width: '100%',\n height: '100%',\n ...(slots?.dataGrid ?? {}),\n };\n\n const [columns, rows] = useDataParser(data, include);\n return (\n <Stack flex={1}>\n <CreateUser\n allowCreation={allowCreation}\n buttonText={buttonText}\n onUserCreateSuccess={onUserCreateSuccess}\n />\n <DataGrid\n sx={dataGridSx}\n rows={rows}\n columns={columns}\n hideFooter={true}\n />\n </Stack>\n );\n}\n","import { useEffect, useState } from 'react';\n\nexport default function useTextSizer() {\n const [ctx, setCtx] = useState<CanvasRenderingContext2D>();\n useEffect(() => {\n const canvas = document.createElement('canvas');\n const canvasContext = canvas.getContext('2d');\n if (canvasContext) {\n canvasContext.font = '18px Roboto';\n setCtx(canvasContext);\n }\n }, []);\n return ctx;\n}\n","import { GridRowsProp } from '@mui/x-data-grid';\n\nexport default function getColumnSize(\n column: unknown,\n rows: GridRowsProp,\n canvasContext: void | CanvasRenderingContext2D\n) {\n const dataWidthReducer = (\n longest: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n nextRow: { [key: string]: any }\n ) => {\n let value = nextRow[String(column)];\n if (value == null) {\n value = '';\n }\n value = value?.toString();\n return longest.length > value.length ? longest : value;\n };\n\n let columnHeaderLen =\n canvasContext && column\n ? canvasContext.measureText(String(column)).width\n : 50;\n /* padding 12, icon-width 15 */\n columnHeaderLen += 15 + 12;\n\n let width = columnHeaderLen;\n width =\n 16 +\n Math.ceil(\n canvasContext\n ? canvasContext.measureText(rows.reduce(dataWidthReducer, '')).width\n : 50\n );\n if (width < columnHeaderLen) {\n width = columnHeaderLen;\n }\n /* Gracefull */\n width += 8;\n return width;\n}\n"],"names":["Themer","theme","children","slotProps","React","JoyCssVarsProvider","createElement","CssBaseline","enableColorScheme","queryClient","QueryClient","context","createContext","api","Browser","basePath","credentials","apiUrl","Provider","BaseQueryProvider","QueryClientProvider","client","useNileContext","useContext","useNileConfig","tenantId","appUrl","useMemo","useApi","_g","_extends","Object","assign","bind","target","i","arguments","length","source","key","prototype","hasOwnProperty","call","apply","this","AttributeType","SvgGoogle","props","xmlns","width","height","fillRule","fill","d","CheckGroup","options","attribute","display","helperText","watch","control","useFormContext","currentVals","name","checkProps","color","Controller","rules","required","Boolean","render","field","Stack","FormLabel","htmlFor","label","Box","role","sx","borderRadius","p","border","List","orientation","wrap","map","item","id","String","value","ListItem","Checkbox","overlay","checked","includes","disableIcon","variant","onChange","event","allowMultiple","concat","remaining","filter","val","Typography","level","FormAttributeType","getAttributeDefault","Array","isArray","defaultValue","Labler","error","attr","Tooltip","title","cursor","Error","ml","fontSize","SimpleForm","mutation","buttonText","attributes","cancelButton","loading","successMessage","defaultValues","reduce","accum","methods","useForm","register","handleSubmit","formState","errors","onSubmit","useCallback","data","mutate","FormProvider","component","spacing","fieldConfig","placeholder","disabled","helpText","type","Switch","FormControl","alignItems","FormHelperText","endDecorator","Select","_","newValue","option","Option","Password","Input","Number","Text","direction","Button","gap","AddUser","open","setOpen","refetch","errorText","setErrorText","useState","email","useEffect","useMutation","users","createTenantUser","signUpRequest","onSuccess","onError","e","message","handleUpdate","async","Modal","ModalDialog","Fragment","fullWidth","size","autoComplete","pt","onClick","CreateUser","allowCreation","onUserCreateSuccess","UserModal","startDecorator","Add","makeRenderable","vals","keys","cleaned","Set","from","join","BaseSSOForm","config","providerName","allowEdit","configurationGuide","setLoading","success","setSuccess","optimisticConfig","setConfig","timer","useRef","enabled","clientId","configUrl","emailDomains","splice","ssoRequest","payload","toLowerCase","updateProviderRequest","split","auth","updateProvider","createProvider","vars","onSettled","current","clearTimeout","setTimeout","position","Alert","opacity","transition","CheckCircleOutlined","textAlign","ConfigGuide","callbackUrl","copied","setCopied","fontFamily","navigator","clipboard","writeText","input","span","palette","primary","readOnly","top","left","CopyAll","newTenantName","console","contextHref","query","encodeURIComponent","href","flex","textDecoration","padding","textTransform","boxShadow","fontWeight","backgroundColor","background","GoogleLogo","QueryProvider","values","ThemeProvider","provider","providers","find","beforeMutate","nextButtonText","loginButtonText","disableSSO","setButtonText","_data","login","loginRequest","password","sso","token","redirectURI","window","location","completeAttributes","mainAttributes","push","setError","undefined","preferredName","newTenant","metadata","warn","signUp","UserForm","slots","include","dataGridSx","dataGrid","columns","rows","ctx","setCtx","canvasContext","document","getContext","font","useTextSizer","cols","parseResults","fields","existentCols","col","column","columnHeaderLen","measureText","Math","ceil","dataWidthReducer","longest","nextRow","toString","getColumnSize","slice","padEnd","headerName","useDataParser","DataGrid","hideFooter"],"mappings":"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"}
package/dist/react.esm.js CHANGED
@@ -48,7 +48,7 @@ const defaultContext = {
48
48
  basePath: 'https://api.thenile.dev',
49
49
  credentials: 'include'
50
50
  }),
51
- basePath: ''
51
+ apiUrl: ''
52
52
  };
53
53
  const context = /*#__PURE__*/createContext(defaultContext);
54
54
  const {
@@ -68,19 +68,20 @@ const NileProvider = props => {
68
68
  slotProps,
69
69
  tenantId,
70
70
  QueryProvider = BaseQueryProvider,
71
- basePath = 'https://api.thenile.dev',
71
+ appUrl,
72
+ apiUrl = 'https://api.thenile.dev',
72
73
  api
73
74
  } = props;
74
75
  const values = useMemo(() => {
75
76
  return {
76
77
  api: api ?? new Browser({
77
- basePath,
78
+ basePath: appUrl,
78
79
  credentials: 'include'
79
80
  }),
80
81
  tenantId: String(tenantId),
81
- basePath
82
+ apiUrl
82
83
  };
83
- }, [api, basePath, tenantId]);
84
+ }, [api, apiUrl, appUrl, tenantId]);
84
85
  return /*#__PURE__*/React__default.createElement(QueryProvider, null, /*#__PURE__*/React__default.createElement(Themer, {
85
86
  slotProps: slotProps?.provider,
86
87
  theme: theme
@@ -93,13 +94,15 @@ const useNileContext = () => {
93
94
  };
94
95
  const useNileConfig = () => {
95
96
  const {
96
- basePath,
97
- tenantId
97
+ apiUrl,
98
+ tenantId,
99
+ appUrl
98
100
  } = useNileContext();
99
101
  return useMemo(() => ({
100
102
  tenantId,
101
- basePath
102
- }), [basePath, tenantId]);
103
+ apiUrl,
104
+ appUrl
105
+ }), [apiUrl, tenantId, appUrl]);
103
106
  };
104
107
  const useApi = () => {
105
108
  return useNileContext().api;
@@ -141,16 +144,18 @@ const LOGIN_PATH = 'users/oidc/google/login';
141
144
  */
142
145
  function GoogleSSOButton(props) {
143
146
  const {
144
- databaseId,
145
147
  newTenantName
146
148
  } = props;
147
149
  const {
148
- basePath
150
+ apiUrl
149
151
  } = useNileConfig();
150
- const encodedDatabase = encodeURIComponent(databaseId ?? '');
151
- const contextHref = `${basePath}/databases/${encodedDatabase}/${LOGIN_PATH}`;
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}`;
152
157
  const query = newTenantName ? '?newTenant=' + encodeURIComponent(newTenantName) : '';
153
- const href = (props?.href ?? contextHref) + query;
158
+ const href = contextHref + query;
154
159
  return /*#__PURE__*/React__default.createElement(Box, {
155
160
  component: "a",
156
161
  href: href,