Fork of FusionPBX but with LDAP kinda working
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1144 lines
43 KiB

2 years ago
  1. {* <?php *}
  2. {*//set the doctype *}
  3. {if $browser_name == 'Internet Explorer'}
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  5. {else}
  6. <!DOCTYPE html>
  7. {/if}
  8. <html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  9. <head>
  10. <meta charset='utf-8'>
  11. <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
  12. <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  13. <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' />
  14. {*//external css files *}
  15. <link rel='stylesheet' type='text/css' href='{$project_path}/resources/bootstrap/css/bootstrap.min.css.php'>
  16. <link rel='stylesheet' type='text/css' href='{$project_path}/resources/bootstrap/css/bootstrap-tempusdominus.min.css.php'>
  17. <link rel='stylesheet' type='text/css' href='{$project_path}/resources/bootstrap/css/bootstrap-colorpicker.min.css.php'>
  18. <link rel='stylesheet' type='text/css' href='{$project_path}/resources/fontawesome/css/all.min.css.php'>
  19. <link rel='stylesheet' type='text/css' href='{$project_path}/themes/default/css.php'>
  20. {*//link to custom css file *}
  21. {if $settings.theme.custom_css}
  22. <link rel='stylesheet' type='text/css' href='{$settings.theme.custom_css}'>
  23. {/if}
  24. {*//set favorite icon *}
  25. <link rel='icon' href='{$settings.theme.favicon}'>
  26. {*//document title *}
  27. <title>{$document_title}</title>
  28. {*//remote javascript *}
  29. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/jquery/jquery.min.js.php'></script>
  30. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/jquery/jquery.autosize.input.js.php'></script>
  31. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/momentjs/moment-with-locales.min.js.php'></script>
  32. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/bootstrap/js/bootstrap.min.js.php'></script>
  33. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/bootstrap/js/bootstrap-tempusdominus.min.js.php'></script>
  34. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/bootstrap/js/bootstrap-colorpicker.min.js.php'></script>
  35. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/bootstrap/js/bootstrap-pwstrength.min.js.php'></script>
  36. <script language='JavaScript' type='text/javascript'>{literal}window.FontAwesomeConfig = { autoReplaceSvg: false }{/literal}</script>
  37. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/fontawesome/js/solid.min.js.php' defer></script>
  38. {*//web font loader *}
  39. {if $settings.theme.font_loader == 'true'}
  40. {if $settings.theme.font_retrieval != 'asynchronous'}
  41. <script language='JavaScript' type='text/javascript' src='//ajax.googleapis.com/ajax/libs/webfont/{$settings.theme.font_loader_version}/webfont.js'></script>
  42. {/if}
  43. <script language='JavaScript' type='text/javascript' src='{$project_path}/resources/fonts/web_font_loader.php?v={$settings.theme.font_loader_version}'></script>
  44. {/if}
  45. {*//local javascript *}
  46. <script language='JavaScript' type='text/javascript'>
  47. //message bar display
  48. {literal}
  49. function display_message(msg, mood, delay) {
  50. mood = mood !== undefined ? mood : 'default';
  51. delay = delay !== undefined ? delay : {/literal}{$settings.theme.message_delay}{literal};
  52. if (msg !== '') {
  53. var message_text = $(document.createElement('div'));
  54. message_text.addClass('message_text message_mood_'+mood);
  55. message_text.html(msg);
  56. message_text.on('click', function() {
  57. var object = $(this);
  58. object.clearQueue().finish();
  59. $('#message_container div').remove();
  60. $('#message_container').css({opacity: 0, 'height': 0}).css({'height': 'auto'});
  61. } );
  62. $('#message_container').append(message_text);
  63. message_text.css({'height': 'auto'}).animate({opacity: 1}, 250, function(){
  64. $('#message_container').delay(delay).animate({opacity: 0, 'height': 0}, 500, function() {
  65. $('#message_container div').remove();
  66. $('#message_container').animate({opacity: 1}, 300).css({'height': 'auto'});
  67. });
  68. });
  69. }
  70. }
  71. {/literal}
  72. {if $settings.theme.menu_style == 'side'}
  73. //side menu visibility toggle
  74. var menu_side_expand_timer;
  75. var menu_side_contract_timer;
  76. var menu_side_state_current = '{if $menu_side_state == 'hidden'}expanded{else}{$menu_side_state}{/if}';
  77. {literal}
  78. function menu_side_contract_start() {
  79. menu_side_contract_timer = setTimeout(function() {
  80. menu_side_contract();
  81. }, {/literal}{$settings.theme.menu_side_toggle_hover_delay_contract}{literal});
  82. }
  83. function menu_side_contract() {
  84. if (menu_side_state_current == 'expanded') {
  85. {/literal}
  86. {if $menu_side_state == 'hidden'}
  87. {literal}
  88. $('#menu_side_container').hide();
  89. {/literal}
  90. {else}
  91. {literal}
  92. $('.menu_side_sub').slideUp(180);
  93. $('.menu_side_item_title').hide();
  94. {/literal}
  95. {if $settings.theme.menu_brand_type == 'image' || $settings.theme.menu_brand_type == 'image_text' || $settings.theme.menu_brand_type == ''}
  96. {literal}
  97. $('#menu_brand_image_expanded').fadeOut(180, function() {
  98. $('#menu_brand_image_contracted').fadeIn(180);
  99. });
  100. {/literal}
  101. {else if $settings.theme.menu_brand_type == 'text'}
  102. {literal}
  103. $('.menu_brand_text').hide();
  104. {/literal}
  105. {/if}
  106. {literal}
  107. $('.menu_side_control_state').hide();
  108. $('.menu_side_item_main_sub_icons').hide();
  109. $('.sub_arrows').removeClass('fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_contract}{literal}').addClass('fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_expand}{literal}');
  110. $('#menu_side_container').animate({ width: '{/literal}{$settings.theme.menu_side_width_contracted}{literal}px' }, 180, function() {
  111. menu_side_state_current = 'contracted';
  112. });
  113. {/literal}
  114. {if $settings.theme.menu_side_toggle_body_width == 'shrink' || ($settings.theme.menu_side_state == 'expanded' && $settings.theme.menu_side_toggle_body_width == 'fixed')}
  115. {literal}
  116. if ($(window).width() >= 576) {
  117. $('#content_container').animate({ width: $(window).width() - {/literal}{$settings.theme.menu_side_width_contracted}{literal} }, 250);
  118. }
  119. {/literal}
  120. {/if}
  121. {literal}
  122. $('.menu_side_contract').hide();
  123. $('.menu_side_expand').show();
  124. if ($(window).width() < 576) {
  125. $('#menu_side_container').hide();
  126. }
  127. {/literal}
  128. {/if}
  129. {literal}
  130. }
  131. }
  132. function menu_side_expand_start() {
  133. menu_side_expand_timer = setTimeout(function() {
  134. menu_side_expand();
  135. }, {/literal}{$settings.theme.menu_side_toggle_hover_delay_expand}{literal});
  136. }
  137. function menu_side_expand() {
  138. {/literal}
  139. {if $menu_side_state == 'hidden'}
  140. {literal}
  141. $('.menu_side_contract').show();
  142. {/literal}
  143. {if $settings.theme.menu_brand_type == 'image' || $settings.theme.menu_brand_type == 'image_text' || $settings.theme.menu_brand_type == ''}
  144. {literal}
  145. $('#menu_brand_image_contracted').hide();
  146. $('#menu_brand_image_expanded').show();
  147. {/literal}
  148. {/if}
  149. {literal}
  150. $('.menu_side_control_state').show();
  151. $('.menu_brand_text').show();
  152. $('.menu_side_item_main_sub_icons').show();
  153. $('.menu_side_item_title').show();
  154. if ($(window).width() < 576) {
  155. $('#menu_side_container').width($(window).width());
  156. }
  157. $('#menu_side_container').show();
  158. {/literal}
  159. {else}
  160. {if $settings.theme.menu_brand_type == 'image' || $settings.theme.menu_brand_type == 'image_text' ||$settings.theme.menu_brand_type == ''}
  161. {literal}
  162. $('#menu_brand_image_contracted').fadeOut(180);
  163. {/literal}
  164. {/if}
  165. {literal}
  166. $('.menu_side_expand').hide();
  167. $('.menu_side_contract').show();
  168. $('#menu_side_container').show();
  169. var menu_side_container_width = $(window).width() < 576 ? $(window).width() : '{/literal}{$settings.theme.menu_side_width_expanded}{literal}px';
  170. $('#menu_side_container').animate({ width: menu_side_container_width }, 180, function() {
  171. {/literal}
  172. {if $settings.theme.menu_brand_type == 'image' || $settings.theme.menu_brand_type == 'image_text' || $settings.theme.menu_brand_type == ''}
  173. {literal}
  174. $('#menu_brand_image_expanded').fadeIn(180);
  175. {/literal}
  176. {/if}
  177. {literal}
  178. $('.menu_side_control_state').fadeIn(180);
  179. $('.menu_brand_text').fadeIn(180);
  180. $('.menu_side_item_main_sub_icons').fadeIn(180);
  181. $('.menu_side_item_title').fadeIn(180, function() {
  182. menu_side_state_current = 'expanded';
  183. });
  184. });
  185. {/literal}
  186. {if $settings.theme.menu_side_toggle_body_width == 'shrink' || ($settings.theme.menu_side_state == 'expanded' && $settings.theme.menu_side_toggle_body_width == 'fixed')}
  187. {literal}
  188. if ($(window).width() >= 576) {
  189. $('#content_container').animate({ width: $(window).width() - {/literal}{$settings.theme.menu_side_width_expanded}{literal} }, 250);
  190. }
  191. {/literal}
  192. {/if}
  193. {/if}
  194. {literal}
  195. }
  196. function menu_side_item_toggle(item_id) {
  197. $('#sub_arrow_'+item_id).toggleClass(['fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_contract}{literal}','fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_expand}{literal}']);
  198. $('.sub_arrows').not('#sub_arrow_'+item_id).removeClass('fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_contract}{literal}').addClass('fa-{/literal}{$settings.theme.menu_side_item_main_sub_icon_expand}{literal}');
  199. $('#sub_'+item_id).slideToggle(180, function() {
  200. {/literal}
  201. {if $settings.theme.menu_side_item_main_sub_close != 'manual'}
  202. {literal}
  203. if (!$(this).is(':hidden')) {
  204. $('.menu_side_sub').not($(this)).slideUp(180);
  205. }
  206. {/literal}
  207. {/if}
  208. {literal}
  209. });
  210. }
  211. function menu_side_state_set(state) {
  212. var user_setting_set_path = '{/literal}{$project_path}{literal}/core/user_settings/user_setting_set.php?category=theme&subcategory=menu_side_state&name=text&value='+state;
  213. var xhr = new XMLHttpRequest();
  214. xhr.open('GET', user_setting_set_path);
  215. xhr.send(null);
  216. xhr.onreadystatechange = function () {
  217. var setting_modified;
  218. if (xhr.readyState === 4) {
  219. if (xhr.status === 200) {
  220. setting_modified = xhr.responseText;
  221. if (setting_modified == 'true') {
  222. document.getElementById('menu_side_state_set_expanded').style.display = state == 'expanded' ? 'none' : 'block';
  223. document.getElementById('menu_side_state_set_contracted').style.display = state == 'contracted' ? 'none' : 'block';
  224. {/literal}
  225. {if $menu_side_state == 'hidden'}
  226. {literal}
  227. document.getElementById('menu_side_state_hidden_button').style.display='none';
  228. {/literal}
  229. {/if}
  230. {literal}
  231. if (state == 'expanded') {
  232. if ($(window).width() >= 576) {
  233. $('#content_container').animate({ width: $(window).width() - {/literal}{$settings.theme.menu_side_width_expanded}{literal} }, 250);
  234. }
  235. else {
  236. $('#menu_side_container').animate({ width: $(window).width() }, 180);
  237. }
  238. document.getElementById('menu_side_state_current').value = 'expanded';
  239. display_message("{/literal}{$text.theme_message_menu_expanded}{literal}", 'positive', 1000);
  240. }
  241. else {
  242. menu_side_contract();
  243. if ($(window).width() >= 576) {
  244. $('#content_container').animate({ width: $(window).width() - {/literal}{$settings.theme.menu_side_width_contracted}{literal} }, 250);
  245. }
  246. menu_side_state_current = 'contracted';
  247. document.getElementById('menu_side_state_current').value = 'contracted';
  248. display_message("{/literal}{$text.theme_message_menu_contracted}{literal}", 'positive', 1000);
  249. }
  250. }
  251. else if (setting_modified == 'deleted') {
  252. display_message("{/literal}{$text.theme_message_menu_reset}{literal}", 'positive', 1000);
  253. document.location.reload();
  254. }
  255. }
  256. }
  257. }
  258. }
  259. {/literal}
  260. {/if}
  261. {literal}
  262. $(document).ready(function() {
  263. {/literal}
  264. {$messages}
  265. //message bar hide on hover
  266. {literal}
  267. $('#message_container').on('mouseenter',function() {
  268. $('#message_container div').remove();
  269. $('#message_container').css({opacity: 0, 'height': 0}).css({'height': 'auto'});
  270. });
  271. {/literal}
  272. //domain selector controls
  273. {if $domain_selector_enabled}
  274. {literal}
  275. $('.domain_selector_domain').on('click', function() { show_domains(); });
  276. $('#header_domain_selector_domain').on('click', function() { show_domains(); });
  277. $('#domains_hide').on('click', function() { hide_domains(); });
  278. function show_domains() {
  279. $('#domains_visible').val(1);
  280. var scrollbar_width = (window.innerWidth - $(window).width()); //gold: only solution that worked with body { overflow:auto } (add -ms-overflow-style: scrollbar; to <body> style for ie 10+)
  281. if (scrollbar_width > 0) {
  282. $('body').css({'margin-right':scrollbar_width, 'overflow':'hidden'}); //disable body scroll bars
  283. $('.navbar').css('margin-right',scrollbar_width); //adjust navbar margin to compensate
  284. $('#domains_container').css('right',-scrollbar_width); //domain container right position to compensate
  285. }
  286. $(document).scrollTop(0);
  287. $('#domains_container').show();
  288. $('#domains_block').animate({marginRight: '+=300'}, 400, function() {
  289. $('#domains_filter').trigger('focus');
  290. });
  291. }
  292. function hide_domains() {
  293. $('#domains_visible').val(0);
  294. $(document).ready(function() {
  295. $('#domains_block').animate({marginRight: '-=300'}, 400, function() {
  296. $('#domains_filter').val('');
  297. domain_search($('#domains_filter').val());
  298. $('.navbar').css('margin-right','0'); //restore navbar margin
  299. $('#domains_container').css('right','0'); //domain container right position
  300. $('#domains_container').hide();
  301. $('body').css({'margin-right':'0','overflow':'auto'}); //enable body scroll bars
  302. document.activeElement.blur();
  303. });
  304. });
  305. }
  306. {/literal}
  307. {/if}
  308. //keyboard shortcut scripts
  309. //key: [enter] - retain default behavior to submit form, when present - note: safari does not honor the first submit element when hiding it using 'display: none;' in the setAttribute method
  310. {if $settings.theme.keyboard_shortcut_submit_enabled}
  311. {literal}
  312. var action_bar_actions, first_form, first_submit, modal_input_class, modal_continue_button;
  313. action_bar_actions = document.querySelector('div#action_bar.action_bar > div.actions');
  314. first_form = document.querySelector('form#frm');
  315. if (action_bar_actions !== null) {
  316. if (first_form !== null) {
  317. first_submit = document.createElement('input');
  318. first_submit.type = 'submit';
  319. first_submit.id = 'default_submit';
  320. first_submit.setAttribute('style','position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden;');
  321. first_form.prepend(first_submit);
  322. window.addEventListener('keydown',function(e){
  323. modal_input_class = e.target.className;
  324. if (e.which == 13 && (e.target.tagName == 'INPUT' || e.target.tagName == 'SELECT')) {
  325. if (modal_input_class.includes('modal-input')) {
  326. e.preventDefault();
  327. modal_continue_button = document.getElementById(e.target.dataset.continue);
  328. if (modal_continue_button) { modal_continue_button.click(); }
  329. }
  330. else {
  331. if (typeof window.submit_form === 'function') { submit_form(); }
  332. else { document.getElementById('frm').submit(); }
  333. }
  334. }
  335. });
  336. }
  337. }
  338. {/literal}
  339. {/if}
  340. //common (used by delete and toggle)
  341. {if $settings.theme.keyboard_shortcut_delete_enabled || $settings.theme.keyboard_shortcut_toggle_enabled}
  342. var list_checkboxes;
  343. list_checkboxes = document.querySelectorAll('table.list tr.list-row td.checkbox input[type=checkbox]');
  344. {/if}
  345. //keyup event listener
  346. {literal}
  347. window.addEventListener('keyup', function(e) {
  348. {/literal}
  349. //key: [escape] - close modal window, if open, or toggle domain selector
  350. {literal}
  351. if (e.which == 27) {
  352. e.preventDefault();
  353. var modals, modal_visible, modal;
  354. modal_visible = false;
  355. modals = document.querySelectorAll('div.modal-window');
  356. if (modals.length !== 0) {
  357. for (var x = 0, max = modals.length; x < max; x++) {
  358. modal = document.getElementById(modals[x].id);
  359. if (window.getComputedStyle(modal).getPropertyValue('opacity') == 1) {
  360. modal_visible = true;
  361. }
  362. }
  363. }
  364. if (modal_visible) {
  365. modal_close();
  366. }
  367. {/literal}
  368. {if $domain_selector_enabled}
  369. {literal}
  370. else {
  371. if (document.getElementById('domains_visible').value == 0) {
  372. show_domains();
  373. }
  374. else {
  375. hide_domains();
  376. }
  377. }
  378. {/literal}
  379. {/if}
  380. {literal}
  381. }
  382. {/literal}
  383. //key: [insert], list: to add
  384. {if $settings.theme.keyboard_shortcut_add_enabled}
  385. {literal}
  386. if (e.which == 45 && !(e.target.tagName == 'INPUT' && e.target.type == 'text') && e.target.tagName != 'TEXTAREA') {
  387. e.preventDefault();
  388. var add_button;
  389. add_button = document.getElementById('btn_add');
  390. if (add_button === null || add_button === undefined) {
  391. add_button = document.querySelector('button[name=btn_add]');
  392. }
  393. if (add_button !== null) { add_button.click(); }
  394. }
  395. {/literal}
  396. {/if}
  397. //key: [delete], list: to delete checked, edit: to delete
  398. {if $settings.theme.keyboard_shortcut_delete_enabled}
  399. {literal}
  400. if (e.which == 46 && !(e.target.tagName == 'INPUT' && e.target.type == 'text') && e.target.tagName != 'TEXTAREA') {
  401. e.preventDefault();
  402. var delete_button;
  403. delete_button = document.querySelector('button[name=btn_delete]');
  404. if (delete_button === null || delete_button === undefined) {
  405. delete_button = document.getElementById('btn_delete');
  406. }
  407. if (delete_button !== null) { delete_button.click(); }
  408. }
  409. {/literal}
  410. {/if}
  411. //key: [space], list,edit:prevent default space key behavior when opening toggle confirmation (which would automatically *click* the focused continue button on key-up)
  412. {if $settings.theme.keyboard_shortcut_toggle_enabled}
  413. {literal}
  414. if (e.which == 32 && e.target.id == 'btn_toggle') {
  415. e.preventDefault();
  416. }
  417. {/literal}
  418. {/if}
  419. //keyup end
  420. {literal}
  421. });
  422. {/literal}
  423. //keydown event listener
  424. {literal}
  425. window.addEventListener('keydown', function(e) {
  426. {/literal}
  427. //key: [space], list: to toggle checked - note: for default [space] checkbox behavior (ie. toggle focused checkbox) include in the if statement: && !(e.target.tagName == 'INPUT' && e.target.type == 'checkbox')
  428. {if $settings.theme.keyboard_shortcut_toggle_enabled}
  429. {literal}
  430. if (e.which == 32 && !(e.target.tagName == 'INPUT' && e.target.type == 'text') && e.target.tagName != 'BUTTON' && !(e.target.tagName == 'INPUT' && e.target.type == 'button') && !(e.target.tagName == 'INPUT' && e.target.type == 'submit') && e.target.tagName != 'TEXTAREA' && list_checkboxes.length !== 0) {
  431. e.preventDefault();
  432. var toggle_button;
  433. toggle_button = document.querySelector('button[name=btn_toggle]');
  434. if (toggle_button === null || toggle_button === undefined) {
  435. toggle_button = document.getElementById('btn_toggle');
  436. }
  437. if (toggle_button !== null) { toggle_button.click(); }
  438. }
  439. {/literal}
  440. {/if}
  441. //key: [ctrl]+[a], list,edit: to check all
  442. {if $settings.theme.keyboard_shortcut_check_all_enabled}
  443. {literal}
  444. if ((((e.which == 97 || e.which == 65) && (e.ctrlKey || e.metaKey) && !e.shiftKey) || e.which == 19) && !(e.target.tagName == 'INPUT' && e.target.type == 'text') && e.target.tagName != 'TEXTAREA') {
  445. var all_checkboxes;
  446. all_checkboxes = document.querySelectorAll('table.list tr.list-header th.checkbox input[name=checkbox_all]');
  447. if (typeof all_checkboxes != 'object' || all_checkboxes.length == 0) {
  448. all_checkboxes = document.querySelectorAll('td.edit_delete_checkbox_all > span > input[name=checkbox_all]');
  449. }
  450. if (typeof all_checkboxes == 'object' && all_checkboxes.length > 0) {
  451. e.preventDefault();
  452. for (var x = 0, max = all_checkboxes.length; x < max; x++) {
  453. all_checkboxes[x].click();
  454. }
  455. }
  456. }
  457. {/literal}
  458. {/if}
  459. //key: [ctrl]+[s], edit: to save
  460. {if $settings.theme.keyboard_shortcut_save_enabled}
  461. {literal}
  462. if (((e.which == 115 || e.which == 83) && (e.ctrlKey || e.metaKey) && !e.shiftKey) || (e.which == 19)) {
  463. e.preventDefault();
  464. var save_button;
  465. save_button = document.getElementById('btn_save');
  466. if (save_button === null || save_button === undefined) {
  467. save_button = document.querySelector('button[name=btn_save]');
  468. }
  469. if (save_button !== null) { save_button.click(); }
  470. }
  471. {/literal}
  472. {/if}
  473. //key: [ctrl]+[c], list,edit: to copy
  474. {if $settings.theme.keyboard_shortcut_copy_enabled}
  475. {if $browser_name_short == 'Safari'} //emulate with detecting [c] only, as [command] and [control] keys are ignored when captured
  476. {literal}
  477. if (
  478. (e.which == 99 || e.which == 67) &&
  479. !(e.target.tagName == 'INPUT' && e.target.type == 'text') &&
  480. !(e.target.tagName == 'INPUT' && e.target.type == 'password') &&
  481. e.target.tagName != 'TEXTAREA'
  482. ) {
  483. {/literal}
  484. {else}
  485. {literal}
  486. if (
  487. (
  488. (
  489. (e.which == 99 || e.which == 67) &&
  490. (e.ctrlKey || e.metaKey) &&
  491. !e.shiftKey
  492. ) ||
  493. e.which == 19
  494. ) &&
  495. !(e.target.tagName == 'INPUT' && e.target.type == 'text') &&
  496. e.target.tagName != 'TEXTAREA'
  497. ) {
  498. {/literal}
  499. {/if}
  500. {literal}
  501. var current_selection, copy_button;
  502. current_selection = window.getSelection();
  503. if (current_selection === null || current_selection === undefined || current_selection.toString() == '') {
  504. e.preventDefault();
  505. copy_button = document.querySelector('button[name=btn_copy]');
  506. if (copy_button === null || copy_button === undefined) {
  507. copy_button = document.getElementById('btn_copy');
  508. }
  509. if (copy_button !== null) { copy_button.click(); }
  510. }
  511. }
  512. {/literal}
  513. {/if}
  514. //keydown end
  515. {literal}
  516. });
  517. {/literal}
  518. //link list rows
  519. {literal}
  520. $('.tr_hover tr,.list tr').each(function(i,e) {
  521. $(e).children('td:not(.list_control_icon,.list_control_icons,.tr_link_void,.list-row > .no-link,.list-row > .checkbox,.list-row > .button,.list-row > .action-button)').on('click', function() {
  522. var href = $(this).closest('tr').attr('href');
  523. var target = $(this).closest('tr').attr('target');
  524. if (href) {
  525. if (target) { window.open(href, target); }
  526. else { window.location = href; }
  527. }
  528. });
  529. });
  530. {/literal}
  531. //autosize jquery autosize plugin on applicable input fields
  532. {literal}
  533. $('input[type=text].txt.auto-size,input[type=number].txt.auto-size,input[type=password].txt.auto-size,input[type=text].formfld.auto-size,input[type=number].formfld.auto-size,input[type=password].formfld.auto-size').autosizeInput();
  534. {/literal}
  535. //initialize bootstrap tempusdominus (calendar/datetime picker) plugin
  536. {literal}
  537. $(function() {
  538. //set defaults
  539. $.fn.datetimepicker.Constructor.Default = $.extend({}, $.fn.datetimepicker.Constructor.Default, {
  540. buttons: {
  541. showToday: true,
  542. showClear: true,
  543. showClose: true,
  544. },
  545. icons: {
  546. time: 'fas fa-clock',
  547. date: 'fas fa-calendar-alt',
  548. up: 'fas fa-arrow-up',
  549. down: 'fas fa-arrow-down',
  550. previous: 'fas fa-chevron-left',
  551. next: 'fas fa-chevron-right',
  552. today: 'fas fa-calendar-check',
  553. clear: 'fas fa-trash',
  554. close: 'fas fa-times',
  555. }
  556. });
  557. //define formatting of individual classes
  558. $('.datepicker').datetimepicker({ format: 'YYYY-MM-DD', });
  559. $('.datetimepicker').datetimepicker({ format: 'YYYY-MM-DD HH:mm', });
  560. $('.datetimesecpicker').datetimepicker({ format: 'YYYY-MM-DD HH:mm:ss', });
  561. });
  562. {/literal}
  563. //apply bootstrap colorpicker plugin
  564. {literal}
  565. $(function(){
  566. $('.colorpicker').colorpicker({
  567. align: 'left',
  568. customClass: 'colorpicker-2x',
  569. sliders: {
  570. saturation: {
  571. maxLeft: 200,
  572. maxTop: 200
  573. },
  574. hue: {
  575. maxTop: 200
  576. },
  577. alpha: {
  578. maxTop: 200
  579. }
  580. }
  581. });
  582. });
  583. {/literal}
  584. //apply bootstrap password strength plugin
  585. {literal}
  586. $('#password').pwstrength({
  587. common: {
  588. minChar: 8,
  589. usernameField: '#username',
  590. },
  591. //rules: { },
  592. ui: {
  593. colorClasses: ['danger', 'warning', 'warning', 'warning', 'success', 'success'], //weak,poor,normal,medium,good,strong
  594. progressBarMinPercentage: 15,
  595. showVerdicts: false,
  596. viewports: {
  597. progress: '#pwstrength_progress'
  598. }
  599. }
  600. });
  601. {/literal}
  602. //crossfade menu brand images (if hover version set)
  603. {if $settings.theme.menu_brand_image != '' && $settings.theme.menu_brand_image_hover != '' && $settings.theme.menu_style != 'side'}
  604. {literal}
  605. $(function(){
  606. $('#menu_brand_image').on('mouseover',function(){
  607. $(this).fadeOut('fast', function(){
  608. $('#menu_brand_image_hover').fadeIn('fast');
  609. });
  610. });
  611. $('#menu_brand_image_hover').on('mouseout',function(){
  612. $(this).fadeOut('fast', function(){
  613. $('#menu_brand_image').fadeIn('fast');
  614. });
  615. });
  616. });
  617. {/literal}
  618. {/if}
  619. //generate resizeEnd event after window resize event finishes (used when side menu and on messages app)
  620. {literal}
  621. $(window).on('resize', function() {
  622. if (this.resizeTO) { clearTimeout(this.resizeTO); }
  623. this.resizeTO = setTimeout(function() { $(this).trigger('resizeEnd'); }, 180);
  624. });
  625. {/literal}
  626. //side menu: adjust content container width after window resize
  627. {if $settings.theme.menu_style == 'side'}
  628. {literal}
  629. $(window).on('resizeEnd', function() {
  630. if ($(window).width() < 576) {
  631. if (menu_side_state_current == 'contracted') {
  632. $('#menu_side_container').hide();
  633. }
  634. if (menu_side_state_current == 'expanded') {
  635. {/literal}
  636. {if $menu_side_state != 'hidden'}
  637. {literal}
  638. $('#menu_side_container').show();
  639. {/literal}
  640. {/if}
  641. {literal}
  642. $('#menu_side_container').animate({ width: $(window).width() }, 180);
  643. }
  644. $('#content_container').animate({ width: $(window).width() }, 100);
  645. }
  646. else {
  647. {/literal}
  648. {if $menu_side_state == 'hidden'}
  649. {literal}
  650. $('#menu_side_container').animate({ width: '{/literal}{$settings.theme.menu_side_width_expanded}{literal}px' }, 180);
  651. $('#content_container').animate({ width: $(window).width() }, 100);
  652. {/literal}
  653. {else}
  654. {literal}
  655. $('#menu_side_container').show();
  656. if (menu_side_state_current == 'expanded') {
  657. $('#menu_side_container').animate({ width: '{/literal}{$settings.theme.menu_side_width_expanded}{literal}px' }, 180, function() {
  658. $('#content_container').animate({ width: $(window).width() - $('#menu_side_container').width() }, 100);
  659. });
  660. }
  661. else {
  662. $('#content_container').animate({ width: $(window).width() - $('#menu_side_container').width() }, 100);
  663. }
  664. {/literal}
  665. {/if}
  666. {literal}
  667. }
  668. });
  669. {/literal}
  670. {/if}
  671. {literal}
  672. }); //document ready end
  673. {/literal}
  674. //audio playback functions
  675. {literal}
  676. var recording_audio, audio_clock;
  677. function recording_play(recording_id) {
  678. if (document.getElementById('recording_progress_bar_'+recording_id)) {
  679. document.getElementById('recording_progress_bar_'+recording_id).style.display='';
  680. }
  681. recording_audio = document.getElementById('recording_audio_'+recording_id);
  682. if (recording_audio.paused) {
  683. recording_audio.volume = 1;
  684. recording_audio.play();
  685. document.getElementById('recording_button_'+recording_id).innerHTML = "<span class='{/literal}{$settings.theme.button_icon_pause}{literal} fa-fw'></span>";
  686. audio_clock = setInterval(function () { update_progress(recording_id); }, 20);
  687. $('[id*=recording_button]').not('[id*=recording_button_'+recording_id+']').html("<span class='{/literal}{$settings.theme.button_icon_play}{literal} fa-fw'></span>");
  688. $('[id*=recording_progress_bar]').not('[id*=recording_progress_bar_'+recording_id+']').css('display', 'none');
  689. $('audio').each(function(){$('#menu_side_container').width()
  690. if ($(this).get(0) != recording_audio) {
  691. $(this).get(0).pause(); //stop playing
  692. $(this).get(0).currentTime = 0; //reset time
  693. }
  694. });
  695. }
  696. else {
  697. recording_audio.pause();
  698. document.getElementById('recording_button_'+recording_id).innerHTML = "<span class='{/literal}{$settings.theme.button_icon_play}{literal} fa-fw'></span>";
  699. clearInterval(audio_clock);
  700. }
  701. }
  702. function recording_stop(recording_id) {
  703. recording_reset(recording_id);
  704. clearInterval(audio_clock);
  705. }
  706. function recording_reset(recording_id) {
  707. recording_audio = document.getElementById('recording_audio_'+recording_id);
  708. recording_audio.pause();
  709. recording_audio.currentTime = 0;
  710. if (document.getElementById('recording_progress_bar_'+recording_id)) {
  711. document.getElementById('recording_progress_bar_'+recording_id).style.display='none';
  712. }
  713. document.getElementById('recording_button_'+recording_id).innerHTML = "<span class='{/literal}{$settings.theme.button_icon_play}{literal} fa-fw'></span>";
  714. clearInterval(audio_clock);
  715. }
  716. function update_progress(recording_id) {
  717. recording_audio = document.getElementById('recording_audio_'+recording_id);
  718. var recording_progress = document.getElementById('recording_progress_'+recording_id);
  719. var value = 0;
  720. if (recording_audio.currentTime > 0) {
  721. value = (100 / recording_audio.duration) * recording_audio.currentTime;
  722. }
  723. recording_progress.style.marginLeft = value + '%';
  724. if (parseInt(recording_audio.duration) > 30) { //seconds
  725. clearInterval(audio_clock);
  726. }
  727. }
  728. {/literal}
  729. //handle action bar style on scroll
  730. {literal}
  731. window.addEventListener('scroll', function(){
  732. action_bar_scroll('action_bar', 20);
  733. }, false);
  734. function action_bar_scroll(action_bar_id, scroll_position, function_sticky, function_inline) {
  735. if (document.getElementById(action_bar_id)) {
  736. //sticky
  737. if (this.scrollY > scroll_position) {
  738. document.getElementById(action_bar_id).classList.add('scroll');
  739. if (typeof function_sticky === 'function') { function_sticky(); }
  740. }
  741. //inline
  742. if (this.scrollY < scroll_position) {
  743. document.getElementById(action_bar_id).classList.remove('scroll');
  744. if (typeof function_inline === 'function') { function_inline(); }
  745. }
  746. }
  747. }
  748. {/literal}
  749. //enable button class button
  750. {literal}
  751. function button_enable(button_id) {
  752. button = document.getElementById(button_id);
  753. button.disabled = false;
  754. button.classList.remove('disabled');
  755. if (button.parentElement.nodeName == 'A') {
  756. anchor = button.parentElement;
  757. anchor.classList.remove('disabled');
  758. anchor.setAttribute('onclick','');
  759. }
  760. }
  761. {/literal}
  762. //disable button class button
  763. {literal}
  764. function button_disable(button_id) {
  765. button = document.getElementById(button_id);
  766. button.disabled = true;
  767. button.classList.add('disabled');
  768. if (button.parentElement.nodeName == 'A') {
  769. anchor = button.parentElement;
  770. anchor.classList.add('disabled');
  771. anchor.setAttribute('onclick','return false;');
  772. }
  773. }
  774. {/literal}
  775. //checkbox on change
  776. {literal}
  777. function checkbox_on_change(checkbox) {
  778. checked = false;
  779. var inputs = document.getElementsByTagName('input');
  780. for (var i = 0, max = inputs.length; i < max; i++) {
  781. if (inputs[i].type === 'checkbox' && inputs[i].checked == true) {
  782. checked = true;
  783. break;
  784. }
  785. }
  786. btn_copy = document.getElementById("btn_copy");
  787. btn_toggle = document.getElementById("btn_toggle");
  788. btn_delete = document.getElementById("btn_delete");
  789. if (checked == true) {
  790. if (btn_copy) {
  791. btn_copy.style.display = "inline";
  792. }
  793. if (btn_toggle) {
  794. btn_toggle.style.display = "inline";
  795. }
  796. if (btn_delete) {
  797. btn_delete.style.display = "inline";
  798. }
  799. }
  800. else {
  801. if (btn_copy) {
  802. btn_copy.style.display = "none";
  803. }
  804. if (btn_toggle) {
  805. btn_toggle.style.display = "none";
  806. }
  807. if (btn_delete) {
  808. btn_delete.style.display = "none";
  809. }
  810. }
  811. }
  812. {/literal}
  813. //list page functions
  814. {literal}
  815. function list_all_toggle(modifier) {
  816. var checkboxes = (modifier !== undefined) ? document.getElementsByClassName('checkbox_'+modifier) : document.querySelectorAll("input[type='checkbox']");
  817. var checkbox_checked = document.getElementById('checkbox_all' + (modifier !== undefined ? '_'+modifier : '')).checked;
  818. for (var i = 0, max = checkboxes.length; i < max; i++) {
  819. checkboxes[i].checked = checkbox_checked;
  820. }
  821. if (document.getElementById('btn_check_all') && document.getElementById('btn_check_none')) {
  822. if (checkbox_checked) {
  823. document.getElementById('btn_check_all').style.display = 'none';
  824. document.getElementById('btn_check_none').style.display = '';
  825. }
  826. else {
  827. document.getElementById('btn_check_all').style.display = '';
  828. document.getElementById('btn_check_none').style.display = 'none';
  829. }
  830. }
  831. }
  832. function list_all_check() {
  833. var inputs = document.getElementsByTagName('input');
  834. document.getElementById('checkbox_all').checked;
  835. for (var i = 0, max = inputs.length; i < max; i++) {
  836. if (inputs[i].type === 'checkbox') {
  837. inputs[i].checked = true;
  838. }
  839. }
  840. }
  841. function list_self_check(checkbox_id) {
  842. var inputs = document.getElementsByTagName('input');
  843. for (var i = 0, max = inputs.length; i < max; i++) {
  844. if (inputs[i].type === 'checkbox') {
  845. inputs[i].checked = false;
  846. }
  847. }
  848. document.getElementById(checkbox_id).checked = true;
  849. }
  850. function list_action_set(action) {
  851. document.getElementById('action').value = action;
  852. }
  853. function list_form_submit(form_id) {
  854. document.getElementById(form_id).submit();
  855. }
  856. function list_search_reset() {
  857. document.getElementById('btn_reset').style.display = 'none';
  858. document.getElementById('btn_search').style.display = '';
  859. }
  860. {/literal}
  861. //edit page functions
  862. {literal}
  863. function edit_all_toggle(modifier) {
  864. var checkboxes = document.getElementsByClassName('checkbox_'+modifier);
  865. var checkbox_checked = document.getElementById('checkbox_all_'+modifier).checked;
  866. if (checkboxes.length > 0) {
  867. for (var i = 0; i < checkboxes.length; ++i) {
  868. checkboxes[i].checked = checkbox_checked;
  869. }
  870. if (document.getElementById('btn_delete')) {
  871. document.getElementById('btn_delete').value = checkbox_checked ? '' : 'delete';
  872. }
  873. }
  874. }
  875. function edit_delete_action(modifier) {
  876. var checkboxes = document.getElementsByClassName('chk_delete');
  877. if (document.getElementById('btn_delete') && checkboxes.length > 0) {
  878. var checkbox_checked = false;
  879. for (var i = 0; i < checkboxes.length; ++i) {
  880. if (checkboxes[i].checked) {
  881. checkbox_checked = true;
  882. }
  883. else {
  884. if (document.getElementById('checkbox_all'+(modifier !== undefined ? '_'+modifier : ''))) {
  885. document.getElementById('checkbox_all'+(modifier !== undefined ? '_'+modifier : '')).checked = false;
  886. }
  887. }
  888. }
  889. document.getElementById('btn_delete').value = checkbox_checked ? '' : 'delete';
  890. }
  891. }
  892. {/literal}
  893. //modal functions
  894. {literal}
  895. function modal_open(modal_id, focus_id) {
  896. var modal = document.getElementById(modal_id);
  897. modal.style.opacity = '1';
  898. modal.style.pointerEvents = 'auto';
  899. if (focus_id !== undefined) {
  900. document.getElementById(focus_id).focus();
  901. }
  902. }
  903. function modal_close() {
  904. var modals = document.getElementsByClassName('modal-window');
  905. if (modals.length > 0) {
  906. for (var m = 0; m < modals.length; ++m) {
  907. modals[m].style.opacity = '0';
  908. modals[m].style.pointerEvents = 'none';
  909. }
  910. }
  911. document.activeElement.blur();
  912. }
  913. {/literal}
  914. //misc functions
  915. {literal}
  916. function swap_display(a_id, b_id, display_value) {
  917. display_value = display_value !== undefined ? display_value : 'inline-block';
  918. a = document.getElementById(a_id);
  919. b = document.getElementById(b_id);
  920. if (window.getComputedStyle(a).display === 'none') {
  921. a.style.display = display_value;
  922. b.style.display = 'none';
  923. }
  924. else {
  925. a.style.display = 'none';
  926. b.style.display = display_value;
  927. }
  928. }
  929. function hide_password_fields() {
  930. var password_fields = document.querySelectorAll("input[type='password']");
  931. for (var p = 0, max = password_fields.length; p < max; p++) {
  932. password_fields[p].style.visibility = 'hidden';
  933. password_fields[p].type = 'text';
  934. }
  935. }
  936. window.addEventListener('beforeunload', function(e){
  937. hide_password_fields();
  938. });
  939. {/literal}
  940. {*//session timer *}
  941. {$session_timer}
  942. </script>
  943. </head>
  944. <body>
  945. {*//message container *}
  946. <div id='message_container'></div>
  947. {*//domain selector *}
  948. {if $authenticated && $domain_selector_enabled}
  949. <div id='domains_container'>
  950. <input type='hidden' id='domains_visible' value='0'>
  951. <div id='domains_block'>
  952. <div id='domains_header'>
  953. <input id='domains_hide' type='button' class='btn' style='float: right' value="{$text.theme_button_close}">
  954. <a id='domains_title' href='{$domains_app_path}'>{$text.theme_title_domains} <span style='font-size: 80%;'>({$domain_count})</span></a>
  955. <br><br>
  956. <input type='text' id='domains_filter' class='formfld' style='margin-left: 0; min-width: 100%; width: 100%;' placeholder="{$text.theme_label_search}" onkeyup='domain_search(this.value)'>
  957. </div>
  958. <div id='domains_list'>
  959. {foreach $domains as $row}
  960. {if $row.domain_enabled}
  961. {*//alternate background colors of inactive domains *}
  962. {if $background_color == $domain_selector_background_color_1}
  963. {$background_color=$domain_selector_background_color_2}
  964. {else}
  965. {$background_color=$domain_selector_background_color_1}
  966. {/if}
  967. {*//set active domain color *}
  968. {if $domain_active_background_color != ''}
  969. {if $row.domain_uuid == $domain_uuid}{$background_color=$domain_active_background_color}{/if}
  970. {/if}
  971. {*//active domain text hover color *}
  972. {if $settings.theme.domain_active_text_color_hover != '' && $row.domain_uuid == $domain_uuid}
  973. <div id='{$row.domain_name}' class='domains_list_item_active' style='background-color: {$background_color}' onclick="document.location.href='{$domains_app_path}?domain_uuid={$row.domain_uuid}&domain_change=true';">
  974. {elseif $settings.theme.domain_inactive_text_color_hover != '' && $row.domain_uuid != $domain_uuid}
  975. <div id='{$row.domain_name}' class='domains_list_item_inactive' style='background-color: {$background_color}' onclick="document.location.href='{$domains_app_path}?domain_uuid={$row.domain_uuid}&domain_change=true';">
  976. {else}
  977. <div id='{$row.domain_name}' class='domains_list_item' style='background-color: {$background_color}' onclick="document.location.href='{$domains_app_path}?domain_uuid={$row.domain_uuid}&domain_change=true';">
  978. {/if}
  979. {*//domain link *}
  980. <a href='{$domains_app_path}?domain_uuid={$row.domain_uuid}&domain_change=true' {if $row.domain_uuid == $domain_uuid}style='font-weight: bold;'{/if}>{$row.domain_name}</a>
  981. {*//domain description *}
  982. {if $row.domain_description != ''}
  983. {*//active domain description text color *}
  984. {if $settings.theme.domain_active_desc_text_color != '' && $row.domain_uuid == $domain_uuid}
  985. <span class='domain_active_list_item_description' title="{$row.domain_description}"> - {$row.domain_description}</span>
  986. {*//inactive domains description text color *}
  987. {elseif $settings.theme.domain_inactive_desc_text_color != '' && $row.domain_uuid != $domain_uuid}
  988. <span class='domain_inactive_list_item_description' title="{$row.domain_description}"> - {$row.domain_description}</span>
  989. {*//default domain description text color *}
  990. {else}
  991. <span class='domain_list_item_description' title="{$row.domain_description}"> - {$row.domain_description}</span>
  992. {/if}
  993. {/if}
  994. </div>
  995. {$ary_domain_names[]=$row.domain_name}
  996. {$ary_domain_descs[]=$row.domain_description|replace:'"':'\"'}
  997. {/if}
  998. {/foreach}
  999. </div>
  1000. <script>
  1001. {literal}
  1002. var domain_names = new Array("{/literal}{'","'|implode:$ary_domain_names}{literal}");
  1003. var domain_descs = new Array("{/literal}{'","'|implode:$ary_domain_descs}{literal}");
  1004. function domain_search(criteria) {
  1005. for (var x = 0; x < domain_names.length; x++) {
  1006. if (domain_names[x].toLowerCase().match(criteria.toLowerCase()) || domain_descs[x].toLowerCase().match(criteria.toLowerCase())) {
  1007. document.getElementById(domain_names[x]).style.display = '';
  1008. }
  1009. else {
  1010. document.getElementById(domain_names[x]).style.display = 'none';
  1011. }
  1012. }
  1013. }
  1014. {/literal}
  1015. </script>
  1016. </div>
  1017. </div>
  1018. {/if}
  1019. {*//qr code container for contacts *}
  1020. <div id='qr_code_container' style='display: none;' onclick='$(this).fadeOut(400);'>
  1021. <table cellpadding='0' cellspacing='0' border='0' width='100%' height='100%'><tr><td align='center' valign='middle'>
  1022. <span id='qr_code' onclick="$('#qr_code_container').fadeOut(400);"></span>
  1023. </td></tr></table>
  1024. </div>
  1025. {*//login page *}
  1026. {if $login_page}
  1027. <div id='default_login'>
  1028. <a href='{$project_path}/'><img id='login_logo' style='width: {$login_logo_width}; height: {$login_logo_height};' src='{$login_logo_source}'></a><br />
  1029. {$document_body}
  1030. </div>
  1031. <div id='footer_login'>
  1032. <span class='footer'>{$settings.theme.footer}</span>
  1033. </div>
  1034. {*//other pages *}
  1035. {else}
  1036. {if $settings.theme.menu_style == 'side' || $settings.theme.menu_style == 'inline' || $settings.theme.menu_style == 'static'}
  1037. {$container_open}
  1038. {if $settings.theme.menu_style == 'inline'}{$logo}{/if}
  1039. {$menu}
  1040. {if $settings.theme.menu_style == 'inline' || $settings.theme.menu_style == 'static'}<br />{/if}
  1041. {if $settings.theme.menu_style == 'side'}<input type='hidden' id='menu_side_state_current' value='{if $menu_side_state == 'hidden'}expanded{else}{$menu_side_state}{/if}'>{/if}
  1042. {else} {*//default: fixed *}
  1043. {$menu}
  1044. {$container_open}
  1045. {/if}
  1046. <div id='main_content'>
  1047. {$document_body}
  1048. </div>
  1049. <div id='footer'>
  1050. <span class='footer'>{$settings.theme.footer}</span>
  1051. </div>
  1052. {$container_close}
  1053. {/if}
  1054. </body>
  1055. </html>