Skip to content

[UEPR-553] Front-end blocking in scratch-www#10189

Open
kbangelov wants to merge 11 commits into
scratchfoundation:release/read-only-modefrom
kbangelov:task/uepr-553-front-end-feature-freeze-read-only-mode
Open

[UEPR-553] Front-end blocking in scratch-www#10189
kbangelov wants to merge 11 commits into
scratchfoundation:release/read-only-modefrom
kbangelov:task/uepr-553-front-end-feature-freeze-read-only-mode

Conversation

@kbangelov

Copy link
Copy Markdown
Contributor

Resolves:

Part of https://scratchfoundation.atlassian.net/browse/UEPR-553

Changes:

Disable frontend operations for PDP and Studios

@kbangelov kbangelov changed the base branch from develop to release/read-only-mode April 29, 2026 10:43

Copilot AI left a comment

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.

Pull request overview

Introduces a READ_ONLY_MODE feature flag to disable interactive/editing operations across Studio pages and the Project Detail Page (preview), to support front-end blocking for UEPR-553.

Changes:

  • Add READ_ONLY_MODE flag (env-driven) and thread it through Studio + Preview views to disable/hide interactive controls.
  • Add “disabled” styling helpers and new disabled color tokens used by Studio UI elements.
  • Prevent certain PDP interactions (love/favorite/share/add-to-studio) and gate editor capabilities when in read-only mode.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/views/studio/studio.scss Adds shared “disabled” styles and thumbnail-edit disabled styles for studios.
src/views/studio/studio-title.jsx Disables title textarea and applies disabled styling in read-only mode.
src/views/studio/studio-project-tile.jsx Hides project tile overflow actions in read-only mode.
src/views/studio/studio-project-adder.jsx Disables project add/browse controls in read-only mode.
src/views/studio/studio-member-tile.jsx Hides member management overflow actions in read-only mode.
src/views/studio/studio-image.jsx Disables studio thumbnail upload and applies disabled styling in read-only mode.
src/views/studio/studio-follow.jsx Disables follow/unfollow in read-only mode.
src/views/studio/studio-description.jsx Disables description textarea and applies disabled styling in read-only mode.
src/views/studio/studio-curator-inviter.jsx Disables curator invite form in read-only mode.
src/views/studio/studio-curator-invite.jsx Adds disabled styling for invite acceptance button (but currently doesn’t fully disable behavior).
src/views/preview/project-view.jsx Blocks love/favorite toggles and gates editor capabilities based on read-only/shared state.
src/views/preview/presentation.jsx Suppresses “share” banner in read-only mode and passes readOnlyMode to child components.
src/lib/feature-flags.js Adds READ_ONLY_MODE flag sourced from process.env.READ_ONLY_MODE.
src/_colors.scss Adds disabled UI color tokens used by new styling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 50 to 51
disabled={submitting}
onClick={() => {

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

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

The accept-invite button is still clickable in read-only mode: you add the studio-disabled class when READ_ONLY_MODE is true, but disabled is only driven by submitting. This still allows accepting curator invites while the UI looks disabled. Include READ_ONLY_MODE in the disabled condition (and/or early-return in the click handler) so the action cannot fire in read-only mode.

Suggested change
disabled={submitting}
onClick={() => {
disabled={submitting || READ_ONLY_MODE}
onClick={() => {
if (READ_ONLY_MODE || submitting) return;

Copilot uses AI. Check for mistakes.

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.

Yep, that's a valid point, also pointer-events: none would resolve that even if the button is not disabled, but I agree that we should add {submitting || READ_ONLY_MODE} as we do for the other buttons.

Comment on lines +56 to +60
.studio-disabled {
background: colors.$ui-background-disabled;
color: colors.$ui-text-disabled;
cursor: not-allowed;

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

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

.studio-disabled sets a disabled background, but for studio title/description textareas it looks like the existing textarea.studio-title/textarea.studio-description &:not(:focus) { background: transparent; } rule later in this file will override it (higher specificity), so READ_ONLY_MODE may not visually show the disabled background there. Consider adding a more specific override for disabled textareas (e.g., .studio-disabled.studio-title:disabled / .studio-disabled.studio-description:disabled) or adjusting the :not(:focus) rule to not override when disabled.

Copilot uses AI. Check for mistakes.
Comment thread src/views/preview/project-view.jsx Outdated
canSave={this.props.canSave &&
(!READ_ONLY_MODE || !this.props.isShared)}
canShare={this.props.canShare && !READ_ONLY_MODE}
canUpdateThumbnail={!READ_ONLY_MODE}

Copilot AI Apr 29, 2026

Copy link

Choose a reason for hiding this comment

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

canUpdateThumbnail is disabled whenever READ_ONLY_MODE is true, even for unshared projects. That’s inconsistent with the nearby gating for canEditTitle/canSave (which still allow edits when !isShared) and with the existing canManuallySaveThumbnails logic earlier in this file (which explicitly allows thumbnails when READ_ONLY_MODE and !isShared). If the intent is “block shared/public operations only”, gate canUpdateThumbnail the same way (or align/remove the conflicting thumbnail logic so behavior is consistent).

Suggested change
canUpdateThumbnail={!READ_ONLY_MODE}
canUpdateThumbnail={!READ_ONLY_MODE || !this.props.isShared}

Copilot uses AI. Check for mistakes.

@adzhindzhi adzhindzhi left a comment

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.

I haven't reviewed everything yet, but I'm sharing my comments so far.

Comment thread src/views/preview/presentation.jsx Outdated
/>);
}
} else if (!isShared) {
} else if (!isShared && !READ_ONLY_MODE) {

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.

I think by design the banner is displayed but the Share button is disabled

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.

@adzhindzhi Doesn't the share button hide once someone shares a project?

Comment thread src/views/preview/presentation.jsx Outdated
Comment thread src/views/preview/presentation.jsx Outdated
Comment thread src/views/preview/project-view.jsx Outdated
}
handleFavoriteToggle () {
if (!this.props.favedLoaded) return;
if (!this.props.favedLoaded || READ_ONLY_MODE) return;

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.

You probably wouldn't need these if you apply the disabled styles to the love/favorite buttons + pointer-events: none.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think it doesn't hurt to add that check.

Comment thread src/views/preview/project-view.jsx Outdated
Comment thread src/views/preview/project-view.jsx Outdated
Comment on lines +1203 to +1204
canSave={this.props.canSave &&
(!READ_ONLY_MODE || !this.props.isShared)}

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.

This doesn't handle pressing CTRL + 'S' in the editor, right? I wonder if we should try to disable that, or let the backend handle it and just display an error... 🤔

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.

Doesn't CTRL+S in Chrome (maybe some Chromium browsers too) activate a system keybind to save a page in a .mhtml?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It is handled in the sense that the frontend fails by displaying "Project could not save.", because of this very prop. So I think that's enough?

Comment thread src/views/preview/project-view.jsx Outdated
authorUsername: authorUsername,
authorAvatarBadge: authorAvatarBadge,
canAddToStudio: isLoggedIn && isShared,
canAddToStudio: isLoggedIn && isShared && !READ_ONLY_MODE,

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.

Hmm, this would remove the whole button, right? It's disabled by design, I don't mind it, but let's confirm with Tereza if that's okay.

@adzhindzhi adzhindzhi left a comment

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.

One additional general comment: We should also disable the "Anyone can add projects" toggle? It shouldn't make a difference, but it would be more consistent.

Comment on lines 50 to 51
disabled={submitting}
onClick={() => {

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.

Yep, that's a valid point, also pointer-events: none would resolve that even if the button is not disabled, but I agree that we should add {submitting || READ_ONLY_MODE} as we do for the other buttons.

Comment thread src/views/studio/studio.scss Outdated
Comment thread src/views/studio/studio-member-tile.jsx Outdated
}
</div>
{(canRemove || canPromote || canTransferHost) &&
{(canRemove || canPromote || canTransferHost) && !READ_ONLY_MODE &&

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.

I think by design the menu is disabled in readonly mode, not hidden.

Comment thread src/views/studio/studio-project-tile.jsx Outdated
Comment thread src/views/preview/presentation.jsx Outdated
@kbangelov kbangelov requested a review from adzhindzhi May 5, 2026 08:11
Comment thread src/components/overflow-menu/overflow-menu.jsx Outdated
Comment thread src/components/overflow-menu/overflow-menu.jsx Outdated
Comment thread src/components/overflow-menu/overflow-menu.jsx Outdated
Comment thread src/views/preview/banner.jsx Outdated
Comment thread src/views/preview/banner.jsx Outdated
Comment thread src/views/preview/banner.scss Outdated
Comment thread src/views/preview/presentation.jsx Outdated
Comment thread src/views/preview/project-view.jsx Outdated
Comment thread src/views/preview/subactions.scss Outdated
@kbangelov kbangelov requested a review from adzhindzhi May 7, 2026 16:47

@adzhindzhi adzhindzhi left a comment

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.

Looks good! I left two small comments, but otherwise I think it's pretty clean! One additional general comment is that a few of the disabled buttons still have cursor: pointer, which may be a bit confusing from UX perspective. I think I've only seen this for the love, favorite on PDP and Edit Thumbnail on Studios, but there may be other buttons also affected.

Comment on lines +51 to +52
{canRemove && process.env.READ_ONLY_MODE !== 'true' &&
<OverflowMenu disabled={process.env.READ_ONLY_MODE === 'true'}>

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.

Will the disabled attribute ever be true? Wouldn't we just not show the menu with the process.env.READ_ONLY_MODE !== 'true' check?

Comment thread src/components/overflow-menu/overflow-menu.jsx Outdated
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.

4 participants