prepare schedule end + fix hot reload

This commit is contained in:
jr-k 2024-05-12 21:16:13 +02:00
parent f24f28584f
commit 3592191367
14 changed files with 108 additions and 24 deletions

View File

@ -469,6 +469,7 @@ button.purple:hover {
min-width: 30%; min-width: 30%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: auto;
} }
.modals-outer .modal-close { .modals-outer .modal-close {
@ -479,7 +480,7 @@ button.purple:hover {
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
margin-bottom: 20px; margin-bottom: 20px;
margin-top: -100px; margin-top: 0px;
} }
.modals-inner { .modals-inner {
@ -494,6 +495,14 @@ button.purple:hover {
margin: 0; margin: 0;
} }
.modals-inner .modal h3 {
align-self: stretch;
border-bottom: 1px solid #DDD;
padding: 15px 15px;
margin: 0;
}
form { form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -503,7 +512,7 @@ form {
} }
form .form-group { form .form-group {
margin: 20px; margin: 10px 20px 5px 20px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;

View File

@ -154,6 +154,10 @@ jQuery(document).ready(function ($) {
const hasCron = slide.cron_schedule && slide.cron_schedule.length > 0; const hasCron = slide.cron_schedule && slide.cron_schedule.length > 0;
const hasDateTime = hasCron && validateCronDateTime(slide.cron_schedule); const hasDateTime = hasCron && validateCronDateTime(slide.cron_schedule);
const hasCronEnd = slide.cron_schedule_end && slide.cron_schedule_end.length > 0;
const hasDateTimeEnd = hasCronEnd && validateCronDateTime(slide.cron_schedule_end);
let location = slide.location; let location = slide.location;
if (slide.type == 'youtube') { if (slide.type == 'youtube') {
@ -165,11 +169,20 @@ jQuery(document).ready(function ($) {
$('#slide-edit-type').val(slide.type); $('#slide-edit-type').val(slide.type);
$('#slide-edit-location').val(location).prop('disabled', !slide.is_editable); $('#slide-edit-location').val(location).prop('disabled', !slide.is_editable);
$('#slide-edit-duration').val(slide.duration); $('#slide-edit-duration').val(slide.duration);
$('#slide-edit-cron-schedule').val(slide.cron_schedule).toggleClass('hidden', !hasCron || hasDateTime); $('#slide-edit-cron-schedule').val(slide.cron_schedule).toggleClass('hidden', !hasCron || hasDateTime);
$('#slide-edit-cron-schedule-trigger').val(hasDateTime ? 'datetime' : (hasCron ? 'cron' : 'loop')); $('#slide-edit-cron-schedule-trigger').val(hasDateTime ? 'datetime' : (hasCron ? 'cron' : 'loop'));
$('#slide-edit-cron-schedule-end').val(slide.cron_schedule_end).toggleClass('hidden', !hasCronEnd || hasDateTimeEnd);
$('#slide-edit-cron-schedule-end-trigger').val(hasDateTimeEnd ? 'datetime' : (hasCronEnd ? 'cron' : 'loop'));
$('#slide-edit-cron-schedule-datetimepicker').toggleClass('hidden', !hasDateTime).val( $('#slide-edit-cron-schedule-datetimepicker').toggleClass('hidden', !hasDateTime).val(
hasDateTime ? getCronDateTime(slide.cron_schedule) : '' hasDateTime ? getCronDateTime(slide.cron_schedule) : ''
); );
$('#slide-edit-cron-schedule-end-datetimepicker').toggleClass('hidden', !hasDateTimeEnd).val(
hasDateTimeEnd ? getCronDateTime(slide.cron_schedule_end) : ''
);
$('#slide-edit-id').val(slide.id); $('#slide-edit-id').val(slide.id);
}); });

View File

@ -8,10 +8,10 @@
"slideshow_slide_panel_inactive": "Inactive slides", "slideshow_slide_panel_inactive": "Inactive slides",
"slideshow_slide_panel_empty": "Currently, there are no slides. %link% now.", "slideshow_slide_panel_empty": "Currently, there are no slides. %link% now.",
"slideshow_slide_panel_th_name": "Name", "slideshow_slide_panel_th_name": "Name",
"slideshow_slide_panel_th_duration": "Duration", "slideshow_slide_panel_th_duration": "Ends after",
"slideshow_slide_panel_th_duration_unit": "sec", "slideshow_slide_panel_th_duration_unit": "sec",
"slideshow_slide_panel_th_enabled": "Enabled", "slideshow_slide_panel_th_enabled": "Enabled",
"slideshow_slide_panel_th_cron_scheduled": "Scheduled", "slideshow_slide_panel_th_cron_scheduled": "Scheduled Start",
"slideshow_slide_panel_th_activity": "Activity", "slideshow_slide_panel_th_activity": "Activity",
"slideshow_slide_panel_td_cron_scheduled_loop": "Loop", "slideshow_slide_panel_td_cron_scheduled_loop": "Loop",
"slideshow_slide_panel_td_cron_scheduled_bad_cron": "Bad cron value", "slideshow_slide_panel_td_cron_scheduled_bad_cron": "Bad cron value",
@ -19,13 +19,16 @@
"slideshow_slide_form_add_submit": "Add", "slideshow_slide_form_add_submit": "Add",
"slideshow_slide_form_edit_title": "Edit Slide", "slideshow_slide_form_edit_title": "Edit Slide",
"slideshow_slide_form_edit_submit": "Save", "slideshow_slide_form_edit_submit": "Save",
"slideshow_slide_form_section_content": "Content",
"slideshow_slide_form_section_scheduling": "Scheduling",
"slideshow_slide_form_label_name": "Name", "slideshow_slide_form_label_name": "Name",
"slideshow_slide_form_label_location": "Location", "slideshow_slide_form_label_location": "Location",
"slideshow_slide_form_label_type": "Type", "slideshow_slide_form_label_type": "Type",
"slideshow_slide_form_label_object": "Object", "slideshow_slide_form_label_object": "Object",
"slideshow_slide_form_label_duration": "Duration", "slideshow_slide_form_label_duration": "Duration",
"slideshow_slide_form_label_duration_unit": "seconds", "slideshow_slide_form_label_duration_unit": "seconds",
"slideshow_slide_form_label_cron_scheduled": "Scheduled", "slideshow_slide_form_label_cron_scheduled": "Start",
"slideshow_slide_form_label_cron_scheduled_end": "End",
"slideshow_slide_form_label_cron_scheduled_loop": "In the loop", "slideshow_slide_form_label_cron_scheduled_loop": "In the loop",
"slideshow_slide_form_label_cron_scheduled_datetime": "Date & Time", "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Time",
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Set a date and time", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Set a date and time",
@ -79,7 +82,7 @@
"settings_variable_panel_th_description": "Description", "settings_variable_panel_th_description": "Description",
"settings_variable_panel_th_value": "Value", "settings_variable_panel_th_value": "Value",
"settings_variable_panel_th_activity": "Options", "settings_variable_panel_th_activity": "Options",
"settings_variable_form_edit_title": "Edit Variable", "settings_variable_form_edit_title": "Edit Setting",
"settings_variable_form_edit_submit": "Save", "settings_variable_form_edit_submit": "Save",
"settings_variable_form_label_name": "Name", "settings_variable_form_label_name": "Name",
"settings_variable_form_label_value": "Value", "settings_variable_form_label_value": "Value",

View File

@ -8,7 +8,7 @@
"slideshow_slide_panel_inactive": "Slides inactives", "slideshow_slide_panel_inactive": "Slides inactives",
"slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.", "slideshow_slide_panel_empty": "Actuellement, il n'y a aucune slide. %link% maintenant.",
"slideshow_slide_panel_th_name": "Nom", "slideshow_slide_panel_th_name": "Nom",
"slideshow_slide_panel_th_duration": "Durée", "slideshow_slide_panel_th_duration": "Fin après",
"slideshow_slide_panel_th_duration_unit": "sec", "slideshow_slide_panel_th_duration_unit": "sec",
"slideshow_slide_panel_th_enabled": "Activé", "slideshow_slide_panel_th_enabled": "Activé",
"slideshow_slide_panel_th_cron_scheduled": "Programmation", "slideshow_slide_panel_th_cron_scheduled": "Programmation",
@ -19,13 +19,16 @@
"slideshow_slide_form_add_submit": "Ajouter", "slideshow_slide_form_add_submit": "Ajouter",
"slideshow_slide_form_edit_title": "Modification d'une slide", "slideshow_slide_form_edit_title": "Modification d'une slide",
"slideshow_slide_form_edit_submit": "Enregistrer", "slideshow_slide_form_edit_submit": "Enregistrer",
"slideshow_slide_form_section_content": "Contenu",
"slideshow_slide_form_section_scheduling": "Programmation",
"slideshow_slide_form_label_name": "Nom", "slideshow_slide_form_label_name": "Nom",
"slideshow_slide_form_label_location": "Chemin", "slideshow_slide_form_label_location": "Chemin",
"slideshow_slide_form_label_type": "Type", "slideshow_slide_form_label_type": "Type",
"slideshow_slide_form_label_object": "Objet", "slideshow_slide_form_label_object": "Objet",
"slideshow_slide_form_label_duration": "Durée", "slideshow_slide_form_label_duration": "Durée",
"slideshow_slide_form_label_duration_unit": "secondes", "slideshow_slide_form_label_duration_unit": "secondes",
"slideshow_slide_form_label_cron_scheduled": "Programmer", "slideshow_slide_form_label_cron_scheduled": "Début",
"slideshow_slide_form_label_cron_scheduled_end": "Fin",
"slideshow_slide_form_label_cron_scheduled_loop": "Dans la boucle", "slideshow_slide_form_label_cron_scheduled_loop": "Dans la boucle",
"slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure", "slideshow_slide_form_label_cron_scheduled_datetime": "Date & Heure",
"slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure", "slideshow_slide_form_label_cron_scheduled_datetime_placeholder": "Choisir une date et une heure",
@ -79,7 +82,7 @@
"settings_variable_panel_th_description": "Description", "settings_variable_panel_th_description": "Description",
"settings_variable_panel_th_value": "Valeur", "settings_variable_panel_th_value": "Valeur",
"settings_variable_panel_th_activity": "Options", "settings_variable_panel_th_activity": "Options",
"settings_variable_form_edit_title": "Modification de la variable", "settings_variable_form_edit_title": "Modification du paramètre",
"settings_variable_form_edit_submit": "Enregistrer", "settings_variable_form_edit_submit": "Enregistrer",
"settings_variable_form_label_name": "Nom", "settings_variable_form_label_name": "Nom",
"settings_variable_form_label_value": "Valeur", "settings_variable_form_label_value": "Valeur",

View File

@ -42,6 +42,7 @@ class SlideshowController(ObController):
type=str_to_enum(request.form['type'], SlideType), type=str_to_enum(request.form['type'], SlideType),
duration=request.form['duration'], duration=request.form['duration'],
cron_schedule=get_optional_string(request.form['cron_schedule']), cron_schedule=get_optional_string(request.form['cron_schedule']),
cron_schedule_end=get_optional_string(request.form['cron_schedule_end']),
) )
if slide.has_file(): if slide.has_file():
@ -72,6 +73,7 @@ class SlideshowController(ObController):
name=request.form['name'], name=request.form['name'],
duration=request.form['duration'], duration=request.form['duration'],
cron_schedule=request.form['cron_schedule'], cron_schedule=request.form['cron_schedule'],
cron_schedule_end=request.form['cron_schedule_end'],
location=request.form['location'] if 'location' in request.form else None location=request.form['location'] if 'location' in request.form else None
) )
self._post_update() self._post_update()

View File

@ -21,7 +21,8 @@ class SlideManager(ModelManager):
"duration", "duration",
"position", "position",
"location", "location",
"cron_schedule" "cron_schedule",
"cron_schedule_end"
] ]
def __init__(self, lang_manager: LangManager, database_manager: DatabaseManager): def __init__(self, lang_manager: LangManager, database_manager: DatabaseManager):
@ -83,7 +84,7 @@ class SlideManager(ModelManager):
for slide_id, slide_position in positions.items(): for slide_id, slide_position in positions.items():
self._db.update_by_id(slide_id, {"position": slide_position}) self._db.update_by_id(slide_id, {"position": slide_position})
def update_form(self, id: str, name: str, duration: int, cron_schedule: Optional[str] = '', location: Optional[str] = None) -> None: def update_form(self, id: str, name: str, duration: int, cron_schedule: Optional[str] = '', cron_schedule_end: Optional[str] = '', location: Optional[str] = None) -> None:
slide = self.get(id) slide = self.get(id)
if not slide: if not slide:
@ -92,7 +93,8 @@ class SlideManager(ModelManager):
form = { form = {
"name": name, "name": name,
"duration": duration, "duration": duration,
"cron_schedule": get_optional_string(cron_schedule) "cron_schedule": get_optional_string(cron_schedule),
"cron_schedule_end": get_optional_string(cron_schedule_end)
} }
if location is not None and location: if location is not None and location:

View File

@ -7,7 +7,7 @@ from src.utils import str_to_enum
class Slide: class Slide:
def __init__(self, location: str = '', duration: int = 3, type: Union[SlideType, str] = SlideType.URL, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[str] = None, cron_schedule: Optional[str] = None): def __init__(self, location: str = '', duration: int = 3, type: Union[SlideType, str] = SlideType.URL, enabled: bool = False, name: str = 'Untitled', position: int = 999, id: Optional[str] = None, cron_schedule: Optional[str] = None, cron_schedule_end: Optional[str] = None):
self._id = id if id else None self._id = id if id else None
self._location = location self._location = location
self._duration = duration self._duration = duration
@ -16,6 +16,7 @@ class Slide:
self._name = name self._name = name
self._position = position self._position = position
self._cron_schedule = cron_schedule self._cron_schedule = cron_schedule
self._cron_schedule_end = cron_schedule_end
@property @property
def id(self) -> Optional[str]: def id(self) -> Optional[str]:
@ -45,6 +46,14 @@ class Slide:
def cron_schedule(self, value: Optional[str]): def cron_schedule(self, value: Optional[str]):
self._cron_schedule = value self._cron_schedule = value
@property
def cron_schedule_end(self) -> Optional[str]:
return self._cron_schedule_end
@cron_schedule_end.setter
def cron_schedule_end(self, value: Optional[str]):
self._cron_schedule_end = value
@property @property
def duration(self) -> int: def duration(self) -> int:
return self._duration return self._duration
@ -87,6 +96,7 @@ class Slide:
f"position='{self.position}',\n" \ f"position='{self.position}',\n" \
f"location='{self.location}',\n" \ f"location='{self.location}',\n" \
f"cron_schedule='{self.cron_schedule}',\n" \ f"cron_schedule='{self.cron_schedule}',\n" \
f"cron_schedule_end='{self.cron_schedule_end}',\n" \
f")" f")"
def to_json(self) -> str: def to_json(self) -> str:
@ -102,6 +112,7 @@ class Slide:
"duration": self.duration, "duration": self.duration,
"location": self.location, "location": self.location,
"cron_schedule": self.cron_schedule, "cron_schedule": self.cron_schedule,
"cron_schedule_end": self.cron_schedule_end,
} }
if with_virtual: if with_virtual:

View File

@ -105,11 +105,7 @@ class WebServer:
SlideshowController(self, self._app, auth_required, self._model_store, self._template_renderer) SlideshowController(self, self._app, auth_required, self._model_store, self._template_renderer)
SettingsController(self, self._app, auth_required, self._model_store, self._template_renderer) SettingsController(self, self._app, auth_required, self._model_store, self._template_renderer)
SysinfoController(self, self._app, auth_required, self._model_store, self._template_renderer) SysinfoController(self, self._app, auth_required, self._model_store, self._template_renderer)
if self._model_store.variable().map().get('fleet_enabled').as_bool():
FleetController(self, self._app, auth_required, self._model_store, self._template_renderer) FleetController(self, self._app, auth_required, self._model_store, self._template_renderer)
if self._login_manager:
AuthController(self, self._app, auth_required, self._model_store, self._template_renderer) AuthController(self, self._app, auth_required, self._model_store, self._template_renderer)
def _setup_web_globals(self) -> None: def _setup_web_globals(self) -> None:

View File

@ -109,7 +109,6 @@ def get_keys(dict_or_object, key_list_name: str, key_attr_name: str = 'key') ->
def enum_to_str(enum: Optional[Enum]) -> Optional[str]: def enum_to_str(enum: Optional[Enum]) -> Optional[str]:
if enum: if enum:
print(enum)
return str(enum.value) return str(enum.value)
return None return None

View File

@ -1,6 +1,6 @@
<div class="modal modal-user-edit hidden"> <div class="modal modal-user-edit hidden">
<h2> <h2>
{{ l.auth_user_form_edit_submit }} {{ l.auth_user_form_edit_title }}
</h2> </h2>
<form action="/auth/user/edit" method="POST"> <form action="/auth/user/edit" method="POST">

View File

@ -1,6 +1,6 @@
<div class="modal modal-screen-edit hidden"> <div class="modal modal-screen-edit hidden">
<h2> <h2>
{{ l.fleet_screen_form_edit_submit }} {{ l.fleet_screen_form_edit_title }}
</h2> </h2>
<form action="/fleet/screen/edit" method="POST"> <form action="/fleet/screen/edit" method="POST">

View File

@ -1,6 +1,6 @@
<div class="modal modal-variable-edit hidden"> <div class="modal modal-variable-edit hidden">
<h2> <h2>
{{ l.settings_variable_form_edit_submit }} {{ l.settings_variable_form_edit_title }}
</h2> </h2>
<form action="/settings/variable/edit" method="POST"> <form action="/settings/variable/edit" method="POST">

View File

@ -4,6 +4,11 @@
</h2> </h2>
<form action="/slideshow/slide/add" method="POST" enctype="multipart/form-data"> <form action="/slideshow/slide/add" method="POST" enctype="multipart/form-data">
<h3>
{{ l.slideshow_slide_form_section_content }}
</h3>
<div class="form-group"> <div class="form-group">
<label for="slide-add-name">{{ l.slideshow_slide_form_label_name }}</label> <label for="slide-add-name">{{ l.slideshow_slide_form_label_name }}</label>
<div class="widget"> <div class="widget">
@ -32,6 +37,10 @@
</div> </div>
</div> </div>
<h3>
{{ l.slideshow_slide_form_section_scheduling }}
</h3>
<div class="form-group"> <div class="form-group">
<label for="slide-add-duration">{{ l.slideshow_slide_form_label_duration }}</label> <label for="slide-add-duration">{{ l.slideshow_slide_form_label_duration }}</label>
<div class="widget"> <div class="widget">
@ -53,6 +62,19 @@
</div> </div>
</div> </div>
<div class="form-group hidden">
<label for="slide-add-cron-schedule-end">{{ l.slideshow_slide_form_label_cron_scheduled_end }}</label>
<div class="widget">
<select id="slide-add-cron-schedule-end-trigger" class="trigger">
<option value="loop">{{ l.slideshow_slide_form_label_cron_scheduled_loop }}</option>
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
</select>
<input type="text" id="slide-add-cron-schedule-end-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" />
<input type="text" name="cron_schedule_end" id="slide-add-cron-schedule-end" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" />
</div>
</div>
<div class="actions"> <div class="actions">
<button type="button" class="modal-close"> <button type="button" class="modal-close">
{{ l.slideshow_slide_form_button_cancel }} {{ l.slideshow_slide_form_button_cancel }}

View File

@ -1,9 +1,16 @@
<div class="modal modal-slide-edit modal-slide hidden"> <div class="modal modal-slide-edit modal-slide hidden">
<h2> <h2>
{{ l.slideshow_slide_form_edit_submit }} {{ l.slideshow_slide_form_edit_title }}
</h2> </h2>
<form action="/slideshow/slide/edit" method="POST"> <form action="/slideshow/slide/edit" method="POST">
<h3>
{{ l.slideshow_slide_form_section_content }}
</h3>
<input type="hidden" name="id" id="slide-edit-id" /> <input type="hidden" name="id" id="slide-edit-id" />
<div class="form-group"> <div class="form-group">
@ -32,6 +39,10 @@
</div> </div>
</div> </div>
<h3>
{{ l.slideshow_slide_form_section_scheduling }}
</h3>
<div class="form-group"> <div class="form-group">
<label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label> <label for="slide-edit-duration">{{ l.slideshow_slide_form_label_duration }}</label>
<div class="widget"> <div class="widget">
@ -53,6 +64,19 @@
</div> </div>
</div> </div>
<div class="form-group hidden">
<label for="slide-edit-cron-schedule-end">{{ l.slideshow_slide_form_label_cron_scheduled_end }}</label>
<div class="widget">
<select id="slide-edit-cron-schedule-end-trigger" class="trigger">
<option value="loop">{{ l.slideshow_slide_form_label_cron_scheduled_loop }}</option>
<option value="datetime">{{ l.slideshow_slide_form_label_cron_scheduled_datetime }}</option>
<option value="cron">{{ l.slideshow_slide_form_label_cron_scheduled_cron }}</option>
</select>
<input type="text" id="slide-edit-cron-schedule-end-datetimepicker" class="datetimepicker" value="" placeholder="{{ l.slideshow_slide_form_label_cron_scheduled_datetime_placeholder }}" />
<input type="text" name="cron_schedule_end" id="slide-edit-cron-schedule-end" class="target hidden" placeholder="{{ l.slideshow_slide_form_widget_cron_scheduled_placeholder }}" />
</div>
</div>
<div class="actions"> <div class="actions">
<button type="button" class="modal-close"> <button type="button" class="modal-close">
{{ l.slideshow_slide_form_button_cancel }} {{ l.slideshow_slide_form_button_cancel }}