Commit Graph
100 Commits
Author SHA1 Message Date
Alan Guo Xiang Tan 070eac16a8 PERF: Optimize the performance of TopicLink.topic_map query (#19630)
Instead of relying on the `ILIKE` operator to filter out image links, we
can instead rely on the `TopicLink#extension` column which allows us to
more efficiently filter out image links.

This optimization mainly affects topics that are link heavy which is
common in topics with alot of replies. When profiling a production
instance for a topic with 10K replies and 2.5K `topic_links`, this
optimization reduces the query time from ~18ms to around ~4ms.
2022-12-28 08:10:36 +08:00
Alan Guo Xiang Tan 1fd0e82da7 PERF: Fix N+1 queries problem on topic view page (#19629)
`User#flair_group` was not preloaded leading to the N+1 queries problem
when multiple users have flair groups.
2022-12-27 09:05:37 +08:00
Alan Guo Xiang Tan 1d926e88a9 FIX: Admin can't see user sidebar preferences of other users (#19570) 2022-12-23 11:45:29 +08:00
Alan Guo Xiang Tan c2a733a95a DEV: Make recent creation of chat index idempotent (#19603) 2022-12-23 10:23:57 +08:00
Alan Guo Xiang Tan a7f30cfcf7 PERF: Fix N+1 queries on /categories route (#19585)
Featured topics are eventually serialized by `ListableTopicSerializer`
which calls `Topic#image_url` which requires us to preload
`Topic#topic_thumbnails`.
2022-12-23 04:29:49 +08:00
Alan Guo Xiang Tan a8ee56ebee PERF: Remove unnecessary query from TopicQuery.remove_muted_tags (#19586)
When `default_tags_muted` site settings has not been set, there is no
need to execute the query.
2022-12-23 04:29:17 +08:00
Alan Guo Xiang Tan 954b39f5ec FIX: Sidebar preferences link shown when navigation menu is legacy (#19568) 2022-12-22 07:58:06 +08:00
Alan Guo Xiang Tan 4eee1320b0 PERF: Fix N+1 queries when serializing topic posters (#19545)
At the time of writing, this is how the `TopicPosterSerializer` looks
like:

```
class TopicPosterSerializer < ApplicationSerializer
  attributes :extras, :description

  has_one :user, serializer: PosterSerializer
  has_one :primary_group, serializer: PrimaryGroupSerializer
  has_one :flair_group, serializer: FlairGroupSerializer
end
```

Within `PosterSerializer`, the `primary_group` and `flair_group`
association is requested on the `user` object. However, the associations
have not been loaded on the `user` object at this point leading to the
N+1 queries problem. One may wonder
why the associations have not been loaded when the `TopicPosterSerializer`
has `has_one :primary_group` and `has_one :flair_group`. It turns out that `TopicPoster`
is just a struct containing the  `user`, `primary_group` and
`flair_group` objects. The `primary_group` and `flair_group`
ActiveRecord objects are loaded seperately in `UserLookup` and not preloaded when querying for
the users. This is done for performance reason so that we are able to
load the `primary_group` and `flair_group` records in a single query
without duplication.
2022-12-22 05:30:29 +08:00
Alan Guo Xiang Tan 6bcf558bae PERF: Stop serializing user in ChatChannelSerializer#current_user_membership (#19527)
The client already has all the information about the current user so
there is no need for us to be serializing the current `User` object each
time per channel that is preloaded.

In production, profiling shows that this unneeded serializing
adds a roughly 5% overhead to a request.
2022-12-22 05:30:06 +08:00
Alan Guo Xiang Tan 14d54872f0 PERF: Use MessageBus.last_ids instead of MessageBus.last_id for chat (#19523)
Prior to this change, each request executed 2 Redis calls per chat channel
that was loaded. The number of Redis calls quickly adds up once a user
is following multiple channels.
2022-12-20 08:20:45 +08:00
Alan Guo Xiang Tan a176ce2fd0 PERF: Remove unnecessary SQL UNION query when search public channels (#19515)
It is pointless to include DM channels because the query for public
channel search restricts chatable type to `Category`.
2022-12-20 07:52:26 +08:00
Alan Guo Xiang Tan 80d289eb8b PERF: Add index for chat unread counts query (#19516)
This commit adds an index for the query which the chat plugin executes
multiple times when preloading user data in `Chat::ChatChannelFetcher.unread_counts`.

Sample query plan from a query I grabbed from one of our production
instance.

Before:

```
                                                                                        QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=10.77..696.67 rows=7 width=16) (actual time=7.735..7.736 rows=0 loops=1)
   Group Key: cc.id
   ->  Nested Loop  (cost=10.77..696.54 rows=12 width=8) (actual time=7.734..7.735 rows=0 loops=1)
         Join Filter: (cc.id = cm.chat_channel_id)
         ->  Nested Loop  (cost=0.56..76.44 rows=1 width=16) (actual time=0.011..0.037 rows=7 loops=1)
               ->  Index Only Scan using chat_channels_pkey on chat_channels cc  (cost=0.28..22.08 rows=7 width=8) (actual time=0.004..0.014 rows=7 loops=1)
                     Index Cond: (id = ANY ('{192,300,228,727,8,612,1633}'::bigint[]))
                     Heap Fetches: 0
               ->  Index Scan using user_chat_channel_unique_memberships on user_chat_channel_memberships uccm  (cost=0.28..7.73 rows=1 width=8) (actual time=0.003..0.003 rows=1 loops=7)
                     Index Cond: ((user_id = 1338) AND (chat_channel_id = cc.id))
         ->  Bitmap Heap Scan on chat_messages cm  (cost=10.21..618.98 rows=89 width=12) (actual time=1.096..1.097 rows=0 loops=7)
               Recheck Cond: (chat_channel_id = uccm.chat_channel_id)
               Filter: ((deleted_at IS NULL) AND (user_id <> 1338) AND (id > COALESCE(uccm.last_read_message_id, 0)))
               Rows Removed by Filter: 2085
               Heap Blocks: exact=7106
               ->  Bitmap Index Scan on index_chat_messages_on_chat_channel_id_and_created_at  (cost=0.00..10.19 rows=270 width=0) (actual time=0.114..0.114 rows=2085 loops=7)
                     Index Cond: (chat_channel_id = uccm.chat_channel_id)
 Planning Time: 0.408 ms
 Execution Time: 7.762 ms
(19 rows)
```

After:

```
                                                                                        QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 GroupAggregate  (cost=5.84..367.39 rows=7 width=16) (actual time=0.130..0.131 rows=0 loops=1)
   Group Key: cc.id
   ->  Nested Loop  (cost=5.84..367.26 rows=12 width=8) (actual time=0.129..0.130 rows=0 loops=1)
         Join Filter: (cc.id = cm.chat_channel_id)
         ->  Nested Loop  (cost=0.56..76.44 rows=1 width=16) (actual time=0.038..0.069 rows=7 loops=1)
               ->  Index Only Scan using chat_channels_pkey on chat_channels cc  (cost=0.28..22.08 rows=7 width=8) (actual time=0.011..0.022 rows=7 loops=1)
                     Index Cond: (id = ANY ('{192,300,228,727,8,612,1633}'::bigint[]))
                     Heap Fetches: 0
               ->  Index Scan using user_chat_channel_unique_memberships on user_chat_channel_memberships uccm  (cost=0.28..7.73 rows=1 width=8) (actual time=0.006..0.006 rows=1 loops=7)
                     Index Cond: ((user_id = 1338) AND (chat_channel_id = cc.id))
         ->  Bitmap Heap Scan on chat_messages cm  (cost=5.28..289.71 rows=89 width=12) (actual time=0.008..0.008 rows=0 loops=7)
               Recheck Cond: ((chat_channel_id = uccm.chat_channel_id) AND (id > COALESCE(uccm.last_read_message_id, 0)) AND (deleted_at IS NULL))
               Filter: (user_id <> 1338)
               ->  Bitmap Index Scan on index_chat_messages_on_chat_channel_id_and_id  (cost=0.00..5.26 rows=90 width=0) (actual time=0.008..0.008 rows=0 loops=7)
                     Index Cond: ((chat_channel_id = uccm.chat_channel_id) AND (id > COALESCE(uccm.last_read_message_id, 0)))
 Planning Time: 1.217 ms
 Execution Time: 0.188 ms
(17 rows)
```
2022-12-20 05:10:53 +08:00
Alan Guo Xiang Tan 4ea6b09fc7 PERF: Remove unnecessary DB queries when preloading for chat (#19514)
Use `Chat::ChatChannelFetcher.secured_public_channel_search` directly
checking for existence instead of running through
`Chat::ChatChannelFetcher.secured_public_channels` which executes 7 more
DB queries.
2022-12-19 15:34:07 +08:00
Alan Guo Xiang Tan 68d5bdefdd DEV: Skip flaky tests (#19511) 2022-12-19 11:36:04 +08:00
Alan Guo Xiang Tan 5bd29b89dd DEV: Add missing test case (#19510)
Follow-up to f77660b047
2022-12-19 10:09:19 +08:00
Alan Guo Xiang Tan 5d2e2677c0 FIX: Invalid route path for staff info warnings link (#19461)
This regressed in 4da2e3fef4
2022-12-14 07:14:01 +08:00
Alan Guo Xiang Tan 0abd772098 DEV: Pass in site guardian for Plugin::Instance.register_site_categories_callback (#19430)
The guardian is useful for plugins to determine if the callback should
do anything. A common use case is to not do anything in the callback if
the user is anonymous.
2022-12-13 07:49:13 +08:00
Alan Guo Xiang Tan ab4158d257 DEV: Flush redis db after each system test (#19415)
This ensures that all system tests are starting from a clean state and
not leak state between requests. Note that we have to simplify flush the
Redis db here because it is not pratical to manually clean up Redis keys
in system tests.
2022-12-12 07:53:39 +08:00
Alan Guo Xiang Tan 332ac0f299 UX: Exclude child catgegories of muted category in similar to search (#19414)
Follow-up to 207b764ea3
2022-12-12 06:31:46 +08:00
Alan Guo Xiang Tan b50d071307 DEV: Update copy for navigation_menu site setting (#19390) 2022-12-09 06:25:11 +08:00
Alan Guo Xiang Tan fde9e6bc25 DEV: Migrate sidebar site settings (#19336)
This new site setting replaces the
`enable_experimental_sidebar_hamburger` and `enable_sidebar` site
settings as the sidebar feature exits the experimental phase.

Note that we're replacing this without depreciation since the previous
site setting was considered experimental.

Internal Ref: /t/86563
2022-12-08 09:44:29 +08:00
Alan Guo Xiang Tan c79eec7fdc DEV: Add system test for updating color scheme of a theme (#19370)
Follow-up to 63119144ff
2022-12-08 08:38:36 +08:00
Alan Guo Xiang Tan 773cf045b2 DEV: Update redis gem to 4.8.0 (#19350) 2022-12-08 06:48:44 +08:00
Alan Guo Xiang Tan 207b764ea3 UX: Exclude search ignored and user muted categories in similarity search (#19349)
When finding the candidates for `Topic.similar_to`, we will now ignore
topics in categories where `Category#search_priority` has been set to
ignore and also topics in categories which the user has specifically
muted.

Internal Ref: /t/87132
2022-12-07 11:33:01 +08:00
Alan Guo Xiang Tan ff40c890ac DEV: Correct order of triggering topic trashed and recovered event (#19313)
Previously we would trigger the event before the `Topic#deleted_at`
column has been updated making it hard for plugins to correctly work
with the model when its new state has not been persisted in the
database.
2022-12-06 05:56:16 +08:00
Alan Guo Xiang Tan 02f48414b8 FEATURE: Add experimental plugin API to register messages nav dropdown (#19294)
This commit also removes the `user-messages-nav` plugin outlet without
deprecation in the redesigned user page navigation.
2022-12-05 12:31:09 +08:00
Alan Guo Xiang Tan 9b5bc60325 DEV: Simplify new user page nav messages dropdown. (#19289)
With the refactoring of the user messages routes in
4da2e3fef4, we can now depend on the top
level routes like `userPrivateMessages.user`, `userPrivateMessages.group` and `userPrivateMessages.tags`
to determine what the active value for the dropdown should be which
greatly simplifies the logic.
2022-12-02 10:02:04 +08:00
Alan Guo Xiang Tan a2cec6366f DEV: Port user-private-messages controller to native class (#19285) 2022-12-02 07:02:04 +08:00
Alan Guo Xiang Tan fb2507c6ce DEV: Centralise logic for updating sidebar section links (#19275)
The centralization helps in reducing code duplication in our code base
and more importantly, centralizing logic for guardian checks into a
single spot.
2022-12-01 09:32:35 +08:00
Alan Guo Xiang Tan 4da2e3fef4 DEV: Group and nest routes in userPrivateMessages into child routes (#19190)
Currently this is how the navigation structure looks like on the messages page: 

#### When personal inbox route is active

```
Inbox
  sent
  new
  unread
  archive
Group 1 Inbox
Group 2 Inbox
Tags
<Plugin Outlet>
```

#### When group inbox route is active

```
Inbox
Group 1 Inbox
  sent
  new
  unread
  archive
Group 2 Inbox
Tags
<Plugin Outlet>
```

With the existing structure, it is very easy for plugins to add additional navigation links by using the plugin outlet. In the redesigned user page navigation, the navigation structure on the messages page has been changed to look like this: 

#### When personal inbox route is active

```
---dropdown-------
| Inbox          |   Latest | Sent | New | Unread | Archive
------------------
```

#### When group inbox route is active 

```
---dropdown------
| Group 1 Inbox |   Latest | New | Unread | Archive
-----------------
```

With the new navigation structure, we can no longer rely on a simple plugin outlet to extend the navigation structure. Instead, we will need to introduce a plugin API for plugins to extend the navigation structure. The API needs to allow two things to happen: 

1. The plugin API needs to allow the plugin to register an item in the drop down and for the registered item to be "selected" whenever the plugin's routes are active. 

1. The plugin API needs to allow the plugin to register items into the secondary horizontal navigation menu beside the drop down. 

While trying to design the API, I struggle with trying to determine the "context" of the current route. In order words, it was hard to figure out if the current user is viewing the personal inbox, group inbox or tags. This is attributed to the fact that our current routing structure looks like this:

```
this.route(
  "userPrivateMessages",
  { path: "/messages", resetNamespace: true },
  function () {
    this.route("new");
    this.route("unread");
    this.route("archive");
    this.route("sent");
    this.route("warnings");
    this.route("group", { path: "group/:name" });
    this.route("groupArchive", { path: "group/:name/archive" });
    this.route("groupNew", { path: "group/:name/new" });
    this.route("groupUnread", { path: "group/:name/unread" });
    this.route("tags");
    this.route("tagsShow", { path: "tags/:id" });
  }
);
```

In order to provide context of the current route, we currently require all child routes under the `userPrivateMessages` route to set a `pmView` property on the `userPrivateMessages` controller. If the route requires additional context like the group currently active on the group inbox routes, the child routes would then have to set the `group` property on the `userPrivateMessages` controller. The problems with this approach is that we end up with many permutations of state on the `userPrivateMessages` controller and have to always clean up the state when navigating between the child routes. Basically, data is flowing upwards from the child routes into the parent controller which is not an ideal approach because we cannot easily determine where the "data" setup happens. Instead, we want to follow something similar to the "Data down, actions up" pattern where data flows downwards. In this commit, the `userPrivateMessages` routes have been changed to look like this: 

```
this.route(
  "userPrivateMessages",
  { path: "/messages", resetNamespace: true },
  function () {
    this.route("user", { path: "/" }, function () {
      this.route("new");
      this.route("unread");
      this.route("archive");
      this.route("sent");
      this.route("warnings");
    });

    this.route("group", { path: "group/:name" }, function () {
      this.route("archive");
      this.route("new");
      this.route("unread");
    });

    this.route("tags", { path: "/tags" }, function () {
      this.route("show", { path: ":id" });
    });
  }
);
```

Basically, we group the child routes based on the purpose each route servers. User inbox routes are grouped together while group inbox routes are grouped together. A big benefit of this is that now have a different Ember router and controller for each grouping of child routes. The context of the current route is then tied directly to the route name instead of requiring each child route to set an attribute on the parent controller. 

The second reason for why we needed to group the child routes together is because it allows us to pass the responsibility of rendering the secondary navigation links to the child routes. In this commit, we use the `{{in-element}}` modifier in the child route to render the secondary navigation links.

```
---dropdown--------
| Group 1 Inbox   |     Latest | New | Unread | Archive
------------------------
<parent template>    <horizontal secondary navigation links element>
```

This means that each child route with its own model and context can then handle the responsibility of rendering the secondary navigation links without having to pass its context up to the `userPrivateMessages` controller. While this should have simplified by the `userPrivateMessages` controller, we can't do that in this commit because our current navigation structure requires all links for all message inboxes to remain on screen at all times. Once we fully transition to the redesigned user menu navigation, we will be able to greatly simplify things around the routes and controllers for `userPrivateMessages`. 

In an ideal world, we would deprecate the old routes but I have done a quick search through all known plugins and no plugins are currently relying on those routes. There is a chance we could break plugins here but I'll like to see some smoke first before committing to the effort of deprecating client side routes.
2022-12-01 09:21:12 +08:00
Alan Guo Xiang Tan 5103268312 DEV: Run system tests with documentation and profiling on actions (#19271)
When a test takes too long, we want to know which test and at what step
2022-12-01 05:54:17 +08:00
Alan Guo Xiang TanandJoffrey JAFFEUX 7688628993 FIX: horizontal scrolling was not working correctly (#19236)
Fixes broken behaviour of arrow buttons for certain users as the interval to scroll menu can be cancelled before the scrolling actually happens.

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2022-12-01 05:27:53 +08:00
Alan Guo Xiang TanandRafael dos Santos Silva 7c321d3aad PERF: Update Group#user_count counter cache outside DB transaction (#19256)
While load testing our user creation code path in production, we
identified that executing the DB statement to update the `Group#user_count` column within a
transaction is creating a bottleneck for us. This is because the
creation of a user and addition of the user to the relevant groups are
done in a transaction. When we execute the DB statement to update
`Group#user_count` for the relevant group, a row level lock is held
until the transaction completes. This row level lock acts like a global
lock when the server is creating users that will be added to the same
group in quick succession.

Instead of updating the counter cache within a transaction which the
default ActiveRecord `counter_cache` option does, we simply update the
counter cache outside of the committing transaction.

Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com>

Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com>
2022-11-30 11:52:08 -03:00
Alan Guo Xiang Tan 8b2c2e5c34 UX: Align user page dismiss notifications btn with new navigation (#19235)
This change only affects the redesign user page navigation menu. The
dismiss button was incorrectly positioned below the user notifications
stream. A side effect of this is that it affected our infinite loading
code for the notifications stream.

No tests have been added in this commit as we have yet to quite figure
out how we can reliabily test for behaviours which requires us to scroll
the page.
2022-11-29 10:33:31 +08:00
Alan Guo Xiang Tan f14189eb3b FIX: PMs displaying outdated unread counts when read status is processing (#19217)
When a client "reads" a post, we do no immediately send the data of the
post for processing on the server. Instead, read posts data is batched
together and sent to the server for processing at regular intervals. On
the server side, processing of read posts data is done in the
background. As such, there is a small window of delay before a post is
marked as read by a user on the server side.

If a client reads a topic and loads the messages topic list before the
server has processed the read post, the unread posts count for the topic
which the client just read will appear to be incorrect/outdated.

As part of tracking a post as read, we are already tracking the highest
read post number for the last read topic by the client. Therefore, we
can use this information to correct the highest post read number in the
scenario that was described above. This solution is the same as what
we've been doing for the regular topics list.
2022-11-29 05:55:48 +08:00
Alan Guo Xiang Tan 20715cd7f0 DEV: Refactor messages code to use user.groupsWithMessages function (#19189)
Simplifies the template since we have one less conditional and one less
level of nesting
2022-11-25 11:23:50 +08:00
Alan Guo Xiang Tan 45f3e9f19e DEV: Publish reviewable claimed topic message to groups instead of users (#19188)
I'm hesitant to call this a performance improvement since claiming a
reviewable is probably rare. However, this commit cuts out two DB
queries each time we have to publish a reviewable claimed message. More
importantly, publishing to groups scales much better than publishing to
users because we esstentially cap the number ids we have to load into
memory.
2022-11-25 08:07:29 +08:00
Alan Guo Xiang Tan 470b8b8984 DEV: Simplifying rendering of secondary nav links for group inbox (#19164)
Also run user private messages page tests against redesign user page nav
2022-11-24 05:07:41 +08:00
Alan Guo Xiang Tan 5552e257d8 UX: Styling backwards compatibility for old user page navigation (#19161)
While updating all user pages to use the new horizontal, scrollable user
page navigation, we've inadvertently broken the interface for plugins which rely on the
`user-main-nav` plugin outlet to extend the user profile page. Such
plugins usually add a new user profile page with the following
template structure which is copied from Discourse core before the user
page navigation redesign:

```
{{#d-section pageClass="..." class="user-secondary-navigation" scrollTop=false}}
  {{#mobile-nav class="..." desktopClass="action-list nav-stacked"}}
    ...
  {{/mobile-nav}}
{{/d-section}}

<section class="user-content">
  {{outlet}}
</section>
```

This commit seeks to add backwards compatibility in terms of the styling
of the interface such that even if the old template structure is used,
it would not look completely broken.
2022-11-23 11:53:08 +08:00
Alan Guo Xiang Tan d3366a9092 DEV: Centralise user preferences security test into a single file (#19121)
* Makes it easier to find all the related tests for the particular route
* Remove some tests that don't really provide much value against regressions
2022-11-22 07:43:30 +08:00
Alan Guo Xiang Tan e05cd5de8f DEV: Add tests for sidebar accessibility changes (#19138)
Accessibility is a feature which we do not want to regress on.

Follow-up to e30df22716
2022-11-22 06:07:47 +08:00
Alan Guo Xiang Tan 59e02bd210 UX: Removed tracked section link from Community section in Sidebar (#19122)
Product has decided that the tracked section link provides very little
value at this moment in time so we're removing it.

See https://meta.discourse.org/t/245374 for more context.
2022-11-21 16:45:19 +08:00
Alan Guo Xiang Tan a64d2364ec FIX: Correct implementation for user preferences tracking page (#19119)
The user preferences tracking page is only present when the redesign
user navigation menu is enabled. During the first pass of
implementation, some old bugs were introduced and this commit fixes
that. Regression tests have also been added.
2022-11-21 14:48:47 +08:00
Alan Guo Xiang Tan a8eb607162 DEV: Centralise user preferences account route tests into single file (#19118)
Makes it easier to associate the route with the tests instead of
squeezing difference acceptance modules into a single file
2022-11-21 13:09:33 +08:00
Alan Guo Xiang Tan 6d8a93ac41 DEV: Centralise more user preferences tests into individual files (#19100)
Makes it easier to associate the route with the tests
2022-11-21 10:16:47 +08:00
Alan Guo Xiang Tan 6867b8226d DEV: Fix lint failures (#19101) 2022-11-18 11:26:33 +01:00
Alan Guo Xiang Tan af0c7ff453 DEV: Move 2FA preferences tests into individual files (#19099)
This helps to make it easier to identify the test file for the
particular route.
2022-11-18 11:40:40 +08:00
Alan Guo Xiang Tan fde8d9b4bb DEV: Move tests for user preferences change email into own file (#19097)
This helps to make it easier to identify the test file for the
particular route.
2022-11-18 11:40:22 +08:00
Alan Guo Xiang Tan 5e516a7d7d DEV: Split tests for user preferences security page into individual file (#19096)
Mixing multiple acceptance tests in a single file makes the acceptance
tests much harder to find.
2022-11-18 11:40:05 +08:00
Alan Guo Xiang Tan 41eb92f5db UX: Change ordering of categories shown in sidebar (#18803)
There are two possible ordering for categories shown in sidebar with
this commit.

When the `fixed_category_positions` site setting is enabled, the
categories are ordered based on `Category#position` which is a configurable
option by the user. When said site setting is disabled, the categories
are ordered based on `Category#name`.

The categories in Sidebar are also sorted in such a way where child
categories are always ordered right after their parents. When multiple
child categories are present, the child categories are ordered based on
the ordering described above.
2022-11-04 05:21:49 +09:00
Alan Guo Xiang Tan d446ad3290 UX: Muted style for entire chat section link when muted (#18852) 2022-11-03 08:37:39 +09:00
Alan Guo Xiang Tan 46e9f402eb DEV: Avoid cloning site settings in QUnit tests (#18811)
`siteSettings` is now a service which means there should only be one
state for `siteSettings` during the life time of the application. This
also helps to maintain parity with production where the `site` model
relies on the `siteSettings` service and not a clone of the attributes.
2022-11-02 20:07:17 +09:00
Alan Guo Xiang Tan 02304cae83 FIX: Can't change notification level of categories set to regular (#18801)
This commit fixes a bug on the client site where we would include the
`regular_category_ids` field when trying to update the notification levels of
categories for a user. The `regulary_category_ids` field should only be
included when the `mute_all_categories_by_default` is enabled
2022-11-01 07:15:53 +08:00
Alan Guo Xiang Tan cfefdf0832 UX: Switch no categories/tags configured text in sidebar to a link (#18787)
Internal Ref: /t/73500
2022-10-31 06:42:55 +08:00
Alan Guo Xiang Tan 4244b1c57d FIX: Ignore unique conflicts when backfilling sidebar defaults (#18785)
`insert_all!` raises an error when the insertion violates any unique
constraints which is not what we want here.

Follow-up to 1b56a55f50
2022-10-28 07:47:41 +08:00
Alan Guo Xiang Tan 101ec21bc9 SECURITY: Restrict display of topic titles associated with user badges (#18768)
Before this commit, we did not have guardian checks in place to determine if a
topic's title associated with a user badge should be displayed or not.
This means that the topic title of topics with restricted access
could be leaked to anon and users without access if certain conditions
are met. While we will not specify the conditions required, we have internally
assessed that the odds of meeting such conditions are low.

With this commit, we will now apply a guardian check to ensure that the
current user is able to see a topic before the topic's title is included
in the serialized object of a `UserBadge`.
2022-10-27 11:26:14 +08:00
Alan Guo Xiang Tan 1b56a55f50 DEV: Sidebar default tags and categories are determined at user creation (#18620)
The previous sidebar default tags and categories implementation did not
allow for a user to configure their sidebar to have no categories or
tags. This commit changes how the defaults are applied. When a user is being created,
we create the SidebarSectionLink records based on the `default_sidebar_categories` and
`default_sidebar_tags` site settings. SidebarSectionLink records are
only created for categories and tags which the user has visibility on at
the point of user creation.

With this change, we're also adding the ability for admins to apply
changes to the `default_sidebar_categories` and `default_sidebar_tags`
site settings historically when changing their site setting. When a new
category/tag has been added to the default, the new category/tag will be
added to the sidebar for all users if the admin elects to apply the changes historically.
Like wise when a tag/category is removed, the tag/category will be
removed from the sidebar for all users if the admin elects to apply the
changes historically.

Internal Ref: /t/73500
2022-10-27 06:38:50 +08:00
Alan Guo Xiang Tan a473e352de DEV: Introduce TopicGuardian#can_see_topic_ids method (#18692)
Before this commit, there was no way for us to efficiently check an
array of topics for which a user can see. Therefore, this commit
introduces the `TopicGuardian#can_see_topic_ids` method which accepts an
array of `Topic#id`s and filters out the ids which the user is not
allowed to see. The `TopicGuardian#can_see_topic_ids` method is meant to
maintain feature parity with `TopicGuardian#can_see_topic?` at all
times so a consistency check has been added in our tests to ensure that
`TopicGuardian#can_see_topic_ids` returns the same result as
`TopicGuardian#can_see_topic?`. In the near future, the plan is for us
to switch to `TopicGuardian#can_see_topic_ids` completely but I'm not
doing that in this commit as we have to be careful with the performance
impact of such a change.

This method is currently not being used in the current commit but will
be relied on in a subsequent commit.
2022-10-27 06:13:21 +08:00
Alan Guo Xiang Tan fd993240fd DEV: Add missing assertion for InvitesController test (#18755) 2022-10-26 13:04:55 +01:00
Alan Guo Xiang Tan 305b7c8fae DEV: Update rubocop (#18754) 2022-10-26 09:05:15 +08:00
Alan Guo Xiang Tan d85c89ba6d FIX: Category chooser not updating selection when editing reviewable (#18737) 2022-10-25 09:13:37 +08:00
Alan Guo Xiang Tan 0ffd408674 DEV: Remove harded id when fabricating in tests (#18729)
Hardcoding ids always lead to sadness for our test suite
2022-10-25 06:18:40 +08:00
Alan Guo Xiang Tan c752d68737 DEV: Fabricate instead of just building topic, post and user in tests (#18698)
Building does not persist the object in the database which is
unrealistic since we're mostly dealing with persisted objects in
production.

In theory, this will result our test suite taking longer to run since we
now have to write to the database. However, I don't expect the increase
to be significant and it is actually no different than us adding new
tests which fabricates more objects.
2022-10-24 05:51:41 +08:00
Alan Guo Xiang Tan 5fbd16926b DEV: Add missing test case for TopicGuardian#can_see_topic? (#18694)
Staged users are allowed to view topics they created in a read restricted category
when category has `Category#email_in` and
`Category#email_in_allow_strangers` configured.
2022-10-21 16:40:46 +08:00
Alan Guo Xiang Tan fff575ffd2 FEATURE: Add sidebar link for admin to configure default tags (#18593)
Displays a sidebar section link to admin users when
`default_sidebar_tags` site setting has not been configured for the
site.

Internal Ref: /t/73500
2022-10-17 12:08:32 +08:00
Alan Guo Xiang Tan ae6549a6ea FEATURE: Add sidebar link for admin to configure default categories (#18595)
Displays a sidebar section link to admin users when
`default_sidebar_categories` site setting has not been configured for the
site.

Internal Ref: /t/73500
2022-10-17 12:08:15 +08:00
Alan Guo Xiang Tan d1304ecb46 DEV: Move sidebar site settings to the sidebar category (#18596)
Sidebar category is only shown in the admin panel when `enable_experimental_sidebar_hamburger` site setting is enabled
2022-10-17 10:33:15 +08:00
Alan Guo Xiang Tan c16cb0e00b FIX: Missing category badge for category with color stored as 3-digit hex code (#18579)
On the server side, the only limitation for `Category#color` is a length
limit of 6. Therefore, we cannot assume on the client side that the hex
code is always 6 digits.
2022-10-13 17:00:46 +08:00
Alan Guo Xiang Tan 7e94fa86d7 FIX: Category sidebar link not active when filtered by none and all (#18578) 2022-10-13 17:00:20 +08:00
Alan Guo Xiang Tan 940eb0ce4d UX: Conditionally display sidebar tags section for user (#18558)
If a site has no default sidebar tags configured, show tags section if the user has personal sidebar tags configured.
Otherwise, hide the tags section from the sidebar for the user.

If a site has default sidebar tags configured, always display the tags section.
2022-10-13 09:52:25 +08:00
Alan Guo Xiang Tan 8e80f4c211 UX: Conditionally hide sidebar categories section for user (#18557)
If a site has no default sidebar categories configured:
  * Show categories section if user has categories configured
  * Hide categories section if user does not have categories configured

If a site has default sidebar categories configured:
  * Always show categories section
2022-10-13 09:18:39 +08:00
Alan Guo Xiang Tan deb0656b63 UX: Hide tags section in sidebar when user has no visible tags (#18539)
Also hides the tags configuration for sidebar under user preferences

Internal ref: /t/73500
2022-10-13 08:37:28 +08:00
Alan Guo Xiang Tan b75dc04a25 UX: Hide tags section from anonymous user when site has no tags (#18538)
If there are no top tags that an anonymous user can see and the site do
not have default sidebar tags configured for anonymous users, hide the
tag section entirely.
2022-10-11 13:33:50 +08:00
Alan Guo Xiang Tan a7bdd0a58e PERF: Exclude anon sidebar tags in site serializer for logged in user (#18527)
This commits excludes the `anonymous_default_sidebar_tags` property in `SiteSerializer` when user
is not anonymous and when tagging has been disabled.
2022-10-11 08:45:22 +08:00
Alan Guo Xiang Tan b2a14eeb16 FIX: Ensure group inboxes in messages section is sorted by group name (#18508) 2022-10-10 14:47:55 +08:00
Alan Guo Xiang Tan 14532ad425 DEV: Try out double nav for new experimental user page nav (#18495)
No tests and this redesign is still highly highly experimental
2022-10-07 12:20:39 +08:00
Alan Guo Xiang Tan 3629b2de1b DEV: Add tests for SiteSerializer#top_tags (#18498) 2022-10-06 15:58:55 +08:00
Alan Guo Xiang Tan f3392a5a81 DEV: Avoid configuring Rails configuration in tests (#18499) 2022-10-06 15:45:19 +08:00
Alan Guo Xiang Tan 89ac01704e DEV: Remove contextual topic list linking behaviour in sidebar (#18485)
The feedback we got here is that the contextual topic list link
behaviour is surprising and people prefer that the topic list sidebar
links always go to a consistent location.

Internal ref: /t/74666/16
2022-10-06 08:15:05 +11:00
Alan Guo Xiang Tan 2559c763ad DEV: Fix message section link filters displaying icons (#18484)
Follow-up to c0037dc0f0
2022-10-05 17:59:50 +08:00
Alan Guo Xiang Tan c0037dc0f0 FIX: Missing sidebar section link icon for PM tags (#18481)
No tests cause a missing icon regression is not the end of the world and
I don't feel like it will provide enough value as a regression test long
term.
2022-10-05 14:20:03 +08:00
Alan Guo Xiang Tan 637b1211b5 DEV: Convert experimental user page activity nav to horizontal nav (#18483)
As usual, design is still in flux so no tests for now.

Internal Ref: /t/67780/59
2022-10-05 14:19:46 +08:00
Alan Guo Xiang Tan 63b7f7c85c UX: More... -> More in Sidebar (#18482)
We already have an icon so `...` is redundant
2022-10-05 12:50:30 +08:00
Alan Guo Xiang Tan 90f1e2df80 FIX: Link to discovery.category in sidebar` (#18467)
`discovery.category` route respects the default view of the category as
configured by `Category#default_view`. `discovery.latestCategory` forces
the latest filter when viewing the category which is not what we want.

https://meta.discourse.org/t/239999
2022-10-05 09:54:32 +08:00
Alan Guo Xiang Tan c654bdbfa9 DEV: Experimental changes to user page notifications nav (#18466)
No tests as the changes are experimental and unconfirmed

Internal Ref: /t/67780/58
2022-10-04 15:18:54 +08:00
Alan Guo Xiang Tan ba2c5c7948 UX: Hide sidebar on 2FA route (#18464)
Internal Ref: /t/75929
2022-10-04 14:23:20 +08:00
Alan Guo Xiang Tan 044dc85358 DEV: Remove broken line of code (#18465)
The router service isn't even injected so the code is not used and
broken.
2022-10-04 13:37:25 +08:00
Alan Guo Xiang Tan de071fc1e8 DEV: Convert messages user page nav to experimental redesign (#18456)
No tests are written for now as we're still in a highly iterative stage
2022-10-04 12:05:09 +08:00
Alan Guo Xiang Tan 76a79b6adf UX: Change notifications nav icon in user page to bell (#18455)
Now that we have chat, the comment icon is no longer ideal

Internal Ref: /t/67780/55
2022-10-04 10:48:33 +08:00
Alan Guo Xiang Tan c5544a7624 FIX: Review sidebar link showing for users that can't review (#18454) 2022-10-03 16:59:25 +08:00
Alan Guo Xiang Tan 0bdb616edc DEV: Refactor community section code (#18436)
In a recent commit when adding the review section link, I moved to a
pattern where we allowed the section links to be refreshed after the
section has been constructed. However, we were not tearing down the old
section links when refreshing. This made me realise that refreshing
section links in a section is not a pattern I want to adopt since people
can easily forget to teardown. Instead, each section link should be
responsible for defining a teardown function for cleanup which will
always be called when the sidebar is removed.
2022-09-30 13:13:50 +08:00
Alan Guo Xiang Tan 4c5e575c15 FIX: Ensure closing sidebar tears down all callbacks. (#18434) 2022-09-30 10:02:51 +08:00
Alan Guo Xiang Tan 5248fbbe24 UX: Add flag icon for review section link in sidebar (#18414) 2022-09-29 15:41:23 +08:00
Alan Guo Xiang Tan 4f84ed6723 FIX: Use Category#category_text for sidebar title (#18411)
Previously we used `Category#category_excerpt` but the excerpt keeps the
HTML entities around if present and we can't really display HTML in the
title of a link.
2022-09-29 14:44:41 +08:00
Alan Guo Xiang Tan ec1851b1dc DEV: Fix lint (#18412) 2022-09-29 14:44:23 +08:00
Alan Guo Xiang Tan 4c2525adc6 UX: Correct padding and height for sidebar section message (#18410)
Follow-up to f1cbc23f1e
2022-09-29 14:06:28 +08:00
Alan Guo Xiang Tan 3ec1808d75 DEV: Revert change in background-color of sidebar (#18409)
Follow-up to f1cbc23f1e
2022-09-29 13:52:23 +08:00
Alan Guo Xiang Tanandawesomerobot f1cbc23f1e UX: Add icons to all section links in Sidebar (#18378)
This commit introduces an icon to all links in the sidebar. If an icon has not been configured, we will fall back to a generic "link" icon. As part of this commit, we also standardised the size of each prefix to 20px by 20px and set a fix margin. This is to allow sufficient space for text prefixes and image prefixes to be displayed. 

Tests have been intentionally left out for now as I don't feel like asserting for the icons will bring much value at this point. Time shall prove me wrong.

Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
2022-09-29 12:28:01 +08:00
Alan Guo Xiang Tan 4b561277a9 FEATURE: Add review link to community section for logged in user (#18374)
When there are pending reviewables, the review section link is displayed
in the main section. When there are no pending reviewables, the review
section link is displayed under the more links drawer.

Internal ref: /t/74210
2022-09-28 09:58:07 +08:00
Alan Guo Xiang Tan 8c7a38449c FIX: Sidebar categories for anonymous not being sorted by name (#18339)
Sort it by name for now even though we have an on going conversation to
decide how categories should be sorted in sidebar

https://meta.discourse.org/t/sidebar-categories-are-out-of-order-for-anonymous-users/239679
2022-09-23 12:17:42 +08:00