# Context
Add `disableDefaultKeyboardShortcuts` function to the plugin API to allow for disabling [default bindings](e4941278b2/app/assets/javascripts/discourse/app/lib/keyboard-shortcuts.js (L49)).
# Details
This function is used to disable a "default" keyboard shortcut. You can pass an array of shortcut bindings as strings to disable them.
**Please note that this function must be called from a pre-initializer.**
Example:
```js
api.disableDefaultKeyboardShortcuts(['command+f', 'shift+c']);
```
- Added system spec, displaying intended behavior
Using execCommand to replace the entire contents of the textarea is very slow for larger posts (it seems the browser does a reflow after every 'virtual keypress').
This commit updates the `maybeContinueList()` function to be more surgical when removing the bullet. Now it only selects & removes the characters which actually need to be deleted
Similar to a7cd220704
This adds several improvements to the signup/login forms. Some of them include:
- Added a minimal signup progress bar design for mobile.
- Made the signup/login modals full height on mobile.
- Improved the activation, account creation, and login-required pages on mobile.
- Removed the subheader and emoji from the welcome component.
- Removed most input instructions.
- Used consistent font size for text below the inputs.
- Displayed input instructions only when the field is focused.
- Improved the vertical alignment of input labels.
- Increased the spacing between inputs.
- Fixed label positioning for custom fields.
- Moved the "(optional)" text for the name input outside the instructions.
- Disabled buttons during login to prevent layout shifts.
- Reused the CTA component for modals as well.
- Matched the invite CTA styles with the signup form.
---------
Co-authored-by: Jan Cernik <jancernik12@gmail.com>
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
PR #26784 adds the scroll lock in the modal which renders this second scroll lock for SK component redundant. Having it there in fact causes issues on iPads, where it isn't necessary.
The new style is called `categories_only_optimized` and it is designed
to show only the parent categories, without any subcategories. This
works best for communities with many categories (over a thousand).
* UX: Apply admin table classes for consistent mobile styling on custom flags
* UX: Apply admin table classes for consistent mobile styling on custom flags
* UX: Apply admin table classes for consistent mobile styling on backups
* UX: Apply admin table classes for consistent mobile styling on plugins list
* DEV: tweaks on admin table
* UX: Apply admin table classes for consistent mobile styling on chat plugin
* apply prettier
* apply lint
* DEV: removed commented out code
* DEV: removed unnecessary div element
* scroll to the element
* remove the workaround
* revert
* add an extra assertion
* add enabled check
* improve switching
* rm
---------
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
When rendering the initial search options, we re-use the `AssistantItem` component.
`AssistantItem` requires that you pass in the required params to define what _type_ of component it will be - category, tag, tag intersection, user, etc. This flexibility is nice, as we can just loop through all `@results` and pass in params, without having to predefine what _type_ of result it is.
It is is not very good when it comes to seperating the html strucutre of each unique _type_. This is an example of the initial search results:
<img width="408" alt="Screenshot 2024-10-23 at 9 04 18 AM" src="https://github.com/user-attachments/assets/46795697-6246-4b60-be18-fea200a57baa">
You can see that both categories **and** tags are being rendered. The HTML strcuture looks like so:
```html
<ul class="search-menu-assistant">
<li class="search-menu-assistant-item">
<a class="search-link" href="#"> CATEGORY </a>
</li>
<li class="search-menu-assistant-item">
<a class="search-link" href="#"> CATEGORY </a>
</li>
<li class="search-menu-assistant-item">
<a class="search-link" href="#"> TAG </a>
</li>
<li class="search-menu-assistant-item">
<a class="search-link" href="#"> TAG </a>
</li>
</ul>
```
There is no way to differentiate between the types, even though some are categories and others tags.
This PR adds a _typeClass_ to each component, that will be a additional class included at the top level of the component HTML structure.
```html
<ul class="search-menu-assistant">
<li class="category search-menu-assistant-item">
<a class="search-link" href="#"> CATEGORY </a>
</li>
<li class="category search-menu-assistant-item">
<a class="search-link" href="#"> CATEGORY </a>
</li>
<li class="tag search-menu-assistant-item">
<a class="search-link" href="#"> TAG </a>
</li>
<li class="tag search-menu-assistant-item">
<a class="search-link" href="#"> TAG </a>
</li>
</ul>
```
_See `.category` and `.tag` attached to each `search-menu-assistant-item`._
This will help us identify which _type_ it is, and allow devs to target and customize each element by _type_.
A followup to f05b984208
* modifiers to keep track of components' lifecycles, instead of did-insert/did-update/willDestroy
* proper glimmer-friendly tracking in related models
* caching
* `@outletArgs`
* gjs
We were using a modifier purely for its lifecycle hooks - not to modify an element. This commit switches to using a helper, which provides a similar lifecycle, but without needing to be attached to an element.
Bug introduced in this PR https://github.com/discourse/discourse/pull/29244
When the experiment toggle button was introduced, new features did not look right when the toggle button was not available.
In addition, the plugin name can be an empty string. In that case, information about new features should be displayed.
…or a tip with the highest priority.
This regressed in 597ef11195 where we got rid of `next()` calls, so we'd render the first tip we encounter.
The commit also adds a test and updates existing ones.
Moves the user-tip from the topic-timeline notifications button to the one at the bottom of the topic page.
Three reasons:
1. new users are more likely to use the button that has the full text (and description) rather than the icon-only one
2. we hide the timeline button when scrolled all the way to the bottom of the page, and then the tip doesn't seems to be attached to anything
3. we might be removing the timeline button altogether in the near future
The visitor stats on the /about page were previously showing as `NaN` immediately after enabling the `display_eu_visitor_stats` site setting because the stats for the /about page are cached and updated once every 30 minutes in a sidekiq job. The `NaN` would go away upon the next run of the relevant sidekiq job, but it's not good UX to display a cryptic `NaN` until the job runs. So, this commit ensures that the visitor stats is not displayed at all until the visitor stats is calculated and available.
Internal topic: t/128480.
This PR is a follow-up to ea1473e532. When we initially added the experimental feature for automatically adding `[grid]` to images, we add the [grid] surrounding images after all the uploads have been completed.
This can lead to confusion when `[grid]` is delayed to be added in the composer, as users may try to add grid manually leading to breakage. This also leads to issues with Discourse AI's automatic image caption feature.
**In this PR**: we simply move the logic to be added when the images are uploaded and processing. This way, `[grid]` surrounding images is added immediately. We also apply a fix for an edge-case to prevent images from being wrapped in `[grid]` when they are already inside `[grid]` tags.
Toggle the button to enable the experimental site setting from "What's new" announcement.
The toggle button is displayed when:
- site setting exists and is boolean;
- potentially required plugin is enabled.
This PR adds the feature where three or more image uploads in the composer will result in the images being surrounded by `[grid]` tags. This helps take advantage of the grid feature (https://github.com/discourse/discourse/pull/21513) and display images in a more appealing way immediately after upload.
These tweaks will help adoption of the non-mixin-based uppy patterns.
- Add `type:` to default arguments list
- Update pick-files-button to support explicit element registration
- Make `cancelSingleUpload` a public API, and add `cancelAllUploads`
- Remove `isDestroyed` logic - it doesn't do anything outside a component
- Add `@bind` to `setup()`
- Allow `additionalParams` to be a function
- Fix `autoStart` mixin shim
This commit simplifies the initial state of the invite modal when it's opened to make it one click away from creating an invite link. The existing options/fields within the invite modal are still available, but are now hidden behind an advanced mode which can be enabled.
On the technical front, this PR also switches the invite modal to use our FormKit library.
Internal topic: t/134023.
When a user is missing required fields, they are required to fill those up before continuing to interact with the forum. This applies to admins as well.
We keep a whitelist of paths that can still be visited in this mode: FAQ, About, 2FA setup, and any admin route for admins.
We concluded that admins should still be able to enable safe mode even with missing required fields. Since plugins etc. can potentially mess with the ability to fill those up.
When adding or updating a custom user field to apply to all users (retroactively) we want to alert the admin that this will force all existing users to fill up the field before they are able to access the forum again.
However, we currently show this prompt when making changes only to other attributes on the custom field, i.e. the requirement hasn't changed.
This commit fixes that.
This component will soon be updated to remove the mixin entirely (and add a regression test for it). But for now, this is a quick fix to get it working again.
This commit is fixing the path which sets a default value to trigger. We were doing `if (!this.model.trigger)` but `this.model.trigger` can have `0` as value, which would trigger this codepath and this codepath was setting the first value of `badgeTriggers` as a default value for trigger.
The subcategories page was not paginated and it was using the
subcategory style from the category settings. The same page style should
be used for categories and subcategories page.
Theme modifiers can now be defined as theme settings, this allows for
site operators to override behavior of theme modifiers.
New syntax is:
```
{
...
"modifiers": {
"modifier_name": {
"type": "setting",
"value": "setting_name"
}
}
}
```
This also introduces a new theme modifier for serialize_post_user_badges. Name of badge must match the name of the badge in the badges table. The client-side is updated to load this new data from the post-stream serializer.
Co-authored-by: David Taylor <david@taylorhq.com>
When converting the user custom fields admin form in #29070, I accidentally removed the plugin outlet after-admin-user-fields. This is used by the discourse-authentication-validations plugin, which is now broken on main core.
This commit adds back the plugin outlet in core.
Add plugin outlets for each assistant result type - User, Tag and Categories, Groups, etc. This gives us the ability to add content for each _type_ of search suggestion:
<img width="216" alt="Screenshot 2024-10-16 at 10 01 09 AM" src="https://github.com/user-attachments/assets/fbbc71fe-a8fe-499b-8377-480dd0ed5f75">
I would have preferred to add a single plugin outlet at the top of the template and pass `this.suggestionType` and `@results`, but that would then require that we carry over a ton of core logic to plugins to calculate which _type_ is being rendered, and it would get unnecessarily messy quick. So instead I opted to create a plugin outlet for each _type_.
#29209 introduced a bug where columns to the directory added via add_directory_column are not being translated properly.
This fixes the issue and adds an integration test.
This commit replaces all uppy-related mixins with standalone classes. The main entrypoint is now lib/uppy/uppy-upload.js, which has a list of its config options listed at the top of the file. Functionality & logic is completely unchanged.
The uppy-upload mixin is replaced with a backwards-compatibility shim, which will allow us to migrate to the new pattern incrementally.
* UX: More additions
* UX: more
* DEV: Add admin/config/themes route
* UX: Use admin config card
* syntax merge fixes
* cleanup
* cleanup
* checkbox
* more
* error
* save on click
* more
* fix setter
* DEV: Implement vanilla checkbox
* cleanup
* UX: save themes as default
* DEV: Add component list to card
* DEV: Add placeholder for no screenshots
* DEV: Fix default theme reactivity
Also add content/optionalAction yields to config area
card and put the theme user selectable checkbox there,
along with adding styles.
* DEV: Change to generic "look and feel" config area
* DEV: Auto redirect to themes on base look and feel route
* UX: Remove computed from sorted themes
* linting
* UX: Turn update icon into button that routes to settings
* DEV: remove unused function
* UX: center icons with title
* DEV: Lint
* UX: Hook up theme preview button
* DEV: Minor fixes
---------
Co-authored-by: Martin Brennan <martin@discourse.org>
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
This adds dedicated routes for /login and /signup, replacing the use of modals. Currently, this is behind the experimental_full_page_login feature flag. It also includes some small consistency fixes related to formatting, spacing, icons, and the loading of certain elements
Prior to this fix the format class was only applied to the child control, but in case of full we also need to ensure the parent wrapping field is also taking 100% width otherwise we are at risk of having a field of the width of its content.
theme-setting and theme-i18n are not needed in `.gjs` files. This commit adds more helpful error messages to direct developers to the modern alternatives.
Currently the topic timeline tip appears before the suggested topics one only due to a small implementation detail in the latter.
This ensures that tips appear in the expected order when more than one of these components is rendered at the same time.
If a plugin's JS fails to load for some reason, most commonly
ad blockers, the entire admin interface would break. This is because
we are adding links to the admin routes for plugins that define
them in the sidebar.
We have a fix for this already in the plugin list which shows a warning
to the admin. This fix just prevents the broken link from rendering
in the sidebar if the route is not valid.