@tmlmobilidade/dates 20260421.1115.34 → 20260424.1050.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -51,14 +51,24 @@ export function buildWeekdaysPart(rule, cfg = { mode: 'long' }) {
|
|
|
51
51
|
const hasMonFri = [1, 2, 3, 4, 5].every(d => weekdaySet.has(d));
|
|
52
52
|
const hasWeekend = weekdaySet.has(6) && weekdaySet.has(7);
|
|
53
53
|
const getDayLabel = (value) => WEEKDAY_OPTIONS.find(opt => opt.value === value)?.label ?? '?';
|
|
54
|
+
const getSingleDayLongLabel = (value) => {
|
|
55
|
+
if (value === 6) {
|
|
56
|
+
return `ao ${getDayLabel(value)}`;
|
|
57
|
+
}
|
|
58
|
+
if (value === 7) {
|
|
59
|
+
return `aos ${getDayLabel(value)}`;
|
|
60
|
+
}
|
|
61
|
+
return `à ${getDayLabel(value)}`;
|
|
62
|
+
};
|
|
54
63
|
if (hasMonFri && hasWeekend)
|
|
55
|
-
return 'Todos os dias';
|
|
64
|
+
return cfg.mode === 'short' ? 'Todos os dias' : 'em todos os dias';
|
|
56
65
|
if (hasMonFri) {
|
|
57
66
|
const extraDays = rule.weekdays
|
|
58
67
|
.filter(d => d < 1 || d > 5)
|
|
59
68
|
.sort((a, b) => a - b);
|
|
60
|
-
if (extraDays.length === 0)
|
|
61
|
-
return 'Dias úteis';
|
|
69
|
+
if (extraDays.length === 0) {
|
|
70
|
+
return cfg.mode === 'short' ? 'Dias úteis' : 'nos dias úteis';
|
|
71
|
+
}
|
|
62
72
|
const extraLabels = extraDays.map(getDayLabel);
|
|
63
73
|
return cfg.mode === 'short'
|
|
64
74
|
? `Dias úteis + ${extraLabels.join(', ')}`
|
|
@@ -78,9 +88,13 @@ export function buildWeekdaysPart(rule, cfg = { mode: 'long' }) {
|
|
|
78
88
|
}
|
|
79
89
|
const sortedDays = [...rule.weekdays].sort((a, b) => a - b);
|
|
80
90
|
const dayLabels = sortedDays.map(getDayLabel);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
if (cfg.mode === 'short') {
|
|
92
|
+
return dayLabels.join(', ');
|
|
93
|
+
}
|
|
94
|
+
if (sortedDays.length === 1) {
|
|
95
|
+
return getSingleDayLongLabel(sortedDays[0]);
|
|
96
|
+
}
|
|
97
|
+
return `à ${dayLabels.join(', ')}`;
|
|
84
98
|
}
|
|
85
99
|
export function buildDayPeriodsPart(parameter, cfg) {
|
|
86
100
|
const selected = (parameter.day_periods ?? []);
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
/* * */
|
|
3
|
+
function safeStringCompare(a, b) {
|
|
4
|
+
return (a || '').localeCompare(b || '');
|
|
5
|
+
}
|
|
6
|
+
function getSortedPeriodIds(rule) {
|
|
7
|
+
if ('year_period_ids' in rule && Array.isArray(rule.year_period_ids)) {
|
|
8
|
+
return [...rule.year_period_ids].sort((a, b) => a.localeCompare(b));
|
|
9
|
+
}
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
function hasAllYearPeriods(rule, totalYearPeriods) {
|
|
13
|
+
if (!('year_period_ids' in rule) || !Array.isArray(rule.year_period_ids)) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return totalYearPeriods > 0 && new Set(rule.year_period_ids).size === totalYearPeriods;
|
|
17
|
+
}
|
|
18
|
+
function getPeriodSortKey(rule) {
|
|
19
|
+
return getSortedPeriodIds(rule).join('|');
|
|
20
|
+
}
|
|
21
|
+
function normalizeWeekdayValue(weekday) {
|
|
22
|
+
if (typeof weekday === 'number')
|
|
23
|
+
return weekday;
|
|
24
|
+
const numericValue = Number(weekday);
|
|
25
|
+
if (!Number.isNaN(numericValue))
|
|
26
|
+
return numericValue;
|
|
27
|
+
return 999;
|
|
28
|
+
}
|
|
29
|
+
function getSortedWeekdays(rule) {
|
|
30
|
+
if ('weekdays' in rule && Array.isArray(rule.weekdays)) {
|
|
31
|
+
return [...rule.weekdays]
|
|
32
|
+
.map(normalizeWeekdayValue)
|
|
33
|
+
.sort((a, b) => a - b);
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
function isExactWeekdaySet(rule, expected) {
|
|
38
|
+
const weekdays = getSortedWeekdays(rule);
|
|
39
|
+
if (weekdays.length !== expected.length)
|
|
40
|
+
return false;
|
|
41
|
+
return weekdays.every((day, index) => day === expected[index]);
|
|
42
|
+
}
|
|
43
|
+
function getWeekdayGroupPriority(rule) {
|
|
44
|
+
// 1..7 => first
|
|
45
|
+
if (isExactWeekdaySet(rule, [1, 2, 3, 4, 5, 6, 7]))
|
|
46
|
+
return 0;
|
|
47
|
+
// DU / weekdays only => second
|
|
48
|
+
if (isExactWeekdaySet(rule, [1, 2, 3, 4, 5]))
|
|
49
|
+
return 1;
|
|
50
|
+
// everything else
|
|
51
|
+
return 2;
|
|
52
|
+
}
|
|
53
|
+
function getWeekdaySortKey(rule) {
|
|
54
|
+
return getSortedWeekdays(rule)
|
|
55
|
+
.map(day => day.toString().padStart(3, '0'))
|
|
56
|
+
.join('|');
|
|
57
|
+
}
|
|
58
|
+
function getFirstDate(rule) {
|
|
59
|
+
if ('dates' in rule && Array.isArray(rule.dates) && rule.dates.length > 0) {
|
|
60
|
+
return [...rule.dates].sort((a, b) => a.localeCompare(b))[0];
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
function isEventException(rule) {
|
|
65
|
+
if (rule.kind === 'event_restriction' || rule.kind === 'event_replacement') {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return rule.kind === 'manual' && Boolean(rule.event_id);
|
|
69
|
+
}
|
|
70
|
+
function compareByEventDate(a, b) {
|
|
71
|
+
const firstDateA = getFirstDate(a) || '99999999';
|
|
72
|
+
const firstDateB = getFirstDate(b) || '99999999';
|
|
73
|
+
const dateComparison = firstDateA.localeCompare(firstDateB);
|
|
74
|
+
if (dateComparison !== 0)
|
|
75
|
+
return dateComparison;
|
|
76
|
+
return safeStringCompare(a.name, b.name);
|
|
77
|
+
}
|
|
78
|
+
function compareByRuleParams(a, b, totalYearPeriods) {
|
|
79
|
+
const aHasAllPeriods = hasAllYearPeriods(a, totalYearPeriods);
|
|
80
|
+
const bHasAllPeriods = hasAllYearPeriods(b, totalYearPeriods);
|
|
81
|
+
if (aHasAllPeriods && !bHasAllPeriods)
|
|
82
|
+
return -1;
|
|
83
|
+
if (!aHasAllPeriods && bHasAllPeriods)
|
|
84
|
+
return 1;
|
|
85
|
+
const periodComparison = getPeriodSortKey(a).localeCompare(getPeriodSortKey(b));
|
|
86
|
+
if (periodComparison !== 0)
|
|
87
|
+
return periodComparison;
|
|
88
|
+
const weekdayGroupComparison = getWeekdayGroupPriority(a) - getWeekdayGroupPriority(b);
|
|
89
|
+
if (weekdayGroupComparison !== 0)
|
|
90
|
+
return weekdayGroupComparison;
|
|
91
|
+
const weekdayComparison = getWeekdaySortKey(a).localeCompare(getWeekdaySortKey(b));
|
|
92
|
+
if (weekdayComparison !== 0)
|
|
93
|
+
return weekdayComparison;
|
|
94
|
+
return safeStringCompare(a.name, b.name);
|
|
95
|
+
}
|
|
96
|
+
function compareIncludeExcludeRules(a, b, totalYearPeriods) {
|
|
97
|
+
const aIsEventException = isEventException(a);
|
|
98
|
+
const bIsEventException = isEventException(b);
|
|
99
|
+
if (aIsEventException && !bIsEventException)
|
|
100
|
+
return 1;
|
|
101
|
+
if (!aIsEventException && bIsEventException)
|
|
102
|
+
return -1;
|
|
103
|
+
if (aIsEventException && bIsEventException) {
|
|
104
|
+
return compareByEventDate(a, b);
|
|
105
|
+
}
|
|
106
|
+
return compareByRuleParams(a, b, totalYearPeriods);
|
|
107
|
+
}
|
|
108
|
+
function compareOverwriteRules(a, b) {
|
|
109
|
+
return compareByEventDate(a, b);
|
|
110
|
+
}
|
|
111
|
+
/* * */
|
|
112
|
+
export function sortRulesBySection(rules, section, totalYearPeriods) {
|
|
113
|
+
const sortedRules = [...rules];
|
|
114
|
+
if (section === 'overwrite') {
|
|
115
|
+
return sortedRules.sort((a, b) => compareOverwriteRules(a, b));
|
|
116
|
+
}
|
|
117
|
+
return sortedRules.sort((a, b) => compareIncludeExcludeRules(a, b, totalYearPeriods));
|
|
118
|
+
}
|
|
@@ -2,6 +2,7 @@ export * from './calculation/index.js';
|
|
|
2
2
|
export * from './calculation/types.js';
|
|
3
3
|
export * from './formatting/parameter-summary.js';
|
|
4
4
|
export * from './formatting/rule-summary.js';
|
|
5
|
+
export * from './formatting/sort.js';
|
|
5
6
|
export * from './merging/index.js';
|
|
6
7
|
export * from './preview/affectedDates.js';
|
|
7
8
|
export * from './preview/buildDayDetails.js';
|
|
@@ -2,6 +2,7 @@ export * from './calculation/index.js';
|
|
|
2
2
|
export * from './calculation/types.js';
|
|
3
3
|
export * from './formatting/parameter-summary.js';
|
|
4
4
|
export * from './formatting/rule-summary.js';
|
|
5
|
+
export * from './formatting/sort.js';
|
|
5
6
|
export * from './merging/index.js';
|
|
6
7
|
export * from './preview/affectedDates.js';
|
|
7
8
|
export * from './preview/buildDayDetails.js';
|