PageRenderTime 41ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/jira-project/jira-components/jira-webapp/src/main/webapp/includes/jira/shifter/ShifterDialog.js

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
JavaScript | 208 lines | 165 code | 22 blank | 21 comment | 16 complexity | c49d221c7a16d7c4e81cda9ce92887e6 MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * @module jira/shifter/shifter-dialog
  3. */
  4. define('jira/shifter/shifter-dialog', [
  5. 'jira/jquery/deferred',
  6. 'jira/lib/class',
  7. 'jira/data/session-storage',
  8. 'jira/shifter/shifter-select',
  9. 'jira/ajs/list/group-descriptor',
  10. 'jira/ajs/list/item-descriptor-factory',
  11. 'jira/shifter/shifter-analytics',
  12. 'jquery',
  13. 'underscore'
  14. ], function(
  15. Deferred,
  16. Class,
  17. sessionStorage,
  18. ShifterSelect,
  19. GroupDescriptor,
  20. ItemDescriptorFactory,
  21. ShifterAnalytics,
  22. jQuery,
  23. _
  24. ) {
  25. /**
  26. * @class ShifterDialog
  27. * @extends Class
  28. * @alias module:jira/shifter/shifter-dialog
  29. */
  30. return Class.extend({
  31. BLUR_DELAY: 50,
  32. /**
  33. * @constructs
  34. * @param {String} id - unique id for this dialog
  35. * @param {ShifterGroup[]} groups
  36. * @param {Object} options
  37. * @param {Number} options.maxResultsDisplayedPerGroup
  38. */
  39. init: function(id, groups, options) {
  40. this.id = id;
  41. this.groups = groups;
  42. this.options = options;
  43. this._render();
  44. this._destroyOnBlur();
  45. this._preventFocusOnNonInputElements();
  46. jQuery(document).on('mousedown.shifterdialog.' + id, _.bind(this._destroyOnMousedownOutside, this));
  47. },
  48. focus: function() {
  49. if (this.$dialog) {
  50. this.$dialog.find('input').focus();
  51. }
  52. },
  53. destroy: function() {
  54. var $dialog = this.$dialog;
  55. if ($dialog) {
  56. $dialog.stop().animate({
  57. top: -1 * $dialog.height()
  58. }, 100, function() {
  59. $dialog.remove();
  60. });
  61. this.$dialog = null;
  62. jQuery(document).off('mousedown.shifterdialog.' + this.id);
  63. }
  64. },
  65. destroyed: function() {
  66. return !this.$dialog;
  67. },
  68. saveLastQuery: function(query) {
  69. sessionStorage.setItem('JIRA.Shifter.lastQuery', query);
  70. },
  71. getLastQuery: function() {
  72. return sessionStorage.getItem('JIRA.Shifter.lastQuery');
  73. },
  74. enterLoadingState: function() {
  75. var $dialog = this.$dialog;
  76. $dialog.addClass('loading-action');
  77. $dialog.find('.aui-list').slideUp(200);
  78. },
  79. _render: function() {
  80. var html = JIRA.Templates.Shifter.dialog({
  81. id: this.id
  82. });
  83. var $dialog = this.$dialog = jQuery(html).appendTo('body');
  84. var shifterSelect = this.shifterSelect = new ShifterSelect({
  85. id: this.id,
  86. element: $dialog.find('.aui-list'),
  87. groups: this.groups,
  88. suggestionsHandler: this._makeSuggestionsHandler(),
  89. onSelection: _.bind(this._onSelection, this),
  90. maxResultsDisplayedPerGroup: this.options.maxResultsDisplayedPerGroup
  91. });
  92. if (this.getLastQuery()) {
  93. shifterSelect.$field.val(this.getLastQuery()).select();
  94. shifterSelect.onEdit();
  95. }
  96. shifterSelect.$field.on('keyup', _.bind(function(e) {
  97. if (e.which === jQuery.ui.keyCode.ESCAPE) {
  98. e.stopPropagation();
  99. this.destroy();
  100. }
  101. }, this));
  102. //JRADEV-19747 - Hide any layer to avoid conflicts with the keyboard handling (up, down, return...)
  103. if (AJS.currentLayerItem && AJS.currentLayerItem.hide) {
  104. AJS.currentLayerItem.hide();
  105. }
  106. //NEXT-851 dropdown2 is not store as currentLayerItem so we have to manually close them
  107. this._closeDropdownsIfNeeded();
  108. $dialog.css('top', -1 * $dialog.height()).animate({
  109. top: 0
  110. }, 100);
  111. },
  112. _closeDropdownsIfNeeded: function () {
  113. jQuery('.aui-dropdown2-trigger.active').trigger('aui-button-invoke');
  114. },
  115. _destroyOnBlur: function() {
  116. this.$dialog.find('input').blur(_.bind(function() {
  117. setTimeout(_.bind(function() {
  118. if (this.$dialog && !jQuery.contains(this.$dialog[0], document.activeElement)) {
  119. this.destroy();
  120. }
  121. }, this), this.BLUR_DELAY);
  122. }, this));
  123. },
  124. /**
  125. * Preventing focus when clicking on elements inside the dialog doesn't completely work in IE8
  126. */
  127. _destroyOnMousedownOutside: function(e) {
  128. if (this.$dialog.find(e.target).length === 0 && e.target !== this.$dialog) {
  129. this.destroy();
  130. }
  131. },
  132. _preventFocusOnNonInputElements: function() {
  133. var $inputs = this.$dialog.find('input');
  134. this.$dialog.mousedown(function(e) {
  135. if (jQuery.inArray(e.target, $inputs) === -1) {
  136. e.preventDefault();
  137. }
  138. });
  139. },
  140. _makeSuggestionsHandler: function() {
  141. var groups = this.groups;
  142. return Class.extend({
  143. execute: function(query) {
  144. var suggestions = [];
  145. var masterDeferred = Deferred();
  146. var deferredsRemaining = groups.length;
  147. _.map(groups, function(group, groupIndex) {
  148. return group.getSuggestions(query).done(function(groupSuggestions) {
  149. if (!_.isArray(groupSuggestions)) {
  150. return;
  151. }
  152. suggestions.push(new GroupDescriptor({
  153. label: group.name,
  154. description: group.context,
  155. weight: group.weight,
  156. items: _.map(groupSuggestions, function(suggestion) {
  157. return ItemDescriptorFactory.createItemDescriptor(suggestion, groupIndex);
  158. })
  159. }));
  160. // Keep the groups sorted
  161. suggestions.sort(function(a,b){ return a.weight() - b.weight(); });
  162. }).always(function() {
  163. deferredsRemaining--;
  164. if (deferredsRemaining === 0) {
  165. masterDeferred.resolve(suggestions, query);
  166. }
  167. });
  168. });
  169. return masterDeferred;
  170. }
  171. });
  172. },
  173. _onSelection: function(group, value, label) {
  174. ShifterAnalytics.selection(label, value, group.id);
  175. this.saveLastQuery(label);
  176. var ret = group.onSelection(value, label);
  177. if (ret && _.isFunction(ret.always)) {
  178. this.enterLoadingState();
  179. ret.always(_.bind(this.destroy, this));
  180. } else {
  181. this.destroy();
  182. }
  183. }
  184. });
  185. });
  186. AJS.namespace('JIRA.ShifterComponent.ShifterDialog', null, require('jira/shifter/shifter-dialog'));