* 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>
* 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}}`.
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.
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.
Scrolling was not working as expected after clicking the browser back button and navigating back to the tag topic list. We need to wrap the scroll inside a debounce function to ensure that the "window.pageYOffset" property is populated before our function runs.