Commit Graph
63386 Commits
Author SHA1 Message Date
Martin Brennan d8ee96b335 FIX: Do not count deleted posts or topics in Rewind score calculation (#37434)
This fixes a missed `WHERE NOT deleted_at` condition
in the WritingAnalysis rewind report, we already had it
for the other queries here.

Also makes sure we exclude deleted topics too
2026-02-02 17:00:49 +10:00
Martin Brennan d8e47d0893 DEV: Deal with log spam for upcoming changes (#37429)
We don't need to log to such a high level (error) for
most of these service failures
2026-02-02 15:35:37 +10:00
Sam a1c2ac845d DEV: fix a large amount of typos (#37428) 2026-02-02 16:31:58 +11:00
Martin Brennan 6871c639fd FIX: Problem checks running with NO_TARGET (#37430)
Targeted checks (like the `UpcomingChangeStableOptedOut` check)
were sometimes invoked with target `NO_TARGET` when
`targets.call` returned the default `[NO_TARGET]`, so `targeted?` was
false and the guard never ran.

That led to `call()` being run with `NO_TARGET`
(e.g. `SiteSetting.send("__NULL__")`) and `NoMethodError` in the job
above.

We can skip running and enqueueing targeted checks when target is
`NO_TARGET`, it's pointless to do this since these kind of checks
are supposed to iterate over each target and run the check for that
target. This just avoids a bad/stale job issue caused by the current
logic.
2026-02-02 15:28:58 +10:00
Sam 1f0f9b1d01 DEV: Remove unused VALID_ID_REGEX constants (#37432)
These constants were defined in multiple dialect classes but
never referenced anywhere in the codebase.
2026-02-02 16:25:04 +11:00
Sam ffe0f46a6f FIX: Use valid CSS value for border-radius (#37431)
`border-radius: none` is not valid CSS. The correct way to
remove border-radius is to use `0`.
2026-02-02 16:07:35 +11:00
Martin Brennan effce878c5 FIX: Minor upcoming change bugs/edge cases (#37425)
Found with automated AI review, all legit minor issues.

* Avoid notifying admins about upcoming changes they already
  opted into
* Cache upcomingChanges getter in UI to avoid recreating TrackedObjects
* Fix previous_value not always stored in Toggle
2026-02-02 12:48:15 +10:00
Natalie Tay 9e99066b07 DEV: Expand top_tags, topic.tags, etc, to return an array of tag objects instead of tag names (#36678)
Currently in several endpoints, we return an array of strings for tags.
Our goal with this PR is to expand array tag name strings to an array of
tag objects.

#### before: Tags were returned as string arrays
```
{ "tags": ["support", "bug-report"] }
```

#### after: Tags are returned as object arrays
```
{ "tags": [{"id": 12, "name": "support", "slug": "support"}, {"id": 13, "name": "bug-report", "slug": "bug-report"}] }
```

This allows us to start referencing tags by their ids, and return more
information for a tag for future features.

This commit involves updating several areas:
- topic lists (/latest.json, /top.json, /c/:category/:id.json, etc, for
`top_tags`)
- tag chooser components (`MiniTagChooser`, `TagDrop`, etc)
- topic view (/t/:id.json)
- tag groups (/tag_groups.json, tags, parent_tag)
- category settings
- staff action logs
- synonyms
- ...

APIs that reference tags based on their names will still be supported
with a deprecation warning. Moving on, we will reference them using
their tag ids.
2026-02-02 10:03:02 +08:00
Martin Brennan 42da6860fd DEV: Migrate existing experiments to upcoming changes (#37401)
- **DEV: Migrate experimental_impersonation to upcoming changes**
- **DEV: Migrate experimental_form_templates to upcoming changes**
- **DEV: Migrate experimental_auto_grid_images to upcoming changes**
2026-02-02 11:08:12 +10:00
Jarek Radosz 4713e3abc8 DEV: Remove two unused components (#37423) 2026-02-01 12:11:02 +01:00
Jarek Radosz 7db224f32b DEV: Clean up @class usage (#37424)
Either replaces it with `class=` and `...attributes` or removes the
argument if it wasn't supported
2026-02-01 12:10:26 +01:00
Kris 7e603d4374 UX: sync up suggested topic nav colors with other nav pills (#37415)
Using some existing color variables to get these nav states for
suggested topics to have matching colors

Before:
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/227ce3c2-64a9-4be1-b8ba-f2cf31fa7c2d"
/>


After:
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/59a3a45a-a4e4-47f2-873d-3c42a9b48094"
/>


Meant to match other nav pills: 

<img width="400" alt="image"
src="https://github.com/user-attachments/assets/8b04aa7b-1fea-4bb2-b42d-81774d5dd1c6"
/>
2026-01-30 16:46:06 -05:00
Kris ec4c3cecc9 UX: remove extra line that can sometimes appear in dropdown search (#37414)
Sometimes this margin can actually wrap! which gives us a whole blank
line below a search result title

As far as I can tell, there's no inline element that comes after
`.topic-title` in
https://github.com/discourse/discourse/blob/83fd6153e9f2752094d649c8ee4a61297da86cf6/frontend/discourse/app/components/search-menu/results/type/topic.gjs
... so we can just remove this margin


<img width="500" alt="image"
src="https://github.com/user-attachments/assets/e3e261fc-1da0-4821-a8ff-9969727b19fd"
/>


<img width="500" alt="image"
src="https://github.com/user-attachments/assets/70337fab-644e-4285-8b8c-93f0021d8289"
/>
2026-01-30 16:24:33 -05:00
Kris dfbb141218 UX: quick edit textarea doesn't need to resize horizontally (#37413)
Resizing the textarea horizontally can cause overflow issues... so let's
limit it to vertical, content length in quick edits is somewhat limited
anyway.

Also noticed that this nested CSS within `.quote-button` is dead, this
was for a previous version of fast-edit that wasn't a dedicated modal.

Before:
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/2d9e280a-fdcb-4e00-8de7-9e26a87265ed"
/>


After (can only resize vertically): 
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/df6a8288-f9b9-4374-8ca3-8fe0906407a5"
/>
2026-01-30 16:24:19 -05:00
Kris 3595c7043f FIX: set locale to avoid flakiness on color spec (#37410)
Failures look like 

```
 expected: ["Default light", "Default dark", "Selectable custom scheme a", "Selectable custom scheme b", "Select...izon scheme a", "Horizon scheme b", "Foundation scheme a", "Foundation scheme b", "Light (default)"]
       got: ["Default light", "Default dark", "Selectable custom scheme a", "Selectable custom scheme b", "Select...n scheme a", "Horizon scheme b", "Clair (par défaut)", "Foundation scheme a", "Foundation scheme b"]
```

This ensures it's always sorting in English to avoid it... I think
@ZogStriP pointed this out before, and I didn't think it would happen,
but it does 😭
2026-01-30 16:23:45 -05:00
Kris b80d894b6d UX: switch header and sidebar footer buttons to focus-visible (#37412)
Sometimes a header button can have lingering focus after it's used — the
change to focus-visible ensures the focus state is only visible when
desired, like when using keyboard nav

Before (after toggling):
<img width="255" alt="image"
src="https://github.com/user-attachments/assets/acc856c8-8d80-4ee5-8190-785f11105da1"
/>

After (also after toggling):
<img width="255" alt="image"
src="https://github.com/user-attachments/assets/f18e3830-ec2d-46b9-a7e0-9d88a8f79b48"
/>

Also fixed this same issue for the sidebar footer while I was at it!
2026-01-30 15:13:17 -05:00
Kris 9586fc7506 UX: fix route loading spinner alignment (#37411)
Before:
<img width="350" alt="image"
src="https://github.com/user-attachments/assets/9e02a5c2-4975-4575-bd98-29e4577c3eb1"
/>


After: 
<img width="359" alt="image"
src="https://github.com/user-attachments/assets/c5149081-17c9-469e-8217-4bed5dcaeb23"
/>
2026-01-30 15:13:06 -05:00
Keegan George 1efd0d6643 FEATURE: Include PR number in the GitHub PR oneboxes (#37409)
## 🔍 Overview
This update shows the pull request number inside the GitHub PR onebox.
This makes it easy to look at a onebox and quickly use the `gh` CLI to
`gh pr checkout` into a PR without needing to open the PR link first.

## 📷 Screenshots

### ← Before
<img width="712" height="469" alt="before-pr-onebox"
src="https://github.com/user-attachments/assets/cd66ca98-21a7-43c2-9b0e-b1b1b9235fc6"
/>

### → After
<img width="726" height="495" alt="after-pr-onebox"
src="https://github.com/user-attachments/assets/abd7b491-e334-4efd-8254-b1da4b33aa4a"
/>
2026-01-30 11:17:57 -08:00
Jake Goldsborough f4a7f213f0 FEATURE: Warn admins when QQ Mail SMTP is configured
QQ Mail (smtp.qq.com and smtp.exmail.qq.com) is known to cause duplicate
email issues with Discourse. The SMTP server does not return proper
acknowledgments, causing Discourse to retry sends that already succeeded.

This adds a ProblemCheck that displays a warning on the admin dashboard
when QQ Mail SMTP is detected, linking to recommended alternatives.
2026-01-30 16:39:24 +00:00
Kris 0542764723 UX: track category group permissions for experiemental new category feature (#37406)
Currently when you add groups to the access field of the experimental
general tab, you can't then edit the permissions from the security tab.
These need to be tracked (like they are in the category model) so the
group permissions on the general tab can sync up.

Also fixed a minor CSS issue I noticed with the color swatch

before:
<img width="250" alt="image"
src="https://github.com/user-attachments/assets/8fa70cef-b625-4c26-9e9b-2aab2fa4295a"
/>


after: 
<img width="250" alt="image"
src="https://github.com/user-attachments/assets/e70e7d41-8c63-414c-af23-f816855c7a60"
/>
2026-01-30 11:15:22 -05:00
David Battersby 93eec3c454 FEATURE: mark topic as solved confetti (#37403)
Makes the Discourse Solved experience a little more fun by adding a
confetti burst when selecting answers to questions that are more than 1
week old.

How it looks:



https://github.com/user-attachments/assets/a2bade25-1088-4049-85c0-890ae63b0b21
2026-01-30 12:56:53 +04:00
Martin Brennan 89f9423e4a DEV: Fix upcoming change specs (#37399)
These broke as a result of 60259dd453,
the specs changed a little because
b8672b3dfb
was merged beforehand. We were getting an error because the instance
of site settings in site_setting_extension_spec was not the same
as SiteSetting called by the UpcomingChanges module.

We can stub it in the spec, so both refer to the same instance,
otherwise things will get complicated fast. We have other specs
that cover the behaviour correctly.

Also cleaned up TODOs from the previous commit that intended
to call UpcomingChanges.resolved_value when it was ready
2026-01-30 13:59:22 +10:00
Martin Brennan 60259dd453 DEV: Implement depends_behavior for depends_on in site settings (#37370)
Followup 12fdb69279

We introduced `depends_on` in the above commit for site settings,
where you can define one or more boolean site settings that a given
setting depends on. However, this was only used for a dependency
graph, and did not have an effect on the UI.

This commit introduces `depends_behavior`, which can be set to
`hidden` only for now. When a setting has `depends_behavior: hidden`
and one of its `depends_on` settings is false, the setting will be
hidden from the UI.

This will be useful for upcoming changes, where we want to hide
certain site settings if the upcoming change is not enabled.
2026-01-30 13:06:46 +10:00
Martin BrennanandLoïc Guitaut b8672b3dfb DEV: Move upcoming change tracking and promotion out of initializers (#37283)
There are several problems with running these upcoming change
checks added in
https://github.com/discourse/discourse/commit/fb9bb3198384b76af9947ad011dda86885e6c536:

* The app is slower to boot because there is DB work to be done
* We sometimes swap out database configs at runtime in our hosting,
  which does not call the initializer again
* We have to think about readonly states for the DB
* There are race conditions because of blue-green deployments
  to consider

To solve these problems, we move the tracking and promotion into
a scheduled job that runs every twenty minutes, since the notification
of admins about upcoming changes are not time-sensitive. This avoids
a whole host of problems.

In addition, we are making upcoming change settings declarative
via SiteSettingExtension. Now, instead of actually changing the DB
value of the change when promoting, we just return true for the
setting if it has met the promotion status. However, if admins have
changed the value of the setting in the DB, we do still use that
value instead. Finally we fall back to the default value of the setting.

I've also added a change to track modified site settings. Before this we
had no way to tell if a setting in `current` inside
`SiteSettingExtension`
was modified by an admin or not. This change tracks modified settings in
a new
`modified` object and their values.

---------

Co-authored-by: Loïc Guitaut <loic@discourse.org>
2026-01-30 12:50:39 +10:00
Kris 55f6b9fd38 UX: further simplify experimental category creation (#37398)
This simplifies the experimental category creation general tab by:
* reducing the group permissions to a single step, if someone wants more
finite control they can use the security tab
* hides category descriptions from the subcategory dropdown

I've also made it so when adding a private parent category, you can only
select groups allowed to access the parent for the subcategory. This
avoids an awkward error message explain that you can't make
subcategories more permissive than the parent.
2026-01-30 12:25:04 +10:00
Jarek RadoszandKeegan George d6d3fc8629 DEV: Convert CustomHtml to glimmer/gjs (#37397)
Co-authored-by: Keegan George <kgeorge13@gmail.com>
2026-01-30 01:57:06 +01:00
Jarek Radosz 0c1a658f28 DEV: Convert HtmlWithLinks to glimmer/gjs (#37389) 2026-01-30 01:34:45 +01:00
Régis Hanol b1d31caaef DEV: Clean up ThemeSettingsMigration records in test suite setup (#37376)
Running `RAILS_ENV=test bin/rails db:migrate` could fail with:

    Theme::SettingsMigrationError:
    Migration '0001-convert-topic-card-context-to-boolean' is out of
    sequence. The last migration for this theme had version number 1
    which is higher than the new migration

This occurred because of orphaned `ThemeSettingsMigration` records in
the test database.

Root cause:
The `before(:suite)` block in `spec/rails_helper.rb` calls
`ThemeField.delete_all` but did not delete the associated
`ThemeSettingsMigration` records. This left orphaned records where
`theme_field_id` references a non-existent `ThemeField`.

When `db:migrate` runs seeds and syncs system themes, the migration
runner finds:
- A "pending" migration (new ThemeField has no ThemeSettingsMigration)
- But `current_migration_version = 1` from the orphaned record
- Since version 1 <= 1, it errors with "out of sequence"

How to reproduce (before this fix):
```
RAILS_ENV=test bin/rails db:drop db:create db:migrate
bin/rspec spec/models/theme_spec.rb  # any spec triggers before(:suite)
RAILS_ENV=test bin/rails db:migrate  # fails
```

This commit:
1. Adds `ThemeSettingsMigration.delete_all` to the test suite setup to
clean up migration records alongside theme fields
2. Adds `dependent: :destroy` to the ThemeField association as a safety
net for any code path that destroys ThemeFields via ActiveRecord
2026-01-30 00:24:13 +01:00
Jarek Radosz 513c09ebe3 DEV: Remove deprecated hbs support from CustomHtml (#37391)
Previously deprecated 3 years ago in
https://github.com/discourse/discourse/pull/20264
2026-01-30 00:06:21 +01:00
Kris ca48d4728a FIX: update tag drop to reference name instead of ID (#37395)
The tag dropdown is missing an active state on the currently selected
tag, this fixes it
2026-01-29 17:53:42 -05:00
Jarek Radosz 7613bc6316 DEV: Convert VersionChecks to glimmer (#37390) 2026-01-29 23:47:23 +01:00
Jarek Radosz d1e581209e DEV: Convert SubscribeCard to glimmer/gjs (#37388) 2026-01-29 23:47:09 +01:00
Jarek Radosz dd987b90ee DEV: Remove unused components (#37387) 2026-01-29 23:46:58 +01:00
Jake Goldsborough e817cf6f47 FIX: Use safe navigation for MIME lookup in backup upload
MiniMime.lookup_by_filename can return nil if the extension is not
recognized. Other code in the codebase uses safe navigation (&.) for
this call, but backup_restore/creator.rb did not.

This adds safe navigation with a fallback to "application/gzip" since
backup files are always .tar.gz or .sql.gz.
2026-01-29 22:22:00 +00:00
Kris ea0d445546 FIX: reapply missing CSS for topic-replies-toggle (#37393)
Unintentionally removed this CSS in
1880ad8e74, this adds it back


Before:
<img width="350" alt="image"
src="https://github.com/user-attachments/assets/8af9c033-2aa9-41c5-bb33-957bdb67a728"
/>


After: 
<img width="350" alt="image"
src="https://github.com/user-attachments/assets/7fb140a1-4919-42ce-a4ac-ba4782cc19ae"
/>
2026-01-29 17:06:03 -05:00
Loïc Guitaut aaadd98603 DEV: Allow to filter backtrace in exceptions caught in services (#37382) 2026-01-30 07:59:13 +10:00
Kris 08f7b5f36a UX: admin report heading alignment adjustments, reactions report fix (#37392)
Improves alignment of the headings by absolutely positioning the caret
for sorting and resolving a couple other minor issues. Also fixed broken
headings in a reactions report.

Before:
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/d0b6543a-52cf-4c59-8b70-2b25dbf89b6d"
/>


After: 
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/fb5272d5-8b0d-478a-b50e-aff353d617c6"
/>


Before:
<img width="500" alt="image"
src="https://github.com/user-attachments/assets/779d3c11-27c2-4112-b9b9-bf79ca0dc31e"
/>


After:
<img width="500" alt="image"
src="https://github.com/user-attachments/assets/1e179cb1-b885-4233-958e-d38c41abe3cb"
/>




Before: 
<img width="1198" height="346" alt="image"
src="https://github.com/user-attachments/assets/cc9c5af7-3047-4e91-b274-81c31506b751"
/>


After: 
<img width="1222" height="438" alt="image"
src="https://github.com/user-attachments/assets/ce71e5b5-0adc-4391-9f9c-449b8a06d25f"
/>
2026-01-29 14:22:05 -05:00
Jake Goldsborough 66e4ac59de DEV: Handle filesystem hardlink limits during backup deduplication
When the hardlink limit is reached (Errno::EMLINK), copy the file locally
and use the copy as the new primary for subsequent hardlinks. This avoids
re-downloading from S3 and works regardless of filesystem type.

Previously, hitting the limit would fall back to downloading each remaining
file individually. Now we detect the specific error and handle it gracefully
by copying the already-downloaded file.

Added :copied stat to track when this fallback is used.
2026-01-29 18:49:09 +00:00
Penar Musaraj 7e3b5cc490 UX: Fix color-palette input styling on non-default themes (#37386)
Saw an issue while working on a local theme with strong rounded corners
and a larger font size. This fixes that issue without affecting
Foundation or Horizon.

<img width="600" alt="CleanShot 2026-01-29 at 12 40 49@2x"
src="https://github.com/user-attachments/assets/f23d008b-9f2f-4d48-9561-d5701f0bb5b4"
/>
2026-01-29 13:27:13 -05:00
Kris ea7e0d88df UX: hide the composer grippie in the saving state (#37385)
The grippie shouldn't appear here and the spinner can be centered with
the text

Before:
<img width="1372" height="118" alt="image"
src="https://github.com/user-attachments/assets/20081b2a-066e-44a6-a4e8-6272a45b226a"
/>


After:
<img width="1596" height="192" alt="image"
src="https://github.com/user-attachments/assets/bebf77b0-5183-40a8-a2cc-ba8521245927"
/>
2026-01-29 12:49:10 -05:00
Kris 52db81bd55 UX: update formkit validation summary error styles, improve danger-low contrast (#37362)
Generally styling our formkit validation error summary to be smaller and
simpler — removing the icon, smaller text to match the form labels,
width to match inputs. Also included a singular version in addition to
the plural error text.

I've adjusted our danger-low color globally to be *slightly* lighter,
which helps with improving the contrast of links against it.

Before: 

<img width="600" alt="image"
src="https://github.com/user-attachments/assets/bf46268d-fbe1-4fec-8a9d-f4645baf8648"
/>



After: 

<img width="380" alt="image"
src="https://github.com/user-attachments/assets/cf276ebc-65d5-4221-a98c-54e453168e69"
/>
2026-01-29 12:38:06 -05:00
Rafael dos Santos Silva e9fcab6675 DEV: Await async button actions in chat composer dropdown (#37384)
Fixes GIF modal not displaying when triggered from chat composer
dropdown on mobile.

Async button actions were not being awaited, causing potential timing
issues when the dropdown modal closes and another modal opens.
2026-01-29 14:20:48 -03:00
Jarek Radosz 5058610ad3 DEV: Lint-to-the-future ember/no-side-effects (#37380) 2026-01-29 15:25:27 +01:00
Jarek Radosz 75650d306c DEV: Refactor ai-category-suggester (#37379)
Similar to #37365 and #37366, mostly to fix `ember/no-side-effects` lint
in `showSuggestionButton` getter
2026-01-29 14:17:16 +01:00
Jarek Radosz 06b80444a8 DEV: Refactor ai-tag-suggester (#37366)
Similar to #37365, mostly to fix `ember/no-side-effects` lint in
`showSuggestionButton` getter
2026-01-29 12:41:28 +01:00
Jarek Radosz 4662ad419a DEV: Remove the deprecated UserStreamItem component (#37367) 2026-01-29 12:35:43 +01:00
Arpit Jalan 01cdbcf413 FIX: do not remove uploads from posts that are still in review queue (#37372)
The "Remove upload markup from deleted posts" automation was incorrectly
processing posts that were deleted but still had pending reviewables in
the review queue.

Scenario: When a post is flagged (hidden from public) and the author
subsequently deletes it, the post has both `hidden: true` and
`deleted_at` set. The automation would strip upload markup from these
posts, causing data loss when moderators later restored them after
completing their review.

This fix adds a NOT EXISTS clause to exclude any post with a pending
reviewable targeting it. The automation will now wait until the review
is resolved (approved/rejected/ignored) before processing the post.
2026-01-29 17:00:33 +05:30
Jarek Radosz 4dd917c819 DEV: Refactor ai-title-suggester (#37365)
Mostly to fix `ember/no-side-effects` lint in `showSuggestionButton`
getter
2026-01-29 12:19:26 +01:00
Régis Hanol 8de9ea2fc3 FIX: Modal-based chat composer buttons not working on mobile (#37378)
Commit 9cbb0c3da3 fixed Safari file uploads by removing async/await from
the button click handler, but this introduced a regression: modal-based
buttons (like "Insert date/time") stopped working on mobile.

The issue is a race condition where the modal tries to open while the
dropdown menu modal is still closing, causing the new modal to be
dismissed immediately.

This fix introduces a `synchronous` property for chat composer buttons:

- `synchronous: true` - action runs immediately without awaiting the
menu close (required for file inputs on Safari)
- `synchronous: false` (default) - awaits menu close before running
action (required for modal-based buttons)

The upload button is marked with `synchronous: true` to preserve the
Safari fix, while all other buttons use the default async behavior.
2026-01-29 11:20:56 +01:00
Natalie Tay d47a9a9da1 FIX: Parent tag auto-addition now respects category (settings) (#37373)
When a tag belongs to multiple tag groups (each restricted to different
categories), the parent tag auto-addition logic was adding parent tags
from ALL tag groups—including those restricted to unrelated categories.

For example, a generic tag like "cost" in tag groups across "Finance",
"Sales", and "Engineering" categories would cause parent tags from wrong
categories to appear when editing topics.

The fix filters parent tags based on category context:
1. Category with no tag restrictions: Only include parent tags from tag
groups not restricted to any category
2. Category with tag restrictions:
- If "allow global tags" is enabled: Include parent tags from both
global and category-specific tag groups
- If "allow global tags" is disabled: Only include parent tags from tag
groups restricted to that category

t/394023/7
2026-01-29 18:18:03 +08:00