From e7c8df01fd59b6ca599a572b8ed4385836231d13 Mon Sep 17 00:00:00 2001
From: Linus Rath <139418639+rathlinus@users.noreply.github.com>
Date: Sun, 1 Nov 2026 06:42:37 +0100
Subject: [PATCH] fix: show the out-of-office calendar choice the way the
organisation's lock applies it
---
.../__tests__/vacation-calendar-block.test.tsx | 14 +++++++++++++-
components/settings/vacation-calendar-block.tsx | 11 +++++++----
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/components/settings/__tests__/vacation-calendar-block.test.tsx b/components/settings/__tests__/vacation-calendar-block.test.tsx
index 81dce2d98..8b9d46efa 100644
--- a/components/settings/__tests__/vacation-calendar-block.test.tsx
+++ b/components/settings/__tests__/vacation-calendar-block.test.tsx
@@ -26,7 +26,7 @@ const client = {
function lock(value: boolean | null) {
const policy = usePolicyStore.getState().policy;
- usePolicyStore.setState({ policy: { ...policy, restrictions: value === null ? {} : { vacationBlockCalendar: { locked: true, value } } } });
+ usePolicyStore.setState({ policy: { ...policy, defaults: {}, restrictions: value === null ? {} : { vacationBlockCalendar: { locked: true, value } } } });
}
describe('VacationCalendarBlock', () => {
@@ -61,6 +61,18 @@ describe('VacationCalendarBlock', () => {
expect(box.closest('[inert]')).not.toBeNull();
});
+ it('shows what the sync does for a lock without a value, and nothing when hidden', async () => {
+ const policy = usePolicyStore.getState().policy;
+ usePolicyStore.setState({ policy: { ...policy, defaults: { vacationBlockCalendar: false }, restrictions: { vacationBlockCalendar: { locked: true } } } });
+ const view = render();
+ expect(((await screen.findByTestId('vacation-block-calendar')) as HTMLInputElement).checked).toBe(false);
+ view.unmount();
+ usePolicyStore.setState({ policy: { ...policy, defaults: {}, restrictions: { vacationBlockCalendar: { hidden: true } } } });
+ const hidden = render();
+ await waitFor(() => expect(client.getAllCalendars).toHaveBeenCalled());
+ expect(hidden.container.querySelector('[data-testid="vacation-block-calendar"]')).toBeNull();
+ });
+
it('says a managed account\'s calendar can\'t be blocked without write access', async () => {
client.getAllCalendars.mockResolvedValueOnce([{ id: 'boss:b', isDefault: true, isShared: true, accountId: 'boss', myRights: { mayWriteAll: false, mayWriteOwn: false } }] as never);
render();
diff --git a/components/settings/vacation-calendar-block.tsx b/components/settings/vacation-calendar-block.tsx
index 8de77ac0d..9911ff2b9 100644
--- a/components/settings/vacation-calendar-block.tsx
+++ b/components/settings/vacation-calendar-block.tsx
@@ -8,7 +8,8 @@ import { useAuthStore } from '@/stores/auth-store';
import { useSettingsStore } from '@/stores/settings-store';
import { useVacationStore } from '@/stores/vacation-store';
import { useRestriction } from '@/hooks/use-restriction';
-import { blockCalendar, ownFilterScriptStops, vacationBlockChanged } from '@/lib/vacation-calendar';
+import { blockCalendar, ownFilterScriptStops, resolveBlockSetting, vacationBlockChanged } from '@/lib/vacation-calendar';
+import { usePolicyStore } from '@/stores/policy-store';
/**
* "Block my calendar" under the out-of-office dates (lib/vacation-calendar.ts):
@@ -22,7 +23,9 @@ export function VacationCalendarBlock({ hasDates, accountId }: { hasDates: boole
const setting = useSettingsStore((s) => s.vacationBlockCalendar);
const updateSetting = useSettingsStore((s) => s.updateSetting);
const restriction = useRestriction('vacationBlockCalendar');
- const checked = restriction.locked && typeof restriction.value === 'boolean' ? restriction.value : setting !== false;
+ const policyDefault = usePolicyStore((s) => s.policy.defaults?.vacationBlockCalendar);
+ // The same resolution as the sync (lib/vacation-calendar.ts).
+ const { value: checked, locked, hidden } = resolveBlockSetting(restriction, policyDefault, setting);
const [access, setAccess] = useState<{ key: string; ok: boolean } | null>(null);
const id = useId();
const key = accountId ?? '';
@@ -40,7 +43,7 @@ export function VacationCalendarBlock({ hasDates, accountId }: { hasDates: boole
return () => { cancelled = true; };
}, [client, supported, hasDates, accountId, key]);
- if (!client || !supported || !hasDates) return null;
+ if (!client || !supported || !hasDates || hidden) return null;
if (access?.key === key && !access.ok) {
return (
@@ -56,7 +59,7 @@ export function VacationCalendarBlock({ hasDates, accountId }: { hasDates: boole
};
return (
-
+