Skip to content

Commit 1e82475

Browse files
authored
Merge pull request #1435 from plone/pgrunewald-clear-selection
Clear selection when changing path in structure pattern
2 parents cf58049 + 12f2127 commit 1e82475

File tree

10 files changed

+170
-202
lines changed

10 files changed

+170
-202
lines changed

src/pat/structure/js/actionmenu.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,6 @@ const menuOptions = {
7171
css: "",
7272
modal: false,
7373
},
74-
"selectAll": {
75-
method: "selectAll",
76-
url: "#",
77-
title: _t("Select all contained items"),
78-
category: "dropdown",
79-
icon: "check-all",
80-
css: "",
81-
modal: false,
82-
},
8374
};
8475

8576
const ActionMenu = function (menu) {
@@ -108,10 +99,6 @@ const ActionMenu = function (menu) {
10899
delete result["set-default-page"];
109100
}
110101

111-
if (!model.is_folderish) {
112-
delete result.selectAll;
113-
}
114-
115102
const typeToViewAction = app.options.typeToViewAction;
116103
const viewAction = (typeToViewAction && typeToViewAction[model.portal_type]) || "";
117104
result.openItem.url = model.getURL + viewAction;

src/pat/structure/js/views/app.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,11 @@ export default BaseView.extend({
105105

106106
this.wellView = new SelectionWellView({
107107
collection: this.selectedCollection,
108-
triggerView: this.toolbar.get("selected-items"),
108+
triggerView: this.toolbar.get("change-selection"),
109109
app: this,
110-
id: "selected-items",
110+
id: "change-selection",
111111
});
112112

113-
this.toolbar.get("selected-items").disable();
114113
this.buttons.disable();
115114

116115
let timeout = 0;
@@ -241,10 +240,8 @@ export default BaseView.extend({
241240

242241
updateButtons: function () {
243242
if (this.selectedCollection.length) {
244-
this.toolbar.get("selected-items").enable();
245243
this.buttons.enable();
246244
} else {
247-
this.toolbar.get("selected-items").disable();
248245
this.buttons.disable();
249246
}
250247

@@ -302,6 +299,9 @@ export default BaseView.extend({
302299
this.collection.setCurrentPath(path);
303300
// this.textfilter.clearTerm();
304301
this.clearStatus();
302+
303+
// remove the selection the user made
304+
this.selectedCollection.reset();
305305
},
306306

307307
getAjaxUrl: function (url) {
@@ -406,10 +406,11 @@ export default BaseView.extend({
406406

407407
items.push(
408408
new SelectionButtonView({
409-
title: _t("Selected"),
410-
id: "selected-items",
409+
title: _t("${current} of ${total} selected", { current: 0, total: 0 }),
410+
id: "change-selection",
411411
tooltip: _t("Manage selection"),
412412
collection: this.selectedCollection,
413+
appCollection: this.collection,
413414
icon: "plone-selection",
414415
})
415416
);

src/pat/structure/js/views/selectionbutton.js

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import ButtonView from "../../../../core/ui/views/button";
2-
import tplButton from "../../templates/selection_button.xml";
32

43
export default ButtonView.extend({
54
collection: null,
6-
template: tplButton,
5+
template: '<%- _t("${current} of ${total} selected", { current: current, total: total }) %>',
76

87
initialize: function (options) {
98
ButtonView.prototype.initialize.apply(this, [options]);
@@ -24,17 +23,14 @@ export default ButtonView.extend({
2423
this
2524
);
2625
}
26+
// keep count up-to-date
27+
this.appCollection.on('reset sync', this.render, this);
2728
},
2829

29-
serializedModel: function () {
30-
const obj = {
31-
icon: "",
32-
title: this.options.title,
33-
length: 0,
30+
serializedModel: function() {
31+
return {
32+
current: (this.collection !== null) ? this.collection.length : 0,
33+
total: (this.appCollection.state.totalRecords) ? this.appCollection.state.totalRecords : 0,
3434
};
35-
if (this.collection !== null) {
36-
obj.length = this.collection.length;
37-
}
38-
return obj;
3935
},
4036
});

src/pat/structure/js/views/selectionwell.js

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ import _ from "underscore";
33
import PopoverView from "../../../../core/ui/views/popover";
44
import utils from "../../../../core/utils";
55
import ItemTemplate from "../../templates/selection_item.xml";
6+
import Actions from "../actions";
7+
import _t from "../../../../core/i18n-wrapper";
68

79
export default PopoverView.extend({
8-
className: "popover selected-items",
10+
className: "popover change-selection",
911

10-
title: _.template(
11-
'<input type="text" class="filter" placeholder="<%- _t("Filter") %>" />' +
12-
'<a href="#" class=" remove-all">' +
13-
'<%= removeIcon %> <%- _t("remove all") %></a>'
14-
),
12+
13+
title: _t("Manage selection"),
1514

1615
content: _.template(
17-
"<% collection.each(function(item) { %>" +
18-
"<%= item_template($.extend({'removeIcon': removeIcon}, item.toJSON())) %>" +
19-
"<% }); %>"
16+
'<div class="list-group">' +
17+
'<a href="#" class="list-group-item list-group-item-action select-all"><%= selectAllIcon %> <%- _t("Select all items in the folder") %></a>' +
18+
'<a href="#" class="list-group-item list-group-item-action select-all-visible"><%= selectPageIcon %> <%- _t("Select all items on this page") %></a>' +
19+
'<a href="#" class="list-group-item list-group-item-action remove-all"><%= removeIcon %> <%- _t("Cancel selection") %></a>' +
20+
'</div>'
2021
),
2122

2223
events: {
23-
"click a.remove": "itemRemoved",
24-
"keyup input.filter": "filterSelected",
24+
"click .select-all": "selectAll",
25+
"click .select-all-visible": "selectVisible",
2526
"click .remove-all": "removeAll",
2627
},
2728

@@ -39,35 +40,33 @@ export default PopoverView.extend({
3940

4041
render: async function () {
4142
this.options["removeIcon"] = await utils.resolveIcon("x-circle");
43+
this.options["selectAllIcon"] = await utils.resolveIcon("check2-all");
44+
this.options["selectPageIcon"] = await utils.resolveIcon("check2");
4245
PopoverView.prototype.render.call(this);
4346
if (this.collection.length === 0) {
4447
this.$el.removeClass("active");
4548
}
4649
return this;
4750
},
48-
49-
itemRemoved: function (e) {
50-
e.preventDefault();
51-
const uid = $(e.currentTarget).data("uid");
52-
this.collection.removeByUID(uid);
53-
if (this.collection.length !== 0) {
54-
// re-rendering causes it to close, reopen
55-
this.show();
56-
}
51+
selectAll: function (e) {
52+
// use the actions module as it has a handy "selectAll" method
53+
const actions = new Actions({
54+
app: this.options.app,
55+
model: {
56+
attributes: this.options.app.options,
57+
},
58+
selectedCollection: this.options.collection,
59+
});
60+
actions.selectAll(e);
61+
this.options.app.tableView.setContextInfo();
62+
this.hide();
5763
},
58-
59-
filterSelected: function (e) {
60-
const val = $(e.target).val().toLowerCase();
61-
for (const item of $(".selected-item", this.$el)) {
62-
const $el = $(item);
63-
if ($el.text().toLowerCase().indexOf(val) === -1) {
64-
$el.hide();
65-
} else {
66-
$el.show();
67-
}
68-
}
64+
selectVisible: function (e) {
65+
e.preventDefault();
66+
this.collection.reset();
67+
$('input[type="checkbox"]', this.app.tableView.$('tbody')).prop('checked', true).change();
68+
this.hide();
6969
},
70-
7170
removeAll: function (e) {
7271
e.preventDefault();
7372
this.collection.reset();

src/pat/structure/js/views/table.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@ export default BaseView.extend({
6868
this.trigger("context-info:set");
6969
},
7070

71-
render: async function () {
71+
/**
72+
* Render method
73+
* @param {any} triggerCollection – if render is called as callback for a Backbone collection, Backbone will
74+
* pass the collection as first argument
75+
*/
76+
render: async function (triggerCollection) {
7277
// By default do not start sorted by any column
7378
// Ignore first column and the last one (activeColumns.length + 1)
7479
// Do not show paginator, search or information, we only want column sorting
@@ -156,6 +161,14 @@ export default BaseView.extend({
156161
await table_row_rendering_finished();
157162
events.remove_event_listener = (this.el, "table_row_rendering_finished__listener"); // prettier-ignore
158163
registry.scan(this.$el);
164+
165+
// Set the context (again) after rerendering. If render was called after a collection sync – which is the
166+
// case if Backbone passed the collection as eventObject – do nothing, as collection syncs are always
167+
// followed by a context sync followed by a 'context-info-loaded' event,
168+
// which will trigger setContextInfo with the new context anyway.
169+
if (this.contextInfo && triggerCollection !== this.collection) {
170+
this.setContextInfo();
171+
}
159172
}
160173

161174
this.$el
@@ -231,6 +244,7 @@ export default BaseView.extend({
231244
},
232245

233246
selectAll: function (e) {
247+
// select all items on the *current* page
234248
if ($(e.target).is(":checked")) {
235249
$('input[type="checkbox"]', this.$("tbody")).prop("checked", true).trigger("change");
236250
} else {
@@ -242,12 +256,6 @@ export default BaseView.extend({
242256
}
243257
this.setContextInfo();
244258
},
245-
toggleSelectAll: function (e) {
246-
const $el = $(e.target);
247-
if (!$el.is(":checked")) {
248-
this.$(".select-all").prop("checked", false);
249-
}
250-
},
251259

252260
addReordering: function () {
253261
// if we have a custom query going on, we do not allow sorting.

src/pat/structure/structure.scss

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
margin-right: 1em;
4141
}
4242

43-
#btn-selected-items,
43+
#btn-change-selection,
4444
#btn-structure-rearrange,
4545
#btn-upload,
4646
#btn-filter {
@@ -292,38 +292,26 @@
292292
}
293293
}
294294

295-
.popover.selected-items {
295+
.popover.change-selection {
296296
--bs-popover-max-width: 350px;
297297

298-
.items {
299-
max-height: 300px;
300-
overflow-y: auto;
301-
302-
.selected-item {
303-
display: flex;
304-
margin: 0 8px 3px 0;
305-
border-radius: 6px;
306-
padding: 4px 6px;
307-
word-break: break-all;
308-
&:hover {
309-
background-color: var(--bs-light);
310-
}
311-
312-
a {
313-
padding-right:.5rem;
298+
.popover-content {
299+
padding: 0;
300+
}
314301

315-
&:hover {
316-
text-decoration: none;
317-
}
302+
.list-group-item:first-child {
303+
border-top-left-radius: unset;
304+
border-top-right-radius: unset;
305+
}
318306

319-
&:before {
320-
color: var(--bs-gray);
307+
a {
308+
svg {
309+
margin-right: calc(var(--bs-list-group-item-padding-x) * 0.5);
310+
display: inline-block;
311+
}
321312

322-
&:hover {
323-
color: var(--bs-gray-dark);
324-
}
325-
}
326-
}
313+
&:hover {
314+
text-decoration: none;
327315
}
328316
}
329317
}

0 commit comments

Comments
 (0)