Отключенная категория «Без категории» отображается в выпадающих списках категорий

Ага, понял. Только что провёл небольшую локальную отладку и подтверждаю: проблема воспроизводится на 100% в стандартных установках Discourse.

Давайте кратко резюмирую:

Когда речь заходит о категории «Без категории» (Uncategorized), есть два параметра:

allow_uncategorized_topics — по умолчанию выключено
suppress_uncategorized_badge — по умолчанию включено

Если параметр allow_uncategorized_topics отключён (стандартная настройка), его наличие ошибочно проявляется в некоторых местах.

Если попытаться обойти проблему, включив категорию «Без категории», чтобы затем её удалить, вы столкнётесь с следующим:

В Discourse эта категория ведёт себя очень странно:

  1. Она обязательно должна присутствовать.
  2. Её невозможно удалить.
  3. Мы внедряем её в огромное количество логики в самых разных местах:

Мы можем исправить утечку, добавляя всё больше и больше условных операторов; сейчас их, вероятно, уже не менее 10 как на стороне клиента, так и на сервере.

Или же мы можем исправить это в корне: просто разрешить администраторам удалять эту категорию. Тогда она исчезнет, и нам больше никогда не придётся её проверять.

Моя рекомендация следующая:

  1. Удалить оба параметра, а также скрытый параметр uncategorized_category_id.
  2. Ввести понятие категории по умолчанию (что у нас уже есть) — у нас уже есть default_composer_category.
  3. Тогда «Без категории» (uncategorized) перестанет быть особым концептом, и нам не придётся разбираться с лишними сложностями.
  4. Предоставить компонент темы для тех, кому обязательно нужна «категория без значка».

Текущую ошибку в поиске можно исправить примерно так:

diff --git a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
index a678919d16..83a9ed27db 100644
--- a/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
+++ b/app/assets/javascripts/select-kit/addon/components/search-advanced-category-chooser.js
@@ -1,4 +1,5 @@
 import { classNames } from "@ember-decorators/component";
+import { setting } from "discourse/lib/computed";
 import CategoryChooserComponent from "select-kit/components/category-chooser";
 import {
   pluginApiIdentifiers,
@@ -7,11 +8,13 @@ import {
 
 @classNames("search-advanced-category-chooser")
 @selectKitOptions({
-  allowUncategorized: true,
+  allowUncategorized: "allowUncategorized",
   clearable: true,
   none: "category.all",
   displayCategoryDescription: false,
   permissionType: null,
 })
 @pluginApiIdentifiers("search-advanced-category-chooser")
-export default class SearchAdvancedCategoryChooser extends CategoryChooserComponent {}
+export default class SearchAdvancedCategoryChooser extends CategoryChooserComponent {
+  @setting("allow_uncategorized_topics") allowUncategorized;
+}
import { render } from "@ember/test-helpers";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import SearchAdvancedCategoryChooser from "select-kit/components/search-advanced-category-chooser";

module(
  "Integration | Component | select-kit/search-advanced-category-chooser",
  function (hooks) {
    setupRenderingTest(hooks);

    hooks.beforeEach(function () {
      this.set("subject", selectKit());
    });

    test("respects allow_uncategorized_topics setting when false", async function (assert) {
      this.siteSettings.allow_uncategorized_topics = false;

      await render(<template><SearchAdvancedCategoryChooser /></template>);

      await this.subject.expand();

      // Uncategorized category (ID 17 in test data) should not be present when setting is false
      assert.false(
        this.subject.rowByValue(17).exists(),
        "uncategorized category is not available when allow_uncategorized_topics is false"
      );
    });

    test("shows uncategorized category when allow_uncategorized_topics is true", async function (assert) {
      this.siteSettings.allow_uncategorized_topics = true;

      await render(<template><SearchAdvancedCategoryChooser /></template>);

      await this.subject.expand();

      // Uncategorized category (ID 17 in test data) should be present when setting is true
      assert.true(
        this.subject.rowByValue(17).exists(),
        "uncategorized category is available when allow_uncategorized_topics is true"
      );
    });

    test("has correct default options", async function (assert) {
      await render(<template><SearchAdvancedCategoryChooser /></template>);

      assert.strictEqual(
        this.subject.header().label(),
        "All categories",
        "has correct default none label"
      );
    });
  }
);

Но это лишь исправление ошибки в расширенном поиске — мы просто играем в «ладошки» (ловим баги по одному), не решая проблему системно…

3 лайка