diff --git a/web/e2e/smoke.spec.js b/web/e2e/smoke.spec.js index a4f1b6d..b82d005 100644 --- a/web/e2e/smoke.spec.js +++ b/web/e2e/smoke.spec.js @@ -1072,7 +1072,9 @@ test('kalenderen viser Googles begivenheder over egne opgaver, og kun opgaven ka read_only: true, has_client: true, redirect_uri: 'http://localhost/oauth/calendar/callback', - calendars: [] + calendars: [ + { id: 'c1', remote_id: 'fam', name: 'Arbejde', colour: '#0b8043', shown: true } + ] } }) ); @@ -1109,6 +1111,12 @@ test('kalenderen viser Googles begivenheder over egne opgaver, og kun opgaven ka } await expect(cell, `uge-visningen nåede aldrig frem til ${day}`).toBeVisible(); + // Connected, with a calendar ticked — so neither of the two "there is nothing + // here" notices belongs on the screen. They exist so an empty grid is never + // unexplained, and an explanation for a state you are not in is noise. + await expect(page.getByText('Ingen kalender er forbundet endnu.')).toBeHidden(); + await expect(page.getByText('Ingen af kontoens kalendere er valgt endnu.')).toBeHidden(); + // Both kinds are in the same cell, which is the whole point of the view. const event = cell.locator('.event').filter({ hasText: 'Bestyrelsesmøde' }); const allDay = cell.locator('.event').filter({ hasText: 'Feriedag' }); diff --git a/web/src/lib/locales/da.js b/web/src/lib/locales/da.js index 69909b5..06035aa 100644 --- a/web/src/lib/locales/da.js +++ b/web/src/lib/locales/da.js @@ -630,6 +630,7 @@ export const da = { 'cal.notConnected': 'Ingen kalender er forbundet endnu. Det gøres under Indstillinger → Integrationer.', 'cal.settings': 'Indstillinger', + 'cal.noneChosen': 'Ingen af kontoens kalendere er valgt endnu.', 'cal.allDay': 'Hele dagen', 'cal.openInGoogle': 'Åbn i Google Kalender', 'cal.beyondWindow': diff --git a/web/src/lib/locales/en.js b/web/src/lib/locales/en.js index e3c6c08..0e8709f 100644 --- a/web/src/lib/locales/en.js +++ b/web/src/lib/locales/en.js @@ -623,6 +623,7 @@ export const en = { 'cal.title': 'Calendar', 'cal.notConnected': 'No calendar is connected yet. That is done under Settings → Integrations.', 'cal.settings': 'Settings', + 'cal.noneChosen': 'None of the account’s calendars are chosen yet.', 'cal.allDay': 'All day', 'cal.openInGoogle': 'Open in Google Calendar', 'cal.beyondWindow': diff --git a/web/src/routes/indstillinger/integrationer/+page.svelte b/web/src/routes/indstillinger/integrationer/+page.svelte index f23158c..5a57c04 100644 --- a/web/src/routes/indstillinger/integrationer/+page.svelte +++ b/web/src/routes/indstillinger/integrationer/+page.svelte @@ -197,8 +197,19 @@ calendarsSaved = false; try { await api.setCalendars(shownCalendars); - await loadCalendar(); calendarsSaved = true; + // And fetch, without being asked again. + // + // Ticking a calendar is somebody saying "show me this one". Saving the + // choice and leaving the grid empty until the sweep comes round a quarter + // of an hour later is a calendar that says a fortnight is clear — and the + // person is on this page, watching, with the button under their hand. + // Also what refreshes the panel: syncCalendarNow reloads it when it is done. + if (shownCalendars.length) { + await syncCalendarNow(); + } else { + await loadCalendar(); + } } catch (e) { app.toast(humanMessage(e)); } finally { diff --git a/web/src/routes/kalender/+page.svelte b/web/src/routes/kalender/+page.svelte index 81e2c84..2d55f0a 100644 --- a/web/src/routes/kalender/+page.svelte +++ b/web/src/routes/kalender/+page.svelte @@ -22,13 +22,18 @@ /** Null until the first answer, so nothing flashes before it is known. */ let window_ = $state(null); let connected = $state(null); + /** Whether any calendar in the connected account is ticked. */ + let anyShown = $state(false); /** The dates the grid is showing, so the notice below can compare against them. */ let showing = $state(null); $effect(() => { api .getCalendar() - .then((status) => (connected = status.connected)) + .then((status) => { + connected = status.connected; + anyShown = (status.calendars ?? []).some((c) => c.shown); + }) .catch(() => { // A calendar that could not be asked about is not a reason to withhold // the grid: the tasks in it are verdande's own and do not depend on @@ -101,6 +106,16 @@
{/if} + + {#if connected && !anyShown} ++ {t('cal.noneChosen')} + {t('cal.settings')} +
+ {/if} + {#if beyond}{t('cal.beyondWindow', { from: window_.from, to: window_.to })}
{/if}