Skip to content

fix(presentation): AppFlowy error states, official-cloud Present, AI access hints - #689

Merged
appflowy merged 1 commit into
mainfrom
fix/presentation-error-ui-and-access
Nov 1, 2026
Merged

appflowy merged 1 commit into
mainfrom
fix/presentation-error-ui-and-access

Conversation

@appflowy

@appflowy appflowy commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Description

Three presentation UI fixes.

1. Error states use AppFlowy components (no full-screen errors)

  • Slides dialog: when the saved presentation fails to load, the error is centered, with an error icon, a title, a message and AppFlowy Buttons (outline Back to page, primary Retry). Before, it was left-aligned text with legacy white buttons.
  • Mind map (and document) presentation: a failure to load the saved map, the page structure or the source no longer fills the screen. The presentation closes and an AppFlowy toast (notify.error) says why. A presented map that can't load keeps showing the loading surface until it closes, so the old error page never flashes.
  • Mind map empty states (no content, no edit access) use the same centered PresentationState component, with the close button where the map's would be.

2. Present button: official AppFlowy Cloud only
#688 hid the header Present button for everyone with PRESENTATION_ENTRY_ENABLED = false. feature-flags.ts now exports usePresentationEntryEnabled(), which follows useIsOfficialHosted():

  • Official AppFlowy Cloud users see Present in the page header and the page modal.
  • Self-hosted servers never see it. Neither does anyone while server info is loading or unavailable, so it can't flash for self-hosters.

3. AI options explain missing permission
SOURCE_ACCESS_DENIED used to surface only after opening, as a full-screen error. The Cloud presentation API requires a workspace member or owner (enforce_role_strong(Member)), so a guest who can edit the page passes the web's edit check but is still refused.

In the Present menu, Present AI mind map and Generate AI ppt stay visible but unavailable (aria-disabled, greyed out, selection ignored) when:

  • the user is a workspace guest: "Guests can't use AI mind maps or slides. Ask a workspace owner to add you as a member."
  • the user has no edit access to the page: "You need edit access to this page to use AI mind maps or slides. Ask the page owner to give you edit access."

The reason appears with a lock icon in the existing hover/focus tooltip. These rows don't use Radix disabled, because that removes pointer events and the tooltip would never show. Page permission is read only while the menu is open, and unknown permission doesn't block. A denial the client can't predict, such as a mentioned page or linked database the user can't read, still falls back to the toast from (1).

Validation

  • pnpm type-check passed. ESLint shows no errors in the changed files.
  • Affected Jest suites pass: presentation, RightMenu, ViewModal and share. New tests cover:
    • Present visibility on official vs self-hosted servers.
    • The AI access rule.
    • Unavailable AI rows with their tooltip reason.
    • The toast-and-close mind map failure.
    • The in-place slides error.
  • In a fully parallel run of the presentation suites, one to three timing-sensitive tests fail, a different set each run. The same files all pass when rerun with --maxWorkers=2.
  • Not yet checked in a browser as a guest or read-only user.

Checklist

General

  • I've included relevant documentation or comments for the changes introduced.
  • I've tested the changes in multiple environments (e.g., different browsers, operating systems).

Testing

  • I've added or updated tests to validate the changes introduced for AppFlowy Web.

Feature-Specific

  • For feature additions, I've added a preview (video, screenshot, or demo) in the "Feature Preview" section.
  • I've verified that this feature integrates seamlessly with existing functionality.

🤖 Generated with Claude Code

Summary by Sourcery

Improve presentation availability and failure handling across hosted environments while providing clearer guidance for unavailable AI presentation options.

New Features:

  • Show the Present entry only to users on official AppFlowy Cloud.
  • Explain why AI mind maps and slides are unavailable to guests or users without page edit access while keeping those options visible.

Bug Fixes:

  • Replace presentation failure screens with consistent AppFlowy error and empty states, including retry and navigation actions for slides.
  • Close failed mind map and document presentations and report the source failure with an AppFlowy error toast instead of displaying a full-screen error.

Enhancements:

  • Add shared centered presentation states for loading, empty, and error surfaces.

Documentation:

  • Update presentation documentation to describe official-cloud-only Present availability.

Tests:

  • Add coverage for Present visibility, AI access rules and tooltips, presentation error handling, and failure-to-toast behavior.

…access hints

- Load failures in the slides dialog use a centered AppFlowy error state
  (icon, title, message, Back to page / Retry buttons) instead of left-aligned
  text with legacy buttons.
- A presented mind map or document that cannot load closes and shows an
  AppFlowy toast instead of a full-screen error page. Mind map empty states
  use the same centered component.
- The header Present button (hidden for everyone by #688) now shows only on
  official AppFlowy Cloud: usePresentationEntryEnabled() follows
  useIsOfficialHosted(), so self-hosted servers never see it.
- In the Present menu, AI mind map and AI ppt stay visible but unavailable
  for workspace guests (the server requires a member or owner) and for users
  without edit access to the page, with the reason shown on hover/focus.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@appflowy
appflowy merged commit 9d8f3d2 into main Nov 1, 2026
@appflowy
appflowy deleted the fix/presentation-error-ui-and-access branch November 1, 2026 09:13
@sourcery-ai

sourcery-ai Bot commented Nov 1, 2026

Copy link
Copy Markdown

Sorry @appflowy, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 3 days and 2 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Nov 1, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR updates presentation UX around failures, availability, and access: it uses AppFlowy-native centered states and toasts, exposes Present only on confirmed official Cloud deployments, and explains unavailable AI options for guests or non-editors while preserving server-side fallback handling.

Sequence diagram for presentation failure handling

sequenceDiagram
    participant User
    participant PresentationDialog
    participant PresentationStudio
    participant notify
    participant Page

    User->>PresentationDialog: Open presentation
    PresentationDialog->>PresentationDialog: Load source and permissions
    alt Slides load fails
        PresentationDialog-->>User: Show PresentationState error
        User->>PresentationDialog: Click Retry or Back to page
    else Mind map or document load fails
        PresentationDialog->>notify: notify.error(failure)
        PresentationDialog->>Page: onClose()
        Page-->>User: Return to page with toast
    end

    User->>PresentationStudio: Open saved mind map
    PresentationStudio->>PresentationStudio: Load saved map or page structure
    alt Map load fails
        PresentationStudio->>notify: notify.error(mapPresentationError)
        PresentationStudio->>PresentationStudio: closeMapPresentation()
        Page-->>User: Return to page with toast
    else Map is empty or unavailable
        PresentationStudio-->>User: Show centered PresentationState
    end
Loading

Sequence diagram for official Cloud Present visibility

sequenceDiagram
    participant User
    participant Header
    participant ViewModal
    participant usePresentationEntryEnabled
    participant useIsOfficialHosted
    participant ServerInfo

    User->>Header: Open page
    Header->>usePresentationEntryEnabled: Check Present availability
    usePresentationEntryEnabled->>useIsOfficialHosted: Read hosting mode
    useIsOfficialHosted->>ServerInfo: Read server information
    alt Confirmed official AppFlowy Cloud
        ServerInfo-->>useIsOfficialHosted: Official hosted
        usePresentationEntryEnabled-->>Header: true
        Header-->>User: Show Present button
        usePresentationEntryEnabled-->>ViewModal: true
        ViewModal-->>User: Show Present button
    else Self-hosted, loading, or unavailable
        ServerInfo-->>useIsOfficialHosted: Not confirmed official
        usePresentationEntryEnabled-->>Header: false
        usePresentationEntryEnabled-->>ViewModal: false
        Header-->>User: Hide Present button
    end
Loading

Sequence diagram for AI presentation access hints

sequenceDiagram
    participant User
    participant PresentEntry
    participant PresentationMenu
    participant useUserWorkspaceInfoOptional
    participant useViewActionPermissions
    participant presentationAIAccessReason

    User->>PresentEntry: Open Present menu
    PresentEntry->>PresentEntry: setMenuOpen(true)
    PresentEntry->>useUserWorkspaceInfoOptional: Read workspace role
    PresentEntry->>useViewActionPermissions: Load page permissions
    PresentEntry->>presentationAIAccessReason: Check role and canWrite
    alt Workspace role is Guest
        presentationAIAccessReason-->>PresentEntry: Guest reason
        PresentEntry->>PresentationMenu: aiUnavailableReason
        PresentationMenu-->>User: Greyed AI rows with lock tooltip
        User->>PresentationMenu: Select AI row
        PresentationMenu-->>User: Ignore selection
    else Permissions loaded and page is not editable
        presentationAIAccessReason-->>PresentEntry: Edit access reason
        PresentEntry->>PresentationMenu: aiUnavailableReason
        PresentationMenu-->>User: Greyed AI rows with lock tooltip
    else Access is allowed or unknown
        presentationAIAccessReason-->>PresentEntry: undefined
        PresentationMenu-->>User: Enable AI rows
        User->>PresentationMenu: Select AI row
        PresentationMenu->>PresentEntry: onSelect(mode)
    end
Loading

Flow diagram for AI presentation availability

flowchart TD
    A[Open Present menu] --> B{Workspace role is Guest?}
    B -->|Yes| C[Show AI rows unavailable]
    B -->|No| D{Page permissions loaded?}
    D -->|No| E[Keep AI rows available]
    D -->|Yes| F{canWrite?}
    F -->|No| C
    F -->|Yes| E
    C --> G[Show lock icon and access tooltip]
    C --> H[aria-disabled and ignore selection]
    E --> I[Selecting AI row starts presentation]
    I --> J{Server-side access succeeds?}
    J -->|No| K[Toast error and close presentation]
    J -->|Yes| L[Open AI presentation]
Loading

File-Level Changes

Change Details Files
Replace presentation failure pages with centered AppFlowy state surfaces and contextual recovery behavior.
  • Added reusable centered error/empty presentation state with icon, messaging, and AppFlowy buttons.
  • Kept slide-load failures in place with Back to page and Retry actions.
  • Closed failed mind map/document presentations and reported failures through error toasts.
  • Unified mind map empty, permission, loading, and retry states while preventing a failed map error flash.
src/components/presentation/PresentationDialog.tsx
src/components/presentation/PresentationLoading.tsx
src/components/presentation/PresentationStudio.tsx
src/components/_shared/notify.ts
Gate the Present entry point to confirmed official AppFlowy Cloud deployments.
  • Replaced the static presentation flag with a hook backed by official-host detection.
  • Hide Present in page and modal headers for self-hosted, loading, or unavailable server information.
  • Added optional workspace-info access needed by presentation permission checks and documented the hosting behavior.
src/components/presentation/feature-flags.ts
src/components/app/ViewModal.tsx
src/components/app/header/RightMenu.tsx
src/components/app/app.hooks.tsx
src/components/presentation/README.md
Expose AI presentation permission requirements before launch and explain unavailable actions in the menu.
  • Determine AI eligibility from workspace role and loaded page edit permissions.
  • Keep AI menu rows visible but mark them aria-disabled, prevent selection, and show lock-based tooltip explanations.
  • Allow unknown permissions without blocking and retain server-side/toast fallback for cases the client cannot predict.
  • Added policy and component tests for guest, non-editor, allowed, and unknown-permission scenarios.
src/components/presentation/PresentEntry.tsx
src/components/presentation/PresentationMenu.tsx
src/components/presentation/presentation-policy.ts
src/components/presentation/__tests__/PresentEntry.test.tsx
src/components/presentation/__tests__/presentation-paywall-policy.test.ts
Expand regression coverage for presentation visibility, state transitions, and failure handling.
  • Tested official versus self-hosted Present visibility.
  • Tested toast-and-close behavior for failed mind map loading.
  • Tested in-place slide failure actions and updated presentation preload/dialog mocks for new permission dependencies.
src/components/app/header/__tests__/RightMenu.rowFavorite.test.tsx
src/components/presentation/__tests__/studio-render-work.test.tsx
src/components/presentation/__tests__/dialog-source-refresh.test.tsx
src/components/presentation/__tests__/presentation-preload.test.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

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.

1 participant