Add topics management (admin area)
## What does this MR do and why?
In the course of Issues https://gitlab.com/gitlab-org/gitlab/-/issues/340920, we want to give a boost to the project topics :rocket:
In https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70386, the `Projects::Topic` model was extended with an avatar and a description. **As a next step, this MR allows administrators to manage (add/edit) the project topics in the admin area.**
:tools: with :heart: at Siemens
/cc @bufferoverflow
### Database
`Projects::TopicsFinder` execution plans:
* List topics - https://console.postgres.ai/shared/b0b599aa-6cbb-432a-b190-a6e23d7b1d13
* List topics, paginated - https://console.postgres.ai/shared/51e05779-b67b-4009-b479-df1595d5943f
* Search topics - https://console.postgres.ai/shared/a82ac88d-bc35-4972-b052-a8fd3ca1388c
`Gitlab::BackgroundMigration::PopulateTopicsTotalProjectsCountCache` execution plans - these were tested by executing the migration synchronously (on a different branch) and running the migrations testing pipeline - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71974#note_698490482. Looks good.
Migrations output:
**Up:**
```
$ bundle exec rails db:migrate
== 20211004075629 AddTopicsNameGinIndex: migrating ============================
-- transaction_open?()
-> 0.0000s
-- index_exists?(:topics, :name, {:name=>"index_topics_on_name_trigram", :using=>:gin, :opclass=>{:name=>:gin_trgm_ops}, :algorithm=>:concurrently})
-> 0.0066s
-- execute("SET statement_timeout TO 0")
-> 0.0005s
-- add_index(:topics, :name, {:name=>"index_topics_on_name_trigram", :using=>:gin, :opclass=>{:name=>:gin_trgm_ops}, :algorithm=>:concurrently})
-> 0.6582s
-- execute("RESET statement_timeout")
-> 0.0006s
== 20211004075629 AddTopicsNameGinIndex: migrated (0.6920s) ===================
== 20211006060254 AddTopicsTotalProjectsCountCache: migrating =================
-- add_column(:topics, :total_projects_count, :bigint, {:null=>false, :default=>0})
-> 0.0097s
== 20211006060254 AddTopicsTotalProjectsCountCache: migrated (0.0098s) ========
== 20211006060436 SchedulePopulateTopicsTotalProjectsCountCache: migrating ====
-- Scheduled 21 PopulateTopicsTotalProjectsCountCache jobs with a maximum of 10000 records per batch and an interval of 120 seconds.
The migration is expected to take at least 2520 seconds. Expect all jobs to have completed after 2021-10-12 01:37:06 UTC."
== 20211006060436 SchedulePopulateTopicsTotalProjectsCountCache: migrated (0.2077s)
== 20211006122010 AddTopicsTotalProjectsCountIndex: migrating =================
-- transaction_open?()
-> 0.0000s
-- index_exists?(:topics, [:total_projects_count, :id], {:order=>{:total_projects_count=>:desc}, :name=>"index_topics_total_projects_count", :algorithm=>:concurrently})
-> 0.0015s
-- add_index(:topics, [:total_projects_count, :id], {:order=>{:total_projects_count=>:desc}, :name=>"index_topics_total_projects_count", :algorithm=>:concurrently})
-> 0.1684s
== 20211006122010 AddTopicsTotalProjectsCountIndex: migrated (0.1728s) ========
```
**Down:**
```
$ bundle exec rails db:migrate:down VERSION=20211006122010
== 20211006122010 AddTopicsTotalProjectsCountIndex: reverting =================
-- transaction_open?()
-> 0.0000s
-- indexes(:topics)
-> 0.0044s
-- execute("SET statement_timeout TO 0")
-> 0.0005s
-- remove_index(:topics, {:algorithm=>:concurrently, :name=>"index_topics_total_projects_count"})
-> 0.0078s
-- execute("RESET statement_timeout")
-> 0.0005s
== 20211006122010 AddTopicsTotalProjectsCountIndex: reverted (0.0234s) ========
$ bundle exec rails db:migrate:down VERSION=20211006060436
== 20211006060436 SchedulePopulateTopicsTotalProjectsCountCache: reverting ====
== 20211006060436 SchedulePopulateTopicsTotalProjectsCountCache: reverted (0.0000s)
$ bundle exec rails db:migrate:down VERSION=20211006060254
== 20211006060254 AddTopicsTotalProjectsCountCache: reverting =================
-- remove_column(:topics, :total_projects_count)
-> 0.0029s
== 20211006060254 AddTopicsTotalProjectsCountCache: reverted (0.0030s) ========
$ bundle exec rails db:migrate:down VERSION=20211004075629
== 20211004075629 AddTopicsNameGinIndex: reverting ============================
-- transaction_open?()
-> 0.0000s
-- indexes(:topics)
-> 0.0030s
-- execute("SET statement_timeout TO 0")
-> 0.0006s
-- remove_index(:topics, {:algorithm=>:concurrently, :name=>"index_topics_on_name_trigram"})
-> 0.0051s
-- execute("RESET statement_timeout")
-> 0.0006s
== 20211004075629 AddTopicsNameGinIndex: reverted (0.0194s) ===================
```
## Screenshots or screen recordings

## How to set up and validate locally
1. Sign in as administrator
1. Visit `http://localhost:3000/admin/topics`
<details><summary><b>Docs: Administering Topics</b></summary>
You can administer all topics in the GitLab instance from the Admin Area's Topics page.
To access the Topics page:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Topics**.
For each topic, the page displays their name and number of projects labeled with the topic.
To edit a topic, click the **Edit** button in that topic's row.
To change the sort order, click the sort dropdown and select the desired order. The default
sort order is by **Name, ascending**.
To search for topics by name, enter your criteria in the search field. The topic search is case
insensitive, and applies partial matching.
To create a new topic click **New topic**.
</details>
## MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
* [x] I have evaluated the [MR acceptance checklist](https://docs.gitlab.com/ee/development/code_review.html#acceptance-checklist) for this MR.
issue