Feat: Scheduler implemented, WIP
This commit is contained in:
231
templates/partials/projects/schedule_calendar.html
Normal file
231
templates/partials/projects/schedule_calendar.html
Normal file
@@ -0,0 +1,231 @@
|
||||
<!-- Weekly Calendar Schedule Editor -->
|
||||
<!-- Used in modals/forms for creating/editing weekly_calendar type schedules -->
|
||||
|
||||
<div id="schedule-calendar-editor" class="space-y-4">
|
||||
<div class="mb-4">
|
||||
<h4 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Weekly Schedule</h4>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">
|
||||
Select which days to monitor and set start/end times for each day.
|
||||
For overnight monitoring (e.g., 7pm to 7am), the end time will be on the following day.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Day rows -->
|
||||
<div class="space-y-3">
|
||||
{% set days = [
|
||||
('monday', 'Monday'),
|
||||
('tuesday', 'Tuesday'),
|
||||
('wednesday', 'Wednesday'),
|
||||
('thursday', 'Thursday'),
|
||||
('friday', 'Friday'),
|
||||
('saturday', 'Saturday'),
|
||||
('sunday', 'Sunday')
|
||||
] %}
|
||||
|
||||
{% for day_key, day_name in days %}
|
||||
<div class="flex items-center gap-4 p-3 bg-gray-50 dark:bg-gray-700/50 rounded-lg">
|
||||
<!-- Day toggle -->
|
||||
<label class="flex items-center gap-2 w-28 cursor-pointer">
|
||||
<input type="checkbox"
|
||||
id="day-{{ day_key }}"
|
||||
name="weekly_pattern[{{ day_key }}][enabled]"
|
||||
class="rounded text-seismo-orange focus:ring-seismo-orange"
|
||||
onchange="toggleDayTimes('{{ day_key }}', this.checked)"
|
||||
{% if pattern and pattern.get(day_key, {}).get('enabled') %}checked{% endif %}>
|
||||
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">{{ day_name }}</span>
|
||||
</label>
|
||||
|
||||
<!-- Time inputs -->
|
||||
<div class="flex items-center gap-2 day-times flex-1" id="times-{{ day_key }}"
|
||||
{% if not pattern or not pattern.get(day_key, {}).get('enabled') %}style="opacity: 0.4; pointer-events: none;"{% endif %}>
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">Start:</label>
|
||||
<input type="time"
|
||||
name="weekly_pattern[{{ day_key }}][start]"
|
||||
value="{{ pattern.get(day_key, {}).get('start', '19:00') if pattern else '19:00' }}"
|
||||
class="px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-seismo-orange focus:border-seismo-orange">
|
||||
|
||||
<span class="text-gray-400 mx-1">to</span>
|
||||
|
||||
<label class="text-xs text-gray-500 dark:text-gray-400">End:</label>
|
||||
<input type="time"
|
||||
name="weekly_pattern[{{ day_key }}][end]"
|
||||
value="{{ pattern.get(day_key, {}).get('end', '07:00') if pattern else '07:00' }}"
|
||||
class="px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:ring-seismo-orange focus:border-seismo-orange">
|
||||
|
||||
<span class="text-xs text-gray-400 dark:text-gray-500 ml-2" id="overnight-hint-{{ day_key }}"
|
||||
style="display: none;">
|
||||
(next day)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- Quick select buttons -->
|
||||
<div class="flex flex-wrap gap-2 pt-2 border-t border-gray-200 dark:border-gray-700">
|
||||
<span class="text-xs text-gray-500 dark:text-gray-400 mr-2">Quick select:</span>
|
||||
<button type="button" onclick="selectWeekdays()"
|
||||
class="px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
|
||||
Weekdays
|
||||
</button>
|
||||
<button type="button" onclick="selectWeekends()"
|
||||
class="px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
|
||||
Weekends
|
||||
</button>
|
||||
<button type="button" onclick="selectAllDays()"
|
||||
class="px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
|
||||
All Days
|
||||
</button>
|
||||
<button type="button" onclick="clearAllDays()"
|
||||
class="px-2 py-1 text-xs bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-200 dark:hover:bg-gray-600">
|
||||
Clear All
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Automation Options -->
|
||||
<div class="pt-4 border-t border-gray-200 dark:border-gray-700">
|
||||
<h5 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3">Automation Options</h5>
|
||||
|
||||
<div class="space-y-3">
|
||||
<!-- Download data option -->
|
||||
<div class="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4">
|
||||
<label class="flex items-start gap-3 cursor-pointer">
|
||||
<input type="checkbox"
|
||||
name="include_download"
|
||||
id="include_download_calendar"
|
||||
class="rounded text-seismo-orange focus:ring-seismo-orange mt-0.5"
|
||||
{% if include_download is not defined or include_download %}checked{% endif %}>
|
||||
<div>
|
||||
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Download data after each monitoring period
|
||||
</span>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
When enabled, measurement data will be downloaded via FTP after each stop.
|
||||
Disable if you prefer to download manually or if FTP is not configured.
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Auto-increment index option -->
|
||||
<div class="bg-gray-50 dark:bg-gray-700/50 rounded-lg p-4">
|
||||
<label class="flex items-start gap-3 cursor-pointer">
|
||||
<input type="checkbox"
|
||||
name="auto_increment_index"
|
||||
id="auto_increment_index_calendar"
|
||||
class="rounded text-seismo-orange focus:ring-seismo-orange mt-0.5"
|
||||
{% if auto_increment_index is not defined or auto_increment_index %}checked{% endif %}>
|
||||
<div>
|
||||
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">
|
||||
Auto-increment store index before each start
|
||||
</span>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">
|
||||
When enabled, the system will find an unused store/index number before starting.
|
||||
This prevents "overwrite existing data?" prompts on the device.
|
||||
</p>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
|
||||
const weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];
|
||||
const weekends = ['saturday', 'sunday'];
|
||||
|
||||
function toggleDayTimes(day, enabled) {
|
||||
const timesDiv = document.getElementById('times-' + day);
|
||||
if (enabled) {
|
||||
timesDiv.style.opacity = '1';
|
||||
timesDiv.style.pointerEvents = 'auto';
|
||||
} else {
|
||||
timesDiv.style.opacity = '0.4';
|
||||
timesDiv.style.pointerEvents = 'none';
|
||||
}
|
||||
updateOvernightHints();
|
||||
}
|
||||
|
||||
function setDayEnabled(day, enabled) {
|
||||
const checkbox = document.getElementById('day-' + day);
|
||||
checkbox.checked = enabled;
|
||||
toggleDayTimes(day, enabled);
|
||||
}
|
||||
|
||||
function selectWeekdays() {
|
||||
days.forEach(day => setDayEnabled(day, weekdays.includes(day)));
|
||||
}
|
||||
|
||||
function selectWeekends() {
|
||||
days.forEach(day => setDayEnabled(day, weekends.includes(day)));
|
||||
}
|
||||
|
||||
function selectAllDays() {
|
||||
days.forEach(day => setDayEnabled(day, true));
|
||||
}
|
||||
|
||||
function clearAllDays() {
|
||||
days.forEach(day => setDayEnabled(day, false));
|
||||
}
|
||||
|
||||
function updateOvernightHints() {
|
||||
days.forEach(day => {
|
||||
const startInput = document.querySelector(`input[name="weekly_pattern[${day}][start]"]`);
|
||||
const endInput = document.querySelector(`input[name="weekly_pattern[${day}][end]"]`);
|
||||
const hint = document.getElementById('overnight-hint-' + day);
|
||||
|
||||
if (startInput && endInput && hint) {
|
||||
const start = startInput.value;
|
||||
const end = endInput.value;
|
||||
hint.style.display = (end && start && end <= start) ? 'inline' : 'none';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update hints on time change
|
||||
document.querySelectorAll('input[type="time"]').forEach(input => {
|
||||
input.addEventListener('change', updateOvernightHints);
|
||||
});
|
||||
|
||||
// Initial update
|
||||
updateOvernightHints();
|
||||
|
||||
// Function to collect form data as JSON
|
||||
function getWeeklyPatternData() {
|
||||
const pattern = {};
|
||||
days.forEach(day => {
|
||||
const checkbox = document.getElementById('day-' + day);
|
||||
const startInput = document.querySelector(`input[name="weekly_pattern[${day}][start]"]`);
|
||||
const endInput = document.querySelector(`input[name="weekly_pattern[${day}][end]"]`);
|
||||
|
||||
pattern[day] = {
|
||||
enabled: checkbox.checked,
|
||||
start: startInput.value,
|
||||
end: endInput.value
|
||||
};
|
||||
});
|
||||
return pattern;
|
||||
}
|
||||
|
||||
// Function to get auto-increment setting for calendar mode
|
||||
function getCalendarAutoIncrement() {
|
||||
const checkbox = document.getElementById('auto_increment_index_calendar');
|
||||
return checkbox ? checkbox.checked : true;
|
||||
}
|
||||
|
||||
// Function to get include_download setting for calendar mode
|
||||
function getCalendarIncludeDownload() {
|
||||
const checkbox = document.getElementById('include_download_calendar');
|
||||
return checkbox ? checkbox.checked : true;
|
||||
}
|
||||
|
||||
// Function to get all calendar options as object
|
||||
function getCalendarOptions() {
|
||||
return {
|
||||
weekly_pattern: getWeeklyPatternData(),
|
||||
auto_increment_index: getCalendarAutoIncrement(),
|
||||
include_download: getCalendarIncludeDownload()
|
||||
};
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user