first feasability of event management feature
This commit is contained in:
@@ -36,6 +36,10 @@ app.layout = dmc.MantineProvider([
|
||||
])
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=8050, debug=(ENV=="development"))
|
||||
app.run(
|
||||
host="0.0.0.0",
|
||||
port=8050,
|
||||
debug=(ENV=="development"),
|
||||
ssl_context=("/workspace/certs/dev.crt", "/workspace/certs/dev.key")
|
||||
)
|
||||
|
||||
@@ -201,11 +201,30 @@ body {
|
||||
z-index: var(--mantine-z-index-modal, 3000) !important;
|
||||
}
|
||||
|
||||
/* Modalbox */
|
||||
.mantine-Modal-inner,
|
||||
.mantine-Modal-content {
|
||||
z-index: 4000 !important;
|
||||
}
|
||||
|
||||
/* Popups (Dropdowns, Datepicker, Autocomplete, Menüs) innerhalb der Modalbox */
|
||||
.mantine-Popover-dropdown,
|
||||
.mantine-Select-dropdown,
|
||||
.mantine-DatePicker-dropdown,
|
||||
.mantine-Autocomplete-dropdown,
|
||||
.mantine-Menu-dropdown {
|
||||
z-index: 4100 !important;
|
||||
}
|
||||
|
||||
/* Optional: Overlay für Popups noch höher, falls benötigt */
|
||||
.mantine-Popover-root,
|
||||
.mantine-Select-root,
|
||||
.mantine-DatePicker-root,
|
||||
.mantine-Autocomplete-root,
|
||||
.mantine-Menu-root {
|
||||
z-index: 4101 !important;
|
||||
}
|
||||
|
||||
/* Sidebar collapsed: Icon-Farbe normal */
|
||||
.sidebar.collapsed .sidebar-item-collapsed svg {
|
||||
color: #7c5617; /* Icon-Linie/Text */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from dash import Input, Output, State, callback, html, dcc, no_update
|
||||
from dash import Input, Output, State, callback, html, dcc, no_update, ctx
|
||||
import dash_mantine_components as dmc
|
||||
from dash_iconify import DashIconify
|
||||
import dash_quill
|
||||
@@ -313,7 +313,6 @@ def update_end_time_options(search_value):
|
||||
prevent_initial_call=True
|
||||
)
|
||||
def handle_end_time(start_time, reset_clicks, current_end_time):
|
||||
ctx = callback.ctx
|
||||
if not ctx.triggered:
|
||||
return no_update
|
||||
trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
||||
@@ -338,7 +337,7 @@ def handle_end_time(start_time, reset_clicks, current_end_time):
|
||||
@callback(
|
||||
[
|
||||
Output('title-input', 'value'),
|
||||
Output('start-date-input', 'value'),
|
||||
Output('start-date-input', 'value', allow_duplicate=True),
|
||||
Output('time-start', 'value'),
|
||||
Output('type-input', 'value'),
|
||||
Output('description-input', 'value'),
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
import requests
|
||||
import json
|
||||
from flask import session
|
||||
from dash import Input, Output, State, callback, ctx, dash
|
||||
from dash import Input, Output, State, callback, ctx, dash, no_update
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# --- Modalbox öffnen: jetzt auch auf Kalenderklick reagieren ---
|
||||
|
||||
sys.path.append('/workspace')
|
||||
|
||||
print("appointments_callbacks.py geladen")
|
||||
@@ -69,19 +73,86 @@ def load_events(view_dates):
|
||||
|
||||
|
||||
@callback(
|
||||
Output("appointment-modal", "opened"),
|
||||
[
|
||||
Output("appointment-modal", "opened"),
|
||||
Output("start-date-input", "value", allow_duplicate=True),
|
||||
Output("time-start", "value", allow_duplicate=True),
|
||||
Output("time-end", "value", allow_duplicate=True),
|
||||
],
|
||||
[
|
||||
Input("calendar", "lastDateClick"),
|
||||
Input("calendar", "lastSelect"),
|
||||
Input("open-appointment-modal-btn", "n_clicks"),
|
||||
Input("close-appointment-modal-btn", "n_clicks")
|
||||
Input("close-appointment-modal-btn", "n_clicks"),
|
||||
],
|
||||
State("appointment-modal", "opened"),
|
||||
prevent_initial_call=True
|
||||
)
|
||||
def toggle_appointment_modal(open_click, close_click, is_open):
|
||||
from dash import ctx
|
||||
def open_modal(date_click, select, open_click, close_click, is_open):
|
||||
trigger = ctx.triggered_id
|
||||
|
||||
# Bereichsauswahl (lastSelect)
|
||||
if trigger == "calendar" and select:
|
||||
try:
|
||||
start_dt = datetime.fromisoformat(select["start"])
|
||||
end_dt = datetime.fromisoformat(select["end"])
|
||||
|
||||
return (
|
||||
True,
|
||||
start_dt.date().isoformat(),
|
||||
start_dt.strftime("%H:%M"),
|
||||
end_dt.strftime("%H:%M"),
|
||||
)
|
||||
except Exception as e:
|
||||
print("Fehler beim Parsen von select:", e)
|
||||
return no_update, no_update, no_update, no_update
|
||||
|
||||
# Einzelklick (lastDateClick)
|
||||
if trigger == "calendar" and date_click:
|
||||
try:
|
||||
dt = datetime.fromisoformat(date_click)
|
||||
# Versuche, die Slotlänge aus dem Kalender zu übernehmen (optional)
|
||||
# Hier als Beispiel 30 Minuten aufaddieren, falls keine Endzeit vorhanden
|
||||
end_dt = dt + timedelta(minutes=30)
|
||||
return (
|
||||
True,
|
||||
dt.date().isoformat(),
|
||||
dt.strftime("%H:%M"),
|
||||
end_dt.strftime("%H:%M"),
|
||||
)
|
||||
except Exception as e:
|
||||
print("Fehler beim Parsen von date_click:", e)
|
||||
return no_update, no_update, no_update, no_update
|
||||
|
||||
# Modal öffnen per Button
|
||||
if trigger == "open-appointment-modal-btn" and open_click:
|
||||
return True
|
||||
now = datetime.now()
|
||||
end_dt = now + timedelta(minutes=30)
|
||||
return True, now.date().isoformat(), now.strftime("%H:%M"), end_dt.strftime("%H:%M")
|
||||
|
||||
# Modal schließen
|
||||
if trigger == "close-appointment-modal-btn" and close_click:
|
||||
return False
|
||||
return is_open
|
||||
return False, no_update, no_update, no_update
|
||||
|
||||
return is_open, no_update, no_update, no_update
|
||||
|
||||
|
||||
# @callback(
|
||||
# Output("time-end", "value", allow_duplicate=True),
|
||||
# Input("time-start", "value"),
|
||||
# prevent_initial_call=True
|
||||
# )
|
||||
# def handle_end_time(start_time, duration="00:30"):
|
||||
# trigger = ctx.triggered_id
|
||||
# if trigger == "time-start" and start_time and duration:
|
||||
# try:
|
||||
# # Beispiel für start_time: "09:00"
|
||||
# start_dt = datetime.strptime(start_time, "%H:%M")
|
||||
# # Dauer in Stunden und Minuten, z.B. "01:30"
|
||||
# hours, minutes = map(int, duration.split(":"))
|
||||
# # Endzeit berechnen: Dauer addieren!
|
||||
# end_dt = start_dt + timedelta(hours=hours, minutes=minutes)
|
||||
# return end_dt.strftime("%H:%M")
|
||||
# except Exception as e:
|
||||
# print("Fehler bei der Berechnung der Endzeit:", e)
|
||||
# return no_update
|
||||
|
||||
@@ -62,11 +62,6 @@ def get_appointment_modal():
|
||||
title="Neuen Termin anlegen",
|
||||
centered=True,
|
||||
size="auto", # oder "80vw"
|
||||
# fullScreen=True,
|
||||
# styles={
|
||||
# "modal": {"zIndex": 2001, "position": "relative"},
|
||||
# "overlay": {"zIndex": 2000}
|
||||
# },
|
||||
children=[
|
||||
dmc.Container([
|
||||
dmc.Grid([
|
||||
@@ -147,13 +142,14 @@ def get_appointment_modal():
|
||||
{"value": "website", "label": "Website"},
|
||||
{"value": "video", "label": "Video"},
|
||||
{"value": "message", "label": "Nachricht"},
|
||||
{"value": "webuntis", "label": "WebUntis"},
|
||||
{"value": "other", "label": "Sonstiges"}
|
||||
],
|
||||
id="type-input",
|
||||
required=True,
|
||||
style={"flex": 1}
|
||||
),
|
||||
"Wählen Sie den Typ des Termins für bessere Kategorisierung"
|
||||
"Wählen Sie die Art der Präsentation aus."
|
||||
),
|
||||
html.Div(id="type-specific-fields"),
|
||||
create_input_with_tooltip_full(
|
||||
|
||||
Reference in New Issue
Block a user