Skip to content

feat(console): offer the new Console in a dismissible modal - #3195

Merged
HarshMN2345 merged 9 commits into
mainfrom
feat-new-console-modal
Sep 9, 2026
Merged

feat(console): offer the new Console in a dismissible modal#3195
HarshMN2345 merged 9 commits into
mainfrom
feat-new-console-modal

Conversation

@HarshMN2345

@HarshMN2345 HarshMN2345 commented Sep 9, 2026

Copy link
Copy Markdown
Member

Offer eligible cloud users a dismissible introduction to the new Console, with a cover image, retirement notice, and explicit choices to switch or stay. Either choice, the close button, Escape, or a backdrop click records one 30-day snooze with exponential backoff.

The modal uses a native dialog to contain keyboard focus and isolate the background, restores focus when it closes, and disables console shortcuts while open. Escape closes only the promotion, without reaching a background wizard. A reactive route check suppresses the modal throughout onboarding, including client-side navigation; route changes and parent-driven hiding do not record a dismissal.

The existing top banner remains available after dismissal. Its horizontal layout again uses the 767px breakpoint, retaining the earlier fix for the full-width mobile button. The PR also upgrades @faker-js/faker to 10.6.0 and raises the js-yaml override to 4.3.2 to address the dependency advisories that blocked CI.

The retirement copy currently says “in the coming weeks”; an @todo marks where to insert a confirmed date when one is available.

Validation: all 291 unit tests, formatting, lint, and production build pass. Svelte check reports zero errors (92 existing warnings). The 16 new behavior tests exercise persisted notification eligibility across calendar time, repeated dismissals and exponential backoff, duplicate dismissal events, the switch link, parent hiding, onboarding transitions, Escape isolation, and focus restoration.

Browser verification confirms focus containment and restoration, background isolation, all five explicit exits, correct external navigation, silent onboarding transitions, and usable scrolling on short screens. All three live staging E2E journeys pass; they assert the prompt is absent during onboarding and explicitly dismiss it afterward.

Users on the old Console get one interruptive prompt with an explicit
choice: try the new Console, or carry on with the old one. Closing it by
any route counts as choosing to stay.

Built on the existing Modal from $lib/components rather than a bespoke
full-screen surface. wizard.showCover() would be genuinely full-screen but
has never had a consumer, so it is untested in production.

Snoozes for a month with backoff via hideNotification, longer than the
banner's week because this is the most interruptive of the three surfaces.
Never shown during onboarding.

utm_medium=modal keeps it comparable with the banner and the promo card.
bun audit started failing on every branch after an advisory against
js-yaml >=4.0.0 <4.3.2, reached through eslint. The existing override
allowed 4.3.1, which is vulnerable. Pinned to ^4.3.2 rather than >=4.3.2,
which resolved to 5.x and crossed a major boundary.

GHSA-2883-xcg3-v3hh
Two defects found by running it rather than reading it.

`show` starts false and the parent flips it on, so the reactive exit
handler fired on mount and recorded a dismissal before the modal had ever
appeared. It now only counts as an exit once the modal has actually been
open.

Modal also sets show = false on navigation via autoClose, which this
component read as the user choosing to stay on the old Console. Navigating
is not a choice, so autoClose is off; the only ways out are the close
button, Escape, the backdrop, and the two footer buttons.

Also moves the copy from the description slot into the body, which left a
dead gap above the footer, and drops the modal from size l to m so two
lines of text are not stranded in a very wide box.
Replaces the plain text modal with the cover-led layout: a real capture of
the new Console, a one line pitch, the retirement notice, and the two
choices.

The image is the generator export rather than drawn artwork, matching how
the promo card carries its cover. The retirement date is the sentence most
likely to change the answer, so it sits above the actions in Alert.Inline,
the same notice treatment the rest of the console uses, instead of below
them as fine print.

Dropped the three feature bullets. They restated what the screenshot
already showed, and their accent-tinted icon tiles were not a pattern used
anywhere else in the console.

The retirement wording is still a placeholder pending a confirmed date.
@appwrite

appwrite Bot commented Sep 9, 2026

Copy link
Copy Markdown

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
 console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

Teams feature lets you group users with membership management and role permissions

@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge from a correctness perspective, with only the existing non-blocking concern about implementation-coupled tests still outstanding.

Summary

  • Uses a native modal dialog with reactive onboarding suppression, shortcut disabling, and focus restoration.
  • Persists dismissals with exponential backoff and retains the existing banner.
  • Adds unit and E2E coverage for dismissal, onboarding, and navigation flows.
  • Updates Faker and the js-yaml override with corresponding lockfile changes.

Comment thread src/routes/(console)/+layout.svelte Outdated
Comment thread src/lib/components/newConsoleModal.svelte Outdated
Comment on lines +24 to +39
function close(action: 'try' | 'continue') {
if (!recorded) {
recorded = true;
trackEvent('close_new_console_modal', { source: 'new_console_modal', action });
hideNotification('newConsoleModal', {
coolOffPeriod: COOL_OFF_HOURS,
exponentialBackoff: true
});
}

show = false;
}

function onKeydown(event: KeyboardEvent) {
if (show && event.key === 'Escape') close('continue');
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Dismissal behavior is untested

The new modal has bespoke handling for Escape, backdrop clicks, action choices, one-time snoozing, and navigation behavior, but none of these observable paths is covered by a test. A later change could silently restore premature dismissal, double-snoozing, or navigation-triggered dismissal. Add behavior-level coverage that exercises user exits and verifies the resulting notification state rather than mirroring constants or source structure.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/components/newConsoleModal.svelte
Line: 24-39

Comment:
**Dismissal behavior is untested**

The new modal has bespoke handling for Escape, backdrop clicks, action choices, one-time snoozing, and navigation behavior, but none of these observable paths is covered by a test. A later change could silently restore premature dismissal, double-snoozing, or navigation-triggered dismissal. Add behavior-level coverage that exercises user exits and verifies the resulting notification state rather than mirroring constants or source structure.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment thread src/lib/components/newConsoleModal.svelte
Comment thread src/lib/components/newConsoleModal.svelte
The 768px crush had two causes: the full-width mobile button claiming the
whole line, and the direction breakpoint sitting at isSmallViewport (767px)
while .is-full-width-mobile applies at 768px. Dropping fullWidthMobile fixed
it on its own; moving the breakpoint to isTabletViewport (1023px) as well
just made the banner stack 256px earlier than it needs to, pushing "Try it
now" below the copy on ordinary laptop widths.

The text is ~64 characters and the button ~100px, which fits comfortably in
768px minus the shell padding, so the breakpoint goes back to 767px.

Measured at 375, 767, 768, 900, 1023 and 1440: one row above 767px, stacked
and centred below it, and main > header offset matches the stack height
exactly at every width.
GHSA-qxc2-j82w-r537 covers @faker-js/faker <=10.4.0 and is rated high, so
`bun audit --audit-level high` fails and takes the build job with it on every
branch. The repo was on ^9.9.0; the fix landed in 10.6.0.

faker is a runtime dependency here, not a dev one: src/lib/helpers/faker.ts
ships in the console bundle and powers "generate fake data" in the databases
UI. The advisory is specific to helpers.fake(), which this repo never calls,
so the exposure was nil, but the audit gate does not read call sites.

Nothing in src/ needed changing. Every one of the 20 faker APIs used keeps its
v9 signature in the installed v10 typings, including location.latitude and
location.longitude, which still return `number` and so still serialise
correctly into the point and line column payloads.

  bun audit --audit-level high   clean (18 remaining are moderate/low)
  bun run check                  0 errors
  bun run test:unit              275/275
  bun run build                  success
@HarshMN2345

Copy link
Copy Markdown
Member Author

Addressed the review findings in 39e1b14:

  • Onboarding exclusion is derived from the current route inside the Svelte 5 modal and hides it during client-side navigation without recording a dismissal.
  • The modal now uses native dialog.showModal() / close() for background isolation and keyboard focus, restores previous focus on teardown, disables console shortcuts, and prevents Escape from reaching a background wizard.
  • The component uses $props() / $bindable() and the retirement annotation follows @todo convention.
  • Added 15 behavior tests using the real notification preference logic. They cover every explicit exit, duplicate events, backoff and preservation of other preferences, hidden mounting, parent-driven hiding, onboarding navigation, Escape isolation, and focus restoration.
  • Those tests also exposed a swallowed CTA click in the legacy button wrapper. The modal now uses Pink button primitives with onclick, so switching records the intended snooze and analytics.

All 290 unit tests, formatting, Svelte check (zero errors), and lint pass. The E2E suite and browser verification are still running. Please reassess the current commit and flag any remaining issues.

Comment thread src/lib/components/newConsoleModal.svelte.test.ts Outdated
@HarshMN2345
HarshMN2345 merged commit 843f17e into main Sep 9, 2026
4 checks passed
@HarshMN2345
HarshMN2345 deleted the feat-new-console-modal branch September 9, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants