(function(){"use strict";(function(){const InstalledExtension=Backbone.Model.extend({defaults:{author:null,authorURL:null,configURL:null,dbURL:null,enabled:false,loadable:true,loadError:null,name:null,summary:null,version:null},url(){return Backbone.Model.prototype.url.call(this)+"/"},enable(){return new Promise((resolve,reject)=>{this.save({enabled:true},{wait:true,success:()=>resolve(),error:(model,xhr)=>{this.set({loadable:false,loadError:xhr.errorRsp.load_error,canEnable:!xhr.errorRsp.needs_reload});reject(new Error(xhr.errorText))}})})},disable(){return new Promise((resolve,reject)=>{this.save({enabled:false},{wait:true,success:()=>resolve(),error:xhr=>reject(new Error(xhr.errorText))})})},toJSON(){return{enabled:this.get("enabled")}},parse(rsp){if(rsp.stat!==undefined){rsp=rsp.extension}const configLink=rsp.links["admin-configure"];const dbLink=rsp.links["admin-database"];return{author:rsp.author,authorURL:rsp.author_url,canDisable:rsp.can_disable,canEnable:rsp.can_enable,configURL:configLink?configLink.href:null,dbURL:dbLink?dbLink.href:null,enabled:rsp.enabled,loadable:rsp.loadable,loadError:rsp.load_error,id:rsp.class_name,name:rsp.name,summary:rsp.summary,version:rsp.version}},sync(method,model,options){Backbone.sync.call(this,method,model,_.defaults({contentType:"application/x-www-form-urlencoded",data:model.toJSON(options),processData:true,error:xhr=>{let rsp;let text;try{rsp=$.parseJSON(xhr.responseText);text=rsp.err.msg}catch(e){text="HTTP "+xhr.status+" "+xhr.statusText;rsp={loadError:text,canEnable:false}}if(_.isFunction(options.error)){xhr.errorText=text;xhr.errorRsp=rsp;options.error(xhr,options)}}},options))}});const InstalledExtensionCollection=Backbone.Collection.extend({model:InstalledExtension,parse(rsp){return rsp.extensions}});Djblets.ExtensionManager=Backbone.Model.extend({defaults:{apiRoot:null},initialize(){this.installedExtensions=new InstalledExtensionCollection;this.installedExtensions.url=this.get("apiRoot")},load(){this.trigger("loading");this.installedExtensions.fetch({success:()=>this.trigger("loaded")})}})})();"use strict";(function(){const ExtensionItem=Djblets.Config.ListItem.extend({defaults:_.defaults({extension:null},Djblets.Config.ListItem.prototype.defaults),initialize(){Djblets.Config.ListItem.prototype.initialize.apply(this,arguments);this._updateActions();this._updateItemState();this.listenTo(this.get("extension"),"change:loadable change:loadError change:enabled",()=>{this._updateItemState();this._updateActions()})},_updateActions(){const extension=this.get("extension");const actions=[];if(!extension.get("loadable")){actions.push({id:"reload",label:gettext("Reload")})}else if(extension.get("enabled")){const configURL=extension.get("configURL");const dbURL=extension.get("dbURL");if(dbURL){actions.push({id:"database",label:gettext("Database"),url:dbURL})}if(configURL){actions.push({id:"configure",label:gettext("Configure"),primary:true,url:configURL})}actions.push({id:"disable",label:gettext("Disable"),danger:true})}else{actions.push({id:"enable",label:gettext("Enable"),primary:true})}this.setActions(actions)},_updateItemState(){const extension=this.get("extension");let itemState;if(!extension.get("loadable")){itemState="error"}else if(extension.get("enabled")){itemState="enabled"}else{itemState="disabled"}this.set("itemState",itemState)}});const ExtensionItemView=Djblets.Config.TableItemView.extend({className:"djblets-c-extension-item djblets-c-config-forms-list__item",actionHandlers:{disable:"_onDisableClicked",enable:"_onEnableClicked",reload:"_onReloadClicked"},template:_.template(`<td class="djblets-c-config-forms-list__item-main">
 <div class="djblets-c-extension-item__header">
  <h3 class="djblets-c-extension-item__name"><%- name %></h3>
  <span class="djblets-c-extension-item__version"><%- version %></span>
  <div class="djblets-c-extension-item__author">
   <% if (authorURL) { %>
    <a href="<%- authorURL %>"><%- author %></a>
   <% } else { %>
    <%- author %>
   <% } %>
  </div>
 </div>
 <p class="djblets-c-extension-item__description">
  <%- summary %>
 </p>
 <% if (!loadable) { %>
  <pre class="djblets-c-extension-item__load-error"><%- loadError %></pre>
 <% } %>
</td>
<td class="djblets-c-config-forms-list__item-state"></td>
<td></td>`),getRenderContext(){return this.model.get("extension").attributes},_onDisableClicked(){return this.model.get("extension").disable().catch(error=>{alert(interpolate(gettext("Failed to disable the extension: %(value1)s."),{value1:error.message},true))})},_onEnableClicked(){return this.model.get("extension").enable().catch(error=>{alert(interpolate(gettext("Failed to enable the extension: %(value1)s."),{value1:error.message},true))})},_onReloadClicked(){return new Promise(()=>this.model.trigger("needsReload"))}});Djblets.ExtensionManagerView=Backbone.View.extend({events:{"click .djblets-c-extensions__reload":"_reloadFull"},listItemsCollectionType:Djblets.Config.ListItems,listItemType:ExtensionItem,listItemViewType:ExtensionItemView,listViewType:Djblets.Config.TableView,initialize(){this.list=new Djblets.Config.List({},{collection:new this.listItemsCollectionType([],{model:this.listItemType})})},render(){const model=this.model;const list=this.list;this.listView=new this.listViewType({el:this.$(".djblets-c-config-forms-list"),model:list,ItemView:this.listItemViewType});this.listView.render().$el.removeAttr("aria-busy").addClass("-all-items-are-multiline");this._$listContainer=this.listView.$el.parent();this.listenTo(model,"loading",()=>list.collection.reset());this.listenTo(model,"loaded",this._onLoaded);model.load();return this},_onLoaded(){const items=this.list.collection;this.model.installedExtensions.each(extension=>{const item=items.add({extension:extension});this.listenTo(item,"needsReload",this._reloadFull)})},_reloadFull(){this.el.submit()}})})()}).call(this);
