UX: Adjustments to tag groups layout (#13269)

This commit is contained in:
Penar Musaraj 2021-06-03 13:58:28 -04:00 committed by GitHub
parent b27674597c
commit 9a449ac534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 242 additions and 158 deletions

View File

@ -5,9 +5,11 @@ import PermissionType from "discourse/models/permission-type";
import bootbox from "bootbox"; import bootbox from "bootbox";
import { bufferedProperty } from "discourse/mixins/buffered-content"; import { bufferedProperty } from "discourse/mixins/buffered-content";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { inject as service } from "@ember/service";
import { isEmpty } from "@ember/utils"; import { isEmpty } from "@ember/utils";
export default Component.extend(bufferedProperty("model"), { export default Component.extend(bufferedProperty("model"), {
router: service(),
tagName: "", tagName: "",
allGroups: null, allGroups: null,
@ -36,15 +38,6 @@ export default Component.extend(bufferedProperty("model"), {
); );
}, },
@discourseComputed("buffered.permissions")
showPrivateChooser(permissions) {
if (!permissions) {
return true;
}
return permissions.everyone !== PermissionType.READONLY;
},
@discourseComputed("buffered.permissions", "allGroups") @discourseComputed("buffered.permissions", "allGroups")
selectedGroupIds(permissions, allGroups) { selectedGroupIds(permissions, allGroups) {
if (!permissions || !allGroups) { if (!permissions || !allGroups) {
@ -140,6 +133,8 @@ export default Component.extend(bufferedProperty("model"), {
if (this.onSave) { if (this.onSave) {
this.onSave(); this.onSave();
} else {
this.router.transitionTo("tagGroups.index");
} }
}); });
}, },

View File

@ -8,7 +8,7 @@ export default Controller.extend({
const tagGroups = this.tagGroups.model; const tagGroups = this.tagGroups.model;
tagGroups.pushObject(this.model); tagGroups.pushObject(this.model);
this.transitionToRoute("tagGroups.edit", this.model); this.transitionToRoute("tagGroups.index");
}, },
}, },
}); });

View File

@ -1,106 +1,123 @@
<div class="tag-group-content"> <section class="group-name">
<h1>{{text-field value=buffered.name}}</h1> <label>{{i18n "tagging.groups.name_placeholder"}}</label>
<br> <div>{{text-field value=buffered.name}}</div>
</section>
<section class="group-tags-list"> <section class="group-tags-list">
<label>{{i18n "tagging.groups.tags_label"}}</label><br> <label>{{i18n "tagging.groups.tags_label"}}</label><br>
{{tag-chooser {{tag-chooser
tags=buffered.tag_names tags=buffered.tag_names
everyTag=true everyTag=true
allowCreate=true allowCreate=true
unlimitedTagCount=true unlimitedTagCount=true
excludeSynonyms=true}} excludeSynonyms=true
</section> options=(hash
filterPlaceholder="tagging.groups.tags_placeholder"
)
}}
</section>
<section class="parent-tag-section"> <section class="parent-tag-section">
<label>{{i18n "tagging.groups.parent_tag_label"}}</label> <label>{{i18n "tagging.groups.parent_tag_label"}}</label>
<div>
{{tag-chooser {{tag-chooser
tags=buffered.parent_tag_name tags=buffered.parent_tag_name
everyTag=true everyTag=true
maximum=1 maximum=1
allowCreate=true allowCreate=true
excludeSynonyms=true}} excludeSynonyms=true
<span class="description">{{i18n "tagging.groups.parent_tag_description"}}</span> options=(hash
</section> filterPlaceholder="tagging.groups.parent_tag_placeholder"
)
}}
</div>
<div class="description">{{i18n "tagging.groups.parent_tag_description"}}</div>
</section>
<section class="group-one-per-topic"> <section class="group-one-per-topic">
<label> <label>
{{input type="checkbox" checked=buffered.one_per_topic name="onepertopic"}} {{input type="checkbox" checked=buffered.one_per_topic name="onepertopic"}}
{{i18n "tagging.groups.one_per_topic_label"}} {{i18n "tagging.groups.one_per_topic_label"}}
</label>
</section>
<section class="group-visibility">
<div>
{{radio-button
class="tag-permissions-choice"
name="tag-permissions-choice"
value="public"
id="public-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<label class="radio" for="public-permission">
{{i18n "tagging.groups.everyone_can_use"}}
</label> </label>
</section> </div>
<div>
{{radio-button
class="tag-permissions-choice"
name="tag-permissions-choice"
value="visible"
id="visible-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<section class="group-visibility"> <label class="radio" for="visible-permission">
<div> {{i18n "tagging.groups.usable_only_by_groups"}}
{{radio-button </label>
class="tag-permissions-choice"
name="tag-permissions-choice"
value="public"
id="public-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<label class="radio" for="public-permission"> <div class="group-access-control">
{{i18n "tagging.groups.everyone_can_use"}}
</label>
</div>
<div>
{{radio-button
class="tag-permissions-choice"
name="tag-permissions-choice"
value="visible"
id="visible-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<label class="radio" for="visible-permission">
{{i18n "tagging.groups.usable_only_by_groups"}}
</label>
<div class="group-access-control {{if showPrivateChooser "hidden"}}">
{{group-chooser
content=allGroups
value=selectedGroupIds
labelProperty="name"
onChange=(action "setPermissionsGroups")
}}
</div>
</div>
<div>
{{radio-button
class="tag-permissions-choice"
name="tag-permissions-choice"
value="private"
id="private-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<label class="radio" for="private-permission">
{{i18n "tagging.groups.visible_only_to_groups"}}
</label>
</div>
<div class="group-access-control {{unless showPrivateChooser "hidden"}}">
{{group-chooser {{group-chooser
content=allGroups content=allGroups
value=selectedGroupIds value=selectedGroupIds
labelProperty="name" labelProperty="name"
onChange=(action "setPermissionsGroups")}} onChange=(action "setPermissionsGroups")
options=(hash
filterPlaceholder="tagging.groups.select_groups_placeholder"
)
}}
</div> </div>
</section>
<div class="tag-group-controls">
{{d-button
class="btn-default"
action=(action "save")
disabled=buffered.isSaving
label="tagging.groups.save"}}
{{d-button
class="btn-danger"
action=(action "destroy")
disabled=buffered.isNew
icon="far-trash-alt"
label="tagging.groups.delete"}}
</div> </div>
<div>
{{radio-button
class="tag-permissions-choice"
name="tag-permissions-choice"
value="private"
id="private-permission"
selection=buffered.permissionName
onChange=(action "setPermissionsType")}}
<label class="radio" for="private-permission">
{{i18n "tagging.groups.visible_only_to_groups"}}
</label>
<div class="group-access-control">
{{group-chooser
content=allGroups
value=selectedGroupIds
labelProperty="name"
onChange=(action "setPermissionsGroups")
options=(hash
filterPlaceholder="tagging.groups.select_groups_placeholder"
)
}}
</div>
</div>
</section>
<div class="tag-group-controls">
{{d-button
class="btn-primary"
action=(action "save")
disabled=buffered.isSaving
label="tagging.groups.save"}}
{{d-button
class="btn-danger"
action=(action "destroy")
disabled=buffered.isNew
icon="far-trash-alt"
label="tagging.groups.delete"}}
</div> </div>

View File

@ -1 +1,4 @@
{{tag-groups-form model=model onDestroy=(action "onDestroy")}} <div class="tag-group-content">
<h3>{{i18n "tagging.groups.edit_title"}}</h3>
{{tag-groups-form model=model onDestroy=(action "onDestroy")}}
</div>

View File

@ -1,3 +1,19 @@
<div class="tag-group-content"> <div class="tag-group-content">
<p class="about">{{i18n "tagging.groups.about"}}</p> <h3>
{{#if model}}
{{i18n "tagging.groups.about_heading"}}
{{else}}
{{i18n "tagging.groups.about_heading_empty"}}
{{/if}}
</h3>
<section class="tag-groups-about">
<p>{{i18n "tagging.groups.about_description"}}</p>
</section>
<section>
{{#unless model}}
{{#link-to "tagGroups.new" class="btn btn-primary"}}
{{d-icon "plus"}} {{i18n "tagging.groups.new"}}
{{/link-to}}
{{/unless}}
</section>
</div> </div>

View File

@ -1 +1,4 @@
{{tag-groups-form model=model onSave=(action "onSave")}} <div class="tag-group-content">
<h3>{{i18n "tagging.groups.new_title"}}</h3>
{{tag-groups-form model=model onSave=(action "onSave")}}
</div>

View File

@ -1,27 +1,33 @@
<div class="container tag-groups-container"> <div class="container tag-groups-container">
<h2>{{i18n "tagging.groups.title"}}</h2> <h2>{{i18n "tagging.groups.title"}}</h2>
<div class="content-list"> {{#if this.siteSettings.tagging_enabled}}
<ul> {{#if model}}
{{#each model as |tagGroup|}} <div class="tag-groups-sidebar content-list">
<li> <ul>
{{#link-to "tagGroups.edit" tagGroup}} {{#each model as |tagGroup|}}
{{tagGroup.name}} <li>
{{/link-to}} {{#link-to "tagGroups.edit" tagGroup}}
</li> {{tagGroup.name}}
{{/each}} {{/link-to}}
</ul> </li>
{{/each}}
</ul>
{{#if this.siteSettings.tagging_enabled}} {{d-button
{{d-button class="btn-default"
class="btn-default" action=(action "newTagGroup")
action=(action "newTagGroup") icon="plus"
icon="plus" label="tagging.groups.new"
label="tagging.groups.new"}} }}
</div>
{{/if}} {{/if}}
</div>
{{outlet}} {{outlet}}
{{else}}
<div class="tag-group-content">
<div class="alert info">{{i18n "tagging.groups.disabled"}}</div>
</div>
{{/if}}
<div class="clearfix"></div>
</div> </div>

View File

@ -39,18 +39,20 @@ acceptance("Tag Groups", function (needs) {
}); });
test("tag groups can be saved and deleted", async function (assert) { test("tag groups can be saved and deleted", async function (assert) {
const tags = selectKit(".tag-chooser"); const tags = selectKit(".group-tags-list .tag-chooser");
await visit("/tag_groups"); await visit("/tag_groups");
await click(".content-list .btn"); await click(".tag-group-content .btn.btn-primary");
await fillIn(".tag-group-content .group-name input", "test tag group");
await fillIn(".tag-group-content h1 input", "test tag group");
await tags.expand(); await tags.expand();
await tags.selectRowByValue("monkey"); await tags.selectRowByValue("monkey");
await click(".tag-group-content .btn.btn-primary");
await click(".tag-groups-sidebar li:first-child a");
await tags.expand();
await click(".tag-group-content .btn.btn-default"); await click(".group-tags-list .tag-chooser .choice:nth-of-type(1)");
await click(".tag-chooser .choice:nth-of-type(1)");
assert.ok(!queryAll(".tag-group-content .btn.btn-danger")[0].disabled); assert.ok(!queryAll(".tag-group-content .btn.btn-danger")[0].disabled);
}); });
@ -59,9 +61,9 @@ acceptance("Tag Groups", function (needs) {
const groups = selectKit(".group-chooser"); const groups = selectKit(".group-chooser");
await visit("/tag_groups"); await visit("/tag_groups");
await click(".content-list .btn"); await click(".tag-group-content .btn.btn-primary");
await fillIn(".tag-group-content h1 input", "test tag group"); await fillIn(".tag-group-content .group-name input", "test tag group");
await tags.expand(); await tags.expand();
await tags.selectRowByValue("monkey"); await tags.selectRowByValue("monkey");
@ -69,9 +71,12 @@ acceptance("Tag Groups", function (needs) {
await groups.expand(); await groups.expand();
await groups.selectRowByIndex(1); await groups.selectRowByIndex(1);
await groups.selectRowByIndex(0); await groups.selectRowByIndex(0);
assert.ok(!queryAll(".tag-group-content .btn.btn-default")[0].disabled);
await click(".tag-group-content .btn.btn-default"); assert.ok(!queryAll(".tag-group-content .btn.btn-primary")[0].disabled);
await click(".tag-group-content .btn.btn-primary");
await click(".tag-groups-sidebar li:first-child a");
assert.ok( assert.ok(
exists("#visible-permission:checked"), exists("#visible-permission:checked"),
"selected permission does not change after saving" "selected permission does not change after saving"

View File

@ -211,53 +211,84 @@ header .discourse-tag {
} }
.tag-groups-container { .tag-groups-container {
margin-top: 20px; display: grid;
.content-list { grid-template-columns: 1fr 5fr;
width: 20%; grid-template-rows: auto auto;
float: left; grid-template-areas: "header header" "sidebar content" "fullwidth fullwidth";
margin: 20px 0; padding-bottom: 3em;
ul {
margin-bottom: 10px; > h2 {
} grid-area: header;
.btn { background: var(--primary-very-low);
margin-left: 10px; padding: 20px;
margin-bottom: 1em;
}
.tag-groups-sidebar {
grid-area: sidebar;
// generic .content-list overrides
width: auto;
float: none;
ul li:last-child {
margin-bottom: 1em;
} }
} }
.tag-groups-sidebar + .tag-group-content {
grid-area: content;
}
.tag-group-content { .tag-group-content {
width: 75%; grid-area: fullwidth;
float: right;
section { section {
margin-bottom: 20px; margin-bottom: 1.5em;
} }
h3,
section,
.tag-group-controls {
padding-left: 20px;
}
label { label {
font-size: $font-0; font-size: var(--font-0);
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 5px;
&.radio {
padding-left: 0px;
}
} }
.btn { .btn {
margin-right: 10px; margin-right: 10px;
} }
h1 input {
width: 100%;
}
.group-access-control { .group-access-control {
margin-left: 44px; margin-left: 26px;
margin-bottom: 10px; margin-bottom: 1em;
}
input[type="radio"] ~ .group-access-control {
display: none;
}
input[type="radio"]:checked ~ .group-access-control {
display: block;
} }
} }
.tag-group-controls { .tag-group-controls {
display: flex; display: flex;
justify-content: space-between;
} }
.group-tags-list .tag-chooser { .group-tags-list .tag-chooser {
width: 100%; width: calc(100% - 1em);
} }
.saving { .saving {
margin-left: 20px; margin-left: 20px;
} }
.parent-tag-section { .parent-tag-section {
.tag-chooser { .tag-chooser {
width: 200px; width: 210px;
margin-right: 10px; }
.description {
color: var(--primary-medium);
margin-top: 0.5em;
font-size: var(--font-down-1);
} }
} }
} }

View File

@ -3704,14 +3704,18 @@ en:
groups: groups:
title: "Tag Groups" title: "Tag Groups"
about: "Add tags to groups to manage them more easily." about_heading: "Select a tag group or create a new one"
about_heading_empty: "Create a new tag group to get started"
about_description: "Tag groups help you manage permissions for many tags in one place."
new: "New Group" new: "New Group"
tags_label: "Tags in this group:" new_title: "Create New Group"
parent_tag_label: "Parent tag:" edit_title: "Edit Tag Group"
parent_tag_description: "Tags from this group can't be used unless the parent tag is present." tags_label: "Tags in this group"
parent_tag_label: "Parent tag"
parent_tag_description: "Tags from this group can only be used if the parent tag is present."
one_per_topic_label: "Limit one tag per topic from this group" one_per_topic_label: "Limit one tag per topic from this group"
new_name: "New Tag Group" new_name: "New Tag Group"
name_placeholder: "Tag Group Name" name_placeholder: "Name"
save: "Save" save: "Save"
delete: "Delete" delete: "Delete"
confirm_delete: "Are you sure you want to delete this tag group?" confirm_delete: "Are you sure you want to delete this tag group?"
@ -3719,6 +3723,10 @@ en:
usable_only_by_groups: "Tags are visible to everyone, but only the following groups can use them" usable_only_by_groups: "Tags are visible to everyone, but only the following groups can use them"
visible_only_to_groups: "Tags are visible only to the following groups" visible_only_to_groups: "Tags are visible only to the following groups"
cannot_save: "Cannot save tag group. Make sure that there is at least one tag present, tag group name is not empty, and a group is selected for tags permission." cannot_save: "Cannot save tag group. Make sure that there is at least one tag present, tag group name is not empty, and a group is selected for tags permission."
tags_placeholder: "Search or create tags"
parent_tag_placeholder: "Optional"
select_groups_placeholder: "Select groups..."
disabled: "Tagging is disabled. "
topics: topics:
none: none: