Why this change?
Returning an array makes it hard to immediately retrieve a setting by
name and makes the retrieval an O(N) operation. By returning an array,
we make it easier for us to lookup a setting by name and retrieval is
O(1) as well.
This commit sets a default of 0px for `--footer-nav-height` and set it only when `body.footer-nav-visible` allowing us to safely use `--footer-nav-height` wherever it will be needed if set.
This change removes the regex we used previously, which only allowed ASCII characters in fast-edit. Now multi-language content can be used with fast-edit.
It also removes the string replacement we relied on in the past to catch various forms of punctuation marks, as this no longer appears necessary (possibly since this component was updated to use Glimmer).
The `deprecate_column` helper would change its behavior based on the current `Discourse::VERSION`. This means that 'finalizing' a stable release introduces a previously untested behavior change.
Much better to keep it as a deprecation until manual action is taken to introduce the breaking change.
These routes were previously rendered using Rails, and had a fairly fragile 2fa implementation in vanilla-js. This commit refactors the routes to be handled in the Ember app, removes the custom vanilla-js bundles, and leans on our centralized 2fa implementation. It also introduces a set of system specs for the behavior.
Internal links always notify and add internal connections in topics.
This adds a special feature that lets you append `?silent=true` to a link
to have it excluded from:
1. Notifications - users will not be notified for these links
2. Post links below posts in the UI
This is specifically useful for large reports where adding all these connections
just results in noise.
Safari has a bug which means that scripts with the `defer` attribute are executed before stylesheets have finished loading. This is being tracked at https://bugs.webkit.org/show_bug.cgi?id=209261.
This commit works around the problem by introducing a no-op inline `<script>` to the end of our HTML document. This works because defer scripts are guaranteed to run after inline scripts, and inline scripts are guaranteed to run after any preceding stylesheets.
Technically we only need this for Safari. But given that the cost is so low, it makes sense to include it everywhere rather than incurring the complexity of gating it by user-agent.
Running Discourse 3.2 stable under Ember 3 will technically be possible, but is only intended as a short-term migration point. This commit adds an admin warning for sites which are using this configuration, to make it clear that themes and plugins are unlikely to support the configuration.
https://meta.discourse.org/t/287211
In a handful of situations, we need to verify a user's 2fa credentials before `current_user` is assigned. For example: login, email_login and change-email confirmation. This commit adds an explicit `target_user:` parameter to the centralized 2fa system so that it can be used for those situations.
For safety and clarity, this new parameter only works for anon. If some user is logged in, and target_user is set to a different user, an exception will be raised.
When exporting a csv file and the size of the file exceeded the
max_export_file_size_kb it will still send the PM that the export
succeeded with a broken link to a missing export file. This change
ensures that a failed message will be sent instead.
* Revert "FEATURE: Use native number fields for integer inputs (#24984)"
This reverts commit 8fce890ead.
* FIX: Deprecate NumberField, use <input> instead
This reverts #24984 as it introduced regressions (behavioral and visual) and instead it deprecates the NumberField component and replaces its uses in core with native `<input>` elements.
CategoryRow component uses allowUncategorized SelectKit option to
decide whether to show the "Uncategorized" category or not. This was
undefined which lead to "Uncategorized" category being always hidden
causing a minor visual glitch.
Currently when exporting a list of users and there is an error we just
log that there was an error, but we don't show what the issue is in the
logs which makes it really hard to debug in production. This change will
output any errors to the logs.
Some parts of our code (e.g. some types of reviewable) set `topic.category`. In the past this would override the computed property value, but with recent Ember it raises an error. This commit adds a setter which handles the situation cleanly
Having the admin sidebar code in an instance initializer is not
ideal because:
* It runs during app boot which may not even be necessary based on site settings
* It makes it hard for plugins to register additional links in time without resorting
to before/after initializer gymnastics
This PR moves the admin sidebar into a lib and creates the panel
in custom-sections.js, then the sections and links are loaded when
the main sidebar component is rendered, which leaves plugins enough
time to add additional links in an initializer.
---------
Co-authored-by: David Taylor <david@taylorhq.com>
We want to exclude the system user from group user counts, since intuitively admins wouldn't include them.
Originally this was accomplished by booting said system user from the groups, but this is causing problems, because the system user needs TL group membership to perform certain tasks.
After this PR, system user is still in the TL groups, but excluded when refreshing the user count.
Previously, it was not possible to modify the sorting order of the `TopicQuery` result from a plugin. This feature adds support to specify custom sorting functionality in a plugin. We're using the `apply_modifier` method in the `DiscoursePluginRegistry` module to achieve it.
Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
Some preparatory refactoring as we're working on TL groups for the system user. On User we have a scope #human_users to exclude the system user, DiscoBot, etc. This PR adds the same scope (delegated to User) on Group.
* FIX: Minor bookmark issues
* We were showing "missing %{name} value" when the name for the
bookmark was undefined with title translations
* There was no way to see the bookmark details on hover in chat
for a message where the bookmark icon was in the left gutter.
We can show the title on the bookmark button in the chat message
actions instead.
* Minor fix
* DEV: Test fix
We added support for radar type charts in #24274. However, radar charts work with three variables, meaning we can't display any report that way.
Unfortunately, by adding `:radar` to the `Report#modes` variable, I made them widely available.
Related bug report: https://meta.discourse.org/t/report-radar-graph-uncaught-typeerror/292360
The keydown event fires as soon as the key is pressed down. This is often preferred for actions that need to occur immediately, like stopping a process, closing a modal window, or canceling an ongoing operation. The immediacy of keydown makes it more responsive, as the user doesn't have to fully press and release the key.
Moreover, it allows us to not close chat on escape when the search menu is open.
This is a temporary fix to address an issue where the
system user is losing its automatic groups when the server
is running. If any auto groups are provided, and the user is
a system user, then we return true. The system user is admin,
moderator, and TL4, so they usually have all auto groups.
We can remove this when we get to the bottom of why the auto
groups are being deleted.
We're changing the implementation of trust levels to use groups. Part of this is to have site settings that reference trust levels use groups instead. It converts the min_trust_level_for_user_api_key site setting to user_api_key_allowed_groups.
This isn't used by any of our plugins or themes, so very little fallout.
The old strategy used to load 25 categories at a time, including the
subcategories. The new strategy loads 20 parent categories and at most
5 subcategories for each parent category, for a maximum of 120
categories in total.
- Decrease gravity, we come in too hot prioritizing too many new topics
- Remove all muted topics / categories and tags from the hot list
- Punish topics with zero likes in algorithm
This introduces a new experimental hot sort ordering.
It attempts to float top conversations by first prioritizing a topics with lots of recent activity (likes and users responding)
The schedule that updates hot topics is disabled unless the hidden site setting: `experimental_hot_topics` is enabled.
You can control "decay" with `hot_topic_gravity` and `recency` with `hot_topics_recent_days`
Data is stored in the new `topic_hot_scores` table and you can check it out on the `/hot` route once
enabled.
---------
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
Previously only Sidekiq was allowed to generate more than one optimized image at the same time per machine. This adds an easy mechanism to allow the same in rake tasks and other tools.
Why this change?
The `Table Builder when editing a table when cancelling table creation should close the modal if there are no changes made` system
test in `spec/system/table_builder_spec.rb` was flaky. It turns out that
when the modal is opened, we have to load some JS/CSS files. While that
is happening, the modal is actually not functional and clicking stuff
in the footer can actually result in an error. In this case, the
`interceptCloseModal` calls the private `_hasChanges` function which
then calls `this.spreadsheet.getHeaders()`. When stuff is still loading,
`this.spreadsheet` has not been set. As a result we get the following
error:
```
Cannot read properties of null (reading 'getHeaders')
```
What does this change do?
Why stuff is loading, we will now hide the footer in the modal.
Why this change?
While the constant does not change very often, we should still avoid
duplicating the value of a constant used on the server side in the
client side to avoid the values going out of sync.
Why this change?
Currently, is it hard to iteratively write a theme settings migrations
because our theme migrations system does not rollback. Therefore, we
want to allow theme developers to be able to write QUnit tests for their
theme migrations files enabling them to iteratively write their theme
migrations.
What does this change do?
1. Update `Theme#baked_js_tests_with_digest` to include all `ThemeField`
records of `ThemeField#target` equal to `migrations`. Note that we do
not include the `settings` and `themePrefix` variables for migration files.
2. Don't minify JavaScript test files becasue it makes debugging in
development hard.
Some attributes of the microdata schema `DiscussionForumPosting` are rendered in the context of the first post.
Ensure these attributes are also set if the first post is not part of the current view.
* Ensure consistent `datePublished` and remove `text` on second page in topic microdata schema
Always use `datePublished` from topic and never from `first_psot`. This ensures `datePublished` to be consistent on `first page` and `page=2+`.
No need to repeat `text` on `page=2+`. Especially do not set `text` on `page=2+` if it is only an abstract and thereby not 100% consistent with `text` on `first page`.
* Keep `text`attribute on follow-up pages
Why this change?
We have been chasing a problem with our flaky system test where the user
is logged out when it should never be.
What does this change do?
1. Logs the request path when lookup a user auth token.
2. Logs the request path and also the current thread's object id in
ActiveRecord query logs.
This commit makes it so the admin sidebar (when enabled)
will hide the other forum sidebar sections on mobile, the
same way it does on desktop. It was not happening automatically
because the sidebar component is also inside the hamburger-dropdown
component, which is used on mobile.
Why this change?
This is a follow up to cc917a1d7f. It has
been identified that there is a circular dependency issue in our Ember
app with the user topic list route and it looks something like this:
1. `controllers/user-topics-list` imports `routes/build-private-messages-route`
2. `routes/build-private-messages-route` imports
`routes/user-topic-list`
3. `routes/user-topic-list` imports `controllers/user-topics-list`
This caused some weird problems in production where stuff would just not
load.
What does this change do?
1. Move `QUERY_PARAMS` from `controllers/user-topics-list` to
`routes/user-topic-list` which is the more apprioriate place for the
query params to be declared since they are route query params
after all.
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
This commit adds some more links to the admin sidebar and
removes some to give it more parity with the old nav structure.
This also adds the `addAdminSidebarSectionLink` plugin API to
replace the admin-menu plugin outlet, which is used by plugins
like docker-manager to add links to the old admin nav.
* UX: add sorting params to groups table plugin outlet
* FEATURE: allow sorting group members by custom field via API
---------
Co-authored-by: Jean Perez <jmperez127@gmail.com>
* FIX: respect creation date when paginating group activity posts
There are scenarios where the chronological order of posts doesn't match the order of their IDs. For instance, when moving the first post from one topic or PM to another, a new post (with a higher ID) will be created, but it will retain the original creation time.
This PR changes the group activity page and endpoint to paginate posts using created_at instead of relying on ID ordering.
This code introduces code duplication but category dropdown are a common performance area and we expect that having category rows as a glimmer template will improve performance when hundred of rows are rendered.
In the future we should investigate creating a base select-row component using glimmer to ease the migration.
The UI is randomly breaking while generating the messages menu in the user profile when we use the old class format. And it happens only when the `navigation_menu` site setting value is set to `header dropdown`. Users reported issues in some other random cases too.
Why this change?
Importing theme with the `bundle` params is used mainly by
`discourse_theme` CLI in the development environment. However, we do not
want migrations to automatically run in the development environment
and instead want the developer to be intentional about running theme
migrations. As such, this commit adds support for a
`skip_migrations` param when importing a theme with the `bundle` params.
This commit also adds a `migrated` attribute for migrations theme fields
to indicate whether a migrations theme field has been migrated or not.
Followup to be841e666e,
this commit does not show the themes/components list filter
if there are < 10 items in the list. This brings parity
with the search input, which does the same. If you only have
a few themes/components, then this extra UI is just unnecessary.
---------
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
When navigating straight to a topic the category was not displayed at
all because the categories were not loaded. Similarly, the categories
for suggested topics were not loaded either.
This commit adds a list of categories to topic view model class and
serializer.
The query that is now a subquery could return a long list of category
IDs, which slowed down the query considerably. This improvement reduces
the execution time from over 2 seconds down to about 100ms.
The list of categories is loaded async when lazy_load_categories is
enabled, but there is no visual indication that the list of categories
is being loaded.
Parsing html, modifying it, and then serializing had some negative side-effects (namely, it was losing html entity escaping in some cases)
Drops jsdom dependency
Merges the design experiment at
https://meta.discourse.org/t/post-quote-copy-to-clipboard-button-feedback/285376
into core.
This adds a new button by default to the menu that pops up when text is
selected in a post.
The normal Quote button that is shown when selecting text within a post
will open the composer with the quote markdown prefilled.
This new "Copy Quote" button copies the quote markdown directly to the
user’s clipboard. This is useful for when you want to copy the quote
elsewhere – to another topic or a chat message for instance – without
having to manually copy from the opened composer, which then has to be
dismissed afterwards. An example of quote markdown:
```
[quote="someuser, post:7, topic:285376"]
In this moment, I am euphoric.
[/quote]
```
* FEATURE: Cache embed contents in the database
This will be useful for features that rely on the semantic content of topics, like the many AI features
Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com>
In this PR we introduced the enabled/disabled components filter.
https://github.com/discourse/discourse/pull/25105
However, components are slightly more complicated and can be used/unused/enabled/disabled.
- Convert group based `experimental_search_menu_groups_enabled` site setting to be a _hidden_ boolean `experimental_search_menu` setting.
- Make default `true`
- Remove widget search menu tests
Discourse Encrypt Test Failure Fix - https://github.com/discourse/discourse-encrypt/pull/301
Ported from d95706b25a
This is enabled by default, but can be disabled via the `warn_critical_js_deprecations` hidden site setting.
The `warn_critical_js_deprecations_message` site setting can be used by hosting providers to add a sentence to the warning message (e.g. a date when they will be deploying the Ember 5 upgrade).
Followup to b92993fcee
I ran out of time to get this working for that fix,
also here I am making the post.url method have parity
with post.shareUrl in JS, which omits the post number
for the first post.
Currently, when bulk uploading and multiple uploads fail, we show a number of dialogs in quick succession. This is of course a terrible user experience.
With this change, we buffer the error messages until there are no more pending uploads. Then we combine the buffered errors and display a single dialog with a list of failed files.
* add cc addresses and post_id to sent email logs
* sort cc addresses by email address filter value and collapse additional addreses into tooltip
* add slice helper for use in ember tempaltes
* FIX: never skip push notifications
According to Apple, silent push notifications are automatically punished per:
https://developer.apple.com/videos/play/wwdc2022/10098/?time=814
> As mentioned when I showed you the code on how to request a push
> subscription, you must promise that pushes will be user visible.
> Handling a push event is not an invitation for your JavaScript to
> get silent background runtime. Doing so would violate both a user’s
> trust and a user’s battery life. When handling a push event, you are
> in fact required to post a notification to Notification Center.
> Other browsers all have countermeasures against violating the promise
> to make pushes user visible, and so does Safari.
> In the beta build of macOS Ventura, after three push events where you
> fail to post a notification in a timely manner, your site’s push
> subscription will be revoked. You will need to go through the permission
> workflow again.
The isIdle check was causing certain push notifications to be silent
Additionally, the auto dismissal logic was causing delays which may cause
the device to think the push was a silent one.
By removing this we hope to ensure push notification delivery is more robust
and consistent on iOS.
Having separate mobile/desktop templates is something we're moving away from. This commit moves the mobile-specific logic into a conditional in the main colocated template.
Previously it was relying on the `templates/mobile` logic to make this a simple div wrapper on mobile, and a more complex implementation on mobile. This commit colocates the template so it's active on mobile and desktop, but adds an `{{#if` block to explicitly change the behavior.
In Ember, these deprecations are wrapped in an `if(DEBUG)` check, so they are optimized out of the production build. We prefer to keep deprecations in production so that we can collect telemetry and warn theme authors who do not use local development environments.
This commit restores the deprecations as part of our ember-production-deprecations addon.
Currently, the reviewable queue includes ReviewableFlaggedPost with posts that have already been hidden. This allows for such hidden posts to be cleared up by the auto-tool.
Why this change?
A system test which was testing our ability to add a form template to a
category was flaky. This turned out to be a client side bug where the
`FormTemplateChooser` dropdown may not display any dropdown options if
the ajax request to fetch the categories form template has not been
completed when the dropdown is opened.
What does this change do?
Make use of select-kit's `triggerSearch` function to fetch the records
which will properly rerender the dropdown options.
post action feedback is the mechanism in which we provide visual feedback
to the user when a post action is clicked, in cases where the action is a
background (hidden to user) for example: copying text to the clipboard
Core uses this to share post links, but other plugins (for example: AI) use
this to share post transcripts via the clipboard.
This adds a proper plugin API to consume this functionality
`addPostMenuButton` can provide a builder that specified a function as the action.
This function will be called with an object that has both the current post and a method for showing feedback.
`window.deprecationWorkflow` does not exist in the server-side pretty-text environment. This commit fixes the check and adds a general spec for deprecations triggered inside pretty-text
- Add plugin outlet to `AdminUserFieldItem`
- Add ability to include custom fields when saving `AdminUserFieldItem`
- Update plugin API with `includeUserFieldPropertiesOnSave` per ☝️
- Add `DiscoursePluginRegistry` to `UserFieldsController` to add custom columns
Categories will no longer be preloaded when `lazy_load_categories` is
enabled through PreloadStore.
Instead, the list of site categories will continue to be populated
by `Site.updateCategory` as more and more categories are being loaded
from different sources (topic lists, category selectors, etc).
In non secure contexts (HTTP vs HTTPS) which many run in development the
`clipboardCopy` method falls back to and an exec hack.
However, callers expect a promise from this method and the fallback just
returns a boolean.
This change passes down all params to the home logo widget (rather than explicitly setting minimized). This will allow for flexible logo sizing in the Discourse full width theme component.
This change simplifies the layout of our header when chat is open on mobile. The search icon and hamburger menu icons are also hidden and the Discourse logo is replaced by a ← Forum link to make it easier to continue where you left off within the forum (prior to this update the user could only go back to the forum index page).
Why this change?
On CI, we have been seeing the "handles job concurrency" job timing out
on CI after 45 seconds. Upon closer inspection of `Jobs::Base#perform`
when cluster concurrency has been set, we see that a thread is spun up
to extend the expiring of a redis key by 120 seconds every 60 seconds
while the job is still being executed. The thread looks like this before
the fix:
```
keepalive_thread =
Thread.new do
while parent_thread.alive? && !finished
Discourse.redis.without_namespace.expire(cluster_concurrency_redis_key, 120)
sleep 60
end
end
```
In an ensure block of `Jobs::Base#perform`, the thread is stop by doing
something like this:
```
finished = true
keepalive_thread.wakeup
keepalive_thread.join
```
If the thread is sleeping, `keepalive_thread.wakeup` will stop the
`sleep` method and run the next iteration causing the thread to
complete. However, there is a timing issue at play here. If
`keepalive_thread.wakeup` is called at a time when the thread is not
sleeping, it will have no effect and the thread may end up sleeping for
60 seconds which is longer than our timeout on CI of 45 seconds.
What does this change do?
1. Change `sleep 60` to sleep in intervals of 1 second checking if the
job has been finished each time.
2. Add `use_redis_snapshotting` to `Jobs::Base` spec since Redis is
involved in scheduling and we want to ensure we don't leak Redis
keys.
3. Add `ConcurrentJob.stop!` and `thread.join` to `ensure` block in "handles job concurrency"
test since a failing expectation will cause us to not clean up the
thread we created in the test.
When setting an old TL based site setting in the console e.g.:
SiteSetting.min_trust_level_to_allow_ignore = TrustLevel[3]
We will silently convert this to the corresponding Group::AUTO_GROUP. And vice-versa, when we read the value on the old setting, we will automatically get the lowest trust level corresponding to the lowest auto group for the new setting in the database.
With certain conditions, this issue does not show up. The easiest way to reproduce this is probably to do either of this
- Use a 3G slow connection or;
- Add a breakpoint to scrolling-post-stream.topRefresh (anon)
- (and optionally lock-on.lock)
This issue is happening because there are multiple areas that set scroll location in the post stream when loading a topic. In our case, sometimes lock-on is triggering and scrolling to post_1, before ?page=2's post_21 is being scrolled to, due to posts above post_21 can finishing loading at different times. This causes some calculations to not add up, as being in the middle of a post stream has different calculations than being at the top of the post stream.
Why this change?
When running system tests on our CI, we have been occasionally seeing
server errors like:
```
Error encountered while proccessing /stylesheets/desktop_e58cf7f686aab173f9b778797f241913c2833c39.css
NoMethodError: undefined method `+' for nil:NilClass
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/path/pattern.rb:139:in `[]'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:127:in `block (2 levels) in find_routes'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:126:in `each'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:126:in `each_with_index'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:126:in `block in find_routes'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:123:in `map!'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:123:in `find_routes'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/journey/router.rb:32:in `serve'
/__w/discourse/discourse/vendor/bundle/ruby/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/routing/route_set.rb:852:in `call'
```
While looking through various Rails issues related to the error above, I
came across https://github.com/rails/rails/pull/27647 which is a fix to
fully initialize routes before the first request is handled. However,
the routes are only fully initialize only if `config.eager_load` is set
to `true`. There is no reason why `config.eager_load` shouldn't be `true` in the
CI environment and this is what a new Rails 7.1 app is generated with.
What does this change do?
Enable `config.eager_load` when `env["CI"]` is present
The problem:
Removing the options to addEventListener results in events that are properly cleaned up when the search menu is removed. Previously every time you opened the search menu, the listeners would be attached again, and clicking outside even after it was closed would fire the function again and again (N times as you opened the search menu!)
This was made far far worse in this commit c91d053, where I called close() to remove focus from the search input in the event that the search menu is rendered outside the header.
The problem with this was 2-fold. The close function tried to focus the search header button in core here. When the events aren't cleanup up and that happens... you can't do anything in the app.
The solution:
We don't need the event listeners to close the search menu when it's rendered from the header. The widget header handles clicks outside of the header. Sooo
1. Only register them for standalone search menus
2. Remove the passive options to the listeners so that they are properly removed on close
3. Call close() to unfocus input rather than just closing panel
4. Rename passed in are closeSearchMenu -> onClose because it's more accurate. It's really a callback.
Why this change?
The `Editing sidebar tags navigation allows a user to filter the tag in the modal by selection` system test was flaky
when we were doing `modal.filter("").filter_by_unselected`. The
hypothesis here is that the filtering is debounced before issue a
request to load the new tags and the dropdown is only disabled in the
debounced function. Thereforethere is a chance that when
`modal.filter_by_unselected` runs, it is selecting a row against a
disabled dropdown which results in a noop.
What does this change do?
When filtering using the input in the modal, we will now disabled the
dropdown until the filtering completes which will then re-enable the
dropdown.
The `style` variable is always set because every category has a color
defined, so the surrounding if statement is unnecessary.
"+ X categories" option has also been removed in the past and the code
related to it is now dead code.
When updating the position of a category, the server correctly updates the position in the database, but the response sent back to the client still contains the old position, causing it to "flip back" in the UI when saving. Only reloading the page will reveal the new, correct value.
The Positionable concern correctly positions the record and updates the database, but we don't assign the new position to the already instantiated model.
This change just assigns self.position after the database update. 😎
This changes the Plugins link in the admin sidebar to
be a section instead, which then shows all enabled plugin
admin routes (which are custom routes some plugins e.g.
chat define).
This is done via adding some special preloaded data for
all controllers based on AdminController, and also specifically
on Admin::PluginsController, to have the routes loaded without
additional requests on page load.
We just use a cog for all the route icons for now...we don't
have anything better.
We had our own implementation of number fields in Ember, extended from text fields. Number inputs are now widely supported in browsers, and we can fall back on the native implementation which will be a better experience in almost all cases.
One thing traded off here is number fields can't have a placeholder, but that is intentional. We aren't using that ability anywhere, and we probably only kept it because we're extending text fields.
With this change we can get rid of the entire .js file, since there's no custom behaviour, and just make NumberField a template.
Meta topic: https://meta.discourse.org/t/reseting-robots-txt-override-doesnt-seem-to-work-as-expected/287880?u=osama
Discourse provides a default version for `/robots.txt` which can be customized by admins in `/admin/customize/robots`. In that page, there's a button to reset back to the default version that Discourse provides. However, there's currently a bug with the reset button where the content appears to change to some HTML document instead of the default `robots.txt` version when clicking the button. Refreshing the page shows the true/correct content of `robots.txt` which is the default version, so the reset button actually works but there's a display problem.
What causes this display problem is that we use Rails' `render_to_string` method to generate the default content for `robots.txt` from the template, and what we get from that method is the `robots.txt` content wrapped in the application layout. To fix this issue, we need to pass `layout: false` to the `render_to_string` method so that it renders the template without any layouts.
(extracted from #23678)
* Move Wizard back into main app, remove Wizard addon
* Remove Wizard-related resolver or build hacks
* Install and enable `@embroider/router`
* Add "wizard" to `splitAtRoutes`
In a fully optimized Embroider app, route-based code splitting more
or less Just Work™ – install `@embroider/router`, subclass from it,
configure which routes you want to split and that's about it.
However, our app is not "fully optimized", by which I mean we are
not able to turn on all the `static*` flags.
In Embroider, "static" means "statically analyzable". Specifically
it means that all inter-dependencies between modules (files) are
explicitly expressed as `import`s, as opposed to `{{i18n ...}}`
magically means "look for the default export in app/helpers/i18n.js"
or something even more dynamic with the resolver.
Without turning on those flags, Embroider behaves conservatively,
slurps up all `app` files eagerly into the primary bundle/chunks.
So, while you _could_ turn on route-based code splitting, there
won't be much to split.
The commits leading up to this involves a bunch of refactors and
cleanups that 1) works perfectly fine in the classic build, 2) are
good and useful in their own right, but also 3) re-arranged things
such that most dependencies are now explicit.
With those in place, I was able to move all the wizard code into
the "app/static" folder. Embroider does not eagerly pull things from
this folder into any bundle, unless something explicitly "asks" for
them via `imports`. Conversely, things from this folder are not
registered with the resolver and are not added to the `loader.js`
registry.
In conjunction with route-based code splitting, we now have the
ability to split out islands of on-demand functionalities from the
main app bundle.
When you split a route in Embroider, it automatically creates a
bundle/entrypoint with the relevant routes/templates/controllers
matching that route prefix. Anything they import will be added to
the bundle as well, assuming they are not already in the main app
bundle, which is where the "app/static" folder comes into play.
The "app/static" folder name is not special. It is configured in
ember-cli-build.js. Alternatively, we could have left everything
in their normal locations, and add more fine-grained paths to the
`staticAppPaths` array. I just thought it would be easy to manage
and scale, and less error-prone to do it this way.
Note that putting things in `app/static` does not guarantee that
it would not be part of the main app bundle. For example, if we
were to add an `import ... from "app/static/wizard/...";` in a
main bundle file (say, `app.js`), then that chunk of the module
graph would be pulled in. (Consider using `await import(...)`?)
Overtime, we can build better tooling (e.g. lint rules and babel
macros to make things less repetitive) as we expand the use of
this pattern, but this is a start.
Co-authored-by: Godfrey Chan <godfreykfc@gmail.com>
The regen_ember_5_lockfile script was actually just duplicating the ember3 lockfile without changes 🤦♂️. This commit fixes that, and updates the ember-version-enforcement workflow to detect lockfile issues in future.
Consumers should use the default export. This function doesn't work directly (unless you manually construct its arguments) - the default export helper handles all that automatically.