From 99bc7bd886c97d33149a839b29a59b8301242d7e Mon Sep 17 00:00:00 2001 From: abhijit-singh Date: Mon, 27 Jul 2026 20:30:36 +0530 Subject: [PATCH 1/4] Add discoverable private channels request-to-join UX (#37078) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add discoverable private channels request-to-join UX Let users mark private channels discoverable, find them in Browse Channels, submit and withdraw join requests, and track status via My pending requests instead of DM notifications. Co-authored-by: Cursor * Drop unrelated server changes from the branch Restore server files to master; this PR is webapp-only and builds on the existing discoverable-channels server implementation. Co-authored-by: Cursor * Close Request to Join modal immediately on submit Drop the in-modal pending state so the modal closes as soon as the request is sent, rather than flipping into a "sent / Withdraw" view before disappearing. Browse Channels rows already handle the post-send state (Requested pill + Withdraw), so the modal's pending branch was redundant and visually noisy. * Fix lint in channel_settings_info_tab test Split multi-prop JSX onto separate lines and remove the trailing blank line inside the Discoverable toggle describe block. Resolves the react/jsx-max-props-per-line and padded-blocks errors that were failing check-lint and cascading into a skipped build / failed Spinwick. * Fix stylelint property order in request_join_channel_modal SCSS Move min-width before align-items in .RequestJoinChannelModal__header to satisfy stylelint's order/properties-order rule (dimensions before flex alignment). * Restore unintended deletions from original branch commit The initial PR commit accidentally reverted master-side changes in several shared files when the AI agent regenerated them. The rebase onto current master preserved those reverts. Restore each piece while keeping the branch's discoverable additions: - client4.ts: previewLicense method - websocket_actions.ts: handleFileUploadRejected function + switch case - websocket_message.ts / websocket_messages.ts: FileUploadRejected type - config.ts: License type fields (expires_at, customer required, sku_short_name, is_gov_sku) - constants.tsx: CHANNEL_MENTION_AUTO_FOLLOW notification section - en.json: master keys (admin.license.*, admin.access_control.*, etc.) restored; discoverable keys re-inserted using the Mattermost i18n formatter sort rule (case-insensitive, '_' before '.') - package-lock.json: reset to master * Sync webapp package-lock.json with master to fix CI install The branch carried a stale package-lock.json pinning eslint@8.57.0 while package.json (identical to master) declares eslint@9.39.4. npm aborted with an ERESOLVE peer conflict (@typescript-eslint/eslint-plugin@7.18.0 peers eslint@^8.56.0), failing check-lint and the E2E check before any code ran. This branch adds no dependencies, so the lockfile is restored to match master. Co-authored-by: Cursor * Fix join-request pending count double-decrement and prune stale pending map Decrement countsByChannel from the actual pending->terminal transition instead of the incoming status alone, so the acting admin's optimistic dispatch plus the server's WebSocket echo of a single approve/deny no longer double-decrements the badge. Make CREATED count-idempotent for re-delivered events. Rebuild myPendingByChannel from the authoritative full list on RECEIVED_MY_CHANNEL_JOIN_REQUESTS so a request that resolved while the client missed the WS event no longer lingers as stale. Co-authored-by: Ibrahim Serdar Acikgoz * Surface discoverable channels in Browse without requiring a search getChannels only returns public channels, so non-member discoverable private channels (and the Discoverable filter) were empty until the user typed a search term. Fetch them on mount via an empty-term non-admin search (already ABAC-filtered server-side), fold them into the default All list and the Discoverable filter, and resolve My pending requests rows against them. Co-authored-by: Ibrahim Serdar Acikgoz * Browse row cleanup: drop unused action, keep Withdraw if discoverability revoked Remove the requestJoinChannel action that was wired into Browse Channels but never called (the confirmation modal dispatches it directly). Show the Withdraw affordance for any non-member with an open request even after an admin flips the channel's discoverable flag off, instead of falling through to a Join button the server rejects for a private channel. Co-authored-by: Ibrahim Serdar Acikgoz * Fix discoverable-toggle a11y labels and gate settings toggle on in-progress type - Description