FEATURE: Group category permissions tab (#10388)
This commit is contained in:
parent
b44748e503
commit
b7a092bd28
|
@ -0,0 +1,3 @@
|
|||
import Controller from "@ember/controller";
|
||||
|
||||
export default Controller.extend();
|
|
@ -79,6 +79,13 @@ export default Controller.extend({
|
|||
);
|
||||
}
|
||||
|
||||
defaultTabs.push(
|
||||
Tab.create({
|
||||
name: "permissions",
|
||||
i18nKey: "permissions.title"
|
||||
})
|
||||
);
|
||||
|
||||
return defaultTabs;
|
||||
},
|
||||
|
||||
|
|
|
@ -2,28 +2,24 @@ import I18n from "I18n";
|
|||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import EmberObject from "@ember/object";
|
||||
|
||||
export function buildPermissionDescription(id) {
|
||||
return I18n.t("permission_types." + PermissionType.DESCRIPTION_KEYS[id]);
|
||||
}
|
||||
|
||||
const PermissionType = EmberObject.extend({
|
||||
@discourseComputed("id")
|
||||
description(id) {
|
||||
var key = "";
|
||||
|
||||
switch (id) {
|
||||
case 1:
|
||||
key = "full";
|
||||
break;
|
||||
case 2:
|
||||
key = "create_post";
|
||||
break;
|
||||
case 3:
|
||||
key = "readonly";
|
||||
break;
|
||||
}
|
||||
return I18n.t("permission_types." + key);
|
||||
return buildPermissionDescription(id);
|
||||
}
|
||||
});
|
||||
|
||||
PermissionType.FULL = 1;
|
||||
PermissionType.CREATE_POST = 2;
|
||||
PermissionType.READONLY = 3;
|
||||
PermissionType.DESCRIPTION_KEYS = {
|
||||
1: "full",
|
||||
2: "create_post",
|
||||
3: "readonly"
|
||||
};
|
||||
|
||||
export default PermissionType;
|
||||
|
|
|
@ -103,6 +103,8 @@ export default function() {
|
|||
this.route("inbox");
|
||||
this.route("archive");
|
||||
});
|
||||
|
||||
this.route("permissions");
|
||||
});
|
||||
|
||||
// User routes
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import I18n from "I18n";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { buildPermissionDescription } from "discourse/models/permission-type";
|
||||
|
||||
export default DiscourseRoute.extend({
|
||||
showFooter: true,
|
||||
|
||||
titleToken() {
|
||||
return I18n.t("groups.permissions.title");
|
||||
},
|
||||
|
||||
model() {
|
||||
let group = this.modelFor("group");
|
||||
|
||||
return ajax(`/g/${group.name}/permissions`)
|
||||
.then(permissions => {
|
||||
permissions.forEach(permission => {
|
||||
permission.description = buildPermissionDescription(
|
||||
permission.permission_type
|
||||
);
|
||||
});
|
||||
return { permissions };
|
||||
})
|
||||
.catch(() => {
|
||||
this.transitionTo("group.members", group);
|
||||
});
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
this.controllerFor("group-permissions").setProperties({ model });
|
||||
this.controllerFor("group").set("showing", "permissions");
|
||||
}
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
<section class="user-content">
|
||||
{{#if model.permissions}}
|
||||
<label class="group-category-permissions-desc">
|
||||
{{i18n "groups.permissions.description"}}
|
||||
</label>
|
||||
<table class="group-category-permissions">
|
||||
<tbody>
|
||||
{{#each model.permissions as |permission|}}
|
||||
<tr>
|
||||
<td>{{category-link permission.category}}</td>
|
||||
<td>{{permission.description}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{else}}
|
||||
{{i18n "groups.permissions.none"}}
|
||||
{{/if}}
|
||||
</section>
|
||||
|
|
@ -189,3 +189,21 @@ table.group-members {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
label.group-category-permissions-desc {
|
||||
font-size: 1.15em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
table.group-category-permissions {
|
||||
width: 100%;
|
||||
|
||||
tr {
|
||||
line-height: 3em;
|
||||
width: 100%;
|
||||
|
||||
.category-name {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -546,6 +546,12 @@ class GroupsController < ApplicationController
|
|||
render_serialized(groups, BasicGroupSerializer)
|
||||
end
|
||||
|
||||
def permissions
|
||||
group = find_group(:id)
|
||||
category_groups = group.category_groups.select { |category_group| guardian.can_see_category?(category_group.category) }
|
||||
render_serialized(category_groups.sort_by { |category_group| category_group.category.name }, CategoryGroupSerializer)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def group_params(automatic: false)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CategoryGroupSerializer < ApplicationSerializer
|
||||
has_one :category, serializer: CategorySerializer, embed: :objects
|
||||
has_one :group, serializer: BasicGroupSerializer, embed: :objects
|
||||
|
||||
attributes :permission_type
|
||||
end
|
|
@ -682,6 +682,10 @@ en:
|
|||
details: "Details"
|
||||
from: "From"
|
||||
to: "To"
|
||||
permissions:
|
||||
title: "Permissions"
|
||||
none: "There are no categories associated with this group."
|
||||
description: "Members of this group can access these categories"
|
||||
public_admission: "Allow users to join the group freely (Requires publicly visible group)"
|
||||
public_exit: "Allow users to leave the group freely"
|
||||
empty:
|
||||
|
|
|
@ -585,6 +585,7 @@ Discourse::Application.routes.draw do
|
|||
get path => 'groups#show'
|
||||
end
|
||||
|
||||
get "permissions" => "groups#permissions"
|
||||
put "members" => "groups#add_members"
|
||||
delete "members" => "groups#remove_member"
|
||||
post "request_membership" => "groups#request_membership"
|
||||
|
|
|
@ -1747,4 +1747,55 @@ describe GroupsController do
|
|||
expect(response.parsed_body["available"]).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#permissions" do
|
||||
before do
|
||||
sign_in(other_user)
|
||||
end
|
||||
|
||||
it "ensures the group can be seen" do
|
||||
group.update!(visibility_level: Group.visibility_levels[:owners])
|
||||
|
||||
get "/groups/#{group.name}/permissions.json"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
describe "with varying category permissions" do
|
||||
fab!(:category) { Fabricate(:category) }
|
||||
|
||||
before do
|
||||
category.set_permissions("#{group.name}": :full)
|
||||
category.save!
|
||||
end
|
||||
|
||||
it "does not return categories the user cannot see" do
|
||||
get "/groups/#{group.name}/permissions.json"
|
||||
expect(response.parsed_body).to eq([])
|
||||
end
|
||||
|
||||
it "returns categories the user can see" do
|
||||
group.add(other_user)
|
||||
|
||||
get "/groups/#{group.name}/permissions.json"
|
||||
expect(response.parsed_body.count).to eq(1)
|
||||
expect(response.parsed_body.first["category"]["id"]).to eq(category.id)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns categories alphabetically" do
|
||||
sign_in(user)
|
||||
|
||||
["Three", "New Cat", "Abc", "Hello"].each do |name|
|
||||
category = Fabricate(:category, name: name)
|
||||
category.set_permissions("#{group.name}": :full)
|
||||
category.save!
|
||||
end
|
||||
|
||||
get "/groups/#{group.name}/permissions.json"
|
||||
expect(response.parsed_body.map { |permission| permission["category"]["name"] }).to eq(
|
||||
["Abc", "Hello", "New Cat", "Three"]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue