advanceStatsOprs.html 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <!-- Notes: This should be open in its original path-->
  5. <meta charset="utf-8">
  6. <meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
  7. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  8. <script src="../script/jquery-3.6.0.min.js"></script>
  9. <script src="../script/semantic/semantic.min.js"></script>
  10. <script src="../script/utils.js"></script>
  11. </head>
  12. <body>
  13. <link rel="stylesheet" href="../darktheme.css">
  14. <script src="../script/darktheme.js"></script>
  15. <br>
  16. <div class="ui container">
  17. <div class="ui header">
  18. <div class="content">
  19. Advance Statistics Operations
  20. <div class="sub header">Selected Range: <span id="daterange"></span></div>
  21. </div>
  22. </div>
  23. <div class="ui divider"></div>
  24. <h3>Export Data</h3>
  25. <p>You can export the statistics collected by Zoraxy in the selected range for further analysis</p>
  26. <button class="ui basic teal button" onclick="handleExportAsCSV();"><i class="download icon"></i> Export CSV</button>
  27. <button class="ui basic pink button" onclick="handleExportAsJSON();"><i class="download icon"></i> Export JSON</button>
  28. <div class="ui divider"></div>
  29. <h3>Reset Statistics</h3>
  30. <p>You can reset the statistics within the selected time range for debug purpose. Note that this operation is irreversible.</p>
  31. <button class="ui basic red button" onclick="handleResetStats();"><i class="trash icon"></i> RESET STATISTICS</button>
  32. <br><br>
  33. <button class="ui basic button iframeOnly" style="float: right;" onclick="parent.hideSideWrapper();"><i class="remove icon"></i> Cancel</button>
  34. </div>
  35. <script>
  36. let startDate = "";
  37. let endDate = "";
  38. /*
  39. Actions Handler
  40. */
  41. function handleExportAsJSON(){
  42. window.open(`/api/analytic/exportRange?start=${startDate}&end=${endDate}&format=json`, 'download');
  43. }
  44. function handleExportAsCSV(){
  45. window.open(`/api/analytic/exportRange?start=${startDate}&end=${endDate}&format=csv`, 'download');
  46. }
  47. function handleResetStats(){
  48. if (confirm("Confirm remove statistics from " + startDate + " to " + endDate +"?")){
  49. $.cjax({
  50. url: "/api/analytic/resetRange?start=" + startDate + "&end=" + endDate,
  51. method: "DELETE",
  52. success: function(data){
  53. if (data.error != undefined){
  54. parent.msgbox(data.error, false, 5000);
  55. }else{
  56. parent.msgbox("Statistic Cleared");
  57. parent.hideSideWrapper();
  58. }
  59. }
  60. })
  61. }
  62. }
  63. /*
  64. Data Loading
  65. */
  66. function loadDateRange(){
  67. if (window.location.hash.length > 1){
  68. try{
  69. var dateRange = JSON.parse(decodeURIComponent(window.location.hash.substr(1)));
  70. startDate = dateRange[0].trim();
  71. endDate = dateRange[1].trim();
  72. //Check if they are valid dates
  73. if (!isValidDateFormat(startDate)){
  74. alert("Start date is not a valid date: " + startDate);
  75. return
  76. }
  77. if (!isValidDateFormat(endDate)){
  78. alert("End date is not a valid date: " + endDate);
  79. return
  80. }
  81. //Sort the two dates if they are placed in invalid orders
  82. var [s, e] = sortDates(startDate, endDate);
  83. startDate = s;
  84. endDate = e;
  85. $("#daterange").html(startDate + ` <i class="arrow right icon" style="margin-right: 0;"></i> ` + endDate);
  86. }catch(ex){
  87. alert("Invalid usage: Invalid date range given");
  88. }
  89. }
  90. }
  91. loadDateRange();
  92. function isValidDateFormat(dateString) {
  93. if (dateString.indexOf("_") >= 0){
  94. //Replace all the _ to -
  95. dateString = dateString.split("_").join("-");
  96. }
  97. // Create a regular expression pattern for the yyyy-mm-dd format
  98. const pattern = /^\d{4}-\d{2}-\d{2}$/;
  99. // Check if the input string matches the pattern
  100. if (!pattern.test(dateString)) {
  101. return false; // Invalid format
  102. }
  103. // Parse the date components
  104. const year = parseInt(dateString.substring(0, 4), 10);
  105. const month = parseInt(dateString.substring(5, 7), 10);
  106. const day = parseInt(dateString.substring(8, 10), 10);
  107. // Check if the parsed components represent a valid date
  108. const date = new Date(year, month - 1, day);
  109. if (
  110. date.getFullYear() !== year ||
  111. date.getMonth() + 1 !== month ||
  112. date.getDate() !== day
  113. ) {
  114. return false; // Invalid date
  115. }
  116. return true; // Valid date in yyyy-mm-dd format
  117. }
  118. function sortDates(date1, date2) {
  119. // Parse the date strings
  120. const parsedDate1 = new Date(date1);
  121. const parsedDate2 = new Date(date2);
  122. // Compare the parsed dates
  123. if (parsedDate1 > parsedDate2) {
  124. // Swap the dates
  125. const temp = date1;
  126. date1 = date2;
  127. date2 = temp;
  128. }
  129. // Return the swapped dates
  130. return [date1, date2];
  131. }
  132. </script>
  133. </body>
  134. </html>