unleash-server 6.2.3 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/addons/datadog.d.ts.map +1 -1
- package/dist/lib/addons/datadog.js +9 -7
- package/dist/lib/addons/datadog.js.map +1 -1
- package/dist/lib/addons/feature-event-formatter-md-events.d.ts +8 -0
- package/dist/lib/addons/feature-event-formatter-md-events.d.ts.map +1 -0
- package/dist/lib/addons/feature-event-formatter-md-events.js +297 -0
- package/dist/lib/addons/feature-event-formatter-md-events.js.map +1 -0
- package/dist/lib/addons/feature-event-formatter-md.d.ts +17 -6
- package/dist/lib/addons/feature-event-formatter-md.d.ts.map +1 -1
- package/dist/lib/addons/feature-event-formatter-md.js +32 -246
- package/dist/lib/addons/feature-event-formatter-md.js.map +1 -1
- package/dist/lib/addons/feature-event-formatter-md.test.js +3 -1
- package/dist/lib/addons/feature-event-formatter-md.test.js.map +1 -1
- package/dist/lib/addons/new-relic.d.ts.map +1 -1
- package/dist/lib/addons/new-relic.js +3 -1
- package/dist/lib/addons/new-relic.js.map +1 -1
- package/dist/lib/addons/slack-app.d.ts.map +1 -1
- package/dist/lib/addons/slack-app.js +12 -7
- package/dist/lib/addons/slack-app.js.map +1 -1
- package/dist/lib/addons/slack.d.ts.map +1 -1
- package/dist/lib/addons/slack.js +14 -9
- package/dist/lib/addons/slack.js.map +1 -1
- package/dist/lib/addons/teams.d.ts.map +1 -1
- package/dist/lib/addons/teams.js +9 -7
- package/dist/lib/addons/teams.js.map +1 -1
- package/dist/lib/addons/webhook.d.ts.map +1 -1
- package/dist/lib/addons/webhook.js +3 -1
- package/dist/lib/addons/webhook.js.map +1 -1
- package/dist/lib/db/account-store.d.ts +2 -1
- package/dist/lib/db/account-store.d.ts.map +1 -1
- package/dist/lib/db/account-store.js +18 -0
- package/dist/lib/db/account-store.js.map +1 -1
- package/dist/lib/features/events/event-search-controller.d.ts +3 -1
- package/dist/lib/features/events/event-search-controller.d.ts.map +1 -1
- package/dist/lib/features/events/event-search-controller.js +21 -2
- package/dist/lib/features/events/event-search-controller.js.map +1 -1
- package/dist/lib/features/feature-toggle/feature-toggle-service.d.ts.map +1 -1
- package/dist/lib/features/feature-toggle/feature-toggle-service.js +4 -12
- package/dist/lib/features/feature-toggle/feature-toggle-service.js.map +1 -1
- package/dist/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.js +2 -11
- package/dist/lib/features/feature-toggle/tests/feature-toggle-service.e2e.test.js.map +1 -1
- package/dist/lib/features/index.d.ts +1 -0
- package/dist/lib/features/index.d.ts.map +1 -1
- package/dist/lib/features/index.js +1 -0
- package/dist/lib/features/index.js.map +1 -1
- package/dist/lib/features/metrics/client-metrics/client-metrics-store-v2.js +1 -1
- package/dist/lib/features/metrics/client-metrics/client-metrics-store-v2.js.map +1 -1
- package/dist/lib/features/onboarding/onboarding-read-model.d.ts.map +1 -1
- package/dist/lib/features/onboarding/onboarding-read-model.js +1 -0
- package/dist/lib/features/onboarding/onboarding-read-model.js.map +1 -1
- package/dist/lib/features/personal-dashboard/createPersonalDashboardService.d.ts +6 -0
- package/dist/lib/features/personal-dashboard/createPersonalDashboardService.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/createPersonalDashboardService.js +39 -0
- package/dist/lib/features/personal-dashboard/createPersonalDashboardService.js.map +1 -0
- package/dist/lib/features/personal-dashboard/fake-personal-dashboard-read-model.d.ts +8 -0
- package/dist/lib/features/personal-dashboard/fake-personal-dashboard-read-model.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/fake-personal-dashboard-read-model.js +16 -0
- package/dist/lib/features/personal-dashboard/fake-personal-dashboard-read-model.js.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.d.ts +16 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.d.ts +2 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.js +237 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.e2e.test.js.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.js +71 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-controller.js.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model-type.d.ts +27 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model-type.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model-type.js +3 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model-type.js.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model.d.ts +9 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model.js +78 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-read-model.js.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-service.d.ts +25 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-service.d.ts.map +1 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-service.js +75 -0
- package/dist/lib/features/personal-dashboard/personal-dashboard-service.js.map +1 -0
- package/dist/lib/features/playground/feature-evaluator/strategy/flexible-rollout-strategy.d.ts.map +1 -1
- package/dist/lib/features/playground/feature-evaluator/strategy/flexible-rollout-strategy.js +1 -1
- package/dist/lib/features/playground/feature-evaluator/strategy/flexible-rollout-strategy.js.map +1 -1
- package/dist/lib/features/project/fake-project-owners-read-model.d.ts +6 -3
- package/dist/lib/features/project/fake-project-owners-read-model.d.ts.map +1 -1
- package/dist/lib/features/project/fake-project-owners-read-model.js +6 -0
- package/dist/lib/features/project/fake-project-owners-read-model.js.map +1 -1
- package/dist/lib/features/project/fake-project-read-model.d.ts +2 -0
- package/dist/lib/features/project/fake-project-read-model.d.ts.map +1 -1
- package/dist/lib/features/project/fake-project-read-model.js +6 -0
- package/dist/lib/features/project/fake-project-read-model.js.map +1 -1
- package/dist/lib/features/project/project-owners-read-model.d.ts +10 -5
- package/dist/lib/features/project/project-owners-read-model.d.ts.map +1 -1
- package/dist/lib/features/project/project-owners-read-model.js +26 -10
- package/dist/lib/features/project/project-owners-read-model.js.map +1 -1
- package/dist/lib/features/project/project-owners-read-model.test.js +62 -20
- package/dist/lib/features/project/project-owners-read-model.test.js.map +1 -1
- package/dist/lib/features/project/project-owners-read-model.type.d.ts +13 -5
- package/dist/lib/features/project/project-owners-read-model.type.d.ts.map +1 -1
- package/dist/lib/features/project/project-read-model-type.d.ts +5 -4
- package/dist/lib/features/project/project-read-model-type.d.ts.map +1 -1
- package/dist/lib/features/project/project-read-model.d.ts +4 -2
- package/dist/lib/features/project/project-read-model.d.ts.map +1 -1
- package/dist/lib/features/project/project-read-model.js +48 -20
- package/dist/lib/features/project/project-read-model.js.map +1 -1
- package/dist/lib/features/project/project-service.d.ts +4 -4
- package/dist/lib/features/project/project-service.d.ts.map +1 -1
- package/dist/lib/features/project/project-service.e2e.test.js +20 -3
- package/dist/lib/features/project/project-service.e2e.test.js.map +1 -1
- package/dist/lib/features/project/project-service.js +7 -15
- package/dist/lib/features/project/project-service.js.map +1 -1
- package/dist/lib/features/project/project-store-type.d.ts +4 -6
- package/dist/lib/features/project/project-store-type.d.ts.map +1 -1
- package/dist/lib/features/project/project-store.d.ts +1 -5
- package/dist/lib/features/project/project-store.d.ts.map +1 -1
- package/dist/lib/features/project/project-store.e2e.test.js +1 -1
- package/dist/lib/features/project/project-store.e2e.test.js.map +1 -1
- package/dist/lib/features/project/project-store.js +5 -135
- package/dist/lib/features/project/project-store.js.map +1 -1
- package/dist/lib/metrics.d.ts.map +1 -1
- package/dist/lib/metrics.js +18 -1
- package/dist/lib/metrics.js.map +1 -1
- package/dist/lib/metrics.test.js +2 -2
- package/dist/lib/metrics.test.js.map +1 -1
- package/dist/lib/openapi/spec/event-schema.d.ts +10 -0
- package/dist/lib/openapi/spec/event-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/event-schema.js +10 -0
- package/dist/lib/openapi/spec/event-schema.js.map +1 -1
- package/dist/lib/openapi/spec/event-search-response-schema.d.ts +10 -0
- package/dist/lib/openapi/spec/event-search-response-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/events-schema.d.ts +10 -0
- package/dist/lib/openapi/spec/events-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/feature-events-schema.d.ts +10 -0
- package/dist/lib/openapi/spec/feature-events-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/index.d.ts +2 -0
- package/dist/lib/openapi/spec/index.d.ts.map +1 -1
- package/dist/lib/openapi/spec/index.js +2 -0
- package/dist/lib/openapi/spec/index.js.map +1 -1
- package/dist/lib/openapi/spec/integration-event-schema.d.ts +10 -0
- package/dist/lib/openapi/spec/integration-event-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/integration-events-schema.d.ts +20 -0
- package/dist/lib/openapi/spec/integration-events-schema.d.ts.map +1 -1
- package/dist/lib/openapi/spec/personal-dashboard-project-details-schema.d.ts +168 -0
- package/dist/lib/openapi/spec/personal-dashboard-project-details-schema.d.ts.map +1 -0
- package/dist/lib/openapi/spec/personal-dashboard-project-details-schema.js +81 -0
- package/dist/lib/openapi/spec/personal-dashboard-project-details-schema.js.map +1 -0
- package/dist/lib/openapi/spec/personal-dashboard-schema.d.ts +142 -0
- package/dist/lib/openapi/spec/personal-dashboard-schema.d.ts.map +1 -0
- package/dist/lib/openapi/spec/personal-dashboard-schema.js +149 -0
- package/dist/lib/openapi/spec/personal-dashboard-schema.js.map +1 -0
- package/dist/lib/routes/admin-api/index.d.ts.map +1 -1
- package/dist/lib/routes/admin-api/index.js +2 -0
- package/dist/lib/routes/admin-api/index.js.map +1 -1
- package/dist/lib/schema/role-schema.js +1 -1
- package/dist/lib/schema/role-schema.js.map +1 -1
- package/dist/lib/services/access-service.d.ts +1 -0
- package/dist/lib/services/access-service.d.ts.map +1 -1
- package/dist/lib/services/access-service.js +15 -6
- package/dist/lib/services/access-service.js.map +1 -1
- package/dist/lib/services/access-service.test.js +22 -0
- package/dist/lib/services/access-service.test.js.map +1 -1
- package/dist/lib/services/clean-permission-environment.test.d.ts +2 -0
- package/dist/lib/services/clean-permission-environment.test.d.ts.map +1 -0
- package/dist/lib/services/clean-permission-environment.test.js +114 -0
- package/dist/lib/services/clean-permission-environment.test.js.map +1 -0
- package/dist/lib/services/index.d.ts +2 -1
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +12 -1
- package/dist/lib/services/index.js.map +1 -1
- package/dist/lib/types/events.d.ts +4 -0
- package/dist/lib/types/events.d.ts.map +1 -1
- package/dist/lib/types/events.js.map +1 -1
- package/dist/lib/types/experimental.d.ts +1 -1
- package/dist/lib/types/experimental.d.ts.map +1 -1
- package/dist/lib/types/experimental.js +2 -5
- package/dist/lib/types/experimental.js.map +1 -1
- package/dist/lib/types/model.d.ts +1 -10
- package/dist/lib/types/model.d.ts.map +1 -1
- package/dist/lib/types/services.d.ts +3 -0
- package/dist/lib/types/services.d.ts.map +1 -1
- package/dist/lib/types/stores/account-store.d.ts +2 -1
- package/dist/lib/types/stores/account-store.d.ts.map +1 -1
- package/dist/lib/types/user.d.ts +1 -0
- package/dist/lib/types/user.d.ts.map +1 -1
- package/dist/lib/types/user.js.map +1 -1
- package/dist/migrations/20240919083625-client-metrics-env-variants-daily-to-bigint.d.ts +3 -0
- package/dist/migrations/20240919083625-client-metrics-env-variants-daily-to-bigint.d.ts.map +1 -0
- package/dist/migrations/20240919083625-client-metrics-env-variants-daily-to-bigint.js +8 -0
- package/dist/migrations/20240919083625-client-metrics-env-variants-daily-to-bigint.js.map +1 -0
- package/dist/server-dev.js +1 -3
- package/dist/server-dev.js.map +1 -1
- package/dist/test/fixtures/fake-access-store.d.ts +2 -2
- package/dist/test/fixtures/fake-access-store.d.ts.map +1 -1
- package/dist/test/fixtures/fake-access-store.js +5 -3
- package/dist/test/fixtures/fake-access-store.js.map +1 -1
- package/dist/test/fixtures/fake-account-store.d.ts +1 -0
- package/dist/test/fixtures/fake-account-store.d.ts.map +1 -1
- package/dist/test/fixtures/fake-account-store.js +3 -0
- package/dist/test/fixtures/fake-account-store.js.map +1 -1
- package/dist/test/fixtures/fake-project-store.d.ts +2 -4
- package/dist/test/fixtures/fake-project-store.d.ts.map +1 -1
- package/dist/test/fixtures/fake-project-store.js +0 -20
- package/dist/test/fixtures/fake-project-store.js.map +1 -1
- package/frontend/build/index.html +1 -1
- package/frontend/build/static/{AdvancedPlayground-CRdeeG3w.js → AdvancedPlayground-eDTjzS3E.js} +2 -2
- package/frontend/build/static/{CreateProject-8AyZj2dp.js → CreateProject-DEpFVLhl.js} +1 -1
- package/frontend/build/static/FeatureMetricsChart-CZKpaUOH.js +2 -0
- package/frontend/build/static/FeatureStaleDialog-2jleuqhn.js +7 -0
- package/frontend/build/static/FeatureViewLazyExport-CeAl2Yig.js +10 -0
- package/frontend/build/static/FlagMetricsChart-BRMGXeEU.js +2 -0
- package/frontend/build/static/{LazyAdminExport-0g_UOhr3.js → LazyAdminExport-CpfHUB52.js} +14 -14
- package/frontend/build/static/LazyProjectExport-XXHA0k8I.js +735 -0
- package/frontend/build/static/{LineChartComponent-BLXX5chp.js → LineChartComponent-B5O_VFku.js} +1 -1
- package/frontend/build/static/{NetworkOverview-DqGLVIJ6.js → NetworkOverview-DU1OT7gB.js} +1 -1
- package/frontend/build/static/NetworkTraffic-DQdYqYoU.js +1 -0
- package/frontend/build/static/NetworkTrafficUsage-CkyWiuAD.js +1 -0
- package/frontend/build/static/{ReactJSONEditor-Bvhd5heT.js → ReactJSONEditor-DlQuk0pf.js} +1 -1
- package/frontend/build/static/{RoleCell-DGcue0jn.js → RoleCell-DMPAgQMx.js} +1 -1
- package/frontend/build/static/{StrategyItemContainer-Das6_30A.js → StrategyItemContainer-L9vwk9uU.js} +1 -1
- package/frontend/build/static/aggregateFeatureMetrics-CLK9MToQ.js +1 -0
- package/frontend/build/static/formatTickValue-DArtcDRb.js +6 -0
- package/frontend/build/static/{index-BsIpdLcw.js → index-DK5jinWf.js} +1 -1
- package/frontend/build/static/index-JQ6lMAyk.js +524 -0
- package/frontend/build/static/onboardingConcepts-1jcVefeL.png +0 -0
- package/frontend/build/static/unknownify-C7SyNno2.js +1 -0
- package/frontend/build/static/{useApiTokens-5JgqgHim.js → useApiTokens-DQBXJ3PL.js} +1 -1
- package/frontend/package.json +13 -13
- package/package.json +7 -6
- package/frontend/build/static/FeatureMetricsChart-DEo4WxO1.js +0 -2
- package/frontend/build/static/FeatureStaleDialog-CrsbH2rq.js +0 -7
- package/frontend/build/static/FeatureViewLazyExport-BwY7TYmZ.js +0 -10
- package/frontend/build/static/LazyProjectExport-C1eSkT3Z.js +0 -177
- package/frontend/build/static/NetworkTraffic-BWFLlaz7.js +0 -1
- package/frontend/build/static/NetworkTrafficUsage-BvoBumVR.js +0 -6
- package/frontend/build/static/index-Cx91uh9W.js +0 -524
- package/frontend/build/static/unknownify-8qa4PVkQ.js +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{it as c,d8 as y,ie as u,bh as x,b as g,bd as f,r as d,j as b,ig as C,ih as v,ii as M,ip as q,iq as S,ir as h,im as D,il as E,ik as L}from"./index-JQ6lMAyk.js";import{L as T}from"./index-DK5jinWf.js";import{d as $}from"./FeatureViewLazyExport-CeAl2Yig.js";import"./FeatureStaleDialog-2jleuqhn.js";import"./StrategyItemContainer-L9vwk9uU.js";import"./aggregateFeatureMetrics-CLK9MToQ.js";const j=(e,i,s)=>{const a={label:"Total requests",borderColor:e.palette.primary.main,backgroundColor:e.palette.primary.main,data:p(i,s,o=>o.yes+o.no),elements:{point:{radius:6,pointStyle:"circle"},line:{borderDash:[8,4]}}},t={label:"Exposed",borderColor:e.palette.success.main,backgroundColor:e.palette.success.main,data:p(i,s,o=>o.yes),elements:{point:{radius:6,pointStyle:"triangle"}}},r={label:"Not exposed",borderColor:e.palette.error.main,backgroundColor:e.palette.error.main,data:p(i,s,o=>o.no),elements:{point:{radius:6,pointStyle:"triangle",pointRotation:180}}};return{datasets:[t,r,a]}},p=(e,i,s)=>e.map(a=>({x:a.timestamp,y:s(a),variants:a.variants||{}})),k=(e,i)=>{if(i===0)return"";const[s,a]=e,t=Math.floor(Number(a)/i*100);return`${a} (${t}%) - ${s}`},O=(e,i,s,a)=>({locale:a.locale,responsive:!0,maintainAspectRatio:!1,interaction:{mode:"index",intersect:!1},color:e.palette.text.secondary,plugins:{tooltip:{backgroundColor:e.palette.background.paper,bodyColor:e.palette.text.primary,titleColor:e.palette.text.secondary,borderColor:e.palette.primary.main,borderWidth:1,padding:10,boxPadding:5,usePointStyle:!0,itemSort:(t,r)=>{const o=["Total requests","Exposed","Not exposed"],l=o.indexOf(t.dataset.label),n=o.indexOf(r.dataset.label);return l-n},callbacks:{label:t=>`${t.formattedValue} - ${t.dataset.label}`,afterLabel:t=>{const r=t.dataset.data[t.dataIndex];if(t.dataset.label!=="Exposed"||r.variants===void 0)return"";const{disabled:o,...l}=r.variants;return Object.entries(l).map(n=>k(n,r.y)).join(`
|
|
2
|
+
`)},title:t=>`Time: ${s>48?y(t[0].parsed.x,a.locale,"UTC"):u(t[0].parsed.x,a.locale)}`}},legend:{position:"top",align:"end",labels:{boxWidth:10,boxHeight:10,usePointStyle:!0}},title:{text:P(s),position:"top",align:"start",display:!0,font:{size:16,weight:"400"},color:e.palette.text.primary}},scales:{y:{type:"linear",title:{display:!0,text:"Number of requests",color:e.palette.text.secondary},suggestedMin:0,ticks:{precision:0,color:e.palette.text.secondary},grid:{color:e.palette.divider,borderColor:e.palette.divider}},x:{type:"time",time:{unit:s>48?"day":"hour"},grid:{display:!1},ticks:{callback:(t,r,o)=>s>48?x(o[r].value,a.locale,"UTC"):u(o[r].value,a.locale),color:e.palette.text.secondary}}}}),P=e=>e===1?"Requests in the last hour":`Requests in the last ${$(e)}`;c.font={...c.font,family:"Sen",size:13,weight:"400"};const V=({metrics:e,hoursBack:i,statsSectionId:s})=>{const a=g(),{locationSettings:t}=f(),r=d.useMemo(()=>[...e].sort((n,m)=>n.timestamp.localeCompare(m.timestamp)),[e]),o=d.useMemo(()=>O(a,r,i,t),[a,r,i,t]),l=d.useMemo(()=>j(a,r,t),[a,r,t]);return b.jsx("div",{style:{height:400},children:b.jsx(T,{options:o,data:l,"aria-label":"A feature metrics line chart, with three lines: all requests, positive requests, and negative requests.","aria-describedby":s})})};C.register(v,M,q,S,h,D,E,L);export{V as FeatureMetricsChart,V as default};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{x as F,y as q,j as e,aK as B,aU as Q,aY as U,C as I,N as ce,T as E,d2 as de,s as k,an as Z,r as x,b as X,c_ as G,cP as ue,cI as he,hZ as pe,cY as me,d1 as Y,b5 as V,c8 as fe,d0 as ge,c$ as ve,h_ as be,bZ as xe,cf as ee,bc as te,ba as ae,h$ as je,i0 as ye,i1 as Te,i2 as Se,hj as Ee,h9 as se,i3 as Ce,i as Ae,i4 as Re,di as ne,cc as ke,fh as we,e as L,cg as _e,ce as Ie,cj as Pe,bP as $e,hm as De,i5 as Oe,h as O,B as Ve,al as Fe,fj as qe,i6 as Le,aT as Ne,aL as Be,bg as J,cK as re,i7 as Ue,i8 as Me,i9 as ze,fM as He,A as ie,l as oe,cN as We,aP as Ge,aR as Ye,ia as Je,aQ as Ke,u as Qe,b8 as Ze,bp as Xe,b7 as et,b9 as tt}from"./index-JQ6lMAyk.js";var M={},at=q;Object.defineProperty(M,"__esModule",{value:!0});var st=M.default=void 0,nt=at(F()),rt=e,it=(0,nt.default)((0,rt.jsx)("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");st=M.default=it;var z={},ot=q;Object.defineProperty(z,"__esModule",{value:!0});var lt=z.default=void 0,ct=ot(F()),dt=e,ut=(0,ct.default)((0,dt.jsx)("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");lt=z.default=ut;var H={},ht=q;Object.defineProperty(H,"__esModule",{value:!0});var pt=H.default=void 0,mt=ht(F()),ft=e,gt=(0,mt.default)((0,ft.jsx)("path",{d:"M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"}),"LibraryAdd");pt=H.default=gt;const vt=({isOpen:t,disabled:o=!1,onConfirm:n,onClose:u,showBanner:r,environment:l,messageComponent:a})=>{const c=B("projectId"),{data:d}=Q(c),{changeRequestInReviewOrApproved:f,alert:g}=de(d),p=f(l||""),h=p?"Add to existing change request":"Add suggestion to draft";return e.jsxs(U,{open:t,primaryButtonText:h,secondaryButtonText:"Cancel",disabledPrimaryButton:o,onClick:n,onClose:u,title:"Request changes",fullWidth:!0,children:[e.jsx(I,{condition:p,show:g}),e.jsx(I,{condition:!!r,show:e.jsxs(ce,{severity:"info",sx:{mb:2},children:["Change requests feature is enabled for ",l,". 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."]})}),e.jsx(E,{variant:"body2",color:"text.secondary",children:"Your suggestion:"}),a]})},bt=k("div")({display:"flex",flexDirection:"column"}),xt=({strategy:t,setStrategy:o,projectId:n,environment:u,editable:r,permission:l=ge})=>{const{trackEvent:a}=Z(),[c,d]=x.useState([]),f=X(),g=t!=null&&t.parameters&&"stickiness"in(t==null?void 0:t.parameters)?String(t.parameters.stickiness):"default";x.useEffect(()=>{d((t.variants||[]).map(s=>({...s,new:r||!1,isValid:!0,id:G(),overrides:[]})))},[]),x.useEffect(()=>{o(s=>({...s,variants:c.map(m=>({stickiness:g,name:m.name,weight:m.weight,payload:m.payload,weightType:m.weightType}))}))},[g,JSON.stringify(c)]);const p=(s,m)=>{d(v=>Y(v.map(T=>T.id===m?s:T),1e3))},h=()=>{const s=G();d(m=>[...m,{name:"",weightType:ve.VARIABLE,weight:0,stickiness:g,new:!0,isValid:!1,id:s}]),a("strategy-variants",{props:{eventType:"variant added"}})};return e.jsxs(e.Fragment,{children:[e.jsxs(E,{component:"h3",sx:{m:0,display:"flex",gap:"1ch"},variant:"h3",children:["Variants",e.jsx(ue,{htmlTooltip:!0,tooltip:e.jsxs(e.Fragment,{children:[e.jsx("span",{children:"Variants allow to attach one or more values to this strategy. Variants at the strategy level override variants at the feature level."}),e.jsx(he,{target:"_blank",href:"https://docs.getunleash.io/reference/strategy-variants",children:"Learn more"})]})})]}),e.jsxs(bt,{children:[e.jsx(pe,{}),c.map((s,m)=>e.jsx(me,{disableOverrides:!0,variant:s,variants:c,updateVariant:v=>p(v,s.id),removeVariant:()=>d(v=>Y(v.filter(T=>T.id!==s.id),1e3)),decorationColor:f.palette.variants[m%f.palette.variants.length]},s.id))]}),e.jsx(V,{onClick:h,variant:"outlined",permission:l,projectId:n,environmentId:u,"data-testid":"ADD_STRATEGY_VARIANT_BUTTON",children:"Add variant"}),e.jsx(fe,{variants:c})]})},jt=k("form")(({theme:t})=>({display:"grid",gap:t.spacing(2)})),K=k("hr")(({theme:t})=>({width:"100%",height:"1px",margin:t.spacing(2,0),border:"none",background:t.palette.background.elevation2})),yt=k("div")(({theme:t})=>({display:"flex",justifyContent:"end",gap:t.spacing(2),paddingBottom:t.spacing(10)})),Tt=({projectId:t,environmentId:o,permission:n,onSubmit:u,onCancel:r,loading:l,strategy:a,setStrategy:c,segments:d,setSegments:f,errors:g})=>{const p=be(a.constraints),h=xe(n,t,o),{strategyDefinition:s}=ee(a==null?void 0:a.name),m=te(),{uiConfig:v,error:T,loading:P}=ae();if(T)throw T;if(P||!s)return null;const $=j=>s.parameters.find(S=>S.name===j),C=(j,S)=>{const A=$(j);if(j!=="groupId"){const _=Re(A,S);return _?(g.setFormError(j,_),!1):(g.removeFormError(j),!0)}return!0},i=()=>s.parameters.map(j=>j.name).map(j=>{var S;return C(j,(S=a.parameters)==null?void 0:S[j])}).every(Boolean),w=()=>{m(`/projects/${t}/settings/default-strategy`)},D=async j=>{if(j.preventDefault(),i())u();else return};return e.jsxs(jt,{onSubmit:D,children:[e.jsx(je,{title:a.title||"",setTitle:j=>{c(S=>({...S,title:j}))}}),e.jsx(ye,{segments:d,setSegments:f,projectId:t}),e.jsx(Te,{projectId:t,environmentId:o,strategy:a,setStrategy:c}),e.jsx(K,{}),e.jsx(Se,{strategy:a,strategyDefinition:s,setStrategy:c,validateParameter:C,errors:g,hasAccess:h}),e.jsx(I,{condition:a.parameters!=null&&"stickiness"in a.parameters,show:e.jsx(xt,{strategy:a,setStrategy:c,environment:o,projectId:t,permission:[Ee,se]})}),e.jsx(K,{}),e.jsxs(yt,{children:[e.jsx(V,{permission:n,projectId:t,environmentId:o,variant:"contained",color:"primary",type:"submit",disabled:l||!p||g.hasFormErrors(),"data-testid":Ce,children:"Save strategy"}),e.jsx(Ae,{type:"button",color:"primary",onClick:r||w,disabled:l,children:"Cancel"})]})]})},St=(t,o)=>{var a;const{project:n,refetch:u}=ne(t),r={name:"flexibleRollout",constraints:[],parameters:{rollout:"100",stickiness:n.defaultStickiness||"default",groupId:""}},l=(a=n.environments.find(c=>c.environment===o))==null?void 0:a.defaultStrategy;return{defaultStrategyFallback:r,strategy:l,refetch:u}},zt=()=>{const t=B("projectId"),o=ke("environmentId"),{refetch:n}=ne(t),{defaultStrategyFallback:u,strategy:r,refetch:l}=St(t,o),[a,c]=x.useState(r||u),[d,f]=x.useState([]),{updateDefaultStrategy:g,loading:p}=we(),{strategyDefinition:h}=ee(a==null?void 0:a.name),{setToastData:s,setToastApiError:m}=L(),v=_e(),{uiConfig:T}=ae(),{unleashUrl:P}=T,$=te(),{trackEvent:C}=Z(),{segments:i,refetchSegments:w}=Ie();x.useEffect(()=>{if(i&&(r!=null&&r.segments)){const A=[];for(const _ of r==null?void 0:r.segments)A.push(...i.filter(y=>y.id===_));f(A)}},[JSON.stringify(i),JSON.stringify(r==null?void 0:r.segments)]);const D=Et(a,d),j=async A=>{await g(t,o,A),C("default_strategy",{props:{action:"edit",hasTitle:!!A.title}}),w(),n(),s({title:"Default Strategy updated",type:"success",confetti:!0})},S=async()=>{const A=`/projects/${t}/settings/default-strategy`;try{await j(D),await l(),$(A)}catch(_){m(O(_))}};return!h||!a?null:e.jsx(Pe,{modal:!0,title:$e((a==null?void 0:a.name)??""),description:At,documentationLink:Rt,documentationLinkLabel:kt,formatApiCode:()=>Ct(t,o,D,h,P),children:e.jsx(Tt,{projectId:t,strategy:a,setStrategy:c,segments:d,setSegments:f,environmentId:o,onSubmit:S,loading:p,permission:[De,se],errors:v,isChangeRequest:!1})})},Et=(t,o)=>({name:t.name,title:t.title,constraints:t.constraints??[],parameters:t.parameters??{},variants:t.variants??[],segments:o.map(n=>n.id),disabled:t.disabled??!1}),Ct=(t,o,n,u,r)=>{if(!r)return"";const l={...n,parameters:Oe(n.parameters??{},u)},a=`${r}/api/admin/projects/${t}/environments/${o}/default-strategy}`,c=JSON.stringify(l,void 0,2);return`curl --location --request PUT '${a}' \\
|
|
2
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
|
+
--header 'Content-Type: application/json' \\
|
|
4
|
+
--data-raw '${c}'`},At=`
|
|
5
|
+
An activation strategy will only run when a feature flag is enabled and provides a way to control who will get access to the feature.
|
|
6
|
+
If any of a feature flag's activation strategies returns true, the user will get access.
|
|
7
|
+
`,Rt="https://docs.getunleash.io/reference/projects#project-default-strategy",kt="Default strategy documentation",wt=t=>{const[o,n]=x.useState(t),u=x.useCallback(()=>n(t),[t]);return x.useEffect(()=>{n(t)},[t]),[o,n,u]},_t=k(Ve)(()=>({mx:"auto",...Fe})),Ht=({projectId:t,featureId:o,environmentName:n,value:u,onToggle:r})=>{const[l,a,c]=wt(u),d=()=>{a(!l),requestAnimationFrame(()=>{r(!l,c)})},f=`${o}-${n}`;return e.jsx(e.Fragment,{children:e.jsx(_t,{"data-testid":`TOGGLE-${f}`,children:e.jsx(qe,{tooltip:l?`Disable feature in ${n}`:`Enable feature in ${n}`,checked:u,environmentId:n,projectId:t,permission:Le,inputProps:{"aria-label":n},onClick:d,"data-testid":"permission-switch",disableRipple:!0,disabled:u!==l})},f)})},It=t=>{const{setToastData:o,setToastApiError:n}=L(),{addChange:u}=Ne(),{refetch:r}=Q(t),[l,a]=x.useState(!1),[c,d]=x.useState({isOpen:!1}),f=x.useCallback((h,s,m,v)=>{d({featureName:h,environment:s,enabled:m,shouldActivateDisabledStrategies:v,isOpen:!0})},[]),g=x.useCallback(()=>{d(h=>({...h,isOpen:!1}))},[]),p=x.useCallback(async()=>{try{a(!0),await u(t,c.environment,{feature:c.featureName,action:"updateEnabled",payload:{enabled:!!c.enabled,shouldActivateDisabledStrategies:!!c.shouldActivateDisabledStrategies}}),r(),d(h=>({...h,isOpen:!1})),o({type:"success",title:"Changes added to the draft!"})}catch(h){n(O(h)),d(s=>({...s,isOpen:!1}))}finally{a(!1)}},[u]);return{pending:l,onChangeRequestToggle:f,onChangeRequestToggleClose:g,onChangeRequestToggleConfirm:p,changeRequestDialogDetails:c}},Pt=({enabled:t,featureName:o,environment:n})=>e.jsxs(E,{"data-testid":"update-enabled-message",children:[e.jsx("strong",{children:t?"Enable":"Disable"})," feature flag"," ",e.jsx("strong",{children:o})," in ",e.jsx("strong",{children:n})]}),$t=k("ul")(({theme:t})=>({margin:t.spacing(1),paddingLeft:t.spacing(2)})),Dt=({isOpen:t,onAddDefaultStrategy:o,onActivateDisabledStrategies:n,onClose:u,environment:r,featureId:l})=>{var g,p,h;const a=B("projectId"),{feature:c}=Be(a,l),d=(h=(p=(g=c.environments)==null?void 0:g.find(({name:s})=>s===r))==null?void 0:p.strategies)==null?void 0:h.filter(({disabled:s})=>s).length,f=d?d===1?"1 disabled strategy":`${d} disabled strategies`:"disabled strategies";return e.jsxs(U,{open:t,secondaryButtonText:"Cancel",permissionButton:e.jsxs(e.Fragment,{children:[e.jsx(V,{type:"button",variant:"outlined",permission:J,projectId:a,environmentId:r,onClick:o,children:"Add default strategy"}),e.jsx(V,{type:"button",variant:"outlined",permission:J,projectId:a,environmentId:r,onClick:n,children:"Enable all strategies"})]}),onClose:u,title:`Enable feature flag in ${r}`,fullWidth:!0,children:[e.jsx(E,{sx:{mb:s=>s.spacing(3)},children:"A feature flag cannot be enabled without an enabled strategy."}),e.jsx(E,{children:"To enable this feature flag you can choose to:"}),e.jsxs($t,{children:[e.jsx("li",{children:e.jsx(E,{children:e.jsx("strong",{children:"Add the default strategy"})})}),e.jsx("li",{children:e.jsxs(E,{children:[e.jsx("strong",{children:"Enable all the disabled strategies"})," ","(this feature flag has ",f,")"]})})]})]})},Ot=t=>{const o=n=>{n<t.length&&t[n](()=>o(n+1))};o(0)},Wt=t=>{const{toggleFeatureEnvironmentOn:o,toggleFeatureEnvironmentOff:n}=re(),{setToastData:u,setToastApiError:r}=L(),[l,a]=x.useState({open:!1,label:"",loading:!1,onClose:()=>{},onClick:()=>{}}),[c,d]=x.useState({isOpen:!1,environment:"",featureId:"",onClose:()=>{},onActivateDisabledStrategies:()=>{},onAddDefaultStrategy:()=>{}}),{pending:f,onChangeRequestToggle:g,onChangeRequestToggleClose:p,onChangeRequestToggleConfirm:h,changeRequestDialogDetails:s}=It(t),[m,v]=x.useState(),T=x.useCallback(async(C,i)=>{let w=!1;return Ot([y=>{if(i.isChangeRequestEnabled||!Me(i.environmentType||""))return y();a({open:!0,label:`${C?"Enable":"Disable"} Environment`,loading:!1,onClose:()=>{var b;a(R=>({...R,open:!1})),(b=i.onRollback)==null||b.call(i)},onClick:()=>{a(b=>({...b,open:!1,loading:!0})),y()}})},y=>{if(C===!1||!i.hasStrategies||i.hasEnabledStrategies)return y();d({isOpen:!0,environment:i.environmentName,featureId:i.featureId,onClose:()=>{var b;d(R=>({...R,isOpen:!1})),(b=i.onRollback)==null||b.call(i)},onActivateDisabledStrategies:()=>{d(b=>({...b,isOpen:!1})),w=!0,y()},onAddDefaultStrategy:()=>{d(b=>({...b,isOpen:!1})),y()}})},y=>{if(!i.isChangeRequestEnabled)return y();v(()=>{var b;v(void 0),(b=i.onRollback)==null||b.call(i)}),g(i.featureId,i.environmentName,C,w)},async y=>{var b,R;if(C!==!1)return y();try{await n(i.projectId,i.featureId,i.environmentName),u({type:"success",title:`Disabled in ${i.environmentName}`,text:`${i.featureId} is unavailable in ${i.environmentName} and its strategies will no longer have any effect.`}),(b=i.onSuccess)==null||b.call(i)}catch(N){r(O(N)),(R=i.onRollback)==null||R.call(i)}},async y=>{var b,R;if(C!==!0)return y();try{await o(i.projectId,i.featureId,i.environmentName,w),u({type:"success",title:`Enabled in ${i.environmentName}`,text:`${i.featureId} is now available in ${i.environmentName} based on its defined strategies.`}),(b=i.onSuccess)==null||b.call(i)}catch(N){r(O(N)),(R=i.onRollback)==null||R.call(i)}}])},[a]),P=c.featureId.length!==0,$=e.jsxs(e.Fragment,{children:[e.jsx(Ue,{...l}),e.jsx(I,{condition:P,show:e.jsx(Dt,{...c})}),e.jsx(vt,{isOpen:s.isOpen,onClose:()=>{m==null||m(),p()},environment:s==null?void 0:s.environment,disabled:f,onConfirm:()=>{m==null||m(),h()},messageComponent:e.jsx(Pt,{enabled:s==null?void 0:s.enabled,featureName:s==null?void 0:s.featureName,environment:s.environment})})]});return{onToggle:T,modals:$}},Vt=k(ze)(({theme:t})=>({color:t.palette.warning.main,fontSize:t.fontSizes.bodySize})),Gt=()=>e.jsx(He,{arrow:!0,title:e.jsxs(e.Fragment,{children:["This environment has no variants enabled. If you check this feature's variants in this environment, you will get the"," ",e.jsx("a",{href:"https://docs.getunleash.io/reference/feature-toggle-variants#the-disabled-variant",target:"_blank",rel:"noreferrer",children:"disabled variant"}),"."]}),children:e.jsx(Vt,{})});var W={},Ft=q;Object.defineProperty(W,"__esModule",{value:!0});var le=W.default=void 0,qt=Ft(F()),Lt=e,Nt=(0,qt.default)((0,Lt.jsx)("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-2zm-2 10H7v-2h10v2z"}),"IndeterminateCheckBox");le=W.default=Nt;const Bt=Je(),Yt=({options:t,selectedOptions:o,indeterminateOptions:n,tagType:u,existingTags:r,disabled:l=!1,onChange:a})=>{const c=e.jsx(Ke,{fontSize:"small"}),d=p=>p.inputValue?p.inputValue:p.title,f=(p,h,{selected:s})=>{const m=(n==null?void 0:n.some(v=>v.title===h.title))??!1;return e.jsxs("li",{...p,children:[e.jsx(I,{condition:!!h.inputValue,show:e.jsx(We,{sx:{mr:v=>v.spacing(.5)}}),elseShow:e.jsx(Ge,{icon:c,checkedIcon:e.jsx(Ye,{fontSize:"small"}),indeterminateIcon:e.jsx(le,{fontSize:"small"}),sx:{mr:v=>v.spacing(.5)},checked:s&&!m,indeterminate:m})}),h.title]})},g=(p,h)=>{const s=h.inputValue.trim(),m=Bt(p,{...h,inputValue:s}),v=p.some(T=>s===T.title);return s.length>=2&&!v&&m.push({inputValue:s,title:`Create new value "${s}"`}),m};return e.jsx(ie,{multiple:!0,id:"checkboxes-tag",sx:{marginTop:p=>p.spacing(2),width:500},disableCloseOnSelect:!0,options:t,value:o,isOptionEqualToValue:(p,h)=>h.inputValue&&h.inputValue!==""?p.title===h.inputValue:p.title===h.title,getOptionLabel:d,renderOption:f,filterOptions:g,ListboxProps:{style:{maxHeight:200,overflow:"auto"}},onChange:a,renderInput:p=>e.jsx(oe,{...p,label:"Select values",placeholder:"Select values"}),disabled:l})},Ut=k("li")({flexDirection:"column"}),Jt=({options:t,value:o,disabled:n=!1,onChange:u})=>{const r=X();return e.jsx(ie,{disablePortal:!0,disabled:n,id:"tag-type-select",sx:{marginTop:l=>l.spacing(2),width:500},options:t,disableClearable:!0,value:o,getOptionLabel:l=>l.name,renderOption:(l,a)=>e.jsxs(Ut,{...l,style:{alignItems:"flex-start",gap:r.spacing(.5)},children:[e.jsx(E,{variant:"body1",children:a.name}),e.jsx(E,{variant:"caption",children:a.description})]}),renderInput:l=>e.jsx(oe,{...l,label:"Tag type",value:o}),onChange:u,ListboxProps:{style:{maxHeight:200,overflow:"auto"}}})},Kt=()=>{const{makeRequest:t,createRequest:o,errors:n,loading:u}=Qe({propagateErrors:!0});return{createTag:async a=>{const d=o("api/admin/tags",{method:"POST",body:JSON.stringify(a)});return t(d.caller,d.id)},bulkUpdateTags:async(a,c)=>{const d=`api/admin/projects/${c}/tags`,f=o(d,{method:"PUT",body:JSON.stringify(a)});return t(f.caller,f.id)},errors:n,loading:u}},Qt=(t,o={})=>{const n=async()=>{const f=et(`api/admin/tags/${t}`);return(await fetch(f,{method:"GET"}).then(tt("Tags"))).json()},u=`api/admin/tags/${t}`,{data:r,error:l}=Ze(!!t,{tags:[]},u,n,o),[a,c]=x.useState(!l&&!r),d=()=>{Xe(u)};return x.useEffect(()=>{c(!l&&!r)},[r,l]),{tags:(r==null?void 0:r.tags)||[],error:l,loading:a,refetch:d}},Zt=({isStale:t,isOpen:o,projectId:n,featureId:u,onClose:r})=>{const{setToastData:l,setToastApiError:a}=L(),{patchFeatureToggle:c}=re(),d=e.jsx(E,{children:"Setting a flag to stale marks it for cleanup"}),f=e.jsx(E,{children:"Setting a flag to active marks it as in active use"}),g=t?"active":"stale",p=async h=>{h.stopPropagation();try{await c(n,u,[{op:"replace",path:"/stale",value:!t}]),r()}catch(s){a(O(s))}l(t?{type:"success",title:"And we're back!",text:"The flag is no longer marked as stale."}:{type:"success",title:"A job well done.",text:"The flag has been marked as stale."})};return e.jsx(U,{open:o,secondaryButtonText:"Cancel",primaryButtonText:`Flip to ${g}`,title:`Set feature state to ${g}`,onClick:p,onClose:r,children:e.jsx(I,{condition:t,show:f,elseShow:d})})};export{vt as C,zt as E,Ht as F,Jt as T,Gt as V,Wt as a,Kt as b,Qt as c,Yt as d,pt as e,st as f,lt as g,Zt as h,St as u};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{aA as Is,aB as Ps,_ as It,aC as Dn,a as re,aD as rt,j as t,s as p,aE as kn,aF as Pe,r as f,aG as Bs,b as it,aH as At,aI as _e,aJ as _s,aK as k,aL as W,aM as $n,aN as Fn,L as oe,N as he,A as In,aO as Pn,aP as Os,l as Bn,aQ as _n,aR as On,aS as Ls,u as Ln,h as G,an as Te,aT as Ee,aU as be,e as ne,aV as Pt,aW as ce,aX as Mn,aY as ve,B as Q,T as J,C,a5 as Ms,t as ue,w as Ge,aZ as Bt,a_ as zn,M as Ce,a$ as Le,b0 as Me,b1 as ke,b2 as zs,b3 as Je,b4 as Vs,b5 as we,b6 as Gt,b7 as Ke,b8 as Ns,b9 as Qe,ba as Xe,bb as Vn,bc as Re,bd as qs,be as Nn,bf as je,bg as ze,bh as qn,bi as Ws,bj as Wn,bk as Us,bl as Hs,bm as Un,bn as Hn,bo as Yn,bp as Ys,bq as Gs,br as Gn,bs as Jn,bt as Kn,bu as Qn,bv as Xn,bw as Zn,bx as ea,by as ta,bz as Y,bA as sa,bB as na,bC as Jt,bD as Kt,bE as We,bF as aa,bG as pt,bH as oa,bI as Qt,bJ as ra,bK as Xt,bL as ia,bM as ca,bN as la,bO as da,bP as Ze,bQ as Ne,bR as $e,bS as ua,bT as pa,bU as et,bV as Js,bW as Ks,bX as _t,bY as ga,bZ as Dt,b_ as ha,b$ as xa,c0 as fa,c1 as ya,c2 as ma,c3 as ja,c4 as ba,c5 as Sa,c6 as va,c7 as Ca,c8 as Zt,c9 as Qs,ca as wa,ag as tt,H as Ve,Q as Ta,cb as Ot,i as Fe,cc as es,cd as Ea,ce as Ra,cf as Aa,cg as Da,ch as ka,ci as $a,cj as Xs,ck as Fa,cl as Ia,cm as Pa,cn as Ba,co as _a,cp as Oa,cq as La,Y as Lt,cr as Zs,a1 as Ma,cs as Mt,ct as Oe,cu as en,cv as za,cw as Va,cx as Se,cy as Na,cz as qa,a0 as Wa,am as Ua,cA as Ha,cB as Ya,cC as Ga,cD as Ja,cE as Ka,cF as Qa,cG as Xa,cH as Za,cI as zt,cJ as eo,cK as ct,cL as to,X as tn,D as lt,cM as so,cN as no,cO as ao,cP as oo,cQ as sn,cR as ro,cS as nn,cT as Ae,cU as kt,cV as io,cW as an,cX as co,cY as lo,f as uo,cZ as po,c_ as gt,c$ as ts,az as go,d0 as Be,d1 as ss,d2 as ho,d3 as xo,d4 as fo,ax as Vt,ay as yo,as as ns,d5 as mo,d6 as jo,d7 as bo,d8 as as,af as at,x as So,y as vo,d9 as Co,a7 as ht,aj as wo,a9 as To,aa as Eo,ab as Ro,ac as Ao,ad as Do,ae as ko,da as $o,db as os,dc as Fo,dd as Io,de as xt,df as Po,dg as Bo,dh as _o,q as on,di as Oo,dj as rs,dk as Lo,dl as Mo,dm as zo,dn as Vo,dp as No,dq as qo,dr as Wo,ap as Uo,ds as Ho,d as Yo,dt as Go,du as Jo,dv as Ko,dw as Qo,dx as Xo,dy as Zo}from"./index-JQ6lMAyk.js";import{C as rn,u as er,a as tr,F as sr,V as nr,b as ar,c as or,T as rr,d as ir,e as cr,f as lr,g as dr,h as ur}from"./FeatureStaleDialog-2jleuqhn.js";import{S as pr}from"./StrategyItemContainer-L9vwk9uU.js";import{F as $t,u as cn,a as gr,b as hr}from"./aggregateFeatureMetrics-CLK9MToQ.js";function xr(e){return Is("MuiPagination",e)}Ps("MuiPagination",["root","ul","outlined","text"]);const fr=["boundaryCount","componentName","count","defaultPage","disabled","hideNextButton","hidePrevButton","onChange","page","showFirstButton","showLastButton","siblingCount"];function yr(e={}){const{boundaryCount:s=1,componentName:n="usePagination",count:a=1,defaultPage:o=1,disabled:r=!1,hideNextButton:c=!1,hidePrevButton:l=!1,onChange:i,page:d,showFirstButton:g=!1,showLastButton:x=!1,siblingCount:m=1}=e,y=It(e,fr),[j,S]=Dn({controlled:d,default:o,name:n,state:"page"}),h=(E,L)=>{d||S(L),i&&i(E,L)},u=(E,L)=>{const X=L-E+1;return Array.from({length:X},(te,b)=>E+b)},w=u(1,Math.min(s,a)),I=u(Math.max(a-s+1,s+1),a),B=Math.max(Math.min(j-m,a-s-m*2-1),s+2),O=Math.min(Math.max(j+m,s+m*2+2),I.length>0?I[0]-2:a-1),$=[...g?["first"]:[],...l?[]:["previous"],...w,...B>s+2?["start-ellipsis"]:s+1<a-s?[s+1]:[],...u(B,O),...O<a-s-1?["end-ellipsis"]:a-s>s?[a-s]:[],...I,...c?[]:["next"],...x?["last"]:[]],P=E=>{switch(E){case"first":return 1;case"previous":return j-1;case"next":return j+1;case"last":return a;default:return null}},R=$.map(E=>typeof E=="number"?{onClick:L=>{h(L,E)},type:"page",page:E,selected:E===j,disabled:r,"aria-current":E===j?"true":void 0}:{onClick:L=>{h(L,P(E))},type:E,page:P(E),selected:!1,disabled:r||E.indexOf("ellipsis")===-1&&(E==="next"||E==="last"?j>=a:j<=1)});return re({items:R},y)}function mr(e){return Is("MuiPaginationItem",e)}const de=Ps("MuiPaginationItem",["root","page","sizeSmall","sizeLarge","text","textPrimary","textSecondary","outlined","outlinedPrimary","outlinedSecondary","rounded","ellipsis","firstLast","previousNext","focusVisible","disabled","selected","icon"]),is=rt(t.jsx("path",{d:"M18.41 16.59L13.82 12l4.59-4.59L17 6l-6 6 6 6zM6 6h2v12H6z"}),"FirstPage"),cs=rt(t.jsx("path",{d:"M5.59 7.41L10.18 12l-4.59 4.59L7 18l6-6-6-6zM16 6h2v12h-2z"}),"LastPage"),ls=rt(t.jsx("path",{d:"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"}),"NavigateBefore"),ds=rt(t.jsx("path",{d:"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"}),"NavigateNext"),jr=["className","color","component","components","disabled","page","selected","shape","size","slots","type","variant"],ln=(e,s)=>{const{ownerState:n}=e;return[s.root,s[n.variant],s[`size${_e(n.size)}`],n.variant==="text"&&s[`text${_e(n.color)}`],n.variant==="outlined"&&s[`outlined${_e(n.color)}`],n.shape==="rounded"&&s.rounded,n.type==="page"&&s.page,(n.type==="start-ellipsis"||n.type==="end-ellipsis")&&s.ellipsis,(n.type==="previous"||n.type==="next")&&s.previousNext,(n.type==="first"||n.type==="last")&&s.firstLast]},br=e=>{const{classes:s,color:n,disabled:a,selected:o,size:r,shape:c,type:l,variant:i}=e,d={root:["root",`size${_e(r)}`,i,c,n!=="standard"&&`${i}${_e(n)}`,a&&"disabled",o&&"selected",{page:"page",first:"firstLast",last:"firstLast","start-ellipsis":"ellipsis","end-ellipsis":"ellipsis",previous:"previousNext",next:"previousNext"}[l]],icon:["icon"]};return _s(d,mr,s)},Sr=p("div",{name:"MuiPaginationItem",slot:"Root",overridesResolver:ln})(({theme:e,ownerState:s})=>re({},e.typography.body2,{borderRadius:32/2,textAlign:"center",boxSizing:"border-box",minWidth:32,padding:"0 6px",margin:"0 3px",color:(e.vars||e).palette.text.primary,height:"auto",[`&.${de.disabled}`]:{opacity:(e.vars||e).palette.action.disabledOpacity}},s.size==="small"&&{minWidth:26,borderRadius:26/2,margin:"0 1px",padding:"0 4px"},s.size==="large"&&{minWidth:40,borderRadius:40/2,padding:"0 10px",fontSize:e.typography.pxToRem(15)})),vr=p(kn,{name:"MuiPaginationItem",slot:"Root",overridesResolver:ln})(({theme:e,ownerState:s})=>re({},e.typography.body2,{borderRadius:32/2,textAlign:"center",boxSizing:"border-box",minWidth:32,height:32,padding:"0 6px",margin:"0 3px",color:(e.vars||e).palette.text.primary,[`&.${de.focusVisible}`]:{backgroundColor:(e.vars||e).palette.action.focus},[`&.${de.disabled}`]:{opacity:(e.vars||e).palette.action.disabledOpacity},transition:e.transitions.create(["color","background-color"],{duration:e.transitions.duration.short}),"&:hover":{backgroundColor:(e.vars||e).palette.action.hover,"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${de.selected}`]:{backgroundColor:(e.vars||e).palette.action.selected,"&:hover":{backgroundColor:e.vars?`rgba(${e.vars.palette.action.selectedChannel} / calc(${e.vars.palette.action.selectedOpacity} + ${e.vars.palette.action.hoverOpacity}))`:Pe(e.palette.action.selected,e.palette.action.selectedOpacity+e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:(e.vars||e).palette.action.selected}},[`&.${de.focusVisible}`]:{backgroundColor:e.vars?`rgba(${e.vars.palette.action.selectedChannel} / calc(${e.vars.palette.action.selectedOpacity} + ${e.vars.palette.action.focusOpacity}))`:Pe(e.palette.action.selected,e.palette.action.selectedOpacity+e.palette.action.focusOpacity)},[`&.${de.disabled}`]:{opacity:1,color:(e.vars||e).palette.action.disabled,backgroundColor:(e.vars||e).palette.action.selected}}},s.size==="small"&&{minWidth:26,height:26,borderRadius:26/2,margin:"0 1px",padding:"0 4px"},s.size==="large"&&{minWidth:40,height:40,borderRadius:40/2,padding:"0 10px",fontSize:e.typography.pxToRem(15)},s.shape==="rounded"&&{borderRadius:(e.vars||e).shape.borderRadius}),({theme:e,ownerState:s})=>re({},s.variant==="text"&&{[`&.${de.selected}`]:re({},s.color!=="standard"&&{color:(e.vars||e).palette[s.color].contrastText,backgroundColor:(e.vars||e).palette[s.color].main,"&:hover":{backgroundColor:(e.vars||e).palette[s.color].dark,"@media (hover: none)":{backgroundColor:(e.vars||e).palette[s.color].main}},[`&.${de.focusVisible}`]:{backgroundColor:(e.vars||e).palette[s.color].dark}},{[`&.${de.disabled}`]:{color:(e.vars||e).palette.action.disabled}})},s.variant==="outlined"&&{border:e.vars?`1px solid rgba(${e.vars.palette.common.onBackgroundChannel} / 0.23)`:`1px solid ${e.palette.mode==="light"?"rgba(0, 0, 0, 0.23)":"rgba(255, 255, 255, 0.23)"}`,[`&.${de.selected}`]:re({},s.color!=="standard"&&{color:(e.vars||e).palette[s.color].main,border:`1px solid ${e.vars?`rgba(${e.vars.palette[s.color].mainChannel} / 0.5)`:Pe(e.palette[s.color].main,.5)}`,backgroundColor:e.vars?`rgba(${e.vars.palette[s.color].mainChannel} / ${e.vars.palette.action.activatedOpacity})`:Pe(e.palette[s.color].main,e.palette.action.activatedOpacity),"&:hover":{backgroundColor:e.vars?`rgba(${e.vars.palette[s.color].mainChannel} / calc(${e.vars.palette.action.activatedOpacity} + ${e.vars.palette.action.focusOpacity}))`:Pe(e.palette[s.color].main,e.palette.action.activatedOpacity+e.palette.action.focusOpacity),"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${de.focusVisible}`]:{backgroundColor:e.vars?`rgba(${e.vars.palette[s.color].mainChannel} / calc(${e.vars.palette.action.activatedOpacity} + ${e.vars.palette.action.focusOpacity}))`:Pe(e.palette[s.color].main,e.palette.action.activatedOpacity+e.palette.action.focusOpacity)}},{[`&.${de.disabled}`]:{borderColor:(e.vars||e).palette.action.disabledBackground,color:(e.vars||e).palette.action.disabled}})})),Cr=p("div",{name:"MuiPaginationItem",slot:"Icon",overridesResolver:(e,s)=>s.icon})(({theme:e,ownerState:s})=>re({fontSize:e.typography.pxToRem(20),margin:"0 -8px"},s.size==="small"&&{fontSize:e.typography.pxToRem(18)},s.size==="large"&&{fontSize:e.typography.pxToRem(22)})),wr=f.forwardRef(function(s,n){const a=Bs({props:s,name:"MuiPaginationItem"}),{className:o,color:r="standard",component:c,components:l={},disabled:i=!1,page:d,selected:g=!1,shape:x="circular",size:m="medium",slots:y={},type:j="page",variant:S="text"}=a,h=It(a,jr),u=re({},a,{color:r,disabled:i,selected:g,shape:x,size:m,type:j,variant:S}),w=it(),I=br(u),O=(w.direction==="rtl"?{previous:y.next||l.next||ds,next:y.previous||l.previous||ls,last:y.first||l.first||is,first:y.last||l.last||cs}:{previous:y.previous||l.previous||ls,next:y.next||l.next||ds,first:y.first||l.first||is,last:y.last||l.last||cs})[j];return j==="start-ellipsis"||j==="end-ellipsis"?t.jsx(Sr,{ref:n,ownerState:u,className:At(I.root,o),children:"…"}):t.jsxs(vr,re({ref:n,ownerState:u,component:c,disabled:i,className:At(I.root,o)},h,{children:[j==="page"&&d,O?t.jsx(Cr,{as:O,ownerState:u,className:I.icon}):null]}))}),Tr=["boundaryCount","className","color","count","defaultPage","disabled","getItemAriaLabel","hideNextButton","hidePrevButton","onChange","page","renderItem","shape","showFirstButton","showLastButton","siblingCount","size","variant"],Er=e=>{const{classes:s,variant:n}=e;return _s({root:["root",n],ul:["ul"]},xr,s)},Rr=p("nav",{name:"MuiPagination",slot:"Root",overridesResolver:(e,s)=>{const{ownerState:n}=e;return[s.root,s[n.variant]]}})({}),Ar=p("ul",{name:"MuiPagination",slot:"Ul",overridesResolver:(e,s)=>s.ul})({display:"flex",flexWrap:"wrap",alignItems:"center",padding:0,margin:0,listStyle:"none"});function Dr(e,s,n){return e==="page"?`${n?"":"Go to "}page ${s}`:`Go to ${e} page`}const kr=f.forwardRef(function(s,n){const a=Bs({props:s,name:"MuiPagination"}),{boundaryCount:o=1,className:r,color:c="standard",count:l=1,defaultPage:i=1,disabled:d=!1,getItemAriaLabel:g=Dr,hideNextButton:x=!1,hidePrevButton:m=!1,renderItem:y=R=>t.jsx(wr,re({},R)),shape:j="circular",showFirstButton:S=!1,showLastButton:h=!1,siblingCount:u=1,size:w="medium",variant:I="text"}=a,B=It(a,Tr),{items:O}=yr(re({},a,{componentName:"Pagination"})),$=re({},a,{boundaryCount:o,color:c,count:l,defaultPage:i,disabled:d,getItemAriaLabel:g,hideNextButton:x,hidePrevButton:m,renderItem:y,shape:j,showFirstButton:S,showLastButton:h,siblingCount:u,size:w,variant:I}),P=Er($);return t.jsx(Rr,re({"aria-label":"pagination navigation",className:At(P.root,r),ownerState:$,ref:n},B,{children:t.jsx(Ar,{className:P.ul,ownerState:$,children:O.map((R,E)=>t.jsx("li",{children:y(re({},R,{color:c,"aria-label":g(R.type,R.page,R.selected),shape:j,size:w,variant:I}))},E))})}))}),$r=()=>{const e=k("projectId"),s=k("featureId"),{feature:n}=W(e,s);return n.name?t.jsx($n,{title:"Event log",feature:s}):null},Ue=p("div")({display:"flex",flexDirection:"row",justifyContent:"space-between",alignItems:"center"}),De=p("div")(({theme:e})=>({justifyContent:"center",paddingTop:e.spacing(.75),...Fn})),He=p("span")(({theme:e})=>({color:e.palette.text.secondary,marginRight:e.spacing(1)})),Nt=p(oe)(({theme:e})=>({maxWidth:"100%",textDecoration:"none","&:hover, &:focus":{textDecoration:"underline"}})),Fr=()=>t.jsxs(he,{severity:"warning",children:["Remember to update your Unleash client! Feature dependencies require new SDK versions. Read more about ",t.jsx(Ir,{}),"."]}),Ir=()=>t.jsx("a",{href:"https://docs.getunleash.io/reference/dependent-features#client-sdk-support",target:"_blank",rel:"noreferrer",children:"Client SDK support for feature dependencies"}),Pr=p(In)(({theme:e})=>({marginTop:e.spacing(2),marginBottom:e.spacing(1.5)})),Br=({project:e,parent:s,onSelect:n,selectedValues:a})=>{const{parentVariantOptions:o}=Pn(e,s),r=t.jsx(_n,{fontSize:"small"}),c=t.jsx(On,{fontSize:"small"});return t.jsx(Pr,{multiple:!0,id:"parent-variant-options",options:o,disableCloseOnSelect:!0,renderOption:(l,i,{selected:d})=>t.jsxs("li",{...l,children:[t.jsx(Os,{icon:r,checkedIcon:c,style:{marginRight:8},checked:d}),i]}),renderInput:l=>t.jsx(Bn,{...l,placeholder:"Select values"}),fullWidth:!0,value:a,onChange:(l,i)=>{n(i)}})},me={key:"none (remove dependency)",label:"none (remove dependency)"},dn=p(Ls)(({theme:e})=>({marginTop:e.spacing(2),marginBottom:e.spacing(1.5)})),_r=({onSelect:e,parentValue:s})=>t.jsx(dn,{fullWidth:!0,options:[{key:"enabled",label:"enabled"},{key:"enabled_with_variants",label:"enabled with variants"},{key:"disabled",label:"disabled"}],value:s.status,onChange:e}),un=e=>{const{makeRequest:s,createRequest:n,errors:a,loading:o}=Ln({propagateErrors:!0}),r=async(d,g)=>{const x=n(`/api/admin/projects/${e}/features/${d}/dependencies`,{method:"POST",body:JSON.stringify(g)});await s(x.caller,x.id)},c=async(d,g)=>{const x=n(`/api/admin/projects/${e}/features/${d}/dependencies/${g}`,{method:"DELETE"});await s(x.caller,x.id)},l=async d=>{const g=n(`/api/admin/projects/${e}/features/${d}/dependencies`,{method:"DELETE"});await s(g.caller,g.id)},i=[n,s,G,e];return{addDependency:f.useCallback(r,i),removeDependency:f.useCallback(c,i),removeDependencies:f.useCallback(l,i),errors:a,loading:o}},Or=(e,s,n,a,o)=>{const{trackEvent:r}=Te(),{addChange:c}=Ee(),{refetch:l}=be(e),{setToastData:i,setToastApiError:d}=ne(),{refetchFeature:g}=W(e,s),x=Pt(e)(),{isChangeRequestConfiguredInAnyEnv:m}=ce(e),{addDependency:y,removeDependencies:j}=un(e),S=async h=>{if(!x){console.error("No change request environment");return}h==="addDependency"&&(await c(e,x,[{action:h,feature:s,payload:{feature:n,enabled:a.status!=="disabled",variants:a.status==="enabled_with_variants"?a.variants:[]}}]),r("dependent_features",{props:{eventType:"dependency added"}})),h==="deleteDependency"&&await c(e,x,[{action:h,feature:s,payload:void 0}]),l(),i({text:h==="addDependency"?`${s} will depend on ${n}`:`${s} dependency will be removed`,type:"success",title:"Change added to a draft"})};return async()=>{try{if(m()){const h=n===me.key?"deleteDependency":"addDependency";await S(h),r("dependent_features",{props:{eventType:h==="addDependency"?"add dependency added to change request":"delete dependency added to change request"}})}else n===me.key?(await j(s),r("dependent_features",{props:{eventType:"dependency removed"}}),i({title:"Dependency removed",type:"success"})):(await y(s,{feature:n,enabled:a.status!=="disabled",variants:a.status==="enabled_with_variants"?a.variants:[]}),r("dependent_features",{props:{eventType:"dependency added"}}),i({title:"Dependency added",type:"success"}))}catch(h){d(G(h))}g(),o()}},Lr=({project:e,featureId:s,parent:n,onSelect:a})=>{const{parentOptions:o}=Mn(e,s),r=o?[me,...o.map(c=>({key:c,label:c}))]:[me];return t.jsx(dn,{fullWidth:!0,options:r,value:n,onChange:a})},Mr=({project:e,featureId:s,parentDependency:n,showDependencyDialogue:a,onClose:o})=>{const[r,c]=f.useState((n==null?void 0:n.feature)||me.key),l=()=>{var u;return n?(u=n.variants)!=null&&u.length?{status:"enabled_with_variants",variants:n.variants}:n.enabled===!1?{status:"disabled"}:{status:"enabled"}:{status:"enabled"}},[i,d]=f.useState(l),g=()=>{c((n==null?void 0:n.feature)||me.key),d(l())};f.useEffect(()=>{g()},[JSON.stringify(n)]);const x=Or(e,s,r,i,o),{isChangeRequestConfiguredInAnyEnv:m}=ce(e),y=r!==me.key,j=r!==me.key&&i.status==="enabled_with_variants",S=u=>{(u==="enabled"||u==="disabled")&&d({status:u}),u==="enabled_with_variants"&&d({status:u,variants:[]})},h=u=>{d({status:"enabled_with_variants",variants:u})};return t.jsx(ve,{open:a,title:"Add parent feature dependency",onClose:o,onClick:x,primaryButtonText:m()?"Add change to draft":r===me.key?"Remove":"Add",secondaryButtonText:"Cancel",children:t.jsxs(Q,{children:[t.jsx(Fr,{}),t.jsxs(Q,{sx:{mt:2,mb:4},children:["Your feature will be evaluated only when the selected parent feature is"," ",t.jsx("b",{children:i.status==="disabled"?"disabled":"enabled"})," ","in the same environment."]}),t.jsxs(J,{children:["What ",t.jsx("b",{children:"feature"})," do you want to depend on?"]}),t.jsx(C,{condition:a,show:t.jsx(Lr,{project:e,featureId:s,parent:r,onSelect:u=>{d({status:"enabled"}),c(u)}})}),t.jsx(C,{condition:y,show:t.jsxs(Q,{sx:{mt:2},children:[t.jsxs(J,{children:["What ",t.jsx("b",{children:"feature status"})," do you want to depend on?"]}),t.jsx(_r,{parentValue:i,onSelect:S})]})}),t.jsx(C,{condition:j,show:i.status==="enabled_with_variants"&&t.jsxs(Q,{sx:{mt:2},children:[t.jsxs(J,{children:["What ",t.jsx("b",{children:"variant"})," do you want to depend on?"]}),t.jsx(Br,{parent:r,project:e,selectedValues:i.variants,onSelect:h})]})})]})})},zr=p(Ms)(({theme:e})=>({borderRadius:e.shape.borderRadiusLarge,padding:e.spacing(1,1.5)})),Vr=({feature:e,onEdit:s,onDelete:n})=>{const a=`dependency-${e}-actions`,o=`${a}-menu`,[r,c]=f.useState(null),l=!!r,i=g=>{c(g.currentTarget)},d=()=>{c(null)};return t.jsxs(Q,{children:[t.jsx(ue,{title:"Dependency actions",arrow:!0,describeChild:!0,children:t.jsx(Ge,{sx:{mr:.25},id:a,"aria-controls":l?o:void 0,"aria-haspopup":"true","aria-expanded":l?"true":void 0,onClick:i,type:"button",children:t.jsx(Bt,{})})}),t.jsx(zr,{id:o,anchorEl:r,open:l,onClose:d,transformOrigin:{horizontal:"right",vertical:"top"},anchorOrigin:{horizontal:"right",vertical:"bottom"},disableScrollLock:!0,children:t.jsxs(zn,{"aria-labelledby":a,children:[t.jsxs(Ce,{onClick:()=>{s(),d()},children:[t.jsx(Le,{children:t.jsx(Me,{})}),t.jsx(ke,{children:t.jsx(J,{variant:"body2",children:"Edit"})})]}),t.jsxs(Ce,{onClick:()=>{n(),d()},children:[t.jsx(Le,{children:t.jsx(zs,{})}),t.jsx(ke,{children:t.jsx(J,{variant:"body2",children:"Delete"})})]})]})})]})},pn=({childFeatures:e,project:s})=>t.jsx(Je,{tooltip:t.jsx(t.Fragment,{children:e.map(n=>t.jsx(Nt,{to:`/projects/${s}/features/${n}`,children:t.jsx("div",{children:n})},`${s}-${n}`))}),children:e.length===1?"1 feature":`${e.length} features`}),Nr=({variants:e})=>e.length===1&&e[0].length<20?t.jsx("span",{children:e[0]}):t.jsx(Je,{tooltip:t.jsx(t.Fragment,{children:e.map(s=>t.jsx("div",{children:s}))}),children:e.length===1?"1 variant":`${e.length} variants`}),qr=(e,s)=>{const{trackEvent:n}=Te(),{addChange:a}=Ee(),{refetch:o}=be(e),{setToastData:r,setToastApiError:c}=ne(),{refetchFeature:l}=W(e,s),i=Pt(e)(),{isChangeRequestConfiguredInAnyEnv:d}=ce(e),{removeDependencies:g}=un(e),x=async()=>{if(!i){console.error("No change request environment");return}await a(e,i,[{action:"deleteDependency",feature:s,payload:void 0}])};return async()=>{try{d()?(await x(),n("dependent_features",{props:{eventType:"delete dependency added to change request"}}),r({text:`${s} dependency will be removed`,type:"success",title:"Change added to a draft"}),await o()):(await g(s),n("dependent_features",{props:{eventType:"dependency removed"}}),r({title:"Dependency removed",type:"success"}),await l())}catch(y){c(G(y))}}},Wr=({feature:e})=>{var d,g,x,m,y,j;const[s,n]=f.useState(!1),a=!!e.project&&e.dependencies.length===0&&e.children.length===0,o=!!e.project&&e.dependencies.length>0,r=!!e.project&&e.children.length>0,c=Pt(e.project)(),l=Vs(e.project),i=qr(e.project,e.name);return t.jsxs(t.Fragment,{children:[t.jsx(C,{condition:a,show:t.jsx(Ue,{children:t.jsxs(De,{children:[t.jsx(He,{children:"Dependency:"}),t.jsx(we,{size:"small",permission:Gt,projectId:e.project,variant:"text",onClick:()=>{n(!0)},sx:S=>({marginBottom:S.spacing(.4)}),children:"Add parent feature"})]})})}),t.jsx(C,{condition:o,show:t.jsxs(Ue,{children:[t.jsxs(De,{children:[t.jsx(He,{children:"Dependency:"}),t.jsx(Nt,{to:`/projects/${e.project}/features/${(d=e.dependencies[0])==null?void 0:d.feature}`,children:(g=e.dependencies[0])==null?void 0:g.feature})]}),t.jsx(C,{condition:l(Gt,c),show:t.jsx(Vr,{feature:e.name,onEdit:()=>n(!0),onDelete:i})})]})}),t.jsx(C,{condition:o&&!((x=e.dependencies[0])!=null&&x.enabled),show:t.jsx(Ue,{children:t.jsxs(De,{children:[t.jsx(He,{children:"Dependency value:"}),t.jsx("span",{children:"disabled"})]})})}),t.jsx(C,{condition:o&&!!((y=(m=e.dependencies[0])==null?void 0:m.variants)!=null&&y.length),show:t.jsx(Ue,{children:t.jsxs(De,{children:[t.jsx(He,{children:"Dependency value:"}),t.jsx(Nr,{variants:((j=e.dependencies[0])==null?void 0:j.variants)||[]})]})})}),t.jsx(C,{condition:r,show:t.jsx(Ue,{children:t.jsxs(De,{children:[t.jsx(He,{children:"Children:"}),t.jsx(pn,{childFeatures:e.children,project:e.project})]})})}),t.jsx(C,{condition:!!e.project,show:t.jsx(Mr,{project:e.project,featureId:e.name,parentDependency:e.dependencies[0],onClose:()=>n(!1),showDependencyDialogue:s})})]})},Ur=(e,s={})=>{const n=Ke(`/api/admin/projects/${e}/dependencies`),{data:a,error:o}=Ns(e,!1,n,Hr,s);return{dependenciesExist:a,error:o,loading:!o&&!a}},Hr=async e=>await(await fetch(e).then(Qe("Dependencies exist check"))).json(),Yr=e=>{const{dependenciesExist:s}=Ur(e),{isOss:n}=Xe();return!!e&&!!(!n()||s)},Gr=p("div")(({theme:e})=>({borderRadius:e.shape.borderRadiusLarge,backgroundColor:e.palette.background.paper,display:"flex",flexDirection:"column",maxWidth:"350px",minWidth:"350px",marginRight:e.spacing(2),[e.breakpoints.down(1e3)]:{width:"100%",maxWidth:"none",minWidth:"auto"}})),Jr=p("div")({padding:"1.5rem 1.5rem 0 1.5rem"}),Kr=p("div")({display:"flex",alignItems:"center"}),Qr=p("h2")(({theme:e})=>({fontSize:e.fontSizes.mainHeader,fontWeight:"normal",margin:0})),Xr=p("div")(({theme:e})=>({margin:e.spacing(2,0),display:"flex",flexDirection:"column",fontSize:e.fontSizes.smallBody})),ft=p("div")(({theme:e})=>({})),us=p("div")(({theme:e})=>({display:"flex",justifyContent:"space-between",padding:e.spacing(1,0)})),ps=p("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"space-between"})),gs=p("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"space-between"})),Zr=p("p")({wordBreak:"break-word"}),ei=p(Vn)(({theme:e})=>({margin:e.spacing(1)})),Ye=p("span")(({theme:e})=>({color:e.palette.text.secondary,marginRight:e.spacing(1)})),ti=()=>{var h;const e=k("projectId"),s=k("featureId"),{feature:n,refetchFeature:a}=W(e,s),{project:o,description:r,type:c}=n,l=Re(),[i,d]=f.useState(!1),[g,x]=f.useState(!1),{locationSettings:m}=qs(),y=Yr(n.project),j=(h=n.environments)==null?void 0:h.map(u=>({name:u.name,lastSeenAt:u.lastSeenAt,enabled:u.enabled,yes:u.yes,no:u.no})),S=Hn(c);return t.jsxs(Gr,{children:[t.jsxs(Jr,{children:[t.jsxs(Kr,{"data-loading":!0,children:[t.jsx(S,{sx:u=>({marginRight:u.spacing(2),height:"40px",width:"40px",padding:u.spacing(.5),backgroundColor:u.palette.background.alternative,fill:u.palette.primary.contrastText,borderRadius:`${u.shape.borderRadiusMedium}px`})})," ",t.jsxs(Qr,{children:[_e(c||"")," toggle"]})]}),t.jsxs(Xr,{children:[t.jsxs(us,{"data-loading":!0,children:[t.jsx(Ye,{children:"Project:"}),t.jsx(Q,{sx:{wordBreak:"break-all"},children:o})]}),t.jsx(C,{condition:!!n.lifecycle,show:t.jsxs(us,{"data-loading":!0,children:[t.jsx(Ye,{children:"Lifecycle:"}),t.jsx(Nn,{feature:n,onArchive:()=>d(!0),onComplete:()=>x(!0),onUncomplete:a})]})}),t.jsx(C,{condition:!!r,show:t.jsxs(ft,{"data-loading":!0,sx:{pt:1},children:[t.jsx(Ye,{children:"Description:"}),t.jsxs(ps,{children:[t.jsx(Zr,{children:r}),t.jsx(je,{size:"medium",projectId:e,permission:ze,component:oe,to:`/projects/${e}/features/${s}/settings`,tooltipProps:{title:"Edit description"},children:t.jsx(Me,{})})]})]}),elseShow:t.jsx("div",{"data-loading":!0,children:t.jsxs(ps,{children:["No description."," ",t.jsx(je,{size:"medium",projectId:e,permission:ze,component:oe,to:`/projects/${e}/features/${s}/settings`,tooltipProps:{title:"Edit description"},children:t.jsx(Me,{})})]})})}),t.jsx(ft,{children:t.jsxs(gs,{children:[t.jsxs(De,{children:[t.jsx(Ye,{children:"Created at:"}),t.jsx("span",{children:qn(Ws(n.createdAt),m.locale)})]}),t.jsx(Wn,{featureLastSeen:n.lastSeenAt,environments:j})]})}),t.jsx(C,{condition:!!n.createdBy,show:()=>{var u;return t.jsx(ft,{children:t.jsxs(gs,{children:[t.jsxs(De,{children:[t.jsx(Ye,{children:"Created by:"}),t.jsx("span",{children:(u=n.createdBy)==null?void 0:u.name})]}),t.jsx(ei,{user:n.createdBy})]})})}}),t.jsx(C,{condition:y,show:t.jsx(Wr,{feature:n})})]})]}),t.jsx(C,{condition:n.children.length>0,show:t.jsx(Us,{features:n.children,project:e,isOpen:i,onClose:()=>d(!1)}),elseShow:t.jsx(Hs,{isOpen:i,onConfirm:()=>{l(`/projects/${e}`)},onClose:()=>d(!1),projectId:e,featureIds:[s]})}),t.jsx(C,{condition:!!n.project,show:t.jsx(Un,{isOpen:g,setIsOpen:x,projectId:n.project,featureId:n.name,onComplete:a})})]})},hs={lastHourUsage:[],seenApplications:[]},si=(e,s,n={})=>{const a=async()=>{const g=Ke(`api/admin/client-metrics/features/${s}`),x=await fetch(g,{method:"GET"}).then(Qe("feature metrics"));return x.ok?x.json():hs},o=`${e}_${s}_metrics`,{data:r,error:c}=Yn(o,a,{...n}),[l,i]=f.useState(!c&&!r),d=()=>{Ys(o)};return f.useEffect(()=>{i(!c&&!r)},[r,c]),{metrics:r||hs,error:c,loading:l,refetch:d,FEATURE_METRICS_CACHE_KEY:o}},ni=e=>({yes:0,no:0,environment:e,timestamp:""}),ai=(e,s)=>e.map(n=>s.lastHourUsage.find(o=>o.environment===n.name)||ni(n.name)),xs=Gs.use||(e=>{if(e.status==="pending")throw e;if(e.status==="fulfilled")return e.value;throw e.status==="rejected"?e.reason:(e.status="pending",e.then(s=>{e.status="fulfilled",e.value=s},s=>{e.status="rejected",e.reason=s}),e)}),yt={dedupe:!0},oi=(e,s,n)=>{const{cache:a,compare:o,suspense:r,fallbackData:c,revalidateOnMount:l,revalidateIfStale:i,refreshInterval:d,refreshWhenHidden:g,refreshWhenOffline:x,keepPreviousData:m}=n,[y,j,S,h]=Zn.get(a),[u,w]=ea(e),I=f.useRef(!1),B=f.useRef(!1),O=f.useRef(u),$=f.useRef(s),P=f.useRef(n),R=()=>P.current,E=()=>R().isVisible()&&R().isOnline(),[L,X,te,b]=ta(a,u),T=f.useRef({}).current,D=Y(c)?n.fallback[u]:c,v=(N,q)=>{for(const se in T){const H=se;if(H==="data"){if(!o(N[H],q[H])&&(!Y(N[H])||!o(U,q[H])))return!1}else if(q[H]!==N[H])return!1}return!0},F=f.useMemo(()=>{const N=!u||!s?!1:Y(l)?R().isPaused()||r?!1:Y(i)?!0:i:l,q=ae=>{const fe=ia(ae);return delete fe._k,N?{isValidating:!0,isLoading:!0,...fe}:fe},se=L(),H=b(),ge=q(se),Ie=se===H?ge:q(H);let ee=ge;return[()=>{const ae=q(L());return v(ae,ee)?(ee.data=ae.data,ee.isLoading=ae.isLoading,ee.isValidating=ae.isValidating,ee.error=ae.error,ee):(ee=ae,ae)},()=>Ie]},[a,u]),_=sa.useSyncExternalStore(f.useCallback(N=>te(u,(q,se)=>{v(se,q)||N()}),[a,u]),F[0],F[1]),V=!I.current,z=y[u]&&y[u].length>0,M=_.data,Z=Y(M)?D:M,ie=_.error,A=f.useRef(Z),U=m?Y(M)?A.current:M:Z,pe=z&&!Y(ie)?!1:V&&!Y(l)?l:R().isPaused()?!1:r?Y(Z)?!1:i:Y(Z)||i,K=!!(u&&s&&V&&pe),xe=Y(_.isValidating)?K:_.isValidating,Rn=Y(_.isLoading)?K:_.isLoading,qe=f.useCallback(async N=>{const q=$.current;if(!u||!q||B.current||R().isPaused())return!1;let se,H,ge=!0;const Ie=N||{},ee=!S[u]||!Ie.dedupe,ae=()=>Xt?!B.current&&u===O.current&&I.current:u===O.current,fe={isValidating:!1,isLoading:!1},Ut=()=>{X(fe)},Ht=()=>{const le=S[u];le&&le[1]===H&&delete S[u]},Yt={isValidating:!0};Y(L().data)&&(Yt.isLoading=!0);try{if(ee&&(X(Yt),n.loadingTimeout&&Y(L().data)&&setTimeout(()=>{ge&&ae()&&R().onLoadingSlow(u,n)},n.loadingTimeout),S[u]=[q(w),na()]),[se,H]=S[u],se=await se,ee&&setTimeout(Ht,n.dedupingInterval),!S[u]||S[u][1]!==H)return ee&&ae()&&R().onDiscarded(u),!1;fe.error=Jt;const le=j[u];if(!Y(le)&&(H<=le[0]||H<=le[1]||le[1]===0))return Ut(),ee&&ae()&&R().onDiscarded(u),!1;const ye=L().data;fe.data=o(ye,se)?ye:se,ee&&ae()&&R().onSuccess(se,u,n)}catch(le){Ht();const ye=R(),{shouldRetryOnError:dt}=ye;ye.isPaused()||(fe.error=le,ee&&ae()&&(ye.onError(le,u,ye),(dt===!0||Kt(dt)&&dt(le))&&(!R().revalidateOnFocus||!R().revalidateOnReconnect||E())&&ye.onErrorRetry(le,u,ye,An=>{const ut=y[u];ut&&ut[0]&&ut[0](We.ERROR_REVALIDATE_EVENT,An)},{retryCount:(Ie.retryCount||0)+1,dedupe:!0})))}return ge=!1,Ut(),!0},[u,a]),Wt=f.useCallback((...N)=>aa(a,O.current,...N),[]);if(pt(()=>{$.current=s,P.current=n,Y(M)||(A.current=M)}),pt(()=>{if(!u)return;const N=qe.bind(Jt,yt);let q=0;const H=oa(u,y,(ge,Ie={})=>{if(ge==We.FOCUS_EVENT){const ee=Date.now();R().revalidateOnFocus&&ee>q&&E()&&(q=ee+R().focusThrottleInterval,N())}else if(ge==We.RECONNECT_EVENT)R().revalidateOnReconnect&&E()&&N();else{if(ge==We.MUTATE_EVENT)return qe();if(ge==We.ERROR_REVALIDATE_EVENT)return qe(Ie)}});return B.current=!1,O.current=u,I.current=!0,X({_k:w}),pe&&(Y(Z)||Qt?N():ra(N)),()=>{B.current=!0,H()}},[u]),pt(()=>{let N;function q(){const H=Kt(d)?d(L().data):d;H&&N!==-1&&(N=setTimeout(se,H))}function se(){!L().error&&(g||R().isVisible())&&(x||R().isOnline())?qe(yt).then(q):q()}return q(),()=>{N&&(clearTimeout(N),N=-1)}},[d,g,x,u]),f.useDebugValue(U),r&&Y(Z)&&u){if(!Xt&&Qt)throw new Error("Fallback data is required when using suspense in SSR.");$.current=s,P.current=n,B.current=!1;const N=h[u];if(!Y(N)){const q=Wt(N);xs(q)}if(Y(ie)){const q=qe(yt);Y(U)||(q.status="fulfilled",q.value=!0),xs(q)}else throw ie}return{mutate:Wt,get data(){return T.data=!0,U},get error(){return T.error=!0,ie},get isValidating(){return T.isValidating=!0,xe},get isLoading(){return T.isLoading=!0,Rn}}};Gn.defineProperty(Jn,"defaultValue",{value:Kn});const ri=Xn(oi),ii=e=>(s,n,a)=>(a.revalidateOnFocus=!1,a.revalidateIfStale=!1,a.revalidateOnReconnect=!1,e(s,n,a)),ci=Qn(ri,ii),gn=(e,s)=>{const{refetchFeature:n}=W(e,s),a=ca(e,s),{data:o,error:r,mutate:c}=ci(["useFeatureImmutable",a],()=>la(a)),l=f.useCallback(async()=>{await c(),await n()},[c,n]);return{feature:(o==null?void 0:o.body)||da,refetchFeature:l,loading:!r&&!o,status:o==null?void 0:o.status,error:r}},hn=(e,s,n)=>{const{setToastData:a,setToastApiError:o}=ne(),{addChange:r}=Ee(),{refetch:c}=be(e),[l,i]=f.useState({isOpen:!1}),d=f.useCallback((j,S,h)=>{i({featureName:s,environment:j,fromEnvironment:h,strategy:S,isOpen:!0})},[]),g=f.useCallback((j,S,h)=>{i({featureName:s,environment:j,fromEnvironment:h,strategies:S,isOpen:!0})},[]),x=f.useCallback(()=>{i({isOpen:!1})},[]),m=f.useCallback(async()=>{try{await r(e,l.environment,{feature:l.featureName,action:n,payload:l.strategy}),c(),i({isOpen:!1}),a({type:"success",title:"Changes added to the draft!"})}catch(j){o(G(j)),i({isOpen:!1})}},[r]),y=f.useCallback(async()=>{try{await Promise.all(l.strategies.map(j=>r(e,l.environment,{feature:l.featureName,action:n,payload:j}))),c(),i({isOpen:!1}),a({type:"success",title:"Changes added to the draft!"})}catch(j){o(G(j)),i({isOpen:!1})}},[r]);return{onChangeRequestAddStrategy:d,onChangeRequestAddStrategies:g,onChangeRequestAddStrategyClose:x,onChangeRequestAddStrategyConfirm:m,onChangeRequestAddStrategiesConfirm:y,changeRequestDialogDetails:l}},li=({payload:e,fromEnvironment:s,environment:n})=>t.jsxs(J,{children:[t.jsxs("strong",{children:["Copy ",Ze((e==null?void 0:e.name)||"")," strategy"," "]})," ","from ",s," to ",n]}),di=({environmentId:e,environments:s,strategy:n})=>{const a=k("projectId"),o=k("featureId"),[r,c]=f.useState(null),l=!!r,{addStrategyToFeature:i}=Ne(),{setToastData:d,setToastApiError:g}=ne(),{refetchFeature:x}=W(a,o),{refetchFeature:m}=gn(a,o),y=()=>{c(null)},j=Vs(a),{isChangeRequestConfigured:S}=ce(a),{changeRequestDialogDetails:h,onChangeRequestAddStrategyClose:u,onChangeRequestAddStrategy:w,onChangeRequestAddStrategyConfirm:I}=hn(a,o,"addStrategy"),B=async $=>{const{id:P,...R}={...n,targetEnvironment:$};if(S($)){await w($,R,e);return}try{await i(a,o,$,n),x(),m(),d({title:"Strategy created",text:`Successfully copied a strategy to ${$}`,type:"success"})}catch(E){g(G(E))}y()},O=s.some($=>j($e,$));return t.jsxs("div",{children:[t.jsx(rn,{isOpen:h.isOpen,onClose:u,environment:h==null?void 0:h.environment,onConfirm:I,messageComponent:t.jsx(li,{fromEnvironment:h.fromEnvironment,payload:h.strategy})}),t.jsx(ue,{title:`Copy to environment${O?"":" (Access denied)"}`,children:t.jsx("div",{children:t.jsx(Ge,{size:"large",id:`copy-strategy-icon-menu-${n.id}`,"aria-controls":l?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":l?"true":void 0,onClick:$=>{c($.currentTarget)},"data-testid":ua,disabled:!O,children:t.jsx(pa,{})})})}),t.jsx(et,{id:"basic-menu",anchorEl:r,open:l,onClose:y,MenuListProps:{"aria-labelledby":`copy-strategy-icon-menu-${n.id}`},children:[...s,e].map($=>{const P=j($e,$);return t.jsx(ue,{title:P?"":"You don't have access to add a strategy to this environment",children:t.jsx("div",{children:t.jsxs(Ce,{onClick:()=>B($),disabled:!P,children:[t.jsx(C,{condition:!P,show:t.jsx(Le,{children:t.jsx(Js,{fontSize:"small"})})}),t.jsx(ke,{children:$===e?"Duplicate in current":`Copy to ${$}`})]})})},$)})})]})},ui=()=>t.jsx(he,{severity:"error",children:"Removing the strategy will change which users receive access to the feature."}),pi=p("div")(({theme:e})=>({"> * + *":{marginTop:e.spacing(1)}})),gi=({changeRequests:e,projectId:s})=>e&&e.length>0?t.jsxs(he,{severity:"warning",children:[t.jsx("p",{children:"This strategy is in use by at least one scheduled change request. If you remove it, those change requests can no longer be applied."}),t.jsx("p",{children:"The following scheduled change requests use this strategy:"}),t.jsx("ul",{children:e.map(({id:n,title:a})=>{const o=a?`#${n} (${a})`:`#${n}`;return t.jsx("li",{children:t.jsx(oe,{to:`/projects/${s}/change-requests/${n}`,target:"_blank",rel:"noopener noreferrer",title:`Change request ${n}`,children:o})},n)})})]}):e===void 0?t.jsx(he,{severity:"warning",children:t.jsx("p",{children:"This strategy may be in use by one or more scheduled change requests. If you remove it, those change requests can no longer be applied."})}):null,xn=({scheduledChangeRequestsForStrategy:e})=>t.jsxs(pi,{children:[t.jsx(ui,{}),t.jsx(gi,{projectId:e.projectId,changeRequests:e.changeRequests})]}),hi=({onRemove:e,onClose:s,isOpen:n,scheduledChangeRequestsForStrategy:a})=>t.jsx(ve,{title:"Are you sure you want to delete this strategy?",open:n,primaryButtonText:"Remove strategy",secondaryButtonText:"Cancel",onClick:e,onClose:s,children:t.jsx(xn,{scheduledChangeRequestsForStrategy:a})}),xi=p("div")(({theme:e})=>({marginTop:e.spacing(3),marginBottom:e.spacing(1)})),fi=({onRemove:e,onClose:s,isOpen:n,scheduledChangeRequestsForStrategy:a})=>t.jsxs(ve,{title:"Suggest changes",open:n,primaryButtonText:"Add suggestion to draft",secondaryButtonText:"Cancel",onClick:e,onClose:s,children:[t.jsx(xn,{scheduledChangeRequestsForStrategy:a}),t.jsx(xi,{children:t.jsx(J,{variant:"body2",color:"text.secondary",children:"Your suggestion:"})}),t.jsx(J,{fontWeight:"bold",children:"Remove strategy"})]}),yi=({projectId:e,featureId:s,environmentId:n,strategyId:a})=>{const{deleteStrategyFromFeature:o}=Ne(),{setToastData:r,setToastApiError:c}=ne(),l=Re(),{refetchFeature:i}=W(e,s);return async g=>{try{g.preventDefault(),await o(e,s,n,a),r({title:"Strategy deleted",type:"success"}),i(),l(_t(e,s))}catch(x){c(G(x))}}},mi=({projectId:e,featureId:s,environmentId:n,strategyId:a})=>{const{addChange:o}=Ee(),{refetch:r}=be(e),{setToastData:c,setToastApiError:l}=ne();return async d=>{try{d.preventDefault(),await o(e,n,{action:"deleteStrategy",feature:s,payload:{id:a}}),c({title:"Changes added to the draft!",type:"success"}),await r()}catch(g){l(G(g))}}},ji=({projectId:e,featureId:s,environmentId:n,strategyId:a,isOpen:o,onClose:r})=>{const{isChangeRequestConfigured:c}=ce(e),{changeRequests:l}=Ks(e,a),i={changeRequests:l,projectId:e},d=yi({featureId:s,projectId:e,strategyId:a,environmentId:n}),g=mi({featureId:s,projectId:e,strategyId:a,environmentId:n});return c(n)?t.jsx(fi,{isOpen:o,onClose:()=>r(),onRemove:async x=>{await g(x),r()},scheduledChangeRequestsForStrategy:i}):t.jsx(hi,{isOpen:o,onClose:()=>r(),onRemove:d,scheduledChangeRequestsForStrategy:i})},bi=({projectId:e,environmentId:s,featureId:n,strategy:a})=>{const{refetchFeature:o}=W(e,n),{setStrategyDisabledState:r}=Ne(),{setToastData:c,setToastApiError:l}=ne(),i=d=>async()=>{try{await r(e,n,s,a.id,!d),c({title:`Strategy ${d?"enabled":"disabled"}`,type:"success"}),o()}catch(g){l(G(g))}};return{onDisable:i(!1),onEnable:i(!0)}},Si=({projectId:e,environmentId:s,featureId:n,strategy:a})=>{const{addChange:o}=Ee(),{refetch:r}=be(e),{setToastData:c,setToastApiError:l}=ne(),i=d=>async()=>{try{await o(e,s,{action:"updateStrategy",feature:n,payload:{...a,disabled:!d}}),c({title:"Changes added to the draft!",type:"success"}),await r()}catch(g){l(G(g))}};return{onSuggestDisable:i(!1),onSuggestEnable:i(!0)}},vi=({isOpen:e,onClose:s,...n})=>{var y;const{projectId:a,environmentId:o}=n,{isChangeRequestConfigured:r}=ce(a),c=r(o),{onSuggestEnable:l,onSuggestDisable:i}=Si({...n}),{onEnable:d,onDisable:g}=bi({...n}),x=!!((y=n.strategy)!=null&&y.disabled),m=j=>{j.preventDefault(),c?x?l():i():x?d():g(),s()};return t.jsx(ve,{title:c?`Add ${x?"enable":"disable"} strategy to change request?`:`Are you sure you want to ${x?"enable":"disable"} this strategy?`,open:e,primaryButtonText:c?"Add to draft":`${x?"Enable":"Disable"} strategy`,secondaryButtonText:"Cancel",onClick:m,onClose:()=>s(),children:t.jsx(C,{condition:c,show:t.jsx(ga,{environment:o}),elseShow:t.jsxs(he,{severity:"error",children:[x?"Enabling":"Disabling"," the strategy will change which users receive access to the feature."]})})})},Ci=({projectId:e,strategy:s,featureId:n,environmentId:a})=>{const[o,r]=f.useState(null),[c,l]=f.useState(!1),[i,d]=f.useState(!1),g=!!o,x=S=>{r(S.currentTarget)},m=S=>{r(null),S.stopPropagation()},y=Dt(ha,e,a),j=Dt(xa,e,a);return t.jsxs(t.Fragment,{children:[t.jsx(Q,{sx:{display:"flex",alignItems:"center",textAlign:"center"},children:t.jsx(ue,{title:"More actions",children:t.jsx(Ge,{onClick:x,size:"small","aria-controls":g?"actions-menu":void 0,"aria-haspopup":"true","aria-expanded":g?"true":void 0,"data-testid":fa,children:t.jsx(Bt,{sx:{width:32,height:32}})})})}),t.jsxs(et,{anchorEl:o,id:"actions-menu",open:g,onClose:m,onClick:m,transformOrigin:{horizontal:"right",vertical:"top"},anchorOrigin:{horizontal:"right",vertical:"bottom"},"data-testid":ya,children:[t.jsx(ue,{title:s.disabled?"Enable strategy":"Disable strategy",arrow:!0,placement:"left",children:t.jsxs(Ce,{disabled:!y,onClick:()=>l(!0),children:[t.jsx(Le,{children:s.disabled?t.jsx(ma,{}):t.jsx(ja,{})}),t.jsx(ke,{children:s.disabled?"Enable":"Disable"})]})}),t.jsx(ue,{title:"Remove strategy",arrow:!0,placement:"left",children:t.jsxs(Ce,{disabled:!j,onClick:()=>d(!0),"data-testid":ba,children:[t.jsx(Le,{children:t.jsx(zs,{})}),t.jsx(ke,{children:"Remove"})]})})]}),t.jsx(vi,{isOpen:c,onClose:()=>l(!1),projectId:e,featureId:n,environmentId:a,strategy:s}),t.jsx(ji,{isOpen:i,onClose:()=>d(!1),projectId:e,featureId:n,environmentId:a,strategyId:s.id})]})},wi=({environmentId:e,strategy:s,onDragStart:n,onDragEnd:a,otherEnvironments:o,orderNumber:r,headerChildren:c})=>{const l=k("projectId"),i=k("featureId"),d=Sa(l,i,e,s.id);return t.jsxs(pr,{strategy:s,onDragStart:n,onDragEnd:a,orderNumber:r,actions:t.jsxs(t.Fragment,{children:[c,t.jsx(C,{condition:!!(o&&(o==null?void 0:o.length)>0),show:()=>t.jsx(di,{environmentId:e,environments:o,strategy:s})}),t.jsx(je,{permission:va,environmentId:e,projectId:l,component:oe,to:d,tooltipProps:{title:"Edit strategy"},"data-testid":`STRATEGY_EDIT-${s.name}`,children:t.jsx(Me,{})}),t.jsx(Ci,{projectId:l,featureId:i,environmentId:e,strategy:s})]}),children:[t.jsx(Ca,{strategy:s}),s.variants&&s.variants.length>0&&(s.disabled?t.jsx(Q,{sx:{opacity:"0.5"},children:t.jsx(Zt,{variants:s.variants})}):t.jsx(Zt,{variants:s.variants}))]})},Ti=e=>fetch(e).then(Qe("ChangeRequest")).then(s=>s.json()),fn=(e,s)=>{const{data:n,error:a,mutate:o}=Qs([],Ke(`api/admin/projects/${e}/change-requests/pending/${s}`),Ti);return{changeRequests:n,loading:!a&&!n,refetch:o,error:a}},Ei=(e,s,n,a)=>{const{user:o}=wa(),{changeRequests:r}=fn(e,s),c=[],l=r==null?void 0:r.filter(i=>i.environment===n);return l==null||l.forEach(i=>{const d=i==null?void 0:i.features.find(x=>x.name===s),g=d==null?void 0:d.changes.find(x=>x.action==="updateStrategy"||x.action==="deleteStrategy"?x.payload.id===a:!1);if(g){const x=i.state==="Scheduled",m=!x&&i.createdBy.id===(o==null?void 0:o.id);x&&c.push({changeRequestId:i.id,change:g,isScheduledChange:x}),m&&c.push({changeRequestId:i.id,change:g,isScheduledChange:x})}}),c},yn=({scheduledChangeRequestIds:e})=>{const s=it(),n=tt(s.breakpoints.down("sm")),a=k("projectId");return n?null:t.jsx(Q,{sx:{mr:1.5},children:t.jsx(Je,{tooltip:t.jsx(t.Fragment,{children:e==null?void 0:e.map((o,r)=>t.jsxs(Nt,{to:`/projects/${a}/change-requests/${o}`,children:["Change request #",o]},`${a}-${r}`))}),children:t.jsx(Ve,{color:"warning",children:"Changes Scheduled"})})})},fs=({strategy:e,index:s,environmentName:n,otherEnvironments:a,isDragging:o,onDragStartRef:r,onDragOver:c,onDragEnd:l})=>{const i=k("projectId"),d=k("featureId"),g=f.useRef(null),x=Ei(i,d,n,e.id),{changeRequests:m}=Ks(i,e.id);return t.jsxs(Q,{ref:g,onDragOver:c(g,s),sx:{opacity:o?"0.5":"1"},children:[t.jsx(C,{condition:s>0,show:t.jsx(Ta,{text:"OR"})}),t.jsx(wi,{strategy:e,environmentId:n,otherEnvironments:a,onDragStart:r(g,s),onDragEnd:l,orderNumber:s+1,headerChildren:Ai(x,m)})]},e.id)},Ri=({change:e})=>{const s=it();return tt(s.breakpoints.down("sm"))?null:t.jsxs(Q,{sx:{mr:1.5},children:[t.jsx(C,{condition:(e==null?void 0:e.action)==="updateStrategy",show:t.jsx(Ve,{color:"warning",children:"Modified in draft"})}),t.jsx(C,{condition:(e==null?void 0:e.action)==="deleteStrategy",show:t.jsx(Ve,{color:"error",children:"Deleted in draft"})})]})},Ai=(e,s)=>{const n=[];if((e==null?void 0:e.length)===0&&(s==null?void 0:s.length)===0)return[];const a=e==null?void 0:e.find(({isScheduledChange:o})=>!o);return a&&n.push(t.jsx(Ri,{change:a.change},`draft-change#${a.change.id}`)),s&&s.length>0&&n.push(t.jsx(yn,{scheduledChangeRequestIds:s.map(o=>o.id)},"scheduled-changes")),n},Di=({environmentId:e,environments:s,onClick:n})=>{const a=k("projectId"),[o,r]=f.useState(null),c=!!o,{hasAccess:l}=f.useContext(Ot),i=s.some(d=>l($e,a,d));return t.jsxs("div",{children:[t.jsx(ue,{title:i?"":"(Access denied)",children:t.jsx("div",{children:t.jsx(Fe,{id:`copy-all-strategies-${e}`,"aria-controls":c?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":c?"true":void 0,onClick:d=>{r(d.currentTarget)},disabled:!i,variant:"outlined",children:"Copy from another environment"})})}),t.jsx(et,{id:"basic-menu",anchorEl:o,open:c,onClose:()=>{r(null)},MenuListProps:{"aria-labelledby":`copy-all-strategies-${e}`},children:s.map(d=>{const g=l($e,a,d);return t.jsx(ue,{title:g?"":"You don't have access to add a strategy to this environment",children:t.jsx("div",{children:t.jsxs(Ce,{onClick:()=>n(d),disabled:!g,children:[t.jsx(C,{condition:!g,show:t.jsx(Le,{children:t.jsx(Js,{fontSize:"small"})})}),t.jsxs(ke,{children:["Copy from ",d]})]})})},d)})})]})},ki=p("div")(({theme:e})=>({"&>*:nth-child(n)":{margin:e.spacing(1,0)}})),$i=({payload:e,fromEnvironment:s,environment:n})=>t.jsxs(ki,{children:[t.jsx(J,{children:t.jsx("strong",{children:"Copy: "})}),e==null?void 0:e.map(a=>t.jsxs(J,{children:[t.jsxs("strong",{children:[Ze((a==null?void 0:a.name)||"")," strategy"," "]})," "]})),t.jsxs(J,{children:["from ",s," to ",n]})]}),Fi=(e,s)=>{const n={};return s.parameters.forEach(a=>{n[a.name]=Ii(e,a)}),{name:s.name,constraints:[],parameters:n}},Ii=(e,s)=>s.name==="rollout"||s.name==="percentage"||s.type==="percentage"?"50":s.name==="stickiness"?"":s.name==="groupId"?e:s.type==="boolean"?"false":"",Pi=e=>{var o;const{uiConfig:s}=Xe(),n=((o=s.resourceLimits)==null?void 0:o.featureEnvironmentStrategies)||100,a=e>=n;return{limit:n,limitReached:a}},Bi=()=>{const[e,s]=f.useState(0),n=k("projectId"),a=k("featureId"),o=es("environmentId"),r=es("strategyName"),{strategy:c,defaultStrategyFallback:l}=er(n,o),i=JSON.parse(Ea().get("defaultStrategy")||"false"),{segments:d}=Ra(),g=(d||[]).filter(K=>{var xe;return(xe=c==null?void 0:c.segments)==null?void 0:xe.includes(K.id)}),[x,m]=f.useState({}),[y,j]=f.useState(i?g:[]),{strategyDefinition:S}=Aa(r),h=Da(),{addStrategyToFeature:u,loading:w}=Ne(),{addChange:I}=Ee(),{setToastData:B,setToastApiError:O}=ne(),{uiConfig:$}=Xe(),{unleashUrl:P}=$,R=Re(),{feature:E,refetchFeature:L}=W(n,a),X=E==null?void 0:E.environments.find(K=>K.name===o),te=(X==null?void 0:X.strategies.length)||0,{limit:b,limitReached:T}=Pi(te),D=f.useRef(E),{isChangeRequestConfigured:v}=ce(n),{refetch:F}=be(n),{trackEvent:_}=Te(),{data:V,staleDataNotification:z,forceRefreshCache:M}=ka({unleashGetter:W,params:[n,a],dataKey:"feature",refetchFunctionKey:"refetchFeature",options:{}},E,{afterSubmitAction:L},La);f.useEffect(()=>{D.current.name===""&&E.name&&(M(E),D.current=E)},[E.name]),f.useEffect(()=>{var K;if(i){const xe=c||l;((K=xe.parameters)==null?void 0:K.groupId)===""&&a?m({...xe,parameters:{...xe.parameters,groupId:a}}):m(xe)}else S&&m(Fi(a,S))},[a,JSON.stringify(S),JSON.stringify(c),i]);const Z=async K=>{await u(n,a,o,K),B({title:"Strategy created",type:"success",confetti:!0})},ie=async K=>{await I(n,o,{action:"addStrategy",feature:a,payload:K}),B({title:"Strategy added to draft",type:"success",confetti:!0}),F()},A=$a(x,y),U=async()=>{_("strategyTitle",{props:{hasTitle:!!x.title,on:"create"}});try{v(o)?await ie(A):await Z(A),L(),R(_t(n,a))}catch(K){O(G(K))}};return!V||!V.project?null:t.jsxs(Xs,{modal:!0,description:Fa,documentationLink:Ia,documentationLinkLabel:Pa,disablePadding:!0,formatApiCode:()=>_i(n,a,o,A,P),children:[t.jsx(Ba,{projectId:n,feature:V,strategy:x,setStrategy:m,segments:y,setSegments:j,environmentId:o,onSubmit:U,loading:w,permission:$e,errors:h,isChangeRequest:v(o),tab:e,setTab:s,StrategyVariants:t.jsx(_a,{strategy:x,setStrategy:m,environment:o,projectId:n,editable:!0}),Limit:t.jsx(Oa,{name:"strategies in this environment",shortName:"strategies",currentValue:te,limit:b}),disabled:T}),z]})},mn=(e,s,n,a,o=!1)=>{const r=new URLSearchParams({environmentId:n,strategyName:a,defaultStrategy:String(o)});return`/projects/${e}/features/${s}/strategies/create?${r}`},_i=(e,s,n,a,o)=>{if(!o)return"";const r=`${o}/api/admin/projects/${e}/features/${s}/environments/${n}/strategies`,c=JSON.stringify(a,void 0,2);return`curl --location --request POST '${r}' \\
|
|
2
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
3
|
+
--header 'Content-Type: application/json' \\
|
|
4
|
+
--data-raw '${c}'`},Oi=p("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}})),Li=p("div")(({theme:e})=>({fontSize:e.fontSizes.smallBody})),Mi=p(Lt)(({theme:e})=>({fontWeight:e.fontWeight.bold})),zi=p(oe)(({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}})),mt=({projectId:e,featureId:s,environmentId:n,strategy:a,defaultStrategy:o})=>{const r=Zs(a.name),c=Ze(a.name),{trackEvent:l}=Te(),i=mn(e,s,n,a.name,o),d=()=>{l("strategy-add",{props:{buttonTitle:a.displayName||c}})};return t.jsxs(zi,{to:i,onClick:d,children:[t.jsx(Oi,{children:t.jsx(r,{})}),t.jsxs("div",{children:[t.jsx(Mi,{text:a.displayName||c,maxWidth:"200",maxLength:25}),t.jsx(Li,{children:a.description})]})]})},jt=p(J)(({theme:e})=>({fontSize:e.fontSizes.smallBody,padding:e.spacing(1,2)})),Vi=({projectId:e,featureId:s,environmentId:n})=>{const{strategies:a}=Ma(),o=a.filter(l=>!l.deprecated&&!l.editable),r=a.filter(l=>!l.deprecated&&l.editable),c={name:"flexibleRollout",displayName:"Default strategy",description:"This is the default strategy defined for this environment in the project"};return t.jsxs(Mt,{dense:!0,children:[t.jsxs(t.Fragment,{children:[t.jsxs(jt,{color:"textSecondary",children:[n," environment default strategy"]}),t.jsx(Oe,{children:t.jsx(mt,{projectId:e,featureId:s,environmentId:n,strategy:c,defaultStrategy:!0})},c.name)]}),t.jsx(jt,{color:"textSecondary",children:"Predefined strategy types"}),o.map(l=>t.jsx(Oe,{children:t.jsx(mt,{projectId:e,featureId:s,environmentId:n,strategy:l})},l.name)),t.jsx(C,{condition:r.length>0,show:t.jsxs(t.Fragment,{children:[t.jsx(jt,{color:"textSecondary",children:"Custom strategies"}),r.map(l=>t.jsx(Oe,{children:t.jsx(mt,{projectId:e,featureId:s,environmentId:n,strategy:l})},l.name))]})})]})},Ni=p("div")({flexShrink:0}),qi=p(we)(({theme:e})=>({minWidth:0,width:e.spacing(4.5),alignItems:"center",justifyContent:"center",align:"center",flexDirection:"column",marginLeft:e.spacing(1)})),Ft=({label:e,projectId:s,featureId:n,environmentId:a,variant:o,size:r,matchWidth:c,disableReason:l})=>{const[i,d]=f.useState(),g=Re(),{trackEvent:x}=Te(),m=!!i,y=m?"FeatureStrategyMenuPopover":void 0,j=()=>{d(void 0)},S=w=>{x("strategy-add",{props:{buttonTitle:e}}),g(u)},h=w=>{d(w.currentTarget)},u=mn(s,n,a,"flexibleRollout",!0);return t.jsxs(Ni,{onClick:w=>w.stopPropagation(),children:[t.jsx(we,{permission:$e,projectId:s,environmentId:a,onClick:S,"aria-labelledby":y,variant:o,size:r,sx:{minWidth:c?"282px":"auto"},disabled:!!l,tooltipProps:{title:l||void 0},children:e}),t.jsx(qi,{permission:$e,projectId:s,environmentId:a,onClick:h,"aria-labelledby":y,variant:"outlined",size:r,hideLockIcon:!0,disabled:!!l,tooltipProps:{title:l||"More strategies"},children:t.jsx(Bt,{sx:w=>({margin:w.spacing(.25,0)})})}),t.jsx(Ms,{id:y,open:m,anchorEl:i,onClose:j,onClick:j,PaperProps:{sx:w=>({paddingBottom:w.spacing(1)})},children:t.jsx(Vi,{projectId:s,featureId:n,environmentId:a})})]})},Wi=p("div")(({theme:e})=>({display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",paddingTop:e.spacing(2)})),Ui=p("div")(({theme:e})=>({fontSize:e.fontSizes.bodySize,textAlign:"center",color:e.palette.text.primary,marginBottom:e.spacing(1)})),Hi=p("p")(({theme:e})=>({color:e.palette.text.secondary,fontSize:e.fontSizes.smallBody,textAlign:"center",marginBottom:e.spacing(3),a:{color:e.palette.links}})),Yi=({projectId:e,featureId:s,environmentId:n})=>{const{addStrategyToFeature:a}=Ne(),{setToastData:o,setToastApiError:r}=ne(),{refetchFeature:c}=W(e,s),{refetchFeature:l}=gn(e,s),{feature:i}=W(e,s),d=i==null?void 0:i.environments.filter(w=>w.name!==n&&w.strategies&&w.strategies.length>0),{isChangeRequestConfigured:g}=ce(e),{changeRequestDialogDetails:x,onChangeRequestAddStrategies:m,onChangeRequestAddStrategiesConfirm:y,onChangeRequestAddStrategyClose:j}=hn(e,s,"addStrategy"),S=(w=!1)=>{c(),l(),o({title:w?"Strategies created":"Strategy created",text:w?"Successfully copied from another environment":"Successfully created strategy",type:"success"})},h=async w=>{var B;const I=((B=d==null?void 0:d.find(O=>O.name===w))==null?void 0:B.strategies)||[];if(g(n)){await m(n,I,w);return}try{await Promise.all(I.map(O=>{const{id:$,...P}={...O,environment:n};return a(e,s,n,P)})),S(!0)}catch(O){r(G(O))}},u=d&&d.length>0;return t.jsxs(t.Fragment,{children:[t.jsx(rn,{isOpen:x.isOpen,onClose:j,environment:x==null?void 0:x.environment,onConfirm:y,messageComponent:t.jsx($i,{fromEnvironment:x.fromEnvironment,payload:x.strategies})}),t.jsxs(Wi,{children:[t.jsx(Ui,{children:"You have not defined any strategies yet."}),t.jsxs(Hi,{children:["Strategies added in this environment will only be executed if the SDK is using an"," ",t.jsx(oe,{to:"/admin/api",children:"API key configured"})," for this environment."]}),t.jsxs(Q,{sx:{w:"100%",display:"flex",flexWrap:"wrap",gap:2,alignItems:"center",justifyContent:"center"},children:[t.jsx(Ft,{label:"Add your first strategy",projectId:e,featureId:s,environmentId:n,matchWidth:u}),t.jsx(C,{condition:u,show:t.jsx(Di,{environmentId:n,environments:d.map(w=>w.name),onClick:h})})]})]})]})},Gi=(e,s)=>{const n=[];let a=0;if(e.length<=a)return e;for(;a<e.length;)if(a===0){a+=s;const o=e.slice(0,a);n.push(o)}else{const o=e.slice(a,a+s);a+=s,n.push(o)}return n},Ji=(e,s,n)=>{const[a,o]=f.useState([[]]),[r,c]=f.useState(0);f.useEffect(()=>{const m=Gi(e,s);o(m)},[JSON.stringify(e),s]);const l=()=>{r<a.length-1&&c(x=>x+1)},i=()=>{r>0&&c(x=>x-1)},d=()=>{c(a.length-1)},g=()=>{c(0)};return{page:a[r]||[],pages:a,nextPage:l,prevPage:i,lastPage:d,firstPage:g,setPageIndex:c,pageIndex:r}},Ki=p("div")(({theme:e})=>({width:"100%",position:"relative",paddingBottom:e.spacing(2)})),Qi=p("div")(({theme:e})=>({[e.breakpoints.down(400)]:{padding:e.spacing(1)}})),Xi=({featureEnvironment:e,isDisabled:s,otherEnvironments:n})=>{const a=k("projectId"),o=k("featureId"),{setStrategiesSortOrder:r}=Ne(),{addChange:c}=Ee(),{isChangeRequestConfigured:l}=ce(a),{refetch:i}=be(a),{setToastData:d,setToastApiError:g}=ne(),{refetchFeature:x}=W(a,o),m=en("manyStrategiesPagination"),[y,j]=f.useState((e==null?void 0:e.strategies)||[]),{trackEvent:S}=Te(),[h,u]=f.useState(null);if(f.useEffect(()=>{j((e==null?void 0:e.strategies)||[])},[e==null?void 0:e.strategies]),f.useEffect(()=>{y.length>50&&S("many-strategies")},[]),!e)return null;const w=20,{page:I,pages:B,setPageIndex:O,pageIndex:$}=Ji(y,w),P=async b=>{try{await r(a,o,e.name,b),x(),d({title:"Order of strategies updated",type:"success"})}catch(T){g(G(T))}},R=async b=>{await c(a,e.name,{action:"reorderStrategy",feature:o,payload:b}),d({title:"Strategy execution order added to draft",type:"success",confetti:!0}),i()},E=async b=>{try{l(e.name)?await R(b):await P(b)}catch(T){g(G(T))}},L=(b,T)=>D=>{var v;u({id:y[T].id,index:T,height:((v=b.current)==null?void 0:v.offsetHeight)||0}),b!=null&&b.current&&(D.dataTransfer.effectAllowed="move",D.dataTransfer.setData("text/html",b.current.outerHTML),D.dataTransfer.setDragImage(b.current,20,20))},X=b=>(T,D)=>v=>{if(h===null||T.current===null||h.index===D||b===h.id)return;const{top:F,bottom:_}=T.current.getBoundingClientRect(),V=v.clientY-F<h.height,z=_-v.clientY<h.height,M=h.index>D;if(V&&M||z&&!M){const Z=[...y],ie=Z.splice(h.index,1)[0];Z.splice(D,0,ie),j(Z),u({...h,index:D})}},te=()=>{u(null),E(y.map((b,T)=>({id:b.id,sortOrder:T})))};return t.jsx(Ki,{children:t.jsxs(Qi,{children:[t.jsx(C,{condition:y.length>0&&s,show:()=>t.jsx(he,{severity:"warning",sx:{mb:2},children:"This environment is disabled, which means that none of your strategies are executing."})}),t.jsx(C,{condition:y.length>0,show:t.jsx(C,{condition:y.length<50||!m,show:t.jsx(t.Fragment,{children:y.map((b,T)=>t.jsx(fs,{strategy:b,index:T,environmentName:e.name,otherEnvironments:n,isDragging:(h==null?void 0:h.id)===b.id,onDragStartRef:L,onDragOver:X(b.id),onDragEnd:te},b.id))}),elseShow:t.jsxs(t.Fragment,{children:[t.jsx(he,{severity:"error",children:"We noticed you're using a high number of activation strategies. To ensure a more targeted approach, consider leveraging constraints or segments."}),t.jsx("br",{}),I.map((b,T)=>t.jsx(fs,{strategy:b,index:T+$*w,environmentName:e.name,otherEnvironments:n,isDragging:!1,onDragStartRef:()=>{},onDragOver:()=>{},onDragEnd:()=>{}},b.id)),t.jsx("br",{}),t.jsx(kr,{count:B.length,shape:"rounded",page:$+1,onChange:(b,T)=>O(T-1)})]})}),elseShow:t.jsx(Yi,{projectId:a,featureId:o,environmentId:e.name})})]})})},jn=(e,s)=>e===0?0:Math.round(s/e*100),ot=({value:e,threshold:s=1e6,precision:n=2})=>{let a,o=!1;e<s?a=e.toLocaleString():(a=za(e,{precision:n}),o=!0);const r=t.jsx("span",{"data-testid":Va,children:a});return t.jsx(C,{condition:o,show:t.jsx(ue,{title:e.toLocaleString(),arrow:!0,children:r}),elseShow:r})},Zi=e=>e>48?`${Math.floor(e/24)} days (UTC)`:`${e} hours (local time)`,bt=p("article")(({theme:e})=>({padding:e.spacing(2),background:"transparent",borderRadius:e.spacing(2),textAlign:"center",[e.breakpoints.up("md")]:{padding:e.spacing(4)}})),St=p("h3")(({theme:e})=>({margin:0,fontSize:e.fontSizes.bodySize,fontWeight:e.fontWeight.thin})),vt=p("p")(({theme:e})=>({fontSize:"2.25rem",fontWeight:e.fontWeight.bold,color:e.palette.primary.main})),Ct=p("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})),bn=({totalYes:e,totalNo:s,hoursBack:n,statsSectionId:a,tableSectionId:o})=>{const r=n===1?"in the last hour":`in the last ${Zi(n)}`;return t.jsxs(Se,{container:!0,spacing:2,id:a,"aria-describedby":o,"aria-label":"Feature metrics summary",component:"section",children:[t.jsx(Se,{item:!0,xs:12,sm:4,children:t.jsxs(bt,{children:[t.jsx(St,{children:"Exposure"}),t.jsx(vt,{children:t.jsx(ot,{value:e})}),t.jsxs(Ct,{children:["Total exposure of the feature in the environment"," ",r,"."]})]})}),t.jsx(Se,{item:!0,xs:12,sm:4,children:t.jsxs(bt,{children:[t.jsx(St,{children:"Exposure %"}),t.jsxs(vt,{children:[jn(e+s,e),"%"]}),t.jsxs(Ct,{children:["% total exposure of the feature in the environment"," ",r,"."]})]})}),t.jsx(Se,{item:!0,xs:12,sm:4,children:t.jsxs(bt,{children:[t.jsx(St,{children:"Requests"}),t.jsx(vt,{children:t.jsx(ot,{value:e+s})}),t.jsxs(Ct,{children:["Total requests for the feature in the environment"," ",r,"."]})]})})]})},ec=p("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}})),tc=p("span")(({theme:e})=>({fontSize:e.fontSizes.bodySize,textAlign:"center",padding:"0 1rem",background:e.palette.envAccordion.expanded,position:"relative",maxWidth:"80%",color:e.palette.text.primary})),sc=({children:e})=>t.jsx(ec,{children:t.jsx(tc,{children:e})}),nc=({environmentMetric:e})=>e?t.jsxs(t.Fragment,{children:[t.jsx(sc,{children:"Feature flag exposure"}),t.jsx("div",{children:t.jsx(bn,{totalYes:e.yes,totalNo:e.no,hoursBack:1})})]}):null,ys=p("div")({marginLeft:"auto",display:"flex",alignItems:"center"}),ms=p("div")(({theme:e})=>({marginRight:e.spacing(1),display:"flex",flexDirection:"column"})),js=p("p")(({theme:e})=>({color:e.palette.primary.main,textAlign:"right",fontSize:e.fontSizes.bodySize})),bs=p("p")(({theme:e})=>({maxWidth:"270px",marginTop:e.spacing(.5),fontSize:e.fontSizes.smallBody,textAlign:"right",[e.breakpoints.down(700)]:{display:"none"}})),ac=p(Na)(({theme:e})=>({fill:e.palette.background.elevation2,height:"75px",width:"75px",[e.breakpoints.down(500)]:{display:"none"}})),oc=p("div")(({theme:e})=>({margin:e.spacing(0,2),[e.breakpoints.down(500)]:{display:"none"}})),rc=({environmentMetric:e,disabled:s=!1})=>{const n=qa();if(!e)return null;const a=e.yes+e.no,o=jn(a,e==null?void 0:e.yes);return!e||e.yes===0&&e.no===0?t.jsxs(ys,{children:[t.jsxs(ms,{children:[t.jsxs(js,{style:{color:s?n.palette.text.secondary:void 0},"data-loading":!0,children:[o,"%"]}),t.jsxs(bs,{style:{color:s?n.palette.text.secondary:n.palette.text.primary},"data-loading":!0,children:["The feature has been requested ",t.jsx("b",{children:"0 times"})," and exposed",t.jsx("b",{children:" 0 times"})," in the last hour"]})]}),t.jsx(ac,{style:{transform:"scale(1.1)"},"data-loading":!0})]}):t.jsxs(ys,{children:[t.jsxs(ms,{children:[t.jsxs(js,{children:[o,"%"]}),t.jsxs(bs,{children:["The feature has been requested"," ",t.jsxs("b",{children:[t.jsx(ot,{value:a})," times"]})," ","and exposed"," ",t.jsxs("b",{children:[t.jsx(ot,{value:e.yes})," ","times"]})," ","in the last hour"]})]}),t.jsx(oc,{"data-loading":!0,children:t.jsx(Wa,{percentage:o,size:"3rem"})})]})},wt=({strategy:e})=>{const s=Zs(e.name);return t.jsx(ue,{title:Ze(e.name)+(e.title?` - ${e.title}`:""),arrow:!0,children:t.jsx(ic,{children:t.jsx(s,{})})})},ic=p("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)}})),Ss=p("ul")(()=>({all:"unset",display:"flex",alignItems:"center",alignContent:"center"})),Tt=p("li")(()=>({all:"unset",minWidth:30,textAlign:"center"})),cc=p("div")(({theme:e})=>({display:"flex",flexDirection:"row",alignItems:"center",gap:e.spacing(1)})),st=5,lc=({strategies:e})=>e!=null&&e.length?e.length>st+1?t.jsxs(Ss,{"aria-label":"Feature strategies",children:[e.slice(0,st).map(s=>t.jsx(Tt,{children:t.jsx(wt,{strategy:s})},s.id)),t.jsxs(Je,{tooltip:e.slice(st).map(s=>t.jsx(Tt,{children:t.jsxs(cc,{children:[t.jsx(wt,{strategy:s})," ",Ze(s.name)+(s.title?` - ${s.title}`:"")]})},s.id)),children:["(+",e.length-st,")"]})]}):t.jsx(Ss,{"aria-label":"Feature strategies",children:e.map(s=>t.jsx(Tt,{children:t.jsx(wt,{strategy:s})},s.id))}):null,Sn=()=>{const{value:e,setValue:s}=Ua("global:v1",{});return{value:{...e,hiddenEnvironments:Array.from(e.hiddenEnvironments||[])},setValue:s}},dc=p("div",{shouldForwardProp:e=>e!=="enabled"})(({theme:e,enabled:s})=>({borderRadius:e.shape.borderRadiusLarge,marginBottom:e.spacing(2),backgroundColor:s?e.palette.background.paper:e.palette.envAccordion.disabled})),uc=p(Ha)({boxShadow:"none",background:"none"}),pc=p(Ya)(({theme:e})=>({boxShadow:"none",padding:e.spacing(2,4),[e.breakpoints.down(400)]:{padding:e.spacing(1,2)}})),gc=p(Ga,{shouldForwardProp:e=>e!=="enabled"})(({theme:e})=>({padding:e.spacing(3),background:e.palette.envAccordion.expanded,borderBottomLeftRadius:e.shape.borderRadiusLarge,borderBottomRightRadius:e.shape.borderRadiusLarge,boxShadow:e.boxShadows.accordionFooter,[e.breakpoints.down("md")]:{padding:e.spacing(2,1)}})),hc=p(Xi)(({theme:e})=>({width:"100%",position:"relative",paddingBottom:e.spacing(2)})),xc=p("div",{shouldForwardProp:e=>e!=="enabled"})(({theme:e,enabled:s})=>({display:"flex",justifyContent:"center",flexDirection:"column",color:s?e.palette.text.primary:e.palette.text.secondary})),fc=p("div")(({theme:e})=>({display:"flex",alignItems:"center",[e.breakpoints.down(560)]:{flexDirection:"column",textAlign:"center"}})),yc=p(Ja)(({theme:e})=>({[e.breakpoints.down(560)]:{marginBottom:"0.5rem"}})),mc=p(Lt)(({theme:e})=>({fontSize:e.fontSizes.bodySize,fontWeight:e.typography.fontWeightMedium,[e.breakpoints.down(560)]:{textAlign:"center"}})),jc=p("div")(({theme:e})=>({display:"flex",alignItems:"center",marginTop:e.spacing(2),gap:e.spacing(2),flexWrap:"wrap",[e.breakpoints.down(560)]:{flexDirection:"column"}})),bc=({env:e})=>{var d;const s=k("projectId"),n=k("featureId"),{metrics:a}=si(s,n),{feature:o}=W(s,n),{value:r}=Sn(),l=ai(o==null?void 0:o.environments,a).find(g=>g.environment===e.name),i=o==null?void 0:o.environments.find(g=>g.name===e.name);return t.jsx(C,{condition:!new Set(r.hiddenEnvironments).has(e.name),show:t.jsx(dc,{enabled:e.enabled,children:t.jsxs(uc,{TransitionProps:{mountOnEnter:!0},"data-testid":`${Ka}_${e.name}`,className:`environment-accordion ${e.enabled?"":"accordion-disabled"}`,children:[t.jsxs(pc,{expandIcon:t.jsx(Qa,{titleAccess:"Toggle"}),children:[t.jsxs(xc,{"data-loading":!0,enabled:e.enabled,children:[t.jsxs(fc,{children:[t.jsx(yc,{enabled:e.enabled}),t.jsx("div",{children:t.jsx(mc,{text:e.name,maxWidth:"100",maxLength:15})}),t.jsx(C,{condition:!e.enabled,show:t.jsx(Ve,{color:"neutral",sx:{ml:1},children:"Disabled"})})]}),t.jsxs(jc,{children:[t.jsx(Ft,{label:"Add strategy",projectId:s,featureId:n,environmentId:e.name,variant:"outlined",size:"small"}),t.jsx(lc,{strategies:i==null?void 0:i.strategies})]})]}),t.jsx(rc,{environmentMetric:l,disabled:!e.enabled})]}),t.jsxs(gc,{enabled:e.enabled,children:[t.jsx(hc,{featureEnvironment:i,isDisabled:!e.enabled,otherEnvironments:o==null?void 0:o.environments.map(({name:g})=>g).filter(g=>g!==e.name)}),t.jsx(C,{condition:(((d=i==null?void 0:i.strategies)==null?void 0:d.length)||0)>0,show:t.jsxs(t.Fragment,{children:[t.jsx(Q,{sx:{display:"flex",justifyContent:"center",py:1},children:t.jsx(Ft,{label:"Add strategy",projectId:s,featureId:n,environmentId:e.name})}),t.jsx(nc,{environmentMetric:l})]})})]})]})})})},Sc=()=>{const e=k("projectId"),s=k("featureId"),{feature:n}=W(e,s);if(!n)return null;const{environments:a}=n;return t.jsx(t.Fragment,{children:a==null?void 0:a.map(o=>t.jsx(bc,{env:o},o.name))})},vc=p(Ge,{shouldForwardProp:e=>e!=="visibilityOff"})(({theme:e,visibilityOff:s})=>({marginLeft:"auto",marginRight:e.spacing(-1),color:s?e.palette.action.active:e.palette.action.focus,"&:hover":{color:e.palette.action.active}})),Cc=({environment:e,hiddenEnvironments:s,setHiddenEnvironments:n})=>{const a=()=>{n(e.name)};return t.jsx(vc,{onClick:a,visibilityOff:s.has(e.name),children:t.jsx(C,{condition:s.has(e.name),show:t.jsx(Xa,{}),elseShow:t.jsx(Za,{})})})},wc=p("div")(({theme:e})=>({marginLeft:e.spacing(-1.5),"&:not(:last-of-type)":{marginBottom:e.spacing(2)},display:"flex",alignItems:"center"})),Tc=p("label")(()=>({display:"inline-flex",alignItems:"center",cursor:"pointer"})),Ec=({environment:e,callback:s,children:n,hiddenEnvironments:a,setHiddenEnvironments:o})=>{const r=k("projectId"),c=k("featureId"),{feature:l,refetchFeature:i}=W(r,c),{isChangeRequestConfigured:d}=ce(r),g=t.jsxs(t.Fragment,{children:[" ",t.jsxs("span",{"data-loading":!0,children:[e.enabled?"enabled":"disabled"," in"]})," ",t.jsx(Lt,{text:e.name,maxWidth:"120",maxLength:15})]}),{onToggle:x,modals:m}=tr(r),y=(j,S)=>x(j,{projectId:r,featureId:c,environmentName:e.name,environmentType:e.type,hasStrategies:e.strategies.length>0,hasEnabledStrategies:e.strategies.some(h=>!h.disabled),isChangeRequestEnabled:d(e.name),onRollback:S,onSuccess:()=>{s&&s(),i()}});return t.jsxs(wc,{children:[t.jsxs(Tc,{children:[t.jsx(sr,{featureId:l.name,projectId:r,environmentName:e.name,onToggle:y,value:e.enabled}),n??g]}),t.jsx(Cc,{environment:e,hiddenEnvironments:a,setHiddenEnvironments:o}),m]})},Rc=p("div")(({theme:e})=>({padding:e.spacing(3)})),Ac=p("div")(()=>({display:"flex",flexDirection:"column"})),Dc=p("p")(({theme:e})=>({fontSize:e.fontSizes.bodySize})),kc=p("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,display:"flex",alignItems:"center"})),vs=p("span")(({theme:e})=>({padding:e.spacing(0,.5),"::after":{content:'"-"'}})),$c=p(zt)(()=>({"&:hover, &:focus":{textDecoration:"underline"}})),Fc=({feature:e,header:s,hiddenEnvironments:n,setHiddenEnvironments:a})=>{const o=e.environments.some(r=>{var c;return r.enabled&&((c=r.variants)==null?void 0:c.length)});return t.jsxs(Rc,{"data-testid":"feature-flag-status",children:[s,e.environments.map(r=>{const c=r.strategies.length===1?"1 strategy":`${r.strategies.length} strategies`,l=r.variants??[],i=l.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(vs,{}),t.jsx(ue,{title:"View variants",arrow:!0,describeChild:!0,children:t.jsx($c,{component:oe,to:`/projects/${e.project}/features/${e.name}/variants`,underline:"hover",children:l.length===1?"1 variant":`${l.length} variants`})})]}),d=r.enabled&&l.length===0&&o;return t.jsx(Ec,{environment:r,hiddenEnvironments:n,setHiddenEnvironments:a,children:t.jsxs(Ac,{children:[t.jsx(Dc,{children:r.name}),t.jsxs(kc,{children:[c,i,t.jsx(C,{condition:d,show:t.jsxs(t.Fragment,{children:[t.jsx(vs,{}),t.jsx(nr,{})]})})]})]})},r.name)})]})},vn=(e,s={})=>{const n=async()=>{const d=Ke(`api/admin/features/${e}/tags`);return(await fetch(d,{method:"GET"}).then(Qe("Tags"))).json()},a=`api/admin/features/${e}/tags`,{data:o,error:r}=Ns(!!e,{tags:[]},a,n,s),[c,l]=f.useState(!r&&!o),i=()=>{Ys(a)};return f.useEffect(()=>{l(!r&&!o)},[o,r]),{tags:(o==null?void 0:o.tags)||[],error:r,loading:c,refetch:i}},Ic=p("section")(({theme:e})=>({"& > *":{margin:e.spacing(1,0)}})),Et=e=>e.map(s=>({title:s.value})),Cs=(e,s)=>e.map(n=>({value:n.title,type:s})),Cn=({open:e,setOpen:s})=>{const{tagTypes:n}=eo(),a=k("featureId"),{createTag:o}=ar(),{updateFeatureTags:r,loading:c}=ct(),{tags:l,refetch:i,loading:d}=vn(a),{setToastData:g}=ne(),x=n&&n.length>0?n[0]:{name:"simple",description:"Simple tag to get you started",icon:""},[m,y]=f.useState(x),j=c||d,[S,h]=f.useState(0),{trackEvent:u}=Te(),[w,I]=f.useState(Et(l.filter(v=>v.type===m.name))),{tags:B,refetch:O}=or(m.name),$=f.useMemo(()=>Et(B),[B]);f.useEffect(()=>{l&&m&&I(Et(l.filter(v=>v.type===m.name)))},[JSON.stringify(l),m]);const P=()=>{s(!1),I([])};function R(v,F){const _=v.filter(z=>z.type===m.name).filter(z=>!F.find(M=>z.value===M.value&&z.type===M.type)),V=F.filter(z=>z.type===m.name).filter(z=>!v.find(M=>z.value===M.value&&z.type===M.type));return h(_.length+V.length),{added:_,removed:V}}const E=v=>v.filter(F=>!F.title.startsWith("Create")),L=async(v,F)=>{try{await r(a,{addedTags:v,removedTags:F}),await i()}catch(_){const V=G(_);g({type:"error",title:"Failed to add tag",text:V,confetti:!1})}},X=(v,F)=>{let _="We successfully";return v>0&&(_=_.concat(` added ${v} new tag${v>1?"s":""}`)),v>0&&F>0&&(_=_.concat(" and ")),F>0&&(_=_.concat(` removed ${F} tag${F>1?"s":""}`)),_},te=async v=>{v.preventDefault();const F=Cs(E(w),m.name),{added:_,removed:V}=R(F,l);S>0&&(await L(_,V),S>1&&u("suggest_tags",{props:{eventType:"multiple_tags_added"}}),S>0&&g({type:"success",title:`Updated tag${_.length>1?"s":""} to flag`,text:X(_.length,V.length),confetti:!0})),h(0),I([]),s(!1)},b=(v,F)=>{F!=null&&typeof F!="string"&&(v.preventDefault(),y(F),I([]),h(0))},T=(v,F,_)=>{const V=to(F);_==="selectOption"&&F.forEach((M,Z)=>{if(typeof M!="string"&&M.inputValue&&M.inputValue!==""){const ie={value:M.inputValue,type:m.name};o(ie).then(()=>{u("suggest_tags",{props:{eventType:"tag_created"}}),O()}),M.title=M.inputValue,M.inputValue="",V[Z]=M}});const z=Cs(E(V),m.name);R(z,l),I(V)},D="add-tag-form";return t.jsx(ve,{open:e,secondaryButtonText:"Cancel",primaryButtonText:"Save tags",title:"Update feature flag tags",onClick:te,disabledPrimaryButton:j||S===0,onClose:P,formId:D,children:t.jsxs(t.Fragment,{children:[t.jsx(J,{paragraph:!0,sx:{marginBottom:v=>v.spacing(2.5)},children:"Tags allow you to group features together"}),t.jsx("form",{id:D,onSubmit:te,children:t.jsxs(Ic,{children:[t.jsx(rr,{options:n,value:m,onChange:b}),t.jsx(ir,{options:$,existingTags:l,tagType:m,selectedOptions:w,onChange:T})]})})]})})},Pc=p("div")(({theme:e})=>({display:"flex",flexDirection:"column",padding:e.spacing(3)})),Bc=p("div")(({theme:e})=>({display:"flex",gap:e.spacing(1),flexWrap:"wrap"})),_c=p(tn)(({theme:e})=>({fontSize:e.fontSizes.smallBody})),Oc=p(lt)(({theme:e})=>({margin:e.spacing(3),borderStyle:"dashed"})),Lc=p(Fe)(({theme:e})=>({maxWidth:e.spacing(20),alignSelf:"center"})),Mc=({feature:e,header:s})=>{const{tags:n,refetch:a}=vn(e.name),{deleteTagFromFeature:o}=ct(),[r,c]=f.useState(!1),[l,i]=f.useState(!1),[d,g]=f.useState(),{setToastData:x,setToastApiError:m}=ne(),{hasAccess:y}=f.useContext(Ot),j=y(ze,e.project),S=async()=>{if(d)try{await o(e.name,d.type,d.value),a(),x({type:"success",title:"Tag deleted",text:"Successfully deleted tag"})}catch(h){m(G(h))}};return t.jsxs(Pc,{children:[s,t.jsx(Bc,{children:n.map(h=>{const u=`${h.type}:${h.value}`;return t.jsx(_c,{label:u,deleteIcon:t.jsx(so,{titleAccess:"Remove"}),onDelete:j?()=>{i(!0),g(h)}:void 0},u)})}),t.jsx(C,{condition:j,show:t.jsxs(t.Fragment,{children:[t.jsx(C,{condition:n.length>0,show:t.jsx(Oc,{})}),t.jsx(Lc,{"data-loading":!0,variant:"outlined",startIcon:t.jsx(no,{}),onClick:()=>c(!0),children:"Add new tag"})]})}),t.jsx(Cn,{open:r,setOpen:c}),t.jsxs(ve,{open:l,primaryButtonText:"Delete tag",secondaryButtonText:"Cancel",onClose:()=>{i(!1),g(void 0)},onClick:()=>{i(!1),S(),g(void 0)},title:"Delete tag?",children:["You are about to delete tag:"," ",t.jsxs("strong",{children:[d==null?void 0:d.type,":",d==null?void 0:d.value]})]})]})},zc=p(Q)(({theme:e})=>({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"}})),ws=p("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}})),Vc=({hiddenEnvironments:e,setHiddenEnvironments:s})=>{var c;const n=k("projectId"),a=k("featureId"),{feature:o}=W(n,a),r=((c=o.environments)==null?void 0:c.length)<=3;return t.jsxs(zc,{as:r?ao:Q,children:[t.jsx(Fc,{header:t.jsxs(ws,{"data-loading":!0,children:["Enabled in environments (",o.environments.filter(({enabled:l})=>l).length,")",t.jsx(oo,{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:s}),t.jsx(lt,{}),t.jsx(Mc,{header:t.jsx(ws,{"data-loading":!0,children:"Tags for this feature flag"}),feature:o})]})},Nc=()=>{const{trackEvent:e}=Te(),{value:s,setValue:n}=Sn(),[a,o]=f.useState(new Set(s.hiddenEnvironments));return{hiddenEnvironments:a,setHiddenEnvironments:c=>{n(l=>{const i=new Set(Array.from(l.hiddenEnvironments||[]));return i.has(c)?(i.delete(c),e("hidden_environment",{props:{eventType:"environment unhidden"}})):(i.add(c),e("hidden_environment",{props:{eventType:"environment hidden"}})),o(i),{...s,hiddenEnvironments:[...i]}})}}},qc=p("div")(({theme:e})=>({display:"flex",width:"100%",[e.breakpoints.down(1e3)]:{flexDirection:"column"}})),Wc=p("div")(({theme:e})=>({display:"flex",flexDirection:"column",width:"calc(100% - (350px + 1rem))",[e.breakpoints.down(1e3)]:{width:"100%"}})),Uc=()=>{const e=Re(),s=k("projectId"),n=k("featureId"),a=_t(s,n),{hiddenEnvironments:o,setHiddenEnvironments:r}=Nc(),c=()=>e(a);sn(n);const{setLastViewed:l}=ro();return f.useEffect(()=>{l({featureId:n,projectId:s})},[n]),t.jsxs(qc,{children:[t.jsxs("div",{children:[t.jsx(ti,{}),t.jsx(Vc,{hiddenEnvironments:o,setHiddenEnvironments:r})]}),t.jsx(Wc,{children:t.jsx(Sc,{})}),t.jsxs(nn,{children:[t.jsx(Ae,{path:"strategies/create",element:t.jsx(kt,{label:"Create feature strategy",onClose:c,open:!0,children:t.jsx(Bi,{})})}),t.jsx(Ae,{path:"strategies/edit",element:t.jsx(kt,{label:"Edit feature strategy",onClose:c,open:!0,children:t.jsx(io,{})})})]})]})},Hc=p("div")(({theme:e})=>({display:"flex",alignItems:"center",justifyContent:"space-between","& > div":{display:"flex",alignItems:"center"},marginTop:e.spacing(-3.5),marginBottom:e.spacing(2),backgroundColor:e.palette.background.default,paddingTop:e.spacing(2),paddingBottom:e.spacing(2),position:"sticky",top:0,zIndex:2})),Yc=p(an,{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:s})=>({color:s?e.palette.neutral.border:e.palette.primary.main})),Gc=p("span",{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:s})=>({color:s?e.palette.text.secondary:e.palette.text.primary,marginLeft:e.spacing(1.25),fontSize:e.fontSizes.mainHeader,fontWeight:e.fontWeight.bold})),Jc=p("form")(()=>({display:"flex",flexDirection:"column",height:"100%"})),Kc=p(he)(({theme:e})=>({marginBottom:e.spacing(2)})),Qc=p(he)(({theme:e})=>({marginTop:e.spacing(4)})),Xc=p("div")({display:"flex",flexDirection:"column"}),Zc=p("div")(({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1.5),marginBottom:e.spacing(.5)})),Ts=p("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,marginBottom:e.spacing(1.5)})),el=p(lt)(({theme:e})=>({margin:e.spacing(4,0)})),tl=p(co)(({theme:e})=>({minWidth:e.spacing(20),width:"100%"})),sl=p("div")(({theme:e})=>({marginTop:"auto",paddingTop:e.spacing(4),display:"flex",justifyContent:"flex-end"})),nl=p(Fe)(({theme:e})=>({marginLeft:e.spacing(3)})),al=f.memo(lo),ol=({environment:e,open:s,setOpen:n,getApiPayload:a,getCrPayload:o,onConfirm:r})=>{const c=k("projectId"),l=k("featureId"),{uiConfig:i}=Xe(),{context:d}=uo(),{defaultStickiness:g,loading:x}=po(c),{isChangeRequestConfigured:m}=ce(c),{data:y}=be(c),{changeRequestInReviewOrApproved:j,alert:S}=ho(y),h=(e==null?void 0:e.variants)||[],[u,w]=f.useState([]),[I,B]=f.useState();f.useEffect(()=>{x||w(h.length?h.map(A=>({...A,isValid:!0,new:!1,id:gt()})):[{name:"",weightType:ts.VARIABLE,weight:0,overrides:[],stickiness:(u==null?void 0:u.length)>0?u[0].stickiness:g,new:!0,isValid:!1,id:gt()}])},[s,x]);const O=(A,U)=>{w(pe=>ss(pe.map(K=>K.id===U?A:K),1e3))},$=()=>{const A=gt();w(U=>[...U,{name:"",weightType:ts.VARIABLE,weight:0,overrides:[],stickiness:(U==null?void 0:U.length)>0?U[0].stickiness:g,new:!0,isValid:!1,id:A}]),B(A)};f.useEffect(()=>{if(I){const A=document.getElementById(`variant-name-input-${I}`);A==null||A.scrollIntoView({behavior:"smooth",block:"center"}),A==null||A.focus({preventScroll:!0}),B(void 0)}},[I]);const P=u.map(({new:A,isValid:U,id:pe,...K})=>K),R=a(h,P),E=o(P),L=async A=>{A.preventDefault(),r(P)},X=()=>D?`curl --location --request POST '${i.unleashUrl}/api/admin/projects/${c}/environments/${e==null?void 0:e.name}/change-requests' \\
|
|
5
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
6
|
+
--header 'Content-Type: application/json' \\
|
|
7
|
+
--data-raw '${JSON.stringify(E,void 0,2)}'`:`curl --location --request PATCH '${i.unleashUrl}/api/admin/projects/${c}/features/${l}/environments/${e==null?void 0:e.name}/variants' \\
|
|
8
|
+
--header 'Authorization: INSERT_API_KEY' \\
|
|
9
|
+
--header 'Content-Type: application/json' \\
|
|
10
|
+
--data-raw '${JSON.stringify(R.patch,void 0,2)}'`,te=u.every(({isValid:A})=>A),b=j((e==null?void 0:e.name)||""),T=b?"Add to existing change request":"Add change to draft",D=m((e==null?void 0:e.name)||""),v=f.useMemo(()=>{var A;return x?"":((A=P[0])==null?void 0:A.stickiness)||g},[x,g,JSON.stringify(P[0]??{})]),F=f.useMemo(()=>["default",...d.filter(A=>A.stickiness).map(A=>A.name)],[d]),_=F.map(A=>({key:A,label:A}));F.includes(v)||_.push({key:v,label:v});const V=async A=>{w(U=>U.map(pe=>({...pe,stickiness:A})))},z=A=>{V(A)},[M,Z]=f.useState();f.useEffect(()=>{Z(void 0),R.error&&Z(R.error)},[R.error]);const ie=()=>{V(g),n(!1)};return x||v===""?t.jsx(go,{}):t.jsx(kt,{open:s,onClose:ie,label:"",children:t.jsxs(Xs,{modal:!0,title:"",description:"Variants allow you to return a variant object if the feature flag is considered enabled for the current request.",documentationLink:"https://docs.getunleash.io/reference/feature-toggle-variants",documentationLinkLabel:"Feature flag variants documentation",formatApiCode:X,loading:!s,children:[t.jsxs(Hc,{children:[t.jsxs("div",{children:[t.jsx(Yc,{deprecated:!(e!=null&&e.enabled)}),t.jsx(Gc,{deprecated:!(e!=null&&e.enabled),children:e==null?void 0:e.name})]}),t.jsx(we,{"data-testid":"MODAL_ADD_VARIANT_BUTTON",onClick:$,variant:"outlined",permission:Be,projectId:c,environmentId:e==null?void 0:e.name,children:"Add variant"})]}),t.jsxs(Jc,{onSubmit:L,children:[t.jsx(C,{condition:b,show:S,elseShow:t.jsx(C,{condition:!!D,show:t.jsxs(Kc,{severity:"info",children:[t.jsx("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.jsx(Xc,{children:u.map(A=>t.jsx(al,{variant:A,variants:u,updateVariant:U=>O(U,A.id),removeVariant:()=>w(U=>ss(U.filter(pe=>pe.id!==A.id),1e3)),error:R.error},A.id))}),t.jsx(we,{onClick:$,variant:"outlined",permission:Be,projectId:c,environmentId:e==null?void 0:e.name,children:"Add variant"}),t.jsx(el,{}),t.jsx(C,{condition:u.length>0,show:t.jsxs(t.Fragment,{children:[t.jsx(Zc,{children:t.jsx("p",{children:"Stickiness"})}),t.jsxs(Ts,{children:["By overriding the stickiness you can control which parameter is used to ensure consistent traffic allocation across variants."," ",t.jsx(zt,{href:"https://docs.getunleash.io/reference/feature-toggle-variants",target:"_blank",rel:"noreferrer",children:"Read more"})]}),t.jsx("div",{children:t.jsx(tl,{value:v,label:"",editable:!0,onChange:A=>z(A.target.value)})})]}),elseShow:t.jsx(Ts,{children:"This environment has no variants. Get started by adding a variant."})}),t.jsxs(Qc,{severity:"error",hidden:!M,children:[t.jsx("strong",{children:"Error: "}),M]}),t.jsxs(sl,{children:[t.jsx(Fe,{"data-testid":"DIALOGUE_CONFIRM_ID",type:"submit",variant:"contained",color:"primary",disabled:!te,children:D?T:"Save variants"}),t.jsx(nl,{onClick:ie,children:"Cancel"})]})]})]})})},rl=e=>fetch(e).then(Qe("ChangeRequest")).then(s=>s.json()),il=(e,s)=>{const{data:n,error:a,mutate:o}=Qs([],Ke(`api/admin/projects/${e}/change-requests/scheduled?variantForFlag=${s}`),rl);return{changeRequests:n,loading:!a&&!n,refetch:o,error:a}},cl=(e,s,n)=>{const{changeRequests:a}=il(e,s),o=a==null?void 0:a.filter(r=>r.environment===n);return o?o.map(r=>r.id):[]},ll=p("div")(({theme:e})=>({padding:e.spacing(3),borderRadius:e.shape.borderRadiusLarge,border:`1px solid ${e.palette.divider}`,"&:not(:last-child)":{marginBottom:e.spacing(3)}})),dl=p("div")({display:"flex",alignItems:"center",justifyContent:"space-between","& > div":{display:"flex",alignItems:"center"}}),ul=p(an,{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:s})=>({color:s?e.palette.neutral.border:e.palette.primary.main})),pl=p("span",{shouldForwardProp:e=>e!=="deprecated"})(({theme:e,deprecated:s})=>({color:s?e.palette.text.secondary:e.palette.text.primary,marginLeft:e.spacing(1.25),fontWeight:e.fontWeight.bold})),gl=p("p")(({theme:e})=>({fontSize:e.fontSizes.smallBody,color:e.palette.text.secondary,marginBottom:e.spacing(1.5)})),hl=p("div")(({theme:e})=>({margin:e.spacing(3,0)})),xl=p("div")(({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1.5),marginBottom:e.spacing(.5)})),fl=({environment:e,searchValue:s,children:n})=>{var i;const a=k("projectId"),o=k("featureId"),r=cl(a,o,e.name),c=e.variants??[],l=((i=c[0])==null?void 0:i.stickiness)||"default";return t.jsxs(ll,{children:[t.jsxs(dl,{children:[t.jsxs("div",{children:[t.jsx(ul,{deprecated:!e.enabled}),t.jsx(pl,{deprecated:!e.enabled,children:e.name}),t.jsx(C,{condition:r.length>0,show:t.jsx(xo,{sx:{ml:2},children:t.jsx(yn,{scheduledChangeRequestIds:r})})})]}),n]}),t.jsx(C,{condition:c.length>0,show:t.jsxs(t.Fragment,{children:[t.jsx(hl,{children:t.jsx(fo,{variants:c,searchValue:s})}),t.jsx(C,{condition:c.length>1,show:t.jsxs(t.Fragment,{children:[t.jsxs(xl,{children:[t.jsx("p",{children:"Stickiness:"}),t.jsx(Ve,{children:l})]}),t.jsxs(gl,{children:["By overriding the stickiness you can control which parameter is used to ensure consistent traffic allocation across variants."," ",t.jsx(zt,{href:"https://docs.getunleash.io/reference/feature-toggle-variants",target:"_blank",rel:"noreferrer",children:"Read more"})]})]})})]})})]})},yl=p(ke)(({theme:e})=>({"& span":{fontSize:e.fontSizes.smallBody}})),ml=({environment:e,permission:s,projectId:n,environmentId:a,onCopyVariantsFrom:o,otherEnvsWithVariants:r})=>{const[c,l]=f.useState(null),i=!!c,d=e.variants??[];return t.jsx(C,{condition:r.length>0&&d.length===0,show:t.jsxs(t.Fragment,{children:[t.jsx(we,{onClick:g=>{l(g.currentTarget)},id:`copy-from-menu-${e.name}`,"aria-controls":i?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":i?"true":void 0,variant:"outlined",permission:s,projectId:n,environmentId:a,children:"Copy variants from"}),t.jsx(et,{anchorEl:c,open:i,onClose:()=>l(null),MenuListProps:{"aria-labelledby":`copy-from-menu-${e.name}`},children:r.map(g=>t.jsx(Ce,{onClick:()=>o(g,e),children:t.jsx(yl,{children:`Copy from ${g.name}`})},g.name))})]})})},jl=({permission:e,projectId:s,environment:n,checked:a,onClick:o,...r})=>{const c=Dt(e,s,n);return t.jsxs(Ce,{disabled:!c,onClick:o,...r,children:[t.jsx(Os,{checked:a}),n]})},bl=p(et)(({theme:e})=>({"& > div > ul":{display:"flex",flexDirection:"column",justifyContent:"center","& > li":{padding:e.spacing(0,1)}}})),Sl=p("div")(({theme:e})=>({margin:e.spacing(1,2)})),vl=p(Fe)(({theme:e})=>({marginTop:e.spacing(2)})),Cl=({current:e,environments:s,permission:n,projectId:a,onSubmit:o})=>{var S;const[r,c]=f.useState(null),l=!!r,[i,d]=f.useState([]),g=h=>{d(u=>[...u,h])},x=h=>{d(u=>u.filter(({name:w})=>w!==h.name))},m=h=>{i.includes(h)?x(h):g(h)},y=()=>{d([]),c(null)},j=((S=s.find(h=>h.name===e))==null?void 0:S.variants)??[];return t.jsx(C,{condition:j.length>0&&s.length>1,show:t.jsxs(t.Fragment,{children:[t.jsx(Fe,{onClick:h=>{c(h.currentTarget)},id:`push-to-menu-${e}`,"aria-controls":l?"basic-menu":void 0,"aria-haspopup":"true","aria-expanded":l?"true":void 0,variant:"outlined",children:"Copy to environment"}),t.jsxs(bl,{anchorEl:r,open:l,onClose:()=>c(null),MenuListProps:{"aria-labelledby":`push-to-menu-${e}`},children:[s.filter(h=>h.name!==e).map(h=>t.jsx(jl,{projectId:a,permission:n,environment:h.name,checked:i.includes(h),onClick:()=>m(h)},h.name)),t.jsxs(Sl,{children:[t.jsx(lt,{}),t.jsxs(vl,{variant:"outlined",onClick:()=>{o(i),y()},disabled:i.length===0,children:["Push to selected (",i.length,")"]})]})]})]})})},wl=p("div")(({theme:e})=>({display:"flex",gap:e.spacing(1.5)})),Tl=()=>{const{setToastData:e,setToastApiError:s}=ne(),n=it(),a=tt(n.breakpoints.down("md")),o=k("projectId"),r=k("featureId"),{feature:c,refetchFeature:l,loading:i}=W(o,r),{patchFeatureEnvironmentVariants:d,overrideVariantsInEnvironments:g}=ct(),{refetch:x}=be(o),{addChange:m}=Ee(),{isChangeRequestConfigured:y}=ce(o),[j,S]=f.useState(""),[h,u]=f.useState(),[w,I]=f.useState(!1),B=f.useMemo(()=>{var b;return((b=c==null?void 0:c.environments)==null?void 0:b.map(T=>({...T,crEnabled:y(T.name)})))||[]},[c.environments]),O=(b,T)=>bo(b,T),$=(b,T)=>{try{const D=jo(T,1e3);return{patch:O(b,D)}}catch(D){return{patch:[],error:G(D)}}},P=b=>({feature:r,action:"patchVariant",payload:{variants:b}}),R=async(b,T)=>{if(b.crEnabled)await m(o,b.name,P(T)),x();else{const D=b.variants??[],{patch:v,error:F}=$(D,T);if(v.length===0)return;if(F){e({type:"error",title:F});return}await d(o,r,b.name,v)}l()},E=async(b,T)=>{try{const D=T.filter(({crEnabled:z})=>z),v=T.filter(({crEnabled:z})=>!z);D.length&&await Promise.all(D.map(z=>m(o,z.name,P(b)))),v.length&&await g(o,r,b,v.map(({name:z})=>z)),x(),l();const F=v.length?`Variants pushed to ${v.length===1?v[0].name:`${v.length} environments`}`:"",_=D.length?`Variants push added to ${D.length===1?`${D[0].name} draft`:`${D.length} drafts`}`:"",V=`${F}${F&&_?". ":""}${_}`;e({title:V,type:"success"})}catch(D){s(G(D))}},L=b=>{u(b),I(!0)},X=async b=>{if(h)try{await R(h,b),I(!1),e({title:h.crEnabled?"Variant changes added to draft":"Variants updated successfully",type:"success"})}catch(T){s(G(T))}},te=async(b,T)=>{try{const D=b.variants??[];await R(T,D),e({title:T.crEnabled?"Variants copy added to draft":"Variants copied successfully",type:"success"})}catch(D){s(G(D))}};return t.jsxs(Vt,{isLoading:i,header:t.jsx(yo,{title:"Variants",actions:t.jsx(C,{condition:!a,show:t.jsx(t.Fragment,{children:t.jsx(ns,{initialValue:j,onChange:S})})}),children:t.jsx(C,{condition:a,show:t.jsx(ns,{initialValue:j,onChange:S})})}),children:[t.jsx(mo,{}),B.map(b=>{var D;const T=B.filter(({name:v,variants:F})=>v!==b.name&&(F==null?void 0:F.length));return t.jsx(fl,{environment:b,searchValue:j,children:t.jsxs(wl,{children:[t.jsx(Cl,{current:b.name,environments:B,permission:Be,projectId:o,onSubmit:v=>E(b.variants??[],v)}),t.jsx(ml,{environment:b,permission:Be,projectId:o,environmentId:b.name,onCopyVariantsFrom:te,otherEnvsWithVariants:T}),t.jsx(C,{condition:!!((D=b.variants)!=null&&D.length),show:t.jsx(je,{"data-testid":"EDIT_VARIANTS_BUTTON",onClick:()=>L(b),permission:Be,projectId:o,environmentId:b.name,tooltipProps:{title:"Edit variants"},children:t.jsx(Me,{})}),elseShow:t.jsx(we,{"data-testid":"ADD_VARIANT_BUTTON",onClick:()=>L(b),variant:"outlined",permission:Be,projectId:o,environmentId:b.name,children:"Add variant"})})]})},b.name)}),t.jsx(ol,{environment:h,open:w,setOpen:I,getApiPayload:$,getCrPayload:P,onConfirm:X})]})},El=({value:e,timeZone:s})=>{const{locationSettings:n}=qs(),a=e?e instanceof Date?as(e,n.locale,s):as(Ws(e),n.locale,s):void 0;return t.jsx(at,{lineClamp:1,children:a})};var qt={},Rl=vo;Object.defineProperty(qt,"__esModule",{value:!0});var wn=qt.default=void 0,Al=Rl(So()),Dl=t,kl=(0,Al.default)((0,Dl.jsx)("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");wn=qt.default=kl;const $l=p(J)(({theme:e})=>({fontSize:e.fontSizes.smallerBody})),Fl=({row:e})=>e.original.selectedApplications&&e.original.selectedApplications.length>1?t.jsx(at,{children:t.jsx(Je,{tooltip:t.jsx(t.Fragment,{children:e.original.selectedApplications.map(s=>t.jsx($l,{children:s},s))}),children:e.original.appName})}):t.jsx(at,{children:e.original.appName}),Il=({metrics:e,tableSectionId:s})=>{const n=tt(Co.breakpoints.down("md")),a=f.useMemo(()=>({sortBy:[{id:"timestamp"}]}),[]),{getTableProps:o,getTableBodyProps:r,headerGroups:c,rows:l,prepareRow:i,setHiddenColumns:d}=ht.useTable({initialState:a,columns:Es,data:e,autoResetHiddenColumns:!1,disableSortRemove:!0,defaultColumn:{Cell:at}},ht.useGlobalFilter,ht.useSortBy);return wo([{condition:n,columns:["appName","environment"]}],d,Es),e.length===0?null:t.jsxs(To,{...o(),rowHeight:"standard",id:s,children:[t.jsx(Eo,{headerGroups:c}),t.jsx(Ro,{...r(),children:l.map(g=>(i(g),t.jsx(Ao,{hover:!0,...g.getRowProps(),children:g.cells.map(x=>t.jsx(Do,{...x.getCellProps(),children:x.render("Cell")}))})))})]})},Es=[{id:"Icon",width:"1%",disableSortBy:!0,Cell:()=>t.jsx(ko,{icon:t.jsx(wn,{color:"disabled"})})},{Header:"Time",accessor:"timestamp",Cell:e=>t.jsx(El,{value:e.row.original.timestamp,timeZone:e.row.original.timestamp.includes("23:59")?"UTC":void 0})},{Header:"Application",accessor:"appName",Cell:Fl},{Header:"Environment",accessor:"environment"},{id:"requested",Header:"Requested",accessor:e=>e.yes+e.no},{Header:"Exposed",accessor:"yes"}],Pl=({metrics:e,...s})=>{const n=f.useMemo(()=>e.reduce((o,r)=>o+r.yes,0),[e]),a=f.useMemo(()=>e.reduce((o,r)=>o+r.no,0),[e]);return t.jsx(bn,{...s,totalYes:n,totalNo:a})},Bl=({metrics:e,hoursBack:s})=>{const n=os(),a=os();return e.length===0?t.jsxs(Q,{mt:6,children:[t.jsx(J,{variant:"body1",paragraph:!0,children:"We have yet to receive any metrics for this feature flag in the selected time period."}),t.jsx(J,{variant:"body1",paragraph:!0,children:"Please note that, since the SDKs send metrics on an interval, it might take some time before metrics appear."})]}):t.jsxs(f.Suspense,{fallback:null,children:[t.jsx(Q,{borderTop:1,pt:2,mt:3,borderColor:"divider",children:t.jsx(_l,{metrics:e,hoursBack:s,statsSectionId:n})}),t.jsx(Q,{mt:4,children:t.jsx(Pl,{metrics:e,hoursBack:s,statsSectionId:n,tableSectionId:a})}),t.jsx(Q,{mt:4,children:t.jsx(Il,{metrics:e,tableSectionId:a})})]})},_l=Gs.lazy(()=>$o(()=>import("./FeatureMetricsChart-CZKpaUOH.js"),[])),Ol=p("h2")(({theme:e})=>({margin:0,marginBottom:e.spacing(1.5),fontSize:e.fontSizes.smallBody,fontWeight:e.fontWeight.thin,color:e.palette.text.secondary})),Ll=p("ul")(({theme:e})=>({display:"flex",flexWrap:"wrap",gap:e.spacing(1),listStyleType:"none",padding:0,minHeight:"100%",alignItems:"center",maxHeight:"200px",overflowY:"auto"})),Ml=p("li")(({theme:e})=>({"& > [aria-pressed=true]":{backgroundColor:e.palette.background.alternative,color:e.palette.primary.contrastText},"& > [aria-pressed=true]:hover":{backgroundColor:e.palette.primary.light}})),Rs=({title:e,values:s,selectedValues:n,toggleValue:a,toggleValues:o})=>{const r=i=>()=>{a(i)},c=[...s].every(i=>n.includes(i)),l=f.useMemo(()=>Array.from(s).sort((i,d)=>i.localeCompare(d)),[s]);return t.jsxs("div",{children:[t.jsx(Ol,{children:e}),t.jsxs(Ll,{children:[o&&s.size>1&&t.jsx(Fe,{size:"small",onClick:o,"aria-pressed":c,children:c?"Unselect":"Select all"}),l.map(i=>t.jsx(Ml,{children:t.jsx(tn,{label:i,onClick:r(i),"aria-pressed":n==null?void 0:n.includes(i),sx:Fo})},i))]})]})},zl=()=>{const e=k("projectId"),s=k("featureId"),n=Vl(e,s);sn("Metrics");const a=Array.from(n)[0],[o,r]=Io({environment:xt(Po,a),applications:xt(Bo,[]),hoursBack:xt(_o,$t)}),c=Nl(s,o.hoursBack||$t),l=Array.from(c),i=l[0],{environment:d,hoursBack:g}=o,x=o.applications.filter(u=>u!==null);f.useEffect(()=>{o.applications&&o.applications.length===0&&r({applications:l})},[JSON.stringify(l)]);const m=[...c].every(u=>x.includes(u)),{featureMetrics:y}=cn(s,g),[j,S]=f.useState(y);f.useEffect(()=>{y&&S(y)},[y]);const h=f.useMemo(()=>gr((j==null?void 0:j.filter(u=>d===u.environment).filter(u=>x.includes(u.appName)))||[]).map(u=>({...u,appName:x.length>1?"all selected":u.appName,selectedApplications:x})),[j,d,JSON.stringify(x)]);return h?t.jsxs(Vt,{children:[t.jsxs(Se,{container:!0,component:"header",spacing:2,children:[t.jsx(Se,{item:!0,xs:12,md:4,children:t.jsx(C,{condition:n.size>0,show:t.jsx(Rs,{title:"Environments",values:n,selectedValues:[d],toggleValue:u=>{r({environment:u})}})})}),t.jsx(Se,{item:!0,xs:12,md:6,children:t.jsx(C,{condition:c.size>0,show:t.jsx(Rs,{title:"Applications",values:c,selectedValues:x,toggleValues:()=>{r(m?{applications:[i]}:{applications:[...c]})},toggleValue:u=>{x.includes(u)?r({applications:x.filter(w=>w!==u)}):r({applications:[...x,u]})}})})}),t.jsx(Se,{item:!0,xs:12,md:2,children:t.jsx(hr,{hoursBack:g,setHoursBack:u=>r({hoursBack:u})})})]}),t.jsx(Bl,{metrics:h,hoursBack:g})]}):null},Vl=(e,s)=>{const{feature:n}=W(e,s),a=n.environments.map(o=>o.name);return new Set(a)},Nl=(e,s=$t)=>{const{featureMetrics:n=[]}=cn(e,s),a=n.map(o=>o.appName);return new Set(a)},ql=({enabled:e,value:s,onChange:n,filter:a,...o})=>{const{projects:r}=on();if(!e)return null;const c=i=>({key:i.id,label:i.name,title:i.description||"",sx:{whiteSpace:"pre-line"}});let l;return a?l=r.filter(i=>a(i.id)).map(c):l=r.map(c),s&&!l.find(i=>i.key===s)&&l.push({key:s,label:s}),t.jsx(Ls,{label:"Project",options:l,value:s,onChange:n,...o})},Wl=(e,s)=>{const n=new Set(e),a=new Set(s);return n.size!==a.size?!1:[...n].every(o=>a.has(o))},As=p("div")(({theme:e})=>({display:"grid",gap:e.spacing(2)})),Ds=p(he)(({theme:e})=>({marginBottom:e.spacing(1)})),Ul=p(Mt)({padding:0}),Hl=({projectId:e,open:s,onClose:n,onClick:a,feature:o,changeRequests:r})=>{const c=k("projectId"),{project:l}=Oo(e),{isChangeRequestConfiguredInAnyEnv:i}=ce(e),d=i(),g=f.useMemo(()=>Wl(o.environments.map(y=>y.name),l.environments.map(y=>y.environment)),[o,l]),x=r?r.length>0:!1,m=o.dependencies.length>0||o.children.length>0;return t.jsx(C,{condition:g&&!m&&!x&&!d,show:t.jsx(ve,{open:s,onClose:n,onClick:a,title:"Confirm change project",primaryButtonText:"Change project",secondaryButtonText:"Cancel",children:t.jsxs(As,{children:[t.jsx(Ds,{severity:"success",children:"This feature flag is compatible with the new project."}),t.jsx("p",{children:"Are you sure you want to change the project for this flag?"})]})}),elseShow:t.jsx(ve,{open:s,onClick:n,title:"Confirm change project",primaryButtonText:"Close",children:t.jsxs(As,{children:[t.jsx(Ds,{severity:"warning",children:"Cannot proceed with the move"}),t.jsx(C,{condition:m,show:t.jsxs("p",{children:[t.jsx("span",{children:"The feature flag must not have any dependencies."})," ",t.jsx("br",{}),t.jsx("span",{children:"Please remove feature dependencies first."})]})}),t.jsx(C,{condition:!g,show:t.jsx("p",{children:"In order to move a feature flag between two projects, both projects must have the exact same environments enabled."})}),t.jsx(C,{condition:x,show:t.jsxs(t.Fragment,{children:[t.jsx("p",{children:"The feature flag must not have any pending change requests. This feature flag is currently referenced in the following change requests:"}),t.jsx(Ul,{children:r==null?void 0:r.map(y=>t.jsx(Oe,{children:t.jsxs(oe,{to:`/projects/${c}/change-requests/${y.id}`,children:["View change request"," ",y.id]})},y.id))})]})}),t.jsx(C,{condition:d,show:t.jsxs("p",{children:["You're not allowed to move the feature to project"," ",t.jsx(oe,{to:`/projects/${e}/settings/change-requests`,children:e}),". This project has change requests enabled."]})})]})})})},Yl=()=>{const{hasAccess:e}=f.useContext(Ot),s=k("projectId"),n=k("featureId"),{feature:a,refetchFeature:o}=W(s,n),[r,c]=f.useState(!1),{changeFeatureProject:l}=ct(),{setToastData:i,setToastApiError:d}=ne(),[g,x]=f.useState(s),{projects:m}=on(),y=Re(),{changeRequests:j}=fn(s,n),S=async()=>{try{g&&(await l(s,n,g),o(),i({title:"Project changed",type:"success"}),c(!1),y(`/projects/${g}/features/${n}/settings`,{replace:!0}))}catch(u){d(G(u))}},h=f.useMemo(()=>m.map(u=>u.id).filter(u=>e(rs,u)),[m,e]);return h.length===0?null:t.jsxs(t.Fragment,{children:[t.jsx(ql,{value:g,onChange:x,label:"Project",filter:u=>h.includes(u),enabled:!0}),t.jsx(we,{permission:rs,onClick:()=>c(!0),disabled:g===s,projectId:s,children:"Save"}),t.jsx(Hl,{changeRequests:j,projectId:g,open:r,feature:a,onClose:()=>c(!1),onClick:S})]})},Gl=p("div")({display:"flex",alignItems:"center"}),Jl=p(J)(({theme:e})=>({fontSize:e.fontSizes.mainHeader})),Kl=({projectId:e,featureId:s})=>{var r;const{feature:n}=W(e,s),a=Re(),o=()=>{a(`/projects/${e}/features/${s}/edit`)};return t.jsxs(t.Fragment,{children:[t.jsxs(Gl,{children:[t.jsx(Jl,{children:"Feature information"}),t.jsx(je,{permission:ze,projectId:e,"data-loading":!0,onClick:o,tooltipProps:{title:"Edit"},children:t.jsx(Me,{})})]}),t.jsxs(J,{children:["Name: ",t.jsx("strong",{children:n.name})]}),t.jsxs(J,{children:["Description:"," ",t.jsx("strong",{children:(r=n.description)!=null&&r.length?n.description:"no description"})]}),t.jsxs(J,{children:["Type: ",t.jsx("strong",{children:n.type})]}),t.jsxs(J,{children:["Impression Data:"," ",t.jsx("strong",{children:n.impressionData?"enabled":"disabled"})]})]})},nt="metadata",Rt="project",Ql=p("div")(({theme:e})=>({width:"20%",borderRight:`1px solid ${e.palette.divider}`,padding:e.spacing(2,0),[e.breakpoints.down("md")]:{width:"35%"}})),Xl=p("div")(({theme:e})=>({padding:e.spacing(4),display:"flex",flexDirection:"column",width:400,"& > *":{margin:e.spacing(1,0)}})),Zl=()=>{const e=k("projectId"),s=k("featureId"),[n,a]=f.useState(nt),{uiConfig:o}=Xe();return t.jsx(Vt,{header:"Settings",sx:{padding:0},children:t.jsxs(Q,{sx:{display:"flex"},children:[t.jsx(Ql,{children:t.jsxs(Mt,{children:[t.jsx(Oe,{sx:{padding:"0.75rem 2rem"},button:!0,onClick:()=>a(nt),selected:n===nt,children:"Metadata"},0),t.jsx(Oe,{sx:{padding:"0.75rem 2rem"},button:!0,onClick:()=>a(Rt),selected:n===Rt,hidden:!o.flags.P,children:"Project"},1)]})}),t.jsxs(Xl,{children:[t.jsx(C,{condition:n===nt,show:t.jsx(Kl,{projectId:e,featureId:s})}),t.jsx(C,{condition:n===Rt&&o.flags.P,show:t.jsx(Yl,{})})]})]})})},ed=({stale:e,showActive:s=!0})=>{if(!e&&!s)return null;const n=e?"Feature flag is deprecated.":"Feature flag is active.",a=e?"Stale":"Active";return t.jsx("div",{"data-loading":!0,style:{marginLeft:"8px"},children:t.jsx(Ve,{color:e?"error":"success",title:n,children:a})})},ks=p("strong")({wordBreak:"break-all"}),td=()=>{const e=k("projectId"),s=k("featureId"),{archivedFeatures:n}=Lo(),a=Mo(e,{name:s});return n?n.some(r=>r.name===s)?t.jsxs("p",{children:["The feature ",t.jsx(ks,{children:s})," has been archived. You can find it on the"," ",t.jsx(oe,{to:`/projects/${e}/archive`,children:"project archive page"}),"."]}):t.jsxs("p",{children:["The feature ",t.jsx(ks,{children:s})," does not exist. Would you like to"," ",t.jsx(oe,{to:a,children:"create it"}),"?"]}):null},Tn=p(zo)(({theme:e})=>({width:e.spacing(3),height:e.spacing(3)})),sd=p(Tn)(()=>({marginLeft:0})),En=p("div")(({theme:e})=>({display:"flex",flexFlow:"column",gap:e.spacing(.5),alignItems:"flex-start",height:"min-content",whiteSpace:"nowrap"})),nd=p("div")(({theme:e})=>({display:"flex",flexFlow:"row",gap:e.spacing(1)})),ad=({id:e,name:s,imageUrl:n})=>t.jsxs(En,{children:[t.jsx("span",{children:"Last modified by"}),t.jsxs(nd,{children:[t.jsx(sd,{user:{id:e,name:s,imageUrl:n}}),t.jsx(oe,{to:"logs",children:"view change"})]})]}),od=p(Vo)({flexWrap:"nowrap"}),rd=({collaborators:e})=>t.jsxs(En,{children:[t.jsx("span",{className:"description",children:"Collaborators"}),t.jsx(od,{users:e,avatarLimit:6,AvatarComponent:Tn})]}),id=p("article")(({theme:e})=>({display:"flex",flexDirection:"row",alignItems:"center",justifyContent:"right",[e.breakpoints.down("xl")]:{display:"none"},fontSize:e.typography.body2.fontSize,flex:1})),cd=p("div")(({theme:e})=>({maxWidth:e.spacing(10),minWidth:e.spacing(2),flexGrow:1})),ld=({collaborators:e})=>{if(!e||e.length===0)return null;const s=e[0];return t.jsxs(id,{children:[t.jsx(ad,{...s}),t.jsx(cd,{}),t.jsx(rd,{collaborators:e})]})},dd=p("div")(({theme:e})=>({backgroundColor:e.palette.background.paper,borderRadius:e.shape.borderRadiusLarge,marginBottom:e.spacing(2)})),ud=p("div")(({theme:e})=>({padding:e.spacing(2,4,2,2),display:"flex",justifyContent:"space-between",alignItems:"center",[e.breakpoints.down(500)]:{flexDirection:"column"}})),$s=p("div")({display:"flex",alignItems:"center"}),Fs=p("div")(({theme:e})=>({display:"flex",alignItems:"center",gap:e.spacing(1),marginTop:e.spacing(1),fontSize:e.fontSizes.smallBody,padding:e.spacing(.75,1.5),backgroundColor:e.palette.background.elevation2,borderRadius:`${e.shape.borderRadiusMedium}px`,width:"max-content"})),pd=p("h1")(({theme:e})=>({fontSize:e.fontSizes.mainHeader,fontWeight:"normal",display:"flex",alignItems:"center",wordBreak:"break-all"})),gd=p("div")({flexShrink:0,display:"flex"}),hd=p("div")(({theme:e})=>({width:"100%",backgroundColor:e.palette.divider,height:"1px"})),xd=p("div")(({theme:e})=>({display:"flex",flexFlow:"row nowrap",gap:e.spacing(4),paddingInline:e.spacing(4),justifyContent:"space-between"})),fd=p(No)(({theme:e})=>({textTransform:"none",width:"auto",fontSize:e.fontSizes.bodySize,padding:"0 !important",[e.breakpoints.up("md")]:{minWidth:160}})),yd=p(oe)(()=>({maxWidth:"100%",textDecoration:"none","&:hover, &:focus":{textDecoration:"underline"}})),md=e=>{const s=en("enableLegacyVariants"),n=e.some(a=>{var o;return(o=a.variants)==null?void 0:o.length});return s||n},jd=()=>{var b,T,D;const e=k("projectId"),s=k("featureId"),{favorite:n,unfavorite:a}=qo(),{refetchFeature:o}=W(e,s),{setToastData:r,setToastApiError:c}=ne(),[l,i]=f.useState(!1),[d,g]=f.useState(!1),[x,m]=f.useState(!1),[y,j]=f.useState(!1),S=tt("(max-width:500px)"),{feature:h,loading:u,error:w,status:I}=W(e,s),B=Re(),{pathname:O}=Wo(),$=Uo(u),P=`/projects/${e}/features/${s}`,R=md(h.environments),E=[{title:"Overview",path:`${P}`,name:"overview"},{title:"Metrics",path:`${P}/metrics`,name:"Metrics"},...R?[{title:"Variants",path:`${P}/variants`,name:"Variants"}]:[],{title:"Settings",path:`${P}/settings`,name:"Settings"},{title:"Event log",path:`${P}/logs`,name:"Event log"}],L=E.find(v=>v.path===O)??E[0],X=async()=>{try{h!=null&&h.favorite?await a(e,h.name):await n(e,h.name),o()}catch{c("Something went wrong, could not update favorite")}};if(I===404)return t.jsx(td,{});if(w!==void 0)return t.jsx("div",{ref:$});const te=()=>{try{Zo(h.name),j(!0),setTimeout(()=>{j(!1)},3e3)}catch{r({type:"error",title:"Could not copy feature name"})}};return t.jsxs("div",{ref:$,children:[t.jsxs(dd,{children:[t.jsxs(ud,{children:[t.jsxs($s,{children:[t.jsx(Ho,{onClick:X,isFavorite:h==null?void 0:h.favorite}),t.jsxs("div",{children:[t.jsxs($s,{children:[t.jsxs(pd,{"data-loading":!0,children:[h.name," "]}),t.jsx(ue,{title:y?"Copied!":"Copy name",arrow:!0,children:t.jsx(Ge,{onClick:te,style:{marginLeft:8},children:y?t.jsx(Yo,{style:{fontSize:16}}):t.jsx(Go,{style:{fontSize:16}})})}),t.jsx(C,{condition:!S,show:t.jsx(ed,{stale:h==null?void 0:h.stale})})]}),t.jsx(C,{condition:h.dependencies.length>0,show:t.jsxs(Fs,{children:[t.jsx("b",{children:"Has parent: "}),t.jsx(yd,{to:`/projects/${h.project}/features/${(b=h==null?void 0:h.dependencies[0])==null?void 0:b.feature}`,children:(T=h==null?void 0:h.dependencies[0])==null?void 0:T.feature})]})}),t.jsx(C,{condition:h.children.length>0,show:t.jsxs(Fs,{children:[t.jsx("b",{children:"Has children:"}),t.jsx(pn,{childFeatures:h.children,project:h.project})]})})]})]}),t.jsxs(gd,{children:[t.jsx(je,{permission:Jo,projectId:e,"data-loading":!0,component:oe,to:`/projects/${e}/features/${s}/copy`,tooltipProps:{title:"Clone"},children:t.jsx(cr,{})}),t.jsx(je,{permission:Ko,projectId:e,tooltipProps:{title:"Archive feature flag"},"data-loading":!0,onClick:()=>g(!0),children:t.jsx(lr,{})}),t.jsx(je,{onClick:()=>m(!0),permission:ze,projectId:e,tooltipProps:{title:"Toggle stale state"},"data-loading":!0,children:t.jsx(dr,{})}),t.jsx(je,{onClick:()=>i(!0),permission:ze,projectId:e,tooltipProps:{title:"Add tag"},"data-loading":!0,children:t.jsx(Qo,{})})]})]}),t.jsx(hd,{}),t.jsxs(xd,{children:[t.jsx(Xo,{value:L.path,indicatorColor:"primary",textColor:"primary",children:E.map(v=>t.jsx(fd,{label:v.title,value:v.path,onClick:()=>B(v.path),"data-testid":`TAB-${v.title}`},v.title))}),t.jsx(ld,{collaborators:(D=h.collaborators)==null?void 0:D.users})]})]}),t.jsxs(nn,{children:[t.jsx(Ae,{path:"metrics",element:t.jsx(zl,{})}),t.jsx(Ae,{path:"logs",element:t.jsx($r,{})}),t.jsx(Ae,{path:"variants",element:t.jsx(Tl,{})}),t.jsx(Ae,{path:"settings",element:t.jsx(Zl,{})}),t.jsx(Ae,{path:"*",element:t.jsx(Uc,{})})]}),t.jsx(C,{condition:h.children.length>0,show:t.jsx(Us,{features:h.children,project:e,isOpen:d,onClose:()=>g(!1)}),elseShow:t.jsx(Hs,{isOpen:d,onConfirm:()=>{B(`/projects/${e}`)},onClose:()=>g(!1),projectId:e,featureIds:[s]})}),t.jsx(ur,{isStale:h.stale,isOpen:x,onClose:()=>{m(!1),o()},featureId:s,projectId:e}),t.jsx(Cn,{open:l,setOpen:i})]})},wd=Object.freeze(Object.defineProperty({__proto__:null,default:jd},Symbol.toStringTag,{value:"Module"}));export{wd as F,Zi as d};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{d8 as v,ie as b,bh as C,b as f,r as u,j as i,T as k,s as E,B as M,ig as F,ih as j,ii as B,ij as S,ik as D,il as A,im as P,aL as T,bd as L,aS as N}from"./index-JQ6lMAyk.js";import{f as $,a as H}from"./formatTickValue-DArtcDRb.js";import{B as x}from"./index-DK5jinWf.js";import{b as V,u as w,a as O}from"./aggregateFeatureMetrics-CLK9MToQ.js";const _=e=>{const t={label:"Exposed",hoverBackgroundColor:"#A39EFF",backgroundColor:"#A39EFF",data:g(e,a=>a.yes)},r={label:"Not exposed",hoverBackgroundColor:"#D8D6FF",backgroundColor:"#D8D6FF",data:g(e,a=>a.no)};return{datasets:[t,r]}},g=(e,t)=>e.map(r=>({x:r.timestamp,y:t(r),variants:r.variants||{}})),R=(e,t)=>{if(t===0)return"";const[r,a]=e,s=Math.floor(Number(a)/t*100);return`${a} (${s}%) - ${r}`},y=e=>({plugins:{legend:{position:"bottom",labels:{color:e.palette.text.primary,pointStyle:"circle",usePointStyle:!0,boxHeight:6,padding:15,boxPadding:5}},tooltip:{enabled:!1}},responsive:!0,scales:{x:{stacked:!0,ticks:{color:e.palette.text.secondary},grid:{display:!1}},y:{stacked:!0,ticks:{color:e.palette.text.secondary,maxTicksLimit:5,callback:$},grid:{drawBorder:!1}}},elements:{bar:{borderRadius:5}},interaction:{mode:"index",intersect:!1}}),Y=(e,t,r)=>{const{plugins:a,responsive:s,elements:l,interaction:c,scales:o}=y(e);return{plugins:{legend:a==null?void 0:a.legend,annotation:{clip:!1,annotations:{}},tooltip:{backgroundColor:e.palette.background.paper,titleColor:e.palette.text.primary,bodyColor:e.palette.text.primary,bodySpacing:6,padding:{top:20,bottom:20,left:30,right:30},borderColor:"rgba(0, 0, 0, 0.05)",borderWidth:3,usePointStyle:!0,caretSize:0,boxPadding:10,callbacks:{label:n=>`${n.formattedValue} - ${n.dataset.label}`,afterLabel:n=>{const d=n.dataset.data[n.dataIndex];if(n.dataset.label!=="Exposed"||d.variants===void 0)return"";const{disabled:p,...m}=d.variants;return Object.entries(m).map(h=>R(h,d.y)).join(`
|
|
2
|
+
`)},title:n=>`Time: ${t>48?v(n[0].label,r.locale,"UTC"):b(n[0].label,r.locale)}`}}},responsive:s,scales:{x:{...o?o.x:{},ticks:{color:e.palette.text.secondary,callback(n){const d=this.getLabelForValue(Number(n));return t>48?C(d,r.locale,"UTC"):b(d,r.locale)}}},y:o?o.y:{}},elements:l,interaction:c}},U=[45e6,28e6,28e6,25e6,5e7,27e6,26e6,5e7,32e6,12e6,13e6,31e6,12e6,47e6,29e6,46e6,45e6,28e6,28e6,25e6,5e7,27e6,26e6,5e7,32e6,12e6,13e6,31e6,12e6,47e6],z=[5e6,8e6,3e6,2e6,2e6,5e6,9e6,3e6,7e6,2e6,5e6,8e6,3e6,2e6,2e6,5e6,1e6,3e6,12e6,2e6,1e6,1e6,3e6,2e6,2e6,5e6,1e6,3e6,8e6,2e6],G={labels:Array.from({length:30},(e,t)=>t+1),datasets:[{data:U,label:"yes",backgroundColor:"#BEBEBE",hoverBackgroundColor:"#BEBEBE"},{data:z,label:"no",backgroundColor:"#9A9A9A",hoverBackgroundColor:"#9A9A9A"}]},I=()=>{const e=f(),t=u.useMemo(()=>y(e),[e]);return i.jsxs(i.Fragment,{children:[i.jsx(k,{sx:{mb:4},children:"No feature flag metrics data"}),i.jsx(x,{data:G,options:t,"aria-label":"A placeholder bar chart with a single feature flag exposure metrics"})]})},J=(e,t)=>{const[r,a]=u.useState(null),{feature:s}=T(e,t),l=s.environments.map(o=>({name:o.name,type:o.type})),c=l.find(o=>o.type==="production");return u.useEffect(()=>{c?a(c.name):l.length>0&&a(l[0].name)},[t,JSON.stringify(l)]),{environment:r,setEnvironment:a,activeEnvironments:l}},W=(e,t,r)=>{const{featureMetrics:a=[]}=w(e,r),s=u.useMemo(()=>[...a].sort((p,m)=>p.timestamp.localeCompare(m.timestamp)),[a]),l=u.useMemo(()=>O(s==null?void 0:s.filter(p=>t===p.environment)).map(p=>({...p,appName:"all selected"})),[s,t]),c=u.useMemo(()=>_(l),[l]),o=f(),{locationSettings:n}=L(),d=u.useMemo(()=>Y(o,r,n),[o,r,n]);return{data:c,options:d}},q=({activeEnvironments:e,environment:t,setEnvironment:r})=>i.jsx(N,{name:"feature-environments",id:"feature-environments",options:e.map(a=>({key:a.name,label:a.name})),value:String(t),onChange:r}),K=E(M)(({theme:e})=>({display:"flex",justifyContent:"flex-end",gap:e.spacing(2),mb:e.spacing(6)})),te=({flag:e})=>{const[t,r]=u.useState(48),{environment:a,setEnvironment:s,activeEnvironments:l}=J(e.project,e.name),{data:c,options:o}=W(e.name,a,t),n=c.datasets[0].data.length===0;return i.jsxs(i.Fragment,{children:[i.jsxs(K,{children:[a?i.jsx(q,{environment:a,setEnvironment:s,activeEnvironments:l}):null,i.jsx(V,{hoursBack:t,setHoursBack:r,label:null})]}),n?i.jsx(I,{}):i.jsx(x,{data:c,options:o,"aria-label":"A bar chart with a single feature flag exposure metrics"})]})};F.register(H,j,B,S,D,A,P);export{te as FlagMetricsChart,I as PlaceholderFlagMetricsChart};
|