feat: customizable dashboard layout (#32)

Users can now show/hide widgets and reorder them via a settings button
in the greeting header. Configuration is persisted server-side in
sync_config (dashboard_widgets key) and shared across all family members.

- Greeting widget gets a settings icon button opening a customize modal
- Modal lists all widgets (tasks, calendar, shopping, meals, notes,
  weather) with toggle switches and up/down reorder buttons
- Reset to default layout available in the modal
- GET /preferences now returns dashboard_widgets; PUT accepts it
- All 10 locales updated with new i18n keys
This commit is contained in:
Ulas
2026-04-14 08:04:26 +02:00
parent 6f532e45ec
commit 8f96e066f3
15 changed files with 495 additions and 50 deletions
+8 -1
View File
@@ -77,7 +77,14 @@
"dueSoon": "Heute fällig",
"dueTomorrow": "Morgen fällig",
"allDay": "Ganztägig",
"shoppingMore": "+{{count}} weitere"
"shoppingMore": "+{{count}} weitere",
"weather": "Wetter",
"customize": "Anpassen",
"customizeTitle": "Widgets anpassen",
"customizeReset": "Standard",
"customizeSaved": "Dashboard gespeichert",
"customizeMoveUp": "Nach oben",
"customizeMoveDown": "Nach unten"
},
"tasks": {
"title": "Aufgaben",
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Λήγει σήμερα",
"dueTomorrow": "Λήγει αύριο",
"allDay": "Όλη μέρα",
"shoppingMore": "+{{count}} ακόμα"
"shoppingMore": "+{{count}} ακόμα",
"weather": "Καιρός",
"customize": "Προσαρμογή",
"customizeTitle": "Προσαρμογή widgets",
"customizeReset": "Επαναφορά",
"customizeSaved": "Πίνακας αποθηκεύτηκε",
"customizeMoveUp": "Πάνω",
"customizeMoveDown": "Κάτω"
},
"tasks": {
"title": "Εργασίες",
@@ -589,4 +596,4 @@
"unitMonth": "μήνα",
"unitMonths": "μήνες"
}
}
}
+8 -1
View File
@@ -77,7 +77,14 @@
"dueSoon": "Due today",
"dueTomorrow": "Due tomorrow",
"allDay": "All day",
"shoppingMore": "+{{count}} more"
"shoppingMore": "+{{count}} more",
"weather": "Weather",
"customize": "Customize",
"customizeTitle": "Customize widgets",
"customizeReset": "Reset",
"customizeSaved": "Dashboard saved",
"customizeMoveUp": "Move up",
"customizeMoveDown": "Move down"
},
"tasks": {
"title": "Tasks",
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Vence hoy",
"dueTomorrow": "Vence mañana",
"allDay": "Todo el día",
"shoppingMore": "+{{count}} más"
"shoppingMore": "+{{count}} más",
"weather": "Clima",
"customize": "Personalizar",
"customizeTitle": "Personalizar widgets",
"customizeReset": "Restablecer",
"customizeSaved": "Panel guardado",
"customizeMoveUp": "Subir",
"customizeMoveDown": "Bajar"
},
"tasks": {
"title": "Tareas",
@@ -589,4 +596,4 @@
"unitMonth": "mes",
"unitMonths": "meses"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "À rendre aujourd'hui",
"dueTomorrow": "À rendre demain",
"allDay": "Toute la journée",
"shoppingMore": "+{{count}} de plus"
"shoppingMore": "+{{count}} de plus",
"weather": "Météo",
"customize": "Personnaliser",
"customizeTitle": "Personnaliser les widgets",
"customizeReset": "Réinitialiser",
"customizeSaved": "Tableau de bord sauvegardé",
"customizeMoveUp": "Monter",
"customizeMoveDown": "Descendre"
},
"tasks": {
"title": "Tâches",
@@ -589,4 +596,4 @@
"unitMonth": "mois",
"unitMonths": "mois"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Scade oggi",
"dueTomorrow": "Scade domani",
"allDay": "Tutto il giorno",
"shoppingMore": "+{{count}} altri"
"shoppingMore": "+{{count}} altri",
"weather": "Meteo",
"customize": "Personalizza",
"customizeTitle": "Personalizza widget",
"customizeReset": "Ripristina",
"customizeSaved": "Dashboard salvata",
"customizeMoveUp": "Su",
"customizeMoveDown": "Giù"
},
"tasks": {
"title": "Compiti",
@@ -589,4 +596,4 @@
"unitMonth": "mese",
"unitMonths": "mesi"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Сегодня",
"dueTomorrow": "Завтра",
"allDay": "Весь день",
"shoppingMore": "+{{count}} ещё"
"shoppingMore": "+{{count}} ещё",
"weather": "Погода",
"customize": "Настроить",
"customizeTitle": "Настроить виджеты",
"customizeReset": "Сбросить",
"customizeSaved": "Панель сохранена",
"customizeMoveUp": "Вверх",
"customizeMoveDown": "Вниз"
},
"tasks": {
"title": "Задачи",
@@ -589,4 +596,4 @@
"unitMonth": "месяц",
"unitMonths": "месяцев"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Förfaller idag",
"dueTomorrow": "Förfaller imorgon",
"allDay": "Hela dagen",
"shoppingMore": "+{{count}} till"
"shoppingMore": "+{{count}} till",
"weather": "Väder",
"customize": "Anpassa",
"customizeTitle": "Anpassa widgets",
"customizeReset": "Återställ",
"customizeSaved": "Instrumentpanel sparad",
"customizeMoveUp": "Flytta upp",
"customizeMoveDown": "Flytta ner"
},
"tasks": {
"title": "Uppgifter",
@@ -589,4 +596,4 @@
"unitMonth": "månad",
"unitMonths": "månader"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "Bugün bitiyor",
"dueTomorrow": "Yarın bitiyor",
"allDay": "Tüm gün",
"shoppingMore": "+{{count}} daha"
"shoppingMore": "+{{count}} daha",
"weather": "Hava",
"customize": "Özelleştir",
"customizeTitle": "Widget'ları özelleştir",
"customizeReset": "Sıfırla",
"customizeSaved": "Pano kaydedildi",
"customizeMoveUp": "Yukarı",
"customizeMoveDown": "Aşağı"
},
"tasks": {
"title": "Görevler",
@@ -589,4 +596,4 @@
"unitMonth": "ay",
"unitMonths": "ay"
}
}
}
+9 -2
View File
@@ -77,7 +77,14 @@
"dueSoon": "今天到期",
"dueTomorrow": "明天到期",
"allDay": "全天",
"shoppingMore": "+{{count}} 更多"
"shoppingMore": "+{{count}} 更多",
"weather": "天气",
"customize": "自定义",
"customizeTitle": "自定义小组件",
"customizeReset": "重置",
"customizeSaved": "仪表板已保存",
"customizeMoveUp": "上移",
"customizeMoveDown": "下移"
},
"tasks": {
"title": "任务",
@@ -589,4 +596,4 @@
"unitMonth": "个月",
"unitMonths": "个月"
}
}
}