events.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. const VE = {
  2. core: {
  3. /**
  4. * Main method that invokes further event processing
  5. * @param root is root HTML DOM element that. Pass HTML DOM Element or css selector
  6. * @param event_type (eg: click, mouseover etc..)
  7. */
  8. register: (root, event_type) => {
  9. root = !root ? 'body' : root; // if elm is not passed just bind events to body DOM Element
  10. event_type = !event_type ? 'click' : event_type; // set event type to "click" by default
  11. $(root).bind(event_type, (evt) => {
  12. VE.core.dispatch(evt, $(evt.target), event_type); // dispatch captured event
  13. });
  14. },
  15. /**
  16. * Dispatch event that was previously registered
  17. * @param evt related event object
  18. * @param elm that was catched
  19. * @param event_type (eg: click, mouseover etc..)
  20. */
  21. dispatch: (evt, elm, event_type) => {
  22. if ('undefined' == typeof VE.callbacks[event_type]) {
  23. return VE.helpers.warn(
  24. 'There is no corresponding object that should contain event callbacks for "' +
  25. event_type +
  26. '" event type'
  27. );
  28. }
  29. // get class of element
  30. const classes = $(elm).attr('class');
  31. // if no classes are attached, then just stop any further processings
  32. if (!classes) {
  33. return; // no classes assigned
  34. }
  35. // split the classes and check if it related to function
  36. $(classes.split(/\s/)).each((i, key) => {
  37. VE.callbacks[event_type][key] && VE.callbacks[event_type][key](evt, elm);
  38. });
  39. },
  40. },
  41. navigation: {
  42. state: {
  43. active_menu: 1,
  44. menu_selector: '.main-menu-item',
  45. menu_active_selector: '.active',
  46. },
  47. enter_focused: () => {
  48. if ($('.units').hasClass('active')) {
  49. location.href = $(
  50. '.units.active .l-unit.focus .actions-panel__col.actions-panel__edit a'
  51. ).attr('href');
  52. } else {
  53. if ($(VE.navigation.state.menu_selector + '.focus a').attr('href')) {
  54. location.href = $(VE.navigation.state.menu_selector + '.focus a').attr('href');
  55. }
  56. }
  57. },
  58. move_focus_left: () => {
  59. let index = parseInt(
  60. $(VE.navigation.state.menu_selector).index($(VE.navigation.state.menu_selector + '.focus'))
  61. );
  62. if (index == -1)
  63. index = parseInt(
  64. $(VE.navigation.state.menu_selector).index($(VE.navigation.state.menu_active_selector))
  65. );
  66. if ($('.units').hasClass('active')) {
  67. $('.units').removeClass('active');
  68. index++;
  69. }
  70. $(VE.navigation.state.menu_selector).removeClass('focus');
  71. if (index > 0) {
  72. $($(VE.navigation.state.menu_selector)[index - 1]).addClass('focus');
  73. } else {
  74. VE.navigation.switch_menu('last');
  75. }
  76. },
  77. move_focus_right: () => {
  78. const max_index = $(VE.navigation.state.menu_selector).length - 1;
  79. let index = parseInt(
  80. $(VE.navigation.state.menu_selector).index($(VE.navigation.state.menu_selector + '.focus'))
  81. );
  82. if (index == -1)
  83. index =
  84. parseInt(
  85. $(VE.navigation.state.menu_selector).index($(VE.navigation.state.menu_active_selector))
  86. ) || 0;
  87. $(VE.navigation.state.menu_selector).removeClass('focus');
  88. if ($('.units').hasClass('active')) {
  89. $('.units').removeClass('active');
  90. index--;
  91. }
  92. if (index < max_index) {
  93. $($(VE.navigation.state.menu_selector)[index + 1]).addClass('focus');
  94. } else {
  95. VE.navigation.switch_menu('first');
  96. }
  97. },
  98. move_focus_down: () => {
  99. const max_index = $('.units .l-unit:not(.header)').length - 1;
  100. let index = parseInt($('.units .l-unit').index($('.units .l-unit.focus')));
  101. if (index < max_index) {
  102. $('.units .l-unit.focus').removeClass('focus');
  103. $($('.units .l-unit:not(.header)')[index + 1]).addClass('focus');
  104. $('html, body').animate({ scrollTop: $('.units .l-unit.focus').offset().top - 200 }, 200);
  105. }
  106. },
  107. move_focus_up: () => {
  108. let index = parseInt($('.units .l-unit:not(.header)').index($('.units .l-unit.focus')));
  109. if (index == -1) index = 0;
  110. if (index > 0) {
  111. $('.units .l-unit.focus').removeClass('focus');
  112. $($('.units .l-unit:not(.header)')[index - 1]).addClass('focus');
  113. $('html, body').animate({ scrollTop: $('.units .l-unit.focus').offset().top - 200 }, 200);
  114. }
  115. },
  116. switch_menu: (position) => {
  117. position = position || 'first'; // last
  118. if (VE.navigation.state.active_menu == 0) {
  119. VE.navigation.state.active_menu = 1;
  120. VE.navigation.state.menu_selector = '.main-menu-item';
  121. VE.navigation.state.menu_active_selector = '.active';
  122. if (position == 'first') {
  123. $($(VE.navigation.state.menu_selector)[0]).addClass('focus');
  124. } else {
  125. const max_index = $(VE.navigation.state.menu_selector).length - 1;
  126. $($(VE.navigation.state.menu_selector)[max_index]).addClass('focus');
  127. }
  128. }
  129. },
  130. shortcut: (elm) => {
  131. /** @type {'js' | 'href'} */
  132. const action = elm.attr('key-action');
  133. switch (action) {
  134. case 'js':
  135. VE.core.dispatch(true, elm.find('.data-controls'), 'click');
  136. break;
  137. case 'href':
  138. location.href = elm.find('a').attr('href');
  139. break;
  140. default:
  141. break;
  142. }
  143. },
  144. },
  145. callbacks: {
  146. click: {
  147. do_suspend: (evt, elm) => {
  148. const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
  149. const url = $('input[name="suspend_url"]', ref).val();
  150. const dialog_elm = ref.find('.js-confirm-dialog-suspend');
  151. VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
  152. },
  153. do_unsuspend: (evt, elm) => {
  154. const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
  155. const url = $('input[name="unsuspend_url"]', ref).val();
  156. const dialog_elm = ref.find('.js-confirm-dialog-suspend');
  157. VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
  158. },
  159. do_delete: (evt, elm) => {
  160. const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
  161. const url = $('input[name="delete_url"]', ref).val();
  162. const dialog_elm = ref.find('.js-confirm-dialog-delete');
  163. VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
  164. },
  165. do_servicerestart: (evt, elm) => {
  166. const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
  167. const url = $('input[name="servicerestart_url"]', ref).val();
  168. const dialog_elm = ref.find('.js-confirm-dialog-servicerestart');
  169. VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
  170. },
  171. do_servicestop: (evt, elm) => {
  172. const ref = elm.hasClass('actions-panel') ? elm : elm.parents('.actions-panel');
  173. const url = $('input[name="servicestop_url"]', ref).val();
  174. const dialog_elm = ref.find('.js-confirm-dialog-servicestop');
  175. VE.helpers.createConfirmationDialog(dialog_elm, $(elm).parent().attr('title'), url);
  176. },
  177. },
  178. },
  179. helpers: {
  180. /**
  181. * Create dialog box on the fly
  182. * @param elm Element which contains the dialog contents
  183. * @param dialog_title
  184. * @param confirmed_location_url URL that will be redirected to if user hit "OK"
  185. * @param custom_config Custom configuration parameters passed to dialog initialization (optional)
  186. */
  187. createConfirmationDialog: (elm, dialog_title, confirmed_location_url, custom_config) => {
  188. custom_config = custom_config ?? {};
  189. const default_config = {
  190. modal: true,
  191. //autoOpen: true,
  192. resizable: false,
  193. width: 360,
  194. title: dialog_title,
  195. close: function () {
  196. $(this).dialog('destroy');
  197. },
  198. buttons: {
  199. OK: function () {
  200. location.href = confirmed_location_url;
  201. },
  202. Cancel: function () {
  203. $(this).dialog('close');
  204. },
  205. },
  206. create: function () {
  207. const buttonGroup = $(this).closest('.ui-dialog').find('.ui-dialog-buttonset');
  208. buttonGroup.find('button:first').addClass('button submit');
  209. buttonGroup.find('button:last').addClass('button button-secondary cancel');
  210. },
  211. };
  212. const reference_copied = $(elm[0]).clone();
  213. const config = { ...default_config, ...custom_config };
  214. $(reference_copied).dialog(config);
  215. },
  216. warn: (msg) => {
  217. alert('WARNING: ' + msg);
  218. },
  219. extendPasswordFields: () => {
  220. const references = ['.js-password-input'];
  221. $(document).ready(() => {
  222. $(references).each((i, ref) => {
  223. VE.helpers.initAdditionalPasswordFieldElements(ref);
  224. });
  225. });
  226. },
  227. initAdditionalPasswordFieldElements: (ref) => {
  228. const enabled = Cookies.read('hide_passwords') == 1 ? true : false;
  229. if (enabled) {
  230. Cookies.set('hide_passwords', 1, 365);
  231. $(ref).prop('type', 'password');
  232. }
  233. $(ref).prop('autocomplete', 'off');
  234. const html =
  235. '<span class="toggle-password"><i class="toggle-psw-visibility-icon fas fa-eye-slash ' +
  236. enabled
  237. ? ''
  238. : 'u-opacity-50' +
  239. '" onclick="VE.helpers.toggleHiddenPasswordText(\'' +
  240. ref +
  241. '\', this)"></i></span>';
  242. $(ref).after(html);
  243. },
  244. toggleHiddenPasswordText: (ref, triggering_elm) => {
  245. $(triggering_elm).toggleClass('u-opacity-50');
  246. if ($(ref).prop('type') == 'text') {
  247. Cookies.set('hide_passwords', 1, 365);
  248. $(ref).prop('type', 'password');
  249. } else {
  250. Cookies.set('hide_passwords', 0, 365);
  251. $(ref).prop('type', 'text');
  252. }
  253. },
  254. },
  255. tmp: {
  256. sort_par: 'sort-name',
  257. sort_direction: -1,
  258. sort_as_int: false,
  259. },
  260. };
  261. VE.helpers.extendPasswordFields();