On sites with a large amount of templates, the default display and
filter can become ineffective. By default, templates are ordered by
alphabetical title order. If filtered by keyword, the plugin does a
simple scoring based on whether the text is in the title (+2) or in the
content (+1), then by alphabetical title order. This PR updates it to
use the `usages` count, so the new priority of ordering is by score >
usage > title.
Also adds a localstorage for the selected tag used to filter the
template list. The tag field will be pre-populated with the last used
filtered tag if available.
Renames hint from "Filter by title..." to "Filter by keyword..." to
reflect actual filtering behavior.
@cvx noticed that I broke these back in February
(00907363d4). Since then, we've been
running the suite against Chrome 3 times 🤦♂️
Unfortunately the suite is no longer stable in Firefox, so it'll need
some work to get it running again. In the meantime, let's disable the
pointless jobs.
1. Patch node deprecation in http-proxy
2. Disable Discourse/Ember version logging in qunit tests
3. Disable memory-use reporting, but keep code so it can be re-enabled
when debugging
- auto submit after otp is filled on login form
- ensures input is not taking full width and we render the 1password
helper outside of the input
- ensures there's enough spacing between otp input and submit button
- changes autofocus option from autofocus to autoFocus, this is to have
parity with our autoFocus modifier
- prevents a white rectangle to appear while 1password is filling the
field
This is how it should look now:
<img width="638" height="206" alt="Screenshot 2025-11-12 at 16 48 16"
src="https://github.com/user-attachments/assets/bb367458-9959-4cae-a045-d9887ab60e71"
/>
As a follow-up of #35908.
Allow filtering posts by user from the user card of deactivated user.
### Context
The filter button was missing for deactivated accounts because
`topic_post_count` wasn’t exposed in `InactiveUserSerializer`.
### Result
<img width="701" height="216" alt="Screenshot 2025-11-14 at 00 11 27"
src="https://github.com/user-attachments/assets/e1b8d2a4-9465-4225-aaed-0582f43b8d90"
/>
Followup 782e0ea394
When we refactored the code in the above commit, we missed
the need to wrap the potentially resized image data in the
media-optimization-bundle with `Uint8ClampedArray` before
passing it to `encode` from `@jsquash/jpeg`. This led to
this cryptic error in Chrome:
```
media-optimization-worker.js:24 TypeError: Failed to construct 'ImageData': The provided value is not of type 'ImageDataSettings'.
at globalThis.optimize (media-optimization-bundle.js:116:5)
at onmessage (media-optimization-worker.js:7:42)
```
And this much more helpful error in FireFox:
```
TypeError: ImageData constructor: Argument 1 does not implement interface Uint8ClampedArray.
optimize media-optimization-bundle.js:116
onmessage media-optimization-worker.js:7
EventHandlerNonNull* media-optimization-worker.js:1
```
The difference in errors seems to be due to differences in how the
browsers
overload the `ImageData` constructor. Anyway, the fix here is to
wrap `maybeResized` in a `Uint8ClampedArray` before passing it to
`encode`, which is what we do before passing it to `resize`.
When checking how many times an email job has been retried, we need to check
that the `retry_count` attribute has been set.
In a related error, the `UserEmail` retry wait handler assumed that the
triggering exception would always have a `wrapped` attribute, which
isn't necessarily the case if the exception was raised outside of the
job execution code.
Replaced the use of computed properties with tracked properties and
added a separate `filteredWatchedWords` model to enable dynamic
filtering without altering the original dataset. Integrated
`TrackedArray` for better reactivity when managing arrays.
This improves code readability and ensures consistent state updates,
especially during bulk operations or filtering. Added new message bus
integration to efficiently handle updates after server-side word
uploads.
Refactor `SelectKit` component to use native array methods and
`@trackedArray` instead of Ember-specific utilities like `pushObject`
and `objectAt`. This enhances maintainability and simplifies the code by
aligning it closer to modern JavaScript standards. Includes updates to
methods handling `mainCollection` and `errorsCollection` logic.
First step of multiple steps in improving the new site experience. This
will make sure that when users complete the wizard, they'll end up on
the homepage. (There is a link there to the admin guide, it's one of the
first few seeded topics.)
Previously, the first check of a checkbox made sure the validation
passed. But unchecking the checkbox did not trigger the validation error
as expected.
We want to reduce noise in notifications.
In this PR, we change the notifications from opt-out to opt-in when
performing bulk actions.
To reduce churn and regression risk, it uses the same param (`silent`)
to the back-end, so it's a UI only change.
This change separates chat and other email notifications to give members
more fine-grained control over their notifications.
Includes the following changes:
- Move the Email Notifications setting from Chat preferences
(/preferences/chat) to Email preferences (/preferences/emails).
- Updates `UserOption.chat_email_frequency` description to:
> Email me when I am sent a chat direct message or group
- When `UserOption.chat_email_frequency` is set to `Only when away`,
members can receive email notifications about chat DMs / group chats
regardless of the `UserOption.email_level` value
Internal ref: /t/-/163898
We're on a quest to simplify the admin/setup experience. Part of this is
hiding overly technical/expert-friendly settings.
This PR hides more media optimization settings. The settings are still
available from console/DB for power users.
When a problem check is run with an invalid target, which can happen if
a target is dynamically removed from the list, we destroy the problem
check tracker.
This makes it so that we also clean up any associated admin notices when
this happens.
It also marks `target` as required. This is because we now use
`__NULL__` to indicate "no target". This allows us to clean up the Ruby
implementation a bit. (Context: this is required for uniqueness checks
to work, since PostgreSQL considers `NULL` values to be distinct.)
Adds six new CSS variables for the purpose of defining button types
(default, primary, danger, and success) that don't share the same border
property.
```
--d-button-default-border
--d-button-default-border--hover
--d-button-primary-border
--d-button-primary-border--hover
--d-button-danger-border
--d-button-danger-border--hover
--d-button-success-border
--d-button-success-border--hover
```
### What does this do?
This PR adds reaction data for the first post to the
`TopicListItemSerializer`, enabling reactions to be displayed on topic
lists without requiring additional API calls.
### Why is this needed?
Previously, topic lists only showed basic topic metadata. To display
reactions on the first post of each topic, plugins would need to have
the frontend make separate API calls for each topic's first post,
causing N+1 queries. This change preloads all necessary reaction data
when the topic list is serialized.
### How does it work?
- Adds `op_reactions_data` to `TopicListItemSerializer`. I added
`ReactionsSerializerHelpers` to reuse as much of the existing logic as
possible.
- Adds a `include_discourse_reactions_data_on_topic_list` modifier
(default false) for giving plugins control over the injection of the new
data.
- Includes test coverage
### Usage
From within a topic list plugin outlet, the discourse-reactions can be
displayed like so:
```gjs
<DiscourseReactionsActions
@post={{@topic.op_reactions_data}}
@showLogin={{false}}
/>
```
This PR modifies Discourse AI to provide an option for role-based auth
into Bedrock instances.
It creates a new provider_param in within aws_bedrock, called :role_arn.
If this provider_param is set, the AWSBedrock endpoint will use a
different calling pattern (sts.assume_role, etc.) to provide keyless
authentication.
<img width="455" height="311" alt="image"
src="https://github.com/user-attachments/assets/a9baa636-6768-4291-b759-d96bb77d71ef"
/>
---------
Co-authored-by: Rafael Silva <xfalcox@gmail.com>
When sending a bookmark notification and the user has opted to
automatically delete the bookmark, we should not be trying to clear the
reminder since the bookmark was just deleted.
Internal ref - t/146349
We overlooked the consequence of removing the chat icon in the header in
#35015 so this commit brings it back, in a different way.
On mobile only, the back button will save space to display the unread
indicator, if needed:
<img width="732" height="1568" alt="CleanShot 2025-11-11 at 15 53 50@2x"
src="https://github.com/user-attachments/assets/6ddff73b-3f5c-493b-ad44-ec130c8be491"
/>
As a consequence, there will be extra white-space between back-button
and channel title: this is intentional, unavoidable (alternative is
layout shift), and in line with dominating message apps.
This commit also consolidates the unread indicator styling a bit more.
- Switches to typescript 'composite project' mode for improved
organization & performance
- Generates declarations from core modules, and outputs to a new
`@discourse/types` package
- Introduces tsconfigs for core plugins, which leans on that new
`@discourse/types` package
- In future, we plan to publish this discourse-types package for other
themes/plugins to use
The motivation at this stage is primarily to improve editor
autocompletion. We provide absolutely no guarantees about the accuracy
or stability of the generated types.
For now, some issues have been resolved by adding manual `@type`
declarations.
In particular, extensionless imports of `.gjs` files are broken when
running in composite-project mode, so in those cases we have to add
manual `@type {import("./the-file.gjs").default}` declarations.
Unfortunately this failure does not show up in IDEs. We hope to get this
resolved soon.
---------
Co-authored-by: David Taylor <david@taylorhq.com>
Co-authored-by: Chris Manson <chris@manson.ie>
Avoid throwing an error in `UserPostsStream#findItems` if already
loading or unable to load more items. This improves resilience and
prevents potential uncaught exceptions during certain edge cases in user
post streams.