Skip to content

Commit a4ce90e

Browse files
authored
UX: Improve assign modal design (#403)
Implements a new design that improves the user experience: - add a clear cancel button - add an indication the note is optional - change the plus icon to a search icon - show an error when the user tries to assign without choosing an assignee - move suggestions to default search results - focus search input when modal is displayed
1 parent 700dfe5 commit a4ce90e

File tree

8 files changed

+69
-69
lines changed

8 files changed

+69
-69
lines changed

assets/javascripts/discourse-assign/controllers/assign-user.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ export default Controller.extend(ModalFunctionality, {
1515
taskActions: service(),
1616
autofocus: not("capabilities.touch"),
1717
assigneeName: or("model.username", "model.group_name"),
18+
assigneeError: false,
1819

1920
init() {
2021
this._super(...arguments);
21-
this.allowedGroups = [];
22+
23+
this.set("allowedGroups", []);
24+
this.set("assigneeError", false);
2225

2326
ajax("/assign/suggestions").then((data) => {
2427
if (this.isDestroying || this.isDestroyed) {
@@ -77,6 +80,11 @@ export default Controller.extend(ModalFunctionality, {
7780
return this.bulkAction(this.model.username);
7881
}
7982

83+
if (!this.assigneeName) {
84+
this.set("assigneeError", true);
85+
return;
86+
}
87+
8088
let path = "/assign/assign";
8189

8290
if (isEmpty(this.get("model.username"))) {
@@ -136,6 +144,7 @@ export default Controller.extend(ModalFunctionality, {
136144
},
137145

138146
setGroupOrUser(name) {
147+
this.set("assigneeError", false);
139148
if (this.allowedGroupsForAssignment.includes(name)) {
140149
this.setProperties({
141150
"model.username": null,

assets/javascripts/discourse-assign/initializers/extend-for-assigns.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -924,10 +924,7 @@ export default {
924924
actions: {
925925
showReAssign() {
926926
this.set("assignUser.isBulkAction", true);
927-
this.set("assignUser.model", {
928-
username: "",
929-
description: "discourse_assign.assign_bulk_modal.description",
930-
});
927+
this.set("assignUser.model", { username: "" });
931928
this.send("changeBulkTemplate", "modal/assign-user");
932929
},
933930
unassignTopics() {

assets/javascripts/discourse/services/task-actions.js

-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ export default Service.extend({
2929
this.i18nSuffix(options.targetType) +
3030
`.${options.isAssigned ? "reassign_title" : "title"}`,
3131
model: {
32-
description:
33-
`discourse_assign.${options.isAssigned ? "reassign" : "assign"}` +
34-
this.i18nSuffix(options.targetType) +
35-
".description",
3632
reassign: options.isAssigned,
3733
username: target.assigned_to_user?.username,
3834
group_name: target.assigned_to_group?.name,
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
{{#d-modal-body class="assign"}}
22
<div>
3-
<p>{{i18n model.description}}</p>
4-
{{email-group-user-chooser
5-
autocomplete="off"
6-
value=assigneeName
7-
onChange=(action "assignUsername")
8-
autofocus="autofocus"
9-
showUserStatus=true
10-
options=(hash
11-
mobilePlacementStrategy="absolute"
12-
filterPlaceholder=placeholderKey
13-
includeGroups=true
14-
customSearchOptions=(hash assignableGroups=true)
15-
groupMembersOf=allowedGroups
16-
maximum=1
17-
autofocus=autofocus
18-
tabindex=1
19-
)
20-
}}
21-
<div class="assign-suggestions">
22-
{{#each assignSuggestions as |user|}}
23-
<a href {{action "assignUser" user.username }}>
24-
{{avatar user imageSize="small"}}
25-
{{decorate-username-selector user.username}}
26-
</a>
27-
{{/each}}
3+
<div class="control-group {{if this.assigneeError "assignee-error"}}">
4+
<label>{{i18n "discourse_assign.assign_modal.assignee_label"}}</label>
5+
{{email-group-user-chooser
6+
autocomplete="off"
7+
value=assigneeName
8+
onChange=(action "assignUsername")
9+
autofocus="autofocus"
10+
showUserStatus=true
11+
caretIcon="search"
12+
options=(hash
13+
mobilePlacementStrategy="absolute"
14+
filterPlaceholder=placeholderKey
15+
includeGroups=true
16+
customSearchOptions=(hash assignableGroups=true defaultSearchResults=this.assignSuggestions)
17+
groupMembersOf=allowedGroups
18+
maximum=1
19+
autofocus=autofocus
20+
tabindex=1
21+
)
22+
}}
23+
{{#if this.assigneeError}}
24+
<span class="error-label">
25+
{{d-icon "exclamation-triangle"}} {{i18n "discourse_assign.assign_modal.choose_assignee"}}
26+
</span>
27+
{{/if}}
2828
</div>
29+
2930
{{#if this.statusEnabled}}
3031
<div class="control-group assign-status">
3132
<label>{{i18n "discourse_assign.assign_modal.status_label"}}</label>
@@ -37,8 +38,11 @@
3738
}}
3839
</div>
3940
{{/if}}
41+
4042
<div class="control-group assign-status">
41-
<label>{{i18n "discourse_assign.assign_modal.note_label"}}</label>
43+
<label>
44+
{{i18n "discourse_assign.assign_modal.note_label"}}&nbsp;<span class="label-optional">{{i18n "discourse_assign.assign_modal.optional_label"}}</span>
45+
</label>
4246
{{textarea id="assign-modal-note" value=model.note key-down=(action "handleTextAreaKeydown")}}
4347
</div>
4448
</div>
@@ -52,4 +56,5 @@
5256
class="btn-primary"
5357
disabled=disabled
5458
}}
59+
<DModalCancel @close={{route-action "closeModal"}} />
5560
</div>

assets/stylesheets/assigns.scss

+24-24
Original file line numberDiff line numberDiff line change
@@ -66,37 +66,37 @@
6666
margin-left: 5px;
6767
}
6868

69-
.assign.modal-body .email-group-user-chooser {
70-
display: block;
71-
width: 300px;
72-
margin-top: 5px;
73-
}
74-
75-
.assign-user-modal p {
76-
margin-top: 0;
77-
}
69+
.assign-user-modal {
70+
.modal-inner-container {
71+
width: 400px;
72+
}
7873

79-
.assign-suggestions {
80-
margin-top: 15px;
81-
margin-bottom: 15px;
74+
label {
75+
font-weight: bold;
8276

83-
img {
84-
margin-right: 5px;
85-
cursor: pointer;
77+
.label-optional {
78+
color: var(--primary-medium);
79+
font-weight: normal;
80+
}
8681
}
8782

88-
.groups {
89-
margin-top: 5px;
90-
a {
91-
margin-right: 5px;
83+
.email-group-user-chooser {
84+
width: 100%;
85+
86+
.caret-icon {
87+
color: var(--primary-medium);
9288
}
9389
}
9490

95-
.on-holiday {
96-
position: absolute;
97-
margin-left: -18px;
98-
margin-top: 14px;
99-
color: var(--primary-medium);
91+
.control-group.assignee-error {
92+
.select-kit-header {
93+
border-color: var(--danger);
94+
}
95+
96+
.error-label {
97+
color: var(--danger);
98+
font-size: var(--font-down-1);
99+
}
100100
}
101101
}
102102

config/locales/client.en.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -50,19 +50,17 @@ en:
5050
help: "Edit assignment details"
5151
reassign_modal:
5252
title: "Reassign Topic"
53-
description: "Enter the name of the user you'd like to Reassign this topic"
5453
assign_modal:
5554
title: "Assign Topic"
5655
reassign_title: "Reassign Topic"
57-
description: "Enter the name of the user you'd like to assign this topic"
5856
assign: "Assign"
57+
assignee_label: Assignee
58+
choose_assignee: Choose a user to assign.
5959
note_label: Note
60+
optional_label: "(optional)"
6061
status_label: Status
6162
assign_post_modal:
6263
title: "Assign Post"
63-
description: "Enter the name of the user you'd like to assign this post"
64-
assign_bulk_modal:
65-
description: "Enter the name of the user you'd like to assign these topics"
6664
claim:
6765
title: "claim"
6866
help: "Assign topic to yourself"

test/javascripts/acceptance/assign-enabled-test.js

-4
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ acceptance("Discourse Assign | Assign mobile", function (needs) {
4646
assert.ok(menu.rowByValue("assign").exists());
4747
await menu.selectRowByValue("assign");
4848
assert.ok(exists(".assign.modal-body"), "assign modal opens");
49-
50-
await click(".assign-suggestions .avatar");
5149
});
5250
});
5351

@@ -102,8 +100,6 @@ acceptance("Discourse Assign | Assign desktop", function (needs) {
102100
await click("#topic-footer-button-assign");
103101

104102
assert.ok(exists(".assign.modal-body"), "assign modal opens");
105-
106-
await click(".assign-suggestions .avatar");
107103
});
108104
});
109105

test/javascripts/unit/task-actions-test.js

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ discourseModule("Unit | Service | task-actions", function () {
2121
assert.deepEqual(modalCall[1], {
2222
title: "discourse_assign.assign_modal.title",
2323
model: {
24-
description: "discourse_assign.assign_modal.description",
2524
reassign: false,
2625
username: "tomtom",
2726
group_name: "cats",

0 commit comments

Comments
 (0)