Koombea OpenAir: functions

Add custom functionality to OpenAir website

安装此脚本
作者推荐脚本

您可能也喜欢Koombea OpenAir styles

安装为用户样式
  1. // ==UserScript==
  2. // @name Koombea OpenAir: functions
  3. // @name:es Koombea OpenAir: functions
  4. // @description Add custom functionality to OpenAir website
  5. // @description:es Agrega funcionalidad personalizada al sitio web de OpenAir
  6. // @namespace koombea_air
  7. // @version 0.5.0
  8. // @author rhonaldomaster
  9. // @compatible chrome
  10. // @compatible edge
  11. // @compatible firefox
  12. // @compatible opera
  13. // @compatible safari
  14. // @copyright GNU/GPL v3
  15. // @grant GM_addStyle
  16. // @homepage https://github.com/rhonaldomaster/openair-k-colors
  17. // @icon https://www.google.com/s2/favicons?sz=64&domain=openair.com
  18. // @license GPL-3.0-or-later
  19. // @match *://koombea-inc.app.netsuitesuiteprojectspro.com*
  20. // ==/UserScript==
  21.  
  22. /**
  23. * Converts booking % to h/d
  24. */
  25. function convertBookingPercentToHD() {
  26. const bookings = document.querySelectorAll('.GMGanttFixedIn, .GMGanttLeftIn, .GMGanttRightIn, .GMGanttBaseIn');
  27. bookings.forEach((booking) => {
  28. // Validates that the booking wasn't already converted and that it contains the % value
  29. const bookingHTML = booking.innerHTML;
  30. if (
  31. bookingHTML.split('h/d')[0] == bookingHTML &&
  32. bookingHTML != '' &&
  33. bookingHTML.match(/([0-9]*\.?[0-9]+)\s%/) != null
  34. ) {
  35. const hours_per_day = Math.round(((bookingHTML.match(/([0-9]*\.?[0-9]+)\s%/)[1] * 8) / 100 + Number.EPSILON) * 100) / 100;
  36. if (bookingHTML.match(/([0-9]*\.?[0-9]+)\s%/)[0] == booking.textContent) {
  37. // For allocation percentage bubbles at the top
  38. booking.innerHTML = hours_per_day + 'h/d';
  39. } else {
  40. // For bookings
  41. booking.innerHTML = hours_per_day + 'h/d ' + bookingHTML;
  42. }
  43. }
  44. });
  45. }
  46.  
  47. /**
  48. * Displays alert if the opened timesheet is in the future
  49. */
  50. function checkForFutureTimesheets() {
  51. const timesheetStart = new Date(document.querySelector('.header-text-record-title').innerHTML.split(' to ')[0]); //Gets timesheet's dates based on title
  52. const today = new Date();
  53. if(timesheetStart - today > 0) {
  54. document.querySelector('.header-text-record-title').innerHTML += '<span class="timesheet-alert"><b class="svg"></b> This timesheet is for a future period!</span>';
  55. }
  56. }
  57.  
  58. /**
  59. * UI add-on for bookings form to calculate hours per day
  60. */
  61. function calculateHoursPerDay() {
  62. const iframe = document.querySelector('iframe[name="Edit booking"]');
  63. const isNewBooking = window.location.href.indexOf("/booking.pl") > -1 && window.location.href.indexOf("action=new") > -1;
  64. var doc;
  65.  
  66. if(iframe != null) {
  67. doc = iframe.contentDocument;
  68. } else if(isNewBooking) {
  69. doc = document;
  70. }
  71.  
  72. if(doc != undefined) {
  73. const bookByTable = doc.querySelector('#row_section_4 .formLabeledPair > tbody');
  74. const warningContainer = doc.querySelector('.book-by__warning-text');
  75.  
  76. if(warningContainer == null) {
  77. bookByTable.innerHTML += '<tr><td colspan="4">Hours per day calculator:</td><td class="book-by__hours-per-day"><input type="text" class="book-by__hours-per-day" value="0" size="12" maxlength="12"></td></tr><tr class="book-by__warning-text"><td colspan="5"><strong>Make sure to select "Percentage of time"</strong></td></tr>';
  78. }
  79.  
  80. const perDayInput = doc.querySelector('input.book-by__hours-per-day');
  81. const percentageInput = doc.querySelector('#row_section_4 input[name="percentage"]');
  82. if(perDayInput.value != percentageInput.value * 8 / 100 && doc.activeElement != perDayInput && doc.activeElement != percentageInput) perDayInput.value = percentageInput.value * 8 / 100;
  83.  
  84. percentageInput.addEventListener('input', () => {
  85. perDayInput.value = percentageInput.value * 8 / 100;
  86. });
  87.  
  88. perDayInput.addEventListener('input', () => {
  89. percentageInput.value = perDayInput.value * 100 / 8;
  90. });
  91. }
  92. }
  93.  
  94. /**
  95. * Checks the current page location
  96. */
  97. function pageLocation(page) {
  98. const location = window.location.href;
  99. switch (page) {
  100. case "timesheet":
  101. return (location.indexOf("/timesheet.pl") > -1 && location.indexOf("timesheet_id=") > -1);
  102. break;
  103. case "planner":
  104. return (location.indexOf("/booking.pl") > -1 && location.indexOf("_booking_layout=planner") > -1);
  105. break;
  106. case "booking-edit":
  107. return (location.indexOf("/booking.pl") > -1 && (location.indexOf("_booking_layout=planner") > -1 || location.indexOf("action=new") > -1));
  108. break;
  109. }
  110. }
  111.  
  112. window.addEventListener('load', () => {
  113. if(pageLocation("timesheet")) checkForFutureTimesheets();
  114. if(pageLocation("planner")) setInterval(convertBookingPercentToHD, 1000);
  115. if(pageLocation("booking-edit")) setInterval(calculateHoursPerDay, 1000);
  116. });