Module 857544

11,252 characters · in 33645dc6ae61c139.js
Dependencies
Required by (1)
Lazily required by (0)none
Lazily requires (0)none
Source Raw
function(e,t,n){n.d(t,{A:()=>y});var i=n(627968),s=n(64700),l=n(503698),r=n.n(l),a=n(735438),o=n.n(a),d=n(158954),c=n(435371),u=n(397927),m=n(414079),g=n(416052),_=n(148810),x=n(380610),h=n(235986),A=n(544028),p=n(986238),T=n(650583),f=n(851645),S=n(274446),E=n(818050);let b=["discord_web","discord_marketing","discord_developers","discord_ios","discord_android"],C=[{id:"branch",value:"branch",label:"Branch Name"},{id:"id",value:"id",label:"Commit SHA"}];function v(e){return"discord_ios"in e||"discord_android"in e}class N extends s.Component{handleRemoveBuildOverride=()=>{this.props.onBuildOverrideRemoved(this.props.project)};handleOverrideIdChanged=e=>{this.props.onBuildOverrideUpdated(this.props.project,{id:e})};handleOverrideTypeChanged=e=>{this.props.onBuildOverrideUpdated(this.props.project,{type:e,id:""})};render(){let{project:e,overrideType:t,overrideId:n,disabled:s,error:l}=this.props;return(0,i.jsxs)(h.A,{direction:h.A.Direction.VERTICAL,className:r()(f.oS,E.SX,S.N,f.nM),children:[(0,i.jsx)(m.A,{className:r()(f.lL,{[f.zi]:s}),onClick:s?void 0:this.handleRemoveBuildOverride}),(0,i.jsxs)(h.A,{className:E.QB,children:[(0,i.jsx)(h.A.Child,{basis:"50%",children:(0,i.jsx)(u.l6P,{selectionMode:"single",label:"Override Type",options:C,onSelectionChange:this.handleOverrideTypeChanged,value:t,disabled:s})}),(0,i.jsx)(h.A.Child,{wrap:!0,basis:"50%",children:(0,i.jsx)(u.ksK,{label:"branch"===t?"Branch Name":"Commit SHA",value:n,onChange:this.handleOverrideIdChanged,disabled:s})})]}),(0,i.jsxs)(h.A.Child,{children:[null!=l&&""!==l&&(0,i.jsx)(u.Text,{className:f.AS,color:"text-feedback-critical",variant:"text-sm/normal",children:l}),(0,i.jsxs)(u.Text,{variant:"text-sm/normal",className:f.AS,children:["This controls the build that will be served for the ",(0,i.jsx)("code",{children:e})," project."]})]})]})}}class I extends s.Component{state={loading:!0,buildOverrides:{},loadedBuildOverrides:{},errors:{},saving:!1,didSave:!1};async refreshBuildOverrides(){this.setState({loading:!0});let e=await (0,x.bD)();this.setState({loading:!1,buildOverrides:e,loadedBuildOverrides:o().cloneDeep(e),errors:{}})}isDirty(){let{buildOverrides:e,loadedBuildOverrides:t}=this.state;return!o().isEqual(e,t)}componentDidMount(){this.refreshBuildOverrides()}getAvailableProjects(){let{buildOverrides:e}=this.state;if(null==e)return[];let t=Object.keys(e);return o().without(b,...t)}handleAddBuildOverride=e=>{if(null==e)return;let t={...this.state.buildOverrides,[e]:{type:"branch",id:""}};this.setState({buildOverrides:t})};handleBuildOverrideUpdated=(e,t)=>{let{buildOverrides:n}=this.state,i={...null!=n?n[e]:{},...t},s={...this.state.buildOverrides,[e]:i};this.setState({buildOverrides:s})};handleBuildOverrideRemoved=e=>{let t={...this.state.buildOverrides};delete t[e],this.setState({buildOverrides:t})};handleDiscardChanges=()=>{this.setState({buildOverrides:o().cloneDeep(this.state.loadedBuildOverrides),errors:{},didSave:!1})};handleSaveChanges=async()=>{let{buildOverrides:e}=this.state;if(null==e)return;this.setState({saving:!0});let t=await (0,_.Zk)(e);if(200===t.status){let e=t.body;this.setState({buildOverrides:e,loadedBuildOverrides:o().cloneDeep(e),errors:{},didSave:!0,saving:!1})}else if(400===t.status){let e=t.body;this.setState({errors:e,saving:!1,didSave:!1})}else this.setState({saving:!1,didSave:!1})};handleLinkGeneration=()=>{let{buildOverrides:e}=this.state;(0,u.qfG)(t=>(0,i.jsx)(j,{...t,buildOverrides:e}))};renderEmpty(){return(0,i.jsx)(u.ppr,{theme:A.A.theme,className:r()(E.eT,E.SX),children:(0,i.jsx)(u.SGT,{children:"You have no build overrides configured."})})}renderItems(){let{buildOverrides:e,saving:t,errors:n}=this.state;return null==e?null:o().map(e,(e,s)=>(0,i.jsx)(N,{project:s,overrideType:e.type,overrideId:e.id,disabled:t,error:n[s],onBuildOverrideUpdated:this.handleBuildOverrideUpdated,onBuildOverrideRemoved:this.handleBuildOverrideRemoved},s))}renderRefreshButton(){return!this.state.didSave||this.isDirty()?null:(0,i.jsx)(u.Button,{variant:"secondary",text:"Reload App",onClick:()=>location.reload()})}renderLinkButton(){let{buildOverrides:e}=this.state;return null==e||0===Object.keys(e).length?null:(0,i.jsx)(c.m_,{text:"Generate Public Link",children:(0,i.jsx)(u.K0,{variant:"secondary",icon:u.qYV,"aria-label":"Generate Public Link",onClick:this.handleLinkGeneration})})}renderSaveButton(){if(!this.isDirty())return null;let{saving:e,buildOverrides:t}=this.state;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(u.Button,{variant:"critical-primary",text:"Discard Changes",onClick:this.handleDiscardChanges,disabled:e}),(0,i.jsx)(u.Button,{variant:"primary",text:"Save Build Overrides",disabled:v(t??{}),onClick:this.handleSaveChanges,loading:e})]})}render(){let e,{loading:t,saving:n,buildOverrides:s}=this.state;e=t?(0,i.jsx)(u.y$y,{className:E.QX}):null!=s&&0===Object.keys(s).length?this.renderEmpty():this.renderItems();let l=!n&&!t&&this.getAvailableProjects().length>0,r=v(s??{})&&"stable"!==window.GLOBAL_ENV.RELEASE_CHANNEL?(0,i.jsx)(u.Text,{color:"text-feedback-critical",variant:"text-md/normal",children:"Mobile build overrides must be generated using the desktop/web stable client for now!"}):null;return(0,i.jsx)(u.nVY,{children:(0,i.jsxs)(u.BJc,{gap:16,children:[(0,i.jsx)(u.l6P,{selectionMode:"single",label:"Add Build Override",placeholder:"discord_project",description:"Select a project to create a build override for.",layout:"horizontal-responsive",value:void 0,options:this.getAvailableProjects().map(e=>({id:e,label:e,value:e})),onSelectionChange:this.handleAddBuildOverride,disabled:!l}),r,e,(0,i.jsxs)(u.ButtonGroup,{justify:"end",children:[this.renderRefreshButton(),this.renderLinkButton(),this.renderSaveButton()]})]})})}}class j extends s.Component{state={ttlSeconds:3600,releaseChannel:"all",userIds:new Set,userIdEntry:"",userIdEntryError:null,allowedVersions:[],allowedVersionEntry:"",allowedVersionEntryError:null,publicLink:" ",statusText:null,status:0,allowLoggedOut:!1};setUserEntryError=e=>{this.setState({userIdEntryError:e})};setStatusMessage=(()=>{var e=this;return function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;e.setState({statusText:t,status:n})}})();handleUserIDEntry=e=>{if(!/^[\d\s,]*$/.test(e))return this.setUserEntryError("User IDs are numbers!");let t=new Set(e.split(/[,\s]+/).filter(Boolean));this.setState({userIdEntry:e,userIds:t})};setAllowedVersionError=e=>{this.setState({allowedVersionEntryError:e})};handleAllowedVersionEntry=e=>{this.setState({allowedVersionEntry:e})};handleAllowedVersionEnter=e=>{e.key===T.dh.ENTER&&this.handleAddAllowedVersion()};handleAddAllowedVersion=()=>{let{allowedVersions:e,allowedVersionEntry:t}=this.state;return 0===(t=t.trim()).length?this.setAllowedVersionError("Enter a valid version number!"):e.indexOf(t)>=0?this.setAllowedVersionError("You already added that version!"):void this.setState({allowedVersions:[...e,t],allowedVersionEntry:"",allowedVersionEntryError:""})};handleRemoveAllowedVersion=e=>{let{allowedVersions:t}=this.state;t=t.filter(t=>t!==e),this.setState({allowedVersions:t})};handleAllowLoggedOut=e=>{this.setState({allowLoggedOut:e})};handleExpirationChange=e=>{this.setState({ttlSeconds:e})};handleReleaseChannelChange=e=>{this.setState({releaseChannel:e})};handleExperiments=e=>{if(0===e.trim().length)return void this.setState({experimentsError:void 0});try{let t=JSON.parse(e);for(let e in t){if(null==e.match(/^[0-9]{4}\-[0-9]{2}(-|_)[a-z0-9_-]+$/))return void this.setState({experimentsError:`${e} is an invalid experiment name`});if("number"!=typeof t[e])return void this.setState({experimentsError:`${e} has an invalid bucket override`})}}catch(e){this.setState({experimentsError:`Unable to parse experiments ${e.message}`});return}this.setState({experiments:e,experimentsError:void 0})};generatePayload=()=>({overrides:this.props.buildOverrides,meta:{release_channel:"all"===this.state.releaseChannel?null:this.state.releaseChannel,ttl_seconds:this.state.ttlSeconds,user_ids:Array.from(this.state.userIds),allowed_versions:this.isMobile()?this.state.allowedVersions:void 0,allow_logged_out:this.state.allowLoggedOut,experiments:null==this.state.experiments?null:JSON.parse(this.state.experiments)}});handleGenerateLink=async()=>{if(this.isMobile()&&0===this.state.allowedVersions.length)return void this.setAllowedVersionError("You must add at least one allowed version for iOS");this.setStatusMessage(null);let e=this.generatePayload(),t=await (0,_.SB)(e);!1!==t.error?this.setStatusMessage(JSON.stringify(t.error),0):(this.setState({publicLink:t.url.toString()}),0===e.meta.user_ids.length&&this.setStatusMessage("Warning! No users added to the whitelist! This link could be used by anyone to override their build.",1))};isMobile(){return v(this.props.buildOverrides??{})}renderSettingsForm(){let{ttlSeconds:e,releaseChannel:t,userIdEntry:n,userIdEntryError:s,allowedVersions:l,allowedVersionEntry:r,allowedVersionEntryError:a,allowLoggedOut:o,experiments:d,experimentsError:c}=this.state,m=p.fL.find(t=>t.value===e),g=l.map(e=>({id:e,label:e,value:e}));return(0,i.jsxs)(u.BJc,{gap:20,children:[(0,i.jsx)(u.l6P,{selectionMode:"single",label:"Expire After",value:null!=m?m.value:void 0,options:p.fL,onSelectionChange:this.handleExpirationChange}),this.isMobile()?null:(0,i.jsx)(u.l6P,{selectionMode:"single",label:"Release Channel",value:t,options:p.VP,onSelectionChange:this.handleReleaseChannelChange}),this.isMobile()?(0,i.jsxs)(u.BJc,{gap:20,children:[(0,i.jsx)(u.ksK,{label:"Add allowed app version (required)",autoFocus:!0,value:r,onKeyDown:this.handleAllowedVersionEnter,error:a,onChange:this.handleAllowedVersionEntry,placeholder:"Example: 34",trailing:{icon:u.j96,onClick:this.handleAddAllowedVersion,"aria-label":"Add"}}),(0,i.jsx)(u.l6P,{selectionMode:"single",label:"Remove allowed app version",value:void 0,options:g,onSelectionChange:this.handleRemoveAllowedVersion,disabled:0===l.length})]}):null,this.isMobile()?null:(0,i.jsx)(u.fs1,{label:"Limit to User IDs (optional)",helperText:"User IDs can be separated by whitespace or commas.",value:n,error:s,onBlur:()=>this.setUserEntryError(""),onChange:this.handleUserIDEntry}),(0,i.jsx)(u.fs1,{label:"Client Experiment Override",description:"Locally override the given experiments to the given bucket. This ONLY applies locally and WILL NOT affect the server. When the user clears build override, the experiment override is removed as well.",value:d,error:c,onChange:this.handleExperiments,placeholder:'{"2022-01_threads":1}'}),(0,i.jsx)(u.dOG,{label:"Allow logged out users",checked:o,onChange:this.handleAllowLoggedOut})]})}renderHelpMessage(){let{statusText:e,status:t}=this.state;if(null==e)return(0,i.jsx)("div",{});let n=u.YCn.INFO;switch(t){case 0:n=u.YCn.ERROR;break;case 1:n=u.YCn.WARNING}return(0,i.jsx)(u.po8,{messageType:n,children:e})}render(){let{onClose:e,transitionState:t}=this.props,{publicLink:n}=this.state;return(0,i.jsx)(d.Modal,{title:"Generate Public Build Override Link",input:this.renderHelpMessage(),actionBarInput:(0,i.jsx)(g.A,{value:n}),transitionState:t,"aria-label":"Generate Public Build Override Link",actions:[{variant:"primary",text:"Generate Link",onClick:this.handleGenerateLink}],onClose:e,children:this.renderSettingsForm()})}}let y=I}