@girder/core 3.1.0 → 3.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/collections/Collection.js +30 -2
- package/collections/UserCollection.js +1 -1
- package/dialog.js +2 -2
- package/package.json +2 -2
- package/stylesheets/widgets/hierarchyWidget.styl +28 -0
- package/templates/widgets/hierarchyPaginated.pug +19 -0
- package/templates/widgets/hierarchyWidget.pug +1 -0
- package/templates/widgets/itemList.pug +1 -1
- package/views/body/SystemConfigurationView.js +1 -1
- package/views/widgets/BrowserWidget.js +3 -0
- package/views/widgets/HierarchyWidget.js +97 -3
- package/views/widgets/ItemListWidget.js +101 -15
|
@@ -48,6 +48,11 @@ var Collection = Backbone.Collection.extend({
|
|
|
48
48
|
*/
|
|
49
49
|
pageOffsetStack: null,
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Number of items in the collection returned by 'girder-total-count' header
|
|
53
|
+
*/
|
|
54
|
+
_totalCount: 0,
|
|
55
|
+
|
|
51
56
|
/**
|
|
52
57
|
* Returns a boolean of whether or not this collection has previous pages,
|
|
53
58
|
* i.e. if the offset of the current page start is > 0
|
|
@@ -69,7 +74,15 @@ var Collection = Backbone.Collection.extend({
|
|
|
69
74
|
hasNextPage: function () {
|
|
70
75
|
return this._hasMorePages;
|
|
71
76
|
},
|
|
72
|
-
|
|
77
|
+
/**
|
|
78
|
+
* This value is populated whenever the list length exceeds the pageLimit.
|
|
79
|
+
* It is used to determine how many pages are needed based on the page limit
|
|
80
|
+
* it is retrieved from the response header 'girder-total-count'
|
|
81
|
+
* @returns {number} total number of items retrieved
|
|
82
|
+
*/
|
|
83
|
+
getTotalCount: function () {
|
|
84
|
+
return this._totalCount || 0;
|
|
85
|
+
},
|
|
73
86
|
/**
|
|
74
87
|
* Fetch the previous page of this collection, emitting g:changed when done.
|
|
75
88
|
*/
|
|
@@ -103,7 +116,7 @@ var Collection = Backbone.Collection.extend({
|
|
|
103
116
|
},
|
|
104
117
|
|
|
105
118
|
/**
|
|
106
|
-
*
|
|
119
|
+
* @returns {number} the 0-indexed page number of the current page. Add 1 to this
|
|
107
120
|
* result when displaying it to the user.
|
|
108
121
|
*
|
|
109
122
|
* If this collection hasn't been fully initialized (i.e.: before any pages
|
|
@@ -119,6 +132,20 @@ var Collection = Backbone.Collection.extend({
|
|
|
119
132
|
return Math.ceil((this.offset - this.length) / this.pageLimit);
|
|
120
133
|
},
|
|
121
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Sets a specific pagenumber for loading by caluclating the offset
|
|
137
|
+
* @param {Number} pageNumber The 0 indexed page that should be loaded based on the pageLimit size
|
|
138
|
+
* @param {Object} params Additional parameters to pass to the fetch call
|
|
139
|
+
* @returns {Promise} a fetch promise to retrieve more data
|
|
140
|
+
*/
|
|
141
|
+
fetchPage: function (pageNumber, params) {
|
|
142
|
+
// Make sure the page Number is within range, pageNumber is indexed at 0
|
|
143
|
+
if (!this.append && pageNumber * this.pageLimit < this._totalCount && pageNumber >= 0) {
|
|
144
|
+
this.offset = pageNumber * this.pageLimit;
|
|
145
|
+
return this.fetch(_.extend({}, this.params, params || {}));
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
|
|
122
149
|
/**
|
|
123
150
|
* Fetches the next page of this collection, replacing the existing models
|
|
124
151
|
* of this collection with the requested page. If the next page contains
|
|
@@ -169,6 +196,7 @@ var Collection = Backbone.Collection.extend({
|
|
|
169
196
|
// This means we have more pages to display still. Pop off
|
|
170
197
|
// the extra that we fetched.
|
|
171
198
|
list.pop();
|
|
199
|
+
this._totalCount = xhr.getResponseHeader('girder-total-count');
|
|
172
200
|
this._hasMorePages = true;
|
|
173
201
|
} else {
|
|
174
202
|
this._hasMorePages = false;
|
package/dialog.js
CHANGED
|
@@ -92,7 +92,7 @@ function confirm(params) {
|
|
|
92
92
|
} else {
|
|
93
93
|
el.text(params.text);
|
|
94
94
|
}
|
|
95
|
-
if (params
|
|
95
|
+
if (params.msgConfirmation) {
|
|
96
96
|
if (params.escapedHtml) {
|
|
97
97
|
$('.g-additional-text').html(params.additionalText);
|
|
98
98
|
} else {
|
|
@@ -101,7 +101,7 @@ function confirm(params) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
$('#g-confirm-button').off('click').on('click', function () {
|
|
104
|
-
if (params
|
|
104
|
+
if (params.msgConfirmation) {
|
|
105
105
|
const key = `${params.yesText.toUpperCase()} ${params.name}`;
|
|
106
106
|
const msg = $('#g-confirm-text').val();
|
|
107
107
|
if (msg.toUpperCase() === key.toUpperCase()) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@girder/core",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.12",
|
|
4
4
|
"description": "Extensible data management platform",
|
|
5
5
|
"homepage": "https://girder.readthedocs.org",
|
|
6
6
|
"bugs": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"bootstrap-switch": "~3.3.4",
|
|
19
19
|
"eonasdan-bootstrap-datetimepicker": "~4.17",
|
|
20
20
|
"@girder/fontello": "*",
|
|
21
|
-
"jquery": "~3.
|
|
21
|
+
"jquery": "~3.5.1",
|
|
22
22
|
"jsoneditor": "~5.9.3",
|
|
23
23
|
"moment": "~2.24.0",
|
|
24
24
|
"moment-timezone": "~0.5.27",
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
.g-hierarchy-widget
|
|
2
2
|
border 1px solid #eaeaea
|
|
3
3
|
|
|
4
|
+
.g-hierarchy-sticky
|
|
5
|
+
position sticky
|
|
6
|
+
z-index 10
|
|
7
|
+
|
|
4
8
|
.g-hierarchy-actions-header
|
|
5
9
|
background linear-gradient(to bottom, #e6e6e6 0, #f7f7f7 8px)
|
|
6
10
|
padding 4px 5px 3px
|
|
@@ -21,6 +25,26 @@
|
|
|
21
25
|
.g-folder-header-buttons
|
|
22
26
|
float right
|
|
23
27
|
|
|
28
|
+
.g-hierarachy-paginated-bar
|
|
29
|
+
background-color #eaebea
|
|
30
|
+
.g-hierarchy-pages-header
|
|
31
|
+
.g-hierarchycenter
|
|
32
|
+
margin auto
|
|
33
|
+
text-align center
|
|
34
|
+
.pagination
|
|
35
|
+
display inline-block
|
|
36
|
+
vertical-align middle
|
|
37
|
+
margin 0
|
|
38
|
+
padding 0
|
|
39
|
+
border-radius 4px
|
|
40
|
+
.g-page-next, .g-page-prev
|
|
41
|
+
a
|
|
42
|
+
padding 8px 12px
|
|
43
|
+
#g-page-selection-input
|
|
44
|
+
margin-left 3px
|
|
45
|
+
margin-right 3px
|
|
46
|
+
|
|
47
|
+
|
|
24
48
|
.g-hierarchy-breadcrumb-bar
|
|
25
49
|
ol.breadcrumb
|
|
26
50
|
margin-bottom 0
|
|
@@ -68,6 +92,10 @@
|
|
|
68
92
|
right -3px
|
|
69
93
|
padding 0 0.3em
|
|
70
94
|
|
|
95
|
+
.g-folder-list-container, .g-item-list-container
|
|
96
|
+
position relative
|
|
97
|
+
z-index 0
|
|
98
|
+
|
|
71
99
|
.g-folder-list, .g-item-list, .g-file-list
|
|
72
100
|
margin 0
|
|
73
101
|
padding 0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.g-hierarchy-pages-header
|
|
2
|
+
.g-hierarchycenter
|
|
3
|
+
ul.pagination.pagination-sm
|
|
4
|
+
if (currentPage >1 && !disabled)
|
|
5
|
+
li.g-page-prev
|
|
6
|
+
a#g-previous-paginated « Prev
|
|
7
|
+
else
|
|
8
|
+
li.g-page-prev.disabled
|
|
9
|
+
a#g-previous-paginated « Prev
|
|
10
|
+
li
|
|
11
|
+
span Page:
|
|
12
|
+
input#g-page-selection-input(disabled=disabled, type='number', min=1, max=totalPages, value=currentPage)
|
|
13
|
+
span of #{totalPages}
|
|
14
|
+
if (currentPage+1<=totalPages && !disabled)
|
|
15
|
+
li.g-page-next
|
|
16
|
+
a#g-next-paginated Next »
|
|
17
|
+
else
|
|
18
|
+
li.g-page-next.disabled
|
|
19
|
+
a#g-next-paginated Next »
|
|
@@ -58,6 +58,7 @@ var BrowserWidget = View.extend({
|
|
|
58
58
|
error message) if the selection is unacceptable.
|
|
59
59
|
* @param {string} [input.placeholder] A placeholder string for the input element.
|
|
60
60
|
* @param {boolean} [highlightItem=false] highlights the selected item in the hierarchy and scrolls to it.
|
|
61
|
+
* @param {boolean} [paginated=false] the browser widget is paginated
|
|
61
62
|
*/
|
|
62
63
|
initialize: function (settings) {
|
|
63
64
|
// store options
|
|
@@ -74,6 +75,7 @@ var BrowserWidget = View.extend({
|
|
|
74
75
|
this.selectItem = !!settings.selectItem;
|
|
75
76
|
this.showMetadata = !!settings.showMetadata;
|
|
76
77
|
this.highlightItem = !!settings.highlightItem;
|
|
78
|
+
this.paginated = !!settings.paginated;
|
|
77
79
|
this._selected = null;
|
|
78
80
|
|
|
79
81
|
// Sets RootSelectorWidget to open properly to the root if not already set in the settings
|
|
@@ -148,6 +150,7 @@ var BrowserWidget = View.extend({
|
|
|
148
150
|
onItemClick: _.bind(this._selectItem, this),
|
|
149
151
|
defaultSelectedResource: this.defaultSelectedResource,
|
|
150
152
|
highlightItem: this.highlightItem,
|
|
153
|
+
paginated: this.paginated,
|
|
151
154
|
showMetadata: this.showMetadata
|
|
152
155
|
});
|
|
153
156
|
this.listenTo(this._hierarchyView, 'g:setCurrentModel', this._selectModel);
|
|
@@ -23,6 +23,7 @@ import { getModelClassByName, renderMarkdown, formatCount, capitalize, formatSiz
|
|
|
23
23
|
import { restRequest, getApiRoot } from '@girder/core/rest';
|
|
24
24
|
|
|
25
25
|
import HierarchyBreadcrumbTemplate from '@girder/core/templates/widgets/hierarchyBreadcrumb.pug';
|
|
26
|
+
import HierarchyPaginatedTemplate from '@girder/core/templates/widgets/hierarchyPaginated.pug';
|
|
26
27
|
import HierarchyWidgetTemplate from '@girder/core/templates/widgets/hierarchyWidget.pug';
|
|
27
28
|
|
|
28
29
|
import '@girder/core/stylesheets/widgets/hierarchyWidget.styl';
|
|
@@ -67,6 +68,51 @@ var HierarchyBreadcrumbView = View.extend({
|
|
|
67
68
|
}
|
|
68
69
|
});
|
|
69
70
|
|
|
71
|
+
var HierarchyPaginatedView = View.extend({
|
|
72
|
+
events: {
|
|
73
|
+
'change #g-page-selection-input': function (event) {
|
|
74
|
+
const num = Number(event.target.value);
|
|
75
|
+
if (this.itemListWidget && num <= this.itemListWidget.getNumPages() && num > 0) {
|
|
76
|
+
this.disabled = true;
|
|
77
|
+
this.itemListWidget.setPage(num).done(() => {
|
|
78
|
+
this.disabled = false;
|
|
79
|
+
this.render();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
this.render();
|
|
83
|
+
},
|
|
84
|
+
'click li.g-page-next:not(.disabled) a#g-next-paginated': function () {
|
|
85
|
+
this.disabled = true;
|
|
86
|
+
this.itemListWidget.setPage(Number(this.$('#g-page-selection-input').val()) + 1).done(() => {
|
|
87
|
+
this.disabled = false;
|
|
88
|
+
this.render();
|
|
89
|
+
});
|
|
90
|
+
this.render();
|
|
91
|
+
},
|
|
92
|
+
'click li.g-page-prev:not(.disabled) a#g-previous-paginated': function () {
|
|
93
|
+
this.disabled = true;
|
|
94
|
+
this.itemListWidget.setPage(Number(this.$('#g-page-selection-input').val()) - 1).done(() => {
|
|
95
|
+
this.disabled = false;
|
|
96
|
+
this.render();
|
|
97
|
+
});
|
|
98
|
+
this.render();
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
initialize: function (settings) {
|
|
102
|
+
this.itemListWidget = settings.itemListWidget;
|
|
103
|
+
this.disabled = false;
|
|
104
|
+
},
|
|
105
|
+
render: function () {
|
|
106
|
+
this.$el.html(HierarchyPaginatedTemplate({
|
|
107
|
+
totalPages: this.itemListWidget && this.itemListWidget.getNumPages(),
|
|
108
|
+
currentPage: this.itemListWidget && this.itemListWidget.getCurrentPage(),
|
|
109
|
+
disabled: this.disabled
|
|
110
|
+
}));
|
|
111
|
+
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
70
116
|
/**
|
|
71
117
|
* This widget is used to navigate the data hierarchy of folders and items.
|
|
72
118
|
*/
|
|
@@ -114,6 +160,7 @@ var HierarchyWidget = View.extend({
|
|
|
114
160
|
* event as its second.
|
|
115
161
|
* [defaultSelectedResource] : default selected Resource item , will open up to this resource
|
|
116
162
|
* [highlightItem=false] : sets the item to be styled as selected and will scroll to it in the list
|
|
163
|
+
* [paginated=false] : sets the itemlist view to be paginated, will set appendPages to false
|
|
117
164
|
*/
|
|
118
165
|
initialize: function (settings) {
|
|
119
166
|
this.parentModel = settings.parentModel;
|
|
@@ -136,7 +183,7 @@ var HierarchyWidget = View.extend({
|
|
|
136
183
|
};
|
|
137
184
|
this._defaultSelectedResource = settings.defaultSelectedResource;
|
|
138
185
|
this._highlightItem = _.has(settings, 'highlightItem') ? settings.highlightItem : false;
|
|
139
|
-
|
|
186
|
+
this._paginated = _.has(settings, 'paginated') ? settings.paginated : false;
|
|
140
187
|
this._onFolderSelect = settings.onFolderSelect;
|
|
141
188
|
|
|
142
189
|
this.folderAccess = settings.folderAccess;
|
|
@@ -224,13 +271,34 @@ var HierarchyWidget = View.extend({
|
|
|
224
271
|
showSizes: this._showSizes,
|
|
225
272
|
selectedItem: this._defaultSelectedResource,
|
|
226
273
|
highlightItem: this._highlightItem,
|
|
274
|
+
paginated: this._paginated,
|
|
227
275
|
parentView: this
|
|
228
276
|
});
|
|
229
277
|
this.listenTo(this.itemListView, 'g:itemClicked', this._onItemClick);
|
|
230
278
|
this.listenTo(this.itemListView, 'g:checkboxesChanged', this.updateChecked);
|
|
279
|
+
|
|
231
280
|
this.listenTo(this.itemListView, 'g:changed', () => {
|
|
232
281
|
this.itemCount = this.itemListView.collection.length;
|
|
233
282
|
this._childCountCheck();
|
|
283
|
+
if (this._paginated && this.hierarchyPaginated && this.itemListView.getNumPages() > 1) {
|
|
284
|
+
this.render();
|
|
285
|
+
this.$('.g-hierarchy-breadcrumb-bar').addClass('g-hierarchy-sticky');
|
|
286
|
+
this.$('.g-hierarachy-paginated-bar').addClass('g-hierarchy-sticky');
|
|
287
|
+
this.$('.g-hierarchy-breadcrumb-bar').css({ top: 0 });
|
|
288
|
+
this.$('.g-hierarachy-paginated-bar').css({ bottom: 0 });
|
|
289
|
+
} else {
|
|
290
|
+
// We remove the bar if the current folder doesn't have more than one page, keep the sticky breadcrumb though
|
|
291
|
+
this.$('.g-hierarachy-paginated-bar').remove();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
// Only emitted when there is more than one page of data
|
|
295
|
+
this.listenTo(this.itemListView, 'g:paginated', () => {
|
|
296
|
+
if (this._paginated && !this.hierarchyPaginated) {
|
|
297
|
+
this.hierarchyPaginated = new HierarchyPaginatedView({
|
|
298
|
+
parentView: this,
|
|
299
|
+
itemListWidget: this.itemListView
|
|
300
|
+
});
|
|
301
|
+
}
|
|
234
302
|
});
|
|
235
303
|
}
|
|
236
304
|
|
|
@@ -289,7 +357,9 @@ var HierarchyWidget = View.extend({
|
|
|
289
357
|
this.checkedMenuWidget.dropdownToggle = this.$('.g-checked-actions-button');
|
|
290
358
|
this.checkedMenuWidget.setElement(this.$('.g-checked-actions-menu')).render();
|
|
291
359
|
this.folderListView.setElement(this.$('.g-folder-list-container')).render();
|
|
292
|
-
|
|
360
|
+
if (this.hierarchyPaginated && this.parentModel.resourceName !== 'collection') {
|
|
361
|
+
this.hierarchyPaginated.setElement(this.$('.g-hierarachy-paginated-bar')).render();
|
|
362
|
+
}
|
|
293
363
|
if (this.parentModel.resourceName === 'folder' && this._showItems) {
|
|
294
364
|
this._initFolderViewSubwidgets();
|
|
295
365
|
this.itemListView.setElement(this.$('.g-item-list-container')).render();
|
|
@@ -547,6 +617,7 @@ var HierarchyWidget = View.extend({
|
|
|
547
617
|
viewLinks: this._viewLinks,
|
|
548
618
|
itemFilter: this._itemFilter,
|
|
549
619
|
showSizes: this._showSizes,
|
|
620
|
+
paginated: this._paginated,
|
|
550
621
|
public: this.parentModel.get('public'),
|
|
551
622
|
accessLevel: this.parentModel.getAccessLevel()
|
|
552
623
|
});
|
|
@@ -613,6 +684,7 @@ var HierarchyWidget = View.extend({
|
|
|
613
684
|
yesText: 'Delete',
|
|
614
685
|
confirmCallback: () => {
|
|
615
686
|
var resources = this._getCheckedResourceParam();
|
|
687
|
+
var resourceSize = this._getCheckedResourceSize();
|
|
616
688
|
/* Content on DELETE requests is somewhat oddly supported (I
|
|
617
689
|
* can't get it to work under jasmine/phantom), so override the
|
|
618
690
|
* method. */
|
|
@@ -628,7 +700,9 @@ var HierarchyWidget = View.extend({
|
|
|
628
700
|
if (folders.length && this.parentModel.has('nFolders')) {
|
|
629
701
|
this.parentModel.increment('nFolders', -folders.length);
|
|
630
702
|
}
|
|
631
|
-
|
|
703
|
+
if (this.parentModel.has('size') && resourceSize.items) {
|
|
704
|
+
this.parentModel.increment('size', -resourceSize.items);
|
|
705
|
+
}
|
|
632
706
|
this.setCurrentModel(this.parentModel, { setRoute: false });
|
|
633
707
|
});
|
|
634
708
|
}
|
|
@@ -784,6 +858,26 @@ var HierarchyWidget = View.extend({
|
|
|
784
858
|
return JSON.stringify(resources);
|
|
785
859
|
},
|
|
786
860
|
|
|
861
|
+
/**
|
|
862
|
+
* Get the sum of the sizes of checked resources.
|
|
863
|
+
*/
|
|
864
|
+
_getCheckedResourceSize: function () {
|
|
865
|
+
var totalSize = { items: 0, folders: 0 };
|
|
866
|
+
var folders = this.folderListView.checked;
|
|
867
|
+
_.each(folders, function (cid) {
|
|
868
|
+
var folder = this.folderListView.collection.get(cid);
|
|
869
|
+
totalSize.folders += (folder.get('size') || 0);
|
|
870
|
+
}, this);
|
|
871
|
+
if (this.itemListView) {
|
|
872
|
+
var items = this.itemListView.checked;
|
|
873
|
+
_.each(items, function (cid) {
|
|
874
|
+
var item = this.itemListView.collection.get(cid);
|
|
875
|
+
totalSize.items += (item.get('size') || 0);
|
|
876
|
+
}, this);
|
|
877
|
+
}
|
|
878
|
+
return totalSize;
|
|
879
|
+
},
|
|
880
|
+
|
|
787
881
|
downloadChecked: function () {
|
|
788
882
|
var url = getApiRoot() + '/resource/download';
|
|
789
883
|
var resources = this._getCheckedResourceParam();
|
|
@@ -5,6 +5,7 @@ import ItemCollection from '@girder/core/collections/ItemCollection';
|
|
|
5
5
|
import LoadingAnimation from '@girder/core/views/widgets/LoadingAnimation';
|
|
6
6
|
import View from '@girder/core/views/View';
|
|
7
7
|
import { formatSize } from '@girder/core/misc';
|
|
8
|
+
import { restRequest } from '@girder/core/rest';
|
|
8
9
|
|
|
9
10
|
import ItemListTemplate from '@girder/core/templates/widgets/itemList.pug';
|
|
10
11
|
|
|
@@ -47,6 +48,8 @@ var ItemListWidget = View.extend({
|
|
|
47
48
|
_.has(settings, 'showSizes') ? settings.showSizes : true);
|
|
48
49
|
this._highlightItem = (
|
|
49
50
|
_.has(settings, 'highlightItem') ? settings.highlightItem : false);
|
|
51
|
+
this._paginated = (
|
|
52
|
+
_.has(settings, 'paginated') ? settings.paginated : false);
|
|
50
53
|
|
|
51
54
|
this.accessLevel = settings.accessLevel;
|
|
52
55
|
this.public = settings.public;
|
|
@@ -60,20 +63,74 @@ var ItemListWidget = View.extend({
|
|
|
60
63
|
this.collection = new ItemCollection();
|
|
61
64
|
this.collection.append = true; // Append, don't replace pages
|
|
62
65
|
this.collection.filterFunc = settings.itemFilter;
|
|
66
|
+
this.currentPage = 1; // By default we want to be on the first page
|
|
63
67
|
|
|
64
|
-
this.
|
|
65
|
-
if (this.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
if (this._paginated) {
|
|
69
|
+
if (this.collection.filterFunc) {
|
|
70
|
+
console.warn('Pagination cannot be used with a filter function');
|
|
71
|
+
this._paginated = false;
|
|
72
|
+
} else {
|
|
73
|
+
// Override the default to prevent appending new pages
|
|
74
|
+
this.collection.append = false;
|
|
69
75
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this.collection.fetch({ folderId: settings.folderId }).done(() => {
|
|
79
|
+
this._totalPages = Math.ceil(this.collection.getTotalCount() / this.collection.pageLimit);
|
|
80
|
+
if (this._paginated && this.collection.hasNextPage) {
|
|
81
|
+
// Tells the parent container that the item is paginated so it can render the page selector
|
|
82
|
+
this.trigger('g:paginated');
|
|
83
|
+
// We need to get the position in the list for the selected item
|
|
84
|
+
if (this._selectedItem) {
|
|
85
|
+
restRequest({
|
|
86
|
+
url: `item/${this._selectedItem.get('_id')}/position`,
|
|
87
|
+
method: 'GET',
|
|
88
|
+
data: { folderId: this._selectedItem.get('folderId'), sort: 'name' }
|
|
89
|
+
}).done((val) => {
|
|
90
|
+
// Now we fetch the correct page for the position
|
|
91
|
+
val = Number(val);
|
|
92
|
+
if (val >= this.collection.pageLimit) {
|
|
93
|
+
const pageLimit = this.collection.pageLimit;
|
|
94
|
+
const calculatedPage = 1 + Math.ceil((val - (val % pageLimit)) / pageLimit);
|
|
95
|
+
return this.collection.fetchPage(calculatedPage - 1);
|
|
96
|
+
}
|
|
97
|
+
}).done(() => this.bindOnChanged());
|
|
98
|
+
} else {
|
|
99
|
+
this.bindOnChanged();
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
this.bindOnChanged();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Binds the change function to the collection and calls it initially to update the render
|
|
109
|
+
*/
|
|
110
|
+
bindOnChanged: function () {
|
|
111
|
+
this.collection.on('g:changed', this.changedFunc, this);
|
|
112
|
+
this.changedFunc();
|
|
113
|
+
},
|
|
114
|
+
/**
|
|
115
|
+
* Function that causes a render each time the collection is changed
|
|
116
|
+
* Will also update the current page in a paginated system
|
|
117
|
+
*/
|
|
118
|
+
changedFunc: function () {
|
|
119
|
+
if (this.accessLevel !== undefined) {
|
|
120
|
+
this.collection.each((model) => {
|
|
121
|
+
model.set('_accessLevel', this.accessLevel);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
if (this._paginated) {
|
|
125
|
+
this.currentPage = this.collection.pageNum() + 1;
|
|
126
|
+
}
|
|
127
|
+
this.render();
|
|
128
|
+
this.trigger('g:changed');
|
|
73
129
|
},
|
|
74
130
|
|
|
75
131
|
render: function () {
|
|
76
132
|
this.checked = [];
|
|
133
|
+
// If we set a selected item in the beginning we will center the selection while loading
|
|
77
134
|
if (this._selectedItem && this._highlightItem) {
|
|
78
135
|
this.scrollPositionObserver();
|
|
79
136
|
}
|
|
@@ -88,13 +145,37 @@ var ItemListWidget = View.extend({
|
|
|
88
145
|
viewLinks: this._viewLinks,
|
|
89
146
|
showSizes: this._showSizes,
|
|
90
147
|
highlightItem: this._highlightItem,
|
|
91
|
-
selectedItemId: (this._selectedItem || {}).id
|
|
148
|
+
selectedItemId: (this._selectedItem || {}).id,
|
|
149
|
+
paginated: this._paginated
|
|
150
|
+
|
|
92
151
|
}));
|
|
93
152
|
|
|
94
|
-
// If we set a selected item in the beginning we will center the selection while loading
|
|
95
153
|
return this;
|
|
96
154
|
},
|
|
97
155
|
|
|
156
|
+
/**
|
|
157
|
+
* @returns {number} the number of pages in the itemList for use in a paginated view
|
|
158
|
+
*/
|
|
159
|
+
getNumPages() {
|
|
160
|
+
return this._totalPages || 1;
|
|
161
|
+
},
|
|
162
|
+
/**
|
|
163
|
+
* @returns {number} the current page for paginated lists, defaults to 1 if none is provided
|
|
164
|
+
*/
|
|
165
|
+
getCurrentPage() {
|
|
166
|
+
return this.currentPage || 1;
|
|
167
|
+
},
|
|
168
|
+
/**
|
|
169
|
+
* Externally facing function to allow hierarchyWidget and others to set the current page if the item is paginated
|
|
170
|
+
* @param {Number} page 1 index integer specifying the page to fetch
|
|
171
|
+
*/
|
|
172
|
+
setPage(page) {
|
|
173
|
+
if (this._paginated && this.collection && this.collection.fetchPage) {
|
|
174
|
+
this.currentPage = page;
|
|
175
|
+
return this.collection.fetchPage(page - 1).then(() =>
|
|
176
|
+
this.$el.parents('.g-hierarchy-widget-container').scrollTop(0));
|
|
177
|
+
}
|
|
178
|
+
},
|
|
98
179
|
/**
|
|
99
180
|
* Insert an item into the collection and re-render it.
|
|
100
181
|
*/
|
|
@@ -156,11 +237,16 @@ var ItemListWidget = View.extend({
|
|
|
156
237
|
centerSelected: function () {
|
|
157
238
|
const widgetcontainer = this.$el.parents('.g-hierarchy-widget-container');
|
|
158
239
|
const selected = this.$('li.g-item-list-entry.g-selected');
|
|
159
|
-
|
|
160
240
|
if (widgetcontainer.length > 0 && selected.length > 0) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
const
|
|
241
|
+
// These items will effect the scroll position if they exists
|
|
242
|
+
const folderHeight = $('.g-folder-list').length ? $('.g-folder-list').height() : 0;
|
|
243
|
+
const breadcrumbHeight = $('.g-hierarchy-breadcrumb-bar').length ? $('.g-hierarchy-breadcrumb-bar').height() : 0;
|
|
244
|
+
const selectedTop = selected.position().top;
|
|
245
|
+
// The selectedTop position needs to account for the breadcrumbHeight and the folderHeight
|
|
246
|
+
const scrollingPos = selectedTop + folderHeight + breadcrumbHeight;
|
|
247
|
+
const centerPos = (widgetcontainer.height() / 2.0) - (folderHeight / 2.0) - (breadcrumbHeight / 2.0) - (selected.outerHeight() / 2.0);
|
|
248
|
+
|
|
249
|
+
const scrollPos = scrollingPos - centerPos;
|
|
164
250
|
if (this.tempScrollPos === undefined) {
|
|
165
251
|
this.tempScrollPos = scrollPos;
|
|
166
252
|
}
|
|
@@ -234,7 +320,7 @@ var ItemListWidget = View.extend({
|
|
|
234
320
|
this.observer.disconnect();
|
|
235
321
|
this.observer = null;
|
|
236
322
|
this.tempScrollPos = undefined;
|
|
237
|
-
// Prevents scrolling
|
|
323
|
+
// Prevents scrolling when user clicks 'show more...'
|
|
238
324
|
this._highlightItem = false;
|
|
239
325
|
}
|
|
240
326
|
};
|