215 lines
5.3 KiB
JavaScript
215 lines
5.3 KiB
JavaScript
// Shared schedule rule helpers for playlist playback and editor rendering.
|
|
|
|
const DAY_NAMES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
|
|
function normalizeDateTimeValue(value) {
|
|
const raw = String(value || '').trim();
|
|
return raw ? raw : null;
|
|
}
|
|
|
|
function normalizeTimeValue(value) {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) {
|
|
return null;
|
|
}
|
|
const match = raw.match(/^(\d{2}):(\d{2})(?::\d{2})?$/);
|
|
if (!match) {
|
|
return null;
|
|
}
|
|
return match[1] + ':' + match[2];
|
|
}
|
|
|
|
function normalizeDayValues(value) {
|
|
let days = [];
|
|
|
|
if (Array.isArray(value)) {
|
|
days = value;
|
|
} else if (value !== undefined && value !== null && String(value).trim()) {
|
|
try {
|
|
const parsed = typeof value === 'string' ? JSON.parse(value) : value;
|
|
if (Array.isArray(parsed)) {
|
|
days = parsed;
|
|
}
|
|
} catch (_error) {
|
|
days = String(value)
|
|
.split(',')
|
|
.map(function (item) {
|
|
return item.trim();
|
|
})
|
|
.filter(Boolean);
|
|
}
|
|
}
|
|
|
|
return Array.from(new Set(days.map(function (day) {
|
|
return Number(day);
|
|
}).filter(function (day) {
|
|
return Number.isInteger(day) && day >= 0 && day <= 6;
|
|
}))).sort(function (left, right) {
|
|
return left - right;
|
|
});
|
|
}
|
|
|
|
function normalizeScheduleRule(rule) {
|
|
const input = rule && typeof rule === 'object' ? rule : {};
|
|
const startDatetime = normalizeDateTimeValue(
|
|
input.start_datetime || input.startDateTime || input.schedule_start_datetime || input.scheduleStartDatetime
|
|
);
|
|
const endDatetime = normalizeDateTimeValue(
|
|
input.end_datetime || input.endDateTime || input.schedule_end_datetime || input.scheduleEndDatetime
|
|
);
|
|
const startTime = normalizeTimeValue(
|
|
input.start_time || input.startTime || input.schedule_start_time || input.scheduleStartTime
|
|
);
|
|
const endTime = normalizeTimeValue(
|
|
input.end_time || input.endTime || input.schedule_end_time || input.scheduleEndTime
|
|
);
|
|
const days = normalizeDayValues(
|
|
input.days || input.day_list || input.schedule_days || input.schedule_days_json || input.scheduleDays
|
|
);
|
|
|
|
if (startDatetime || endDatetime) {
|
|
if (!startDatetime || !endDatetime) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if (startTime || endTime) {
|
|
if (!startTime || !endTime) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if (!startDatetime && !endDatetime && !startTime && !endTime && !days.length) {
|
|
return null;
|
|
}
|
|
|
|
const normalized = {};
|
|
if (startDatetime) {
|
|
normalized.start_datetime = startDatetime;
|
|
}
|
|
if (endDatetime) {
|
|
normalized.end_datetime = endDatetime;
|
|
}
|
|
if (startTime) {
|
|
normalized.start_time = startTime;
|
|
}
|
|
if (endTime) {
|
|
normalized.end_time = endTime;
|
|
}
|
|
if (days.length) {
|
|
normalized.days = days;
|
|
}
|
|
|
|
return normalized;
|
|
}
|
|
|
|
function parseScheduleRules(value) {
|
|
let rawRules = [];
|
|
|
|
if (Array.isArray(value)) {
|
|
rawRules = value;
|
|
} else if (value && typeof value === 'object' && Array.isArray(value.rules)) {
|
|
rawRules = value.rules;
|
|
} else {
|
|
const rawValue = String(value || '').trim();
|
|
if (!rawValue) {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
const parsed = JSON.parse(rawValue);
|
|
rawRules = Array.isArray(parsed) ? parsed : [];
|
|
} catch (_error) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return rawRules
|
|
.map(function (rule) {
|
|
return normalizeScheduleRule(rule);
|
|
})
|
|
.filter(Boolean);
|
|
}
|
|
|
|
function serializeScheduleRules(value) {
|
|
const normalized = parseScheduleRules(value);
|
|
if (normalized === null) {
|
|
return null;
|
|
}
|
|
return JSON.stringify(normalized);
|
|
}
|
|
|
|
function formatDateTime(value) {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) {
|
|
return '';
|
|
}
|
|
return raw.replace('T', ' ').slice(0, 16);
|
|
}
|
|
|
|
function formatTime(value) {
|
|
const raw = String(value || '').trim();
|
|
if (!raw) {
|
|
return '';
|
|
}
|
|
return raw.slice(0, 5);
|
|
}
|
|
|
|
function formatDays(value) {
|
|
const days = normalizeDayValues(value);
|
|
return days
|
|
.map(function (day) {
|
|
return DAY_NAMES[day] || '';
|
|
})
|
|
.filter(Boolean)
|
|
.join(', ');
|
|
}
|
|
|
|
function formatScheduleRuleSummary(rule) {
|
|
const normalized = normalizeScheduleRule(rule);
|
|
if (!normalized) {
|
|
return 'Always visible';
|
|
}
|
|
|
|
const leftParts = [];
|
|
if (normalized.start_datetime && normalized.end_datetime) {
|
|
leftParts.push('Dates ' + formatDateTime(normalized.start_datetime) + ' to ' + formatDateTime(normalized.end_datetime));
|
|
} else {
|
|
leftParts.push('Any date');
|
|
}
|
|
|
|
const rightParts = [];
|
|
const days = formatDays(normalized.days || []);
|
|
if (days) {
|
|
rightParts.push(days);
|
|
}
|
|
if (normalized.start_time && normalized.end_time) {
|
|
rightParts.push(formatTime(normalized.start_time) + '-' + formatTime(normalized.end_time));
|
|
}
|
|
|
|
if (rightParts.length) {
|
|
return leftParts[0] + ': ' + rightParts.join(' ');
|
|
}
|
|
|
|
return leftParts[0];
|
|
}
|
|
|
|
function formatScheduleRulesSummary(value) {
|
|
const rules = parseScheduleRules(value) || [];
|
|
if (!rules.length) {
|
|
return 'Always visible';
|
|
}
|
|
|
|
return rules.length === 1 ? '1 rule' : String(rules.length) + ' rules';
|
|
}
|
|
|
|
module.exports = {
|
|
normalizeDateTimeValue: normalizeDateTimeValue,
|
|
normalizeTimeValue: normalizeTimeValue,
|
|
normalizeDayValues: normalizeDayValues,
|
|
normalizeScheduleRule: normalizeScheduleRule,
|
|
parseScheduleRules: parseScheduleRules,
|
|
serializeScheduleRules: serializeScheduleRules,
|
|
formatScheduleRuleSummary: formatScheduleRuleSummary,
|
|
formatScheduleRulesSummary: formatScheduleRulesSummary
|
|
}; |