FEATURE: Group category permissions tab (#10388)

This commit is contained in:
Mark VanLandingham 2020-08-10 09:49:05 -05:00 committed by GitHub
parent b44748e503
commit b7a092bd28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 164 additions and 14 deletions

View File

@ -0,0 +1,3 @@
import Controller from "@ember/controller";
export default Controller.extend();

View File

@ -79,6 +79,13 @@ export default Controller.extend({
);
}
defaultTabs.push(
Tab.create({
name: "permissions",
i18nKey: "permissions.title"
})
);
return defaultTabs;
},

View File

@ -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;

View File

@ -103,6 +103,8 @@ export default function() {
this.route("inbox");
this.route("archive");
});
this.route("permissions");
});
// User routes

View File

@ -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");
}
});

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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"

View File

@ -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