feat: add support for one-off recording schedules with start and end datetime
This commit is contained in:
@@ -456,7 +456,7 @@
|
||||
<!-- Schedule Type Selection -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Schedule Type</label>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<label class="relative cursor-pointer">
|
||||
<input type="radio" name="schedule_type" value="weekly_calendar" class="peer sr-only" checked onchange="toggleScheduleType('weekly_calendar')">
|
||||
<div class="p-4 border-2 border-gray-200 dark:border-gray-600 rounded-lg peer-checked:border-seismo-orange peer-checked:bg-orange-50 dark:peer-checked:bg-orange-900/20 transition-colors">
|
||||
@@ -485,6 +485,20 @@
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
<label class="relative cursor-pointer">
|
||||
<input type="radio" name="schedule_type" value="one_off" class="peer sr-only" onchange="toggleScheduleType('one_off')">
|
||||
<div class="p-4 border-2 border-gray-200 dark:border-gray-600 rounded-lg peer-checked:border-seismo-orange peer-checked:bg-orange-50 dark:peer-checked:bg-orange-900/20 transition-colors">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<svg class="w-6 h-6 text-gray-500 peer-checked:text-seismo-orange" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
<span class="font-medium text-gray-900 dark:text-white">One-Off Recording</span>
|
||||
</div>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Single recording session with a specific start and end date/time (15 min - 24 hrs).
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -498,6 +512,11 @@
|
||||
{% include "partials/projects/schedule_interval.html" %}
|
||||
</div>
|
||||
|
||||
<!-- One-Off Editor -->
|
||||
<div id="schedule-oneoff-wrapper" class="hidden">
|
||||
{% include "partials/projects/schedule_oneoff.html" %}
|
||||
</div>
|
||||
|
||||
<!-- Timezone -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Timezone</label>
|
||||
@@ -1108,13 +1127,18 @@ function getSelectedLocationIds() {
|
||||
function toggleScheduleType(type) {
|
||||
const weeklyEditor = document.getElementById('schedule-weekly-wrapper');
|
||||
const intervalEditor = document.getElementById('schedule-interval-wrapper');
|
||||
const oneoffEditor = document.getElementById('schedule-oneoff-wrapper');
|
||||
|
||||
weeklyEditor.classList.add('hidden');
|
||||
intervalEditor.classList.add('hidden');
|
||||
oneoffEditor.classList.add('hidden');
|
||||
|
||||
if (type === 'weekly_calendar') {
|
||||
weeklyEditor.classList.remove('hidden');
|
||||
intervalEditor.classList.add('hidden');
|
||||
} else {
|
||||
weeklyEditor.classList.add('hidden');
|
||||
} else if (type === 'simple_interval') {
|
||||
intervalEditor.classList.remove('hidden');
|
||||
} else if (type === 'one_off') {
|
||||
oneoffEditor.classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1178,7 +1202,7 @@ document.getElementById('schedule-form').addEventListener('submit', async functi
|
||||
} else {
|
||||
payload.include_download = true;
|
||||
}
|
||||
} else {
|
||||
} else if (scheduleType === 'simple_interval') {
|
||||
// Get interval data
|
||||
if (typeof getIntervalData === 'function') {
|
||||
const intervalData = getIntervalData();
|
||||
@@ -1190,6 +1214,45 @@ document.getElementById('schedule-form').addEventListener('submit', async functi
|
||||
showScheduleError('Interval editor not loaded properly.');
|
||||
return;
|
||||
}
|
||||
} else if (scheduleType === 'one_off') {
|
||||
// Get one-off data
|
||||
if (typeof getOneOffData === 'function') {
|
||||
const oneOffData = getOneOffData();
|
||||
|
||||
if (!oneOffData.start_datetime || !oneOffData.end_datetime) {
|
||||
showScheduleError('Please select both start and end date/time.');
|
||||
return;
|
||||
}
|
||||
|
||||
const start = new Date(oneOffData.start_datetime);
|
||||
const end = new Date(oneOffData.end_datetime);
|
||||
const diffMinutes = (end - start) / (1000 * 60);
|
||||
|
||||
if (diffMinutes <= 0) {
|
||||
showScheduleError('End time must be after start time.');
|
||||
return;
|
||||
}
|
||||
if (diffMinutes < 15) {
|
||||
showScheduleError('Duration must be at least 15 minutes.');
|
||||
return;
|
||||
}
|
||||
if (diffMinutes > 1440) {
|
||||
showScheduleError('Duration cannot exceed 24 hours.');
|
||||
return;
|
||||
}
|
||||
if (start <= new Date()) {
|
||||
showScheduleError('Start time must be in the future.');
|
||||
return;
|
||||
}
|
||||
|
||||
payload.start_datetime = oneOffData.start_datetime;
|
||||
payload.end_datetime = oneOffData.end_datetime;
|
||||
payload.include_download = oneOffData.include_download;
|
||||
payload.auto_increment_index = oneOffData.auto_increment_index;
|
||||
} else {
|
||||
showScheduleError('One-off editor not loaded properly.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user