From b98ab59f0dcf46f89cb77434424357f3d96e9d34 Mon Sep 17 00:00:00 2001 From: Bernd Rodler Date: Fri, 7 Aug 2026 14:20:34 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20Phase=202=20QA=20=E2=80=94=20all=2025=20?= =?UTF-8?q?remaining=20HIGH/MEDIUM/LOW=20issues?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HIGH fixes (7): - H1: VNCdirectory admin i18n — 30+ translation keys added - H2: handleSave try/catch with error toast - H3: Free/busy accountId scoping - H4: cancelEventBookings filter by eventId - H5: Resource picker static apiFetch import - H6: Sharing-store toast messages via lastMessage state - H7: roleLabel for all resource types MEDIUM fixes (11): - M1: identitySignatureMap cleanup on delete - M2: Now-line relative positioning - M3: Radial menu disabled item keyboard nav - M4: Radial menu stable event listener via refs - M5: cancelBooking error on missing booking - M6: PasswordRow isMasked state flag - M7: Extract shared rights into lib/sharing-rights.ts - M8: VNCtalk client server-side guard - M9: Collabora configManager instead of process.env - M10: CONFIG_ENV_MAP VNCdirectory fields - M11: SENSITIVE_CONFIG_KEYS field name unification LOW fixes (7): - L1-L3: Unused imports removed - L4: aria-labels on close, clear, search, spinner - L5-L7: Comments for intentional patterns, null guard --- app/(main)/admin/_tabs/vncdirectory.tsx | 166 ++++++++------ app/api/sharing/route.ts | 171 +------------- components/calendar/free-busy-view.tsx | 16 +- components/calendar/mini-calendar-dashlet.tsx | 3 + components/calendar/resource-picker.tsx | 5 +- components/contacts/contact-import-dialog.tsx | 2 +- components/settings/import-settings.tsx | 4 +- .../settings/signature-editor-modal.tsx | 2 +- components/ui/radial-menu.tsx | 52 +++-- lib/admin/types.ts | 20 +- lib/calendar-freebusy.ts | 12 +- lib/collabora/client.ts | 4 +- lib/demo/demo-client.ts | 9 +- lib/email-import.ts | 10 - lib/eml-import.ts | 4 - lib/jmap/client-interface.ts | 2 +- lib/jmap/client.ts | 5 +- lib/sharing-rights.ts | 216 ++++++++++++++++++ lib/vnctalk/client.ts | 6 + locales/en/common.json | 66 ++++++ runs/2026-08-07-v1.7.8-baseline/QA-PHASE2.md | 128 +++++++++++ stores/resource-store.ts | 13 +- stores/sharing-store.ts | 206 ++--------------- stores/signature-store.ts | 27 ++- 24 files changed, 662 insertions(+), 487 deletions(-) create mode 100644 lib/sharing-rights.ts create mode 100644 runs/2026-08-07-v1.7.8-baseline/QA-PHASE2.md diff --git a/app/(main)/admin/_tabs/vncdirectory.tsx b/app/(main)/admin/_tabs/vncdirectory.tsx index 911c167d..3cde5fd4 100644 --- a/app/(main)/admin/_tabs/vncdirectory.tsx +++ b/app/(main)/admin/_tabs/vncdirectory.tsx @@ -1,8 +1,10 @@ 'use client'; import { useEffect, useState } from 'react'; +import { useTranslations } from 'next-intl'; import { Save, Loader2, Plus, X } from 'lucide-react'; import { apiFetch } from '@/lib/browser-navigation'; +import { toast } from '@/stores/toast-store'; interface VncDirectoryFormData { enabled: boolean; @@ -49,6 +51,7 @@ const BLANK_FORM: VncDirectoryFormData = { }; export function VncDirectoryTab() { + const t = useTranslations('admin.vncdirectory'); const [config, setConfig] = useState({ ...BLANK_FORM }); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); @@ -105,19 +108,25 @@ export function VncDirectoryTab() { setSaving(true); setMessage(null); - const res = await apiFetch('/api/admin/vncdirectory', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(config), - }); + try { + const res = await apiFetch('/api/admin/vncdirectory', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(config), + }); - if (res.ok) { - setMessage({ type: 'success', text: 'VNCdirectory configuration saved.' }); - setDirty(false); - await fetchConfig(); - } else { - const data = await res.json(); - setMessage({ type: 'error', text: data.error || 'Failed to save' }); + if (res.ok) { + setMessage({ type: 'success', text: t('saved') }); + setDirty(false); + await fetchConfig(); + } else { + const data = await res.json(); + setMessage({ type: 'error', text: data.error || t('save_error') }); + } + } catch (err) { + const msg = err instanceof Error ? err.message : t('save_error'); + setMessage({ type: 'error', text: msg }); + toast.error(msg); } setSaving(false); } @@ -125,7 +134,7 @@ export function VncDirectoryTab() { if (loading) { return (
- Loading... + {t('loading')}
); } @@ -136,9 +145,9 @@ export function VncDirectoryTab() {
-

VNCdirectory

+

{t('title')}

- Centralized identity and directory integration (SAML, LDAP, 2FA) + {t('description')}

{dirty && ( @@ -148,7 +157,7 @@ export function VncDirectoryTab() { className="inline-flex items-center gap-2 h-9 px-4 rounded-md bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90 disabled:opacity-50 transition-all shadow-sm" > {saving ? : } - Save configuration + {t('save')} )}
@@ -165,12 +174,12 @@ export function VncDirectoryTab() {
)} -
+
- Enabled + {t('enabled')}

- Turn on VNCdirectory integration for identity management, SSO, and directory services + {t('enabled_description')}