Merge dev v0.5.1 before 0.6 update with calender. #25
@@ -330,19 +330,35 @@ async def disable_schedule(
|
||||
db: Session = Depends(get_db),
|
||||
):
|
||||
"""
|
||||
Disable a schedule.
|
||||
Disable a schedule and cancel all its pending actions.
|
||||
"""
|
||||
service = get_recurring_schedule_service(db)
|
||||
|
||||
# Count pending actions before disabling (for response message)
|
||||
from sqlalchemy import and_
|
||||
from backend.models import ScheduledAction
|
||||
pending_count = db.query(ScheduledAction).filter(
|
||||
and_(
|
||||
ScheduledAction.execution_status == "pending",
|
||||
ScheduledAction.notes.like(f'%"schedule_id": "{schedule_id}"%'),
|
||||
)
|
||||
).count()
|
||||
|
||||
schedule = service.disable_schedule(schedule_id)
|
||||
|
||||
if not schedule:
|
||||
raise HTTPException(status_code=404, detail="Schedule not found")
|
||||
|
||||
message = "Schedule disabled"
|
||||
if pending_count > 0:
|
||||
message += f" and {pending_count} pending action(s) cancelled"
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"schedule_id": schedule.id,
|
||||
"enabled": schedule.enabled,
|
||||
"message": "Schedule disabled",
|
||||
"cancelled_actions": pending_count,
|
||||
"message": message,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -169,8 +169,25 @@ class RecurringScheduleService:
|
||||
return self.update_schedule(schedule_id, enabled=True)
|
||||
|
||||
def disable_schedule(self, schedule_id: str) -> Optional[RecurringSchedule]:
|
||||
"""Disable a schedule."""
|
||||
return self.update_schedule(schedule_id, enabled=False)
|
||||
"""Disable a schedule and cancel its pending actions."""
|
||||
schedule = self.update_schedule(schedule_id, enabled=False)
|
||||
if schedule:
|
||||
# Cancel all pending actions generated by this schedule
|
||||
pending_actions = self.db.query(ScheduledAction).filter(
|
||||
and_(
|
||||
ScheduledAction.execution_status == "pending",
|
||||
ScheduledAction.notes.like(f'%"schedule_id": "{schedule_id}"%'),
|
||||
)
|
||||
).all()
|
||||
|
||||
for action in pending_actions:
|
||||
action.execution_status = "cancelled"
|
||||
|
||||
if pending_actions:
|
||||
self.db.commit()
|
||||
logger.info(f"Cancelled {len(pending_actions)} pending actions for disabled schedule {schedule.name}")
|
||||
|
||||
return schedule
|
||||
|
||||
def generate_actions_for_schedule(
|
||||
self,
|
||||
|
||||
@@ -311,6 +311,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settings-success" class="hidden text-sm text-green-600 dark:text-green-400"></div>
|
||||
<div id="settings-error" class="hidden text-sm text-red-600"></div>
|
||||
|
||||
<div class="flex justify-end gap-3 pt-2">
|
||||
@@ -606,6 +607,9 @@ function switchTab(tabName) {
|
||||
button.classList.remove('border-transparent', 'text-gray-600', 'dark:text-gray-400');
|
||||
button.classList.add('border-seismo-orange', 'text-seismo-orange');
|
||||
}
|
||||
|
||||
// Persist active tab in URL hash so refresh stays on this tab
|
||||
history.replaceState(null, '', `#${tabName}`);
|
||||
}
|
||||
|
||||
// Load project details
|
||||
@@ -677,12 +681,20 @@ document.getElementById('project-settings-form').addEventListener('submit', asyn
|
||||
throw new Error('Failed to update project');
|
||||
}
|
||||
|
||||
// Reload page to show updated data
|
||||
window.location.reload();
|
||||
// Refresh header and dashboard without full page reload
|
||||
refreshProjectDashboard();
|
||||
|
||||
// Show success feedback
|
||||
const successEl = document.getElementById('settings-success');
|
||||
successEl.textContent = 'Settings saved.';
|
||||
successEl.classList.remove('hidden');
|
||||
document.getElementById('settings-error').classList.add('hidden');
|
||||
setTimeout(() => successEl.classList.add('hidden'), 3000);
|
||||
} catch (err) {
|
||||
const errorEl = document.getElementById('settings-error');
|
||||
errorEl.textContent = err.message || 'Failed to update project.';
|
||||
errorEl.classList.remove('hidden');
|
||||
document.getElementById('settings-success').classList.add('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1251,9 +1263,16 @@ document.getElementById('schedule-modal')?.addEventListener('click', function(e)
|
||||
}
|
||||
});
|
||||
|
||||
// Load project details on page load
|
||||
// Load project details on page load and restore active tab from URL hash
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
loadProjectDetails();
|
||||
|
||||
// Restore tab from URL hash (e.g. #schedules, #settings)
|
||||
const hash = window.location.hash.replace('#', '');
|
||||
const validTabs = ['overview', 'locations', 'units', 'schedules', 'sessions', 'data', 'settings'];
|
||||
if (hash && validTabs.includes(hash)) {
|
||||
switchTab(hash);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user