* Fixes capitalisation for *My messages*, *My posts*, and *My drafts*
sidebar links.
* Hides *My messages* link for anonymous users.
* Hides *My messages* link for users who can’t access messages.
* Adds active state for *My messages* link (applies to all child routes:
personal, group, and tags).
When more than 5 files are run via `turbo_rspec`, we'll show the count.
When less than 5 files, we'll list them.
This is slightly better DX as it avoids spamming the console with
unecessary information.
Post edits need to inform the backend if the locale is changed and is
sometimes set as `""`. This PR prevents the locale from being set to
`""` in the database, and includes a migration to purge the empty
strings.
We want to deprecate the enabled/disabled toggle for this setting and rely entirely on the presence of a URL.
This change:
- Deprecates and hides the enabled/disabled setting.
- Updates all code paths and tests that rely on the old setting.
- Adds a migration that clears the URL if the enabled/disabled setting is set to false.
The reviewable notes route was originally created at `/reviewables/:reviewable_id/notes`, which didn't match the existing reviewable routes at `/review/:reviewable_id`.
This change fixes the naming inconsistency, and tidies up some of the endpoint permission checks.
This PR improves the generic bulk import and base scripts by adding
support for several previously unimplemented features and attributes:
- Category Moderation Groups: Implements the import of group-based
moderation settings for categories.
- Group Attributes: Adds import support for public_admission,
public_exit, allow_membership_requests, and assignable_level.
- User Attributes: Adds import support for trust_level and
primary_group_id.
- User Option: Adds import support for the hide_profile_and_presence
user option.
- Multiple Tag Groups per Tag: Updates tag import logic to handle tags
belonging to multiple tag groups.
This consolidates menu-panel (notification menu and navigation menu)
styles into a common file and deletes the separate desktop and mobile
stylesheets. There should be no major visual changes as a result.
Having a text selection can cause issues on iOS where the caret will
show over any other element. The state is already stored in the toolbar
state so we don't need to keep it actually selected.
No test as it's a very specific behavior and a whole system spec for
this seems heavy.
In the follow cases:
- no text selection
- invalid text selection (outside of the cooked of a post)
The quote state should be cleared. This commit also adds a spec to
prevent similar regressions.
Usage:
```js
import loadFullCalendar from "discourse/lib/load-full-calendar";
const calendarModule = await loadFullCalendar();
const fullCalendar = new calendarModule.Calendar(...);
```
This will be used in discourse-calendar.
- Converts plugin apis to use transformers, so that core doesn't need to
import the admin-sidebar modules
- Adds support for admin initializers, and registers the admin sidebar
using one
- Adds support for `needs.instanceInitializer(() => { ... })` in qunit
tests, so that transformers can be registered at the right time.
(`beforeEach` is too early)
Prior to this change, off topic and something else flags did not have
the right CSS classes set resulting in the right colors not being set
for the badges used to display the flag reasons.
This commit also updates the colors used for the off topic and illegal
flags to reflect the severity. Before this change, the badge color for
illegal was green while the badge color for off topic is blue. Those
colors are too "positive".
### Screenshots
#### Before
<img width="718" alt="Screenshot 2025-07-03 at 3 22 49 PM"
src="https://github.com/user-attachments/assets/cc10d078-fe58-41aa-8c15-4bba86eb90e5"
/>
#### After
<img width="715" alt="Screenshot 2025-07-03 at 3 23 02 PM"
src="https://github.com/user-attachments/assets/e039e042-68ae-4e76-bd5a-62116ef020a3"
/>
This commit adds a `use_reviewable_ui_refresh` attribute to the
`CurrentUserSerializer` and updates the client side to use this
attribute as a feature flag to determine when the new reviewable UI
should be shown.
This is the start of the review queue redesign. Due to the rapidly
growing size of this redesign, this PR is being merged in a
semi-functional state: large chunks of it have the new design, but there
are substantial sections that may not function at all.
This PR is focussed on the variations of reviewable posts, other
reviewables (eg, users, chat messages) will continue to use the old UI.
Co-authored-by: Gary Pendergast <gary@pento.net>
The current colour palette editor has a ‘Copy to clipboard’ button on it
that copies a JSON object of the current palette’s colours. This commit
adds the button to the new colour palette UI.
The site setting hide_new_user_profiles states:
> Hide trust level 1 or lower user profiles from the public and trust level 1 users until they post for the first time.
This implies that TL2 and above should be visible.
However, the actual logic encodes the assumption that TL2 have posted at some point. This fails to account for the fact that admins can manually upgrade a user without posts to a higher TL. This PR covers for that scenario.
This PR improves the user invite list for both desktop and mobile views:
* Simplified table layout
* Better layout on mobile
* Removes extra padding and header row clutter
* Better alignment of columns and row spacing
* Keeps invite details compact but clear
* Improved group display
* Group icons and names are now properly aligned side-by-side
* Consistent inline styling for multiple groups per invite
* Updated row actions
* Moves the Remove action into a dropdown to reduce accidental clicks and keep destructive actions less prominent
* Uses consistent button styling (Edit and More actions)
* Replaces green `Illegal` badge with a deeper red to better reflect
severity
* Also updates `Off-topic` badge to a muted yellow/brown to better match
its low-priority nature
This commit replaces the `toolbar-popup-menu-options`, which used
`select-kit` with a new implementation using `dmenu`.
---------
Co-authored-by: Renato Atilio <renato@discourse.org>
Co-authored-by: Martin Brennan <martin@discourse.org>
This fixes an issue where the YouTube thumbnail was huge in a chat
transcript, like in this scenario:
* Share a link to a youtube video in channel A
* See it onebox at a reasonable size
* Grab a link to your message
* Share the link to your message in channel B (e.g. a DM to yourself)
* ❌ See GIANT youtube image
This commit only fixes the issue visually though -- it does not apply
the LazyYoutube decorations that actually embed the video. We can do
this in a followup commit.
Adding an empty href to this link makes it keyboard accessible. You can
now trigger it with the enter key. This also allows us to remove the
tabindex.

`event.preventDefault();` is neccessary because otherwise `href=""` was
resulting in a page refresh, and another work around like `href="#"` was
adding an entry to the browser history
One can use it in a plugin to override the whole "login-required"
template without having to replace all the different (and smaller)
plugin outlets already available in that template.
Internal ref - t/154909
Follow up to 0ccf792b91
In the linked commit, I moved the `AdminConfigAreaCard` component out of the
admin bundle and into the main discourse bundle to make the new
`addCardToAdminThemesGrid` API method, introduced in the same commit, work
without breaking the site for non-staff users who don't get the admin
bundle.
However, there's a better way to go about this without forcing us to
move the component file to the main bundle which is to introduce a new
`PluginOutlet` since it effectively does the same thing as the
`addCardToAdminThemesGrid` API method and it's already a well
established pattern for letting plugins customize and add content to
Discourse pages.
At this point cooked could be null and checking if it's inside a small
action is useless and would generate an error which wouldn't break
anything but is something we want to avoid.