package.browser.panels.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. /**
  2. * The package browser home card
  3. *
  4. * @class MODx.panel.PackageBrowserHome
  5. * @extends MODx.TemplatePanel
  6. * @param {Object} config An object of options.
  7. * @xtype modx-package-browser-home
  8. */
  9. MODx.panel.PackageBrowserHome = function(config) {
  10. config = config || {};
  11. Ext.applyIf(config,{
  12. markup: '<tpl for=".">'
  13. +'<div class="one_half"><div class="x-panel-header"><span class="x-panel-header-text">'+_('most_popular')+'</span></div>'
  14. +'<ol class="x-panel-body">'
  15. +'<tpl for="topdownloaded">'
  16. +'<li>'
  17. +'<span class="highlighted">'+_('downloads_view')+'</span>'
  18. +'<button type="button" onclick="Ext.getCmp(\'modx-package-browser-tree\').searchFor(\'{name}\');">'
  19. +'<span class="ct">{#}</span>'
  20. +'{name}'
  21. +'</button>'
  22. +'</li>'
  23. +'</tpl>'
  24. +'</ol>'
  25. +'</div>'
  26. +'<div class="one_half last"><div class="x-panel-header"><span class="x-panel-header-text">'+_('newest_additions')+'</span></div>'
  27. +'<ol class="x-panel-body">'
  28. +'<tpl for="newest">'
  29. +'<li>'
  30. +'<span class="highlighted">{releasedon}</span>'
  31. +'<button type="button" onclick="Ext.getCmp(\'modx-package-browser-tree\').searchFor(\'{package_name}\');">'
  32. +'<span class="ct">{#}</span>'
  33. +'{name}'
  34. +'</button>'
  35. +'</li>'
  36. +'</tpl>'
  37. +'</ol>'
  38. +'</div>'
  39. +'<div class="stats">'
  40. +'<p>'+_('provider_total_packages')+': {packages}</p>'
  41. +'<p>'+_('provider_total_downloads')+': {downloads}</p>'
  42. +'</div>'
  43. +'</tpl>'
  44. ,bodyCssClass: 'home-panel'
  45. });
  46. MODx.panel.PackageBrowserHome.superclass.constructor.call(this,config);
  47. };
  48. Ext.extend(MODx.panel.PackageBrowserHome,MODx.TemplatePanel,{
  49. activate: function(){
  50. Ext.getCmp('package-browser-card-container').getLayout().setActiveItem(this.id);
  51. var me = this;
  52. setTimeout(function(){
  53. me.doLayout();
  54. }, 500);
  55. }
  56. });
  57. Ext.reg('modx-package-browser-home',MODx.panel.PackageBrowserHome);
  58. /**
  59. * The Repositories template panel
  60. *
  61. * @class MODx.panel.PackageBrowserRepositories
  62. * @extends MODx.TemplatePanel
  63. * @param {Object} config An object of options.
  64. * @xtype modx-package-browser-repositories
  65. */
  66. MODx.panel.PackageBrowserRepositories = function(config) {
  67. config = config || {};
  68. Ext.applyIf(config,{
  69. markup: '<tpl for=".">'
  70. +'<div class="pbr-repository-view">'
  71. +'<h2>{name}</h2>'
  72. +'<p>{description}</p>'
  73. +'</div>'
  74. +'</tpl>'
  75. ,bodyCssClass: 'home-panel'
  76. });
  77. MODx.panel.PackageBrowserRepositories.superclass.constructor.call(this,config);
  78. };
  79. Ext.extend(MODx.panel.PackageBrowserRepositories,MODx.TemplatePanel,{
  80. activate: function(){
  81. Ext.getCmp('package-browser-card-container').getLayout().setActiveItem(this.id);
  82. }
  83. });
  84. Ext.reg('modx-package-browser-repositories',MODx.panel.PackageBrowserRepositories);
  85. /**
  86. * A base combobox for sorting options
  87. *
  88. * @class MODx.changeSortComboBox
  89. * @extends Ext.form.ComboBox
  90. * @param {Object} config An object of options.
  91. * @xtype modx-package-changesort-combobox
  92. */
  93. MODx.changeSortComboBox = function(config) {
  94. config = config || {};
  95. Ext.applyIf(config,{
  96. store: new Ext.data.ArrayStore({
  97. fields: ['d','v']
  98. ,data : [['','']
  99. ,[_('alphabetically'),'alpha']
  100. ,[_('most_downloads'),'downloads']
  101. ,[_('newest_added'),'newest']
  102. ,[_('top_rated'),'toprated']]
  103. })
  104. ,displayField: 'd'
  105. ,valueField: 'v'
  106. ,width:280
  107. ,mode: 'local'
  108. ,forceSelection: true
  109. ,emptyText: _('sort_by_dots')
  110. ,editable: false
  111. ,triggerAction: 'all'
  112. ,typeAhead: false
  113. ,selectOnFocus: false
  114. });
  115. MODx.changeSortComboBox.superclass.constructor.call(this,config);
  116. };
  117. Ext.extend(MODx.changeSortComboBox,Ext.form.ComboBox);
  118. Ext.reg('modx-package-changesort-combobox',MODx.changeSortComboBox);
  119. /**
  120. * The package browser package grid card
  121. *
  122. * @class MODx.panel.PackageBrowserGrid
  123. * @extends MODx.grid.Grid
  124. * @param {Object} config An object of options.
  125. * @xtype modx-package-browser-grid
  126. */
  127. MODx.grid.PackageBrowserGrid = function(config) {
  128. config = config || {};
  129. this.exp = new Ext.grid.RowExpander({
  130. tpl : new Ext.Template(
  131. '<p class="package-readme"><i>{description}</i></p>'
  132. )
  133. });
  134. this.mainColumnTpl = new Ext.XTemplate('<tpl for=".">'
  135. +'<h3 class="main-column{state:defaultValue("")}">{name}</h3>'
  136. +'<tpl if="actions !== null">'
  137. +'<ul class="actions">'
  138. +'<tpl for="actions">'
  139. +'<li><button type="button" class="controlBtn {className}">{text}</button></li>'
  140. +'</tpl>'
  141. +'</ul>'
  142. +'</tpl>'
  143. +'</tpl>', {
  144. compiled: true
  145. });
  146. Ext.applyIf(config,{
  147. id: 'modx-package-browser-grid'
  148. ,fields: ['id','version','release','signature','author','description','instructions','createdon','editedon','name'
  149. ,'downloads','releasedon','screenshot','license','location','version-compiled'
  150. ,'supports_db','minimum_supports','breaks_at','featured','audited','changelog'
  151. ,'downloaded','dlaction-text','dlaction-icon']
  152. ,url: MODx.config.connector_url
  153. ,baseParams: {
  154. provider: MODx.provider
  155. ,action: 'workspace/packages/rest/getList'
  156. }
  157. ,paging: true
  158. ,pageSize: 10
  159. ,plugins: [this.exp]
  160. ,showPerPage: false
  161. ,columns: [this.exp,{
  162. header: _('name')
  163. ,dataIndex: 'name'
  164. ,width: 100
  165. ,sortable: true
  166. ,id:'main'
  167. ,renderer: { fn: this.mainColumnRenderer, scope: this }
  168. },{
  169. header: _('version')
  170. ,dataIndex: 'version-compiled'
  171. ,width: 100
  172. ,fixed:true
  173. ,id: 'meta-col'
  174. },{
  175. header: _('author')
  176. ,dataIndex: 'author'
  177. ,width: 100
  178. ,fixed:true
  179. ,id: 'text-col'
  180. },{
  181. header: _('released')
  182. ,dataIndex: 'releasedon'
  183. ,width: 140
  184. ,fixed:true
  185. ,id: 'info-col'
  186. ,renderer: Ext.util.Format.dateRenderer(MODx.config.manager_date_format)
  187. },{
  188. header: _('downloads')
  189. ,dataIndex: 'downloads'
  190. ,width: 100
  191. ,fixed:true
  192. ,id: 'text-col'
  193. }]
  194. ,tbar: [{
  195. xtype: 'button'
  196. ,text: _('back_to_manager')
  197. ,cls: 'primary-button'
  198. ,handler: function(){
  199. Ext.getCmp('modx-panel-packages').activate();
  200. }
  201. },'->',{
  202. xtype: 'modx-package-changesort-combobox'
  203. ,id: 'modx-package-grid-changesort-combobox'
  204. ,listeners: {
  205. 'select': this.changeSort
  206. ,'change': this.changeSort
  207. ,scope: this
  208. }
  209. }]
  210. });
  211. MODx.grid.PackageBrowserGrid.superclass.constructor.call(this,config);
  212. this.on('click', this.onClick, this);
  213. };
  214. Ext.extend(MODx.grid.PackageBrowserGrid,MODx.grid.Grid,{
  215. // Actions handlers
  216. onClick: function(e){
  217. var t = e.getTarget();
  218. var elm = t.className.split(' ')[0];
  219. if(elm == 'controlBtn'){
  220. var act = t.className.split(' ')[1];
  221. var record = this.getSelectionModel().getSelected();
  222. switch (act) {
  223. case 'details':
  224. this.onDetails(record.data);
  225. break;
  226. case 'download':
  227. this.onDownload(record.data);
  228. break;
  229. default:
  230. break;
  231. }
  232. }
  233. }
  234. ,changeSort: function(cb,rec,idx) {
  235. var v = cb.getValue();
  236. var s = this.getStore();
  237. s.removeAll();
  238. s.setBaseParam('sorter',v);
  239. s.load();
  240. }
  241. ,mainColumnRenderer:function (value, metaData, record, rowIndex, colIndex, store){
  242. var values = { name: value, actions: null, message: null };
  243. var h = [];
  244. h.push({ className:'details', text: _('view_details') });
  245. if(!record.data.downloaded){
  246. h.push({ className:'download primary-button', text: _('download') });
  247. }
  248. values.actions = h;
  249. // Open description links in new tabs
  250. var newElem = document.createElement('div');
  251. newElem.innerHTML = record.data.description;
  252. var links = newElem.getElementsByTagName('a');
  253. for(var i = 0; i < links.length; i++) {
  254. links[i].setAttribute('target', '_blank');
  255. }
  256. record.data.description = newElem.innerHTML;
  257. // Apply to template
  258. return this.mainColumnTpl.apply(values);
  259. }
  260. ,onDownload: function(rec){
  261. var c = Ext.getCmp('modx-panel-packages-browser');
  262. c.showWait();
  263. Ext.Ajax.request({
  264. url : this.config.url
  265. ,params : {
  266. action : 'workspace/packages/rest/download'
  267. ,info : rec.location+'::'+rec.signature
  268. ,provider : MODx.provider
  269. }
  270. ,scope: this
  271. ,success: function ( result, request ) {
  272. this.processResult( result.responseText );
  273. }
  274. ,failure: function ( result, request) {
  275. Ext.MessageBox.alert(_('failure'), result.responseText);
  276. c.hideWait();
  277. }
  278. });
  279. }
  280. ,processResult: function( response ){
  281. var data = Ext.util.JSON.decode( response );
  282. var me = this;
  283. if( data.success ){
  284. me.getStore().reload();
  285. Ext.getCmp('modx-package-grid').getStore().reload();
  286. Ext.getCmp('modx-panel-packages-browser').hideWait();
  287. me.updateBreadcrumbs(_('download_success'), true);
  288. setTimeout(function(){
  289. me.updateBreadcrumbs(_('list_of_packages_in_provider'));
  290. }, 5000);
  291. }
  292. else {
  293. Ext.getCmp('modx-panel-packages-browser').hideWait();
  294. Ext.MessageBox.alert(_('failure'), data.message);
  295. }
  296. }
  297. ,onDetails: function(rec){
  298. Ext.getCmp('modx-package-browser-details').activate();
  299. Ext.getCmp('modx-package-browser-details').updateDetail(rec);
  300. }
  301. ,activate: function(cat, query){
  302. if(cat != undefined){
  303. this.bdText = cat;
  304. }
  305. var msg = (!Ext.isEmpty(query) && !Ext.isObject(query)) ? _('search_results_for',{'query': query}) : _('packages_in_category');
  306. Ext.getCmp('package-browser-card-container').getLayout().setActiveItem(this.id);
  307. this.updateBreadcrumbs(msg);
  308. }
  309. ,updateBreadcrumbs: function(msg, highlight){
  310. var bd = { text: msg };
  311. if(highlight){ bd.className = 'highlight'; }
  312. bd.trail = [{
  313. text : _('package_browser')
  314. ,pnl : 'modx-panel-packages-browser'
  315. },{
  316. text : this.bdText
  317. }];
  318. Ext.getCmp('packages-breadcrumbs').updateDetail(bd);
  319. }
  320. });
  321. Ext.reg('modx-package-browser-grid',MODx.grid.PackageBrowserGrid);
  322. /**
  323. * The package browser detail card
  324. *
  325. * @class MODx.PackageBrowserWaitWindow
  326. * @extends Ext.Window
  327. * @param {Object} config An object of options.
  328. * @xtype modx-package-browser-details
  329. */
  330. MODx.PackageBrowserWaitWindow = function(config) {
  331. config = config || {};
  332. Ext.applyIf(config,{
  333. html: '<p class="wait">'+_('downloading')+'</p>'
  334. ,bodyCssClass: 'centered'
  335. ,modal: true
  336. ,title: _('please_wait')
  337. ,border: false
  338. ,closable: false
  339. ,width: 400
  340. });
  341. MODx.PackageBrowserWaitWindow.superclass.constructor.call(this,config);
  342. }
  343. Ext.extend(MODx.PackageBrowserWaitWindow,Ext.Window);
  344. /**
  345. * The package browser detail card
  346. *
  347. * @class MODx.panel.PackageBrowserDetails
  348. * @extends MODx.Panel
  349. * @param {Object} config An object of options.
  350. * @xtype modx-package-browser-details
  351. */
  352. MODx.panel.PackageBrowserDetails = function(config) {
  353. config = config || {};
  354. Ext.applyIf(config,{
  355. layout: 'column'
  356. ,border: false
  357. ,autoHeight: true
  358. ,items:[{
  359. xtype: 'modx-template-panel'
  360. ,id: 'modx-package-browser-details-main'
  361. ,columnWidth: 1
  362. ,markup: '<div class="details">'
  363. +'<tpl for=".">'
  364. +'<tpl if="description">'
  365. +'<div class="item">'
  366. +'<h4>'+_('description')+'</h4>'
  367. +'{description}'
  368. +'</div>'
  369. +'</tpl>'
  370. +'<tpl if="instructions">'
  371. +'<div class="item">'
  372. +'<h4>'+_('instructions')+'</h4>'
  373. +'{instructions}'
  374. +'</div>'
  375. +'</tpl>'
  376. +'<tpl if="changelog">'
  377. +'<div class="item">'
  378. +'<h4>'+_('changelog')+'</h4>'
  379. +'{changelog}'
  380. +'</div>'
  381. +'</tpl>'
  382. +'</tpl>'
  383. +'</div>'
  384. },{
  385. xtype: 'modx-template-panel'
  386. ,id: 'modx-package-browser-details-aside'
  387. ,cls: 'aside-details'
  388. ,width: 250
  389. ,markup: '<div class="details">'
  390. +'<tpl for=".">'
  391. +'<div class="selected">'
  392. +'<tpl if="screenshot">'
  393. +'<a href="{screenshot}" title="'+_('package_preview_view')+'" alt="'+_('package_preview_view')+'" class="lightbox" />'
  394. +'<img src="{screenshot}" alt="{name}" />'
  395. +'</a>'
  396. +'</tpl>'
  397. +'<h5>{name} {version-compiled}</h5>'
  398. +'<tpl if="!downloaded">'
  399. +'<button class="inline-button primary-button" onclick="Ext.getCmp(\'modx-package-browser-details\').downloadPackage(\'{id}\'); return false;"/>'+_('download')+'</button>'
  400. +'</tpl>'
  401. +'<tpl if="downloaded">'
  402. +'<div class="downloaded">'
  403. +_('package_already_downloaded')
  404. +'</div>'
  405. +'</tpl>'
  406. +'</div>'
  407. +'<div class="infos description">'
  408. +'<h4>Information</h4>'
  409. +'<ul>'
  410. +'<li>'
  411. +'<span class="infoname">'+_('author')+':</span>'
  412. +'<span class="infovalue">{author}</span>'
  413. +'</li>'
  414. +'<li>'
  415. +'<span class="infoname">'+_('released_on')+':</span>'
  416. +'<span class="infovalue">{releasedon}</span>'
  417. +'</li>'
  418. +'<li>'
  419. +'<span class="infoname">'+_('minimum_supports')+':</span>'
  420. +'<span class="infovalue">{minimum_supports:defaultValue("--")}</span>'
  421. +'</li>'
  422. +'<li>'
  423. +'<span class="infoname">'+_('breaks_at')+':</span>'
  424. +'<span class="infovalue">{breaks_at:defaultValue("--")}</span>'
  425. +'</li>'
  426. +'<li>'
  427. +'<span class="infoname">'+_('supports_db')+':</span>'
  428. +'<span class="infovalue">{supports_db:defaultValue("--")}</span>'
  429. +'</li>'
  430. +'<li>'
  431. +'<span class="infoname">'+_('downloads')+':</span>'
  432. +'<span class="infovalue">{downloads}</span>'
  433. +'</li>'
  434. +'<li>'
  435. +'<span class="infoname">'+_('license')+':</span>'
  436. +'<span class="infovalue">{license:defaultValue("--")}</span>'
  437. +'</li>'
  438. +'</ul>'
  439. +'</div>'
  440. +'</tpl>'
  441. +'</div>'
  442. }]
  443. ,tbar: [{
  444. xtype: 'button'
  445. ,text: _('back_to_browser')
  446. ,cls: 'primary-button'
  447. ,handler: this.onBackToPackageBrowserGrid
  448. ,scope: this
  449. }]
  450. });
  451. MODx.panel.PackageBrowserDetails.superclass.constructor.call(this,config);
  452. };
  453. Ext.extend(MODx.panel.PackageBrowserDetails,MODx.Panel,{
  454. activate: function(){
  455. Ext.getCmp('package-browser-card-container').getLayout().setActiveItem(this.id);
  456. }
  457. ,updateBreadcrumbs: function(msg, highlight){
  458. var bd = { text: msg };
  459. if(highlight){ bd.className = 'highlight'; }
  460. bd.trail = [{
  461. text : _('package_browser')
  462. ,pnl : 'modx-panel-packages-browser'
  463. },{
  464. text : _('package_details')
  465. }];
  466. Ext.getCmp('packages-breadcrumbs').updateDetail(bd);
  467. }
  468. ,updateDetail: function(rec, text){
  469. this.updateBreadcrumbs(_('package_details')+': '+ rec.name +' '+ rec['version-compiled']);
  470. Ext.getCmp('modx-package-browser-details-main').updateDetail(rec);
  471. Ext.getCmp('modx-package-browser-details-aside').updateDetail(rec);
  472. var links = Ext.query('#modx-package-browser-details-main a');
  473. Ext.each(links, function(o, i) {
  474. o.setAttribute('target', '_blank');
  475. });
  476. }
  477. ,onBackToPackageBrowserGrid: function(btn,e){
  478. Ext.getCmp('modx-package-browser-grid').activate();
  479. }
  480. ,downloadPackage: function(btn, e){
  481. grid = Ext.getCmp('modx-package-browser-grid');
  482. var record = grid.getSelectionModel().getSelected();
  483. grid.activate();
  484. grid.onDownload(record.data);
  485. }
  486. });
  487. Ext.reg('modx-package-browser-details',MODx.panel.PackageBrowserDetails);
  488. /**
  489. * The view panel for the template browser
  490. *
  491. * @class MODx.PackageBrowserThumbsView
  492. * @extends MODx.DataView
  493. * @param {Object} config An object of options.
  494. * @xtype modx-package-browser-thumbs-view
  495. */
  496. MODx.PackageBrowserThumbsView = function(config) {
  497. config = config || {};
  498. this._initTemplates();
  499. Ext.applyIf(config,{
  500. url: MODx.config.connector_url
  501. ,fields: ['id','version','release','signature','author','description','instructions','createdon','editedon','name'
  502. ,'downloads','releasedon','screenshot','license','supports','location','version-compiled', 'featured'
  503. ,'downloaded','dlaction-text','dlaction-icon']
  504. ,baseParams: {
  505. action: 'workspace/packages/rest/getList'
  506. ,provider: MODx.provider
  507. }
  508. ,tpl: this.templates.thumb
  509. ,listeners: {
  510. 'dblclick': {fn: this.onDblClick ,scope:this }
  511. }
  512. ,prepareData: this.formatData.createDelegate(this)
  513. ,overClass:'x-view-over'
  514. ,selectedClass:'selected'
  515. ,itemSelector: 'div.thumb-wrapper'
  516. ,loadingText : '<div class="empty-msg"><h4>'+_('loading')+'</h4></div>'
  517. ,emptyText : '<div class="empty-msg">' + this.emptyText + '</div>'|| '<div class="empty-msg"><h4>'+_('package_update_err_provider_empty')+'</h4></div>'
  518. });
  519. MODx.PackageBrowserThumbsView.superclass.constructor.call(this,config);
  520. this.on('selectionchange',this.showDetails,this,{buffer: 100});
  521. };
  522. Ext.extend(MODx.PackageBrowserThumbsView,MODx.DataView,{
  523. templates: {}
  524. ,run: function(p) {
  525. var v = {};
  526. Ext.applyIf(v,this.store.baseParams);
  527. Ext.applyIf(v,p);
  528. this.store.load({
  529. params: v
  530. // /* Fix layout after the store's loaded */
  531. ,callback: function(rec, options, success){
  532. setTimeout(function(){
  533. Ext.getCmp('modx-content').doLayout();
  534. }, 500);
  535. }
  536. });
  537. }
  538. ,sortBy: function(sel) {
  539. this.store.baseParams.sorter = sel.getValue();
  540. this.run();
  541. return true;
  542. }
  543. ,sortDir: function(sel) {
  544. this.store.baseParams.dir = sel.getValue();
  545. this.run();
  546. }
  547. ,showDetails : function(){
  548. var selNode = this.getSelectedNodes();
  549. if(selNode && selNode.length > 0){
  550. selNode = selNode[0];
  551. var data = this.lookup[selNode.id];
  552. if (data) { Ext.getCmp('modx-package-browser-view').updateDetail(data); }
  553. }
  554. }
  555. ,formatData: function(data) {
  556. var formatSize = function(data){
  557. if(data.size < 1024) {
  558. return data.size + " bytes";
  559. } else {
  560. return (Math.round(((data.size*10) / 1024))/10) + " KB";
  561. }
  562. };
  563. data.shortName = Ext.util.Format.ellipsis(data.name, 18);
  564. data.shortDescription = Ext.util.Format.ellipsis(Ext.util.Format.stripTags(data.description), 125);
  565. data.sizeString = formatSize(data);
  566. data.releasedon = new Date(data.releasedon).format(MODx.config.manager_date_format);
  567. this.lookup['modx-package-thumb-'+data.id] = data;
  568. return data;
  569. }
  570. ,_initTemplates: function() {
  571. this.templates.thumb = new Ext.XTemplate('<tpl for=".">'
  572. +'<div class="thumb-wrapper <tpl if="downloaded">pbr-thumb-downloaded</tpl>" id="modx-package-thumb-{id}">'
  573. +'<div class="thumb">'
  574. +'<tpl if="screenshot.length == 0">'
  575. +'<span class="no-preview">'+_('no_preview')+'</span>'
  576. +'</tpl>'
  577. +'<tpl if="screenshot">'
  578. +'<img src="{screenshot}" title="{name:htmlEncode}" alt="{name:htmlEncode}" onerror="var span = document.createElement(\'span\'); span.className = \'no-preview\'; span.innerText = _(\'no_preview\'); this.replaceWith(span)"/>'
  579. +'</tpl>'
  580. +'<tpl if="downloaded"><span class="downloaded">'+_('downloaded')+'</span></tpl>'
  581. +'<tpl if="featured"><span class="featured">'+_('featured')+'</span></tpl>'
  582. +'</div>'
  583. +'<span class="name">{shortName:htmlEncode}</span>'
  584. +'<span class="downloads">{downloads:htmlEncode} '+_('downloads') + '<br>' + _('version') + ' {version} ' +'</span>'
  585. +'<p class="thumb-description">{shortDescription:htmlEncode}</p>'
  586. +'<p class="thumb-footer">' + _('released_on') + ' {releasedon} ' + _('by') + '&nbsp;{author}</p>'
  587. +'</div>'
  588. +'</tpl>', {
  589. compiled: true
  590. });
  591. }
  592. ,download: function(id) {
  593. var data = this.lookup['modx-package-thumb-'+id];
  594. if (!data) return false;
  595. MODx.Ajax.request({
  596. url: this.config.url
  597. ,params: {
  598. action: 'workspace/packages/rest/download'
  599. ,info: data.location+'::'+data.signature
  600. ,provider: MODx.provider || MODx.config.default_provider
  601. }
  602. ,scope: this
  603. ,listeners: {
  604. 'success': {fn:function(r) {
  605. this.run();
  606. },scope:this}
  607. }
  608. });
  609. }
  610. });
  611. Ext.reg('modx-package-browser-thumbs-view',MODx.PackageBrowserThumbsView);
  612. /**
  613. * The package browser detail panel
  614. *
  615. * @class MODx.panel.PackageBrowserView
  616. * @extends MODx.Panel
  617. * @param {Object} config An object of options.
  618. * @xtype modx-package-browser-view
  619. */
  620. MODx.panel.PackageBrowserView = function(config) {
  621. config = config || {};
  622. this.ident = config.ident || 'modx-pkgb-'+Ext.id();
  623. this.view = MODx.load({
  624. id: 'modx-package-browser-thumbs-view'
  625. ,xtype: 'modx-package-browser-thumbs-view'
  626. ,containerScroll: true
  627. ,ident: this.ident
  628. ,border: false
  629. });
  630. Ext.applyIf(config,{
  631. layout: 'column'
  632. ,xtype: 'panel'
  633. ,url: MODx.config.connector_url
  634. ,tbar: [{
  635. xtype: 'button'
  636. ,text: _('back_to_browser')
  637. ,handler: function(){
  638. Ext.getCmp('modx-panel-packages').activate();
  639. }
  640. },'->',{
  641. xtype:'modx-package-changesort-combobox'
  642. ,id: 'modx-package-browser-changesort-combobox'
  643. ,listeners: {
  644. 'select': function(cb){
  645. var v = cb.getValue();
  646. var s = Ext.getCmp('modx-package-browser-thumbs-view').getStore();
  647. s.removeAll();
  648. s.setBaseParam('sorter',v);
  649. s.load();
  650. }
  651. }
  652. }]
  653. ,border: false
  654. ,autoHeight: true
  655. ,items:[{
  656. items: this.view
  657. ,border: false
  658. ,bbar: new Ext.PagingToolbar({
  659. pageSize: 10
  660. ,store: this.view.store
  661. ,displayInfo: true
  662. ,autoLoad: true
  663. })
  664. ,columnWidth: 1
  665. },{
  666. xtype: 'modx-template-panel'
  667. ,id: 'modx-package-browser-template-aside'
  668. ,cls: 'aside-details'
  669. ,width: 280
  670. ,startingText: _('template_select_desc')
  671. ,markup: '<div class="details">'
  672. +'<tpl for=".">'
  673. +'<div class="selected">'
  674. +'<tpl if="screenshot.length == 0">'
  675. +'<span class="no-preview">'+_('no_preview')+'</span>'
  676. +'</tpl>'
  677. +'<tpl if="screenshot">'
  678. +'<a href="{screenshot}" title="'+_('template_preview_view')+'" alt="'+_('template_preview_view')+'" class="lightbox" />'
  679. +'<img src="{screenshot}" alt="{name}" />'
  680. +'</a>'
  681. +'</tpl>'
  682. +'<h3>{name} {version-compiled}</h3>'
  683. +'<tpl if="!downloaded">'
  684. +'<button class="inline-button green" onclick="Ext.getCmp(\'modx-package-browser-view\').download(\'{id}\'); return false;"/>'+_('download')+'</button>'
  685. +'</tpl>'
  686. +'<tpl if="downloaded">'
  687. +'<div class="downloaded">'
  688. +_('template_already_downloaded')
  689. +'</div>'
  690. +'</tpl>'
  691. +'</div>'
  692. +'<div class="description">'
  693. +'<h4>'+_('description')+'</h4>'
  694. +'{description}'
  695. +'</div>'
  696. +'<div class="infos">'
  697. +'<h4>'+_('information')+'</h4>'
  698. +'<ul>'
  699. +'<li>'
  700. +'<span class="infoname">'+_('author')+':</span>'
  701. +'<span class="infovalue">{author}</span>'
  702. +'</li>'
  703. +'<li>'
  704. +'<span class="infoname">'+_('released_on')+':</span>'
  705. +'<span class="infovalue">{releasedon}</span>'
  706. +'</li>'
  707. +'<li>'
  708. +'<span class="infoname">'+_('minimum_supports')+':</span>'
  709. +'<span class="infovalue">{supports:defaultValue("--")}</span>'
  710. +'</li>'
  711. +'<li>'
  712. +'<span class="infoname">'+_('breaks_at')+':</span>'
  713. +'<span class="infovalue">{breaks_at:defaultValue("--")}</span>'
  714. +'</li>'
  715. +'<li>'
  716. +'<span class="infoname">'+_('supports_db')+':</span>'
  717. +'<span class="infovalue">{supports_db:defaultValue("--")}</span>'
  718. +'</li>'
  719. +'<li>'
  720. +'<span class="infoname">'+_('downloads')+':</span>'
  721. +'<span class="infovalue">{downloads}</span>'
  722. +'</li>'
  723. +'<li>'
  724. +'<span class="infoname">'+_('license')+':</span>'
  725. +'<span class="infovalue">{license}</span>'
  726. +'</li>'
  727. +'</ul>'
  728. +'</div>'
  729. +'<tpl if="instructions">'
  730. +'<div class="instructions">'
  731. +'<h4>'+_('instructions')+'</h4>'
  732. +'{instructions}'
  733. +'</div>'
  734. +'</tpl>'
  735. +'</tpl>'
  736. +'</div>'
  737. }]
  738. });
  739. MODx.panel.PackageBrowserView.superclass.constructor.call(this,config);
  740. };
  741. Ext.extend(MODx.panel.PackageBrowserView,MODx.Panel,{
  742. activate: function(cat){
  743. if(cat != undefined){
  744. this.bdText = cat;
  745. }
  746. Ext.getCmp('package-browser-card-container').getLayout().setActiveItem(this.id);
  747. this.updateBreadcrumbs(_('viewing_templates_available'));
  748. Ext.getCmp('modx-package-browser-template-aside').reset();
  749. }
  750. ,updateBreadcrumbs: function(msg, highlight){
  751. var bd = { text: msg };
  752. if(highlight){ bd.className = 'highlight'; }
  753. bd.trail = [{
  754. text : _('package_browser')
  755. ,pnl : 'modx-panel-packages-browser'
  756. },{
  757. text : this.bdText
  758. }];
  759. Ext.getCmp('packages-breadcrumbs').updateDetail(bd);
  760. }
  761. ,updateDetail: function(rec){
  762. Ext.getCmp('modx-package-browser-template-aside').updateDetail(rec);
  763. }
  764. ,download: function(id){
  765. var record = this.view.lookup['modx-package-thumb-'+id];
  766. var c = Ext.getCmp('modx-panel-packages-browser');
  767. if(!record) return false;
  768. c.showWait();
  769. var me = this;
  770. MODx.Ajax.request({
  771. url: this.url
  772. ,params: {
  773. action: 'workspace/packages/rest/download'
  774. ,info: record.location+'::'+record.signature
  775. ,provider: MODx.provider || MODx.config.default_provider
  776. }
  777. ,scope: this
  778. ,listeners: {
  779. 'success': {fn:function(r) {
  780. this.view.run();
  781. c.hideWait();
  782. this.updateBreadcrumbs(_('download_success'), true);
  783. setTimeout(function(){
  784. me.updateBreadcrumbs(_('templates_in_category'));
  785. }, 5000);
  786. },scope:this}
  787. }
  788. });
  789. }
  790. });
  791. Ext.reg('modx-package-browser-view',MODx.panel.PackageBrowserView);