Based on feedback from Matt Haughey, we don't need to use so many words when describing a deleted topic or post.
Co-authored-by: Martin Brennan <martin@discourse.org>
If reload a page after enabling slow mode and open the slow mode dialog again it would show a slow mode interval but wouldn't show Enabled Until value. This PR fixes it.
It used to allow adding email addresses to a group even if invites were
disabled for the site. This does not allow user to input email address
if they cannot invite.
The second thing this commit improves is the message that is displayed
to the user when they hit the invite rate limit.
Over the years we accrued many spelling mistakes in the code base.
This PR attempts to fix spelling mistakes and typos in all areas of the code that are extremely safe to change
- comments
- test descriptions
- other low risk areas
This commit fixes an issue where controls scroll in lightboxes with large images (after zooming in)
Before:
05024730b3.mp4
Notice how controls like the close button, the next and previous button, and the image metadata also scroll? This is an undesired behavior.
After:
8047bab735.mp4
This is the desired behavior; only the image should scroll.
The changes in this PR apply to both desktop and mobile.
The problem was we were setting the properties then immediately calling
`refreshRoute` which was being executed before the properties were
settled via the runloop.
> Backtracking re-render refers to a scenario where, in the middle of the rendering process, you have modified something that has already been rendered.
See more details from the Ember team here https://github.com/emberjs/ember.js/issues/13948.
We call _updateInput from init. _updateInput triggers onChangeInput which mutates a date that was given to future-date-input just a moment ago and a rendering cycle wasn't finished yet.
The crash:
```
Uncaught TypeError: Ember.keys is not a function
```
Repro:
- visit home page
- click new topic
- navigate to your messages by clicking your avatar (top right), then enveloppe icon, and finally the bottom chevron
- click New Message
- click cancel in the composer, it should crash
Watched words are always regular expressions, despite watched_words_
_regular_expressions being enabled or not. Internally, wildcard
characters are replaced with a regular expression that matches any non
whitespace character.
This is two fixes:
1. Ember CLI's proxy did not support 3xx redirects so a redirect was
failing.
2. We were not passing query parameters to the `bootstrap.json` endpoint
to correctly handle previewing themes (and other occasional options.)
If you finished reviewing the initially loaded items, and there're more in the queue, load them.
Also, when fast-tracking the pending items updates, use the reviewable_count returned by the perform result. Calling "result.reviewable_count" returns undefines.
This patch remembers the last id for the `file-change` event and uses it
to initialize the client side watcher. This should help fix the issue
where styles are not reloaded client side if the browser refreshed.
Normally we'd use `ember-auto-import` for this, but it's not run on
our admin tree due to the quirky way we load it conditionally.
Instead we'll append it at the bottom like our Rails app does.
* FIX: Ensure the same email cannot be invited twice
When creating a new invite with a duplicated email, the old invite will
be updated and returned. When updating an invite with a duplicated email
address, an error will be returned.
* FIX: not Ember helper does not exist
* FIX: Sync can_invite_to_forum? and can_invite_to?
The two methods should perform the same basic set of checks, such as
check must_approve_users site setting.
Ideally, one of the methods would call the other one or be merged and
that will happen in the future.
* FIX: Show invite to group if user is group owner
Identical callbacks can pile up during tests and cause all sort of weird problems that are difficult to debug. This commit clears registered callbacks after each test.
* FIX: ember-cli proxy subfolder fix
* REFACTOR: put rootURL setup in environment, update baseURL logic for subfolder
Correctly have ember understand and parse relative_url_root and use it in
the dev server
This was needed to fix a bookmark back button issue but it
broke category topic links, causing a full reload. Now it appears
something has changed in core and this is no longer necessary for
the bookmark back button to work, so I am removing it again.
* FIX: Cache missing inline oneboxes
Some inline oneboxes were not cached when the server did not return an
answer for an URL and the queried URL and the absolute URL were
different.
For example, if user typed www.example.com, the client asked the server
for http://www.example.com and if the server returned an empty response,
then the client would keep requesting an inline onebox everytime the
composer changed.
In other words, the key used for reading (the absolute URL) and the one
used for writing (the URL as typed by the user) were not the same when
the server returned an empty response.
* DEV: Check cache before making request
There is another cache check in PrettyText, but that is not enough if
multiple requests are pending. This problem was made obvious in tests,
but can happen for users with slow connections.
* FEATURE: Allow sending a message with invite
It used to be a staff-only feature and this commit makes it available
to everyone who can invite.
* FIX: Inviting to topic uses another email template
This used to be the case, but the extra parameter was lost when we
switched to the new modal.
The user may have changed their category or tag tracking settings since a topic was tracked/watched based on those settings in the past. In that case we need to alter the reason message we show them otherwise it is very confusing for the end user to be told they are tracking a topic because of a category, when they are no longer tracking that category.
For example: "You will see a count of new replies because you are tracking this category." becomes: "You will see a count of new replies because you were tracking this category in the past."
To do this, it was necessary to add tag and category tracking info to current user serializer. I improved the serializer code so it only does 3 SQL queries instead of 9 to get the tracking information for tags and categories for the current user.
It's been awhile since we have supported IE11 so it should be safe to remove
IntersectionObserver now.
From a TODO task in this repo:
> drop when we eventually drop IE11
Announcement of when we removed IE11 support:
https://meta.discourse.org/t/137984/40?u=blake
See: https://meta.discourse.org/t/navigating-back-to-bookmarks/188912/4
Instead of taking the user back to the bookmark list after selecting
a topic and navigating back, the user was navigated back to the page
before that. This is because the topic-link component was missing
the data-auto-route attribute which tells the intercept-click library
not to use DiscourseURL.routeTo to handle the transition (so it is just
handled internally by Ember)
When editing the files for a theme in the admin dashboard, typing "cmd+s" (a common key-binding to save in most text editors) used to engage the browser's default "save page" dialogue.
This commit adds a key-binding to the ace editor that saves the file.
Now, the "cmd+s" (and "ctrl+s" for windows) key-binding does the same action as the save button.
This commit will add CSS classes like `unlisted`, `pinned`, and `unpinned` on the body tag.
* DEV: we no longer using the `categoryClass` & `tagClasses` methods.
* Update app/assets/javascripts/discourse/app/components/add-topic-status-classes.js
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
- better form
- uses d-footer
- ensure buttons have the same height
Note that to achieve same height for btn without text, I made the choice to go for a minimum height which should work in most cases.
Fixes a bug in user preferences > interface, the light scheme dropdown
was defaulting to "Theme Default" even when the user had selected a
different scheme.
This updates the preview_theme_id preservation logic to use more recent, robust, browser APIs. It also adds support for preserving the `?pp=async-flamegraph` parameter which is proposed in https://github.com/MiniProfiler/rack-mini-profiler/pull/494
We really want to encourage all developers to use Ember CLI for local
development and testing. This will display an error page if they are not
with instructions on how to start the local server.
To disable it, you can set `NO_EMBER_CLI=1` as an ENV variable
* DEV: refactor font sizing into css custom variables
Add font variables as css variables. Allows plugins/themes to update/overwrite the variables and have core pick up changes. This allows for a theme or plugin to overhaul core's font ratios if desired.
This commit allows site admins to run theme tests in production via a new `/theme-qunit` route. When you visit `/theme-qunit`, you'll see a list of the themes/components installed on your site that have tests, and from there you can select a theme or component that you run its tests.
We also have a new rake task `themes:install_and_test` that can be used to install a list of themes/components on a temporary database and run the tests of the themes/components that are installed. This rake task can be useful when upgrading/deploying a Discourse instance to make sure that the installed themes/components are compatible with the new Discourse version being deployed, and if the tests fail you can abort the build/deploy process so you don't end up with a broken site.
- ensures footer buttons are aligned
- prevents focus on close button to be much larger than it should be, note that this fix could impact other modals but the current solution is not working, so better fix it differently if needed
This bug has first been seen when loading similar topics, minimum repro:
- Have a topic named "Something Foo Bar" with a category.
- Call this in console:
```
Discourse.currentUser.store.find("similar-topic", { title: "Something foo bar", raw: "" })
```
- Navigate to latest (no full refresh)
- The category from the topic should have disappeared
The aim of this PR is to improve the topic tracking state JavaScript code and test coverage so further modifications can be made in plugins and in core. This is focused on making topic tracking state changes easier to respond to with callbacks, and changing it so all state modifications go through a single method instead of modifying `this.state` all over the place. I have also tried to improve documentation, make the code clearer and easier to follow, and make it clear what are public and private methods.
The changes I have made here should not break backwards compatibility, though there is no way to tell for sure if other plugin/theme authors are using tracking state methods that are essentially private methods. Any name changes made in the tracking-state.js code have been reflected in core.
----
We now have a `_trackedTopicLimit` in the tracking state. Previously, if a topic was neither new nor unread it was removed from the tracking state; now it is only removed if we are tracking more than `_trackedTopicLimit` topics (which is set to 4000). This is so plugins/themes adding topics with `TopicTrackingState.register_refine_method` can add topics to track that aren't necessarily new or unread, e.g. for totals counts.
Anywhere where we were doing `tracker.states["t" + data.topic_id] = newObject` has now been changed to flow through central `modifyState` and `modifyStateProp` methods. This is so state objects are not modified until they need to be (e.g. sometimes properties are set based on certain conditions) and also so we can run callback functions when the state is modified.
I added `onStateChange` and `onMessageIncrement` methods to register callbacks that are called when the state is changed and when the message count is incremented, respectively. This was done so we no longer need to do things like `@observes("trackingState.states")` in other Ember classes.
I split up giant functions like `sync` and `establishChannels` into smaller functions for readability and testability, and renamed many small functions to _functionName to designate them as private functions which not be called by consumers of `topicTrackingState`. Public functions are now all documented (well...at least ones that are not immediately obvious).
----
On the backend side, I have changed the MessageBus publish events for TopicTrackingState to send back tags and tag IDs for more channels, and done some extra code cleanup and refactoring. Plugins may override `TopicTrackingState.report` so I have made its footprint as small as possible and externalised the main parts of it into other methods.
If the "use_site_small_logo_as_system_avatar" setting is enabled, the site's small logo is displayed as the selected option by the avatar-selector. Choosing a different avatar disables the setting.
When the admin creates a new custom field they can specify if that field should be searchable or not.
That setting is taken into consideration for quick search results.
This PR includes few commits that improve the new "Share Topic" modal: same
icon for notify button as the notification, advanced options are only showed
for staff, but the topic name should be visible to everyone.
This commit allows site admins to run theme tests in production via a new `/theme-qunit` route. When you visit `/theme-qunit`, you'll see a list of the themes/components installed on your site that have tests, and from there you can select a theme or component that you run its tests.
We also have a new rake task `themes:install_and_test` that can be used to install a list of themes/components on a temporary database and run the tests of the themes/components that are installed. This rake task can be useful when upgrading/deploying a Discourse instance to make sure that the installed themes/components are compatible with the new Discourse version being deployed, and if the tests fail you can abort the build/deploy process so you don't end up with a broken site.
The bulk button is normally shown only to staff, which is why we did not
do any explicit permissions check. Now we do display it on the messages
page too, where it is accessible to everyone.
Regression was introduced in c54609.
This ensures the full height composer styling only applies when (window
height - viewport height > 0). Previously it was being wrongly triggered
when that calculation returned a negative number.
This filter hides reviewables with a score lower than the "reviewable_low_priority_threshold" setting. We only use reviewables that already met this threshold to calculate the Medium and High priority filters.
The old share modal used to host both share and invite functionality,
under two tabs. The new "Share Topic" modal can be used only for
sharing, but has a link to the invite modal.
Among the sharing methods, there is also "Notify" which points out
that existing users will simply be notified (this was not clear
before). Staff members can notify as many users as they want, but
regular users are restricted to one at a time, no more than
max_topic_invitations_per_day. The user will not receive another
notification if they have been notified of the same topic in past hour.
The "Create Invite" modal also suffered some changes: the two radio
boxes for selecting the type (invite or email) have been replaced by a
single checkbox (is email?) and then the two labels about emails have
been replaced by a single one, some fields were reordered and the
advanced options toggle was moved to the bottom right of the modal.
* DEV: Give a nicer error when `--proxy` argument is missing
* DEV: Improve Ember CLI's bootstrap logic
Instead of having Ember CLI know which URLs to proxy or not, have it try
the URL with a special header `HTTP_X_DISCOURSE_EMBER_CLI`. If present,
and Discourse thinks we should bootstrap the application, it will
instead stop rendering and return a HTTP HEAD with a response header
telling Ember CLI to bootstrap.
In other words, any time Rails would otherwise serve up the HTML for the
Ember app, it stops and says "no, you do it."
* DEV: Support asset filters by path using a new options object
Without this, Ember CLI's bootstrap would not get the assets it wants
because the path it was requesting was different than the browser path.
This adds an optional request header to fix it.
So far this is only used by the styleguide.
Original bug report: https://meta.discourse.org/t/rename-tag-not-working-as-expected/184950
This bug was caused by the use of `oneWay` which can be very dangerous in this case, from the documentation:
> computed.oneWay only provides an aliased get. The set will not mutate the upstream property, rather causes the current property to become the value set. **This causes the downstream property to permanently diverge from the upstream property.**
Not all videos can be rendered everywhere because some browser may be
missing some codecs. This commit adds a notice on top of video to let
the user know about it.
When navigating from a 'discovery' topic list to a 'tags' topic list, the scroll position from the 'discovery' list was being used by the tag list. That meant the user would be taken to a random point in the list, and not scrolled to the top.
Non-tag topic lists were working fine because we only apply the 'cached' logic (and by extension, the saved scroll location) when the user clicks 'back' in the browser. In the code, this is referred to as `isPoppedState`.
This commit takes the `isPoppedState` logic from the regular topic lists, and applies it to the tag topic lists.
* FIX: Show date picker over modal
Previously, scrolling was necessary to see the whole picker.
* FEATURE: Improve validation for polls
Adds new error messages for each of the edge cases. Previously, it
failed with a simple error saying that the minimum value must be less
than the maximum value.
* UX: Copy edit
Note that this is only applied on date-input and not the old date-picker for now.
This commit is also slightly modifying admin report dates form to ensure the native picker is correctly used, as a result: it doesn’t auto refresh on date change and fixes a border bug.
Note that this commit is also fixing various mistakes in emojis.
Some of them have been fixed manually in db.json/data.js/groups.json and will need to be fixed in emoji-db gem.
The "last custom date and time" shortcut for the topic timer and
bookmarks could get into a state where it had an Invalid Date if
the user opened the topic timer modal, clicked Custom Date and then
closed the modal without making changes. This has been fixed, the
last custom date + time will no longer be set in this case and if
somehow the last custom date + time is invalid that option will not
show.
Also improve the wording from just "Last" to "Last custom datetime"
* FEATURE: Review every post using the review queue.
If the `review_every_post` setting is enabled, posts created and edited by regular uses are sent to the review queue so staff can review them. We'll skip PMs and posts created or edited by TL4 or staff users.
Staff can choose to:
- Approve the post (nothing happens)
- Approve and restore the post (if deleted)
- Approve and unhide the post (if hidden)
- Reject and delete it
- Reject and keep deleted (if deleted)
- Reject and suspend the user
- Reject and silence the user
* Update config/locales/server.en.yml
Co-authored-by: Robin Ward <robin.ward@gmail.com>
Co-authored-by: Robin Ward <robin.ward@gmail.com>
When the user has not selected any tags and minimum_required_tags
is specified for a category, they get a clientside validation error
to tell them this. We were not doing the same thing when
min_tags_from_required_group and required_tag_groups was specified.
There is a category setting that enforces 1 or more tags must be added to a topic from a specific tag group before creating it. This validation was not being run before the topic was being sent to a review queue for categories that have that setting enabled.
There was an existing validation in `TopicCreator` but it was not correct; it was only validating when the tags did _not_ exist and also only happened on `create`. I now run the validation in `TopicCreator.valid?`
I also improved the error message shown to the user when they have not added the tags required (showing the tag names from the tag group), and changed the composer tag selector to not show "optional" if there are N tags required from a certain group.
Headings with the exact same name generated exactly the same heading
names, which was invalid. This replaces the old code for generating
names for non-English headings which were using URI encode and resulted
in unreadable headings.
I noticed this while trying to debug slow performing ember tests.
Our docking mixin sometimes sets timers but never cancels them when
removed. I'm not sure of any errors this causes but we should be tidying
up whenever the component is removed.
This commit also updates github’s body onebox styles in Discourse core:
- full width
- prevents show-more btn to trigger vertical scrolling
- makes text standout less and slightly bigger
When invited by email, users will receive an invite URL which contains
a token. If that token is present when the invite is redeemed, their
account will be automatically activated.
* FIX: Use theme color for anchor icon
* FIX: Do not count anchor links
* FIX: Do not count hashtags links either
* DEV: Add tests for link_count
* FIX: Disable anchors in quotes and preview
* FIX: Try building some anchor slugs for unicode
* DEV: Fix tests
This PR adds a new category setting which is a column in the `categories` table, `allow_unlimited_owner_edits_on_first_post`.
What this does is:
* Inside the `can_edit_post?` method of `PostGuardian`, if the current user editing a post is the owner of the post, it is the first post, and the topic's category has `allow_unlimited_owner_edits_on_first_post`, then we bypass the check for `LimitedEdit#edit_time_limit_expired?` on that post.
* Also, similar to wiki topics, in `PostActionNotifier#after_create_post_revision` we send a notification to all users watching a topic when the OP is edited in a topic with the category setting `allow_unlimited_owner_edits_on_first_post` enabled.
This is useful for forums where there is a Marketplace or similar category, where topics are created and then updated indefinitely by the OP rather than the OP making new topics or additional replies. In a way this acts similar to a wiki that only one person can edit.
* Fixes the z-index of the prompt so it is behind the quick access panels
* Adds a dismiss `X` button (made sure the click target of this was quite big)
* Change structure of HTML to address template lint issues
* Fix aria-hidden not returning true/false
* Reload current page instead of navigating to / when clicking on the prompt message
Since cd24eff5d9, theme modules are now prefixed with the theme id. Therefore themes which defined raw-view classes will be broken
This commit updates the `raw` helper to use the resolver for looking up the view class. This automatically takes care of trying theme/plugin paths in addition to core paths.
This commit allows themes and theme components to have QUnit tests. To add tests to your theme/component, create a top-level directory in your theme and name it `test`, and Discourse will save all the files in that directory (and its sub-directories) as "tests files" in the database. While tests files/directories are not required to be organized in a specific way, we recommend that you follow Discourse core's tests [structure](https://github.com/discourse/discourse/tree/master/app/assets/javascripts/discourse/tests).
Writing theme tests should be identical to writing plugins or core tests; all the `import` statements and APIs that you see in core (or plugins) to define/setup tests should just work in themes.
You do need a working Discourse install to run theme tests, and you have 2 ways to run theme tests:
* In the browser at the `/qunit` route. `/qunit` will run tests of all active themes/components as well as core and plugins. The `/qunit` now accepts a `theme_name` or `theme_url` params that you can use to run tests of a specific theme/component like so: `/qunit?theme_name=<your_theme_name>`.
* In the command line using the `themes:qunit` rake task. This take is meant to run tests of a single theme/component so you need to provide it with a theme name or URL like so: `bundle exec rake themes:qunit[name=<theme_name>]` or `bundle exec rake themes:qunit[url=<theme_url>]`.
There are some refactors to how Discourse processes JavaScript that comes with themes/components, and these refactors may break your JS customizations; see https://meta.discourse.org/t/upcoming-core-changes-that-may-break-some-themes-components-april-12/186252?u=osama for details on how you can check if your themes/components are affected and what you need to do to fix them.
This commit also improves theme error handling in Discourse. We will now be able to catch errors that occur when theme initializers are run and prevent them from breaking the site and other themes/components.
The implemented helpers, are helper which might be in Ember core in the future:
- and
- or
- not
- eq
- not-eq
- lt
- lte
- gt
- gte
They follow the implementation of ember-truth-helpers: https://github.com/jmurphyau/ember-truth-helpers
Note 1: Ember rfcs are still debating going with {{not-eq}} or {{neq}}, should be easy to support in the future whatever is finally chosen.
Note 2: this commit also moves it to its own addon, and removes the {{not}} test, to simplify further updates.
You can enable this by using the `includePostAttributes` API call with
the value of `topicMap`. This will always show the topic map at the top
of a topic regardless of how many posts there are.
Currently, new topics for specific tags can be dismissed with the button at the bottom of the page.
When there is more than 15 new topics, we should display the same button at the top as well. It already works in the same manner for categories.
`isTesting` is a function, so `if(isTesting)` was only checking for the presence of the function. We need to actually evaluate it. Followup to 68a032a734
To add an extra layer of security, we sanitize settings before shipping them to the client. We don't sanitize those that have the "html" type.
The CookedPostProcessor already uses Loofah for sanitization, so I chose to also use it for this. I added it to our gemfile since we installed it as a transitive dependency.
Clock manipulation seems not reliable in component tests. This blog post does a great job of explaining it: https://dockyard.com/blog/2018/04/18/bending-time-in-ember-tests
Sadly, we don't have all the "recent" ember test helpers and can't use things like `getSettledState()`.
For now this pattern seems the most reliable and easy to apply, albeit not great.
Note if you wish to reproduce the current timeout, the following command should do it: `QUNIT_SEED=215263717493121190480103670124734840282 rake qunit:test`
This commit allows themes and theme components to have QUnit tests. To add tests to your theme/component, create a top-level directory in your theme and name it `test`, and Discourse will save all the files in that directory (and its sub-directories) as "tests files" in the database. While tests files/directories are not required to be organized in a specific way, we recommend that you follow Discourse core's tests [structure](https://github.com/discourse/discourse/tree/master/app/assets/javascripts/discourse/tests).
Writing theme tests should be identical to writing plugins or core tests; all the `import` statements and APIs that you see in core (or plugins) to define/setup tests should just work in themes.
You do need a working Discourse install to run theme tests, and you have 2 ways to run theme tests:
* In the browser at the `/qunit` route. `/qunit` will run tests of all active themes/components as well as core and plugins. The `/qunit` now accepts a `theme_name` or `theme_url` params that you can use to run tests of a specific theme/component like so: `/qunit?theme_name=<your_theme_name>`.
* In the command line using the `themes:qunit` rake task. This take is meant to run tests of a single theme/component so you need to provide it with a theme name or URL like so: `bundle exec rake themes:qunit[name=<theme_name>]` or `bundle exec rake themes:qunit[url=<theme_url>]`.
There are some refactors to internal code that's responsible for processing themes/components in Discourse, most notably:
* `<script type="text/discourse-plugin">` tags are automatically converted to modules.
* The `theme-settings` service is removed in favor of a simple `lib` file responsible for managing theme settings. This was done to allow us to register/lookup theme settings very early in our Ember app lifecycle and because there was no reason for it to be an Ember service.
These refactors should 100% backward compatible and invisible to theme developers.
This moves the "This site was just updated" modal asking the user if they want to refresh into a subtle prompt that slides down from the header.
Also in this PR I've added a helper to publish message bus messages in JS tests. So instead of this:
```javascript
// Mimic a messagebus message
MessageBus.callbacks
.filterBy("channel", "/global/asset-version")
.map((c) => c.func("somenewversion"));
```
We can have:
```javascript
publishToMessageBus("/global/asset-version", "somenewversion");
```
With a link having an empty href: `<a href>foo</a>` doing
`element.href` will give you the URL of the document, to get the same behavior than `$(element).attr("href")` and get "" you need to do `element.getAttribute("href")`
Changing the invite type from link to email and then copying it was
confusing because it gave user the impression that the invite was
updated and the invite link will reflect the latest changes, but it
did not.
If the user has not been sent any messages, show a message in the quick access menu with an educational message. If the user can send private messages, also show a link to open the "new message" composer:
This also adds a general improvement to the quick-access-panel, to be able to show an `emptyStateWidget` instead of just a message if there is nothing to show in the panel, as well as initial general styles for empty state.
After clicking the message button on the group page, the composer shouldn't display the "official warning" checkbox. The discourse-bcc plugin also relies on this attribute to display an option in the composer.
This change makes is so that when a time-picking modal (e.g. "Add bookmark" modal) is visible, **all** global key bindings are paused.
1. Fixes an issue where opening and closing a time-picking modal would break global single-key keybinds, so for example, <kbd>L</kbd> would no longer like posts, but <kbd>L</kbd> <kbd>L</kbd> would
2. Fixes a related issue, where doing the above would also override custom keybinds provided by plugins (e.g. <kbd>L</kbd> shortcut that discourse-reactions uses)
Included:
* DEV: Reset Mousetraps instead of unbinding
* FIX: Make unbind use unbind
* DEV: Don't check for keyTrapper twice
* DEV: Use an instance of Mousetrap
* DEV: Remove an invalid `for` attribute (`set_reminder` doesn't exist)
* DEV: Add ability to pause all KeyboardShortcuts
* FIX: Pause all keybinds when in a time-picking modal
* DEV: Move bookmark keybind resets to willDestroyElement
* DEV: Fix shortcuts-related tests
Admins can use bulk invites to pre-populate user fields. The imported
CSV file must have a header with "email" column (first position) and
names of the user fields (exact match).
Under the hood, the bulk invite will create staged users and populate
the user fields of those.
This PR improves the code structure of the topic-timer-info component while retaining all the functionality and making it extensible for theme/plugin devs.
The diff is confusing but the gist is that there are some topic acceptance tests that were incorrectly placed in "Topic featured links" group. This moves them into "Topic".
Moved tests:
* Converting to a public topic
* Unpinning unlisted topic
* selecting posts
* select below
* View Hidden Replies
* Quoting a quote keeps the original poster name
* Quoting a quote of a different topic keeps the original topic title
* Quoting a quote with the Reply button keeps the original poster name
* Quoting a quote with replyAsNewTopic keeps the original poster name
* Quoting by selecting text can mark the quote as full
Applying oneboxes and replacing censored watched words does not happen
in a strict order which often lead to inconsistencies. This commit
fixes the behavior and will never censor oneboxes.
To make it always censor oneboxes implies significant changes to the
PrettyText pipeline.
This form does not need to show if discourse connect is enabled
because generally the fields that would be filled in here are
filled in by the SSO provider. There is also an issue right now
where enable_local_logins and enable_discourse_connect can be
true at the same time which is not right.
Find & Replace and Autotag watched words were not completely exported
and import did not work with these either. This commit changes the
input and output format to CSV, which allows for a secondary column.
This change is backwards compatible because a CSV file with only one
column has one value per line.
There are a lot of little fixes to tests here, but the biggest issue was
too much recursion because we kept replacing the helpers over and over
again. I assume Chrome has tail recursion or something to speed this up
but Firefox hated it.
Otherwise, we can't rely on the order of attributes in rendered HTML so
I simplified most of those tests to just look for key strings in the
HTML that are rendered.
Fixes an issue where the "Keep editing" button in the discard draft
modal wouldn't work when switching to a new topic with an open composer
and clicking Reply.
Followup to d470e4f
Users can now pin bookmarks from their bookmark list. This will anchor the bookmark to the top of the list, and show a pin icon next to it. This also applies in the nav bookmarks panel. If there are multiple pinned bookmarks they sort by last updated order.
We currently make an AJAX request every time someone opens the hamburger menu, resulting in a forbidden response when a user can't see the review queue.
This commit ensures that email validation is skipped when the email is
obfuscated, that the email is no longer send when it is not an invite
link and no username is suggested if the email is hidden as it may
reveal the first part of the email.
Follow up to commit 033d6b6437.
* DEV: Use custom tags rather than handlebars server side
These will be skipped if they are ever rendered in a document. The
handlebars really messes stuff up.
* DEV: Build our own locale file for testing purposes
We can't practically proxy everything in test mode, but we can
approximate the logic and build our own locale file for testing purposes
that works quite well. This allows us to run tests without a proxy.
* DEV: Support for testem runner for ember cli tests
We previously included this option conditionally when users were replying
or creating a new topic while they had content already in the composer.
This makes the dialog always include three buttons:
- Close and discard
- Close and save draft for later
- Keed editing
This also changes how the backend notifies the frontend when there is
a current draft topic. This is now sent via the `has_topic_draft`
property in the current user serializer.
This PR allows invitations to be used when the DiscourseConnect SSO is enabled for a site (`enable_discourse_connect`) and local logins are disabled. Previously invites could not be accepted with SSO enabled simply because we did not have the code paths to handle that logic.
The invitation methods that are supported include:
* Inviting people to groups via email address
* Inviting people to topics via email address
* Using invitation links generated by the Invite Users UI in the /my/invited/pending route
The flow works like this:
1. User visits an invite URL
2. The normal invitation validations (redemptions/expiry) happen at that point
3. We store the invite key in a secure session
4. The user clicks "Accept Invitation and Continue" (see below)
5. The user is redirected to /session/sso then to the SSO provider URL then back to /session/sso_login
6. We retrieve the invite based on the invite key in secure session. We revalidate the invitation. We show an error to the user if it is not valid. An additional check here for invites with an email specified is to check the SSO email matches the invite email
7. If the invite is OK we create the user via the normal SSO methods
8. We redeem the invite and activate the user. We clear the invite key in secure session.
9. If the invite had a topic we redirect the user there, otherwise we redirect to /
Note that we decided for SSO-based invites the `must_approve_users` site setting is ignored, because the invite is a form of pre-approval, and because regular non-staff users cannot send out email invites or generally invite to the forum in this case.
Also deletes some group invite checks as per https://github.com/discourse/discourse/pull/12353
Highlight.js changed their default branch from master to main. This switches to the @highlightjs/cdn-assets package, thus sidestepping the problem. It's a slightly cleaner integration though (no need to build locally anymore).
We override the default replacements rule to no longer replace "(c)", "(p)", and "(p)". Additionally, we merged the custom arrows rule into the replacement function.
When syncing code elements, the inner text used to be escaped, which
rendered the actual HTML code instead. This commit overwrites default
parser settings to fix the way code tags are handled.
* UX: Move modal footer into better container
This commit moves the modal footer under the sign-up form for a more cohesive feel between the login + create account modals.
This is not a security issue because regular users are not allowed to insert FA icons anywhere in the app. Admins can insert icons via custom badges, but they do have the ability to create themes with JS.
Currently the process of adding a custom image to badge is quite clunky; you have to upload your image to a topic, and then copy the image URL and pasting it in a text field. Besides being clucky, if the topic or post that contains the image is deleted, the image will be garbage-collected in a few days and the badge will lose the image because the application is not that the image is referenced by a badge.
This commit improves that by adding a proper image uploader widget for badge images.
This commit extends functionality of the expired invites tab, making
it more similar to the pending tab. It also implements a different
layout for mobile.
Some git repos have a different ssh url scheme than github and we should
support them.
This change updates our regex format to account for repos that don't
start with "git", but are still valid ssh urls.
Also I added some tests to account for the various formats and to ensure
we don't show the public key when using https urls.
See: https://meta.discourse.org/t/182668
* FIX: Invite acceptance tests were broken in Ember CLI
They relied on old Ember behavior where the app does not boot until
`visit` is called and this is no longer true.
This refactors the test to DRY stuff up a bit, and modify the DOM where
necessary in `needs.hooks.beforeEach`.
* Update app/assets/javascripts/discourse/tests/acceptance/invite-accept-test.js
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
* UX: Add class to body on first unread notification
This commit adds `first-notification` class to the body element when there is a first unread notification. This will fix any issues with certain themes who use custom headers where z-index issues sometimes cause those custom headers to not be hidden by the transparent shadow over the page.
This commit ensures that "prioritize username in ux" setting is
respected in following places:
- user directory
- user summary
- badge detail
- group detail
Staff can send a post to the review queue by clicking the "Flag Post" button next to "Take Action...". Clicking it flags the post using the "Notify moderators" score type and hides it. A custom message will be sent to the user.
The recalculation of the `forceActive` function for the nav items was being run _before_ the querystring parameters are getting updated. For example for the Unassigned link:
```javascript
i.addNavigationBarItem({
name: "unassigned",
customFilter: (category) => {
return category && category.enable_unassigned_filter;
},
customHref: (category) => {
if (category) {
return getURL(category.url) + "/l/latest?status=open&assigned=nobody";
}
},
forceActive: (category, args, router) => {
const queryParams = router.currentRoute.queryParams;
return (
queryParams &&
Object.keys(queryParams).length === 2 &&
queryParams["assigned"] === "nobody" &&
queryParams["status"] === "open"
);
},
before: "top",
});
```
When forceActive is hit going from e.g.`http://localhost:3000/c/some-category/5/l/top` to `http://localhost:3000/c/some-category/5/l/latest?assigned=nobody&status=open` the `queryParams` are empty and the URL does not seem to change until after the transition and so `active` ends up being false in this `navigation-item` function which controls whether or not to do the highlight:
```javascript
@discourseComputed("content.filterType", "filterType", "content.active")
active(contentFilterType, filterType, active) {
if (active !== undefined) {
return active;
}
return contentFilterType === filterType;
},
```
Also sometimes this is not even recalculated, for example going from `http://localhost:3000/c/some-category/5/l/latest?status=open` to `http://localhost:3000/c/some-category/5/l/latest?assigned=nobody&status=open`. This PR fixes the issue where the query parameters changing was not forcing this recalculation. This was especially noticable in conjunction with https://github.com/discourse/discourse-loading-slider.
The title of Twitter oneboxes is always the name of the Twitter user,
which is not a descriptive topic title. Leave the title field blank so
that users must enter their own title.
By default our QUnit test runner starts automatically. This is normally
fine but for our `run-qunit.js` script we add a bunch of QUnit events
using `eval` and sometimes those events were added after the tests
already started/finished resulting in a hang.
This adds a new parameter that will cause QUnit not to run
automatically, which the runner uses, then triggers a `start()` when it
knows it's ready.
The signup boolean was being passed in the third _autoLogin argument, when it should have been the fourth. The third parameter to _autoLogin was optional, which is confusing. This commit cleans things up so both optional arguments are supplied via keywords.
Followup to cbef2ba151
This allows auth provider plugins to behave differently for login / signup. Previously, there was no way for them to know which button had been used.
This change will be a no-op in the majority of cases. If auth plugins wish to make use of this new feature, they should check for ?signup=true in the URL. For example: https://github.com/discourse/discourse-oauth2-basic/pull/34
* Fixes an issue where long translations cause layout issues
* Fixes an issue where the alignment shifts when switching between signup/login
* Makes some of the margin/padding more consistent
* Removes duplicate .login-modal and .create-account classes and replaces them with .login-modal-body and .create-account-body
* Adds another color transformation so we could remove prefers-color-scheme... the problem with that was that my OS' UI might be set to something different than my Discourse preferences (prefers-color-scheme only responds to OS UI settings)
* FEATURE: allow category group moderators to pin/unpin topics
Category group moderators should be able to pin/unpin any topics within a category where they have appropraite category group moderator permissions.
* DEV: Use Ember CLI middleware to decorate the index template
Previously we'd do this on the client side which did not support our
full plugin API. Now requests for the index template will contact the
dev server for a bootstrap.json and apply it to the current template.
* FIX: Allows logins in development mode for Ember CLI
* FIX: Show resend button only if an email was sent
Otherwise, show the "save and send email" button.
* UX: Copy change
* UX: Show feedback when link was copied
* FEATURE: Do not delete invite if link was copied
* FIX: Show error to user if invite redeeming fails
The error was only displayed to console.
* UX: Better placement of bulk buttons
Destroy all expired invites should be on the expired tab, not pending.
* FIX: Ensure invited_groups is unique per invite and group
* FIX: Do not refresh topic list if title unchanged
* FIX: Do not close modal on enter
This intereferes with the group and topic chooser.
Wrapping everything in a form disables this behavior.
* FIX: Move link and email options outside advanced section
* FIX: Do not close modal if saving a link invite
User may still want to copy the link.
* FIX: Do not show expired invites under Pending tab
* DEV: Controller action was renamed in previous commit
* FEATURE: Add 'Expired' tab to invites
* FEATURE: Refresh model after removing expired invites
* FEATURE: Do not immediately add invite to the list
Opening the 'create-invite' modal used to automatically generate an
invite to reserve an invite link. If the user did not save it and
closed the modal, the invite would be destroyed. This operations caused
the invite list to change in the background and confuse users.
* FEATURE: Sort redeemed users by creation time
* UX: Improve show / hide advanced options link
* FIX: Show redeemed users even if invites were trashed
* UX: Change modal title when editing invite
* UX: Remove Get Link button
Users can get it from the edit modal
* FEATURE: Add limit for invite links generated by regular users
* FEATURE: Add option to skip email
* UX: Show better error messages
* FIX: Show "Invited by" even if invite was trashed
Follow up to 1fdfa13a099d8e46edd0c481b3aaaafe40455ced.
* FEATURE: Add button to save without sending email
Follow up to c86379a465f28a3cc64a4a8c939cf32cf2931659.
* DEV: Use a buffer to hold all changed data
* FEATURE: Close modal after save
* FEATURE: Rate limit resend invite email
* FEATURE: Make the save buttons smarter
* FEATURE: Do not always send email even for new invites
Currently it's very tedious to bulk select hundreds of topics in a topic list -- each time a new batch of topics is loaded you have to scroll all the way to the top to click the `Select All` button and scroll back down to load the next batch, or you have to tick each topic individually.
This commit should make that process a lot easier because we will now remember if the `Select All` button was clicked and so whenever a new batch of topics is loaded, they'll automatically be selected.
Meta topic: https://meta.discourse.org/t/add-select-all-controls-at-the-bottom-of-the-list/178020/2?u=osama.
* Revert "Revert "A11Y: Switch tabs using the keyboard (#12241)" (#12260)"
This reverts commit 4c1e02d412.
* FIX: Make sure that the "menu-link" is present when a plugin adds a tab.
Other changes:
- We put the notification tab first using JS instead of CSS. It's important because of the tab number data attribute, which the keyboard navigation uses.
- We only set the button id from the attrs object if it's a tab. Otherwise, it conflicts with the topic footer button
The user interface has been reorganized to show email and link invites
in the same screen. Staff has more control over creating and updating
invites. Bulk invite has also been improved with better explanations.
On the server side, many code paths for email and link invites have
been merged to avoid duplicated logic. The API returns better responses
with more appropriate HTTP status codes.
remove 3 month option for topic timer
move relative time input inside the custom
date and time shortcut
make sure special options are always at the bottom
Add a new year interval option to relative time picker, and also fix some rounding issues (Math.floor is not ideal because it gets rid of half days etc.)
Also adding some component tests here for relative-time-picker.
* A11Y: Switch tabs using the keyboard
According to the WAI-ARIA Authoring Practices, tabs should be navigable using the left/right arrow keys.
Additionally, the screen reader couldn't correctly announce that a tab was selected when clicking the tab icon. To fix this, we made the SVG icon non-clickable and set the "aria-hidden" attribute to true.
* Handle navigation events using appEvents
This switches to outputting a separate file for each theme component CSS
asset. We have separate CSS plugin files, separate JS files
(for plugins/themes/components), it makes sense to do the same for
component CSS assets.
Benefits:
- easier debugging
- fixes a regression with theme component sourcemaps
- changes to theme components are updated individually
With HTTP/2, there is also no performance downside to having additional
files in the initial request.
- removes the option from site settings
- deletes the site setting on existing sites that have it
- marks posts using emojis as requiring a rebake
Note that the actual image files are not removed here, the plan is to
remove them in a few weeks/months (when presumably the rebaking of old
posts has been completed).
This switches to outputting a separate file for each theme component CSS
asset. We have separate CSS plugin files, separate JS files
(for plugins/themes/components), it makes sense to do the same for
component CSS assets.
Benefits:
- easier debugging
- fixes a regression with theme component sourcemaps
- changes to theme components are updated individually
With HTTP/2, there is also no performance downside to having additional
files in the initial request.
This commit includes other various improvements to watched words.
auto_silence_first_post_regex site setting was removed because it overlapped
with 'require approval' watched words.
Fixes failures in user-preferences-interface-test on Ember CLI.
Included:
* DEV: User themes have `theme_id` not `id`
* FIX: `themeId` could point to a non-existent theme
* DEV: Add request stub
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
This style is unnecessary because text inputs and textareas have
focus styles set elsewhere (lines 228 and 288 respectively) and we don't
have any `select` elements.
* A11Y: Improve the header menu "view all" title.
The title attribute has been used to attempt to provide the link with an accessible name, but the value of the title attribute is “view all” for the link in each of the tabs, and so their purpose is not uniquely identified.
Previously, the `{{mobile-nav}}` component required a `currentRouteName` property, passed from the router service. It would observe changes in this property, and update the UI accordingly.
If we change between routes which have the same `currentRouteName` (e.g. two different group message inboxes), then the `currentRouteName` does not change and does not trigger the observer. Currently in core, we are relying on the fact that currentRouteName temporarily enters a `.loading` substate during a transition. This will change when we remove the loading substate in the near future.
This commit refactors `{{mobile-nav}}` to inject the router directly, and use the `routeDidChange` event instead of an observer. The change is backwards compatible, but plugins passing the old `currentPath` property will be shown a deprecation notice.
On some modals the main/primary input field is a select-kit component (like `{{email-group-user-chooser}}` on the assign modal), so it makes sense to allow select-kit to steal focus on modals like these. This PR adds an `autofocus` option (default false) that allows select-kit to steal focus when it's rendered.
Included:
* DEV: Span can't contains divs
* DEV: Drop extra elements
* UX: Tweak `group` layout to fix button alignment
* UX: Add space between "Members" and "(N)"
This `if` statement was backwards, such that it was a no-op. This hasn't
caused a problem because clicking an item triggers a page load, which
destroys and recreates the component.
However, we are soon planning to remove the intermediate loading screen,
which means the component will not be removed/recreated.
https://meta.discourse.org/t/177939/202
* FIX: Subfolder replace should only affect URL prefix
Issue was reported in https://meta.discourse.org/t/-/179504
* DEV: Test subfolder handling in get-url when called twice on the same path
This PR adds an edit button to the topic timer info message which opens the modal.
Also, I have cleaned up a few more places where we were referencing "topic status update" which is what these were called prior to being called topic timers.
The category settings for auto-close topic hours has now also been modified to use the new relative-time-picker component.
Finally, the relative-time-picker input step and min is dynamic based on mins/other intervals selected, see https://review.discourse.org/t/feature-relative-time-input-for-timers-and-bookmarks-and-promote-auto-close-after-last-post-timer-12063/19204/7?u=martin
This PR adds a new relative-time component, that is an input box with a SK dropdown of minutes, hours, days, and months which outputs the duration selected in minutes. This new component is used in the time shortcuts list (used by bookmarks and topic timers) as a new Relative Time shortcut.
Also in this PR, I have made the "Auto-Close After Last Post" timer into a top level timer type in the UI, and removed the "based on last post" custom time shortcut.
Original PR was reverted because of broken migration https://github.com/discourse/discourse/pull/12058
I fixed it by adding this line
```
AND topics.id IN(SELECT id FROM topics ORDER BY created_at DESC LIMIT :max_new_topics)
```
This time it is left joining a limited amount of topics. I tested it on few databases and it worked quite smooth
* UX: Second Factor + Alert Display
This commit removes JS edits of the modal-alert and uses CSS instead. This commit also adds some styling to the 2FA login when using a key instead of a 2FA authenticator.
`{{user-selector}}` is now deprecated and it will be removed from core in Discourse 2.8. All instances of `{{user-selector}}` has been replaced with `{{email-group-user-chooser}}`.
* DEV: Show warning message when using ember css selectors
When editing the theme css via the admin UI a warning message
will be displayed if it detects that the `#emberXXX` or `.ember-view`
css selectors are being used. These are dynamic selectors that ember
generates, but they can change so they should not be used.
* Update error message text to be more helpful
* Display a warning instead of erroring out
This allows the theme to still be saved, but a warning is displayed.
Updated the tests to check for the error message.
Updated the pre tags css so that it wraps for long messages.
Normally we look at where the cursor is, but when the composer is closed
we don't have a cursor and just append at the end. This fix adds a new
line to make sure quotes will always work when inserted when the
composer is closed.
This commit adjusts the scroll gradient on the login modal, changes `email / username` to `Email / Username` and adjusts the color of social button icons on hover in the login modal.
Previously we would always take the first image in a post to use as the
thumbnail. On media-heavy sites, users may want to manually select a
specific image as the topic thumbnail. This commit allows this to be
done via a `|thumbnail` attribute in markdown.
For example, in this case, bbb would be chosen as the thumbnail:
```
![alttext|100x100](upload://aaa)
![alttext|100x100|thumbnail](upload://bbb)
```
Follow up https://github.com/discourse/discourse/pull/11968
Dismiss all new topics using the same DismissTopicService. In addition, MessageBus receives exact topic ids which should be marked as `seen`.
* FEATURE: Ability to dismiss new topics in a specific tag
Follow up of https://github.com/discourse/discourse/pull/11927
Using the same mechanism to disable new topics in a tag.
* FIX: respect when category and tag is selected
A user browser may rotate a user subscription endpoint/keys
anytime.
Currently, Discourse will receive a 4XX response while trying to
deliver a push notification and silently unsubscribe the device.
With this change, we will gracefully handle desativating the old
subscription and the replacement creation with the need for the user
to resubscribe manually every time it breaks.
https://meta.discourse.org/t/-/125179?u=falco
The 'Discourse SSO' protocol is being rebranded to DiscourseConnect. This should help to reduce confusion when 'SSO' is used in the generic sense.
This commit aims to:
- Rename `sso_` site settings. DiscourseConnect specific ones are prefixed `discourse_connect_`. Generic settings are prefixed `auth_`
- Add (server-side-only) backwards compatibility for the old setting names, with deprecation notices
- Copy `site_settings` database records to the new names
- Rename relevant translation keys
- Update relevant translations
This commit does **not** aim to:
- Rename any Ruby classes or methods. This might be done in a future commit
- Change any URLs. This would break existing integrations
- Make any changes to the protocol. This would break existing integrations
- Change any functionality. Further normalization across DiscourseConnect and other auth methods will be done separately
The risks are:
- There is no backwards compatibility for site settings on the client-side. Accessing auth-related site settings in Javascript is fairly rare, and an error on the client side would not be security-critical.
- If a plugin is monkey-patching parts of the auth process, changes to locale keys could cause broken error messages. This should also be unlikely. The old site setting names remain functional, so security-related overrides will remain working.
A follow-up commit will be made with a post-deploy migration to delete the old `site_settings` rows.
Previous markup used to be
```
<div>
<div>
<li>
```
Instead we will now have:
```
<ul>
<li>
<div>
```
Note this commit also adds two things:
- ability to override tagName of a widget when attaching it
- ability to pass opts and otherOpts to {{attach}}, it could be useful in templates but is mostly useful to test `tagName` for now
Previously it was using various willTransition and didTransition hooks
which can be quite fragile, especially when removing the
intermediate loading state.
This PR allows entering a float value for topic timers e.g. 0.5 for 30 minutes when entering hours, 0.5 for 12 hours when entering days. This is achieved by adding a new column to store the duration of a topic timer in minutes instead of the ambiguous both hours and days that it could be before.
This PR has ommitted the post migration to delete the duration column in topic timers; it will be done in a subsequent PR to ensure that no data is lost if the UPDATE query to set duration_mintues fails.
I have to keep the old keyword of duration in set_or_create_topic_timer for backwards compat, will remove at a later date after plugins are updated.
Some plugins (like discourse-calendar) import things from `@ember/string` and `rsvp`, so we need to add them in order for the plugins to work with Ember CLI.
This encompasses a lot of work done over the last year, much of which
has already been merged into master. This is the final set of changes
required to get Ember CLI running locally for development.
From here on it will be bug fixes / enhancements.
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
Co-authored-by: romanrizzi <rizziromanalejandro@gmail.com>
Co-authored-by: Jarek Radosz <jradosz@gmail.com>
Co-authored-by: romanrizzi <rizziromanalejandro@gmail.com>
It was introduced in c82b2dcc24, but since b76731d722 and 58ee947b35 it's a single-option dropdown, so there's no need to show it (and keep it) instead of a button. We use a button for non-admins already.
This pull requests contains a series of improvements to groups
settings and member management such as:
- Showing which users have set a group as primary
- Moving similar settings together under Effects
- Adding bulk select and actions to members page
This PR revamps the topic timer UI, using the time shortcut selector from the bookmark modal.
* Fixes an issue where the duration of hours/days after last reply or auto delete replies was not enforced to be > 0
* Fixed an issue where the timer dropdown options were not reloaded correctly if the topic status changes in the background (use `MessageBus` to publish topic state in the open/close timer jobs)
* Moved the duration input and the "based on last post" option from the `future-date-input` component, as it was only used for topic timers. Also moved out the notice that is displayed which was also only relevant for topic timers.
To prevent opaque cache files, now all the CDN files will be requested in 'cors' mode if the cdn_cors_enabled global setting is enabled. Before enabling the setting, should enable the cors in the CDN server by adding the response header `access-control-allow-origin: *` or `access-control-allow-origin: https://discourse.example.com.`
And other external file requests other than CDN will not be cached if the response type is opaque.
This PR makes it so the bookmark name shows on hover in the quick access menu. A change was necessary to quick-access-item for the title to render for the link.
Disabling shared drafts used to leave topics in an inconsistent state
where they were not displayed as shared drafts and thus there was no
way of publishing them. Moreover, they were accessible just to users
who have permissions to create shared drafts.
This commit adds another permission check that is used for most
operations and the old can_create_shared_draft? remains used just when
creating a new shared draft.
This PR is the first step towards replacing our `{{user-selector}}` and eventually deprecating and removing it from our codebase. Some of `{{user-selector}}` problems are:
1. It's called `{{user-selector}}`, but in reality in can also select groups and emails.
2. It's an Ember component, yet it doesn't have a handlebars template and uses jQuery to render itself and modify the DOM. An example of this problem is when you want to clear the selected users programmatically, see [this](6c155dba77/app/assets/javascripts/discourse/app/components/user-selector.js (L179-L185)).
3. We now have select kit which does very similar things but a lot better.
This PR introduces `{{email-group-user-chooser}}` which is meant to replace `{{user-selector}}`. It extends select kit and has the same features that `{{user-selector}}` has. `{{user-selector}}` is still used in a few places in core, but they'll all be replaced with the new component in a separate commit.
Once `{{user-selector}}` is not used anywhere in core, it'll be deprecated and then removed after the 2.7 release.
* sometimes the AJAX promise to create/save the bookmark did
not come back before the component destroyed, causing an error
when trying to set the model id afterward. this just eliminates
the set code and uses the response.id instead
This PR moves all of the time picking functionality from the bookmark modal and controller into a reusable time-shortcut-picker component, which will be used for the topic timer UI revamp. All of the utility JS for getting dates like tomorrow/next week/next month etc. have also been moved into a separate utility lib.
The time-shortcut-picker has a couple of options that can be passed in:
* prefilledDatetime - The date and time to parse and prefill into the custom date and time section, useful for editing interfaces.
* onTimeSelected (callback) - Called when one of the time shortcuts is clicked, and passes the type of the shortcut (e.g. tomorrow) and the datetime selected.
* additionalOptionsToShow - An array of option ids to show (by default `later_today` and `later_this_week` are hidden)
* hiddenOptions - An array of option ids to hide
* customOptions - An array of custom options to display (e.g. the option to select a post date for the bookmarks modal). The options should have the below properties:
* id
* icon
* label (I18n key)
* time (moment datetime object)
* timeFormatted
* hidden
The other major work in this PR is moving all of the bookmark functionality out of the bookmark modal controller and into its own component, where it makes more sense to be able to access elements on the page via `document`. Tests have been added to accompany this move, and existing acceptance tests for bookmark are all passing.
* Quite a few Ember-CLI / Upgrade related changes
They should all be backwards compatible. This is all to help merge our
branches.
* REFACTOR: DRY up username validation
Also avoids overwriting computed properties for compatibility with newer
Ember releases.
Adds a new column/setting to groups, allow_unknown_sender_topic_replies, which is default false. When enabled, this scenario is allowed via IMAP:
* OP sends an email to the support email address which is synced to a group inbox via IMAP, creating a group topic
* Group user replies to the group topic
* An email notification is sent to the OP of the topic via GroupSMTPMailer
* The OP has several email accounts and the reply is sent to all of them, or they forward their reply to another email account
* The OP replies from a different email address than the OP (gloria@gmail.com instead of gloria@hey.com for example)
* The a new staged user is created, the new reply is accepted and added to the topic, and the staged user is added to the topic allowed users
Without allow_unknown_sender_topic_replies enabled the new reply creates an entirely new topic (because the email address it is sent from is not previously part of the topic email chain).
Background: I wanted to see `categories.latest_by` translation in context in a live app but couldn't find it, so I traced it throughout the code.
My step-by-step reasoning for the removal is:
1. `categories-only` does not use `latestTopicOnly`, so there's no need to call it with that argument
2. `parent-category-row` is never called with `latestTopicOnly` argument, so the reference to that arg can be removed from its template
3. after that, `featured-topic` is now no longer ever called with `latestTopicOnly` argument (except in the `ghost` theme, but that's because its override of `categories-only` template 4e2fba963c/common/header.html (L119) is based on the old version of that template from core), so it seems safe to remove it there too (`categories.latest_by` i18n string is also no longer needed)
4. then, nothing is using `latestTopicOnly` anymore so it can be removed from `categories` hbs/js
I checked in each step that there are no plugins or themes (in all-the-plugins/all-the-themes) using those properties/arguments/strings.
This change fixes an issue with the user group chooser of a tag group's settings. It was impossible to clear any selected groups through the UI.
The `setPermissionsGroups` function determines which groups appear selected in the group-chooser based on the passed-in `groupIds` array.
It starts with `updatedPermissions` being set to the group permissions as they were prior to the action that called the function. From there, we were correctly adding a group permission to `updatedPermissions` whenever a group appeared in `groupIds`. This addressed newly added groups and also maintained any group permissions that had been set before. The problem was that there was no logic to remove a group permission when the associated group no longer appeared in `groupIds`. If a group isn't included in `groupIds`, we can simply attempt to delete an associated group permission if it exists.
The user summary's delete button UX relied on the "admin-user.js" destroy function, which was called through the "admin-tools" service. After #11724, we no longer put UX behavior on Ember models.
User title in the current-user header-dropdown was sometimes `title="null"` if user doesn’t have a name. This is fixed as part of this commit to improve accessibility of this part of the UI.
The bug was mentioned on [meta](https://meta.discourse.org/t/two-bugs-with-usernames-starting-with-subfolder-name/169505)
When discourse is installed on `/subfolder` and username is containing subfolder name like for example `subfolderadmin` - user URLs were incorrect.
Instead of having `/subfolder/u/subfolderadmin/summary/` we were leading to `/subfolder/uadmin/summary`.
The reason for that was incorrect check in `getUrl` helper:
```javascript
const found = url.indexOf(baseUri);
if (found >= 0 && found < 3) {
return url;
}
return baseUri + url;
```
baseUri is `/subfolder`, url is `/u/subfolderadmin` and indexOf returned position which in the end returned incorrect URL.
I think that we should check if the URL starts with baseUri and not if contains baseUri.
We only want to warn admins when both settings are enabled. When "set locale from accept language header" setting is enabled, the user locale will be set based on the header when they register an account on the site, which could be confusing.
- Improve warning message.
- Only display the warning if the language has a fallback and either "allow_user_locale", or "set_locale_from_accept_language_header" are enabled.
- The icon for the “view all” controls in the panels have no accessible alternative.
- Because the “Log Out” and "Do Not Disturb" elements in the preferences tab are an <a> element without an href attribute, it is not keyboard focusable and therefore not keyboard focusable. Use a button element instead.
* FEATURE: Give user menu icons alt attributes
This commit gives user menu icons + notifications alt attributes
* UI: Use Translations
This commit refactors the code injecting alt tags to the icons to use translations instead of hard-coded text.
* FIX: Add correct syntax for aria-label + role
This commit adds the correct accessibility syntax to the tab icons + notification icons.
This adds a new table UserNotificationSchedules which stores monday-friday start and ends times that each user would like to receive notifications (with a Boolean enabled to remove the use of the schedule). There is then a background job that runs every day and creates do_not_disturb_timings for each user with an enabled notification schedule. The job schedules timings 2 days in advance. The job is designed so that it can be run at any point in time, and it will not create duplicate records.
When a users saves their notification schedule, the schedule processing service will run and schedule do_not_disturb_timings. If the user should be in DND due to their schedule, the user will immediately be put in DND (message bus publishes this state).
The UI for a user's notification schedule is in user -> preferences -> notifications. By default every day is 8am - 5pm when first enabled.
* FEATURE: Give user menu icons alt attributes
This commit gives user menu icons + notifications alt attributes
* UI: Use Translations
This commit refactors the code injecting alt tags to the icons to use translations instead of hard-coded text.
Admins can now edit translations in different languages without having to change their locale. We display a warning when there's a fallback language set.
When selecting the "date in post" option from the bookmark reminder modal, it was not converting the date from the post, which may be in a completely different timezone, to the current user's timezone.
This PR fixes it so the timezone from the post is used to parse the date then converted to the user's timezone.
Going from /latest?f=tracked to /latest will result in three
different topic list requests because the query params are not
considered when determining if the route is staying the same.
Feature for `Must Approve Users` setup. When a user is rejected, a staff member can optionally set a reason for audit purposes. In addition, feedback email can be sent to the user.
Meta: https://meta.discourse.org/t/account-rejection-email/103112/8
It used to change the category of the topic, instead of the destination
category (topic.category_id instead of topic.shared_draft.category_id).
The shared drafts controls were displayed only if the current category
matched the 'shared drafts category', which was not true for shared
drafts that had their categories changed (affected by the previous bug).
Before this change we were setting the input after the query has been done, resulting in us overwriting the input if the user types during the query.
We don't need to update it after the query, we just need to ensure it's set when we load the page and then it should stay in sync.
A while ago we made a change to display a warning after installing a theme component when the admin tries to leave the page without adding the new installed component to any themes (see 5e29ae3ef5).
However there is an edge case that we forgot to address, and that's when an admin installs a component and then immediately opens the install modal again to install another one which can result in the warning being shown twice at the same time.
This PR prevents that by showing the warning when opening the install modal if the conditions are met (new component and not added to any themes) instead of showing it after installing the second component.
Installing multiple copies of the same theme/component is possible, but you rarely need to actually have multiple copies installed. We've seen many times new admins installing duplicates of components because they were unaware it was already installed. This PR makes the theme installer modal loop through the existing themes when you click on 'install', and if there is a theme with a URL that matches the URL you entered, a warning will show up and you will need to click 'install' again to proceed.
When you type # or @ in the search box, a popup appears with
autocomplete suggestions. Currently, when the popup is rendered it has
the first item selected and upon pressing Enter, the first item is
inserted into the search box. The problem with this behavior is that the
first suggestion may not be what you want, and if you are typing quickly
and hit enter, the first suggestion (which is not what you want) is
inserted in the search box.
This PR amends the popup so that it has no suggestions selected by
default which means the enter key will not insert anything unless you
select a suggestion via the up or down arrow keys.