DEV: Replace filter-mode mixin with lib functions (#22986)
The filter-mode mixin was previously serving two distinct purposes via a complex arrangement of getters/setters: 1. To calculate a filterMode, given values for category, filterType and noSubcategories 2. To calculate a filterType, given a filterMode This commit splits the mixin into two functions, and updates all call sites to use them instead of the mixin.
This commit is contained in:
parent
7f2e42c826
commit
a0e45a1e0c
|
@ -1,16 +1,24 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
import { filterTypeForMode } from "discourse/lib/filter-mode";
|
||||||
import NavItem from "discourse/models/nav-item";
|
import NavItem from "discourse/models/nav-item";
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
import { NotificationLevels } from "discourse/lib/notification-levels";
|
import { NotificationLevels } from "discourse/lib/notification-levels";
|
||||||
import { getOwner } from "discourse-common/lib/get-owner";
|
import { getOwner } from "discourse-common/lib/get-owner";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
|
||||||
export default Component.extend(FilterModeMixin, {
|
export default Component.extend({
|
||||||
router: service(),
|
router: service(),
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
tagName: "",
|
tagName: "",
|
||||||
|
filterMode: tracked(),
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterType() {
|
||||||
|
return filterTypeForMode(this.filterMode);
|
||||||
|
},
|
||||||
|
|
||||||
// Should be a `readOnly` instead but some themes/plugins still pass
|
// Should be a `readOnly` instead but some themes/plugins still pass
|
||||||
// the `categories` property into this component
|
// the `categories` property into this component
|
||||||
|
|
|
@ -2,13 +2,21 @@ import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import DiscourseURL from "discourse/lib/url";
|
import DiscourseURL from "discourse/lib/url";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import { next } from "@ember/runloop";
|
import { next } from "@ember/runloop";
|
||||||
|
import { filterTypeForMode } from "discourse/lib/filter-mode";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
export default Component.extend(FilterModeMixin, {
|
export default Component.extend({
|
||||||
tagName: "ul",
|
tagName: "ul",
|
||||||
classNameBindings: [":nav", ":nav-pills"],
|
classNameBindings: [":nav", ":nav-pills"],
|
||||||
elementId: "navigation-bar",
|
elementId: "navigation-bar",
|
||||||
|
filterMode: tracked(),
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterType() {
|
||||||
|
return filterTypeForMode(this.filterMode);
|
||||||
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import Component from "@ember/component";
|
import Component from "@ember/component";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import discourseComputed from "discourse-common/utils/decorators";
|
import discourseComputed from "discourse-common/utils/decorators";
|
||||||
|
import { filterTypeForMode } from "discourse/lib/filter-mode";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
export default Component.extend(FilterModeMixin, {
|
export default Component.extend({
|
||||||
tagName: "li",
|
tagName: "li",
|
||||||
classNameBindings: [
|
classNameBindings: [
|
||||||
"active",
|
"active",
|
||||||
|
@ -15,6 +17,12 @@ export default Component.extend(FilterModeMixin, {
|
||||||
hidden: false,
|
hidden: false,
|
||||||
activeClass: "",
|
activeClass: "",
|
||||||
hrefLink: null,
|
hrefLink: null,
|
||||||
|
filterMode: tracked(),
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterType() {
|
||||||
|
return filterTypeForMode(this.filterMode);
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed("content.filterType", "filterType", "content.active")
|
@discourseComputed("content.filterType", "filterType", "content.active")
|
||||||
active(contentFilterType, filterType, active) {
|
active(contentFilterType, filterType, active) {
|
||||||
|
|
|
@ -1,6 +1,19 @@
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import NavigationDefaultController from "discourse/controllers/navigation/default";
|
import NavigationDefaultController from "discourse/controllers/navigation/default";
|
||||||
|
import { calculateFilterMode } from "discourse/lib/filter-mode";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
export default class NavigationCategoryController extends NavigationDefaultController.extend(
|
export default class NavigationCategoryController extends NavigationDefaultController {
|
||||||
FilterModeMixin
|
@tracked category;
|
||||||
) {}
|
@tracked filterType;
|
||||||
|
@tracked noSubcategories;
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterMode() {
|
||||||
|
return calculateFilterMode({
|
||||||
|
category: this.category,
|
||||||
|
filterType: this.filterType,
|
||||||
|
noSubcategories: this.noSubcategories,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,27 @@
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
import Controller, { inject as controller } from "@ember/controller";
|
import Controller, { inject as controller } from "@ember/controller";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import { TRACKED_QUERY_PARAM_VALUE } from "discourse/lib/topic-list-tracked-filter";
|
import { TRACKED_QUERY_PARAM_VALUE } from "discourse/lib/topic-list-tracked-filter";
|
||||||
|
import { calculateFilterMode } from "discourse/lib/filter-mode";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
export default class NavigationDefaultController extends Controller.extend(
|
export default class NavigationDefaultController extends Controller {
|
||||||
FilterModeMixin
|
|
||||||
) {
|
|
||||||
@service router;
|
@service router;
|
||||||
@controller discovery;
|
@controller discovery;
|
||||||
|
|
||||||
|
@tracked category;
|
||||||
|
@tracked filterType;
|
||||||
|
@tracked noSubcategories;
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterMode() {
|
||||||
|
return calculateFilterMode({
|
||||||
|
category: this.category,
|
||||||
|
filterType: this.filterType,
|
||||||
|
noSubcategories: this.noSubcategories,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
get skipCategoriesNavItem() {
|
get skipCategoriesNavItem() {
|
||||||
return this.router.currentRoute.queryParams.f === TRACKED_QUERY_PARAM_VALUE;
|
return this.router.currentRoute.queryParams.f === TRACKED_QUERY_PARAM_VALUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { inject as controller } from "@ember/controller";
|
||||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||||
import BulkTopicSelection from "discourse/mixins/bulk-topic-selection";
|
import BulkTopicSelection from "discourse/mixins/bulk-topic-selection";
|
||||||
import DismissTopics from "discourse/mixins/dismiss-topics";
|
import DismissTopics from "discourse/mixins/dismiss-topics";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import NavItem from "discourse/models/nav-item";
|
import NavItem from "discourse/models/nav-item";
|
||||||
import Topic from "discourse/models/topic";
|
import Topic from "discourse/models/topic";
|
||||||
|
@ -11,11 +10,14 @@ import { readOnly } from "@ember/object/computed";
|
||||||
import { endWith } from "discourse/lib/computed";
|
import { endWith } from "discourse/lib/computed";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { inject as service } from "@ember/service";
|
import { inject as service } from "@ember/service";
|
||||||
|
import { calculateFilterMode } from "discourse/lib/filter-mode";
|
||||||
|
import { dependentKeyCompat } from "@ember/object/compat";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
export default DiscoverySortableController.extend(
|
export default DiscoverySortableController.extend(
|
||||||
BulkTopicSelection,
|
BulkTopicSelection,
|
||||||
DismissTopics,
|
DismissTopics,
|
||||||
FilterModeMixin,
|
|
||||||
{
|
{
|
||||||
application: controller(),
|
application: controller(),
|
||||||
dialog: service(),
|
dialog: service(),
|
||||||
|
@ -33,6 +35,19 @@ export default DiscoverySortableController.extend(
|
||||||
showInfo: false,
|
showInfo: false,
|
||||||
top: endWith("list.filter", "top"),
|
top: endWith("list.filter", "top"),
|
||||||
|
|
||||||
|
category: tracked(),
|
||||||
|
filterType: tracked(),
|
||||||
|
noSubcategories: tracked(),
|
||||||
|
|
||||||
|
@dependentKeyCompat
|
||||||
|
get filterMode() {
|
||||||
|
return calculateFilterMode({
|
||||||
|
category: this.category,
|
||||||
|
filterType: this.filterType,
|
||||||
|
noSubcategories: this.noSubcategories,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
@discourseComputed(
|
@discourseComputed(
|
||||||
"canCreateTopic",
|
"canCreateTopic",
|
||||||
"category",
|
"category",
|
||||||
|
@ -97,14 +112,14 @@ export default DiscoverySortableController.extend(
|
||||||
},
|
},
|
||||||
|
|
||||||
callResetNew(dismissPosts = false, dismissTopics = false, untrack = false) {
|
callResetNew(dismissPosts = false, dismissTopics = false, untrack = false) {
|
||||||
const tracked =
|
const filterTracked =
|
||||||
(this.router.currentRoute.queryParams["f"] ||
|
(this.router.currentRoute.queryParams["f"] ||
|
||||||
this.router.currentRoute.queryParams["filter"]) === "tracked";
|
this.router.currentRoute.queryParams["filter"]) === "tracked";
|
||||||
|
|
||||||
let topicIds = this.selected ? this.selected.mapBy("id") : null;
|
let topicIds = this.selected ? this.selected.mapBy("id") : null;
|
||||||
|
|
||||||
Topic.resetNew(this.category, !this.noSubcategories, {
|
Topic.resetNew(this.category, !this.noSubcategories, {
|
||||||
tracked,
|
tracked: filterTracked,
|
||||||
tag: this.tag,
|
tag: this.tag,
|
||||||
topicIds,
|
topicIds,
|
||||||
dismissPosts,
|
dismissPosts,
|
||||||
|
@ -114,7 +129,9 @@ export default DiscoverySortableController.extend(
|
||||||
if (result.topic_ids) {
|
if (result.topic_ids) {
|
||||||
this.topicTrackingState.removeTopics(result.topic_ids);
|
this.topicTrackingState.removeTopics(result.topic_ids);
|
||||||
}
|
}
|
||||||
this.refresh(tracked ? { skipResettingParams: ["filter", "f"] } : {});
|
this.refresh(
|
||||||
|
filterTracked ? { skipResettingParams: ["filter", "f"] } : {}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import Category from "discourse/models/category";
|
||||||
|
|
||||||
|
export function calculateFilterMode({ category, filterType, noSubcategories }) {
|
||||||
|
if (category) {
|
||||||
|
return `c/${Category.slugFor(category)}${
|
||||||
|
noSubcategories ? "/none" : ""
|
||||||
|
}/l/${filterType}`;
|
||||||
|
} else {
|
||||||
|
return filterType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filterTypeForMode(mode) {
|
||||||
|
return mode.split("/").pop();
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
import Category from "discourse/models/category";
|
|
||||||
import Mixin from "@ember/object/mixin";
|
|
||||||
import { computed } from "@ember/object";
|
|
||||||
|
|
||||||
export default Mixin.create({
|
|
||||||
filterModeInternal: computed(
|
|
||||||
"rawFilterMode",
|
|
||||||
"filterType",
|
|
||||||
"category",
|
|
||||||
"noSubcategories",
|
|
||||||
function () {
|
|
||||||
const rawFilterMode = this.rawFilterMode;
|
|
||||||
if (rawFilterMode) {
|
|
||||||
return rawFilterMode;
|
|
||||||
} else {
|
|
||||||
const category = this.category;
|
|
||||||
const filterType = this.filterType;
|
|
||||||
|
|
||||||
if (category) {
|
|
||||||
const noSubcategories = this.noSubcategories;
|
|
||||||
|
|
||||||
return `c/${Category.slugFor(category)}${
|
|
||||||
noSubcategories ? "/none" : ""
|
|
||||||
}/l/${filterType}`;
|
|
||||||
} else {
|
|
||||||
return filterType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
),
|
|
||||||
|
|
||||||
filterMode: computed("filterModeInternal", {
|
|
||||||
get() {
|
|
||||||
return this.filterModeInternal;
|
|
||||||
},
|
|
||||||
|
|
||||||
set(key, value) {
|
|
||||||
this.set("rawFilterMode", value);
|
|
||||||
this.set("filterType", value.split("/").pop());
|
|
||||||
|
|
||||||
return value;
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
|
@ -9,7 +9,6 @@ import {
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
import Composer from "discourse/models/composer";
|
import Composer from "discourse/models/composer";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import FilterModeMixin from "discourse/mixins/filter-mode";
|
|
||||||
import I18n from "I18n";
|
import I18n from "I18n";
|
||||||
import PermissionType from "discourse/models/permission-type";
|
import PermissionType from "discourse/models/permission-type";
|
||||||
import { escapeExpression } from "discourse/lib/utilities";
|
import { escapeExpression } from "discourse/lib/utilities";
|
||||||
|
@ -23,7 +22,7 @@ import { inject as service } from "@ember/service";
|
||||||
const NONE = "none";
|
const NONE = "none";
|
||||||
const ALL = "all";
|
const ALL = "all";
|
||||||
|
|
||||||
export default DiscourseRoute.extend(FilterModeMixin, {
|
export default DiscourseRoute.extend({
|
||||||
composer: service(),
|
composer: service(),
|
||||||
navMode: "latest",
|
navMode: "latest",
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<DSection @bodyClass="navigation-categories" @class="navigation-container">
|
<DSection @bodyClass="navigation-categories" @class="navigation-container">
|
||||||
<DNavigation
|
<DNavigation
|
||||||
@filterType="categories"
|
@filterMode="categories"
|
||||||
@showCategoryAdmin={{this.showCategoryAdmin}}
|
@showCategoryAdmin={{this.showCategoryAdmin}}
|
||||||
@createCategory={{route-action "createCategory"}}
|
@createCategory={{route-action "createCategory"}}
|
||||||
@reorderCategories={{route-action "reorderCategories"}}
|
@reorderCategories={{route-action "reorderCategories"}}
|
||||||
|
|
|
@ -20,7 +20,7 @@ module("Integration | Component | d-navigation", function (hooks) {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("filters indirectly muted categories", async function (assert) {
|
test("filters indirectly muted categories", async function (assert) {
|
||||||
await render(hbs`<DNavigation @filterType="categories" />`);
|
await render(hbs`<DNavigation @filterMode="categories" />`);
|
||||||
await click(".category-drop .select-kit-header-wrapper");
|
await click(".category-drop .select-kit-header-wrapper");
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
|
Loading…
Reference in New Issue