您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 

76 行
2.2 KiB

  1. // assets/scripts/duration.js
  2. export const DURATION_CONFIG = {
  3. roundToQuarter: true,
  4. };
  5. export function parseDuration(input) {
  6. input = String(input).trim();
  7. if (!input || input === '0' || input === '0:00') return 0;
  8. // "8 12" -> von 8 bis 12 Uhr
  9. if (/^\d+\s+\d+$/.test(input)) {
  10. const parts = input.split(/\s+/).map(Number);
  11. return Math.max(0, (parts[1] - parts[0]) * 60);
  12. }
  13. // "1:30" -> Stunden:Minuten
  14. if (input.includes(':')) {
  15. const [h, m] = input.split(':').map(s => parseInt(s, 10) || 0);
  16. return h * 60 + m;
  17. }
  18. // "1,75" oder "1.75" -> Dezimalstunden
  19. if (input.includes(',') || input.includes('.')) {
  20. const hours = parseFloat(input.replace(',', '.'));
  21. return isNaN(hours) ? 0 : Math.round(hours * 60);
  22. }
  23. // "2" -> 2 Stunden
  24. const hours = parseInt(input, 10);
  25. return isNaN(hours) ? 0 : hours * 60;
  26. }
  27. export function roundToQuarter(minutes) {
  28. if (!DURATION_CONFIG.roundToQuarter) return minutes;
  29. if (minutes === 0) return 0;
  30. const interval = window.TT?.trackingInterval ?? window.Report?.trackingInterval ?? 15;
  31. return Math.ceil(minutes / interval) * interval;
  32. }
  33. export function formatMinutes(minutes) {
  34. const h = Math.floor(minutes / 60);
  35. const m = minutes % 60;
  36. return `${h}:${String(m).padStart(2, '0')}`;
  37. }
  38. export function validateDuration(minutes) {
  39. if (minutes > 1440) return { status: 'error' };
  40. if (minutes > 480) return { status: 'warn' };
  41. return { status: 'ok' };
  42. }
  43. export function parseAndValidate(raw) {
  44. const minutes = roundToQuarter(parseDuration(raw));
  45. const formatted = formatMinutes(minutes);
  46. if (minutes === 0) return { minutes, formatted, error: 'errorZeroDuration' };
  47. const v = validateDuration(minutes);
  48. if (v.status === 'error') return { minutes, formatted, error: 'errorDurationTooLong' };
  49. if (v.status === 'warn') return { minutes, formatted, warn: 'warnDurationLong' };
  50. return { minutes, formatted };
  51. }
  52. export function initDurationBlurHandler() {
  53. document.addEventListener('blur', e => {
  54. if (!(e.target instanceof Element)) return;
  55. if (!e.target.matches('#create-duration, .edit-duration')) return;
  56. const minutes = roundToQuarter(parseDuration(e.target.value));
  57. e.target.value = formatMinutes(minutes);
  58. }, true);
  59. }