unleash-server 4.22.0-beta.70 → 4.22.0-beta.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/{CreateProject-65c29957.js → CreateProject-0afa3d7c.js} +1 -1
- package/frontend/build/static/{Error-1bc0ccc7.js → Error-15da3f9c.js} +1 -1
- package/frontend/build/static/{ExpandMore-ddba62ef.js → ExpandMore-26c5bb2a.js} +1 -1
- package/frontend/build/static/{FeatureArchiveDialog-5afa5368.js → FeatureArchiveDialog-f945f344.js} +1 -1
- package/frontend/build/static/{FeatureMetricsChart-ac24b16f.js → FeatureMetricsChart-1b77414e.js} +1 -1
- package/frontend/build/static/FeatureViewLazyExport-d17ac05e.js +9 -0
- package/frontend/build/static/{LazyAdminExport-86e7b4ee.js → LazyAdminExport-4f4f3ff2.js} +2 -2
- package/frontend/build/static/{LazyProjectExport-3510d3a3.js → LazyProjectExport-2230f8eb.js} +1 -1
- package/frontend/build/static/{NetworkOverview-af010e9a.js → NetworkOverview-ac162219.js} +1 -1
- package/frontend/build/static/{NetworkTraffic-55e0e1d9.js → NetworkTraffic-972ed1cf.js} +1 -1
- package/frontend/build/static/{Playground-5d9f3c15.js → Playground-8f02bada.js} +1 -1
- package/frontend/build/static/{StrategyItemContainer-6dd7bd76.js → StrategyItemContainer-c8be6a3f.js} +1 -1
- package/frontend/build/static/{chartjs-adapter-date-fns.esm-7ece37b1.js → chartjs-adapter-date-fns.esm-0a652e55.js} +1 -1
- package/frontend/build/static/{index-f0c81751.js → index-bb86461e.js} +1 -1
- package/frontend/build/static/{index-6f489e06.js → index-c1725653.js} +1 -1
- package/frontend/build/static/{index-37d1201a.js → index-c6225d46.js} +41 -41
- package/frontend/build/static/{unknownify-26769500.js → unknownify-006fffb3.js} +1 -1
- package/frontend/build/static/{useProjectRole-2d15f932.js → useProjectRole-35fa370c.js} +1 -1
- package/package.json +1 -1
- package/frontend/build/static/FeatureViewLazyExport-7f2f962e.js +0 -9
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
href="https://fonts.googleapis.com/css2?family=Sen:wght@400;700;800&display=swap"
|
|
17
17
|
rel="stylesheet"
|
|
18
18
|
/>
|
|
19
|
-
<script type="module" crossorigin src="/static/index-
|
|
19
|
+
<script type="module" crossorigin src="/static/index-c6225d46.js"></script>
|
|
20
20
|
<link rel="stylesheet" href="/static/index-1fa04e71.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a2 as N,aq as w,H as I,ar as D,as as U,at as x,au as O,j as t,av as _,aw as b,ax as F,ay as L,a4 as R,az as $}from"./index-
|
|
1
|
+
import{a2 as N,aq as w,H as I,ar as D,as as U,at as x,au as O,j as t,av as _,aw as b,ax as F,ay as L,a4 as R,az as $}from"./index-c6225d46.js";const K=()=>{const{setToastData:n,setToastApiError:i}=N(),{refetchUser:d}=w(),{uiConfig:l}=I(),a=D(),{projectId:e,projectName:u,projectDesc:j,setProjectId:p,setProjectName:m,setProjectDesc:P,getProjectPayload:o,clearErrors:s,validateProjectId:r,validateName:h,setProjectStickiness:f,projectStickiness:g,errors:C}=U(),{createProject:y,loading:S}=x(),{setDefaultProjectStickiness:v}=O(e);return t(_,{loading:S,title:"Create project",description:"Projects allows you to group feature toggles together in the management UI.",documentationLink:"https://docs.getunleash.io/reference/projects",documentationLinkLabel:"Projects documentation",formatApiCode:()=>`curl --location --request POST '${l.unleashUrl}/api/admin/projects' \\
|
|
2
2
|
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
3
|
--header 'Content-Type: application/json' \\
|
|
4
4
|
--data-raw '${JSON.stringify(o(),void 0,2)}'`,children:t(b,{errors:C,handleSubmit:async A=>{A.preventDefault(),s();const T=h(),k=await r();if(T&&k){const c=o();try{await y(c),v(c.projectStickiness),d(),a(`/projects/${e}`),n({title:"Project created",text:"Now you can add toggles to this project",confetti:!0,type:"success"})}catch(E){i(R(E))}}},handleCancel:()=>{a($)},projectId:e,setProjectId:p,projectName:u,projectStickiness:g,setProjectStickiness:f,setProjectName:m,projectDesc:j,setProjectDesc:P,mode:"Create",clearErrors:s,validateProjectId:r,children:t(F,{name:"project",permission:L})})})};export{K as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as r,j as o}from"./index-
|
|
1
|
+
import{c as r,j as o}from"./index-c6225d46.js";const a=r(o("path",{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"}),"Error");export{a as E};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a,j as o}from"./index-
|
|
1
|
+
import{c as a,j as o}from"./index-c6225d46.js";const e=a(o("path",{d:"M16.59 8.59 12 13.17 7.41 8.59 6 10l6 6 6-6z"}),"ExpandMore");export{e as E};
|
package/frontend/build/static/{FeatureArchiveDialog-5afa5368.js → FeatureArchiveDialog-f945f344.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{c as B,j as r,aH as R,b0 as w,f as p,aZ as T,C as E,A as J,T as C,c1 as Q,ct as x,r as d,cu as Z,cv as X,a_ as ee,a$ as P,a2 as b,H as te,ar as z,aI as D,aU as ae,cw as ne,av as se,ap as re,cx as oe,cy as ce,cz as ie,cA as ue,b7 as L,cB as le,b1 as ge,a4 as S,cC as de,s as $,aY as he,cD as ye,cE as fe,F as pe,bA as j}from"./index-
|
|
1
|
+
import{c as B,j as r,aH as R,b0 as w,f as p,aZ as T,C as E,A as J,T as C,c1 as Q,ct as x,r as d,cu as Z,cv as X,a_ as ee,a$ as P,a2 as b,H as te,ar as z,aI as D,aU as ae,cw as ne,av as se,ap as re,cx as oe,cy as ce,cz as ie,cA as ue,b7 as L,cB as le,b1 as ge,a4 as S,cC as de,s as $,aY as he,cD as ye,cE as fe,F as pe,bA as j}from"./index-c6225d46.js";const Re=B(r("path",{d:"m20.54 5.23-1.39-1.68C18.88 3.21 18.47 3 18 3H6c-.47 0-.88.21-1.16.55L3.46 5.23C3.17 5.57 3 6.02 3 6.5V19c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V6.5c0-.48-.17-.93-.46-1.27zM12 17.5 6.5 12H10v-2h4v2h3.5L12 17.5zM5.12 5l.81-1h12l.94 1H5.12z"}),"Archive"),Ee=B(r("path",{d:"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2zm4.2 14.2L11 13V7h1.5v5.2l4.5 2.7-.8 1.3z"}),"WatchLater"),we=({isOpen:e,onConfirm:t,onClose:a,showBanner:n,environment:s,messageComponent:o})=>{const c=R("projectId"),{data:l}=w(c),{changeRequestInReviewOrApproved:u,alert:g}=Q(l),i=u(s||"");return p(T,{open:e,primaryButtonText:i?"Add to existing change request":"Add suggestion to draft",secondaryButtonText:"Cancel",onClick:t,onClose:a,title:"Request changes",fullWidth:!0,children:[r(E,{condition:i,show:g}),r(E,{condition:Boolean(n),show:p(J,{severity:"info",sx:{mb:2},children:["Change requests feature is enabled for ",s,". Your changes need to be approved before they will be live. All the changes you do now will be added into a draft that you can submit for review."]})}),r(C,{variant:"body2",color:"text.secondary",children:"Your suggestion:"}),o]})},me=(e,t)=>{const a={};return t.parameters.forEach(n=>{a[n.name]=ve(e,n)}),{name:t.name,constraints:[],parameters:a}},ve=(e,t)=>t.name==="rollout"||t.name==="percentage"||t.type==="percentage"?"50":t.name==="stickiness"?"":t.name==="groupId"?e:t.type==="boolean"?"false":"",Fe=()=>{const e=R("projectId"),t=R("featureId"),a=x("environmentId"),n=x("strategyName"),[s,o]=d.useState({}),[c,l]=d.useState([]),{strategyDefinition:u}=Z(n),g=X(),{addStrategyToFeature:i,loading:h}=ee(),{addChange:m}=P(),{setToastData:v,setToastApiError:N}=b(),{uiConfig:O}=te(),{unleashUrl:Y}=O,W=z(),{feature:y,refetchFeature:F}=D(e,t),q=d.useRef(y),{isChangeRequestConfigured:k}=ae(e),{refetch:_}=w(e),{data:A,staleDataNotification:H,forceRefreshCache:U}=ne({unleashGetter:D,params:[e,t],dataKey:"feature",refetchFunctionKey:"refetchFeature",options:{}},y,{afterSubmitAction:F},de);d.useEffect(()=>{q.current.name===""&&y.name&&(U(y),q.current=y)},[y]),d.useEffect(()=>{u&&o(me(t,u))},[t,u]);const V=async f=>{await i(e,t,a,f),v({title:"Strategy created",type:"success",confetti:!0})},M=async f=>{await m(e,a,{action:"addStrategy",feature:t,payload:f}),v({title:"Strategy added to draft",type:"success",confetti:!0}),_()},G=async()=>{const f=le(s,c);try{k(a)?await M(f):await V(f),F(),W(ge(e,t))}catch(K){N(S(K))}};return!A||!A.project?null:p(se,{modal:!0,title:re(n),description:oe,documentationLink:ce,documentationLinkLabel:ie,formatApiCode:()=>Te(e,t,a,s,Y),children:[r(ue,{projectId:e,feature:A,strategy:s,setStrategy:o,segments:c,setSegments:l,environmentId:a,onSubmit:G,loading:h,permission:L,errors:g,isChangeRequest:k(a)}),H]})},Ce=(e,t,a,n)=>{const s=new URLSearchParams({environmentId:a,strategyName:n});return`/projects/${e}/features/${t}/strategies/create?${s}`},Te=(e,t,a,n,s)=>{if(!s)return"";const o=`${s}/api/admin/projects/${e}/features/${t}/environments/${a}/strategies`,c=JSON.stringify(n,void 0,2);return`curl --location --request POST '${o}' \\
|
|
2
2
|
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
3
|
--header 'Content-Type: application/json' \\
|
|
4
4
|
--data-raw '${c}'`},I=$("p")(({theme:e})=>({marginBottom:e.spacing(.5),fontSize:e.fontSizes.bodySize})),qe=({open:e,environmentName:t,featureId:a,projectId:n,onClose:s})=>{const o=z(),c=Ce(n,a,t,"default");return p(T,{open:e,maxWidth:"sm",onClose:()=>s(),title:"You need to add a strategy to your toggle",primaryButtonText:"Take me directly to add strategy",permissionButton:r(he,{type:"button",permission:L,projectId:n,environmentId:t,onClick:()=>{s(),o(c)},children:"Take me directly to add strategy"}),secondaryButtonText:"Cancel",children:[r(I,{children:"Before you can enable the toggle in the environment, you need to add an activation strategy."}),r(I,{children:"You can add the activation strategy by selecting the toggle, open the environment accordion and add the activation strategy."})]})},ke="You can not enable the environment before it has strategies",xe=e=>{const{setToastData:t,setToastApiError:a}=b(),{addChange:n}=P(),{refetch:s}=w(e),[o,c]=d.useState({isOpen:!1}),l=d.useCallback((i,h,m)=>{c({featureName:i,environment:h,enabled:m,isOpen:!0})},[]),u=d.useCallback(()=>{c(i=>({...i,isOpen:!1}))},[]),g=d.useCallback(async()=>{try{await n(e,o.environment,{feature:o.featureName,action:"updateEnabled",payload:{enabled:Boolean(o.enabled)}}),s(),c(i=>({...i,isOpen:!1})),t({type:"success",title:"Changes added to the draft!"})}catch(i){a(S(i)),c(h=>({...h,isOpen:!1}))}},[n]);return{onChangeRequestToggle:l,onChangeRequestToggleClose:u,onChangeRequestToggleConfirm:g,changeRequestDialogDetails:o}},De=({enabled:e,featureName:t,environment:a})=>p(C,{"data-testid":"update-enabled-message",children:[r("strong",{children:e?"Enable":"Disable"})," feature toggle"," ",r("strong",{children:t})," in ",r("strong",{children:a})]}),be=$(ye)(({theme:e})=>({color:e.palette.warning.main,fontSize:e.fontSizes.bodySize})),Ie=()=>r(fe,{arrow:!0,title:p(pe,{children:["This environment has no variants enabled. If you check this feature's variants in this environment, you will get the"," ",r("a",{href:"https://docs.getunleash.io/reference/feature-toggle-variants#the-disabled-variant",target:"_blank",rel:"noreferrer",children:"disabled variant"}),"."]}),children:r(be,{})}),Be=({isStale:e,isOpen:t,projectId:a,featureId:n,onClose:s})=>{const{setToastData:o,setToastApiError:c}=b(),{patchFeatureToggle:l}=j(),u=r(C,{children:"Setting a toggle to stale marks it for cleanup"}),g=r(C,{children:"Setting a toggle to active marks it as in active use"}),i=e?"active":"stale",h=async m=>{m.stopPropagation();try{await l(a,n,[{op:"replace",path:"/stale",value:!e}]),s()}catch(v){c(S(v))}o(e?{type:"success",title:"And we're back!",text:"The toggle is no longer marked as stale."}:{type:"success",title:"A job well done.",text:"The toggle has been marked as stale."})};return r(T,{open:t,secondaryButtonText:"Cancel",primaryButtonText:`Flip to ${i}`,title:`Set feature state to ${i}`,onClick:h,onClose:s,children:r(E,{condition:e,show:g,elseShow:u})})},Pe=({isOpen:e,onClose:t,onConfirm:a,projectId:n,featureId:s})=>{const{archiveFeatureToggle:o}=j(),{setToastData:c,setToastApiError:l}=b(),u=async()=>{try{await o(n,s),c({text:"Your feature toggle has been archived",type:"success",title:"Feature archived"}),a(),t()}catch(g){l(S(g)),t()}};return r(T,{onClick:()=>u(),open:e,onClose:t,primaryButtonText:"Archive toggle",secondaryButtonText:"Cancel",title:"Archive feature toggle",children:"Are you sure you want to archive this feature toggle?"})};export{Re as A,we as C,ke as E,Fe as F,De as U,Ie as V,Ee as W,qe as a,Pe as b,Be as c,Ce as f,xe as u};
|
package/frontend/build/static/{FeatureMetricsChart-ac24b16f.js → FeatureMetricsChart-1b77414e.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c9 as i,f3 as p,bv as y,r as l,j as u}from"./index-
|
|
1
|
+
import{c9 as i,f3 as p,bv as y,r as l,j as u}from"./index-c6225d46.js";import{d as c,L as g,C as h,a as C,b as f,P as x,c as S,T as q,p as v,e as M,f as k}from"./chartjs-adapter-date-fns.esm-0a652e55.js";import"./index-c1725653.js";import"./index-bb86461e.js";const L=(t,s)=>{const o={label:"total requests",borderColor:i.palette.primary.main,backgroundColor:i.palette.primary.main,data:n(t,s,r=>r.yes+r.no),elements:{point:{radius:6,pointStyle:"circle"},line:{borderDash:[8,4]}}},e={label:"exposed",borderColor:i.palette.success.main,backgroundColor:i.palette.success.main,data:n(t,s,r=>r.yes),elements:{point:{radius:6,pointStyle:"triangle"}}},a={label:"not exposed",borderColor:i.palette.error.main,backgroundColor:i.palette.error.main,data:n(t,s,r=>r.no),elements:{point:{radius:6,pointStyle:"triangle",pointRotation:180}}};return{datasets:[e,a,o]}},n=(t,s,o)=>t.map(e=>({x:e.timestamp,y:o(e)})),P=(t,s,o)=>({locale:o.locale,responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},plugins:{tooltip:{backgroundColor:"white",bodyColor:i.palette.text.primary,titleColor:i.palette.action.active,borderColor:i.palette.primary.main,borderWidth:1,padding:10,boxPadding:5,usePointStyle:!0,callbacks:{title:e=>p(e[0].parsed.x,o.locale)},itemSort:(e,a)=>a.parsed.y-e.parsed.y},legend:{position:"top",align:"end",labels:{boxWidth:10,boxHeight:10,usePointStyle:!0}},title:{text:w(s),position:"top",align:"start",display:!0,font:{size:16,weight:"400"}}},scales:{y:{type:"linear",title:{display:!0,text:"Number of requests"},suggestedMin:0,ticks:{precision:0}},x:{type:"time",time:{unit:"hour"},grid:{display:!1},ticks:{callback:(e,a,r)=>p(r[a].value,o.locale)}}}}),w=t=>t===1?"Requests in the last hour":`Requests in the last ${t} hours`;c.font={...c.font,family:"Sen",size:13,weight:"400"};const j=({metrics:t,hoursBack:s,statsSectionId:o})=>{const{locationSettings:e}=y(),a=l.useMemo(()=>[...t].sort((m,b)=>m.timestamp.localeCompare(b.timestamp)),[t]),r=l.useMemo(()=>P(a,s,e),[a,s,e]),d=l.useMemo(()=>L(a,e),[a,e]);return u("div",{style:{height:400},children:u(g,{options:r,data:d,"aria-label":"A feature metrics line chart, with three lines: all requests, positive requests, and negative requests.","aria-describedby":o})})};h.register(C,f,x,S,q,v,M,k);export{j as FeatureMetricsChart,j as default};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{aA as Tn,aB as xn,s as d,r as y,aC as An,aD as En,aE as gt,j as t,aF as In,aG as Rn,c as Nt,aH as R,aI as N,aJ as Fn,f as l,aK as kn,C as I,aL as X,aM as ie,aN as Q,aO as ye,aP as Pn,aQ as et,aR as pe,aS as Ce,aT as $e,u as ve,aU as ae,F as O,aV as ht,aW as mt,aX as tt,aY as oe,aZ as le,T as _,a_ as we,a2 as G,ar as ge,a$ as nt,b0 as Te,A as he,b1 as zt,a4 as z,b2 as $n,b3 as Bn,b4 as On,b5 as Dn,ap as xe,b6 as Vn,b7 as ce,b8 as Z,m as Be,b9 as Ln,ba as Mn,bb as Oe,a8 as De,bc as Wt,bd as Ht,be as at,bf as _n,bg as jn,bh as Nn,a as U,p as zn,N as de,B as Se,bi as ot,a9 as re,bj as Wn,x as rt,an as Re,E as Hn,bk as st,bl as Fe,P as qn,bm as Un,bn as ee,bo as Gn,bp as Yn,D as Kn,bq as Jn,br as Xn,bs as Qn,bt as qt,bu as Zn,bv as ea,bw as ta,bx as na,by as aa,bz as oa,bA as Ae,bB as ra,bC as sa,bD as ia,bE as Ut,ad as it,ac as Ve,bF as Gt,bG as Yt,w as lt,bH as la,bI as ca,bJ as da,bK as ua,Z as pa,bL as Kt,bM as ga,af as ke,bN as ha,bO as Ke,bP as Jt,bQ as Xt,bR as ne,bS as Je,bT as ma,bU as Qt,a3 as ct,bV as fa,bW as Zt,bX as ya,bY as Sa,bZ as en,b_ as ba,H as dt,au as Ca,av as va,b$ as me,c0 as ft,c1 as wa,c2 as tn,l as te,c3 as Xe,c4 as nn,R as Ta,b as xa,Q as Aa,d as fe,e as Ea,U as an,X as Ia,g as on,S as rn,h as sn,i as ln,k as cn,W as Ra,c5 as Fa,ak as ut,al as ka,V as yt,c6 as Pa,c7 as $a,c8 as Ba,c9 as dn,I as Oa,ca as Da,cb as Va,cc as St,cd as La,ce as un,cf as Ma,ae as _a,cg as bt,ch as ja,ci as Na,cj as za,ck as Wa,cl as Ha,cm as qa,M as Ua,cn as Ga,co as Ya,cp as Ka,cq as Ja,cr as Xa,cs as Qa}from"./index-c6225d46.js";import{C as Le,f as Za,u as eo,U as to,E as no,V as ao,a as oo,F as ro,A as so,W as io,b as lo,c as co}from"./FeatureArchiveDialog-f945f344.js";import{S as uo}from"./StrategyItemContainer-c8be6a3f.js";import{E as po}from"./ExpandMore-26c5bb2a.js";import{v as je}from"./v4-a960c1f4.js";function go(e){return Tn("MuiCardContent",e)}xn("MuiCardContent",["root"]);const ho=["className","component"],mo=e=>{const{classes:n}=e;return Rn({root:["root"]},go,n)},fo=d("div",{name:"MuiCardContent",slot:"Root",overridesResolver:(e,n)=>n.root})(()=>({padding:16,"&:last-child":{paddingBottom:24}})),yo=y.forwardRef(function(n,a){const r=An({props:n,name:"MuiCardContent"}),{className:o,component:i="div"}=r,s=En(r,ho),c=gt({},r,{component:i}),u=mo(c);return t(fo,gt({as:i,className:In(u.root,o),ownerState:c,ref:a},s))}),So=yo,bo=Nt(t("path",{d:"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"}),"Assessment"),Co=Nt(t("path",{d:"M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96z"}),"Cloud"),vo=d("div")(({theme:e})=>({borderRadius:e.spacing(1.5),backgroundColor:e.palette.background.paper,padding:e.spacing(4)})),wo=()=>{const e=R("projectId"),n=R("featureId"),{feature:a}=N(e,n);return a.name?t(vo,{children:t(Fn,{title:"Event log",feature:n,displayInline:!0})}):null},To=d("div")(({theme:e})=>({borderRadius:e.shape.borderRadiusLarge,color:e.palette.primary.contrastText,backgroundColor:e.palette.background.sidebar,display:"flex",flexDirection:"column",maxWidth:"350px",minWidth:"350px",marginRight:e.spacing(2),[e.breakpoints.down(1e3)]:{width:"100%",maxWidth:"none",minWidth:"auto"}})),xo=d("div")({padding:"1.5rem 1.5rem 0 1.5rem"}),Ao=d("div")({display:"flex",alignItems:"center"}),Eo=d("h2")(({theme:e})=>({fontSize:e.fontSizes.bodySize,fontWeight:"normal",margin:0})),Io=d("div")(({theme:e})=>({margin:e.spacing(2,0),display:"flex",flexDirection:"column"})),Ct=d("span")(({theme:e})=>({margin:e.spacing(1,0),fontSize:e.fontSizes.bodySize,wordBreak:"break-all"})),vt=d("div")(({theme:e})=>({display:"flex",alignItems:"center",color:e.palette.primary.contrastText})),Ro=()=>{const e=R("projectId"),n=R("featureId"),{feature:a}=N(e,n),{project:r,description:o,type:i}=a,s=Pn(i);return t(To,{children:l(xo,{children:[l(Ao,{"data-loading":!0,children:[t(s,{sx:c=>({marginRight:c.spacing(2),height:"40px",width:"40px",fill:c.palette.primary.contrastText})})," ",l(Eo,{children:[kn(i||"")," toggle"]})]}),l(Io,{children:[l(Ct,{"data-loading":!0,children:["Project: ",r]}),t(I,{condition:Boolean(o),show:l(Ct,{"data-loading":!0,children:[t("div",{children:"Description:"}),l(vt,{children:[t("p",{children:o}),t(X,{projectId:e,permission:ie,component:Q,to:`/projects/${e}/features/${n}/settings`,tooltipProps:{title:"Edit description"},children:t(ye,{sx:c=>({color:c.palette.primary.contrastText})})})]})]}),elseShow:t("span",{"data-loading":!0,children:l(vt,{children:["No description."," ",t(X,{projectId:e,permission:ie,component:Q,to:`/projects/${e}/features/${n}/settings`,tooltipProps:{title:"Edit description"},children:t(ye,{sx:c=>({color:c.palette.primary.contrastText})})})]})})})]})]})})},wt={lastHourUsage:[],seenApplications:[]},Fo=(e,n,a={})=>{const r=async()=>{const g=pe(`api/admin/client-metrics/features/${n}`),h=await fetch(g,{method:"GET"}).then(Ce("feature metrics"));return h.ok?h.json():wt},o=`${e}_${n}_metrics`,{data:i,error:s}=et(o,r,{...a}),[c,u]=y.useState(!s&&!i),p=()=>{$e(o)};return y.useEffect(()=>{u(!s&&!i)},[i,s]),{metrics:i||wt,error:s,loading:c,refetch:p,FEATURE_METRICS_CACHE_KEY:o}},ko=e=>({yes:0,no:0,environment:e,timestamp:""}),Po=(e,n)=>e.map(a=>n.lastHourUsage.find(o=>o.environment===a.name)||ko(a.name)),$o=({enabled:e,className:n})=>{const a=ve(),r=e?"Environment enabled":"Environment disabled",o={backgroundColor:e?a.palette.primary.light:a.palette.neutral.border,borderRadius:"50%",width:"28px",height:"28px",minWidth:"28px",display:"flex",alignItems:"center",justifyContent:"center",marginRight:a.spacing(1)};return t("div",{style:o,className:n,children:t(Co,{style:{fill:"#fff",width:"16px",height:"16px"},titleAccess:r})})},pn=()=>t(he,{severity:"error",children:"Removing the strategy will change which users receive access to the feature."}),Bo=({onRemove:e,onClose:n,isOpen:a})=>t(le,{title:"Are you sure you want to delete this strategy?",open:a,primaryButtonText:"Remove strategy",secondaryButtonText:"Cancel",onClick:e,onClose:n,children:t(pn,{})}),Oo=d("div")(({theme:e})=>({marginTop:e.spacing(3),marginBottom:e.spacing(1)})),Do=({onRemove:e,onClose:n,isOpen:a})=>l(le,{title:"Suggest changes",open:a,primaryButtonText:"Add suggestion to draft",secondaryButtonText:"Cancel",onClick:e,onClose:n,children:[t(pn,{}),t(Oo,{children:t(_,{variant:"body2",color:"text.secondary",children:"Your suggestion:"})}),t(_,{fontWeight:"bold",children:"Remove strategy"})]}),Vo=({projectId:e,featureId:n,environmentId:a,strategyId:r})=>{const{deleteStrategyFromFeature:o}=we(),{setToastData:i,setToastApiError:s}=G(),c=ge(),{refetchFeature:u}=N(e,n);return async g=>{try{g.preventDefault(),await o(e,n,a,r),i({title:"Strategy deleted",type:"success"}),u(),c(zt(e,n))}catch(h){s(z(h))}}},Lo=({projectId:e,featureId:n,environmentId:a,strategyId:r})=>{const{addChange:o}=nt(),{refetch:i}=Te(e),{setToastData:s,setToastApiError:c}=G();return async p=>{try{p.preventDefault(),await o(e,a,{action:"deleteStrategy",feature:n,payload:{id:r}}),s({title:"Changes added to the draft!",type:"success"}),await i()}catch(g){c(z(g))}}},Mo=({projectId:e,featureId:n,environmentId:a,strategyId:r,disabled:o,icon:i})=>{const[s,c]=y.useState(!1),{isChangeRequestConfigured:u}=ae(e),p=Vo({featureId:n,projectId:e,strategyId:r,environmentId:a}),g=Lo({featureId:n,projectId:e,strategyId:r,environmentId:a});return l(O,{children:[t(I,{condition:Boolean(i),show:t(X,{onClick:()=>c(!0),projectId:e,environmentId:a,disabled:o,permission:ht,"data-testid":mt,tooltipProps:{title:"Remove strategy"},type:"button",children:t(tt,{})}),elseShow:t(oe,{onClick:()=>c(!0),projectId:e,environmentId:a,disabled:o,permission:ht,"data-testid":mt,color:"secondary",variant:"text",type:"button",children:"Remove strategy"})}),t(I,{condition:u(a),show:t(Do,{isOpen:s,onClose:()=>c(!1),onRemove:async h=>{await g(h),c(!1)}}),elseShow:t(Bo,{isOpen:s,onClose:()=>c(!1),onRemove:p})})]})},_o=e=>(n,a,r)=>(r.revalidateOnFocus=!1,r.revalidateIfStale=!1,r.revalidateOnReconnect=!1,e(n,a,r));var jo=$n(et,_o);const gn=(e,n)=>{const{refetchFeature:a}=N(e,n),r=Bn(e,n),{data:o,error:i,mutate:s}=jo(["useFeatureImmutable",r],()=>On(r)),c=y.useCallback(async()=>{await s(),await a()},[s,a]);return{feature:(o==null?void 0:o.body)||Dn,refetchFeature:c,loading:!i&&!o,status:o==null?void 0:o.status,error:i}},pt=(e,n,a)=>{const{setToastData:r,setToastApiError:o}=G(),{addChange:i}=nt(),{refetch:s}=Te(e),[c,u]=y.useState({isOpen:!1}),p=y.useCallback((T,A,f)=>{u({featureName:n,environment:T,fromEnvironment:f,strategy:A,isOpen:!0})},[]),g=y.useCallback((T,A,f)=>{u({featureName:n,environment:T,fromEnvironment:f,strategies:A,isOpen:!0})},[]),h=y.useCallback(()=>{u({isOpen:!1})},[]),b=y.useCallback(async()=>{try{await i(e,c.environment,{feature:c.featureName,action:a,payload:c.strategy}),s(),u({isOpen:!1}),r({type:"success",title:"Changes added to the draft!"})}catch(T){o(z(T)),u({isOpen:!1})}},[i]),C=y.useCallback(async()=>{try{await Promise.all(c.strategies.map(T=>i(e,c.environment,{feature:c.featureName,action:a,payload:T}))),s(),u({isOpen:!1}),r({type:"success",title:"Changes added to the draft!"})}catch(T){o(z(T)),u({isOpen:!1})}},[i]);return{onChangeRequestAddStrategy:p,onChangeRequestAddStrategies:g,onChangeRequestAddStrategyClose:h,onChangeRequestAddStrategyConfirm:b,onChangeRequestAddStrategiesConfirm:C,changeRequestDialogDetails:c}},No=({payload:e,fromEnvironment:n,environment:a})=>l(_,{children:[l("strong",{children:["Copy ",xe((e==null?void 0:e.name)||"")," strategy"," "]})," ","from ",n," to ",a]}),zo=({environmentId:e,environments:n,strategy:a})=>{const r=R("projectId"),o=R("featureId"),[i,s]=y.useState(null),c=Boolean(i),{addStrategyToFeature:u}=we(),{setToastData:p,setToastApiError:g}=G(),{refetchFeature:h}=N(r,o),{refetchFeature:b}=gn(r,o),C=()=>{s(null)},T=Vn(r),{isChangeRequestConfigured:A}=ae(r),{changeRequestDialogDetails:f,onChangeRequestAddStrategyClose:S,onChangeRequestAddStrategy:x,onChangeRequestAddStrategyConfirm:E}=pt(r,o,"addStrategy"),P=async $=>{const{id:M,...B}={...a,targetEnvironment:$};if(A($)){await x($,{id:M,...B},e);return}try{await u(r,o,$,a),h(),b(),p({title:"Strategy created",text:`Successfully copied a strategy to ${$}`,type:"success"})}catch(W){g(z(W))}C()},D=n.some($=>T(ce,$));return l("div",{children:[t(Le,{isOpen:f.isOpen,onClose:S,environment:f==null?void 0:f.environment,onConfirm:E,messageComponent:t(No,{fromEnvironment:f.fromEnvironment,payload:f.strategy})}),t(Z,{title:`Copy to another environment${D?"":" (Access denied)"}`,children:t("div",{children:t(Be,{size:"large",id:`copy-strategy-icon-menu-${a.id}`,"aria-controls":c?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":c?"true":void 0,onClick:$=>{s($.currentTarget)},"data-testid":Ln,disabled:!D,children:t(Mn,{})})})}),t(Oe,{id:"basic-menu",anchorEl:i,open:c,onClose:C,MenuListProps:{"aria-labelledby":`copy-strategy-icon-menu-${a.id}`},children:n.map($=>{const M=T(ce,$);return t(Z,{title:M?"":"You don't have access to add a strategy to this environment",children:t("div",{children:l(De,{onClick:()=>P($),disabled:!M,children:[t(I,{condition:!M,show:t(Wt,{children:t(Ht,{fontSize:"small"})})}),l(at,{children:["Copy to ",$]})]})})},$)})})]})},Wo=({environmentId:e,strategy:n,onDragStart:a,onDragEnd:r,otherEnvironments:o,orderNumber:i,headerChildren:s})=>{const c=R("projectId"),u=R("featureId"),p=_n(c,u,e,n.id);return t(uo,{strategy:n,onDragStart:a,onDragEnd:r,orderNumber:i,actions:l(O,{children:[s,t(I,{condition:Boolean(o&&(o==null?void 0:o.length)>0),show:()=>t(zo,{environmentId:e,environments:o,strategy:n})}),t(X,{permission:jn,environmentId:e,projectId:c,component:Q,to:p,tooltipProps:{title:"Edit strategy"},children:t(ye,{})}),t(Mo,{projectId:c,featureId:u,environmentId:e,strategyId:n.id,icon:!0})]}),children:t(Nn,{strategy:n})})},Ho=(e,n,a,r)=>{const{data:o}=Te(e),i=o==null?void 0:o.find(u=>u.environment===a),s=i==null?void 0:i.features.find(u=>u.name===n);return s==null?void 0:s.changes.find(u=>u.action==="updateStrategy"||u.action==="deleteStrategy"?u.payload.id===r:!1)},qo=({strategy:e,index:n,environmentName:a,otherEnvironments:r,isDragging:o,onDragStartRef:i,onDragOver:s,onDragEnd:c})=>{const u=R("projectId"),p=R("featureId"),g=y.useRef(null),h=Ho(u,p,a,e.id);return l(U,{ref:g,onDragOver:s(g,n),sx:{opacity:o?"0.5":"1"},children:[t(I,{condition:n>0,show:t(zn,{text:"OR"})}),t(Wo,{strategy:e,environmentId:a,otherEnvironments:r,onDragStart:i(g,n),onDragEnd:c,orderNumber:n+1,headerChildren:t(Uo,{change:h})})]},e.id)},Uo=({change:e})=>{const n=ve();return de(n.breakpoints.down("sm"))?null:l(U,{sx:{mr:1.5},children:[t(I,{condition:(e==null?void 0:e.action)==="updateStrategy",show:t(Se,{color:"warning",children:"Modified in draft"})}),t(I,{condition:(e==null?void 0:e.action)==="deleteStrategy",show:t(Se,{color:"error",children:"Deleted in draft"})})]})},Go=d("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"center",margin:"1rem 0",position:"relative","&:before":{content:'""',position:"absolute",top:"50%",transform:"translateY(-50%)",height:2,width:"100%",backgroundColor:e.palette.divider}})),Yo=d("span")(({theme:e})=>({fontSize:e.fontSizes.bodySize,textAlign:"center",padding:"0 1rem",background:e.palette.background.elevation2,position:"relative",maxWidth:"80%",color:e.palette.text.primary})),hn=({children:e})=>t(Go,{children:t(Yo,{children:e})}),Ko=({environmentId:e,environments:n,onClick:a})=>{const r=R("projectId"),[o,i]=y.useState(null),s=Boolean(o),{hasAccess:c}=y.useContext(ot),u=n.some(p=>c(ce,r,p));return l("div",{children:[t(Z,{title:u?"":"(Access denied)",children:t("div",{children:t(re,{id:`copy-all-strategies-${e}`,"aria-controls":s?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":s?"true":void 0,onClick:p=>{i(p.currentTarget)},disabled:!u,variant:"outlined",children:"Copy from another environment"})})}),t(Oe,{id:"basic-menu",anchorEl:o,open:s,onClose:()=>{i(null)},MenuListProps:{"aria-labelledby":`copy-all-strategies-${e}`},children:n.map(p=>{const g=c(ce,r,p);return t(Z,{title:g?"":"You don't have access to add a strategy to this environment",children:t("div",{children:l(De,{onClick:()=>a(p),disabled:!g,children:[t(I,{condition:!g,show:t(Wt,{children:t(Ht,{fontSize:"small"})})}),l(at,{children:["Copy from ",p]})]})})},p)})})]})},Jo=d("div")(({theme:e})=>({"&>*:nth-child(n)":{margin:e.spacing(1,0)}})),Xo=({payload:e,fromEnvironment:n,environment:a})=>l(Jo,{children:[t(_,{children:t("strong",{children:"Copy: "})}),e==null?void 0:e.map(r=>l(_,{children:[l("strong",{children:[xe((r==null?void 0:r.name)||"")," strategy"," "]})," "]})),l(_,{children:["from ",n," to ",a]})]}),Qo=({payload:e,environment:n})=>l(O,{children:[t(_,{component:"span",children:"Add "}),l("strong",{children:[xe((e==null?void 0:e.name)||"")," strategy"]})," to ",t("strong",{children:n})]}),Zo=d(Wn)(({theme:e})=>({display:"flex",flexDirection:"column",borderRadius:e.shape.borderRadiusMedium})),Tt=({title:e,children:n,featureId:a,projectId:r,environmentId:o,strategy:i,Icon:s,onAfterAddStrategy:c})=>{const{addStrategyToFeature:u}=we(),{setToastApiError:p}=G(),{isChangeRequestConfigured:g}=ae(r),{changeRequestDialogDetails:h,onChangeRequestAddStrategy:b,onChangeRequestAddStrategyConfirm:C,onChangeRequestAddStrategyClose:T}=pt(r,a,"addStrategy");return l(O,{children:[t(Zo,{variant:"outlined",children:l(So,{sx:{display:"flex",flexDirection:"column",flexGrow:1},children:[l(_,{variant:"body1",fontWeight:"medium",sx:{mb:.5,display:"flex",alignItems:"center"},children:[t(s,{color:"disabled",sx:{mr:1}})," ",e]}),t(_,{variant:"body2",color:"text.secondary",component:"p",children:n}),t(U,{sx:{ml:"auto",mt:"auto",pt:1,mr:{xs:"auto",sm:0}},children:t(oe,{permission:ce,projectId:r,environmentId:o,variant:"outlined",size:"small",onClick:async()=>{try{g(o)?b(o,i):(await u(r,a,o,i),c())}catch(f){p(z(f))}},children:"Use template"})})]})}),t(Le,{isOpen:h.isOpen,onClose:T,environment:h==null?void 0:h.environment,onConfirm:C,messageComponent:t(Qo,{environment:o,payload:h.strategy})})]})},er=d("div")(({theme:e})=>({width:e.spacing(4),height:"auto","& > svg":{fill:e.palette.primary.main},"& > div":{height:e.spacing(2),marginLeft:"-.75rem",color:e.palette.primary.main}})),tr=d("div")(({theme:e})=>({fontSize:e.fontSizes.smallBody})),nr=d(rt)(({theme:e})=>({fontWeight:e.fontWeight.bold})),ar=d(Q)(({theme:e})=>({display:"grid",gridTemplateColumns:"3rem 1fr",width:"20rem",padding:e.spacing(2),color:"inherit",textDecoration:"inherit",lineHeight:1.25,borderWidth:"1px",borderStyle:"solid",borderColor:e.palette.divider,borderRadius:e.spacing(1),"&:hover, &:focus":{borderColor:e.palette.primary.main}})),or=({projectId:e,featureId:n,environmentId:a,strategy:r})=>{const o=Re(r.name),i=xe(r.name),s=Za(e,n,a,r.name);return l(ar,{to:s,children:[t(er,{children:t(o,{})}),l("div",{children:[t(nr,{text:r.displayName||i,maxWidth:"200",maxLength:25}),t(tr,{children:r.description})]})]})},rr=({projectId:e,featureId:n,environmentId:a})=>{const{strategies:r}=Hn(),o=y.useMemo(()=>r.filter(i=>!i.deprecated),[r]);return t(st,{dense:!0,children:o.map(i=>t(Fe,{children:t(or,{projectId:e,featureId:n,environmentId:a,strategy:i})},i.name))})},Qe=({label:e,projectId:n,featureId:a,environmentId:r,variant:o,matchWidth:i})=>{const[s,c]=y.useState(),u=Boolean(s),p=u?"FeatureStrategyMenuPopover":void 0,g=()=>{c(void 0)};return l("div",{onClick:b=>b.stopPropagation(),children:[t(oe,{permission:ce,projectId:n,environmentId:r,onClick:b=>{c(b.currentTarget)},"aria-labelledby":p,variant:o,sx:{minWidth:i?"282px":"auto"},children:e}),t(qn,{id:p,open:u,anchorEl:s,onClose:g,onClick:g,children:t(rr,{projectId:n,featureId:a,environmentId:r})})]})},sr=d("div")(({theme:e})=>({display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",paddingTop:e.spacing(2)})),ir=d("div")(({theme:e})=>({fontSize:e.fontSizes.bodySize,textAlign:"center",color:e.palette.text.primary,marginBottom:e.spacing(1)})),lr=d("p")(({theme:e})=>({color:e.palette.text.secondary,fontSize:e.fontSizes.smallBody,textAlign:"center",marginBottom:e.spacing(3)})),cr=({projectId:e,featureId:n,environmentId:a})=>{const{addStrategyToFeature:r}=we(),{setToastData:o,setToastApiError:i}=G(),{refetchFeature:s}=N(e,n),{refetchFeature:c}=gn(e,n),{feature:u}=N(e,n),p=u==null?void 0:u.environments.filter(x=>x.name!==a&&x.strategies&&x.strategies.length>0),{isChangeRequestConfigured:g}=ae(e),{changeRequestDialogDetails:h,onChangeRequestAddStrategies:b,onChangeRequestAddStrategiesConfirm:C,onChangeRequestAddStrategyClose:T}=pt(e,n,"addStrategy"),A=(x=!1)=>{s(),c(),o({title:x?"Strategies created":"Strategy created",text:x?"Successfully copied from another environment":"Successfully created strategy",type:"success"})},f=async x=>{var P;const E=((P=p==null?void 0:p.find(D=>D.name===x))==null?void 0:P.strategies)||[];if(g(a)){await b(a,E,x);return}try{await Promise.all(E.map(D=>{const{id:$,...M}={...D,environment:a};return r(e,n,a,M)})),A(!0)}catch(D){i(z(D))}},S=p&&p.length>0;return l(O,{children:[t(Le,{isOpen:h.isOpen,onClose:T,environment:h==null?void 0:h.environment,onConfirm:C,messageComponent:t(Xo,{fromEnvironment:h.fromEnvironment,payload:h.strategies})}),l(sr,{children:[t(ir,{children:"You have not defined any strategies yet."}),l(lr,{children:["Strategies added in this environment will only be executed if the SDK is using an"," ",t(Q,{to:"/admin/api",children:"API key configured"})," for this environment."]}),l(U,{sx:{w:"100%",display:"flex",flexWrap:"wrap",gap:2,alignItems:"center",justifyContent:"center"},children:[t(Qe,{label:"Add your first strategy",projectId:e,featureId:n,environmentId:a,matchWidth:S}),t(I,{condition:S,show:t(Ko,{environmentId:a,environments:p.map(x=>x.name),onClick:f})})]}),t(U,{sx:{width:"100%",mt:3},children:t(hn,{children:"Or use a strategy template"})}),l(U,{sx:{display:"grid",width:"100%",gap:2,gridTemplateColumns:{xs:"1fr",sm:"1fr 1fr"}},children:[t(Tt,{title:"Standard strategy",projectId:e,featureId:n,environmentId:a,onAfterAddStrategy:A,Icon:Re("default"),strategy:{name:"default",parameters:{},constraints:[]},children:"The standard strategy is strictly on/off for your entire userbase."}),t(Tt,{title:"Gradual rollout",projectId:e,featureId:n,environmentId:a,onAfterAddStrategy:A,Icon:Re("flexibleRollout"),strategy:{name:"flexibleRollout",parameters:{rollout:"50",stickiness:"default",groupId:u.name},constraints:[]},children:"Roll out to a percentage of your userbase."})]})]})]})},dr=d("div")(({theme:e})=>({width:"100%",position:"relative",paddingBottom:e.spacing(2)})),ur=d("div")(({theme:e})=>({[e.breakpoints.down(400)]:{padding:e.spacing(1)}})),pr=({featureEnvironment:e,isDisabled:n,otherEnvironments:a})=>{const r=R("projectId"),o=R("featureId"),{setStrategiesSortOrder:i}=we(),{setToastData:s,setToastApiError:c}=G(),{refetchFeature:u}=N(r,o),[p,g]=y.useState((e==null?void 0:e.strategies)||[]),[h,b]=y.useState(null);if(y.useEffect(()=>{g((e==null?void 0:e.strategies)||[])},[e==null?void 0:e.strategies]),!e)return null;const C=async S=>{try{await i(r,o,e.name,S),u(),s({title:"Order of strategies updated",type:"success"})}catch(x){c(z(x))}},T=(S,x)=>E=>{var P;b({id:p[x].id,index:x,height:((P=S.current)==null?void 0:P.offsetHeight)||0}),S!=null&&S.current&&(E.dataTransfer.effectAllowed="move",E.dataTransfer.setData("text/html",S.current.outerHTML),E.dataTransfer.setDragImage(S.current,20,20))},A=S=>(x,E)=>P=>{if(h===null||x.current===null||h.index===E||S===h.id)return;const{top:D,bottom:$}=x.current.getBoundingClientRect(),M=P.clientY-D<h.height,B=$-P.clientY<h.height,W=h.index>E;if(M&&W||B&&!W){const H=[...p],q=H.splice(h.index,1)[0];H.splice(E,0,q),g(H),b({...h,index:E})}},f=()=>{b(null),C(p.map((S,x)=>({id:S.id,sortOrder:x})))};return t(dr,{children:l(ur,{children:[t(I,{condition:p.length>0&&n,show:()=>t(he,{severity:"warning",sx:{mb:2},children:"This environment is disabled, which means that none of your strategies are executing."})}),t(I,{condition:p.length>0,show:t(O,{children:p.map((S,x)=>t(qo,{strategy:S,index:x,environmentName:e.name,otherEnvironments:a,isDragging:(h==null?void 0:h.id)===S.id,onDragStartRef:T,onDragOver:A(S.id),onDragEnd:f},S.id))}),elseShow:t(cr,{projectId:r,featureId:o,environmentId:e.name})})]})})},mn=(e,n)=>e===0?0:Math.round(n/e*100);var Me={},_e={};Object.defineProperty(_e,"__esModule",{value:!0});_e.defaultOptions=void 0;_e.defaultOptions={decimalSeparator:".",lowercase:!1,precision:1,space:!1,units:["","K","M","B","T","P","E"]};var ue={};Object.defineProperty(ue,"__esModule",{value:!0});ue.roundTo=ue.parseValue=void 0;function gr(e){const n=parseFloat(e==null?void 0:e.toString());if(isNaN(n))throw new Error("Input value is not a number");if(n>Number.MAX_SAFE_INTEGER||n<Number.MIN_SAFE_INTEGER)throw new RangeError("Input value is outside of safe integer range");return n}ue.parseValue=gr;function hr(e,n){if(!Number.isFinite(e))throw new Error("Input value is not a finite number");if(!Number.isInteger(n)||n<0)throw new Error("Precision is not a positive integer");return Number.isInteger(e)?e:parseFloat(e.toFixed(n))}ue.roundTo=hr;Object.defineProperty(Me,"__esModule",{value:!0});Me.millify=void 0;const Ne=_e,xt=ue,At=1e3;function*Et(e){let n=At;for(;;){const a=e/n;if(a<1)return;yield a,n*=At}}function fn(e,n){var a;const r=n?Object.assign(Object.assign({},Ne.defaultOptions),n):Ne.defaultOptions;if(!Array.isArray(r.units)||!r.units.length)throw new Error("Option `units` must be a non-empty array");let o;try{o=xt.parseValue(e)}catch(C){return C instanceof Error&&console.warn(`WARN: ${C.message} (millify)`),String(e)}const i=o<0?"-":"";o=Math.abs(o);let s=0;for(const C of Et(o))o=C,s+=1;if(s>=r.units.length)return e.toString();let u=xt.roundTo(o,r.precision);for(const C of Et(u))u=C,s+=1;const p=(a=r.units[s])!==null&&a!==void 0?a:"",g=r.lowercase?p.toLowerCase():p,h=r.space?" ":"",b=u.toString().replace(Ne.defaultOptions.decimalSeparator,r.decimalSeparator);return`${i}${b}${h}${g}`}Me.millify=fn;var mr=Me.default=fn;const Pe=({value:e,threshold:n=1e6,precision:a=2})=>{let r,o=!1;e<n?r=e.toLocaleString():(r=mr(e,{precision:a}),o=!0);const i=t("span",{"data-testid":Un,children:r});return t(I,{condition:o,show:t(Z,{title:e.toLocaleString(),arrow:!0,children:i}),elseShow:i})},ze=d("article")(({theme:e})=>({padding:e.spacing(2),background:"transparent",borderRadius:e.spacing(2),textAlign:"center",[e.breakpoints.up("md")]:{padding:e.spacing(4)}})),We=d("h3")(({theme:e})=>({margin:0,fontSize:e.fontSizes.bodySize,fontWeight:e.fontWeight.thin})),He=d("p")(({theme:e})=>({fontSize:"2.25rem",fontWeight:e.fontWeight.bold,color:e.palette.primary.main})),qe=d("p")(({theme:e})=>({margin:e.spacing(1,0,0,0),padding:e.spacing(2,0,0,0),borderTopWidth:"1px",borderTopStyle:"solid",borderTopColor:e.palette.divider,fontSize:e.fontSizes.smallerBody,color:e.palette.text.secondary})),yn=({totalYes:e,totalNo:n,hoursBack:a,statsSectionId:r,tableSectionId:o})=>{const i=a===1?"in the last hour":`in the last ${a} hours`;return l(ee,{container:!0,spacing:2,id:r,"aria-describedby":o,"aria-label":"Feature metrics summary",component:"section",children:[t(ee,{item:!0,xs:12,sm:4,children:l(ze,{children:[t(We,{children:"Exposure"}),t(He,{children:t(Pe,{value:e})}),l(qe,{children:["Total exposure of the feature in the environment"," ",i,"."]})]})}),t(ee,{item:!0,xs:12,sm:4,children:l(ze,{children:[t(We,{children:"Exposure %"}),l(He,{children:[mn(e+n,e),"%"]}),l(qe,{children:["% total exposure of the feature in the environment"," ",i,"."]})]})}),t(ee,{item:!0,xs:12,sm:4,children:l(ze,{children:[t(We,{children:"Requests"}),t(He,{children:t(Pe,{value:e+n})}),l(qe,{children:["Total requests for the feature in the environment"," ",i,"."]})]})})]})},fr=({environmentMetric:e})=>e?l(O,{children:[t(hn,{children:"Feature toggle exposure"}),t("div",{children:t(yn,{totalYes:e.yes,totalNo:e.no,hoursBack:1})})]}):null,It=d("div")({marginLeft:"auto",display:"flex",alignItems:"center"}),Rt=d("div")(({theme:e})=>({marginRight:e.spacing(1),display:"flex",flexDirection:"column"})),Ft=d("p")(({theme:e})=>({color:e.palette.primary.main,textAlign:"right",fontSize:e.fontSizes.bodySize})),kt=d("p")(({theme:e})=>({maxWidth:"270px",marginTop:e.spacing(.5),fontSize:e.fontSizes.smallBody,textAlign:"right",[e.breakpoints.down(700)]:{display:"none"}})),yr=d(Gn)(({theme:e})=>({fill:e.palette.background.application,height:"75px",width:"75px",[e.breakpoints.down(500)]:{display:"none"}})),Sr=d("div")(({theme:e})=>({margin:e.spacing(0,2),[e.breakpoints.down(500)]:{display:"none"}})),br=({environmentMetric:e,disabled:n=!1})=>{const a=Yn();if(!e)return null;const r=e.yes+e.no,o=mn(r,e==null?void 0:e.yes);return!e||e.yes===0&&e.no===0?l(It,{children:[l(Rt,{children:[l(Ft,{style:{color:n?a.palette.text.secondary:void 0},"data-loading":!0,children:[o,"%"]}),l(kt,{style:{color:n?a.palette.text.secondary:a.palette.text.primary},"data-loading":!0,children:["The feature has been requested ",t("b",{children:"0 times"})," and exposed",t("b",{children:" 0 times"})," in the last hour"]})]}),t(yr,{style:{transform:"scale(1.1)"},"data-loading":!0})]}):l(It,{children:[l(Rt,{children:[l(Ft,{children:[o,"%"]}),l(kt,{children:["The feature has been requested"," ",l("b",{children:[t(Pe,{value:r})," times"]})," ","and exposed"," ",l("b",{children:[t(Pe,{value:e.yes})," ","times"]})," ","in the last hour"]})]}),t(Sr,{"data-loading":!0,children:t(Kn,{percentage:o,size:"3rem"})})]})},Cr=({strategyName:e})=>{const n=Re(e);return t(Z,{title:xe(e),arrow:!0,children:t(vr,{children:t(n,{})})})},vr=d("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"center",color:e.palette.action.disabled,"& svg":{width:e.spacing(2.5),height:e.spacing(2.5)}})),wr=({strategies:e})=>e!=null&&e.length?t(Tr,{"aria-label":"Feature strategies",children:e.map(n=>t(xr,{children:t(Cr,{strategyName:n.name})},n.id))}):null,Tr=d("ul")(()=>({all:"unset",display:"flex",alignItems:"center",alignContent:"center"})),xr=d("li")(()=>({all:"unset",minWidth:30,textAlign:"center"})),Ar=d("div",{shouldForwardProp:e=>e!=="enabled"})(({theme:e,enabled:n})=>({borderRadius:e.shape.borderRadiusLarge,marginBottom:e.spacing(2),backgroundColor:e.palette.background.paper,background:n?e.palette.background.paper:e.palette.neutral.light})),Er=d(Jn)({boxShadow:"none",background:"none"}),Ir=d(Xn)(({theme:e})=>({boxShadow:"none",padding:e.spacing(2,4),[e.breakpoints.down(400)]:{padding:e.spacing(1,2)}})),Rr=d(Qn,{shouldForwardProp:e=>e!=="enabled"})(({theme:e,enabled:n})=>({padding:e.spacing(3),background:e.palette.background.elevation2,borderBottomLeftRadius:e.shape.borderRadiusLarge,borderBottomRightRadius:e.shape.borderRadiusLarge,borderBottom:`4px solid ${n?e.palette.primary.light:e.palette.neutral.border}`,[e.breakpoints.down("md")]:{padding:e.spacing(2,1)}})),Fr=d(pr)(({theme:e})=>({width:"100%",position:"relative",paddingBottom:e.spacing(2)})),kr=d("div",{shouldForwardProp:e=>e!=="enabled"})(({theme:e,enabled:n})=>({display:"flex",justifyContent:"center",flexDirection:"column",color:n?e.palette.text.primary:e.palette.text.secondary})),Pr=d("div")(({theme:e})=>({display:"flex",alignItems:"center",[e.breakpoints.down(560)]:{flexDirection:"column",textAlign:"center"}})),$r=d($o)(({theme:e})=>({[e.breakpoints.down(560)]:{marginBottom:"0.5rem"}})),Br=d(rt)(({theme:e})=>({fontSize:e.fontSizes.bodySize,fontWeight:e.typography.fontWeightMedium,[e.breakpoints.down(560)]:{textAlign:"center"}})),Or=d("div")(({theme:e})=>({display:"flex",alignItems:"center",marginLeft:"1.8rem",[e.breakpoints.down(560)]:{flexDirection:"column",marginLeft:"0"}})),Dr=({env:e})=>{var p;const n=R("projectId"),a=R("featureId"),{metrics:r}=Fo(n,a),{feature:o}=N(n,a),{value:i}=qt(),c=Po(o==null?void 0:o.environments,r).find(g=>g.environment===e.name),u=o==null?void 0:o.environments.find(g=>g.name===e.name);return t(I,{condition:!Boolean(new Set(i.hiddenEnvironments).has(e.name)),show:t(Ar,{enabled:e.enabled,children:l(Er,{"data-testid":`${Zn}_${e.name}`,children:[l(Ir,{expandIcon:t(po,{titleAccess:"Toggle"}),children:[l(kr,{"data-loading":!0,enabled:e.enabled,children:[l(Pr,{children:[t($r,{enabled:e.enabled}),t("div",{children:t(Br,{text:e.name,maxWidth:"100",maxLength:15})}),t(I,{condition:!e.enabled,show:t(Se,{color:"neutral",sx:{ml:1},children:"Disabled"})})]}),l(Or,{children:[t(Qe,{label:"Add strategy",projectId:n,featureId:a,environmentId:e.name,variant:"text"}),t(wr,{strategies:u==null?void 0:u.strategies})]})]}),t(br,{environmentMetric:c,disabled:!e.enabled})]}),l(Rr,{enabled:e.enabled,children:[t(Fr,{featureEnvironment:u,isDisabled:!e.enabled,otherEnvironments:o==null?void 0:o.environments.map(({name:g})=>g).filter(g=>g!==e.name)}),t(I,{condition:(((p=u==null?void 0:u.strategies)==null?void 0:p.length)||0)>0,show:l(O,{children:[t(U,{sx:{display:"flex",justifyContent:"center",py:1},children:t(Qe,{label:"Add strategy",projectId:n,featureId:a,environmentId:e.name})}),t(fr,{environmentMetric:c})]})})]})]})})})},Vr=()=>{const e=R("projectId"),n=R("featureId"),{feature:a}=N(e,n);if(!a)return null;const{environments:r}=a;return t(O,{children:r==null?void 0:r.map(o=>t(Dr,{env:o},o.name))})},Lr=d("div")(({theme:e})=>({display:"flex",flexDirection:"column",padding:e.spacing(3),fontSize:e.fontSizes.smallBody})),Mr=d("span")(({theme:e})=>({color:e.palette.text.secondary,marginRight:e.spacing(1)})),_r=({feature:e,header:n})=>{const{locationSettings:a}=ea();return l(Lr,{children:[n,l("div",{"data-loading":!0,children:[t(Mr,{children:"Created at:"}),t("span",{children:ta(na(e.createdAt),a.locale)})]})]})},jr=d(Be,{shouldForwardProp:e=>e!=="visibilityOff"})(({theme:e,visibilityOff:n})=>({marginLeft:"auto",marginRight:e.spacing(-1),color:n?e.palette.neutral.main:e.palette.divider,"&:hover":{color:e.palette.neutral.main}})),Nr=({environment:e,hiddenEnvironments:n,setHiddenEnvironments:a})=>t(jr,{onClick:()=>{a(e.name)},visibilityOff:n.has(e.name),children:t(I,{condition:n.has(e.name),show:t(aa,{}),elseShow:t(oa,{})})}),zr=d("div")(({theme:e})=>({marginLeft:e.spacing(-1.5),"&:not(:last-of-type)":{marginBottom:e.spacing(2)},display:"flex",alignItems:"center"})),Wr=d("label")(()=>({display:"inline-flex",alignItems:"center",cursor:"pointer"})),Hr=({environment:e,callback:n,showInfoBox:a,children:r,hiddenEnvironments:o,setHiddenEnvironments:i})=>{const{name:s,enabled:c}=e,u=R("projectId"),p=R("featureId"),{toggleFeatureEnvironmentOn:g,toggleFeatureEnvironmentOff:h}=Ae(),{refetchFeature:b}=N(u,p),{setToastData:C,setToastApiError:T}=G(),{isChangeRequestConfigured:A}=ae(u),{onChangeRequestToggle:f,onChangeRequestToggleClose:S,onChangeRequestToggleConfirm:x,changeRequestDialogDetails:E}=eo(u),P=async()=>{try{await g(u,p,s),C({type:"success",title:`Available in ${s}`,text:`${p} is now available in ${s} based on its defined strategies.`}),b(),n&&n()}catch(B){B instanceof Error&&B.message===no?a():T(z(B))}},D=async()=>{try{await h(u,p,s),C({type:"success",title:`Unavailable in ${s}`,text:`${p} is unavailable in ${s} and its strategies will no longer have any effect.`}),b(),n&&n()}catch(B){T(z(B))}},$=async B=>{if(A(s)){B.preventDefault(),f(p,s,!c);return}if(c){await D();return}await P()},M=l(O,{children:[" ",l("span",{"data-loading":!0,children:[c?"enabled":"disabled"," in"]})," ",t(rt,{text:s,maxWidth:"120",maxLength:15})]});return l(zr,{children:[l(Wr,{children:[t(ra,{tooltip:c?`Disable feature in ${s}`:`Enable feature in ${s}`,permission:sa,projectId:u,checked:c,onChange:$,environmentId:s}),r??M]}),t(Nr,{environment:e,hiddenEnvironments:o,setHiddenEnvironments:i}),t(Le,{isOpen:E.isOpen,onClose:S,environment:E==null?void 0:E.environment,onConfirm:x,messageComponent:t(to,{enabled:E==null?void 0:E.enabled,featureName:E==null?void 0:E.featureName,environment:E.environment})})]})},qr=d("div")(({theme:e})=>({padding:e.spacing(3)})),Ur=d("div")(()=>({display:"flex",flexDirection:"column"})),Gr=d("p")(({theme:e})=>({fontSize:e.fontSizes.bodySize})),Yr=d("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,display:"flex",alignItems:"center"})),Pt=d("span")(({theme:e})=>({padding:e.spacing(0,.5),"::after":{content:'"-"'}})),Kr=d(ia)(()=>({"&:hover, &:focus":{textDecoration:"underline"}})),Jr=({feature:e,header:n,hiddenEnvironments:a,setHiddenEnvironments:r})=>{const[o,i]=y.useState(!1),[s,c]=y.useState(""),u=e.environments.some(p=>{var g;return p.enabled&&((g=p.variants)==null?void 0:g.length)});return l(qr,{"data-testid":"feature-toggle-status",children:[n,e.environments.map(p=>{const g=p.strategies.length===1?"1 strategy":`${p.strategies.length} strategies`,h=p.variants??[],b=h.length>0&&l(O,{children:[t(Pt,{}),t(Z,{title:"View variants",arrow:!0,describeChild:!0,children:t(Kr,{component:Q,to:`/projects/${e.project}/features/${e.name}/variants`,underline:"hover",children:h.length===1?"1 variant":`${h.length} variants`})})]}),C=p.enabled&&h.length===0&&u;return t(Hr,{environment:p,hiddenEnvironments:a,setHiddenEnvironments:r,showInfoBox:()=>{c(p.name),i(!0)},children:l(Ur,{children:[t(Gr,{children:p.name}),l(Yr,{children:[g,b,t(I,{condition:C,show:l(O,{children:[t(Pt,{}),t(ao,{})]})})]})]})},p.name)}),t(oo,{open:o,onClose:()=>i(!1),projectId:e.project,featureId:e.name,environmentName:s})]})},Sn=(e,n={})=>{const a=async()=>{const p=pe(`api/admin/features/${e}/tags`);return(await fetch(p,{method:"GET"}).then(Ce("Tags"))).json()},r=`api/admin/features/${e}/tags`,{data:o,error:i}=Ut(Boolean(e),{tags:[]},r,a,n),[s,c]=y.useState(!i&&!o),u=()=>{$e(r)};return y.useEffect(()=>{c(!i&&!o)},[o,i]),{tags:(o==null?void 0:o.tags)||[],error:i,loading:s,refetch:u}},Xr=la(),Qr=({options:e,selectedOptions:n,tagType:a,existingTags:r,onChange:o})=>{const i=t(ca,{fontSize:"small"}),s=t(da,{fontSize:"small"});return t(it,{multiple:!0,id:"checkboxes-tag",sx:{marginTop:h=>h.spacing(2),width:500},disableCloseOnSelect:!0,placeholder:"Select Values",options:e,value:n,renderTags:(h,b)=>h.map((C,T)=>r.some(f=>f.value===C.title&&f.type===a.name)?null:t(lt,{...b({index:T}),label:C.title})),isOptionEqualToValue:(h,b)=>b.inputValue&&b.inputValue!==""?h.title===b.inputValue:h.title===b.title,getOptionLabel:h=>h.inputValue?h.inputValue:h.title,renderOption:(h,b,{selected:C})=>l("li",{...h,children:[t(I,{condition:Boolean(b.inputValue),show:t(Gt,{sx:{mr:T=>T.spacing(.5)}}),elseShow:t(Yt,{icon:i,checkedIcon:s,sx:{mr:T=>T.spacing(.5)},checked:C})}),b.title]}),filterOptions:(h,b)=>{const C=Xr(h,b),{inputValue:T}=b,A=h.some(f=>T===f.title);return T!==""&&!A&&C.push({inputValue:T,title:`Create new value "${T}"`}),C},ListboxProps:{style:{maxHeight:200,overflow:"auto"}},onChange:o,renderInput:h=>t(Ve,{...h,label:"Select values",placeholder:"Select values"})})},Zr=d("li")({flexDirection:"column"}),es=({value:e,onChange:n})=>{const{tagTypes:a}=ua(),r=ve();return t(it,{disablePortal:!0,id:"tag-type-select",sx:{marginTop:o=>o.spacing(2),width:500},options:a,disableClearable:!0,value:e,getOptionLabel:o=>o.name,renderOption:(o,i)=>l(Zr,{...o,style:{alignItems:"flex-start",gap:r.spacing(.5)},children:[t(_,{variant:"body1",children:i.name}),t(_,{variant:"caption",children:i.description})]}),renderInput:o=>t(Ve,{...o,label:"Tag type",value:e}),onChange:n,ListboxProps:{style:{maxHeight:200,overflow:"auto"}}})},ts=()=>{const{makeRequest:e,createRequest:n,errors:a,loading:r}=pa({propagateErrors:!0});return{createTag:async i=>{const c=n("api/admin/tags",{method:"POST",body:JSON.stringify(i)});try{return await e(c.caller,c.id)}catch(u){throw u}},errors:a,loading:r}},ns=(e,n={})=>{const a=async()=>{const p=pe(`api/admin/tags/${e}`);return(await fetch(p,{method:"GET"}).then(Ce("Tags"))).json()},r=`api/admin/tags/${e}`,{data:o,error:i}=Ut(Boolean(e),{tags:[]},r,a,n),[s,c]=y.useState(!i&&!o),u=()=>{$e(r)};return y.useEffect(()=>{c(!i&&!o)},[o,i]),{tags:(o==null?void 0:o.tags)||[],error:i,loading:s,refetch:u}},as=d("section")(({theme:e})=>({["& > *"]:{margin:e.spacing(1,0)}})),Ue=e=>e.map(n=>({title:n.value})),$t=(e,n)=>e.map(a=>({value:a.title,type:n})),bn=({open:e,setOpen:n})=>{const a=R("featureId"),{createTag:r}=ts(),{updateFeatureTags:o,loading:i}=Ae(),{tags:s,refetch:c,loading:u}=Sn(a),{setToastData:p}=G(),[g,h]=y.useState({name:"simple",description:"Simple tag to get you started",icon:""}),b=i||u,[C,T]=y.useState(0),{trackEvent:A}=Kt(),[f,S]=y.useState(Ue(s.filter(v=>v.type===g.name))),{tags:x,refetch:E}=ns(g.name),P=y.useMemo(()=>Ue(x),[x]);y.useEffect(()=>{s&&g&&S(Ue(s.filter(v=>v.type===g.name)))},[JSON.stringify(s),g]);const D=()=>{n(!1),S([])};function $(v,m){const w=v.filter(V=>V.type===g.name).filter(V=>!m.find(L=>V.value===L.value&&V.type===L.type)),k=m.filter(V=>V.type===g.name).filter(V=>!v.find(L=>V.value===L.value&&V.type===L.type));return T(w.length+k.length),{added:w,removed:k}}const M=v=>v.filter(m=>!m.title.startsWith("Create")),B=async(v,m)=>{try{await o(a,{addedTags:v,removedTags:m}),await c()}catch(w){const k=z(w);p({type:"error",title:"Failed to add tag",text:k,confetti:!1})}},W=(v,m)=>{let w="We successfully";return v>0&&(w=w.concat(` added ${v} new tag${v>1?"s":""}`)),v>0&&m>0&&(w=w.concat(" and ")),m>0&&(w=w.concat(` removed ${m} tag${m>1?"s":""}`)),w},H=async v=>{v.preventDefault();const m=$t(M(f),g.name),{added:w,removed:k}=$(m,s);C>0&&(await B(w,k),C>1&&A("suggest_tags",{props:{eventType:"multiple_tags_added"}}),C>0&&p({type:"success",title:`Updated tag${w.length>1?"s":""} to toggle`,text:W(w.length,k.length),confetti:!0})),T(0),S([]),n(!1)},q=(v,m)=>{m!=null&&typeof m!="string"&&(v.preventDefault(),h(m),S([]),T(0))},Y=(v,m,w)=>{const k=ga(m);w==="selectOption"&&m.forEach((L,F)=>{if(typeof L!="string"&&L.inputValue&&L.inputValue!==""){const j={value:L.inputValue,type:g.name};r(j).then(()=>{A("suggest_tags",{props:{eventType:"tag_created"}}),E()}),L.title=L.inputValue,L.inputValue="",k[F]=L}});const V=$t(M(k),g.name);$(V,s),S(k)},K="add-tag-form";return t(O,{children:t(le,{open:e,secondaryButtonText:"Cancel",primaryButtonText:"Save tags",title:"Update tags to feature toggle",onClick:H,disabledPrimaryButton:b||C===0,onClose:D,formId:K,children:l(O,{children:[t(_,{paragraph:!0,sx:{marginBottom:v=>v.spacing(2.5)},children:"Tags allow you to group features together"}),t("form",{id:K,onSubmit:H,children:l(as,{children:[t(es,{autoFocus:!0,value:g,onChange:q}),t(Qr,{options:P,existingTags:s,tagType:g,selectedOptions:f,onChange:Y})]})})]})})})},os=d("div")(({theme:e})=>({display:"flex",flexDirection:"column",padding:e.spacing(3)})),rs=d("div")(({theme:e})=>({display:"flex",gap:e.spacing(1),flexWrap:"wrap"})),ss=d(lt)(({theme:e})=>({fontSize:e.fontSizes.smallBody})),is=d(ke)(({theme:e})=>({margin:e.spacing(3),borderStyle:"dashed"})),ls=d(re)(({theme:e})=>({maxWidth:e.spacing(20),alignSelf:"center"})),cs=({feature:e,header:n})=>{const{tags:a,refetch:r}=Sn(e.name),{deleteTagFromFeature:o}=Ae(),[i,s]=y.useState(!1),[c,u]=y.useState(!1),[p,g]=y.useState(),{setToastData:h,setToastApiError:b}=G(),{hasAccess:C}=y.useContext(ot),T=C(ie,e.project),A=async()=>{if(p)try{await o(e.name,p.type,p.value),r(),h({type:"success",title:"Tag deleted",text:"Successfully deleted tag"})}catch(f){b(z(f))}};return l(os,{children:[n,t(rs,{children:a.map(f=>{const S=`${f.type}:${f.value}`;return t(ss,{label:S,deleteIcon:t(ha,{titleAccess:"Remove"}),onDelete:T?()=>{u(!0),g(f)}:void 0},S)})}),t(I,{condition:T,show:l(O,{children:[t(I,{condition:a.length>0,show:t(is,{})}),t(ls,{"data-loading":!0,variant:"outlined",startIcon:t(Gt,{}),onClick:()=>s(!0),children:"Add new tag"})]})}),t(bn,{open:i,setOpen:s}),l(le,{open:c,primaryButtonText:"Delete tag",secondaryButtonText:"Cancel",onClose:()=>{u(!1),g(void 0)},onClick:()=>{u(!1),A(),g(void 0)},title:"Delete tag?",children:["You are about to delete tag:"," ",l("strong",{children:[p==null?void 0:p.type,":",p==null?void 0:p.value]})]})]})},ds=d("div")(({theme:e})=>({position:"sticky",top:e.spacing(2),borderRadius:e.shape.borderRadiusLarge,backgroundColor:e.palette.background.paper,display:"flex",flexDirection:"column",maxWidth:"350px",minWidth:"350px",marginRight:"1rem",marginTop:"1rem",[e.breakpoints.down(1e3)]:{marginBottom:"1rem",width:"100%",maxWidth:"none",minWidth:"auto"}})),Ge=d("h3")(({theme:e})=>({display:"flex",gap:e.spacing(1),alignItems:"center",fontSize:e.fontSizes.bodySize,margin:0,marginBottom:e.spacing(3),"& > :last-child":{position:"relative",top:1}})),us=({hiddenEnvironments:e,setHiddenEnvironments:n})=>{const a=R("projectId"),r=R("featureId"),{feature:o}=N(a,r);return l(ds,{children:[t(Jr,{header:l(Ge,{"data-loading":!0,children:["Enabled in environments (",o.environments.filter(({enabled:i})=>i).length,")",t(Ke,{tooltip:"When a feature is switched off in an environment, it will always return false. When switched on, it will return true or false depending on its strategies.",placement:"top"})]}),feature:o,hiddenEnvironments:e,setHiddenEnvironments:n}),t(ke,{}),t(_r,{header:t(Ge,{"data-loading":!0,children:"Feature toggle details"}),feature:o}),t(ke,{}),t(cs,{header:t(Ge,{"data-loading":!0,children:"Tags for this feature toggle"}),feature:o})]})},ps=()=>{const{trackEvent:e}=Kt(),{value:n,setValue:a}=qt(),[r,o]=y.useState(new Set(n.hiddenEnvironments));return{hiddenEnvironments:r,setHiddenEnvironments:s=>{a(c=>{const u=new Set(c.hiddenEnvironments);return u.has(s)?(u.delete(s),e("hidden_environment",{props:{eventType:"environment unhidden"}})):(u.add(s),e("hidden_environment",{props:{eventType:"environment hidden"}})),o(u),{...n,hiddenEnvironments:u}})}}},gs=d("div")(({theme:e})=>({display:"flex",width:"100%",[e.breakpoints.down(1e3)]:{flexDirection:"column"}})),hs=d("div")(({theme:e})=>({display:"flex",flexDirection:"column",width:"calc(100% - (350px + 1rem))",[e.breakpoints.down(1e3)]:{width:"100%"}})),ms=()=>{const e=ge(),n=R("projectId"),a=R("featureId"),r=zt(n,a),{hiddenEnvironments:o,setHiddenEnvironments:i}=ps(),s=()=>e(r);return Jt(a),l(gs,{children:[l("div",{children:[t(Ro,{}),t(us,{hiddenEnvironments:o,setHiddenEnvironments:i})]}),t(hs,{children:t(Vr,{})}),l(Xt,{children:[t(ne,{path:"strategies/create",element:t(Je,{label:"Create feature strategy",onClose:s,open:!0,children:t(ro,{})})}),t(ne,{path:"strategies/edit",element:t(Je,{label:"Edit feature strategy",onClose:s,open:!0,children:t(ma,{})})})]})]})},fs=({values:e=[],updateValues:n,placeholder:a="",error:r,...o})=>{const i=c=>{const p=c.target.value.split(/,\s?/).map(g=>g.trim());n(p)},s=c=>{if(c.key==="Backspace"){const u=c.target.value;if(u.endsWith(", ")){c.preventDefault();const p=u.slice(0,-2);n(p.split(/,\s*/))}}};return t(Ve,{...o,error:r,placeholder:a,value:e?e.join(", "):"",onKeyDown:s,onChange:i,style:{width:"100%"},variant:"outlined",size:"small"})},ys=d("div")(({theme:e})=>({display:"flex",alignItems:"center",rowGap:e.spacing(1.5),marginBottom:e.spacing(2),[e.breakpoints.down("sm")]:{flexDirection:"column","& > div, .MuiInputBase-root":{width:"100%",alignItems:"flex-start"}}})),Ss=d(Qt)(({theme:e})=>({minWidth:e.spacing(20),marginRight:e.spacing(10)})),bs=d("div")(({theme:e})=>({width:"100%",gap:e.spacing(1.5),display:"flex"})),Cs=d(fs)(()=>({width:"100%"})),vs=d(Ve)(()=>({width:"100%"})),ws=({overrides:e,overridesDispatch:n})=>{const{context:a}=ct(),r=a.map(({name:s})=>({key:s,label:s})),o=s=>c=>{n({type:"UPDATE_VALUES_AT",payload:[s,c]})},i=s=>(c,u)=>{c==null||c.preventDefault(),n({type:"UPDATE_VALUES_AT",payload:[s,u||[]]})};return t(O,{children:e.map((s,c)=>{var h;const u=a.find(({name:b})=>b===s.contextName),p=((h=u==null?void 0:u.legalValues)==null?void 0:h.map(({value:b})=>b))||[],g=s.values.filter(b=>p.includes(b));return l(ys,{children:[t(Ss,{id:"override-context-name",name:"contextName",label:"Context Field",value:s.contextName,options:r,onChange:b=>n({type:"UPDATE_TYPE_AT",payload:[c,b.target.value]})}),l(bs,{children:[t(I,{condition:Boolean(p&&p.length>0),show:t(it,{multiple:!0,id:`override-select-${c}`,isOptionEqualToValue:(b,C)=>b===C,options:p,onChange:i(c),getOptionLabel:b=>b,value:g,style:{width:"100%"},filterSelectedOptions:!0,size:"small",renderInput:b=>t(vs,{...b,variant:"outlined",label:"Legal values"})}),elseShow:t(Cs,{label:"Values (v1, v2, ...)",name:"values",placeholder:"",values:s.values,updateValues:o(c)})}),t(Z,{title:"Remove",arrow:!0,children:t(Be,{onClick:b=>{b.preventDefault(),n({type:"REMOVE",payload:c})},children:t(tt,{})})})]})]},`override=${c}`)})})},Ts=(e,n)=>{switch(n.type){case"SET":return n.payload;case"CLEAR":return[];case"ADD":return[...e,n.payload];case"REMOVE":return e.filter((s,c)=>c!==n.payload);case"UPDATE_VALUES_AT":const[a,r]=n.payload;return e.map((s,c)=>c===a?{...s,values:r}:s);case"UPDATE_TYPE_AT":const[o,i]=n.payload;return e.map((s,c)=>c===o?{...s,contextName:i}:s)}},xs=(e=[])=>y.useReducer(Ts,e);var J=(e=>(e.FIX="fix",e.VARIABLE="variable",e))(J||{});const As=d("div")(({theme:e})=>({position:"relative",backgroundColor:e.palette.neutral.light,display:"flex",flexDirection:"column",padding:e.spacing(3),marginBottom:e.spacing(3),borderRadius:e.shape.borderRadiusLarge})),Es=d(Z)(({theme:e})=>({position:"absolute",top:e.spacing(2),right:e.spacing(2)})),Cn=d("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody})),Bt=d(Cn)(({theme:e})=>({display:"flex",color:e.palette.text.primary,marginTop:e.spacing(1),marginBottom:e.spacing(2)})),Is=d("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,marginBottom:e.spacing(2)})),Rs=d(fa)(({theme:e})=>({marginBottom:e.spacing(1),"& > span":{fontSize:e.fontSizes.smallBody},[e.breakpoints.down("sm")]:{marginTop:e.spacing(1),marginBottom:e.spacing(1.5)}})),Ot=d(Zt)(()=>({width:"100%"})),Fs=d("div")(({theme:e})=>({marginLeft:e.spacing(3)})),ks=d(Zt)(({theme:e})=>({width:e.spacing(24),[e.breakpoints.down("sm")]:{width:"100%"}})),Ps=d("div")(({theme:e})=>({marginTop:e.spacing(3),flexGrow:1})),vn=d("div")(({theme:e})=>({display:"flex",rowGap:e.spacing(1.5),marginBottom:e.spacing(2),[e.breakpoints.down("sm")]:{flexDirection:"column","& > div, .MuiInputBase-root":{width:"100%"}}})),$s=d(vn)({alignItems:"end",justifyContent:"space-between"}),Bs=d(Qt)(({theme:e})=>({minWidth:e.spacing(20),marginRight:e.spacing(10)})),Os=d(re)(({theme:e})=>({width:e.spacing(20),maxWidth:"100%"})),Ds=[{key:"string",label:"string"},{key:"json",label:"json"},{key:"csv",label:"csv"}],Vs={type:"string",value:""},Ls=({variant:e,variants:n,updateVariant:a,removeVariant:r,apiPayload:o})=>{const[i,s]=y.useState(e.name),[c,u]=y.useState(e.weightType===J.FIX),[p,g]=y.useState(String(e.weight/10)),[h,b]=y.useState(e.payload||Vs),[C,T]=xs(e.overrides||[]),{context:A}=ct(),[f,S]=y.useState({}),x=m=>{S(w=>({...w,[m]:void 0}))},E=(m,w)=>{S(k=>({...k,[m]:w}))};y.useEffect(()=>{var m;x("percentage"),(m=o.error)!=null&&m.includes("%")&&E("percentage","Total weight must equal 100%")},[o.error]);const P=!e.new,D=n.filter(({id:m,weightType:w})=>m!==e.id&&w===J.VARIABLE).length>0,$=m=>{const w=m.weightType===J.VARIABLE,k=n.some(L=>L.weightType===J.FIX),V=n.filter(L=>L.weightType===J.VARIABLE).length===1;return k&&V&&w},M=m=>{x("name"),Y(m,e.id)||E("name","A variant with that name already exists for this environment."),s(m)},B=m=>{(m===""||K(m))&&g(m)},W=m=>{v(m)||E("payload","Invalid JSON.")},H=()=>{A.length>0&&T({type:"ADD",payload:{contextName:A[0].name,values:[]}})},q=m=>Boolean(m.length),Y=(m,w)=>P||!n.some(k=>k.name===m&&k.id!==w),K=m=>{if(!c)return!0;if(m===""||m.match(/\.[0-9]{2,}$/))return!1;const w=Number(m);return w>=0&&w<=100},v=m=>{try{return m.type==="json"&&JSON.parse(m.value),!0}catch{return!1}};return y.useEffect(()=>{a({...e,name:i,weight:Number(c?p:100)*10,weightType:c?J.FIX:J.VARIABLE,stickiness:(n==null?void 0:n.length)>0?n[0].stickiness:"default",payload:h.value?h:void 0,overrides:C.map(m=>({contextName:m.contextName,values:m.values})).filter(m=>m.values&&m.values.length>0),isValid:q(i)&&Y(i,e.id)&&K(p)&&v(h)&&!o.error})},[i,c,p,h,C]),y.useEffect(()=>{c||g(String(e.weight/10))},[e.weight]),l(As,{children:[t(Es,{arrow:!0,title:$(e)?"You need to have at least one variable variant":"Delete variant",children:t("div",{children:t(Be,{"data-testid":`VARIANT_DELETE_BUTTON_${e.name}`,onClick:()=>r(e.id),disabled:$(e),children:t(tt,{})})})}),l($s,{children:[l(Ps,{children:[t(Cn,{children:"Variant name"}),t(Is,{children:"This will be used to identify the variant in your code"}),t(Ot,{"data-testid":"VARIANT_NAME_INPUT",autoFocus:!0,label:"Variant name",error:Boolean(f.name),errorText:f.name,value:i,onChange:m=>M(m.target.value),disabled:P,required:!0})]}),t(I,{condition:D,show:l(Fs,{children:[t(Rs,{label:"Custom percentage",control:t(ya,{"data-testid":"VARIANT_WEIGHT_CHECK",checked:c,onChange:m=>u(m.target.checked)})}),t(ks,{"data-testid":"VARIANT_WEIGHT_INPUT",type:"number",label:"Variant weight",error:Boolean(f.percentage),errorText:f.percentage,value:p,onChange:m=>B(m.target.value),required:c,disabled:!c,"aria-valuemin":0,"aria-valuemax":100,InputProps:{endAdornment:t(Sa,{position:"end",children:"%"})}})]})})]}),l(Bt,{children:["Payload",t(Ke,{tooltip:"Passed along with the the variant object."})]}),l(vn,{children:[t(Bs,{id:"variant-payload-type",name:"type",label:"Type",value:h.type,options:Ds,onChange:m=>{x("payload"),b(w=>({...w,type:m.target.value}))}}),t(Ot,{id:"variant-payload-value",name:"variant-payload-value",label:"Value",multiline:h.type!=="string",rows:h.type==="string"?1:4,value:h.value,onChange:m=>{x("payload"),b(w=>({...w,value:m.target.value}))},placeholder:h.type==="json"?'{ "hello": "world" }':"",onBlur:()=>W(h),error:Boolean(f.payload),errorText:f.payload})]}),l(Bt,{children:["Overrides",t(Ke,{tooltip:"Here you can specify which users should get this variant."})]}),t(ws,{overrides:C,overridesDispatch:T}),t(Os,{onClick:H,variant:"outlined",color:"primary",children:"Add override"})]})},Ms=d("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"space-between","& > div":{display:"flex",alignItems:"center"},marginTop:e.spacing(-1.5),marginBottom:e.spacing(4)})),_s=d(en,{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:n})=>({color:n?e.palette.neutral.border:e.palette.primary.main})),js=d("span",{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:n})=>({color:n?e.palette.text.secondary:e.palette.text.primary,marginLeft:e.spacing(1.25),fontSize:e.fontSizes.mainHeader,fontWeight:e.fontWeight.bold})),Ns=d("form")(()=>({display:"flex",flexDirection:"column",height:"100%"})),zs=d(he)(({theme:e})=>({marginBottom:e.spacing(2)})),Ws=d(he)(({theme:e})=>({marginTop:e.spacing(4)})),Hs=d("div")({display:"flex",flexDirection:"column-reverse"}),qs=d("div")(({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1.5),marginBottom:e.spacing(.5)})),Dt=d("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,marginBottom:e.spacing(1.5)})),Us=d(ba)(({theme:e})=>({minWidth:e.spacing(20),width:"100%"})),Gs=d("div")(({theme:e})=>({marginTop:"auto",paddingTop:e.spacing(4),display:"flex",justifyContent:"flex-end"})),Ys=d(re)(({theme:e})=>({marginLeft:e.spacing(3)})),Ks=({environment:e,open:n,setOpen:a,getApiPayload:r,getCrPayload:o,onConfirm:i})=>{var L;const s=R("projectId"),c=R("featureId"),{uiConfig:u}=dt(),{context:p}=ct(),{defaultStickiness:g}=Ca(s),{isChangeRequestConfigured:h}=ae(s),{data:b}=Te(s),{changeRequestInReviewOrApproved:C,alert:T}=wa(b),A=(e==null?void 0:e.variants)||[],[f,S]=y.useState([]);y.useEffect(()=>{S(A.length?A.map(F=>({...F,isValid:!0,new:!1,id:je()})):[{name:"",weightType:J.VARIABLE,weight:0,overrides:[],stickiness:(f==null?void 0:f.length)>0?f[0].stickiness:g,new:!0,isValid:!1,id:je()}])},[n]);const x=(F,j)=>{S(se=>ft(se.map(Ee=>Ee.id===j?F:Ee),1e3))},E=f.map(({new:F,isValid:j,id:se,...Ee})=>Ee),P=r(A,E),D=o(E),$=async F=>{F.preventDefault(),i(E)},M=()=>q?`curl --location --request POST '${u.unleashUrl}/api/admin/projects/${s}/environments/${e==null?void 0:e.name}/change-requests' \\
|
|
2
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
|
+
--header 'Content-Type: application/json' \\
|
|
4
|
+
--data-raw '${JSON.stringify(D,void 0,2)}'`:`curl --location --request PATCH '${u.unleashUrl}/api/admin/projects/${s}/features/${c}/environments/${e==null?void 0:e.name}/variants' \\
|
|
5
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
6
|
+
--header 'Content-Type: application/json' \\
|
|
7
|
+
--data-raw '${JSON.stringify(P.patch,void 0,2)}'`,B=f.every(({isValid:F})=>F),W=C((e==null?void 0:e.name)||""),H=W?"Add to existing change request":"Add change to draft",q=h((e==null?void 0:e.name)||"")&&u.flags.crOnVariants,Y=((L=E[0])==null?void 0:L.stickiness)||g,K=y.useMemo(()=>["default",...p.filter(F=>F.stickiness).map(F=>F.name)],[p]),v=K.map(F=>({key:F,label:F}));K.includes(Y)||v.push({key:Y,label:Y});const m=async F=>{S(j=>j.map(se=>({...se,stickiness:F})))},w=F=>{m(F).catch(console.warn)},[k,V]=y.useState();return y.useEffect(()=>{V(void 0),P.error&&V(P.error)},[P.error]),t(Je,{open:n,onClose:()=>{a(!1)},label:"",children:l(va,{modal:!0,title:"",description:"Variants allows you to return a variant object if the feature toggle is considered enabled for the current request.",documentationLink:"https://docs.getunleash.io/reference/feature-toggle-variants",documentationLinkLabel:"Feature toggle variants documentation",formatApiCode:M,loading:!n,children:[l(Ms,{children:[l("div",{children:[t(_s,{deprecated:!(e!=null&&e.enabled)}),t(js,{deprecated:!(e!=null&&e.enabled),children:e==null?void 0:e.name})]}),t(oe,{"data-testid":"MODAL_ADD_VARIANT_BUTTON",onClick:()=>S(F=>[...F,{name:"",weightType:J.VARIABLE,weight:0,overrides:[],stickiness:(F==null?void 0:F.length)>0?F[0].stickiness:"default",new:!0,isValid:!1,id:je()}]),variant:"outlined",permission:me,projectId:s,environmentId:e==null?void 0:e.name,children:"Add variant"})]}),l(Ns,{onSubmit:$,children:[t(I,{condition:W,show:T,elseShow:t(I,{condition:Boolean(q),show:l(zs,{severity:"info",children:[t("strong",{children:"Change requests"})," are enabled",e?` for ${e.name}`:"",". Your changes need to be approved before they will be live. All the changes you do now will be added into a draft that you can submit for review."]})})}),t(Hs,{children:f.map(F=>t(Ls,{variant:F,variants:f,updateVariant:j=>x(j,F.id),removeVariant:()=>S(j=>ft(j.filter(se=>se.id!==F.id),1e3)),projectId:s,apiPayload:P},F.id))}),t(I,{condition:f.length>0,show:l(O,{children:[t(qs,{children:t("p",{children:"Stickiness"})}),l(Dt,{children:["By overriding the stickiness you can control which parameter is used to ensure consistent traffic allocation across variants."," ",t("a",{href:"https://docs.getunleash.io/reference/feature-toggle-variants",target:"_blank",rel:"noreferrer",children:"Read more"})]}),t("div",{children:t(Us,{value:Y,label:"",editable:!0,onChange:F=>w(F.target.value)})})]}),elseShow:t(Dt,{children:"This environment has no variants. Get started by adding a variant."})}),l(Ws,{severity:"error",hidden:!Boolean(k),children:[t("strong",{children:"Error: "}),k]}),l(Gs,{children:[t(re,{"data-testid":"DIALOGUE_CONFIRM_ID",type:"submit",variant:"contained",color:"primary",disabled:!B,children:q?H:"Save variants"}),t(Ys,{onClick:()=>{a(!1)},children:"Cancel"})]})]})]})})},Js=d(_)(({theme:e})=>({fontSize:e.fontSizes.smallerBody,whiteSpace:"pre-wrap"})),Xs=({value:e})=>{const{searchQuery:n}=tn();return e?e.type==="string"&&e.value.length<20?t(te,{children:t(Xe,{search:n,children:e.value})}):t(te,{children:t(nn,{tooltip:t(O,{children:t(Js,{children:t(Xe,{search:n,children:e.value})})}),highlighted:n.length>0&&e.value.toLowerCase().includes(n.toLowerCase()),children:e.type})}):t(te,{})},Qs=d(_)(({theme:e})=>({fontSize:e.fontSizes.smallerBody})),Zs=({value:e})=>{const{searchQuery:n}=tn();if(!e||e.length===0)return t(te,{});const a=r=>`${r.contextName}:${r.values.join()}`;return t(te,{children:t(nn,{tooltip:t(O,{children:e.map((r,o)=>t(Qs,{children:t(Xe,{search:n,children:a(r)})},r.contextName+o))}),highlighted:n.length>0&&(e==null?void 0:e.map(a).join(`
|
|
8
|
+
`).toLowerCase().includes(n.toLowerCase())),children:e.length===1?"1 override":`${e.length} overrides`})})},ei=d("div")(({theme:e})=>({margin:e.spacing(3,0)})),ti=({environment:e,searchValue:n})=>{const a=R("projectId"),r=ve(),o=de(r.breakpoints.down("md")),i=de(r.breakpoints.down("lg")),s=e.variants??[],c=y.useMemo(()=>[{Header:"Name",accessor:"name",Cell:Ta,sortType:"alphanumeric",minWidth:350,searchable:!0},{Header:"Payload",accessor:"payload",Cell:Xs,disableSortBy:!0,searchable:!0,filterParsing:S=>S==null?void 0:S.value},{Header:"Overrides",accessor:"overrides",Cell:Zs,disableSortBy:!0,searchable:!0,filterParsing:S=>(S==null?void 0:S.map(({contextName:x,values:E})=>`${x}:${E.join()}`).join(`
|
|
9
|
+
`))||""},{Header:"Weight",accessor:"weight",Cell:({row:{original:{name:S,weight:x}}})=>l(te,{"data-testid":`VARIANT_WEIGHT_${S}`,children:[xa(x)," %"]}),sortType:"number"},{Header:"Type",accessor:S=>S.weightType==="fix"?"Fixed":"Variable",Cell:te,sortType:"alphanumeric"}],[a,s,e]),u=y.useMemo(()=>({sortBy:[{id:"name",desc:!1}]}),[]),{data:p,getSearchText:g}=Aa(c,n,s),{getTableProps:h,getTableBodyProps:b,headerGroups:C,rows:T,prepareRow:A,setHiddenColumns:f}=fe.useTable({columns:c,data:p,initialState:u,sortTypes:Ea,autoResetHiddenColumns:!1,autoResetSortBy:!1,disableSortRemove:!0,disableMultiSort:!0},fe.useSortBy);return an([{condition:o,columns:["payload","overrides"]},{condition:i,columns:["weightType"]}],f,c),l(ei,{children:[t(Ia,{value:g(n),children:l(on,{...h(),children:[t(rn,{headerGroups:C}),t(sn,{...b(),children:T.map(S=>(A(S),t(ln,{hover:!0,...S.getRowProps(),children:S.cells.map(x=>t(cn,{...x.getCellProps(),children:x.render("Cell")}))})))})]})}),t(I,{condition:T.length===0,show:t(I,{condition:(n==null?void 0:n.length)>0,show:l(Ra,{children:["No variants found matching “",n,"”"]})})})]})},ni=d("div")(({theme:e})=>({padding:e.spacing(3),borderRadius:e.shape.borderRadiusLarge,border:`1px solid ${e.palette.divider}`,"&:not(:last-child)":{marginBottom:e.spacing(3)}})),ai=d("div")({display:"flex",alignItems:"center",justifyContent:"space-between","& > div":{display:"flex",alignItems:"center"}}),oi=d(en,{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:n})=>({color:n?e.palette.neutral.border:e.palette.primary.main})),ri=d("span",{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:n})=>({color:n?e.palette.text.secondary:e.palette.text.primary,marginLeft:e.spacing(1.25),fontWeight:e.fontWeight.bold})),si=d("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,marginBottom:e.spacing(1.5)})),ii=d("div")(({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1.5),marginBottom:e.spacing(.5)})),li=({environment:e,searchValue:n,children:a})=>{var i;const r=e.variants??[],o=((i=r[0])==null?void 0:i.stickiness)||"default";return l(ni,{children:[l(ai,{children:[l("div",{children:[t(oi,{deprecated:!e.enabled}),t(ri,{deprecated:!e.enabled,children:e.name})]}),a]}),t(I,{condition:r.length>0,show:l(O,{children:[t(ti,{environment:e,searchValue:n}),t(I,{condition:r.length>1,show:l(O,{children:[l(ii,{children:[t("p",{children:"Stickiness:"}),t(Se,{children:o})]}),l(si,{children:["By overriding the stickiness you can control which parameter is used to ensure consistent traffic allocation across variants."," ",t("a",{href:"https://docs.getunleash.io/reference/feature-toggle-variants",target:"_blank",rel:"noreferrer",children:"Read more"})]})]})})]})})]})},ci=d(at)(({theme:e})=>({"& span":{fontSize:e.fontSizes.smallBody}})),di=({environment:e,permission:n,projectId:a,environmentId:r,onCopyVariantsFrom:o,otherEnvsWithVariants:i})=>{const[s,c]=y.useState(null),u=Boolean(s),p=e.variants??[];return t(I,{condition:i.length>0&&p.length===0,show:l(O,{children:[t(oe,{onClick:g=>{c(g.currentTarget)},id:`copy-from-menu-${e.name}`,"aria-controls":u?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":u?"true":void 0,variant:"outlined",permission:n,projectId:a,environmentId:r,children:"Copy variants from"}),t(Oe,{anchorEl:s,open:u,onClose:()=>c(null),MenuListProps:{"aria-labelledby":`copy-from-menu-${e.name}`},children:i.map(g=>t(De,{onClick:()=>o(g,e),children:t(ci,{children:`Copy from ${g.name}`})},g.name))})]})})},ui=({permission:e,projectId:n,environment:a,checked:r,onClick:o,...i})=>{const s=Fa(e,n,a);return l(De,{disabled:!s,onClick:o,...i,children:[t(Yt,{checked:r}),a]})},pi=d(Oe)(({theme:e})=>({"& > div > ul":{display:"flex",flexDirection:"column",justifyContent:"center","& > li":{padding:e.spacing(0,1)}}})),gi=d("div")(({theme:e})=>({margin:e.spacing(1,2)})),hi=d(re)(({theme:e})=>({marginTop:e.spacing(2)})),mi=({current:e,environments:n,permission:a,projectId:r,onSubmit:o})=>{var A;const[i,s]=y.useState(null),c=Boolean(i),[u,p]=y.useState([]),g=f=>{p(S=>[...S,f])},h=f=>{p(S=>S.filter(({name:x})=>x!==f.name))},b=f=>{u.includes(f)?h(f):g(f)},C=()=>{p([]),s(null)},T=((A=n.find(f=>f.name===e))==null?void 0:A.variants)??[];return t(I,{condition:T.length>0&&n.length>1,show:l(O,{children:[t(re,{onClick:f=>{s(f.currentTarget)},id:`push-to-menu-${e}`,"aria-controls":c?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":c?"true":void 0,variant:"outlined",children:"Push to environment"}),l(pi,{anchorEl:i,open:c,onClose:()=>s(null),MenuListProps:{"aria-labelledby":`push-to-menu-${e}`},children:[n.filter(f=>f.name!==e).map(f=>t(ui,{projectId:r,permission:a,environment:f.name,checked:u.includes(f),onClick:()=>b(f)},f.name)),l(gi,{children:[t(ke,{}),l(hi,{variant:"outlined",onClick:()=>{o(u),C()},disabled:u.length===0,children:["Push to selected (",u.length,")"]})]})]})]})})},fi=d(he)(({theme:e})=>({marginBottom:e.spacing(4),"& code":{fontWeight:e.fontWeight.bold}})),yi=d("div")(({theme:e})=>({display:"flex",gap:e.spacing(1.5)})),Si=()=>{const{uiConfig:e}=dt(),{setToastData:n,setToastApiError:a}=G(),r=ve(),o=de(r.breakpoints.down("md")),i=R("projectId"),s=R("featureId"),{feature:c,refetchFeature:u,loading:p}=N(i,s),{patchFeatureEnvironmentVariants:g,overrideVariantsInEnvironments:h}=Ae(),{refetch:b}=Te(i),{addChange:C}=nt(),{isChangeRequestConfigured:T}=ae(i),[A,f]=y.useState(""),[S,x]=y.useState(),[E,P]=y.useState(!1),D=y.useMemo(()=>{var v;return((v=c==null?void 0:c.environments)==null?void 0:v.map(m=>({...m,crEnabled:e.flags.crOnVariants&&T(m.name)})))||[]},[c.environments,e.flags.crOnVariants]),$=(v,m)=>$a(v,m),M=(v,m)=>{try{const w=Pa(m,1e3);return{patch:$(v,w)}}catch(w){return{patch:[],error:z(w)}}},B=v=>({feature:s,action:"patchVariant",payload:{variants:v}}),W=async(v,m)=>{if(v.crEnabled)await C(i,v.name,B(m)),b();else{const w=v.variants??[],{patch:k,error:V}=M(w,m);if(k.length===0)return;if(V){n({type:"error",title:V});return}await g(i,s,v.name,k)}u()},H=async(v,m)=>{try{const w=m.filter(({crEnabled:j})=>j),k=m.filter(({crEnabled:j})=>!j);w.length&&await Promise.all(w.map(j=>C(i,j.name,B(v)))),k.length&&await h(i,s,v,k.map(({name:j})=>j)),b(),u();const V=k.length?`Variants pushed to ${k.length===1?k[0].name:`${k.length} environments`}`:"",L=w.length?`Variants push added to ${w.length===1?`${w[0].name} draft`:`${w.length} drafts`}`:"",F=`${V}${V&&L?". ":""}${L}`;n({title:F,type:"success"})}catch(w){a(z(w))}},q=v=>{x(v),P(!0)},Y=async v=>{if(S)try{await W(S,v),P(!1),n({title:S.crEnabled?"Variant changes added to draft":"Variants updated successfully",type:"success"})}catch(m){a(z(m))}},K=async(v,m)=>{try{const w=v.variants??[];await W(m,w),n({title:m.crEnabled?"Variants copy added to draft":"Variants copied successfully",type:"success"})}catch(w){a(z(w))}};return l(ut,{isLoading:p,header:t(ka,{title:"Variants",actions:t(I,{condition:!o,show:t(O,{children:t(yt,{initialValue:A,onChange:f})})}),children:t(I,{condition:o,show:t(yt,{initialValue:A,onChange:f})})}),children:[l(fi,{severity:"info",children:["Variants allows you to return a variant object if the feature toggle is considered enabled for the current request. When using variants you should use the ",t("code",{children:"getVariant()"})," method in the Client SDK."]}),D.map(v=>{var w;const m=D.filter(({name:k,variants:V})=>k!==v.name&&(V==null?void 0:V.length));return t(li,{environment:v,searchValue:A,children:l(yi,{children:[t(mi,{current:v.name,environments:D,permission:me,projectId:i,onSubmit:k=>H(v.variants??[],k)}),t(di,{environment:v,permission:me,projectId:i,environmentId:v.name,onCopyVariantsFrom:K,otherEnvsWithVariants:m}),t(I,{condition:Boolean((w=v.variants)==null?void 0:w.length),show:t(X,{"data-testid":"EDIT_VARIANTS_BUTTON",onClick:()=>q(v),permission:me,projectId:i,environmentId:v.name,tooltipProps:{title:"Edit variants"},children:t(ye,{})}),elseShow:t(oe,{"data-testid":"ADD_VARIANT_BUTTON",onClick:()=>q(v),variant:"outlined",permission:me,projectId:i,environmentId:v.name,children:"Add variant"})})]})},v.name)}),t(Ks,{environment:S,open:E,setOpen:P,getApiPayload:M,getCrPayload:B,onConfirm:Y})]})},bi=pe("api/admin/client-metrics/features"),wn=(e,n)=>{const a=pe(`api/admin/client-metrics/features/${e}/raw?hoursBack=${n}`),{data:r,error:o}=et(a,()=>Ci(a)),i=y.useCallback(()=>{$e(bi).catch(console.warn)},[]);return{featureMetrics:r==null?void 0:r.data,loading:!o&&!r,refetchFeatureMetrics:i,error:o}},Ci=e=>fetch(e).then(Ce("Features")).then(n=>n.json()).then(),be=48,vi=({hoursBack:e,setHoursBack:n})=>{const a=r=>{n(wi(r))};return t(Ba,{label:"Period",name:"feature-metrics-period",id:"feature-metrics-period",options:Ti,value:String(e),onChange:a,fullWidth:!0})},wi=e=>{switch(e){case"1":return 1;case"24":return 24;default:return be}},Ti=[{key:"1",label:"Last hour"},{key:"24",label:"Last 24 hours"},{key:`${be}`,label:`Last ${be} hours`}],xi=({metrics:e,tableSectionId:n})=>{const a=de(dn.breakpoints.down("md")),r=y.useMemo(()=>({sortBy:[{id:"timestamp"}]}),[]),{getTableProps:o,getTableBodyProps:i,headerGroups:s,rows:c,prepareRow:u,setHiddenColumns:p}=fe.useTable({initialState:r,columns:Vt,data:e,autoResetHiddenColumns:!1,disableSortRemove:!0,defaultColumn:{Cell:te}},fe.useGlobalFilter,fe.useSortBy);return an([{condition:a,columns:["appName","environment"]}],p,Vt),e.length===0?null:l(on,{...o(),rowHeight:"standard",id:n,children:[t(rn,{headerGroups:s}),t(sn,{...i(),children:c.map(g=>(u(g),t(ln,{hover:!0,...g.getRowProps(),children:g.cells.map(h=>t(cn,{...h.getCellProps(),children:h.render("Cell")}))})))})]})},Vt=[{id:"Icon",width:"1%",disableSortBy:!0,Cell:()=>t(Oa,{icon:t(bo,{color:"disabled"})})},{Header:"Time",accessor:"timestamp",Cell:e=>t(Da,{value:e.row.original.timestamp})},{Header:"Application",accessor:"appName"},{Header:"Environment",accessor:"environment"},{id:"requested",Header:"Requested",accessor:e=>e.yes+e.no},{Header:"Exposed",accessor:"yes"}],Ai=({metrics:e,...n})=>{const a=y.useMemo(()=>e.reduce((o,i)=>o+i.yes,0),[e]),r=y.useMemo(()=>e.reduce((o,i)=>o+i.no,0),[e]);return t(yn,{...n,totalYes:a,totalNo:r})},Ei=({metrics:e,hoursBack:n})=>{const a=St(),r=St();return e.length===0?l(U,{mt:6,children:[t(_,{variant:"body1",paragraph:!0,children:"We have yet to receive any metrics for this feature toggle in the selected time period."}),t(_,{variant:"body1",paragraph:!0,children:"Please note that, since the SDKs send metrics on an interval, it might take some time before metrics appear."})]}):l(y.Suspense,{fallback:null,children:[t(U,{borderTop:1,pt:2,mt:3,borderColor:dn.palette.divider,children:t(Ii,{metrics:e,hoursBack:n,statsSectionId:a})}),t(U,{mt:4,children:t(Ai,{metrics:e,hoursBack:n,statsSectionId:a,tableSectionId:r})}),t(U,{mt:4,children:t(xi,{metrics:e,tableSectionId:r})})]})},Ii=Va.lazy(()=>import("./FeatureMetricsChart-1b77414e.js")),Ze=e=>{const{search:n}=window.location,a=ge(),r=y.useMemo(()=>new URLSearchParams(n),[n]),o=y.useCallback(i=>{const s=new URLSearchParams(n);s.set(e,i),a({search:s.toString()},{replace:!0})},[e,n,a]);return[r.get(e)||void 0,o]},Ri=e=>{const[n,a]=Ze(e),r=y.useCallback(o=>a(String(o)),[a]);return[Number.isFinite(Number(n))?Number(n):void 0,r]},Fi=d("h2")(({theme:e})=>({margin:0,marginBottom:e.spacing(1),fontSize:e.fontSizes.smallBody,fontWeight:e.fontWeight.thin,color:e.palette.text.secondary})),ki=d("ul")(({theme:e})=>({display:"flex",flexWrap:"wrap",gap:e.spacing(1),listStyleType:"none",padding:0,minHeight:"100%"})),Pi=d("li")(({theme:e})=>({"& > [aria-pressed=true]":{backgroundColor:e.palette.primary.main,color:e.palette.primary.contrastText},"& > [aria-pressed=true]:hover":{backgroundColor:e.palette.primary.light}})),Lt=({title:e,values:n,value:a,setValue:r})=>{const o=s=>()=>{n.has(s)&&r(s)},i=y.useMemo(()=>Array.from(n).sort((s,c)=>s.localeCompare(c)),[n]);return l("div",{children:[t(Fi,{children:e}),t(ki,{children:i.map(s=>t(Pi,{children:t(lt,{label:s,onClick:o(s),"aria-pressed":s===a,sx:La})},s))})]})},$i=d("div")(({theme:e})=>({[e.breakpoints.down("md")]:{marginTop:e.spacing(2)}})),Bi=()=>{const e=R("projectId"),n=R("featureId"),a=Oi(e,n),r=Di(n);Jt("Metrics");const[o=be,i]=Ri("hoursBack"),{featureMetrics:s}=wn(n,o),[c,u]=y.useState(s);y.useEffect(()=>{s&&u(s)},[s]);const p=Array.from(a)[0],g=Array.from(r)[0],[h=p,b]=Ze("environment"),[C=g,T]=Ze("application"),A=y.useMemo(()=>c==null?void 0:c.filter(f=>f.environment===h).filter(f=>f.appName===C),[c,h,C]);return A?l(ut,{children:[l(ee,{container:!0,component:"header",spacing:2,alignItems:"flex-end",children:[t(ee,{item:!0,xs:12,md:5,children:t(I,{condition:a.size>0,show:t(Lt,{title:"Environments",values:a,value:h,setValue:b})})}),t(ee,{item:!0,xs:12,md:5,children:t(I,{condition:r.size>0,show:t(Lt,{title:"Applications",values:r,value:C,setValue:T})})}),t(ee,{item:!0,xs:12,md:2,children:t($i,{children:t(vi,{hoursBack:o,setHoursBack:i})})})]}),t(Ei,{metrics:A,hoursBack:o})]}):null},Oi=(e,n)=>{const{feature:a}=N(e,n),r=a.environments.map(o=>o.name);return new Set(r)},Di=e=>{const{featureMetrics:n=[]}=wn(e,be),a=n.map(r=>r.appName);return new Set(a)},Vi=(e,n)=>{const a=new Set(e),r=new Set(n);return a.size!==r.size?!1:[...a].every(o=>r.has(o))},Mt=d("div")(({theme:e})=>({display:"grid",gap:e.spacing(2)})),_t=d(he)(({theme:e})=>({marginBottom:e.spacing(1)})),Li=d(st)({padding:0}),Mi=({projectId:e,open:n,onClose:a,onClick:r,feature:o,changeRequests:i})=>{const s=R("projectId"),{project:c}=un(e),u=y.useMemo(()=>Vi(o.environments.map(g=>g.name),c.environments),[o,c]),p=i?i.length>0:!1;return t(I,{condition:u&&!p,show:t(le,{open:n,onClose:a,onClick:r,title:"Confirm change project",primaryButtonText:"Change project",secondaryButtonText:"Cancel",children:l(Mt,{children:[t(_t,{severity:"success",children:"This feature toggle is compatible with the new project."}),t("p",{children:"Are you sure you want to change the project for this toggle?"})]})}),elseShow:t(le,{open:n,onClick:a,title:"Confirm change project",primaryButtonText:"OK",children:l(Mt,{children:[t(_t,{severity:"warning",children:"Incompatible project environments"}),t("p",{children:"In order to move a feature toggle between two projects, both projects must have the exact same environments enabled."}),t(I,{condition:p,show:l(O,{children:[t("p",{children:"In addition the feature toggle must not have any pending change requests. This feature toggle is currently referenced in the following change requests:"}),t(Li,{children:i==null?void 0:i.map(g=>t(Fe,{children:l(Q,{to:`/projects/${s}/change-requests/${g.id}`,children:["View change request"," ",g.id]})},g.id))})]})})]})})})},_i=e=>fetch(e).then(Ce("ChangeRequest")).then(n=>n.json()),ji=(e,n)=>{const{data:a,error:r,mutate:o}=Ma([],pe(`api/admin/projects/${e}/change-requests/pending/${n}`),_i);return{changeRequests:a,loading:!r&&!a,refetch:o,error:r}},Ni=()=>{const{hasAccess:e}=y.useContext(ot),n=R("projectId"),a=R("featureId"),{feature:r,refetchFeature:o}=N(n,a),[i,s]=y.useState(!1),{changeFeatureProject:c}=Ae(),{setToastData:u,setToastApiError:p}=G(),[g,h]=y.useState(n),{projects:b}=_a(),C=ge(),{changeRequests:T}=ji(n,a),A=async()=>{try{g&&(await c(n,a,g),o(),u({title:"Project changed",type:"success"}),s(!1),C(`/projects/${g}/features/${a}/settings`,{replace:!0}))}catch(S){p(z(S))}},f=y.useMemo(()=>b.map(S=>S.id).filter(S=>e(bt,S)),[b,e]);return f.length===0?null:l(O,{children:[t(ja,{value:g,onChange:h,label:"Project",filter:S=>f.includes(S),enabled:!0}),t(oe,{permission:bt,onClick:()=>s(!0),disabled:g===n,projectId:n,children:"Save"}),t(Mi,{changeRequests:T,projectId:g,open:i,feature:r,onClose:()=>s(!1),onClick:A})]})},zi=d("div")({display:"flex",alignItems:"center"}),Wi=d(_)(({theme:e})=>({fontSize:e.fontSizes.mainHeader})),Hi=({projectId:e,featureId:n})=>{var i;const{feature:a}=N(e,n),r=ge();return l(O,{children:[l(zi,{children:[t(Wi,{children:"Feature information"}),t(X,{permission:ie,projectId:e,"data-loading":!0,onClick:()=>{r(`/projects/${e}/features/${n}/edit`)},tooltipProps:{title:"Edit"},children:t(ye,{})})]}),l(_,{children:["Name: ",t("strong",{children:a.name})]}),l(_,{children:["Description:"," ",t("strong",{children:(i=a.description)!=null&&i.length?a.description:"no description"})]}),l(_,{children:["Type: ",t("strong",{children:a.type})]}),l(_,{children:["Impression Data:"," ",t("strong",{children:a.impressionData?"enabled":"disabled"})]})]})},Ie="metadata",Ye="project",qi=d("div")(({theme:e})=>({width:"20%",borderRight:`1px solid ${e.palette.divider}`,padding:e.spacing(2,0),[e.breakpoints.down("md")]:{width:"35%"}})),Ui=d("div")(({theme:e})=>({padding:e.spacing(4),display:"flex",flexDirection:"column",width:400,["& > *"]:{margin:e.spacing(1,0)}})),Gi=()=>{const e=R("projectId"),n=R("featureId"),[a,r]=y.useState(Ie),{uiConfig:o}=dt();return t(ut,{header:"Settings",sx:{padding:0},children:l(U,{sx:{display:"flex"},children:[t(qi,{children:l(st,{children:[t(Fe,{sx:{padding:"0.75rem 2rem"},button:!0,onClick:()=>r(Ie),selected:a===Ie,children:"Metadata"},0),t(Fe,{sx:{padding:"0.75rem 2rem"},button:!0,onClick:()=>r(Ye),selected:a===Ye,hidden:!o.flags.P,children:"Project"},1)]})}),l(Ui,{children:[t(I,{condition:a===Ie,show:t(Hi,{projectId:e,featureId:n})}),t(I,{condition:a===Ye&&o.flags.P,show:t(Ni,{})})]})]})})},Yi=({stale:e,showActive:n=!0})=>!e&&!n?null:t("div",{"data-loading":!0,style:{marginLeft:"8px"},children:t(Se,{color:e?"neutral":"secondary",title:e?"Feature toggle is deprecated.":"Feature toggle is active.",children:e?"Stale":"Active"})}),jt=d("strong")({wordBreak:"break-all"}),Ki=()=>{const e=R("projectId"),n=R("featureId"),{archivedFeatures:a}=Na(),r=za(e,{name:n});return a?a.some(i=>i.name===n)?l("p",{children:["The feature ",t(jt,{children:n})," has been archived. You can find it on the"," ",t(Q,{to:`/projects/${e}/archive`,children:"project archive page"}),"."]}):l("p",{children:["The feature ",t(jt,{children:n})," does not exist. Would you like to"," ",t(Q,{to:r,children:"create it"}),"?"]}):null},Ji=d("div")(({theme:e})=>({backgroundColor:e.palette.background.paper,borderRadius:e.shape.borderRadiusLarge,marginBottom:e.spacing(2)})),Xi=d("div")(({theme:e})=>({padding:e.spacing(2,4,2,2),display:"flex",justifyContent:"space-between",alignItems:"center",[e.breakpoints.down(500)]:{flexDirection:"column"}})),Qi=d("div")({display:"flex",alignItems:"center"}),Zi=d("h1")(({theme:e})=>({fontSize:e.fontSizes.mainHeader,fontWeight:"normal",display:"flex",alignItems:"center",wordBreak:"break-all"})),el=d("div")({flexShrink:0,display:"flex"}),tl=d("div")(({theme:e})=>({width:"100%",backgroundColor:e.palette.background.elevation2,height:"1px"})),nl=d("div")(({theme:e})=>({padding:e.spacing(0,4)})),al=d(Wa)(({theme:e})=>({textTransform:"none",width:"auto",fontSize:e.fontSizes.bodySize,padding:"0 !important",[e.breakpoints.up("md")]:{minWidth:160}})),cl=()=>{const e=R("projectId"),n=R("featureId"),{refetch:a}=un(e),{favorite:r,unfavorite:o}=Ha(),{refetchFeature:i}=N(e,n),[s,c]=y.useState(!1),[u,p]=y.useState(!1),[g,h]=y.useState(!1),b=de(`(max-width:${500}px)`),{feature:C,loading:T,error:A,status:f}=N(e,n),S=ge(),{pathname:x}=qa(),E=Ua(T),P=`/projects/${e}/features/${n}`,D=[{title:"Overview",path:`${P}`,name:"overview"},{title:"Metrics",path:`${P}/metrics`,name:"Metrics"},{title:"Variants",path:`${P}/variants`,name:"Variants"},{title:"Settings",path:`${P}/settings`,name:"Settings"},{title:"Event log",path:`${P}/logs`,name:"Event log"}],$=D.find(B=>B.path===x)??D[0],M=async()=>{C!=null&&C.favorite?await o(e,C.name):await r(e,C.name),i()};return f===404?t(Ki,{}):A!==void 0?t("div",{ref:E}):l("div",{ref:E,children:[l(Ji,{children:[l(Xi,{children:[l(Qi,{children:[t(Ga,{onClick:M,isFavorite:C==null?void 0:C.favorite}),l(Zi,{"data-loading":!0,children:[C.name," "]}),t(I,{condition:!b,show:t(Yi,{stale:C==null?void 0:C.stale})})]}),l(el,{children:[t(X,{permission:Ya,projectId:e,"data-loading":!0,component:Q,to:`/projects/${e}/features/${n}/strategies/copy`,tooltipProps:{title:"Copy feature toggle"},children:t(Ka,{})}),t(X,{permission:Ja,projectId:e,tooltipProps:{title:"Archive feature toggle"},"data-loading":!0,onClick:()=>p(!0),children:t(so,{})}),t(X,{onClick:()=>h(!0),permission:ie,projectId:e,tooltipProps:{title:"Toggle stale state"},"data-loading":!0,children:t(io,{})}),t(X,{onClick:()=>c(!0),permission:ie,projectId:e,tooltipProps:{title:"Add tag"},"data-loading":!0,children:t(Xa,{})})]})]}),t(tl,{}),t(nl,{children:t(Qa,{value:$.path,indicatorColor:"primary",textColor:"primary",children:D.map(B=>t(al,{label:B.title,value:B.path,onClick:()=>S(B.path)},B.title))})})]}),l(Xt,{children:[t(ne,{path:"metrics",element:t(Bi,{})}),t(ne,{path:"logs",element:t(wo,{})}),t(ne,{path:"variants",element:t(Si,{})}),t(ne,{path:"settings",element:t(Gi,{})}),t(ne,{path:"*",element:t(ms,{})})]}),t(lo,{isOpen:u,onConfirm:()=>{a(),S(`/projects/${e}`)},onClose:()=>p(!1),projectId:e,featureId:n}),t(co,{isStale:C.stale,isOpen:g,onClose:()=>{h(!1),i()},featureId:n,projectId:e}),t(bn,{open:s,setOpen:c})]})};export{cl as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{s as f,r as p,aC as yo,cF as bo,aD as So,j as e,aE as vn,cG as Kt,cH as Tt,cI as vo,cJ as Co,cK as wo,cL as xo,c as Xe,cM as Cn,cN as Oe,cO as It,aR as oe,aQ as Te,aS as Ce,bi as he,cP as wn,C as k,cQ as Zt,ak as Q,al as te,f as r,F,V as ye,cR as xn,cS as $e,cT as ht,cU as ko,cV as To,ae as Ao,cW as Eo,a2 as K,H as Y,ar as ae,bP as kn,av as we,ax as Ot,cX as Nt,a4 as V,az as me,bn as y,bV as ie,bX as be,a5 as Ze,a6 as Ro,a7 as Po,a8 as He,ac as X,Z as Ie,cY as qe,cZ as z,A as _,a9 as M,a as j,c_ as Do,T as I,af as Gt,c$ as Tn,a1 as Io,d0 as Uo,d1 as Me,B as Ut,d2 as Bo,aN as Re,d as Z,e as je,l as Se,g as An,S as En,h as pt,i as We,k as Rn,W as ge,ca as Ne,m as Fe,d3 as Lo,aT as $t,d4 as jt,bv as Pn,d5 as Oo,d6 as Dn,d7 as In,d8 as ne,bw as Un,d9 as No,cc as Xt,da as Ft,bE as Bn,ad as Go,db as $o,dc as At,bG as Ln,bI as jo,bJ as Fo,N as ve,c9 as Ge,dd as ze,R as xe,b8 as Pe,aX as De,U as Qe,Y as et,bW as Ve,bF as zt,w as zo,de as Mo,df as Ho,bO as qo,dg as Wo,dh as _o,di as Vo,aH as mt,dj as Mt,dk as On,ah as Nn,aZ as se,bS as Gn,K as Yo,u as Ht,dl as gt,dm as Jo,L as $n,Q as qt,aL as ke,dn as Ko,aO as tt,dp as Zo,dq as jn,dr as Xo,X as Ye,P as Fn,ds as Qo,bc as Et,be as Rt,dt as ea,du as ta,dv as na,bL as Wt,dw as oa,cm as zn,cs as Mn,ck as de,bQ as Hn,bR as J,x as aa,bq as ra,br as ia,bs as sa,bZ as la,dx as ca,bM as Pt,I as da,dy as qn,dz as dt,dA as Wn,dB as ua,dC as ha,dD as ut,dE as Bt,bD as _n,c2 as pa,O as ma,c4 as ga,c3 as fa,dF as ya,dG as ba,dH as Sa,dI as va,dJ as Ca,dK as wa,c8 as xa,aY as ka,dL as Vn,dM as Ta,dN as Aa,dO as Ea,dP as Ra,dQ as Qt,M as Yn,bd as Pa,bx as Dt,dR as Da}from"./index-
|
|
1
|
+
import{s as f,r as p,aC as yo,cF as bo,aD as So,j as e,aE as vn,cG as Kt,cH as Tt,cI as vo,cJ as Co,cK as wo,cL as xo,c as Xe,cM as Cn,cN as Oe,cO as It,aR as oe,aQ as Te,aS as Ce,bi as he,cP as wn,C as k,cQ as Zt,ak as Q,al as te,f as r,F,V as ye,cR as xn,cS as $e,cT as ht,cU as ko,cV as To,ae as Ao,cW as Eo,a2 as K,H as Y,ar as ae,bP as kn,av as we,ax as Ot,cX as Nt,a4 as V,az as me,bn as y,bV as ie,bX as be,a5 as Ze,a6 as Ro,a7 as Po,a8 as He,ac as X,Z as Ie,cY as qe,cZ as z,A as _,a9 as M,a as j,c_ as Do,T as I,af as Gt,c$ as Tn,a1 as Io,d0 as Uo,d1 as Me,B as Ut,d2 as Bo,aN as Re,d as Z,e as je,l as Se,g as An,S as En,h as pt,i as We,k as Rn,W as ge,ca as Ne,m as Fe,d3 as Lo,aT as $t,d4 as jt,bv as Pn,d5 as Oo,d6 as Dn,d7 as In,d8 as ne,bw as Un,d9 as No,cc as Xt,da as Ft,bE as Bn,ad as Go,db as $o,dc as At,bG as Ln,bI as jo,bJ as Fo,N as ve,c9 as Ge,dd as ze,R as xe,b8 as Pe,aX as De,U as Qe,Y as et,bW as Ve,bF as zt,w as zo,de as Mo,df as Ho,bO as qo,dg as Wo,dh as _o,di as Vo,aH as mt,dj as Mt,dk as On,ah as Nn,aZ as se,bS as Gn,K as Yo,u as Ht,dl as gt,dm as Jo,L as $n,Q as qt,aL as ke,dn as Ko,aO as tt,dp as Zo,dq as jn,dr as Xo,X as Ye,P as Fn,ds as Qo,bc as Et,be as Rt,dt as ea,du as ta,dv as na,bL as Wt,dw as oa,cm as zn,cs as Mn,ck as de,bQ as Hn,bR as J,x as aa,bq as ra,br as ia,bs as sa,bZ as la,dx as ca,bM as Pt,I as da,dy as qn,dz as dt,dA as Wn,dB as ua,dC as ha,dD as ut,dE as Bt,bD as _n,c2 as pa,O as ma,c4 as ga,c3 as fa,dF as ya,dG as ba,dH as Sa,dI as va,dJ as Ca,dK as wa,c8 as xa,aY as ka,dL as Vn,dM as Ta,dN as Aa,dO as Ea,dP as Ra,dQ as Qt,M as Yn,bd as Pa,bx as Dt,dR as Da}from"./index-c6225d46.js";import{u as Ia,C as Ua,A as Ba,a as La,R as Oa,S as Na,T as Ga,b as $a,c as ja,d as Fa,e as za,E as Ma,f as Ha,m as qa,g as ft,B as Wa,h as en}from"./useProjectRole-35fa370c.js";import{E as _a}from"./ExpandMore-26c5bb2a.js";import{a as Va}from"./index-bb86461e.js";import{a as Ya}from"./index-c1725653.js";const Ja=["component","direction","spacing","divider","children"];function Ka(t,n){const o=p.Children.toArray(t).filter(Boolean);return o.reduce((a,i,s)=>(a.push(i),s<o.length-1&&a.push(p.cloneElement(n,{key:`separator-${s}`})),a),[])}const Za=t=>({row:"Left","row-reverse":"Right",column:"Top","column-reverse":"Bottom"})[t],Xa=({ownerState:t,theme:n})=>{let o=vn({display:"flex",flexDirection:"column"},Kt({theme:n},Tt({values:t.direction,breakpoints:n.breakpoints.values}),a=>({flexDirection:a})));if(t.spacing){const a=vo(n),i=Object.keys(n.breakpoints.values).reduce((l,c)=>((typeof t.spacing=="object"&&t.spacing[c]!=null||typeof t.direction=="object"&&t.direction[c]!=null)&&(l[c]=!0),l),{}),s=Tt({values:t.direction,base:i}),d=Tt({values:t.spacing,base:i});typeof s=="object"&&Object.keys(s).forEach((l,c,u)=>{if(!s[l]){const b=c>0?s[u[c-1]]:"column";s[l]=b}}),o=Co(o,Kt({theme:n},d,(l,c)=>({"& > :not(style) + :not(style)":{margin:0,[`margin${Za(c?s[c]:t.direction)}`]:xo(a,l)}})))}return o=wo(n.breakpoints,o),o},Qa=f("div",{name:"MuiStack",slot:"Root",overridesResolver:(t,n)=>[n.root]})(Xa),er=p.forwardRef(function(n,o){const a=yo({props:n,name:"MuiStack"}),i=bo(a),{component:s="div",direction:d="column",spacing:h=0,divider:l,children:c}=i,u=So(i,Ja);return e(Qa,vn({as:s,ownerState:{direction:d,spacing:h},ref:o},u,{children:l?Ka(c,l):c}))}),tr=er,nr=Xe(e("path",{d:"M11.8 10.9c-2.27-.59-3-1.2-3-2.15 0-1.09 1.01-1.85 2.7-1.85 1.42 0 2.13.54 2.39 1.4.12.4.45.7.87.7h.3c.66 0 1.13-.65.9-1.27-.42-1.18-1.4-2.16-2.96-2.54V4.5c0-.83-.67-1.5-1.5-1.5S10 3.67 10 4.5v.66c-1.94.42-3.5 1.68-3.5 3.61 0 2.31 1.91 3.46 4.7 4.13 2.5.6 3 1.48 3 2.41 0 .69-.49 1.79-2.7 1.79-1.65 0-2.5-.59-2.83-1.43-.15-.39-.49-.67-.9-.67h-.28c-.67 0-1.14.68-.89 1.3.57 1.39 1.9 2.21 3.4 2.53v.67c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5v-.65c1.95-.37 3.5-1.5 3.5-3.55 0-2.84-2.43-3.81-4.7-4.4z"}),"AttachMoneyRounded"),or=Xe(e("path",{d:"M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5s-3 1.34-3 3 1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V18c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-1.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05.02.01.03.03.04.04 1.14.83 1.93 1.94 1.93 3.41V18c0 .35-.07.69-.18 1H22c.55 0 1-.45 1-1v-1.5c0-2.33-4.67-3.5-7-3.5z"}),"GroupRounded"),ar=Xe(e("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"}),"MoreVert"),rr=Xe(e("path",{d:"M11.99 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm3.61 6.34c1.07 0 1.93.86 1.93 1.93 0 1.07-.86 1.93-1.93 1.93-1.07 0-1.93-.86-1.93-1.93-.01-1.07.86-1.93 1.93-1.93zm-6-1.58c1.3 0 2.36 1.06 2.36 2.36 0 1.3-1.06 2.36-2.36 2.36s-2.36-1.06-2.36-2.36c0-1.31 1.05-2.36 2.36-2.36zm0 9.13v3.75c-2.4-.75-4.3-2.6-5.14-4.96 1.05-1.12 3.67-1.69 5.14-1.69.53 0 1.2.08 1.9.22-1.64.87-1.9 2.02-1.9 2.68zM11.99 20c-.27 0-.53-.01-.79-.04v-4.07c0-1.42 2.94-2.13 4.4-2.13 1.07 0 2.92.39 3.84 1.15-1.17 2.97-4.06 5.09-7.45 5.09z"}),"SupervisedUserCircle"),ir=Xe(e("path",{d:"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-6 10H6v-2h8v2zm4-4H6v-2h12v2z"}),"Topic");function lt(t){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?lt=function(o){return typeof o}:lt=function(o){return o&&typeof Symbol=="function"&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},lt(t)}function ct(t,n){if(Cn(2,arguments),!n||lt(n)!=="object")return new Date(NaN);var o=n.years?Oe(n.years):0,a=n.months?Oe(n.months):0,i=n.weeks?Oe(n.weeks):0,s=n.days?Oe(n.days):0,d=n.hours?Oe(n.hours):0,h=n.minutes?Oe(n.minutes):0,l=n.seconds?Oe(n.seconds):0,c=It(t),u=a||o?Ya(c,a+o*12):c,m=s||i?Va(u,s+i*7):u,b=h+d*60,v=l+b*60,g=v*1e3,C=new Date(m.getTime()+g);return C}function tn(t,n){Cn(2,arguments);var o=It(t),a=It(n);return o.getTime()>a.getTime()}const Jn=(t={})=>{const n=oe("api/admin/api-tokens"),{data:o,error:a,mutate:i}=Te(n,sr,t),s=p.useMemo(()=>o??[],[o]),d=p.useCallback(()=>{i().catch(console.warn)},[i]);return{tokens:s,error:a,loading:!a&&!o,refetch:d}},sr=async t=>(await(await fetch(t).then(Ce("Api tokens"))).json()).tokens,lr=()=>{const{hasAccess:t}=p.useContext(he),{tokens:n,loading:o,refetch:a}=Jn(),{deleteToken:i}=wn(),{getTableProps:s,getTableBodyProps:d,headerGroups:h,rows:l,prepareRow:c,state:{globalFilter:u},setGlobalFilter:m,setHiddenColumns:b,columns:v}=Ia(n,g=>r(ht,{children:[e(La,{token:g.row.original,permission:Zt}),e(Oa,{token:g.row.original,permission:ko,onRemove:async()=>{await i(g.row.original.secret),a()}})]}));return e(k,{condition:t(Zt),show:()=>e(Q,{header:e(te,{title:`API access (${l.length})`,actions:r(F,{children:[e(ye,{initialValue:u,onChange:m}),e(te.Divider,{}),e(Ua,{permission:xn,path:"/admin/api/create-token"})]})}),children:e(Ba,{loading:o,headerGroups:h,setHiddenColumns:b,prepareRow:c,getTableBodyProps:d,getTableProps:s,rows:l,columns:v,globalFilter:u})}),elseShow:()=>e($e,{})})},cr=({type:t,projects:n,setProjects:o,errors:a,clearErrors:i})=>{const s=To("projectId"),{projects:d}=Ao(),h=d.map(l=>({value:l.id,label:l.name}));return s?null:r(F,{children:[e(Na,{children:"Which project do you want to give access to?"}),e(Eo,{disabled:t===Ga.ADMIN,options:h,defaultValue:n,onChange:o,error:a==null?void 0:a.projects,onFocus:()=>i("projects")})]})},nn="Create API token",dr=({modal:t=!1})=>{const{setToastApiError:n}=K(),{uiConfig:o}=Y(),a=ae(),[i,s]=p.useState(!1),[d,h]=p.useState(""),{getApiTokenPayload:l,username:c,type:u,projects:m,environment:b,setUsername:v,setTokenType:g,setProjects:C,setEnvironment:w,isValid:S,errors:x,clearErrors:P}=$a(),{createToken:L,loading:T}=wn(),{refetch:R}=Jn();kn(nn);const U="api/admin/api-tokens";return r(we,{loading:T,title:nn,modal:t,description:"Unleash SDKs use API tokens to authenticate to the Unleash API. Client SDKs need a token with 'client privileges', which allows them to fetch feature toggle configurations and post usage metrics.",documentationLink:"https://docs.getunleash.io/reference/api-tokens-and-client-keys",documentationLinkLabel:"API tokens documentation",formatApiCode:()=>`curl --location --request POST '${o.unleashUrl}/${U}' \\
|
|
2
2
|
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
3
|
--header 'Content-Type: application/json' \\
|
|
4
4
|
--data-raw '${JSON.stringify(l(),void 0,2)}'`,children:[r(ja,{handleSubmit:async W=>{if(W.preventDefault(),!!S())try{const E=l();await L(E).then(N=>N.json()).then(N=>{Nt(),h(N.secret),s(!0),R()})}catch(E){n(V(E))}},handleCancel:()=>{a(me)},mode:"Create",actions:e(Ot,{name:"token",permission:xn}),children:[e(Fa,{username:c,setUsername:v,errors:x,clearErrors:P}),e(za,{type:u,setType:g}),e(cr,{type:u,projects:m,setProjects:C,errors:x,clearErrors:P}),e(Ma,{type:u,environment:b,setEnvironment:w})]}),e(Ha,{open:i,closeConfirm:()=>{s(!1),a(me)},token:d,type:u})]})},Kn=({data:t={enabled:!1,autoCreate:!1},setValue:n})=>{const o=()=>{n("autoCreate",!t.autoCreate)},a=s=>{n("defaultRootRole",s.target.value)},i=s=>{n(s.target.name,s.target.value)};return r(p.Fragment,{children:[r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Auto-create users"}),e("p",{children:"Enable automatic creation of new users when signing in."})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:o,name:"enabled",checked:t.autoCreate,disabled:!t.enabled}),label:"Auto-create users"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Default Root Role"}),e("p",{children:"Choose which root role the user should get when no explicit role mapping exists."})]}),e(y,{item:!0,md:6,children:r(Ze,{style:{minWidth:"200px"},children:[e(Ro,{id:"defaultRootRole-label",children:"Default Role"}),r(Po,{label:"Default Role",labelId:"defaultRootRole-label",id:"defaultRootRole",name:"defaultRootRole",disabled:!t.autoCreate||!t.enabled,value:t.defaultRootRole||"Editor",onChange:a,children:[e(He,{value:"Viewer",children:"Viewer"}),e(He,{value:"Editor",children:"Editor"}),e(He,{value:"Admin",children:"Admin"})]})]})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Email domains"}),e("p",{children:"Comma separated list of email domains that should be allowed to sign in."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:i,label:"Email domains",name:"emailDomains",disabled:!t.autoCreate||!t.enabled,required:Boolean(t.autoCreate),value:t.emailDomains||"",placeholder:"@company.com, @anotherCompany.com",style:{width:"400px"},rows:2,variant:"outlined",size:"small"})})]})]})},ur=async(t,n)=>{if(t){if(n){const o=await n.json();throw t({message:o.message}),new Error(o.message)}throw new Error}},yt=t=>{const{makeRequest:n,createRequest:o,errors:a,loading:i}=Ie({propagateErrors:!0,handleBadRequest:ur});return{updateSettings:async d=>{const h=`api/admin/auth/${t}/settings`,l=o(h,{method:"POST",body:JSON.stringify(d)});try{await n(l.caller,l.id)}catch(c){throw c}},errors:a,loading:i}},_t=t=>{const o=Object.entries(t).filter(([,a])=>a!=="");return Object.fromEntries(o)},Zn=({ssoType:t,data:n={enabled:!1,enableGroupSyncing:!1,groupJsonPath:""},setValue:o})=>{const a=()=>{o("enableGroupSyncing",!n.enableGroupSyncing)},i=s=>{o(s.target.name,s.target.value)};return r(F,{children:[r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Enable Group Syncing"}),r("p",{children:["Enables automatically syncing of users from the"," ",t,"provider when a user logs in."]})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:a,value:n.enableGroupSyncing,name:"enableGroupSyncing",checked:n.enableGroupSyncing,disabled:!n.enabled}),label:n.enableGroupSyncing?"Enabled":"Disabled"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Group Field JSON Path"}),r("p",{children:["Specifies the path in the ",t," token response from which to read the groups the user belongs to."]})]}),e(y,{item:!0,md:6,children:e(X,{onChange:i,label:"Group JSON Path",name:"groupJsonPath",value:n.groupJsonPath,disabled:!n.enableGroupSyncing,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]})]})},hr={enabled:!1,enableSingleSignOut:!1,enableGroupSyncing:!1,autoCreate:!1,unleashHostname:location.hostname,groupJsonPath:"",clientId:"",discoverUrl:"",secret:"",acrValues:""},pr=()=>{const{setToastData:t,setToastApiError:n}=K(),{uiConfig:o}=Y(),[a,i]=p.useState(hr),{hasAccess:s}=p.useContext(he),{config:d}=qe("oidc"),{updateSettings:h,errors:l,loading:c}=yt("oidc");if(p.useEffect(()=>{d.discoverUrl&&i(d)},[d]),!s(z))return e(_,{severity:"error",children:"You need to be a root admin to access this section."});const u=C=>{v(C.target.name,C.target.value)},m=()=>{i({...a,enabled:!a.enabled})},b=()=>{i({...a,enableSingleSignOut:!a.enableSingleSignOut})},v=(C,w)=>{i({...a,[C]:w})},g=async C=>{C.preventDefault();try{await h(_t(a)),t({title:"Settings stored",type:"success"})}catch(w){n(V(w))}};return r(Q,{children:[e(y,{container:!0,style:{marginBottom:"1rem"},children:e(y,{item:!0,md:12,children:r(_,{severity:"info",children:["Please read the"," ",e("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with specific Open Id Connect providers (Okta, Keycloak, Google, etc). ",e("br",{}),"Callback URL:"," ",r("code",{children:[o.unleashUrl,"/auth/oidc/callback"]})]})})}),r("form",{onSubmit:g,children:[r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Enable"}),e("p",{children:"Enable Open Id Connect Authentication."})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:m,value:a.enabled,name:"enabled",checked:a.enabled}),label:a.enabled?"Enabled":"Disabled"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Discover URL"}),e("p",{children:"(Required) Issuer discover metadata URL"})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Discover URL",name:"discoverUrl",value:a.discoverUrl,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Client ID"}),e("p",{children:"(Required) Client ID of your OpenID application"})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Client ID",name:"clientId",value:a.clientId,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),r(y,{container:!0,spacing:3,mb:4,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Client secret"}),r("p",{children:["(Required) Client secret of your OpenID application."," "]})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Client Secret",name:"secret",value:a.secret,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),e("h3",{children:"Optional Configuration"}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Enable Single Sign-Out"}),e("p",{children:"If you enable Single Sign-Out Unleash will redirect the user to the IDP as part of the Sign-out process."})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:b,value:a.enableSingleSignOut,disabled:!a.enabled,name:"enableSingleSignOut",checked:a.enableSingleSignOut}),label:a.enableSingleSignOut?"Enabled":"Disabled"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"ACR Values"}),e("p",{children:'Requested Authentication Context Class Reference values. If multiple values are specified they should be "space" separated. Will be sent as "acr_values" as part of the authentication request. Unleash will validate the acr value in the id token claims against the list of acr values.'})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"ACR Values",name:"acrValues",value:a.acrValues,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small"})})]}),e(Zn,{ssoType:"OIDC",data:a,setValue:v}),e(Kn,{data:a,setValue:v}),e(y,{container:!0,spacing:3,children:r(y,{item:!0,md:12,children:[e(M,{variant:"contained",color:"primary",type:"submit",disabled:c,children:"Save"})," ",e("p",{children:e("small",{style:{color:"red"},children:l==null?void 0:l.message})})]})})]})]})},mr={enabled:!1,autoCreate:!1,enableGroupSyncing:!1,unleashHostname:location.hostname,entityId:"",signOnUrl:"",certificate:"",signOutUrl:"",spCertificate:"",groupJsonPath:""},gr=()=>{const{setToastData:t,setToastApiError:n}=K(),{uiConfig:o}=Y(),[a,i]=p.useState(mr),{hasAccess:s}=p.useContext(he),{config:d}=qe("saml"),{updateSettings:h,errors:l,loading:c}=yt("saml");if(p.useEffect(()=>{d.entityId&&i(d)},[d]),!s(z))return e(_,{severity:"error",children:"You need to be a root admin to access this section."});const u=g=>{b(g.target.name,g.target.value)},m=()=>{i({...a,enabled:!a.enabled})},b=(g,C)=>{i({...a,[g]:C})},v=async g=>{g.preventDefault();try{await h(_t(a)),t({title:"Settings stored",type:"success"})}catch(C){n(V(C))}};return r(Q,{children:[e(y,{container:!0,style:{marginBottom:"1rem"},children:e(y,{item:!0,md:12,children:r(_,{severity:"info",children:["Please read the"," ",e("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with specific SAML 2.0 providers (Okta, Keycloak, etc). ",e("br",{}),"Callback URL:"," ",r("code",{children:[o.unleashUrl,"/auth/saml/callback"]})]})})}),r("form",{onSubmit:v,children:[r(y,{container:!0,spacing:3,children:[r(y,{item:!0,md:5,mb:2,children:[e("strong",{children:"Enable"}),e("p",{children:"Enable SAML 2.0 Authentication."})]}),e(y,{item:!0,md:6,children:e(ie,{control:e(be,{onChange:m,value:a.enabled,name:"enabled",checked:a.enabled}),label:a.enabled?"Enabled":"Disabled"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Entity ID"}),e("p",{children:"(Required) The Entity Identity provider issuer."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Entity ID",name:"entityId",value:a.entityId,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Single Sign-On URL"}),e("p",{children:"(Required) The url to redirect the user to for signing in."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Single Sign-On URL",name:"signOnUrl",value:a.signOnUrl,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),r(y,{container:!0,spacing:3,mb:4,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"X.509 Certificate"}),e("p",{children:"(Required) The certificate used to sign the SAML 2.0 request."})]}),e(y,{item:!0,md:7,children:e(X,{onChange:u,label:"X.509 Certificate",name:"certificate",value:a.certificate,disabled:!a.enabled,style:{width:"100%"},InputProps:{style:{fontSize:"0.6em",fontFamily:"monospace"}},multiline:!0,rows:14,maxRows:14,variant:"outlined",size:"small",required:!0})})]}),e("h3",{children:"Optional Configuration"}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Single Sign-out URL"}),e("p",{children:"(Optional) The url to redirect the user to for signing out of the IDP."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Single Sign-out URL",name:"signOutUrl",value:a.signOutUrl,disabled:!a.enabled,style:{width:"400px"},variant:"outlined",size:"small"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Service Provider X.509 Certificate"}),e("p",{children:"(Optional) The private certificate used by the Service Provider used to sign the SAML 2.0 request towards the IDP. E.g. used to sign single logout requests (SLO)."})]}),e(y,{item:!0,md:7,children:e(X,{onChange:u,label:"X.509 Certificate",name:"spCertificate",value:a.spCertificate,disabled:!a.enabled,style:{width:"100%"},InputProps:{style:{fontSize:"0.6em",fontFamily:"monospace"}},multiline:!0,rows:14,maxRows:14,variant:"outlined",size:"small"})})]}),e(Zn,{ssoType:"SAML",data:a,setValue:b}),e(Kn,{data:a,setValue:b}),e(y,{container:!0,spacing:3,children:r(y,{item:!0,md:5,children:[e(M,{variant:"contained",color:"primary",type:"submit",disabled:c,children:"Save"})," ",e("p",{children:e("small",{style:{color:"red"},children:l==null?void 0:l.message})})]})})]})]})},fr=()=>{const{setToastData:t,setToastApiError:n}=K(),{config:o}=qe("simple"),[a,i]=p.useState(!1),{updateSettings:s,errors:d,loading:h}=yt("simple"),{hasAccess:l}=p.useContext(he);return p.useEffect(()=>{i(!!o.disabled)},[o.disabled]),l(z)?e(Q,{children:r("form",{onSubmit:async m=>{m.preventDefault();try{await s({disabled:a}),t({title:"Successfully saved",text:"Password authentication settings stored.",autoHideDuration:4e3,type:"success",show:!0})}catch(b){n(V(b)),i(o.disabled)}},children:[r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Password based login"}),e("p",{children:"Allow users to login with username & password"})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:()=>{i(!a)},value:!a,name:"disabled",checked:!a}),label:a?"Disabled":"Enabled"})})]}),e(y,{container:!0,spacing:3,children:r(y,{item:!0,md:12,children:[e(M,{variant:"contained",color:"primary",type:"submit",disabled:h,children:"Save"})," ",e("p",{children:e("small",{style:{color:"red"},children:d==null?void 0:d.message})})]})})]})}):e(_,{severity:"error",children:"You need to be a root admin to access this section."})},yr={enabled:!1,autoCreate:!1,unleashHostname:location.hostname,clientId:"",clientSecret:"",emailDomains:""},br=()=>{const{setToastData:t,setToastApiError:n}=K(),{uiConfig:o}=Y(),[a,i]=p.useState(yr),{hasAccess:s}=p.useContext(he),{config:d}=qe("google"),{updateSettings:h,errors:l,loading:c}=yt("google");if(p.useEffect(()=>{d.clientId&&i(d)},[d]),!s(z))return e("span",{children:"You need admin privileges to access this section."});const u=g=>{i({...a,[g.target.name]:g.target.value})},m=()=>{i({...a,enabled:!a.enabled})},b=()=>{i({...a,autoCreate:!a.autoCreate})},v=async g=>{g.preventDefault();try{await h(_t(a)),t({title:"Settings stored",type:"success"})}catch(C){n(V(C))}};return r(Q,{children:[r(j,{children:[r(_,{severity:"error",sx:{mb:2},children:["This integration is deprecated and will be removed in next major version. Please use ",e("strong",{children:"OpenID Connect"})," to enable Google SSO."]}),r(_,{severity:"info",sx:{mb:3},children:["Read the"," ",e("a",{href:"https://www.unleash-hosted.com/docs/enterprise-authentication/google",target:"_blank",rel:"noreferrer",children:"documentation"})," ","to learn how to integrate with Google OAuth 2.0. ",e("br",{}),"Callback URL:"," ",r("code",{children:[o.unleashUrl,"/auth/google/callback"]})]})]}),r("form",{onSubmit:v,children:[r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,xs:5,children:[e("strong",{children:"Enable"}),e("p",{children:"Enable Google users to login. Value is ignored if Client ID and Client Secret are not defined."})]}),e(y,{item:!0,xs:6,style:{padding:"20px"},children:e(ie,{control:e(be,{onChange:m,value:a.enabled,name:"enabled",checked:a.enabled}),label:a.enabled?"Enabled":"Disabled"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,xs:5,children:[e("strong",{children:"Client ID"}),e("p",{children:"(Required) The Client ID provided by Google when registering the application."})]}),e(y,{item:!0,xs:6,children:e(X,{onChange:u,label:"Client ID",name:"clientId",placeholder:"",value:a.clientId,style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Client Secret"}),e("p",{children:"(Required) Client Secret provided by Google when registering the application."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Client Secret",name:"clientSecret",value:a.clientSecret,placeholder:"",style:{width:"400px"},variant:"outlined",size:"small",required:!0})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Unleash hostname"}),r("p",{children:["(Required) The hostname you are running Unleash on that Google should send the user back to. The final callback URL will be"," ",e("small",{children:e("code",{children:"https://[unleash.hostname.com]/auth/google/callback"})})]})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Unleash Hostname",name:"unleashHostname",placeholder:"",value:a.unleashHostname||"",style:{width:"400px"},variant:"outlined",size:"small"})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Auto-create users"}),e("p",{children:"Enable automatic creation of new users when signing in with Google."})]}),e(y,{item:!0,md:6,style:{padding:"20px"},children:e(be,{onChange:b,name:"enabled",checked:a.autoCreate})})]}),r(y,{container:!0,spacing:3,mb:2,children:[r(y,{item:!0,md:5,children:[e("strong",{children:"Email domains"}),e("p",{children:"(Optional) Comma separated list of email domains that should be allowed to sign in."})]}),e(y,{item:!0,md:6,children:e(X,{onChange:u,label:"Email domains",name:"emailDomains",value:a.emailDomains,placeholder:"@company.com, @anotherCompany.com",style:{width:"400px"},rows:2,multiline:!0,variant:"outlined",size:"small"})})]}),e(y,{container:!0,spacing:3,children:r(y,{item:!0,md:5,children:[e(M,{variant:"contained",color:"primary",type:"submit",disabled:c,children:"Save"})," ",e("p",{children:e("small",{style:{color:"red"},children:l==null?void 0:l.message})})]})})]})]})},Sr=()=>{const{authenticationType:t}=Y().uiConfig;return e("div",{children:r(Q,{header:"Single Sign-On",children:[e(k,{condition:t==="enterprise",show:e(Do,{tabData:[{label:"OpenID Connect",component:e(pr,{})},{label:"SAML 2.0",component:e(gr,{})},{label:"Password",component:e(fr,{})},{label:"Google",component:e(br,{})}]})}),e(k,{condition:t==="open-source",show:e(_,{severity:"warning",children:"You are running the open-source version of Unleash. You have to use the Enterprise edition in order configure Single Sign-on."})}),e(k,{condition:t==="demo",show:e(_,{severity:"warning",children:"You are running Unleash in demo mode. You have to use the Enterprise edition in order configure Single Sign-on."})}),e(k,{condition:t==="custom",show:e(_,{severity:"warning",children:"You have decided to use custom authentication type. You have to use the Enterprise edition in order configure Single Sign-on from the user interface."})}),e(k,{condition:t==="hosted",show:e(_,{severity:"info",children:"Your Unleash instance is managed by the Unleash team."})})]})})},vr=oe("api/admin/invoices"),Cr=f(M)(({theme:t})=>({width:"100%",marginBottom:t.spacing(1.5)})),wr=({update:t})=>e(Cr,{href:`${vr}/${t?"portal":"checkout"}`,variant:t?"outlined":"contained",children:t?"Update billing information":"Add billing information"}),xr=f("aside")(({theme:t})=>({padding:t.spacing(4),height:"100%",borderRadius:t.shape.borderRadiusLarge,backgroundColor:t.palette.background.elevation2})),kr=f(I)(({theme:t})=>({marginBottom:t.spacing(4)})),Tr=f(_)(({theme:t})=>({marginBottom:t.spacing(4)})),on=f(I)(({theme:t})=>({fontSize:t.fontSizes.smallBody,color:t.palette.text.secondary})),Ar=f(Gt)(({theme:t})=>({margin:`${t.spacing(2.5)} 0`,borderColor:t.palette.divider})),Er=({instanceStatus:t})=>{const n=t.state!==Tn.ACTIVE;return e(y,{item:!0,xs:12,md:5,children:r(xr,{children:[e(kr,{variant:"body1",children:"Billing information"}),e(k,{condition:n,show:r(Tr,{severity:"warning",children:["In order to ",e("strong",{children:"Upgrade trial"})," you need to provide us your billing information."]})}),e(wr,{update:!n}),e(on,{children:n?"Once we have received your billing information we will upgrade your trial within 1 business day":"Update your credit card and business information and change which email address we send invoices to"}),e(Ar,{}),r(on,{children:[e("a",{href:"mailto:elise@getunleash.ai?subject=PRO plan clarifications",children:"Get in touch with us"})," ","for any clarification"]})]})})},Ue=()=>{const{data:t,error:n,mutate:o}=Te(oe("api/admin/user-admin"),Rr);return p.useMemo(()=>({users:(t==null?void 0:t.users)??[],roles:(t==null?void 0:t.rootRoles)??[],loading:!n&&!t,refetch:()=>o(),error:n}),[t,n,o])},Rr=t=>fetch(t).then(Ce("Users")).then(n=>n.json()),Pr=f(y)(({theme:t})=>({flexWrap:"nowrap",gap:t.spacing(1)})),ot=({sx:t,children:n})=>e(Pr,{container:!0,item:!0,justifyContent:"space-between",alignItems:"center",sx:t,children:n}),Ee=({children:t,vertical:n=!1})=>e(y,{container:n,item:!0,display:"flex",alignItems:n?"start":"center",direction:n?"column":void 0,children:t}),Dr=f("span")(({theme:t})=>({fontSize:t.fontSizes.smallBody,marginLeft:t.spacing(1)})),an=({children:t})=>r(Dr,{children:["(",t,")"]}),Ir=f("aside")(({theme:t})=>({padding:t.spacing(2.5),height:"100%",borderRadius:t.shape.borderRadiusLarge,boxShadow:t.boxShadows.elevated,[t.breakpoints.up("md")]:{padding:t.spacing(6.5)}})),rn=f(I)(({theme:t})=>({fontSize:t.fontSizes.smallBody,color:t.palette.text.secondary})),Ur=f("span")(({theme:t})=>({fontSize:"3.25rem",lineHeight:1,color:t.palette.primary.main,fontWeight:800})),Br=f("span")(({theme:t})=>({marginLeft:t.spacing(1.5),fontWeight:t.fontWeight.bold})),Lr=f("span")(({theme:t})=>({color:t.palette.primary.main,fontSize:t.fontSizes.mainHeader,fontWeight:t.fontWeight.bold})),Or=f(_)(({theme:t})=>({fontSize:t.fontSizes.smallerBody,marginBottom:t.spacing(3),marginTop:t.spacing(-1.5),[t.breakpoints.up("md")]:{marginTop:t.spacing(-4.5)}})),Nr=f(Io)(({theme:t})=>({fontSize:"1rem",marginRight:t.spacing(1)})),Gr=f(Gt)(({theme:t})=>({margin:`${t.spacing(3)} 0`})),$r=({instanceStatus:t})=>{var v;const{users:n}=Ue(),o=Uo(t),{uiConfig:a}=Y(),i=n.filter(g=>g.email),s={[Me.PRO]:80,[Me.COMPANY]:0,[Me.TEAM]:0,[Me.UNKNOWN]:0,user:15},d=s[t.plan],h=t.seats??5,l=Math.min(i.length,h),c=i.length-l,u=s.user*c,m=d+u,b=t.state!==Tn.ACTIVE;return e(y,{item:!0,xs:12,md:7,children:r(Ir,{children:[e(k,{condition:b,show:r(Or,{severity:"info",children:["After you have sent your billing information, your instance will be upgraded - you don't have to do anything."," ",e("a",{href:"mailto:elise@getunleash.ai?subject=PRO plan clarifications",children:"Get in touch with us"})," ","for any clarification"]})}),e(Ut,{color:"success",children:"Current plan"}),e(y,{container:!0,children:r(ot,{sx:g=>({marginBottom:g.spacing(3)}),children:[r(Ee,{children:[e(Ur,{children:t.plan}),e(k,{condition:Bo(t),show:e(Br,{sx:g=>({color:o?g.palette.error.dark:g.palette.warning.dark}),children:o?"Trial expired":t.trialExtended?"Extended Trial":"Trial"})})]}),e(Ee,{children:e(k,{condition:d>0,show:r(Lr,{children:["$",d.toFixed(2)]})})})]})}),e(k,{condition:Boolean(((v=a==null?void 0:a.flags)==null?void 0:v.proPlanAutoCharge)&&t.plan===Me.PRO),show:r(F,{children:[r(y,{container:!0,children:[r(ot,{sx:g=>({marginBottom:g.spacing(1.5)}),children:[r(Ee,{vertical:!0,children:[r(I,{children:[e("strong",{children:"Included members"}),e(an,{children:r(Re,{to:"/admin/users",children:[l," of 5 assigned"]})})]}),e(rn,{children:"You have 5 team members included in your PRO plan"})]}),r(Ee,{children:[e(Nr,{}),e(I,{variant:"body2",children:"included"})]})]}),r(ot,{children:[r(Ee,{vertical:!0,children:[r(I,{children:[e("strong",{children:"Paid members"}),e(an,{children:r(Re,{to:"/admin/users",children:[c," assigned"]})})]}),e(rn,{children:"$15/month per paid member"})]}),e(Ee,{children:r(I,{sx:g=>({fontSize:g.fontSizes.mainHeader}),children:["$",u.toFixed(2)]})})]})]}),e(Gr,{}),e(y,{container:!0,children:r(ot,{children:[e(Ee,{children:e(I,{sx:g=>({fontWeight:g.fontWeight.bold,fontSize:g.fontSizes.mainHeader}),children:"Total per month"})}),e(Ee,{children:r(I,{sx:g=>({fontWeight:g.fontWeight.bold,fontSize:"2rem"}),children:["$",m.toFixed(2)]})})]})})]})})]})})},jr=({instanceStatus:t})=>r(y,{container:!0,spacing:4,children:[e(Er,{instanceStatus:t}),e($r,{instanceStatus:t})]}),Fr=f(I)(({theme:t})=>({marginTop:t.spacing(6),marginBottom:t.spacing(2.5),fontSize:t.fontSizes.mainHeader})),zr=[{Header:"Amount",accessor:"amountFormatted"},{Header:"Status",accessor:"status",disableGlobalFilter:!0},{Header:"Created date",accessor:"created",Cell:Ne,sortType:"date",disableGlobalFilter:!0},{Header:"Due date",accessor:"dueDate",Cell:Ne,sortType:"date",disableGlobalFilter:!0},{Header:"Download",accessor:"invoicePDF",align:"center",Cell:({value:t})=>e(j,{sx:{display:"flex",justifyContent:"center"},"data-loading":!0,children:e(Fe,{href:t,children:e(Lo,{})})}),width:100,disableGlobalFilter:!0,disableSortBy:!0}],Mr=({data:t,isLoading:n=!1})=>{const o=p.useMemo(()=>({sortBy:[{id:"created"}]}),[]),{getTableProps:a,getTableBodyProps:i,headerGroups:s,rows:d,prepareRow:h}=Z.useTable({columns:zr,data:t,initialState:o,sortTypes:je,autoResetGlobalFilter:!1,disableSortRemove:!0,defaultColumn:{Cell:Se}},Z.useGlobalFilter,Z.useSortBy);return r(Q,{isLoading:n,disablePadding:!0,children:[e(Fr,{children:"Payment history"}),r(An,{...a(),children:[e(En,{headerGroups:s}),e(pt,{...i(),children:d.map(l=>(h(l),e(We,{hover:!0,...l.getRowProps(),children:l.cells.map(c=>e(Rn,{...c.getCellProps(),children:c.render("Cell")}))})))})]}),e(k,{condition:d.length===0,show:e(ge,{children:"No invoices to show."})})]})},Lt="api/admin/invoices",Hr=oe(Lt),Xn=(t={})=>{const n=()=>fetch(Hr,{method:"GET"}).then(Ce("Invoices")).then(h=>h.json()),{data:o,error:a}=Te(Lt,n,t),[i,s]=p.useState(!a&&!o),d=()=>{$t(Lt)};return p.useEffect(()=>{s(!a&&!o)},[o,a]),{invoices:(o==null?void 0:o.invoices)||[],error:a,loading:i,refetchInvoices:d}},qr=()=>{const{instanceStatus:t,isBilling:n,refetchInstanceStatus:o,refresh:a,loading:i}=jt(),{invoices:s}=Xn(),{hasAccess:d}=p.useContext(he);return p.useEffect(()=>{(async()=>{await a(),o()})()},[o,a]),e("div",{children:e(Q,{header:"Billing",isLoading:i,children:e(k,{condition:n,show:e(k,{condition:d(z),show:()=>r(F,{children:[e(jr,{instanceStatus:t}),e(Mr,{data:s})]}),elseShow:()=>e($e,{})}),elseShow:e(_,{severity:"error",children:"Billing is not enabled for this instance."})})})})},Wr=oe("api/admin/invoices/portal"),_r=()=>{const{refetchInvoices:t,invoices:n}=Xn(),[o,a]=p.useState(!1),{locationSettings:i}=Pn();return p.useEffect(()=>{t(),a(!0)},[]),e(k,{condition:n.length>0,show:e(Q,{header:e(te,{title:"Invoices",actions:e(M,{href:Wr,rel:"noreferrer",target:"_blank",endIcon:e(Oo,{}),children:"Billing portal"})}),children:e("div",{children:r(Dn,{children:[e(In,{children:r(We,{children:[e(ne,{children:"Amount"}),e(ne,{children:"Status"}),e(ne,{children:"Due date"}),e(ne,{children:"PDF"}),e(ne,{children:"Link"})]})}),e(pt,{children:n.map(s=>r(We,{style:{backgroundColor:s.status==="past-due"?"#ff9194":"inherit"},children:[e(ne,{style:{textAlign:"left"},children:s.amountFormatted}),e(ne,{style:{textAlign:"left"},children:s.status}),e(ne,{style:{textAlign:"left"},children:s.dueDate&&Un(s.dueDate,i.locale)}),e(ne,{style:{textAlign:"left"},children:e("a",{href:s.invoicePDF,children:"PDF"})}),e(ne,{style:{textAlign:"left"},children:e("a",{href:s.invoiceURL,target:"_blank",rel:"noreferrer",children:"Payment link"})})]},s.invoiceURL))})]})})}),elseShow:e("div",{children:o&&"No invoices to show."})})},Vr=()=>{const{hasAccess:t}=p.useContext(he);return e("div",{children:e(k,{condition:t(z),show:e(_r,{}),elseShow:e(_,{severity:"error",children:"You need to be instance admin to access this section."})})})},Yr=()=>{const{uiConfig:t,loading:n}=Y();return n?null:t.flags.UNLEASH_CLOUD?e(No,{to:"/admin/billing",replace:!0}):e(Vr,{})},Jr=()=>r(_,{severity:"info",children:[r("p",{children:["Use this page to configure allowed CORS origins for the Frontend API (",e("code",{children:"/api/frontend"}),")."]}),r("p",{children:["This configuration will not affect the Admin API (",e("code",{children:"/api/admin"}),") nor the Client API (",e("code",{children:"/api/client"}),")."]}),r("p",{children:["An asterisk (",e("code",{children:"*"}),") may be used to allow API calls from any origin."]}),e("br",{}),e("p",{children:"Be aware that changes here will take up to two minutes to be updated. In addition, there is a maxAge on the Access-Control-Allow-Origin header that will instruct browsers to cache this header for some time. The cache period is set to the maxium that the browser allows (2h for Chrome, 24h for Firefox)."})]}),Kr=()=>{const{makeRequest:t,createRequest:n,errors:o,loading:a}=Ie({propagateErrors:!0});return{setFrontendSettings:async s=>{const h=n("api/admin/ui-config",{method:"POST",body:JSON.stringify({frontendSettings:{frontendApiOrigins:s}})},"setFrontendSettings");await t(h.caller,h.id)},loading:a,errors:o}},Zr=({frontendApiOrigins:t})=>{const{setFrontendSettings:n}=Kr(),{setToastData:o,setToastApiError:a}=K(),[i,s]=p.useState(sn(t)),d=Xt(),h=Xt();return e("form",{onSubmit:async c=>{try{const u=Xr(i);c.preventDefault(),await n(u),s(sn(u)),o({title:"Settings saved",type:"success"})}catch(u){a(V(u))}},children:r(j,{sx:{display:"grid",gap:1},children:[r("label",{htmlFor:d,children:["Which origins should be allowed to call the Frontend API? Add only one origin per line. The CORS specification does not support wildcard for subdomains, it needs to be a fully qualified domain, including the protocol.",e("br",{}),e("br",{}),'If you specify "*" it will be the chosen origin.',e("br",{}),e("br",{}),"Example:"]}),r("code",{style:{fontSize:"0.7em"},children:["https://www.example.com",e("br",{}),"https://www.example2.com"]}),e(X,{id:d,"aria-describedby":h,placeholder:Qr,value:i,onChange:c=>s(c.target.value),multiline:!0,rows:12,variant:"outlined",fullWidth:!0,InputProps:{style:{fontFamily:"monospace",fontSize:"0.8em"}}}),e(Ft,{permission:z})]})})},Xr=t=>t.split(/[,\n\s]+/).map(n=>n.replace(/\/$/,"")).filter(Boolean),sn=t=>(t==null?void 0:t.join(`
|
|
@@ -12,7 +12,7 @@ import{s as f,r as p,aC as yo,cF as bo,aD as So,j as e,aE as vn,cG as Kt,cH as T
|
|
|
12
12
|
--data-raw '${JSON.stringify(w(),void 0,2)}'`,H=()=>{h(me)},B=E=>E.length,D=E=>!(L!=null&&L.filter(N=>N.name===E&&N.id!==t).length),O=B(l)&&D(l);return e(we,{loading:R,title:"Edit group",description:"Groups is the best and easiest way to organize users and then use them in projects to assign a specific role in one go to all the users in a group.",documentationLink:"https://docs.getunleash.io/advanced/groups",documentationLinkLabel:"Groups documentation",formatApiCode:A,children:e(to,{name:l,description:u,mappingsSSO:b,users:g,setName:E=>{S(),D(E)||P({name:"A group with that name already exists."}),c(E)},setDescription:m,setMappingsSSO:v,setUsers:C,errors:x,handleSubmit:U,handleCancel:H,mode:Mt,children:e(M,{type:"submit",variant:"contained",color:"primary",disabled:!O,"data-testid":On,children:"Save"})})})},vi=f(Nn)(({theme:t})=>({borderRadius:t.shape.borderRadiusLarge,padding:t.spacing(2.5,4),boxShadow:"none",marginBottom:t.spacing(2),fontSize:t.fontSizes.smallBody})),Ci=f("div")(({theme:t})=>({display:"flex",alignItems:"center",justifyContent:"space-between"})),wi=f("h1")(({theme:t})=>({fontSize:t.fontSizes.mainHeader})),xi=f("div")(({theme:t})=>({display:"flex"})),ki=f("span")(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginLeft:t.spacing(1)})),Ti=({title:t,description:n,actions:o})=>(kn(t),r(vi,{children:[r(Ci,{children:[e(wi,{children:t}),e(xi,{children:o})]}),e(k,{condition:Boolean(n==null?void 0:n.length),show:r(F,{children:["Description:",e(ki,{children:n})]})})]})),no=({open:t,setOpen:n,group:o})=>{const{refetchGroups:a}=_e(),{removeGroup:i}=nt(),{setToastData:s,setToastApiError:d}=K(),h=ae();return e(se,{open:t,primaryButtonText:"Delete group",secondaryButtonText:"Cancel",onClick:async()=>{try{await i(o.id),a(),n(!1),h("/admin/groups"),s({title:"Group removed successfully",type:"success"})}catch(c){d(V(c))}},onClose:()=>{n(!1)},title:"Delete group?",children:r(I,{children:["Do you really want to delete ",e("strong",{children:o.name}),"? Users who are granted access to projects only via this group will lose access to those projects."]})})},Ai=f("form")(()=>({display:"flex",flexDirection:"column",height:"100%"})),Ei=f("p")(({theme:t})=>({color:t.palette.text.secondary,marginBottom:t.spacing(1)})),Ri=f("div")(()=>({marginTop:"auto",display:"flex",justifyContent:"flex-end"})),Pi=f(M)(({theme:t})=>({marginLeft:t.spacing(3)})),Di=f(j)(({theme:t})=>({marginTop:t.spacing(2)})),oo=({open:t,setOpen:n,group:o})=>{const{refetchGroup:a}=ft(o.id),{refetchGroups:i}=_e(),{updateGroup:s,loading:d}=nt(),{setToastData:h,setToastApiError:l}=K(),{uiConfig:c}=Y(),{users:u,setUsers:m,getGroupPayload:b}=Vt(o.name,o.description,o.mappingsSSO,o.users);return p.useEffect(()=>{m(o.users)},[o.users,t,m]),e(Gn,{open:t,onClose:()=>{n(!1)},label:"Edit users",children:e(we,{loading:d,modal:!0,title:"Edit users",description:"Groups is the best and easiest way to organize users and then use them in projects to assign a specific role in one go to all the users in a group.",documentationLink:"https://docs.getunleash.io/advanced/groups",documentationLinkLabel:"Groups documentation",formatApiCode:()=>`curl --location --request PUT '${c.unleashUrl}/api/admin/groups/${o.id}' \\
|
|
13
13
|
--header 'Authorization: INSERT_API_KEY' \\
|
|
14
14
|
--header 'Content-Type: application/json' \\
|
|
15
|
-
--data-raw '${JSON.stringify(b(),void 0,2)}'`,children:r(Ai,{onSubmit:async C=>{C.preventDefault();try{await s(o.id,b()),a(),i(),n(!1),h({title:"Group users saved successfully",type:"success"})}catch(w){l(V(w))}},children:[r("div",{children:[e(Ei,{children:"Edit users in this group"}),e(Qn,{users:u,setUsers:m}),e(eo,{users:u,setUsers:m})]}),e(Ri,{children:r(Di,{children:[e(M,{type:"submit",variant:"contained",color:"primary","data-testid":On,children:"Save"}),e(Pi,{onClick:()=>{n(!1)},children:"Cancel"})]})})]})})})},Ii=({open:t,setOpen:n,user:o,group:a})=>{const{refetchGroup:i}=ft(a.id),{updateGroup:s}=nt(),{setToastData:d,setToastApiError:h}=K(),l=async()=>{try{const u={...a,users:a.users.filter(({id:m})=>m!==(o==null?void 0:o.id)).map(({id:m})=>({user:{id:m}}))};await s(a.id,u),i(),n(!1),d({title:"User removed from group successfully",type:"success"})}catch(u){h(V(u))}},c=(o==null?void 0:o.name)||(o==null?void 0:o.username)||(o==null?void 0:o.email);return e(se,{open:t&&Boolean(o),primaryButtonText:"Remove user",secondaryButtonText:"Cancel",onClick:l,onClose:()=>{n(!1)},title:"Remove user from group?",children:r(I,{children:["Do you really want to remove ",e("strong",{children:c})," from"," ",e("strong",{children:a.name}),"? ",e("strong",{children:c})," will lose all access rights granted by this group."]})})},Ui=Array(15).fill({name:"Name of the user",username:"Username of the user"}),Bi={id:"joinedAt"},{value:cn,setValue:Li}=Yo("Group:v1",Bi),Oi=()=>{const t=Number(mt("groupId")),n=Ht(),o=ve(n.breakpoints.down("md")),{group:a,loading:i}=ft(t),[s,d]=p.useState(!1),[h,l]=p.useState(!1),[c,u]=p.useState(!1),[m,b]=p.useState(),v=p.useMemo(()=>[{Header:"Avatar",accessor:"imageUrl",Cell:({row:{original:D}})=>e(Se,{children:e(ze,{user:D})}),maxWidth:85,disableSortBy:!0},{id:"name",Header:"Name",accessor:D=>D.name||"",Cell:xe,minWidth:100,searchable:!0},{id:"username",Header:"Username",accessor:D=>D.username||D.email,Cell:xe,minWidth:100,searchable:!0},{Header:"Joined",accessor:"joinedAt",Cell:Ne,sortType:"date",maxWidth:150},{id:"createdBy",Header:"Added by",accessor:"createdBy",Cell:xe,minWidth:90,searchable:!0},{Header:"Last login",accessor:D=>D.seenAt||"",Cell:({row:{original:D}})=>e(gt,{value:D.seenAt,emptyText:"Never",title:O=>`Last login: ${O}`}),sortType:"date",maxWidth:150},{Header:"Actions",id:"Actions",align:"center",Cell:({row:{original:D}})=>e(ht,{children:e(Pe,{title:"Remove user from group",arrow:!0,describeChild:!0,children:e("span",{children:e(Fe,{"data-testid":`${Jo}-${D.id}`,onClick:()=>{b(D),u(!0)},children:e(De,{})})})})}),maxWidth:100,disableSortBy:!0}],[b,u]),[g,C]=$n(),[w]=p.useState(()=>({sortBy:[{id:g.get("sort")||cn.id,desc:g.has("order")?g.get("order")==="desc":cn.desc}],hiddenColumns:["description"],globalFilter:g.get("search")||""})),[S,x]=p.useState(w.globalFilter),{data:P,getSearchText:L,getSearchContext:T}=qt(v,S,(a==null?void 0:a.users)??[]),R=p.useMemo(()=>(P==null?void 0:P.length)===0&&i?Ui:P,[P,i]),{headerGroups:U,rows:A,prepareRow:H,state:{sortBy:B}}=Z.useTable({columns:v,data:R,initialState:w,sortTypes:je,autoResetSortBy:!1,disableSortRemove:!0,disableMultiSort:!0},Z.useSortBy,Z.useFlexLayout);return p.useEffect(()=>{const D={};D.sort=B[0].id,B[0].desc&&(D.order="desc"),S&&(D.search=S),C(D,{replace:!0}),Li({id:B[0].id,desc:B[0].desc||!1})},[B,S,C]),e(k,{condition:Boolean(a),show:r(F,{children:[e(Ti,{title:a==null?void 0:a.name,description:a==null?void 0:a.description,actions:r(F,{children:[e(ke,{"data-testid":Ko,to:`/admin/groups/${t}/edit`,component:Re,"data-loading":!0,permission:z,tooltipProps:{title:"Edit group"},children:e(tt,{})}),e(ke,{"data-testid":Zo,"data-loading":!0,onClick:()=>d(!0),permission:z,tooltipProps:{title:"Delete group"},children:e(De,{})})]})}),r(Q,{isLoading:i,header:e(te,{secondary:!0,title:`Users (${A.length<R.length?`${A.length} of ${R.length}`:R.length})`,actions:r(F,{children:[e(k,{condition:!o,show:r(F,{children:[e(ye,{initialValue:S,onChange:x,hasFilters:!0,getSearchContext:T}),e(te.Divider,{})]})}),e(jn,{"data-testid":Xo,onClick:()=>{l(!0)},maxWidth:"700px",Icon:zt,permission:z,children:"Edit users"})]}),children:e(k,{condition:o,show:e(ye,{initialValue:S,onChange:x,hasFilters:!0,getSearchContext:T})})}),children:[e(Ye,{value:L(S),children:e(et,{rows:A,headerGroups:U,prepareRow:H})}),e(k,{condition:A.length===0,show:e(k,{condition:(S==null?void 0:S.length)>0,show:r(ge,{children:["No users found matching “",S,"” in this group."]}),elseShow:e(ge,{children:"This group is empty. Get started by adding a user to the group."})})}),e(no,{open:s,setOpen:d,group:a}),e(oo,{open:h,setOpen:l,group:a}),e(Ii,{open:c,setOpen:u,user:m,group:a})]})]})})},Ni=f(Fn)(({theme:t})=>({pointerEvents:"none",".MuiPaper-root":{padding:t.spacing(2)}})),Gi=f("div")(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(1)})),$i=({user:t,open:n,anchorEl:o,onPopoverClose:a})=>r(Ni,{open:n,anchorEl:o,onClose:a,anchorOrigin:{vertical:"bottom",horizontal:"left"},transformOrigin:{vertical:"top",horizontal:"left"},children:[e(Gi,{children:(t==null?void 0:t.name)||(t==null?void 0:t.username)}),e("div",{children:t==null?void 0:t.email})]}),ji=f("div")(({theme:t})=>({display:"inline-flex",alignItems:"center",flexWrap:"wrap",marginLeft:t.spacing(1)})),dn=f(ze)(({theme:t})=>({outline:`${t.spacing(.25)} solid ${t.palette.background.paper}`,marginLeft:t.spacing(-1),"&:hover":{outlineColor:t.palette.primary.main}})),Fi=({users:t})=>{const n=p.useMemo(()=>t.sort((c,u)=>(u==null?void 0:u.joinedAt.getTime())-(c==null?void 0:c.joinedAt.getTime())).slice(0,9),[t]),[o,a]=p.useState(null),[i,s]=p.useState(),d=c=>{a(c.currentTarget)},h=()=>{a(null)},l=Boolean(o);return r(ji,{children:[n.map(c=>e(dn,{user:c,onMouseEnter:u=>{d(u),s(c)},onMouseLeave:h},c.id)),e(k,{condition:t.length>9,show:r(dn,{children:["+",t.length-n.length]})}),e($i,{open:l,user:i,anchorEl:o,onPopoverClose:h})]})},zi=f("div")(({theme:t})=>({display:"flex",justifyContent:"center",transform:"translate3d(8px, -6px, 0)"})),Mi=f(Fn)(({theme:t})=>({borderRadius:t.shape.borderRadiusLarge,padding:t.spacing(1,1.5)})),Hi=({groupId:t,onEditUsers:n,onRemove:o})=>{const[a,i]=p.useState(null),s=Boolean(a),d=u=>{i(u.currentTarget)},h=()=>{i(null)},l=`feature-${t}-actions`,c=`${l}-menu`;return r(zi,{onClick:u=>{u.preventDefault(),u.stopPropagation()},children:[e(Pe,{title:"Group actions",arrow:!0,describeChild:!0,children:e(Fe,{id:l,"aria-controls":s?c:void 0,"aria-haspopup":"true","aria-expanded":s?"true":void 0,onClick:d,type:"button",children:e(ar,{})})}),e(Mi,{id:c,anchorEl:a,open:s,onClose:h,transformOrigin:{horizontal:"right",vertical:"top"},anchorOrigin:{horizontal:"right",vertical:"bottom"},disableScrollLock:!0,children:r(Qo,{"aria-labelledby":l,children:[r(He,{onClick:h,component:Re,to:`/admin/groups/${t}/edit`,children:[e(Et,{children:e(tt,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Edit group"})})]}),r(He,{onClick:()=>{n(),h()},children:[e(Et,{children:e(or,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Edit group users"})})]}),r(He,{onClick:()=>{o(),h()},children:[e(Et,{children:e(De,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Delete group"})})]})]})})]})},qi=f(Re)(({theme:t})=>({textDecoration:"none",color:t.palette.text.primary})),Wi=f("aside")(({theme:t})=>({padding:t.spacing(2.5),height:"100%",border:`1px solid ${t.palette.divider}`,borderRadius:t.shape.borderRadiusLarge,boxShadow:t.boxShadows.card,display:"flex",flexDirection:"column",[t.breakpoints.up("md")]:{padding:t.spacing(4)},"&:hover":{transition:"background-color 0.2s ease-in-out",backgroundColor:t.palette.neutral.light}})),ao=f("div")(()=>({display:"flex",alignItems:"center",justifyContent:"space-between"})),_i=f(ao)(()=>({alignItems:"flex-start"})),Vi=f(ao)(()=>({marginTop:"auto"})),Yi=f("h2")(({theme:t})=>({fontSize:t.fontSizes.mainHeader,fontWeight:t.fontWeight.medium})),Ji=f("div")(({theme:t})=>({display:"flex",alignItems:"center",color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody})),Ki=f("p")(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(1),marginBottom:t.spacing(4)})),Zi=f("span")(({theme:t})=>({color:t.palette.text.secondary,marginLeft:t.spacing(1)})),Xi=f("div")(({theme:t})=>({maxWidth:"50%",display:"flex",justifyContent:"flex-end",gap:t.spacing(.5),flexWrap:"wrap"})),Qi=({group:t,onEditUsers:n,onRemoveGroup:o})=>{var i;const a=ae();return e(F,{children:e(qi,{to:`/admin/groups/${t.id}`,children:r(Wi,{children:[r(_i,{children:[e(Yi,{children:t.name}),e(Ji,{children:e(Hi,{groupId:t.id,onEditUsers:()=>n(t),onRemove:()=>o(t)})})]}),e(Ki,{children:t.description}),r(Vi,{children:[e(k,{condition:((i=t.users)==null?void 0:i.length)>0,show:e(Fi,{users:t.users}),elseShow:e(Zi,{children:"This group has no users."})}),e(Xi,{children:e(k,{condition:t.projects.length>0,show:t.projects.map(s=>e(Pe,{title:"View project",arrow:!0,placement:"bottom-end",describeChild:!0,children:e(Ut,{onClick:d=>{d.preventDefault(),a(`/projects/${s}/settings/access`)},color:"secondary",icon:e(ea,{}),children:s})},s)),elseShow:e(Pe,{title:"This group is not used in any project",arrow:!0,describeChild:!0,children:e(Ut,{children:"Not used"})})})})]})]})},t.id)})},es=()=>{const t=f("div")(({theme:o})=>({display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",margin:o.spacing(6),marginLeft:"auto",marginRight:"auto"})),n=f(I)(({theme:o})=>({fontSize:o.fontSizes.bodySize,marginBottom:o.spacing(2.5)}));return r(t,{children:[e(n,{children:"No groups available. Get started by adding a new group."}),e(M,{to:"/admin/groups/create-group",component:Re,variant:"outlined",color:"secondary",children:"Create your first group"})]})},ts=(t,n)=>{var i,s,d,h,l,c;const o=n.toLowerCase(),a={names:(i=t.users)==null?void 0:i.map(u=>{var m;return((m=u.name)==null?void 0:m.toLowerCase())||""}),usernames:(s=t.users)==null?void 0:s.map(u=>{var m;return((m=u.username)==null?void 0:m.toLowerCase())||""}),emails:(d=t.users)==null?void 0:d.map(u=>{var m;return((m=u.email)==null?void 0:m.toLowerCase())||""})};return t.name.toLowerCase().includes(o)||t.description.toLowerCase().includes(o)||((h=a.names)==null?void 0:h.some(u=>u.includes(o)))||((l=a.usernames)==null?void 0:l.some(u=>u.includes(o)))||((c=a.emails)==null?void 0:c.some(u=>u.includes(o)))},ns=()=>{const t=ae(),[n,o]=p.useState(!1),[a,i]=p.useState(!1),[s,d]=p.useState(void 0),{groups:h=[],loading:l}=_e(),[c,u]=$n(),[m,b]=p.useState(c.get("search")||""),v=ve(Ge.breakpoints.down("md"));p.useEffect(()=>{const S={};m&&(S.search=m),u(S,{replace:!0})},[m,u]);const g=p.useMemo(()=>{const S=h.sort((x,P)=>x.name.localeCompare(P.name));return m?S.filter(x=>ts(x,m)):S},[h,m]),C=S=>{d(S),o(!0)},w=S=>{d(S),i(!0)};return r(Q,{isLoading:l,header:e(te,{title:`Groups (${g.length})`,actions:r(F,{children:[e(k,{condition:!v,show:r(F,{children:[e(ye,{initialValue:m,onChange:b}),e(te.Divider,{})]})}),e(jn,{onClick:()=>t("/admin/groups/create-group"),maxWidth:"700px",Icon:zt,permission:z,"data-testid":ta,children:"New group"})]}),children:e(k,{condition:v,show:e(ye,{initialValue:m,onChange:b})})}),children:[e(Ye,{value:m,children:e(y,{container:!0,spacing:2,children:g.map(S=>e(y,{item:!0,xs:12,md:6,children:e(Qi,{group:S,onEditUsers:C,onRemoveGroup:w})},S.id))})}),e(k,{condition:!l&&g.length===0,show:e(k,{condition:(m==null?void 0:m.length)>0,show:r(ge,{children:["No groups found matching “",m,"”"]}),elseShow:e(es,{})})}),e(k,{condition:Boolean(s),show:e(oo,{open:n,setOpen:o,group:s})}),e(k,{condition:Boolean(s),show:e(no,{open:a,setOpen:i,group:s})})]})},os=()=>e("div",{children:e(ns,{})}),as=()=>{const{data:t,error:n,mutate:o}=Te(oe("api/admin/instance-admin/statistics"),rs);return p.useMemo(()=>({stats:t,loading:!n&&!t,refetchGroup:()=>o(),error:n}),[t,n,o])},rs=t=>fetch(t).then(Ce("Instance Stats")).then(n=>n.json()),is=()=>{const{stats:t}=as();let n,o;t!=null&&t.versionEnterprise?(n="Unleash Enterprise version",o=t.versionEnterprise):(n="Unleash OSS version",o=t==null?void 0:t.versionOSS);const a=[{title:"Instance Id",value:t==null?void 0:t.instanceId},{title:n,value:o},{title:"Users",value:t==null?void 0:t.users},{title:"Feature toggles",value:t==null?void 0:t.featureToggles},{title:"Projects",value:t==null?void 0:t.projects},{title:"Environments",value:t==null?void 0:t.environments},{title:"Roles",value:t==null?void 0:t.roles},{title:"Groups",value:t==null?void 0:t.groups},{title:"Context fields",value:t==null?void 0:t.contextFields},{title:"Strategies",value:t==null?void 0:t.strategies},{title:"Feature exports",value:t==null?void 0:t.featureExports},{title:"Feature imports",value:t==null?void 0:t.featureImports}];return t!=null&&t.versionEnterprise&&a.push({title:"SAML enabled",value:t!=null&&t.SAMLenabled?"Yes":"No"},{title:"OIDC enabled",value:t!=null&&t.OIDCenabled?"Yes":"No"}),e(Q,{header:e(te,{title:"Instance Statistics"}),children:r(Wa,{sx:{display:"grid",gap:4},children:[r(Dn,{"aria-label":"Instance statistics",children:[e(In,{children:r(We,{children:[e(ne,{children:"Field"}),e(ne,{align:"right",children:"Value"})]})}),e(pt,{children:a.map(i=>r(We,{children:[e(ne,{component:"th",scope:"row",children:i.title}),e(ne,{align:"right",children:i.value})]},i.title))})]}),e("span",{style:{textAlign:"center"},children:e(M,{startIcon:e(na,{}),"aria-label":"Download instance statistics",color:"primary",variant:"contained",target:"_blank",href:oe("/api/admin/instance-admin/statistics/csv"),children:"Download"})})]})})},ss=()=>e("div",{children:e(is,{})}),ls=()=>e(_,{severity:"warning",children:r("p",{children:[e("b",{children:"Heads up!"})," If you enable maintenance mode, edit access in the entire system will be disabled for all the users (admins, editors, custom roles, etc). During this time nobody will be able to do changes or to make new configurations."]})}),cs=()=>{const{data:t,error:n,mutate:o}=Te(oe("api/admin/maintenance"),ds);return p.useMemo(()=>({enabled:Boolean(t==null?void 0:t.enabled),loading:!n&&!t,refetchMaintenance:o,error:n}),[t,n,o])},ds=t=>fetch(t).then(Ce("Maintenance")).then(n=>n.json()),us=()=>{const{makeRequest:t,createRequest:n,errors:o,loading:a}=Ie({propagateErrors:!0});return{toggleMaintenance:async s=>{const h=n("api/admin/maintenance",{method:"POST",body:JSON.stringify(s)});try{await t(h.caller,h.id)}catch(l){throw l}},errors:o,loading:a}},hs=f("div")(({theme:t})=>({display:"flex",flexDirection:"column",padding:t.spacing(3),border:`1px solid ${t.palette.divider}`,borderRadius:t.shape.borderRadiusLarge})),ps=f(j)(({theme:t})=>({display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"center"})),ms=f(j)(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(2)})),gs=f(I)(({theme:t})=>({fontSize:t.fontSizes.smallBody})),fs=()=>{const{enabled:t,refetchMaintenance:n}=cs(),{toggleMaintenance:o}=us(),{trackEvent:a}=Wt(),{setToastData:i}=K();return r(hs,{children:[r(ps,{children:[e("b",{children:"Maintenance Mode"}),e(ie,{sx:{margin:0},control:e(be,{onChange:async()=>{i({type:"success",title:`Maintenance mode has been successfully ${t?"disabled":"enabled"}`}),a("maintenance",{props:{eventType:`maintenance ${t?"de":""}activated`}}),await o({enabled:!t}),n()},value:t,name:"enabled",checked:t}),label:e(gs,{children:t?"Enabled":"Disabled"})})]}),e(ms,{children:"Maintenance Mode is useful when you want to freeze your system so nobody can do any changes during this time. When enabled it will show a banner at the top of the applications and only an admin can enable it or disable it."})]})},ys=()=>{const{hasAccess:t}=p.useContext(he);return e("div",{children:e(k,{condition:t(z),show:e(Ss,{}),elseShow:e($e,{})})})},bs=f(j)(({theme:t})=>({display:"grid",gap:t.spacing(4)})),Ss=()=>{const{loading:t}=Y();return t?null:e(Q,{header:e(te,{title:"Maintenance"}),children:r(bs,{children:[e(ls,{}),e(fs,{})]})})},vs=t=>{const n={display:"flex",justifyContent:"center",alignItems:"center",width:"100%",textDecoration:"none",color:"inherit",padding:t.theme.spacing(1.5,3)},o={fontWeight:"bold",borderRadius:"3px",padding:t.theme.spacing(1.5,3)};return t.isActive?{...n,...o}:n},ue=({to:t,children:n})=>{const o=Ht();return e(oa,{to:t,style:({isActive:a})=>vs({isActive:a,theme:o}),children:n})},Cs=f(Nn)(({theme:t})=>({marginBottom:"1rem",borderRadius:"12.5px",boxShadow:"none",padding:"0 2rem"}));function ws(){const{uiConfig:t,isEnterprise:n}=Y(),{pathname:o}=zn(),{isBilling:a}=jt(),{flags:i,networkViewEnabled:s}=t,d=o.split("/")[2];return e(Cs,{children:r(Mn,{value:d,variant:"scrollable",scrollButtons:"auto",allowScrollButtonsMobile:!0,children:[e(de,{value:"users",label:e(ue,{to:"/admin/users",children:e("span",{children:"Users"})})}),n()&&e(de,{value:"service-accounts",label:e(ue,{to:"/admin/service-accounts",children:e("span",{children:"Service accounts"})})}),i.UG&&e(de,{value:"groups",label:e(ue,{to:"/admin/groups",children:e("span",{children:"Groups"})})}),i.RE&&e(de,{value:"roles",label:e(ue,{to:"/admin/roles",children:e("span",{children:"Project roles"})})}),e(de,{value:"api",label:e(ue,{to:"/admin/api",children:"API access"})}),t.flags.embedProxyFrontend&&e(de,{value:"cors",label:e(ue,{to:"/admin/cors",children:"CORS origins"})}),e(de,{value:"auth",label:e(ue,{to:"/admin/auth",children:"Single sign-on"})}),e(de,{value:"instance",label:e(ue,{to:"/admin/instance",children:"Instance stats"})}),s&&e(de,{value:"network",label:e(ue,{to:"/admin/network",children:"Network"})}),e(de,{value:"maintenance",label:e(ue,{to:"/admin/maintenance",children:"Maintenance"})}),a&&e(de,{value:"billing",label:e(ue,{to:"/admin/billing",children:"Billing"})})]})})}const xs=p.lazy(()=>import("./NetworkOverview-af010e9a.js")),ks=p.lazy(()=>import("./NetworkTraffic-55e0e1d9.js")),Ts=f(Q)(()=>({".page-header":{padding:0}})),As=[{label:"Overview",path:"/admin/network"},{label:"Traffic",path:"/admin/network/traffic"}],Es=()=>{const{pathname:t}=zn();return e("div",{children:e(Ts,{headerClass:"page-header",header:e(Mn,{value:t,indicatorColor:"primary",textColor:"primary",variant:"scrollable",allowScrollButtonsMobile:!0,children:As.map(({label:n,path:o})=>e(de,{value:o,label:e(ue,{to:o,children:e("span",{children:n})})},n))}),children:r(Hn,{children:[e(J,{path:"traffic",element:e(ks,{})}),e(J,{path:"*",element:e(xs,{})})]})})})},St=()=>{const{makeRequest:t,createRequest:n,errors:o,loading:a}=Ie({propagateErrors:!0});return{createRole:async l=>{const u=n("api/admin/roles",{method:"POST",body:JSON.stringify(l)});try{return await t(u.caller,u.id)}catch(m){throw m}},deleteRole:async l=>{const c=`api/admin/roles/${l}`,u=n(c,{method:"DELETE"});try{return await t(u.caller,u.id)}catch(m){throw m}},editRole:async(l,c)=>{const u=`api/admin/roles/${l}`,m=n(u,{method:"PUT",body:JSON.stringify(c)});try{return await t(m.caller,m.id)}catch(b){throw b}},validateRole:async l=>{const u=n("api/admin/roles/validate",{method:"POST",body:JSON.stringify(l)});try{return await t(u.caller,u.id)}catch(m){throw m}},errors:o,loading:a}},Rs=f(j)(({theme:t})=>({display:"flex",alignItems:"center",[t.breakpoints.down(500)]:{flexDirection:"column",alignItems:"flex-start"}})),Ps=f(aa)(({theme:t})=>({fontWeight:t.typography.fontWeightBold,marginRight:t.spacing(1)})),un=({title:t,permissions:n,checkedPermissions:o,Icon:a,isInitiallyExpanded:i,context:s,onPermissionChange:d,onCheckAll:h,getRoleKey:l})=>{const[c,u]=p.useState(i),m=p.useMemo(()=>(n==null?void 0:n.reduce((g,C)=>(g[l(C)]=!0,g),{}))||{},[n]),b=p.useMemo(()=>Object.keys(o).filter(g=>m[g]).length||0,[o,m]),v=p.useMemo(()=>b===(n==null?void 0:n.length),[b,n]);return e(j,{sx:{my:2,pb:1},children:r(ra,{expanded:c,onChange:()=>u(!c),sx:{boxShadow:"none",px:3,py:1,border:g=>`1px solid ${g.palette.divider}`,borderRadius:g=>`${g.shape.borderRadiusLarge}px`},children:[e(ia,{expandIcon:e(Fe,{children:e(_a,{titleAccess:"Toggle"})}),sx:{boxShadow:"none",padding:"0"},children:r(Rs,{children:[a,e(Ps,{text:t,maxWidth:"120",maxLength:25})," ",r(I,{variant:"body2",color:"text.secondary",children:["(",b," / ",n==null?void 0:n.length," ","permissions)"]})]})}),r(sa,{sx:{px:0,py:1,flexWrap:"wrap"},children:[e(Gt,{sx:{mb:1}}),r(M,{variant:"text",size:"small",onClick:h,sx:{fontWeight:g=>g.typography.fontWeightRegular},children:[v?"Unselect ":"Select ","all ",s," permissions"]}),e(j,{children:n==null?void 0:n.map(g=>e(ie,{sx:{minWidth:{sm:"300px",xs:"auto"}},control:e(Ln,{checked:!!o[l(g)],onChange:()=>d(g),color:"primary"}),label:g.displayName},l(g)))})]})]})})},ro=({children:t,roleName:n,roleDesc:o,checkedPermissions:a,errors:i,permissions:s,onSubmit:d,onCancel:h,setRoleName:l,setRoleDesc:c,handlePermissionChange:u,checkAllProjectPermissions:m,checkAllEnvironmentPermissions:b,validateNameUniqueness:v,clearErrors:g,getRoleKey:C})=>{const{project:w,environments:S}=s;return r("form",{onSubmit:d,children:[r(j,{sx:{maxWidth:"400px"},children:[e(I,{sx:{mb:1},children:"What is your role name?"}),e(Ve,{label:"Role name",value:n,onChange:x=>l(x.target.value),error:Boolean(i.name),errorText:i.name,onFocus:()=>g(),onBlur:v,autoFocus:!0,sx:{width:"100%",marginBottom:"1rem"}}),e(I,{sx:{mb:1},children:"What is this role for?"}),e(X,{label:"Role description",variant:"outlined",multiline:!0,maxRows:4,value:o,onChange:x=>c(x.target.value),sx:{width:"100%",marginBottom:"1rem"}})]}),e("div",{children:e(k,{condition:Boolean(i.permissions),show:e(I,{variant:"body2",color:"error.main",children:"You must select at least one permission for a role."})})}),e(un,{isInitiallyExpanded:!0,title:"Project permissions",Icon:e(ir,{color:"disabled",sx:{mr:1}}),permissions:w,checkedPermissions:a,onPermissionChange:x=>u(x),onCheckAll:m,getRoleKey:C,context:"project"}),e("div",{children:S.map(x=>e(un,{title:x.name,Icon:e(la,{sx:{mr:1},color:"disabled"}),permissions:x.permissions,checkedPermissions:a,onPermissionChange:P=>u(P),onCheckAll:()=>b(x.name),getRoleKey:C,context:"environment"},x.name))}),r(j,{sx:{marginTop:"auto",display:"flex",justifyContent:"flex-end"},children:[t,e(M,{onClick:h,sx:{marginLeft:2},children:"Cancel"})]})]})},pe=t=>t.environment?`${t.id}-${t.environment}`:`${t.id}`,io=(t="",n="",o=[])=>{const{permissions:a}=ca({revalidateIfStale:!1,revalidateOnReconnect:!1,revalidateOnFocus:!1}),[i,s]=p.useState(t),[d,h]=p.useState(n),[l,c]=p.useState({});p.useEffect(()=>{o.length>0&&c(o==null?void 0:o.reduce((T,R)=>(T[pe(R)]=R,T),{}))},[o==null?void 0:o.length]);const[u,m]=p.useState({}),{validateRole:b}=St();p.useEffect(()=>{s(t)},[t]),p.useEffect(()=>{h(n)},[n]);const v=T=>{let R=Pt(l);R[pe(T)]?delete R[pe(T)]:R[pe(T)]={...T},c(R)},g=()=>{const{project:T}=a;let R=Pt(l);T.every(A=>R[pe(A)])?T.forEach(A=>{delete R[pe(A)]}):T.forEach(A=>{R[pe(A)]={...A}}),c(R)},C=T=>{const{environments:R}=a,U=Pt(l),A=R.find(B=>B.name===T);if(!A)return;A.permissions.every(B=>U[pe(B)])?A.permissions.forEach(B=>{delete U[pe(B)]}):A.permissions.forEach(B=>{U[pe(B)]={...B}}),c(U)},w=()=>({name:i,description:d,permissions:Object.values(l)});return{roleName:i,roleDesc:d,errors:u,checkedPermissions:l,permissions:a,setRoleName:s,setRoleDesc:h,handlePermissionChange:v,onToggleAllProjectPermissions:g,onToggleAllEnvironmentPermissions:C,getProjectRolePayload:w,validatePermissions:()=>Object.keys(l).length===0?(m(T=>({...T,permissions:"You must include at least one permission."})),!1):!0,validateName:()=>i.length===0?(m(T=>({...T,name:"Name can not be empty."})),!1):!0,clearErrors:()=>{m({})},validateNameUniqueness:async()=>{const T=w();try{await b(T)}catch(R){m(U=>({...U,name:V(R)}))}},getRoleKey:pe}},Ds=()=>{const{setToastData:t,setToastApiError:n}=K(),{uiConfig:o}=Y(),a=ae(),{roleName:i,roleDesc:s,permissions:d,checkedPermissions:h,errors:l,setRoleName:c,setRoleDesc:u,handlePermissionChange:m,onToggleAllProjectPermissions:b,onToggleAllEnvironmentPermissions:v,getProjectRolePayload:g,validatePermissions:C,validateName:w,validateNameUniqueness:S,clearErrors:x,getRoleKey:P}=io(),{createRole:L,loading:T}=St();return e(we,{loading:T,title:"Create project role",description:`A project role can be
|
|
15
|
+
--data-raw '${JSON.stringify(b(),void 0,2)}'`,children:r(Ai,{onSubmit:async C=>{C.preventDefault();try{await s(o.id,b()),a(),i(),n(!1),h({title:"Group users saved successfully",type:"success"})}catch(w){l(V(w))}},children:[r("div",{children:[e(Ei,{children:"Edit users in this group"}),e(Qn,{users:u,setUsers:m}),e(eo,{users:u,setUsers:m})]}),e(Ri,{children:r(Di,{children:[e(M,{type:"submit",variant:"contained",color:"primary","data-testid":On,children:"Save"}),e(Pi,{onClick:()=>{n(!1)},children:"Cancel"})]})})]})})})},Ii=({open:t,setOpen:n,user:o,group:a})=>{const{refetchGroup:i}=ft(a.id),{updateGroup:s}=nt(),{setToastData:d,setToastApiError:h}=K(),l=async()=>{try{const u={...a,users:a.users.filter(({id:m})=>m!==(o==null?void 0:o.id)).map(({id:m})=>({user:{id:m}}))};await s(a.id,u),i(),n(!1),d({title:"User removed from group successfully",type:"success"})}catch(u){h(V(u))}},c=(o==null?void 0:o.name)||(o==null?void 0:o.username)||(o==null?void 0:o.email);return e(se,{open:t&&Boolean(o),primaryButtonText:"Remove user",secondaryButtonText:"Cancel",onClick:l,onClose:()=>{n(!1)},title:"Remove user from group?",children:r(I,{children:["Do you really want to remove ",e("strong",{children:c})," from"," ",e("strong",{children:a.name}),"? ",e("strong",{children:c})," will lose all access rights granted by this group."]})})},Ui=Array(15).fill({name:"Name of the user",username:"Username of the user"}),Bi={id:"joinedAt"},{value:cn,setValue:Li}=Yo("Group:v1",Bi),Oi=()=>{const t=Number(mt("groupId")),n=Ht(),o=ve(n.breakpoints.down("md")),{group:a,loading:i}=ft(t),[s,d]=p.useState(!1),[h,l]=p.useState(!1),[c,u]=p.useState(!1),[m,b]=p.useState(),v=p.useMemo(()=>[{Header:"Avatar",accessor:"imageUrl",Cell:({row:{original:D}})=>e(Se,{children:e(ze,{user:D})}),maxWidth:85,disableSortBy:!0},{id:"name",Header:"Name",accessor:D=>D.name||"",Cell:xe,minWidth:100,searchable:!0},{id:"username",Header:"Username",accessor:D=>D.username||D.email,Cell:xe,minWidth:100,searchable:!0},{Header:"Joined",accessor:"joinedAt",Cell:Ne,sortType:"date",maxWidth:150},{id:"createdBy",Header:"Added by",accessor:"createdBy",Cell:xe,minWidth:90,searchable:!0},{Header:"Last login",accessor:D=>D.seenAt||"",Cell:({row:{original:D}})=>e(gt,{value:D.seenAt,emptyText:"Never",title:O=>`Last login: ${O}`}),sortType:"date",maxWidth:150},{Header:"Actions",id:"Actions",align:"center",Cell:({row:{original:D}})=>e(ht,{children:e(Pe,{title:"Remove user from group",arrow:!0,describeChild:!0,children:e("span",{children:e(Fe,{"data-testid":`${Jo}-${D.id}`,onClick:()=>{b(D),u(!0)},children:e(De,{})})})})}),maxWidth:100,disableSortBy:!0}],[b,u]),[g,C]=$n(),[w]=p.useState(()=>({sortBy:[{id:g.get("sort")||cn.id,desc:g.has("order")?g.get("order")==="desc":cn.desc}],hiddenColumns:["description"],globalFilter:g.get("search")||""})),[S,x]=p.useState(w.globalFilter),{data:P,getSearchText:L,getSearchContext:T}=qt(v,S,(a==null?void 0:a.users)??[]),R=p.useMemo(()=>(P==null?void 0:P.length)===0&&i?Ui:P,[P,i]),{headerGroups:U,rows:A,prepareRow:H,state:{sortBy:B}}=Z.useTable({columns:v,data:R,initialState:w,sortTypes:je,autoResetSortBy:!1,disableSortRemove:!0,disableMultiSort:!0},Z.useSortBy,Z.useFlexLayout);return p.useEffect(()=>{const D={};D.sort=B[0].id,B[0].desc&&(D.order="desc"),S&&(D.search=S),C(D,{replace:!0}),Li({id:B[0].id,desc:B[0].desc||!1})},[B,S,C]),e(k,{condition:Boolean(a),show:r(F,{children:[e(Ti,{title:a==null?void 0:a.name,description:a==null?void 0:a.description,actions:r(F,{children:[e(ke,{"data-testid":Ko,to:`/admin/groups/${t}/edit`,component:Re,"data-loading":!0,permission:z,tooltipProps:{title:"Edit group"},children:e(tt,{})}),e(ke,{"data-testid":Zo,"data-loading":!0,onClick:()=>d(!0),permission:z,tooltipProps:{title:"Delete group"},children:e(De,{})})]})}),r(Q,{isLoading:i,header:e(te,{secondary:!0,title:`Users (${A.length<R.length?`${A.length} of ${R.length}`:R.length})`,actions:r(F,{children:[e(k,{condition:!o,show:r(F,{children:[e(ye,{initialValue:S,onChange:x,hasFilters:!0,getSearchContext:T}),e(te.Divider,{})]})}),e(jn,{"data-testid":Xo,onClick:()=>{l(!0)},maxWidth:"700px",Icon:zt,permission:z,children:"Edit users"})]}),children:e(k,{condition:o,show:e(ye,{initialValue:S,onChange:x,hasFilters:!0,getSearchContext:T})})}),children:[e(Ye,{value:L(S),children:e(et,{rows:A,headerGroups:U,prepareRow:H})}),e(k,{condition:A.length===0,show:e(k,{condition:(S==null?void 0:S.length)>0,show:r(ge,{children:["No users found matching “",S,"” in this group."]}),elseShow:e(ge,{children:"This group is empty. Get started by adding a user to the group."})})}),e(no,{open:s,setOpen:d,group:a}),e(oo,{open:h,setOpen:l,group:a}),e(Ii,{open:c,setOpen:u,user:m,group:a})]})]})})},Ni=f(Fn)(({theme:t})=>({pointerEvents:"none",".MuiPaper-root":{padding:t.spacing(2)}})),Gi=f("div")(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(1)})),$i=({user:t,open:n,anchorEl:o,onPopoverClose:a})=>r(Ni,{open:n,anchorEl:o,onClose:a,anchorOrigin:{vertical:"bottom",horizontal:"left"},transformOrigin:{vertical:"top",horizontal:"left"},children:[e(Gi,{children:(t==null?void 0:t.name)||(t==null?void 0:t.username)}),e("div",{children:t==null?void 0:t.email})]}),ji=f("div")(({theme:t})=>({display:"inline-flex",alignItems:"center",flexWrap:"wrap",marginLeft:t.spacing(1)})),dn=f(ze)(({theme:t})=>({outline:`${t.spacing(.25)} solid ${t.palette.background.paper}`,marginLeft:t.spacing(-1),"&:hover":{outlineColor:t.palette.primary.main}})),Fi=({users:t})=>{const n=p.useMemo(()=>t.sort((c,u)=>(u==null?void 0:u.joinedAt.getTime())-(c==null?void 0:c.joinedAt.getTime())).slice(0,9),[t]),[o,a]=p.useState(null),[i,s]=p.useState(),d=c=>{a(c.currentTarget)},h=()=>{a(null)},l=Boolean(o);return r(ji,{children:[n.map(c=>e(dn,{user:c,onMouseEnter:u=>{d(u),s(c)},onMouseLeave:h},c.id)),e(k,{condition:t.length>9,show:r(dn,{children:["+",t.length-n.length]})}),e($i,{open:l,user:i,anchorEl:o,onPopoverClose:h})]})},zi=f("div")(({theme:t})=>({display:"flex",justifyContent:"center",transform:"translate3d(8px, -6px, 0)"})),Mi=f(Fn)(({theme:t})=>({borderRadius:t.shape.borderRadiusLarge,padding:t.spacing(1,1.5)})),Hi=({groupId:t,onEditUsers:n,onRemove:o})=>{const[a,i]=p.useState(null),s=Boolean(a),d=u=>{i(u.currentTarget)},h=()=>{i(null)},l=`feature-${t}-actions`,c=`${l}-menu`;return r(zi,{onClick:u=>{u.preventDefault(),u.stopPropagation()},children:[e(Pe,{title:"Group actions",arrow:!0,describeChild:!0,children:e(Fe,{id:l,"aria-controls":s?c:void 0,"aria-haspopup":"true","aria-expanded":s?"true":void 0,onClick:d,type:"button",children:e(ar,{})})}),e(Mi,{id:c,anchorEl:a,open:s,onClose:h,transformOrigin:{horizontal:"right",vertical:"top"},anchorOrigin:{horizontal:"right",vertical:"bottom"},disableScrollLock:!0,children:r(Qo,{"aria-labelledby":l,children:[r(He,{onClick:h,component:Re,to:`/admin/groups/${t}/edit`,children:[e(Et,{children:e(tt,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Edit group"})})]}),r(He,{onClick:()=>{n(),h()},children:[e(Et,{children:e(or,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Edit group users"})})]}),r(He,{onClick:()=>{o(),h()},children:[e(Et,{children:e(De,{})}),e(Rt,{children:e(I,{variant:"body2",children:"Delete group"})})]})]})})]})},qi=f(Re)(({theme:t})=>({textDecoration:"none",color:t.palette.text.primary})),Wi=f("aside")(({theme:t})=>({padding:t.spacing(2.5),height:"100%",border:`1px solid ${t.palette.divider}`,borderRadius:t.shape.borderRadiusLarge,boxShadow:t.boxShadows.card,display:"flex",flexDirection:"column",[t.breakpoints.up("md")]:{padding:t.spacing(4)},"&:hover":{transition:"background-color 0.2s ease-in-out",backgroundColor:t.palette.neutral.light}})),ao=f("div")(()=>({display:"flex",alignItems:"center",justifyContent:"space-between"})),_i=f(ao)(()=>({alignItems:"flex-start"})),Vi=f(ao)(()=>({marginTop:"auto"})),Yi=f("h2")(({theme:t})=>({fontSize:t.fontSizes.mainHeader,fontWeight:t.fontWeight.medium})),Ji=f("div")(({theme:t})=>({display:"flex",alignItems:"center",color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody})),Ki=f("p")(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(1),marginBottom:t.spacing(4)})),Zi=f("span")(({theme:t})=>({color:t.palette.text.secondary,marginLeft:t.spacing(1)})),Xi=f("div")(({theme:t})=>({maxWidth:"50%",display:"flex",justifyContent:"flex-end",gap:t.spacing(.5),flexWrap:"wrap"})),Qi=({group:t,onEditUsers:n,onRemoveGroup:o})=>{var i;const a=ae();return e(F,{children:e(qi,{to:`/admin/groups/${t.id}`,children:r(Wi,{children:[r(_i,{children:[e(Yi,{children:t.name}),e(Ji,{children:e(Hi,{groupId:t.id,onEditUsers:()=>n(t),onRemove:()=>o(t)})})]}),e(Ki,{children:t.description}),r(Vi,{children:[e(k,{condition:((i=t.users)==null?void 0:i.length)>0,show:e(Fi,{users:t.users}),elseShow:e(Zi,{children:"This group has no users."})}),e(Xi,{children:e(k,{condition:t.projects.length>0,show:t.projects.map(s=>e(Pe,{title:"View project",arrow:!0,placement:"bottom-end",describeChild:!0,children:e(Ut,{onClick:d=>{d.preventDefault(),a(`/projects/${s}/settings/access`)},color:"secondary",icon:e(ea,{}),children:s})},s)),elseShow:e(Pe,{title:"This group is not used in any project",arrow:!0,describeChild:!0,children:e(Ut,{children:"Not used"})})})})]})]})},t.id)})},es=()=>{const t=f("div")(({theme:o})=>({display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",margin:o.spacing(6),marginLeft:"auto",marginRight:"auto"})),n=f(I)(({theme:o})=>({fontSize:o.fontSizes.bodySize,marginBottom:o.spacing(2.5)}));return r(t,{children:[e(n,{children:"No groups available. Get started by adding a new group."}),e(M,{to:"/admin/groups/create-group",component:Re,variant:"outlined",color:"secondary",children:"Create your first group"})]})},ts=(t,n)=>{var i,s,d,h,l,c;const o=n.toLowerCase(),a={names:(i=t.users)==null?void 0:i.map(u=>{var m;return((m=u.name)==null?void 0:m.toLowerCase())||""}),usernames:(s=t.users)==null?void 0:s.map(u=>{var m;return((m=u.username)==null?void 0:m.toLowerCase())||""}),emails:(d=t.users)==null?void 0:d.map(u=>{var m;return((m=u.email)==null?void 0:m.toLowerCase())||""})};return t.name.toLowerCase().includes(o)||t.description.toLowerCase().includes(o)||((h=a.names)==null?void 0:h.some(u=>u.includes(o)))||((l=a.usernames)==null?void 0:l.some(u=>u.includes(o)))||((c=a.emails)==null?void 0:c.some(u=>u.includes(o)))},ns=()=>{const t=ae(),[n,o]=p.useState(!1),[a,i]=p.useState(!1),[s,d]=p.useState(void 0),{groups:h=[],loading:l}=_e(),[c,u]=$n(),[m,b]=p.useState(c.get("search")||""),v=ve(Ge.breakpoints.down("md"));p.useEffect(()=>{const S={};m&&(S.search=m),u(S,{replace:!0})},[m,u]);const g=p.useMemo(()=>{const S=h.sort((x,P)=>x.name.localeCompare(P.name));return m?S.filter(x=>ts(x,m)):S},[h,m]),C=S=>{d(S),o(!0)},w=S=>{d(S),i(!0)};return r(Q,{isLoading:l,header:e(te,{title:`Groups (${g.length})`,actions:r(F,{children:[e(k,{condition:!v,show:r(F,{children:[e(ye,{initialValue:m,onChange:b}),e(te.Divider,{})]})}),e(jn,{onClick:()=>t("/admin/groups/create-group"),maxWidth:"700px",Icon:zt,permission:z,"data-testid":ta,children:"New group"})]}),children:e(k,{condition:v,show:e(ye,{initialValue:m,onChange:b})})}),children:[e(Ye,{value:m,children:e(y,{container:!0,spacing:2,children:g.map(S=>e(y,{item:!0,xs:12,md:6,children:e(Qi,{group:S,onEditUsers:C,onRemoveGroup:w})},S.id))})}),e(k,{condition:!l&&g.length===0,show:e(k,{condition:(m==null?void 0:m.length)>0,show:r(ge,{children:["No groups found matching “",m,"”"]}),elseShow:e(es,{})})}),e(k,{condition:Boolean(s),show:e(oo,{open:n,setOpen:o,group:s})}),e(k,{condition:Boolean(s),show:e(no,{open:a,setOpen:i,group:s})})]})},os=()=>e("div",{children:e(ns,{})}),as=()=>{const{data:t,error:n,mutate:o}=Te(oe("api/admin/instance-admin/statistics"),rs);return p.useMemo(()=>({stats:t,loading:!n&&!t,refetchGroup:()=>o(),error:n}),[t,n,o])},rs=t=>fetch(t).then(Ce("Instance Stats")).then(n=>n.json()),is=()=>{const{stats:t}=as();let n,o;t!=null&&t.versionEnterprise?(n="Unleash Enterprise version",o=t.versionEnterprise):(n="Unleash OSS version",o=t==null?void 0:t.versionOSS);const a=[{title:"Instance Id",value:t==null?void 0:t.instanceId},{title:n,value:o},{title:"Users",value:t==null?void 0:t.users},{title:"Feature toggles",value:t==null?void 0:t.featureToggles},{title:"Projects",value:t==null?void 0:t.projects},{title:"Environments",value:t==null?void 0:t.environments},{title:"Roles",value:t==null?void 0:t.roles},{title:"Groups",value:t==null?void 0:t.groups},{title:"Context fields",value:t==null?void 0:t.contextFields},{title:"Strategies",value:t==null?void 0:t.strategies},{title:"Feature exports",value:t==null?void 0:t.featureExports},{title:"Feature imports",value:t==null?void 0:t.featureImports}];return t!=null&&t.versionEnterprise&&a.push({title:"SAML enabled",value:t!=null&&t.SAMLenabled?"Yes":"No"},{title:"OIDC enabled",value:t!=null&&t.OIDCenabled?"Yes":"No"}),e(Q,{header:e(te,{title:"Instance Statistics"}),children:r(Wa,{sx:{display:"grid",gap:4},children:[r(Dn,{"aria-label":"Instance statistics",children:[e(In,{children:r(We,{children:[e(ne,{children:"Field"}),e(ne,{align:"right",children:"Value"})]})}),e(pt,{children:a.map(i=>r(We,{children:[e(ne,{component:"th",scope:"row",children:i.title}),e(ne,{align:"right",children:i.value})]},i.title))})]}),e("span",{style:{textAlign:"center"},children:e(M,{startIcon:e(na,{}),"aria-label":"Download instance statistics",color:"primary",variant:"contained",target:"_blank",href:oe("/api/admin/instance-admin/statistics/csv"),children:"Download"})})]})})},ss=()=>e("div",{children:e(is,{})}),ls=()=>e(_,{severity:"warning",children:r("p",{children:[e("b",{children:"Heads up!"})," If you enable maintenance mode, edit access in the entire system will be disabled for all the users (admins, editors, custom roles, etc). During this time nobody will be able to do changes or to make new configurations."]})}),cs=()=>{const{data:t,error:n,mutate:o}=Te(oe("api/admin/maintenance"),ds);return p.useMemo(()=>({enabled:Boolean(t==null?void 0:t.enabled),loading:!n&&!t,refetchMaintenance:o,error:n}),[t,n,o])},ds=t=>fetch(t).then(Ce("Maintenance")).then(n=>n.json()),us=()=>{const{makeRequest:t,createRequest:n,errors:o,loading:a}=Ie({propagateErrors:!0});return{toggleMaintenance:async s=>{const h=n("api/admin/maintenance",{method:"POST",body:JSON.stringify(s)});try{await t(h.caller,h.id)}catch(l){throw l}},errors:o,loading:a}},hs=f("div")(({theme:t})=>({display:"flex",flexDirection:"column",padding:t.spacing(3),border:`1px solid ${t.palette.divider}`,borderRadius:t.shape.borderRadiusLarge})),ps=f(j)(({theme:t})=>({display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"center"})),ms=f(j)(({theme:t})=>({color:t.palette.text.secondary,fontSize:t.fontSizes.smallBody,marginTop:t.spacing(2)})),gs=f(I)(({theme:t})=>({fontSize:t.fontSizes.smallBody})),fs=()=>{const{enabled:t,refetchMaintenance:n}=cs(),{toggleMaintenance:o}=us(),{trackEvent:a}=Wt(),{setToastData:i}=K();return r(hs,{children:[r(ps,{children:[e("b",{children:"Maintenance Mode"}),e(ie,{sx:{margin:0},control:e(be,{onChange:async()=>{i({type:"success",title:`Maintenance mode has been successfully ${t?"disabled":"enabled"}`}),a("maintenance",{props:{eventType:`maintenance ${t?"de":""}activated`}}),await o({enabled:!t}),n()},value:t,name:"enabled",checked:t}),label:e(gs,{children:t?"Enabled":"Disabled"})})]}),e(ms,{children:"Maintenance Mode is useful when you want to freeze your system so nobody can do any changes during this time. When enabled it will show a banner at the top of the applications and only an admin can enable it or disable it."})]})},ys=()=>{const{hasAccess:t}=p.useContext(he);return e("div",{children:e(k,{condition:t(z),show:e(Ss,{}),elseShow:e($e,{})})})},bs=f(j)(({theme:t})=>({display:"grid",gap:t.spacing(4)})),Ss=()=>{const{loading:t}=Y();return t?null:e(Q,{header:e(te,{title:"Maintenance"}),children:r(bs,{children:[e(ls,{}),e(fs,{})]})})},vs=t=>{const n={display:"flex",justifyContent:"center",alignItems:"center",width:"100%",textDecoration:"none",color:"inherit",padding:t.theme.spacing(1.5,3)},o={fontWeight:"bold",borderRadius:"3px",padding:t.theme.spacing(1.5,3)};return t.isActive?{...n,...o}:n},ue=({to:t,children:n})=>{const o=Ht();return e(oa,{to:t,style:({isActive:a})=>vs({isActive:a,theme:o}),children:n})},Cs=f(Nn)(({theme:t})=>({marginBottom:"1rem",borderRadius:"12.5px",boxShadow:"none",padding:"0 2rem"}));function ws(){const{uiConfig:t,isEnterprise:n}=Y(),{pathname:o}=zn(),{isBilling:a}=jt(),{flags:i,networkViewEnabled:s}=t,d=o.split("/")[2];return e(Cs,{children:r(Mn,{value:d,variant:"scrollable",scrollButtons:"auto",allowScrollButtonsMobile:!0,children:[e(de,{value:"users",label:e(ue,{to:"/admin/users",children:e("span",{children:"Users"})})}),n()&&e(de,{value:"service-accounts",label:e(ue,{to:"/admin/service-accounts",children:e("span",{children:"Service accounts"})})}),i.UG&&e(de,{value:"groups",label:e(ue,{to:"/admin/groups",children:e("span",{children:"Groups"})})}),i.RE&&e(de,{value:"roles",label:e(ue,{to:"/admin/roles",children:e("span",{children:"Project roles"})})}),e(de,{value:"api",label:e(ue,{to:"/admin/api",children:"API access"})}),t.flags.embedProxyFrontend&&e(de,{value:"cors",label:e(ue,{to:"/admin/cors",children:"CORS origins"})}),e(de,{value:"auth",label:e(ue,{to:"/admin/auth",children:"Single sign-on"})}),e(de,{value:"instance",label:e(ue,{to:"/admin/instance",children:"Instance stats"})}),s&&e(de,{value:"network",label:e(ue,{to:"/admin/network",children:"Network"})}),e(de,{value:"maintenance",label:e(ue,{to:"/admin/maintenance",children:"Maintenance"})}),a&&e(de,{value:"billing",label:e(ue,{to:"/admin/billing",children:"Billing"})})]})})}const xs=p.lazy(()=>import("./NetworkOverview-ac162219.js")),ks=p.lazy(()=>import("./NetworkTraffic-972ed1cf.js")),Ts=f(Q)(()=>({".page-header":{padding:0}})),As=[{label:"Overview",path:"/admin/network"},{label:"Traffic",path:"/admin/network/traffic"}],Es=()=>{const{pathname:t}=zn();return e("div",{children:e(Ts,{headerClass:"page-header",header:e(Mn,{value:t,indicatorColor:"primary",textColor:"primary",variant:"scrollable",allowScrollButtonsMobile:!0,children:As.map(({label:n,path:o})=>e(de,{value:o,label:e(ue,{to:o,children:e("span",{children:n})})},n))}),children:r(Hn,{children:[e(J,{path:"traffic",element:e(ks,{})}),e(J,{path:"*",element:e(xs,{})})]})})})},St=()=>{const{makeRequest:t,createRequest:n,errors:o,loading:a}=Ie({propagateErrors:!0});return{createRole:async l=>{const u=n("api/admin/roles",{method:"POST",body:JSON.stringify(l)});try{return await t(u.caller,u.id)}catch(m){throw m}},deleteRole:async l=>{const c=`api/admin/roles/${l}`,u=n(c,{method:"DELETE"});try{return await t(u.caller,u.id)}catch(m){throw m}},editRole:async(l,c)=>{const u=`api/admin/roles/${l}`,m=n(u,{method:"PUT",body:JSON.stringify(c)});try{return await t(m.caller,m.id)}catch(b){throw b}},validateRole:async l=>{const u=n("api/admin/roles/validate",{method:"POST",body:JSON.stringify(l)});try{return await t(u.caller,u.id)}catch(m){throw m}},errors:o,loading:a}},Rs=f(j)(({theme:t})=>({display:"flex",alignItems:"center",[t.breakpoints.down(500)]:{flexDirection:"column",alignItems:"flex-start"}})),Ps=f(aa)(({theme:t})=>({fontWeight:t.typography.fontWeightBold,marginRight:t.spacing(1)})),un=({title:t,permissions:n,checkedPermissions:o,Icon:a,isInitiallyExpanded:i,context:s,onPermissionChange:d,onCheckAll:h,getRoleKey:l})=>{const[c,u]=p.useState(i),m=p.useMemo(()=>(n==null?void 0:n.reduce((g,C)=>(g[l(C)]=!0,g),{}))||{},[n]),b=p.useMemo(()=>Object.keys(o).filter(g=>m[g]).length||0,[o,m]),v=p.useMemo(()=>b===(n==null?void 0:n.length),[b,n]);return e(j,{sx:{my:2,pb:1},children:r(ra,{expanded:c,onChange:()=>u(!c),sx:{boxShadow:"none",px:3,py:1,border:g=>`1px solid ${g.palette.divider}`,borderRadius:g=>`${g.shape.borderRadiusLarge}px`},children:[e(ia,{expandIcon:e(Fe,{children:e(_a,{titleAccess:"Toggle"})}),sx:{boxShadow:"none",padding:"0"},children:r(Rs,{children:[a,e(Ps,{text:t,maxWidth:"120",maxLength:25})," ",r(I,{variant:"body2",color:"text.secondary",children:["(",b," / ",n==null?void 0:n.length," ","permissions)"]})]})}),r(sa,{sx:{px:0,py:1,flexWrap:"wrap"},children:[e(Gt,{sx:{mb:1}}),r(M,{variant:"text",size:"small",onClick:h,sx:{fontWeight:g=>g.typography.fontWeightRegular},children:[v?"Unselect ":"Select ","all ",s," permissions"]}),e(j,{children:n==null?void 0:n.map(g=>e(ie,{sx:{minWidth:{sm:"300px",xs:"auto"}},control:e(Ln,{checked:!!o[l(g)],onChange:()=>d(g),color:"primary"}),label:g.displayName},l(g)))})]})]})})},ro=({children:t,roleName:n,roleDesc:o,checkedPermissions:a,errors:i,permissions:s,onSubmit:d,onCancel:h,setRoleName:l,setRoleDesc:c,handlePermissionChange:u,checkAllProjectPermissions:m,checkAllEnvironmentPermissions:b,validateNameUniqueness:v,clearErrors:g,getRoleKey:C})=>{const{project:w,environments:S}=s;return r("form",{onSubmit:d,children:[r(j,{sx:{maxWidth:"400px"},children:[e(I,{sx:{mb:1},children:"What is your role name?"}),e(Ve,{label:"Role name",value:n,onChange:x=>l(x.target.value),error:Boolean(i.name),errorText:i.name,onFocus:()=>g(),onBlur:v,autoFocus:!0,sx:{width:"100%",marginBottom:"1rem"}}),e(I,{sx:{mb:1},children:"What is this role for?"}),e(X,{label:"Role description",variant:"outlined",multiline:!0,maxRows:4,value:o,onChange:x=>c(x.target.value),sx:{width:"100%",marginBottom:"1rem"}})]}),e("div",{children:e(k,{condition:Boolean(i.permissions),show:e(I,{variant:"body2",color:"error.main",children:"You must select at least one permission for a role."})})}),e(un,{isInitiallyExpanded:!0,title:"Project permissions",Icon:e(ir,{color:"disabled",sx:{mr:1}}),permissions:w,checkedPermissions:a,onPermissionChange:x=>u(x),onCheckAll:m,getRoleKey:C,context:"project"}),e("div",{children:S.map(x=>e(un,{title:x.name,Icon:e(la,{sx:{mr:1},color:"disabled"}),permissions:x.permissions,checkedPermissions:a,onPermissionChange:P=>u(P),onCheckAll:()=>b(x.name),getRoleKey:C,context:"environment"},x.name))}),r(j,{sx:{marginTop:"auto",display:"flex",justifyContent:"flex-end"},children:[t,e(M,{onClick:h,sx:{marginLeft:2},children:"Cancel"})]})]})},pe=t=>t.environment?`${t.id}-${t.environment}`:`${t.id}`,io=(t="",n="",o=[])=>{const{permissions:a}=ca({revalidateIfStale:!1,revalidateOnReconnect:!1,revalidateOnFocus:!1}),[i,s]=p.useState(t),[d,h]=p.useState(n),[l,c]=p.useState({});p.useEffect(()=>{o.length>0&&c(o==null?void 0:o.reduce((T,R)=>(T[pe(R)]=R,T),{}))},[o==null?void 0:o.length]);const[u,m]=p.useState({}),{validateRole:b}=St();p.useEffect(()=>{s(t)},[t]),p.useEffect(()=>{h(n)},[n]);const v=T=>{let R=Pt(l);R[pe(T)]?delete R[pe(T)]:R[pe(T)]={...T},c(R)},g=()=>{const{project:T}=a;let R=Pt(l);T.every(A=>R[pe(A)])?T.forEach(A=>{delete R[pe(A)]}):T.forEach(A=>{R[pe(A)]={...A}}),c(R)},C=T=>{const{environments:R}=a,U=Pt(l),A=R.find(B=>B.name===T);if(!A)return;A.permissions.every(B=>U[pe(B)])?A.permissions.forEach(B=>{delete U[pe(B)]}):A.permissions.forEach(B=>{U[pe(B)]={...B}}),c(U)},w=()=>({name:i,description:d,permissions:Object.values(l)});return{roleName:i,roleDesc:d,errors:u,checkedPermissions:l,permissions:a,setRoleName:s,setRoleDesc:h,handlePermissionChange:v,onToggleAllProjectPermissions:g,onToggleAllEnvironmentPermissions:C,getProjectRolePayload:w,validatePermissions:()=>Object.keys(l).length===0?(m(T=>({...T,permissions:"You must include at least one permission."})),!1):!0,validateName:()=>i.length===0?(m(T=>({...T,name:"Name can not be empty."})),!1):!0,clearErrors:()=>{m({})},validateNameUniqueness:async()=>{const T=w();try{await b(T)}catch(R){m(U=>({...U,name:V(R)}))}},getRoleKey:pe}},Ds=()=>{const{setToastData:t,setToastApiError:n}=K(),{uiConfig:o}=Y(),a=ae(),{roleName:i,roleDesc:s,permissions:d,checkedPermissions:h,errors:l,setRoleName:c,setRoleDesc:u,handlePermissionChange:m,onToggleAllProjectPermissions:b,onToggleAllEnvironmentPermissions:v,getProjectRolePayload:g,validatePermissions:C,validateName:w,validateNameUniqueness:S,clearErrors:x,getRoleKey:P}=io(),{createRole:L,loading:T}=St();return e(we,{loading:T,title:"Create project role",description:`A project role can be
|
|
16
16
|
customised to limit access
|
|
17
17
|
to resources within a project`,documentationLink:"https://docs.getunleash.io/reference/rbac#custom-project-roles",documentationLinkLabel:"Project roles documentation",formatApiCode:()=>`curl --location --request POST '${o.unleashUrl}/api/admin/roles' \\
|
|
18
18
|
--header 'Authorization: INSERT_API_KEY' \\
|