UX: Revamp category security tab (#11273)

UX: Revamp category security tab (#11273)

diff --git a/app/assets/javascripts/discourse/app/components/category-permission-row.js b/app/assets/javascripts/discourse/app/components/category-permission-row.js
new file mode 100644
index 0000000..881f33a
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/components/category-permission-row.js
@@ -0,0 +1,123 @@
+import I18n from "I18n";
+import Component from "@ember/component";
+import discourseComputed, { observes } from "discourse-common/utils/decorators";
+import PermissionType from "discourse/models/permission-type";
+import { equal, alias } from "@ember/object/computed";
+
+const EVERYONE = "everyone";
+
+export default Component.extend({
+  classNames: ["permission-row", "row-body"],
+  canCreate: equal("type", PermissionType.FULL),
+  everyonePermissionType: alias("everyonePermission.permission_type"),
+
+  @discourseComputed("type")
+  canReply(value) {
+    return (
+      value === PermissionType.CREATE_POST || value === PermissionType.FULL
+    );
+  },
+
+  @discourseComputed("type")
+  canReplyIcon() {
+    return this.canReply ? "check-square" : "far-square";
+  },
+
+  @discourseComputed("type")
+  canCreateIcon() {
+    return this.canCreate ? "check-square" : "far-square";
+  },
+
+  @discourseComputed("type")
+  replyGranted() {
+    return this.type <= PermissionType.CREATE_POST ? "reply-granted" : "";
+  },
+
+  @discourseComputed("type")
+  createGranted() {
+    return this.type === PermissionType.FULL ? "create-granted" : "";
+  },
+
+  @observes("everyonePermissionType")
+  inheritFromEveryone() {
+    if (this.group_name === EVERYONE) {
+      return;
+    }
+
+    // groups cannot have a lesser permission than "everyone"
+    if (this.everyonePermissionType < this.type) {
+      this.updatePermission(this.everyonePermissionType);
+    }
+  },
+
+  @discourseComputed("everyonePermissionType", "type")
+  replyDisabled(everyonePermissionType) {
+    if (
+      this.group_name !== EVERYONE &&
+      everyonePermissionType &&
+      everyonePermissionType <= PermissionType.CREATE_POST
+    ) {
+      return true;
+    }
+    return false;
+  },
+
+  @discourseComputed("replyDisabled")
+  replyTooltip() {
+    return this.replyDisabled
+      ? I18n.t("category.permissions.inherited")
+      : I18n.t("category.permissions.toggle_reply");
+  },
+
+  @discourseComputed("everyonePermissionType", "type")
+  createDisabled(everyonePermissionType) {
+    if (
+      this.group_name !== EVERYONE &&
+      everyonePermissionType &&
+      everyonePermissionType === PermissionType.FULL
+    ) {
+      return true;
+    }
+    return false;
+  },
+
+  @discourseComputed("createDisabled")
+  createTooltip() {
+    return this.createDisabled
+      ? I18n.t("category.permissions.inherited")
+      : I18n.t("category.permissions.toggle_full");
+  },
+
+  updatePermission(type) {
+    this.category.updatePermission(this.group_name, type);
+  },
+
+  actions: {
+    removeRow() {
+      this.category.removePermission(this.group_name);
+    },
+
+    setPermissionReply() {
+      if (this.type <= PermissionType.CREATE_POST) {
+        this.updatePermission(PermissionType.READONLY);
+      } else {
+        this.updatePermission(PermissionType.CREATE_POST);
+      }
+    },
+
+    setPermissionFull() {
+      if (
+        this.group_name !== EVERYONE &&
+        this.everyonePermissionType === PermissionType.FULL
+      ) {
+        return;
+      }
+
+      if (this.type === PermissionType.FULL) {
+        this.updatePermission(PermissionType.CREATE_POST);
+      } else {
+        this.updatePermission(PermissionType.FULL);
+      }
+    },
+  },
+});
diff --git a/app/assets/javascripts/discourse/app/components/edit-category-security.js b/app/assets/javascripts/discourse/app/components/edit-category-security.js
index a85558f..cd69ba5 100644
--- a/app/assets/javascripts/discourse/app/components/edit-category-security.js
+++ b/app/assets/javascripts/discourse/app/components/edit-category-security.js
@@ -1,78 +1,39 @@
 import { buildCategoryPanel } from "discourse/components/edit-category-panel";
 import PermissionType from "discourse/models/permission-type";
-import { on } from "discourse-common/utils/decorators";
+import discourseComputed from "discourse-common/utils/decorators";
+
+import { not } from "@ember/object/computed";
 
 export default buildCategoryPanel("security", {
-  editingPermissions: false,
   selectedGroup: null,
-  selectedPermission: null,
-  showPendingGroupChangesAlert: false,
-  interactedWithDropdowns: false,
+  noGroupSelected: not("selectedGroup"),
 
-  @on("init")
-  _setup() {
-    this.setProperties({
-      selectedGroup: this.get("category.availableGroups.firstObject"),
-      selectedPermission: this.get(
-        "category.availablePermissions.firstObject.id"
-      ),
-    });
+  @discourseComputed("category.permissions.@each.permission_type")
+  everyonePermission(permissions) {
+    return permissions.findBy("group_name", "everyone");
   },
 
-  @on("init")
-  _registerValidator() {
-    this.registerValidator(() => {
-      if (
-        !this.showPendingGroupChangesAlert &&
-        this.interactedWithDropdowns &&
-        this.activeTab
-      ) {
-        this.set("showPendingGroupChangesAlert", true);
-        return true;
-      }
-    });
+  @discourseComputed("category.permissions.@each.permission_type")
+  everyoneGrantedFull() {
+    return (
+      this.everyonePermission &&
+      this.everyonePermission.permission_type === PermissionType.FULL
+    );
   },
 
-  actions: {
-    onSelectGroup(selectedGroup) {
-      this.setProperties({
-        interactedWithDropdowns: true,
-        selectedGroup,
-      });
-    },
-
-    onSelectPermission(selectedPermission) {
-      this.setProperties({
-        interactedWithDropdowns: true,
-        selectedPermission,
-      });
-    },
-
-    editPermissions() {
-      if (!this.get("category.is_special")) {
-        this.set("editingPermissions", true);
-      }
-    },
-
-    addPermission(group, id) {
-      if (!this.get("category.is_special")) {
-        this.category.addPermission({
-          group_name: group + "",
-          permission: PermissionType.create({ id: parseInt(id, 10) }),
-        });
-      }
+  @discourseComputed("everyonePermission")
+  minimumPermission(everyonePermission) {
+    return everyonePermission
+      ? everyonePermission.permission_type
+      : PermissionType.READONLY;
+  },
 
-      this.setProperties({
-        selectedGroup: this.get("category.availableGroups.firstObject"),
-        showPendingGroupChangesAlert: false,
-        interactedWithDropdowns: false,
+  actions: {
+    onSelectGroup(group_name) {
+      this.category.addPermission({
+        group_name,
+        permission_type: this.minimumPermission,
       });
     },
-
-    removePermission(permission) {
-      if (!this.get("category.is_special")) {
-        this.category.removePermission(permission);
-      }
-    },
   },
 });
diff --git a/app/assets/javascripts/discourse/app/components/edit-category-tab.js b/app/assets/javascripts/discourse/app/components/edit-category-tab.js
index eb0f52c..0ead526 100644
--- a/app/assets/javascripts/discourse/app/components/edit-category-tab.js
+++ b/app/assets/javascripts/discourse/app/components/edit-category-tab.js
@@ -6,6 +6,7 @@ import { propertyEqual } from "discourse/lib/computed";
 import getURL from "discourse-common/lib/get-url";
 import { empty } from "@ember/object/computed";
 import DiscourseURL from "discourse/lib/url";
+import { underscore } from "@ember/string";
 
 export default Component.extend({
   tagName: "li",
@@ -21,7 +22,7 @@ export default Component.extend({
 
   @discourseComputed("tab")
   title(tab) {
-    return I18n.t("category." + tab.replace("-", "_"));
+    return I18n.t(`category.${underscore(tab)}`);
   },
 
   didInsertElement() {

[... diff too long, it was truncated ...]

GitHub sha: 7539c2ed

This commit appears in #11273 which was approved by eviltrout. It was merged by pmusaraj.