diff --git a/.discourse-compatibility b/.discourse-compatibility
index c277e98..c1f40a2 100644
--- a/.discourse-compatibility
+++ b/.discourse-compatibility
@@ -1 +1,2 @@
-< 3.3.0.beta3-dev: 5288581b1d232a9a8a1d3803951f3a6b30ed5468
\ No newline at end of file
+< 3.4.0.beta3-dev: 2db5bfe10525888e8e34929b293ae9407a77aee5
+< 3.3.0.beta3-dev: 5288581b1d232a9a8a1d3803951f3a6b30ed5468
diff --git a/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.gjs b/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.gjs
new file mode 100644
index 0000000..5004616
--- /dev/null
+++ b/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.gjs
@@ -0,0 +1,94 @@
+import Component from "@glimmer/component";
+import { tracked } from "@glimmer/tracking";
+import { fn } from "@ember/helper";
+import { action } from "@ember/object";
+import { service } from "@ember/service";
+import { i18n } from "discourse-i18n";
+import GroupChooser from "select-kit/components/group-chooser";
+
+export default class LockdownSettings extends Component {
+ @service site;
+ @tracked lockdownEnabled;
+
+ constructor() {
+ super(...arguments);
+ this.lockdownEnabled = [true, "true"].includes(
+ this.args.outletArgs.category?.custom_fields?.lockdown_enabled
+ );
+ }
+
+ get availableGroups() {
+ return (this.site.groups || [])
+ .map((g) => {
+ // prevents group "everyone" to be listed
+ return g.id === 0 ? null : g.name;
+ })
+ .filter(Boolean);
+ }
+
+ selectedGroups(value) {
+ return (value || "").split(",").filter(Boolean);
+ }
+
+ @action
+ async onToggleEnabled(value, { set, name }) {
+ this.lockdownEnabled = value;
+ // store "" (which deletes the custom field) when disabled, so the
+ // checkbox state stays consistent after a reload
+ await set(name, value || "");
+ }
+
+ @action
+ onChangeGroups(field, values) {
+ field.set(values.join(","));
+ }
+
+
+ <@outletArgs.form.Section
+ @title={{i18n "lockdown.category_setting_heading"}}
+ class="lockdown-settings"
+ >
+ <@outletArgs.form.Object @name="custom_fields" as |object|>
+
+
+
+
+ {{#if this.lockdownEnabled}}
+
+
+
+
+
+
+
+
+
+ {{/if}}
+ @outletArgs.form.Object>
+ @outletArgs.form.Section>
+
+}
diff --git a/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.hbs b/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.hbs
deleted file mode 100644
index b8f9cd9..0000000
--- a/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.hbs
+++ /dev/null
@@ -1,33 +0,0 @@
-
{{i18n "lockdown.category_setting_heading"}}
-
-{{#if @outletArgs.category.custom_fields.lockdown_enabled}}
-
-
-
-
-
-{{/if}}
\ No newline at end of file
diff --git a/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.js b/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.js
deleted file mode 100644
index 3f9803d..0000000
--- a/assets/javascripts/discourse/connectors/category-custom-security/lockdown-settings.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import Component from "@glimmer/component";
-import { tracked } from "@glimmer/tracking";
-import { action, computed } from "@ember/object";
-import { service } from "@ember/service";
-
-export default class LockdownSettings extends Component {
- @service site;
- @tracked selectedGroups = null;
-
- constructor() {
- super(...arguments);
- this.selectedGroups = (
- this.args.outletArgs.category.custom_fields.lockdown_allowed_groups || ""
- )
- .split(",")
- .filter(Boolean);
- }
-
- @computed("site.groups.[]")
- get availableGroups() {
- return (this.site.groups || [])
- .map((g) => {
- // prevents group "everyone" to be listed
- return g.id === 0 ? null : g.name;
- })
- .filter(Boolean);
- }
-
- @action
- onChangeGroups(values) {
- this.selectedGroups = values;
- this.args.outletArgs.category.custom_fields.lockdown_allowed_groups =
- values.join(",");
- }
-}
diff --git a/assets/javascripts/discourse/connectors/topic-link__before/category-lockdown-icon.gjs b/assets/javascripts/discourse/connectors/topic-link__before/category-lockdown-icon.gjs
index 82dc2b9..0d9c175 100644
--- a/assets/javascripts/discourse/connectors/topic-link__before/category-lockdown-icon.gjs
+++ b/assets/javascripts/discourse/connectors/topic-link__before/category-lockdown-icon.gjs
@@ -1,20 +1,18 @@
import Component from "@glimmer/component";
import { service } from "@ember/service";
-import i18n from "discourse-common/helpers/i18n";
import icon from "discourse-common/helpers/d-icon";
+import i18n from "discourse-common/helpers/i18n";
+
+export default class CategoryLockdownIcon extends Component {
+ @service siteSettings;
- export default class CategoryLockdownIcon extends Component {
- @service siteSettings;
-
{{~#if this.siteSettings.category_lockdown_enabled~}}
{{~#if @outletArgs.topic.is_locked_down~}}
- {{icon
- this.siteSettings.category_lockdown_list_icon
- }}
+ {{icon this.siteSettings.category_lockdown_list_icon}}
{{~/if~}}
{{~/if~}}
-
- }
\ No newline at end of file
+
+}
diff --git a/assets/stylesheets/lockdown.scss b/assets/stylesheets/lockdown.scss
deleted file mode 100644
index 4e01f0b..0000000
--- a/assets/stylesheets/lockdown.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-.lockdown-settings .lockdownAllowedGroups {
- display: inline-block;
- vertical-align: middle;
-}
diff --git a/plugin.rb b/plugin.rb
index cc591eb..14bf3a6 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -1,13 +1,12 @@
# frozen_string_literal: true
# name: discourse-category-lockdown
# about: Set all topics in a category to redirect, unless part of a specified group
-# version: 1.2.1
+# version: 1.2.2
# authors: Pavilion
# meta_topic_id: 70649
# url: https://github.com/paviliondev/discourse-category-lockdown
enabled_site_setting :category_lockdown_enabled
-register_asset "stylesheets/lockdown.scss"
module ::CategoryLockdown
PLUGIN_NAME = "category-lockdown"
diff --git a/test/javascripts/integration/components/lockdown-settings-test.gjs b/test/javascripts/integration/components/lockdown-settings-test.gjs
new file mode 100644
index 0000000..4f2c9e5
--- /dev/null
+++ b/test/javascripts/integration/components/lockdown-settings-test.gjs
@@ -0,0 +1,91 @@
+import { hash } from "@ember/helper";
+import { click, render } from "@ember/test-helpers";
+import { module, test } from "qunit";
+import Form from "discourse/components/form";
+import { setupRenderingTest } from "discourse/tests/helpers/component-test";
+import LockdownSettings from "discourse/plugins/discourse-category-lockdown/discourse/connectors/category-custom-security/lockdown-settings";
+
+module(
+ "Discourse Category Lockdown | Integration | Component | lockdown-settings",
+ function (hooks) {
+ setupRenderingTest(hooks);
+
+ test("hides the redirect settings when lockdown is disabled", async function (assert) {
+ const data = { custom_fields: { lockdown_enabled: false } };
+ const category = { custom_fields: data.custom_fields };
+
+ await render(
+
+ );
+
+ assert.dom(".lockdown-settings").includesText("Category Lockdown");
+ assert.dom("input[type=checkbox]").isNotChecked();
+ assert
+ .dom(".lockdown-settings input[type=text]")
+ .doesNotExist("hides the redirect url field");
+ assert
+ .dom(".group-chooser")
+ .doesNotExist("hides the allowed groups chooser");
+ });
+
+ test("reveals the redirect settings when lockdown is enabled", async function (assert) {
+ const data = {
+ custom_fields: {
+ lockdown_enabled: true,
+ redirect_url: "https://example.com",
+ lockdown_allowed_groups: "",
+ },
+ };
+ const category = { custom_fields: data.custom_fields };
+
+ await render(
+
+ );
+
+ assert.dom("input[type=checkbox]").isChecked();
+ assert
+ .dom(".lockdown-settings input[type=text]")
+ .hasValue("https://example.com", "shows the stored redirect url");
+ assert.dom(".group-chooser").exists("renders the allowed groups chooser");
+ });
+
+ test("toggling the checkbox reveals the fields and writes through the form", async function (assert) {
+ const data = { custom_fields: {} };
+ const category = { custom_fields: data.custom_fields };
+ let submitted = null;
+
+ const onSubmit = (formData) => {
+ submitted = formData;
+ };
+
+ await render(
+
+
+ );
+
+ assert
+ .dom(".group-chooser")
+ .doesNotExist("fields are hidden before enabling");
+
+ await click("input[type=checkbox]");
+
+ assert
+ .dom(".group-chooser")
+ .exists("enabling the checkbox reveals the fields");
+
+ await click(".form-kit__button[type='submit']");
+
+ assert.strictEqual(
+ submitted?.custom_fields?.lockdown_enabled,
+ true,
+ "the lockdown_enabled change is routed through the form"
+ );
+ });
+ }
+);