PageRenderTime 36ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/tine20/Tinebase/js/AppTabsPanel.js

https://gitlab.com/rsilveira1987/Expresso
JavaScript | 380 lines | 217 code | 50 blank | 113 comment | 23 complexity | f5d71ff4f0da38b9262de107544f68ff MD5 | raw file
  1. /*
  2. * Tine 2.0
  3. *
  4. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  5. * @author Cornelius Weiss <c.weiss@metaways.de>
  6. * @copyright Copyright (c) 2010 Metaways Infosystems GmbH (http://www.metaways.de)
  7. */
  8. Ext.ns('Tine.Tinebase');
  9. /**
  10. * Main appStarter/picker tab panel
  11. *
  12. * NOTE: Tab panels are not sortable yet {@see http://www.extjs.com/forum/showthread.php?p=55045#post55045}
  13. *
  14. * @todo discuss: default app vs. last active tab
  15. * @todo discuss: have a set of default apps?
  16. *
  17. * @namespace Tine.Tinebase
  18. * @class Tine.Tinebase.AppTabsPanel
  19. * @extends Ext.TabPanel
  20. * @author Cornelius Weiss <c.weiss@metaways.de>
  21. */
  22. Tine.Tinebase.AppTabsPanel = function(config) {
  23. Ext.apply(this, config);
  24. this.plugins = [new Ext.ux.TabPanelSortPlugin({
  25. dragZoneConfig: {
  26. onBeforeDrag: this.onBeforeDrag.createDelegate(this)
  27. },
  28. dropZoneConfig: {
  29. getTargetFromEvent: this.getTargetFromEvent.createDelegate(this)
  30. }
  31. })];
  32. Tine.Tinebase.AppTabsPanel.superclass.constructor.call(this, config);
  33. };
  34. Ext.extend(Tine.Tinebase.AppTabsPanel, Ext.TabPanel, {
  35. activeTab: 1,
  36. stateful: true,
  37. stateEvents: ['add', 'remove', 'tabchange', 'tabsort'],
  38. stateId: 'tinebase-mainscreen-apptabs',
  39. /**
  40. * @cfg {Array} of Strings currentTab ids
  41. */
  42. currentTabs: null,
  43. // private
  44. findTargets : function(e){
  45. var item = null,
  46. itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
  47. if(itemEl){
  48. item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
  49. if(item && item.disabled){
  50. return {
  51. close : null,
  52. item : null,
  53. el : null
  54. };
  55. }
  56. }
  57. return {
  58. close : e.getTarget('.x-tab-strip-close', this.strip),
  59. item : item,
  60. el : itemEl
  61. };
  62. },
  63. /**
  64. * init appTabsPanel
  65. */
  66. initComponent: function() {
  67. Ext.apply(this, Ext.state.Manager.get(this.stateId));
  68. this.initMenu();
  69. this.items = [{
  70. id: this.app2id('menu'),
  71. title: Tine.title,
  72. iconCls: 'tine-favicon',
  73. closable: true,
  74. listeners: {
  75. scope: this,
  76. beforeclose: this.onBeforeTabClose
  77. }
  78. }].concat(this.getDefaultTabItems());
  79. // set states last active app to the sessions default app
  80. Tine.Tinebase.appMgr.setDefault(this.id2appName(this.activeTab));
  81. Tine.Tinebase.appMgr.on('activate', this.onActivateApp, this);
  82. this.on('beforetabchange', this.onBeforeTabChange, this);
  83. this.on('tabsort', this.onTabChange, this);
  84. this.on('add', this.onTabChange, this);
  85. this.on('remove', this.onTabChange, this);
  86. this.supr().initComponent.call(this);
  87. // fake an access stack
  88. for (var i=1, tabCount=this.items.getCount(); i<tabCount; i++) {
  89. this.stack.add(this.items.get(i));
  90. }
  91. },
  92. /**
  93. * init the combined appchooser/tine menu
  94. */
  95. initMenu: function() {
  96. this.menu = new Ext.menu.Menu({
  97. layout: 'column',
  98. width: 400,
  99. autoHeight: true,
  100. style: {
  101. 'background-image': 'none'
  102. },
  103. defaults: {
  104. xtype: 'menu',
  105. floating: false,
  106. columnWidth: 0.5,
  107. hidden: false,
  108. listeners: {
  109. scope: this,
  110. itemclick: function(item, e) {
  111. this.menu.hide();
  112. }
  113. },
  114. style: {
  115. //'border-color': 'transparent'
  116. 'border': '0'
  117. }
  118. },
  119. items: [{
  120. items: this.getAppItems(),
  121. style: {'border-right': '1px solid #E2E2E3'}
  122. }, {
  123. items: Tine.Tinebase.MainScreen.getMainMenu().getMainActions()
  124. }]
  125. });
  126. },
  127. /**
  128. * executed after render
  129. */
  130. afterRender: function() {
  131. this.supr().afterRender.apply(this, arguments);
  132. this.menuTabEl = Ext.get(this.getTabEl(0));
  133. this.menuTabEl.addClass('tine-mainscreen-apptabspanel-menu-tabel');
  134. // remove plain style
  135. this.header.removeClass('x-tab-panel-header-plain');
  136. },
  137. /**
  138. * get app items for the tabPanel
  139. *
  140. * @return {Array}
  141. */
  142. getAppItems: function() {
  143. var appItems = [];
  144. Tine.Tinebase.appMgr.getAll().each(function(app) {
  145. if (app.hasMainScreen) {
  146. appItems.push({
  147. text: app.getTitle(),
  148. iconCls: app.getIconCls(),
  149. handler: this.onAppItemClick.createDelegate(this, [app])
  150. });
  151. }
  152. }, this);
  153. return appItems.reverse();
  154. },
  155. /**
  156. * get default tab items configurations
  157. *
  158. * @return {Array}
  159. */
  160. getDefaultTabItems: function() {
  161. if (Ext.isEmpty(this.currentTabs)) {
  162. this.currentTabs = [this.id2appName(Tine.Tinebase.appMgr.getDefault())];
  163. }
  164. var tabItems = [];
  165. Ext.each(this.currentTabs, function(appName) {
  166. var app = Tine.Tinebase.appMgr.get(appName);
  167. if (app) {
  168. tabItems.push(this.getTabItem(app));
  169. }
  170. }, this);
  171. return tabItems;
  172. },
  173. /**
  174. * deny drag on menuEl
  175. * @param {} e
  176. * @return {}
  177. */
  178. onBeforeDrag: function(data, e) {
  179. return e.getTarget('li[class*=mainscreen-apptabspanel-menu-tabel]', 10) ? false : true;
  180. },
  181. /**
  182. * deny drop on menuEl
  183. * @param {} e
  184. * @return {}
  185. */
  186. getTargetFromEvent: function(e) {
  187. var target = e.getTarget('ul[class^=x-tab]', 10),
  188. li = this.findTargets(e);
  189. if (li.el && li.el == this.menuTabEl.dom) {
  190. return false;
  191. }
  192. return target;
  193. },
  194. /**
  195. * get tabs state
  196. *
  197. * @return {Object}
  198. */
  199. getState: function() {
  200. return {
  201. currentTabs: this.currentTabs,
  202. activeTab: Ext.isNumber(this.activeTab) ? this.activeTab : this.items.indexOf(this.activeTab)
  203. };
  204. },
  205. /**
  206. * get tab item configuration
  207. *
  208. * @param {Tine.Application} app
  209. * @return {Object}
  210. */
  211. getTabItem: function(app) {
  212. return {
  213. id: this.app2id(app),
  214. title: app.getTitle(),
  215. iconCls: app.getIconCls(),
  216. closable: true,
  217. listeners: {
  218. scope: this,
  219. beforeclose: this.onBeforeTabClose,
  220. activate: this.onTabActivate
  221. }
  222. };
  223. },
  224. /**
  225. * executed when an app get activated by mainscreen
  226. *
  227. * @param {Tine.Application} app
  228. */
  229. onActivateApp: function(app) {
  230. var tab = this.getItem(this.app2id(app)) || this.add(this.getTabItem(app));
  231. this.setActiveTab(tab);
  232. },
  233. /**
  234. * executed when an app item in this.menu is clicked
  235. *
  236. * @param {Tine.Application} app
  237. */
  238. onAppItemClick: function(app) {
  239. Tine.Tinebase.appMgr.activate(app);
  240. this.menu.hide();
  241. },
  242. /**
  243. * executed on tab changes
  244. *
  245. * @param {TabPanel} this
  246. * @param {Panel} newTab The tab being activated
  247. * @param {Panel} currentTab The current active tab
  248. */
  249. onBeforeTabChange: function(tp, newTab, currentTab) {
  250. if (this.id2appName(newTab) === 'menu') {
  251. this.menu.show(this.menuTabEl, 'tl-bl');
  252. return false;
  253. }
  254. },
  255. /**
  256. * executed before a tab panel is closed
  257. *
  258. * @param {Ext.Panel} tab
  259. * @return {boolean}
  260. */
  261. onBeforeTabClose: function(tab) {
  262. if (this.id2appName(tab) === 'menu') {
  263. return this.onBeforeTabChange(this, tab, this.activeTab);
  264. }
  265. // don't close last app panel
  266. return this.items.getCount() > 2;
  267. },
  268. /**
  269. * executed when a tab gets activated
  270. *
  271. * @param {Ext.Panel} tab
  272. */
  273. onTabActivate: function(tab) {
  274. var appName = this.id2appName(tab);
  275. var app = Tine.Tinebase.appMgr.get(appName);
  276. // fixme
  277. if (Ext.getCmp('treecards').rendered) {
  278. Tine.Tinebase.appMgr.activate(app);
  279. }
  280. },
  281. /**
  282. * executed when tabs chages
  283. */
  284. onTabChange: function() {
  285. var tabCount = this.items.getCount();
  286. var closable = tabCount > 2;
  287. this.currentTabs = [];
  288. for (var i=1, tab, el; i<tabCount; i++) {
  289. tab = this.items.get(i);
  290. // update currentTabs
  291. this.currentTabs.push(this.id2appName(tab.id));
  292. // handle closeables
  293. tab.closable = closable;
  294. el = this.getTabEl(i);
  295. if (el) {
  296. Ext.get(el)[closable ? 'addClass' : 'removeClass']('x-tab-strip-closable');
  297. }
  298. }
  299. },
  300. /**
  301. * returns appName of given tab/id
  302. *
  303. * @param {Ext.Panel/String/Number} id
  304. * @return {String} appName
  305. */
  306. id2appName: function(id) {
  307. if (Ext.isNumber(id)) {
  308. if (Ext.isArray(this.items)) {
  309. id = this.items[id] ? this.items[id].id : null;
  310. } else {
  311. id = this.items.get(id);
  312. }
  313. }
  314. if (Ext.isObject(id) && ! Ext.isEmpty(id)) {
  315. id = id.id;
  316. }
  317. if (Ext.isString(id)) {
  318. return id.split('-').pop();
  319. }
  320. return null;
  321. },
  322. /**
  323. * returns tab id of given app
  324. * @param {Tine.Application/String} app
  325. */
  326. app2id: function(app) {
  327. var appName = app.appName || app;
  328. return this.id + '-' + appName;
  329. }
  330. });