Markdown zu Label bis auf Monatsübersicht

This commit is contained in:
Alexander Malzkuhn 2025-06-04 09:01:45 +02:00
parent 0ebf563f21
commit 46a0182377
6 changed files with 152 additions and 148 deletions

View File

@ -78,7 +78,7 @@ def page_admin():
with ui.tab_panels(overview_tabs, value = user_month_overview):
with ui.tab_panel(user_month_overview).classes('w-full'):
ui.markdown("##Übersichten")
ui.label("Übersichten").classes(h3)
# Tabelle konstruieren
with ui.card().classes('w-full'):
@ -119,7 +119,7 @@ def page_admin():
except NameError:
pass
ui.markdown("Benutzer:")
ui.label("Benutzer:")
time_user = ui.select(options=userlist, on_change=update_user)
time_user.value = userlist[0]
@ -159,7 +159,7 @@ def page_admin():
#current_user = user(time_user.value)
# Archivstatus
days_with_errors = current_user.archiving_validity_check(int(select_year.value), int(select_month.value))
with ui.grid(columns='auto auto auto 1fr 1fr 1fr 1fr').classes('w-full md:min-w-[600px] lg:min-w-[800px]') as table_grid:
with ui.grid(columns='auto auto auto 1fr 1fr 1fr 1fr').classes('w-full md:min-w-[600px] lg:min-w-[800px] items-baseline') as table_grid:
if int(select_month.value) > 1:
archive_status = current_user.get_archive_status(int(select_year.value),
int(select_month.value))
@ -199,12 +199,12 @@ def page_admin():
else:
calendar_card.classes('bg-white')
# Überschriften
ui.markdown("**Datum**")
ui.markdown("**Buchungen**")
ui.label("Datum").classes('font-bold')
ui.label("Buchungen").classes('font-bold')
ui.space()
ui.markdown("**Ist**")
ui.markdown("**Soll**")
ui.markdown("**Saldo**")
ui.label("Ist").classes('font-bold')
ui.label("Soll").classes('font-bold')
ui.label("Saldo").classes('font-bold')
ui.space()
timestamps = current_user.get_timestamps(year=select_year.value, month=select_month.value)
@ -229,7 +229,7 @@ def page_admin():
class_content = ""
if day_in_list.date() == datetime.datetime.now().date():
class_content = 'font-bold text-red-700 uppercase'
ui.markdown(f"{day_in_list.strftime('%a')}., {day}. {calendar.month_name[int(select_month.value)]}").classes(class_content)
ui.label(f"{day_in_list.strftime('%a')}., {day}. {calendar.month_name[int(select_month.value)]}").classes(class_content)
# Buchungen
@ -242,9 +242,8 @@ def page_admin():
dialog.close()
ui.notify("Abwesenheitseintrag gelöscht")
with ui.dialog() as dialog, ui.card():
ui.markdown(f'''Soll der Eintrag **{absence_type}** für den **{day}. {calendar.month_name[int(select_month.value)]} {select_year.value}** gelöscht werden?
Dies kann nicht rückgängig gemacht werden!''')
ui.markdown(f'Soll der Eintrag **{absence_type}** für den **{day}. {calendar.month_name[int(select_month.value)]} {select_year.value}** gelöscht werden?')
ui.label('Dies kann nicht rückgängig gemacht werden!')
with ui.grid(columns=3):
ui.button("Ja", on_click=execute_deletion)
ui.space()
@ -269,7 +268,7 @@ Dies kann nicht rückgängig gemacht werden!''')
except:
pass
day_type = ui.markdown("Kein Arbeitstag")
day_type = ui.label("Kein Arbeitstag")
day_type.set_visibility(False)
# Hier werden nur die Tage mit Timestamps behandelt
@ -279,7 +278,7 @@ Dies kann nicht rückgängig gemacht werden!''')
def edit_entry(t_stamp, day):
with ui.dialog() as edit_dialog, ui.card():
ui.markdown("**Eintrag bearbeiten**")
ui.label("Eintrag bearbeiten").classes(h4)
timestamp = datetime.datetime.fromtimestamp(int(t_stamp))
input_time = ui.time().props('format24h now-btn').classes('w-full justify-center')
@ -355,14 +354,14 @@ Dies kann nicht rückgängig gemacht werden!''')
if days_notes != { }:
with ui.icon('o_description').classes('text-2xl'):
with ui.tooltip():
with ui.grid(columns='auto auto'):
with ui.grid(columns='auto auto').classes('items-center'):
for username, text in days_notes.items():
admins_name = load_adminsettings()["admin_user"]
if username == admins_name:
ui.markdown('Administrator:')
ui.label('Administrator:')
else:
ui.markdown(current_user.fullname)
ui.markdown(text)
ui.label(current_user.fullname)
ui.label(text)
else:
ui.space()
@ -396,9 +395,9 @@ Dies kann nicht rückgängig gemacht werden!''')
timestamps_of_this_day[i])
time_sum = time_sum + time_delta
ui.markdown(convert_seconds_to_hours(time_sum)).classes('text-right')
ui.label(convert_seconds_to_hours(time_sum)).classes('text-right')
else:
ui.markdown("Kein")
ui.label("Kein")
# Arbeitszeitsoll bestimmen
@ -408,7 +407,7 @@ Dies kann nicht rückgängig gemacht werden!''')
day_type.content="Kein Arbeitsverhältnis"
day_type.set_visibility(True)
else:
ui.markdown(f"{convert_seconds_to_hours(int(hours_to_work) * 3600)}").classes('text-right')
ui.label(f"{convert_seconds_to_hours(int(hours_to_work) * 3600)}").classes('text-right')
if int(hours_to_work) == 0:
day_type.content = "**Kein Arbeitstag**"
day_type.set_visibility(True)
@ -434,13 +433,13 @@ Dies kann nicht rückgängig gemacht werden!''')
pass
general_saldo = general_saldo + saldo
ui.markdown(convert_seconds_to_hours(saldo)).classes('text-right')
ui.label(convert_seconds_to_hours(saldo)).classes('text-right')
else:
ui.markdown("-").classes('text-center')
ui.label("-").classes('text-center')
def add_entry(day):
with ui.dialog() as add_dialog, ui.card():
ui.markdown("###Eintrag hinzufügen")
ui.label("Eintrag hinzufügen").classes(h4)
input_time = ui.time().classes('w-full justify-center')
def add_entry_save():
@ -563,19 +562,19 @@ Dies kann nicht rückgängig gemacht werden!''')
note_labels = { }
del_buttons = { }
ui.markdown(f'**Notizen für {day}.{current_month}.{current_year}**')
with ui.grid(columns='auto auto auto'):
ui.label(f'Notizen für {day}.{current_month}.{current_year}').classes('font-bold')
with ui.grid(columns='auto auto auto').classes('items-baseline'):
admin_settings = load_adminsettings()
# Beschreibungsfeld für Admin
username_labels["admin"] = ui.markdown("Administrator:")
username_labels["admin"] = ui.label("Administrator:")
# Textarea für Admin
note_labels["admin"] = ui.textarea()
del_buttons["admin"] = ui.button(icon='remove', on_click=lambda user="admin": del_note_entry(user))
for name, text in notes.items():
if name != "admin":
username_labels["user"] = ui.markdown(current_user.fullname)
note_labels["user"] = ui.markdown(text)
username_labels["user"] = ui.label(current_user.fullname)
note_labels["user"] = ui.label(text)
del_buttons["user"] = ui.button(icon='remove', on_click=lambda user="user": del_note_entry(user))
elif name == "admin":
note_labels["admin"].value = text
@ -612,12 +611,12 @@ Dies kann nicht rückgängig gemacht werden!''')
#4x leer und dann Gesamtsaldo
ui.space().classes('col-span-5')
ui.markdown(f"{convert_seconds_to_hours(general_saldo)}").classes('text-right')
ui.markdown("Stunden aus Vormonat").classes('col-span-5 text-right')
ui.label(convert_seconds_to_hours(general_saldo)).classes('text-right')
ui.label("Stunden aus Vormonat").classes('col-span-5 text-right')
last_months_overtime = current_user.get_last_months_overtime(select_year.value, select_month.value)
ui.markdown(f"{convert_seconds_to_hours(last_months_overtime)}").classes('text-right')
ui.markdown("Gesamtsaldo").classes('col-span-5 text-right')
ui.markdown(f"**<ins>{convert_seconds_to_hours(general_saldo + last_months_overtime)}</ins>**").classes('text-right')
ui.label(convert_seconds_to_hours(last_months_overtime)).classes('text-right')
ui.label("Gesamtsaldo").classes('col-span-5 text-right')
ui.label(convert_seconds_to_hours(general_saldo + last_months_overtime)).classes('text-right text-bold text-underline')
table_grid.move(calendar_card)
@ -744,20 +743,20 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.tab_panel(settings):
with ui.grid(columns='auto auto'):
with ui.card():
ui.markdown("**Administrationsbenutzer:**")
with ui.grid(columns=2):
ui.label("Administrationsbenutzer:").classes('text-bold')
with ui.grid(columns=2).classes('items-baseline'):
ui.markdown("Benutzername des Adminstrators")
ui.label("Benutzername des Adminstrators:")
admin_user = ui.input().tooltip("Geben Sie hier den Benutzernamen für den Adminstationsnutzer ein")
admin_user.value = data["admin_user"]
ui.markdown("Passwort des Administrators")
ui.label("Passwort des Administrators:")
admin_password = ui.input(password=True).tooltip("Geben Sie hier das Passwort für den Administationsnutzer ein. Merken Sie sich dieses Passwort gut. Es kann nicht über das Webinterface zurückgesetzt werden.")
secret = data["secret"]
with ui.card():
ui.markdown("**Systemeinstellungen:**")
with ui.grid(columns=2):
ui.label("Systemeinstellungen:").classes('text-bold')
with ui.grid(columns=2).classes('items-baseline'):
def check_is_number(number):
try:
number = int(number)
@ -765,7 +764,7 @@ Dies kann nicht rückgängig gemacht werden!''')
except:
return False
ui.markdown("Port:")
ui.label("Port:")
port = ui.input(validation={"Nur ganzzahlige Portnummern erlaubt": lambda value: check_is_number(value),
"Portnummer zu klein": lambda value: len(value)>=2}).tooltip("Geben Sie hier die Portnummer ein, unter der die Zeiterfassung erreichbar ist.").props('size=5').bind_enabled_from(enabled_because_not_docker, 'value')
if is_docker():
@ -774,8 +773,8 @@ Dies kann nicht rückgängig gemacht werden!''')
port.value = old_port
with ui.card():
ui.markdown("**Einstellungen für das Touchscreenterminal:**")
with ui.column():
ui.label("Einstellungen für das Touchscreenterminal:").classes('text-bold')
with ui.column().classes('items-baseline'):
touchscreen_switch = ui.switch("Touchscreenterminal aktiviert")
touchscreen_switch.value = data["touchscreen"]
timestamp_switch = ui.switch("Stempelzeiten anzeigen").bind_visibility_from(touchscreen_switch, 'value')
@ -784,13 +783,13 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.row().bind_visibility_from(touchscreen_switch, 'value'):
photo_switch.value = bool(data["photos_on_touchscreen"])
with ui.row().bind_visibility_from(photo_switch, 'value'):
ui.markdown("Maximale Bilderöhe")
ui.label("Maximale Bilderöhe")
picture_height_input = ui.input(validation={"Größe muss eine Ganzzahl sein.": lambda value: check_is_number(value),
"Größe muss größer 0 sein": lambda value: int(value)>0}).props('size=5')
picture_height_input.value = data["picture_height"]
ui.markdown('px')
ui.label('px')
with ui.row().bind_visibility_from(touchscreen_switch, 'value'):
ui.markdown("Minimale Buttonhöhe")
ui.label("Minimale Buttonhöhe:")
def compare_button_height(height):
if not photo_switch.value:
return True
@ -805,16 +804,16 @@ Dies kann nicht rückgängig gemacht werden!''')
button_height_input.value = data["button_height"]
photo_switch.on_value_change(button_height_input.validate)
picture_height_input.on_value_change(button_height_input.validate)
ui.markdown('px')
ui.label('px')
with ui.card():
ui.markdown("**Einstellungen für Benutzerfrontend**")
ui.label("Einstellungen für Benutzerfrontend").classes('text-bold')
notes_switch = ui.switch("Notizfunktion aktiviert", value=data["user_notes"])
va_switch = ui.switch("Urlaubsanträge", value=data["vacation_application"])
reset_visibility = ValueBinder()
def holiday_section():
with ui.card():
ui.markdown('**Feiertage:**')
ui.label('Feiertage:').classes('text-bold')
reset_visibility.value = False
@ -834,7 +833,7 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.dialog() as dialog, ui.card():
with ui.grid(columns='auto auto'):
ui.markdown('Geben Sie den neuen Feiertag ein:').classes('col-span-2')
ui.label('Geben Sie den neuen Feiertag ein:').classes('col-span-2')
datepicker = ui.date(value=datetime.datetime.now().strftime('%Y-%m-%d')).classes('col-span-2')
description = ui.input('Beschreibung').classes('col-span-2')
repetition = ui.number('Für Jahre wiederholen', value=1, min=1, precision=0).classes('col-span-2')
@ -878,7 +877,7 @@ Dies kann nicht rückgängig gemacht werden!''')
def defined_holidays():
with ui.dialog() as dialog, ui.card():
ui.markdown("Bitte wählen Sie aus, welche Feiertage eingetragen werden sollen. Vom Osterdatum abhängige Feiertage werden für die verschiedenen Jahre berechnet.:")
ui.label("Bitte wählen Sie aus, welche Feiertage eingetragen werden sollen. Vom Osterdatum abhängige Feiertage werden für die verschiedenen Jahre berechnet.:")
with ui.grid(columns='auto auto'):
with ui.column().classes('gap-0'): # Auswahlen für Feiertage
@ -1035,7 +1034,7 @@ Dies kann nicht rückgängig gemacht werden!''')
if int(old_port) != int(port.value):
with ui.dialog() as dialog, ui.card():
ui.markdown(
ui.label(
"Damit die Porteinstellungen wirksam werden, muss der Server neu gestartet werden.")
ui.button("OK", on_click=lambda: dialog.close())
dialog.open()
@ -1046,7 +1045,7 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.button("Speichern", on_click=save_admin_settings).tooltip("Hiermit werden sämtliche oben gemachten Einstellungen gespeichert.")
with ui.tab_panel(users):
ui.markdown("###Benutzerverwaltung")
ui.label("Benutzerverwaltung").classes(h3)
workhours = [ ]
with ui.row():
@ -1126,9 +1125,9 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.dialog() as dialog, ui.card():
if user_selection.value != username_input.value:
ui.markdown("**Benutzername wurde geändert.**")
ui.markdown(f"Benutzerdaten werden in den neuen Ordner {username_input.value}")
ui.markdown("Sollen die Einstellungen gespeichert werden?")
ui.label("Benutzername wurde geändert.").classes('text-bold')
ui.label(f"Benutzerdaten werden in den neuen Ordner {username_input.value} verschoben.")
ui.label("Sollen die Einstellungen gespeichert werden?")
with ui.row():
ui.button("Speichern", on_click=save_settings)
ui.button("Abbrechen", on_click=dialog.close)
@ -1156,8 +1155,8 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.notify("Benutzer gelöscht")
with ui.dialog() as dialog, ui.card():
ui.markdown(f"Soll der Benutzer *{current_user.username}* gelöscht werden?")
ui.markdown("**Dies kann nicht rückgängig gemacht werden?**")
ui.label(f"Soll der Benutzer *{current_user.username}* gelöscht werden?")
ui.label("Dies kann nicht rückgängig gemacht werden?").classes('text-bold')
with ui.row():
ui.button("Löschen", on_click=del_definitely)
ui.button("Abbrechen", on_click=dialog.close)
@ -1181,7 +1180,7 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.notify("Einstellungen gespeichert")
with ui.dialog() as dialog, ui.card():
ui.markdown("Sollen die Änderungen an den Arbeitsstunden und/oder Urlaubstagen gespeichert werden?")
ui.label("Sollen die Änderungen an den Arbeitsstunden und/oder Urlaubstagen gespeichert werden?")
with ui.row():
ui.button("Speichern", on_click=save_settings)
ui.button("Abrrechen", on_click=dialog.close)
@ -1204,8 +1203,8 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.dialog() as dialog, ui.card():
current_user = user(user_selection.value)
if len(current_user.workhours) > 1:
ui.markdown(f"Soll der Eintrag *{workhours_select.value}* wirklich gelöscht werden?")
ui.markdown("**Dies kann nicht rückgängig gemacht werden.**")
ui.label(f"Soll der Eintrag *{workhours_select.value}* wirklich gelöscht werden?")
ui.label("Dies kann nicht rückgängig gemacht werden.").classes('text-bold')
with ui.row():
ui.button("Löschen", on_click=delete_entry)
ui.button("Abbrechen", on_click=dialog.close)
@ -1217,7 +1216,7 @@ Dies kann nicht rückgängig gemacht werden!''')
dialog.close()
keyboard = ui.keyboard(on_key=handle_key)
else:
ui.markdown("Es gibt nur einen Eintrag. Dieser kann nicht gelöscht werden.")
ui.label("Es gibt nur einen Eintrag. Dieser kann nicht gelöscht werden.")
ui.button("OK", on_click=dialog.close)
dialog.open()
@ -1234,7 +1233,7 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.notify("Ungültiger Benutzername")
with ui.dialog() as dialog, ui.card():
ui.markdown("Geben Sie den Benutzernamen für das neue Konto an:")
ui.label("Geben Sie den Benutzernamen für das neue Konto an:")
user_name_input = ui.input(label="Benutzername", validation={'Leerer Benutzername nicht erlaubt': lambda value: len(value) != 0,
'Leerzeichen im Benutzername nicht erlaubt': lambda value: " " not in value,
'Benutzername schon vergeben': lambda value: value not in userlist}).on('keypress.enter', create_new_user)
@ -1260,20 +1259,20 @@ Dies kann nicht rückgängig gemacht werden!''')
def usersettings_card():
global usersettingscard
with ui.card() as usersettingscard:
ui.markdown("**Benutzereinstellungen**")
with ui.grid(columns="auto 1fr") as usersettingsgrid:
ui.label("Benutzereinstellungen").classes('text-bold')
with ui.grid(columns="auto 1fr").classes('items-baseline') as usersettingsgrid:
ui.markdown("Benutzername:")
ui.label("Benutzername:")
global username_input
username_input = ui.input()
ui.markdown("Voller Name:")
ui.label("Voller Name:")
global fullname_input
fullname_input = ui.input()
ui.markdown("Passwort")
ui.label("Passwort:")
global password_input
password_input = ui.input(password=True)
password_input.value = ""
ui.markdown("API-Schlüssel:")
ui.label("API-Schlüssel:")
with ui.row():
global api_key_input
api_key_input = ui.input().props('size=37')
@ -1281,7 +1280,7 @@ Dies kann nicht rückgängig gemacht werden!''')
api_key_input.value = hashlib.shake_256(bytes(f'{username_input.value}_{datetime.datetime.now().timestamp()}', 'utf-8')).hexdigest(20)
ui.button("Neu", on_click=new_api_key).tooltip("Neuen API-Schlüssel erzeugen. Wird erst beim Klick auf Speichern übernommen und entsprechende Links und QR-Codes aktualisiert")
ui.markdown('Aufruf zum Stempeln:')
ui.label('Aufruf zum Stempeln:')
global api_link_column
with ui.column().classes('gap-0') as api_link_column:
global stamp_link
@ -1297,7 +1296,7 @@ Dies kann nicht rückgängig gemacht werden!''')
usersettings_card()
with ui.card() as photocard:
ui.markdown('**Foto**')
ui.label('Foto').classes('text-bold')
current_user = user(user_selection.value)
user_photo = ui.image(current_user.photofile)
@ -1321,7 +1320,7 @@ Dies kann nicht rückgängig gemacht werden!''')
with ui.card() as workinghourscard:
workhours = []
ui.markdown("**Arbeitszeiten**")
ui.label("Arbeitszeiten").classes('text-bold')
with ui.card():
@ -1332,30 +1331,30 @@ Dies kann nicht rückgängig gemacht werden!''')
sum = float(days[i].value) + sum
except:
pass
workhours_sum.set_content(str(sum))
workhours_sum.value = str(sum)
with ui.grid(columns='auto auto auto'):
ui.markdown("gültig ab:")
with ui.grid(columns='auto auto auto').classes('items-baseline'):
ui.label("gültig ab:")
workhours_select = ui.select(options=workhours, on_change=workhours_selection_changed).classes('col-span-2')
days = [ ]
weekdays = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"]
counter = 0
for day in weekdays:
ui.markdown(f"{day}:")
ui.label(f"{day}:")
days.append(ui.number(on_change=calculate_weekhours).props('size=3'))
ui.markdown('Stunden')
ui.label('Stunden')
counter = counter + 1
ui.separator().classes('col-span-full')
ui.markdown("**Summe:**")
workhours_sum = ui.markdown()
ui.markdown("Stunden")
ui.label("Summe:").classes('text-bold')
workhours_sum = ui.label()
ui.label("Stunden")
with ui.card():
with ui.grid(columns='auto auto auto'):
ui.markdown("Urlaubstage")
with ui.grid(columns='auto auto auto').classes('items-baseline'):
ui.label("Urlaubstage")
vacation_input = ui.number().props('size=3')
ui.markdown("Tage")
ui.label("Tage")
def new_workhours_entry():
current_user = user(user_selection.value)
@ -1378,7 +1377,7 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.notify("Eintrag angelegt")
with ui.dialog() as dialog, ui.card():
ui.markdown("Geben Sie das Gültigkeitsdatum an, ab wann die Einträge gültig sein sollen.")
ui.label("Geben Sie das Gültigkeitsdatum an, ab wann die Einträge gültig sein sollen.")
date_picker = ui.date()
with ui.row():
@ -1403,8 +1402,8 @@ Dies kann nicht rückgängig gemacht werden!''')
api_key = ""
ui.label("Backupeinstellungen").classes('font-bold')
with ui.grid(columns='auto auto auto'):
ui.markdown("Backupordner:")
with ui.grid(columns='auto auto auto').classes('items-baseline'):
ui.label("Backupordner:")
backupfolder_input = ui.input(value=backupfolder).props(f"size={len(backupfolder)}").bind_enabled_from(enabled_because_not_docker, 'value')
def save_new_folder_name():
if os.path.exists(backupfolder_input.value):
@ -1421,7 +1420,7 @@ Dies kann nicht rückgängig gemacht werden!''')
if is_docker():
save_backup_folder_button.tooltip("Diese Einstellung ist beim Einsatz von Docker deaktiviert.")
ui.markdown("API-Schlüssel:")
ui.label("API-Schlüssel:")
backup_api_key_input = ui.input(value=api_key).tooltip("Hier den API-Schlüssel eintragen, der für Backuperzeugung mittels API-Aufruf verwendet werden soll.")
def new_backup_api_key():
backup_api_key_input.value = hashlib.shake_256(bytes(f"{backupfolder}-{datetime.datetime.now().timestamp()}", 'utf-8')).hexdigest(20)
@ -1435,7 +1434,7 @@ Dies kann nicht rückgängig gemacht werden!''')
ui.separator()
ui.markdown('**Backups**')
ui.label('Backups').classes('text-bold')
date_format = '%Y-%m-%d_%H-%M'
searchpath = backupfolder
@ -1447,7 +1446,7 @@ Dies kann nicht rückgängig gemacht werden!''')
backup_files = []
file_info = []
with ui.grid(columns='auto auto auto auto auto auto'):
with ui.grid(columns='auto auto auto auto auto auto').classes('items-baseline'):
ui.label("Backupzeitpunkt/Dateiname")
ui.label("Backupgröße")
@ -1478,12 +1477,12 @@ Dies kann nicht rückgängig gemacht werden!''')
button_string = date_string_dt.strftime('%d.%m.%Y - %H:%M')
except ValueError:
button_string = date_string
ui.markdown(button_string)
ui.label(button_string)
if size > 1_000_000:
ui.markdown(f'{round(size/1_000_000,2)} MB')
ui.label(f'{round(size/1_000_000,2)} MB')
else:
ui.markdown(f'{round(size / 1_000, 2)} kB')
ui.markdown(version)
ui.label(f'{round(size / 1_000, 2)} kB')
ui.label(version)
ui.button(icon='download', on_click=lambda file=date_string: ui.download.file(
os.path.join(scriptpath, backupfolder, f'{file}.zip'))).tooltip(
"Backup herunterladen")

View File

@ -41,7 +41,7 @@ def page_overview_month(username: str, year: int, month: int):
ui.markdown(f'#Bericht für {current_user.fullname} für {calendar.month_name[month]} {year}')
pad_x = 4
pad_y = 0
pad_y = 1
color_weekend = "gray-100"
color_holiday = "gray-100"
@ -73,12 +73,12 @@ def page_overview_month(username: str, year: int, month: int):
if current_user.get_archive_status(year, month):
bg_color = ' bg-yellow-100'
with ui.grid(columns='auto auto 1fr 1fr 1fr').classes(f'gap-0 border px-0 py-0{bg_color}'):
ui.markdown("**Datum**").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown("**Buchungen**").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown("**Ist**").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown("**Soll**").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown("**Saldo**").classes(f'border px-{pad_x} py-{pad_y}')
with ui.grid(columns='auto auto 1fr 1fr 1fr').classes(f'gap-0 border px-0 py-0 {bg_color}'):
ui.label("Datum").classes(f'border px-{pad_x} py-{pad_y} text-bold')
ui.label("Buchungen").classes(f'border px-{pad_x} py-{pad_y} text-bold')
ui.label("Ist").classes(f'border px-{pad_x} py-{pad_y} text-bold')
ui.label("Soll").classes(f'border px-{pad_x} py-{pad_y} text-bold')
ui.label("Saldo").classes(f'border px-{pad_x} py-{pad_y} text-bold')
# Gehe jeden einzelnen Tag des Dictionaries für die Timestamps durch
for day in list(timestamps_dict):
@ -213,15 +213,15 @@ def page_overview_month(username: str, year: int, month: int):
ui.markdown(total).classes(total_class).classes(f'border px-{pad_x} py-{pad_y}')
# Überstundenzusammenfassung
ui.markdown("Überstunden aus Vormonat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
ui.label("Überstunden aus Vormonat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
last_months_overtime = current_user.get_last_months_overtime(year, month)
ui.markdown(f"{convert_seconds_to_hours(last_months_overtime)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.markdown("Überstunden diesen Monat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
ui.markdown(f"{convert_seconds_to_hours(general_saldo)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.markdown("**Überstunden Gesamt:**").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
ui.label(f"{convert_seconds_to_hours(last_months_overtime)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.label("Überstunden diesen Monat:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y}')
ui.label(f"{convert_seconds_to_hours(general_saldo)} h").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.label("Überstunden Gesamt:").classes(f'col-span-4 text-right border px-{pad_x} py-{pad_y} text-bold')
global overtime_overall
overtime_overall = last_months_overtime + general_saldo
ui.markdown(f"**{convert_seconds_to_hours(overtime_overall)} h**").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.label(f"{convert_seconds_to_hours(overtime_overall)} h").classes(f'text-right border px-{pad_x} py-{pad_y} text-bold')
overview_table()
@ -241,14 +241,14 @@ def page_overview_month(username: str, year: int, month: int):
total_absence_days += absence_dict[key]
if total_absence_days > 0:
ui.markdown("###Abwesenheitstage diesen Monat:")
ui.label("Abwesenheitstage diesen Monat:").classes(h3)
with ui.grid(columns='auto 25%').classes(f'gap-0 border px-0 py-0'):
for key, value in absence_dict.items():
if value > 0:
ui.markdown(absence_entries[key]['name']).classes(f"border px-{pad_x} py-{pad_y}")
ui.markdown(str(value)).classes(f'border px-{pad_x} py-{pad_y} text-center')
ui.label(absence_entries[key]['name']).classes(f"border px-{pad_x} py-{pad_y}")
ui.label(str(value)).classes(f'border px-{pad_x} py-{pad_y} text-center')
absence_table()
@ -296,12 +296,12 @@ def page_overview_month(username: str, year: int, month: int):
except Exception as e:
print(str(type(e).__name__) + " " + str(e))
if type(e) == UnboundLocalError:
ui.markdown('#Fehler')
ui.markdown('Benutzer existiert nicht')
ui.label('Fehler').classes(h1)
ui.label('Benutzer existiert nicht')
else:
ui.markdown('#Fehler')
ui.markdown(str(type(e)))
ui.markdown(str(e))
ui.label('Fehler').classes(h1)
ui.label(str(type(e)))
ui.label(str(e))
else:
login_mask(target=f'/api/month/{username}/{year}-{month}')
@ui.page('/api/vacation/{username}/{year}')
@ -321,22 +321,21 @@ def page_overview_vacation(username: str, year: int):
day = datetime.now().day
ui.page_title(f"Urlaubsanspruch für {current_user.fullname} für {year}")
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('absolute top-5 right-5')
ui.space()
ui.markdown(f'#Urlaubsanspruch für {current_user.fullname} für {year}')
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('w-full text-right')
ui.label(f'Urlaubsanspruch für {current_user.fullname} für {year}').classes(h1)
pad_x = 4
pad_y = 0
pad_y = 2
vacationclaim = int(current_user.get_vacation_claim(year, month, day))
if vacationclaim == -1:
ui.markdown(f"###Kein Urlaubsanspruch für {year}")
ui.label(f"Kein Urlaubsanspruch für {year}").classes(h3)
else:
with ui.grid(columns='auto auto').classes(f'gap-0 border px-0 py-0'):
ui.markdown(f"Urlaubsanspruch für {year}:").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown(f"{vacationclaim} Tage").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.markdown("Registrierte Urlaubstage").classes(f'border px-{pad_x} py-{pad_y} col-span-2')
ui.label(f"Urlaubsanspruch für {year}:").classes(f'border px-{pad_x} py-{pad_y}')
ui.label(f"{vacationclaim} Tage").classes(f'text-right border px-{pad_x} py-{pad_y}')
ui.label("Registrierte Urlaubstage").classes(f'border px-{pad_x} py-{pad_y} col-span-2')
vacation_counter = 0
try:
for i in range(1, 13):
@ -345,24 +344,24 @@ def page_overview_vacation(username: str, year: int):
# print(day + "." + str(i) + " " + absence_type)
if absence_type == "U":
day_in_list = datetime(int(year), int(i), int(day)).strftime("%d.%m.%Y")
ui.markdown(day_in_list).classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown("-1 Tag").classes(f'border px-{pad_x} py-{pad_y} text-center')
ui.label(day_in_list).classes(f'border px-{pad_x} py-{pad_y}')
ui.label("-1 Tag").classes(f'border px-{pad_x} py-{pad_y} text-center')
vacation_counter += 1
except Exception as e:
print(str(type(e).__name__) + " " + str(e))
ui.markdown("**Resturlaub:**").classes(f'border px-{pad_x} py-{pad_y}')
ui.markdown(f'**{str(vacationclaim - vacation_counter)} Tage**').classes(f'border px-{pad_x} py-{pad_y} text-center')
ui.label("Resturlaub:").classes(f'border px-{pad_x} py-{pad_y} text-bold')
ui.label(f'{str(vacationclaim - vacation_counter)} Tage').classes(f'border px-{pad_x} py-{pad_y} text-center text-bold')
except Exception as e:
print(str(type(e).__name__) + " " + str(e))
if type(e) == UnboundLocalError:
ui.markdown('#Fehler')
ui.markdown('Benutzer existiert nicht')
ui.label('Fehler').classes(h1)
ui.label('Benutzer existiert nicht')
else:
ui.markdown('#Fehler')
ui.markdown(str(type(e)))
ui.markdown(str(e))
ui.label('Fehler').classes(h1)
ui.label(str(type(e)))
ui.label(str(e))
else:
login = login_mask(target=f'/api/vacation/{username}/{year}')
@ -376,12 +375,11 @@ def page_overview_absence(username: str, year: int):
if login_is_valid(username) or admin_auth:
current_user = user(username)
ui.page_title(f"Abwesenheitsübersicht für {current_user.fullname} für {year}")
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('absolute top-5 right-5')
ui.space()
ui.label(datetime.now().strftime('%d.%m.%Y')).classes('w-full text-right')
pageheader(f"Abwesenheitsübersicht für {current_user.fullname} für {year}")
pad_x = 2
pad_y = 0
pad_y = 1
def absence_calender():
@ -394,12 +392,12 @@ def page_overview_absence(username: str, year: int):
# Erste Zeile
ui.space()
for i in range(1, 32):
ui.markdown(str(i)).classes(f'border px-{pad_x} py-{pad_y} text-center')
ui.label(str(i)).classes(f'border px-{pad_x} py-{pad_y} text-center')
# Monate durchgehen
for month in range(1, 13):
for column in range(0, 32):
if column == 0:
ui.markdown(month_name[month]).classes(f'border px-{pad_x} py-{pad_y} text.center')
ui.label(month_name[month]).classes(f'border px-{pad_x} py-{pad_y} text.center')
else:
absences = current_user.get_absence(year, month)
if str(column) in list(absences):
@ -407,7 +405,7 @@ def page_overview_absence(username: str, year: int):
text_color = absence_entries[absences[str(column)]]['text-color']
tooltip_text = absence_entries[absences[str(column)]]['name']
with ui.element():
ui.markdown(absences[str(column)]).classes(f'border px-{pad_x} py-{pad_y} bg-{bg_color} text-{text_color} align-middle text-center')
ui.label(absences[str(column)]).classes(f'border px-{pad_x} py-{pad_y} bg-{bg_color} text-{text_color} align-middle text-center')
ui.tooltip(tooltip_text)
else:
tooltip_text = ""
@ -430,17 +428,17 @@ def page_overview_absence(username: str, year: int):
def absence_table():
with ui.grid(columns='auto auto').classes(f'gap-0 px-0 py-0'):
ui.markdown('**Summen**').classes('col-span-2 px-2')
with ui.grid(columns='auto auto').classes(f'gap-0 px-0 py-0 items-baseline'):
ui.label('Summen').classes('col-span-2 px-2 text-bold')
for type in list(absence_entries):
number_of_days = 0
ui.markdown(absence_entries[type]["name"]).classes(f'border px-{pad_x} py-{pad_y}')
ui.label(absence_entries[type]["name"]).classes(f'border px-{pad_x} py-{pad_y}')
for month in range(1, 13):
absences_of_month = current_user.get_absence(year, month)
for i in list(absences_of_month):
if absences_of_month[i] == type:
number_of_days += 1
ui.markdown(str(number_of_days)).classes(f'border px-{pad_x} py-{pad_y} text-center')
ui.label(str(number_of_days)).classes(f'border px-{pad_x} py-{pad_y} text-center')
absence_table()
else:

View File

@ -85,3 +85,9 @@ absence_entries = {"U": { "name": "Urlaub",
"color": "pink",
"text-color": "white"}
}
# Styling
h1 = "text-5xl font-bold"
h2 = "text-4xl font-medium"
h3 = "text-3xl font-light"
h4 = "text-2xl"

View File

@ -212,9 +212,9 @@ def homepage():
def activate_absence():
binder_absence.value = True
with ui.grid(columns='1fr 1fr'):
with ui.grid(columns='1fr 1fr').classes('items-end'):
ui.markdown("**Monatsübersicht:**").classes('col-span-2')
ui.label("Monatsübersicht:").classes('col-span-2 font-bold')
month_year_select = ui.select(list(reversed(available_years)), label="Jahr", on_change=update_month).bind_value_to(binder_available_years, 'value')
month_month_select = ui.select(available_months, label="Monat", on_change=enable_month)
@ -222,10 +222,10 @@ def homepage():
ui.space()
month_button = ui.button("Anzeigen", on_click=lambda: ui.navigate.to(f"/api/month/{current_user.username}/{month_year_select.value}-{month_month_select.value}", new_tab=True)).bind_enabled_from(binder_month_button, 'value')
ui.markdown("**Urlaubsanspruch**").classes('col-span-2')
ui.label("Urlaubsanspruch").classes('col-span-2 font-bold')
vacation_select = ui.select(list(reversed(available_years)), on_change=activate_vacation)
vacation_button = ui.button("Anzeigen", on_click=lambda: ui.navigate.to(f"/api/vacation/{current_user.username}/{vacation_select.value}", new_tab=True)).bind_enabled_from(binder_vacation, 'value')
ui.markdown("**Fehlzeitenübersicht**").classes('col-span-2')
ui.label("Fehlzeitenübersicht").classes('col-span-2 font-bold')
absences_select = ui.select(list(reversed(available_years)), on_change=activate_absence)
absences_button = ui.button("Anzeigen", on_click=lambda: ui.navigate.to(f"api/absence/{current_user.username}/{absences_select.value}", new_tab=True)).bind_enabled_from(binder_absence, 'value')
ui.separator().classes('col-span-2')

View File

@ -20,8 +20,8 @@ class pageheader:
def __init__(self, heading):
self.heading = heading
ui.markdown(f"##{app_title} {app_version}")
ui.markdown(f"###{self.heading}")
ui.label(f"{app_title} {app_version}").classes(h2)
ui.label(self.heading).classes(h3)
class ValueBinder:
def __init__(self):
@ -63,7 +63,7 @@ class login_mask:
pageheader("Bitte einloggen:")
with ui.grid(columns='20% auto 20%').classes('w-full justify-center'):
with ui.grid(columns='1fr auto 1fr').classes('w-full justify-center'):
ui.space()
with ui.grid(columns=2):

View File

@ -51,6 +51,7 @@ def main():
ui.tab.default_classes('normal-case')
ui.toggle.default_classes('normal-case')
ui.toggle.default_props('rounded')
ui.row.default_classes('items-baseline')
ui.run(favicon="favicon.svg", port=port, storage_secret=secret, language='de-DE', show_welcome_message=False)