Improve: #368 error message when user has no public calendars (#412)

- Add translation key 'userDoesNotHavePublicCalendars' to all locale files (en, fr, vi, ru)
- Update ErrorSnackbar to support translation keys in error messages with params
- Update getTempCalendarsListAsync to throw error with translation key format instead of hardcoded message
- Error message now displays user-friendly translated text: '{User Name} does not have public calendars'
This commit is contained in:
lenhanphung
2025-12-12 23:32:36 +07:00
committed by GitHub
parent aa7d032aef
commit 6161e295ce
6 changed files with 45 additions and 2 deletions
+31 -1
View File
@@ -20,6 +20,36 @@ export function ErrorSnackbar({
dispatch(type === "calendar" ? calendarClearError() : userClearError());
};
const getErrorMessage = () => {
if (!error) return t("error.unknown");
// Check if error message is a translation key with params
// Format: TRANSLATION:key|param1=value1|param2=value2
if (error.startsWith("TRANSLATION:")) {
const parts = error.substring(12).split("|");
const translationKey = parts[0];
const params: Record<string, string> = {};
for (let i = 1; i < parts.length; i++) {
const equalIndex = parts[i].indexOf("=");
if (equalIndex === -1) continue;
const key = parts[i].substring(0, equalIndex);
const value = parts[i].substring(equalIndex + 1);
if (key && value) {
try {
params[key] = decodeURIComponent(value);
} catch {
params[key] = value;
}
}
}
return t(translationKey, params);
}
return error;
};
return (
<Snackbar
open={!!error}
@@ -36,7 +66,7 @@ export function ErrorSnackbar({
</Button>
}
>
{error || t("error.unknown")}
{getErrorMessage()}
</Alert>
</Snackbar>
);
+10 -1
View File
@@ -170,7 +170,16 @@ export const getTempCalendarsListAsync = createAsyncThunk<
tempUser.openpaasId ?? "",
"sharedPublic=true&"
)) as Record<string, any>;
const rawCalendars = calendars._embedded["dav:calendar"];
const rawCalendars = calendars._embedded?.["dav:calendar"];
if (!rawCalendars || rawCalendars.length === 0) {
const userName = tempUser.displayName || tempUser.email || "User";
// Format: TRANSLATION:key|param1=value1
const encodedName = encodeURIComponent(userName);
throw new Error(
`TRANSLATION:calendar.userDoesNotHavePublicCalendars|name=${encodedName}`
);
}
for (const cal of rawCalendars) {
const name = cal["dav:name"];
+1
View File
@@ -18,6 +18,7 @@
"browseOtherCalendars": "Browse other calendars",
"noPublicCalendarsFor": "No publicly available calendars for %{name}",
"noMoreCalendarsFor": "No more calendars for %{name}",
"userDoesNotHavePublicCalendars": "%{name} does not have public calendars",
"delete": {
"title": "Remove %{name}?",
"personalWarning": "You will lose all events in this calendar.",
+1
View File
@@ -18,6 +18,7 @@
"browseOtherCalendars": "Parcourir d'autres calendriers",
"noPublicCalendarsFor": "Aucun calendrier public disponible pour %{name}",
"noMoreCalendarsFor": "Plus de calendriers disponibles pour %{name}",
"userDoesNotHavePublicCalendars": "%{name} n'a pas de calendriers publics",
"delete": {
"title": "Supprimer %{name} ?",
"personalWarning": "Vous allez perdre tous les événements de ce calendrier.",
+1
View File
@@ -18,6 +18,7 @@
"browseOtherCalendars": "Просмотреть другие календари",
"noPublicCalendarsFor": "Нет общедоступных календарей для %{name}",
"noMoreCalendarsFor": "Других календарей для %{name} нет",
"userDoesNotHavePublicCalendars": "%{name} не имеет общедоступных календарей",
"delete": {
"title": "Удалить %{name}?",
"personalWarning": "Вы потеряете все события в этом календаре.",
+1
View File
@@ -18,6 +18,7 @@
"browseOtherCalendars": "Xem các lịch khác",
"noPublicCalendarsFor": "Không có lịch công khai cho %{name}",
"noMoreCalendarsFor": "Không còn lịch nào cho %{name}",
"userDoesNotHavePublicCalendars": "%{name} không có lịch công khai",
"delete": {
"title": "Xóa %{name}?",
"personalWarning": "Bạn sẽ mất tất cả sự kiện trong lịch này.",