@girder/core 3.2.8 → 5.0.0-a6
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/README.md +61 -0
- package/package.json +79 -31
- package/assets/Girder_Mark.png +0 -0
- package/auth.js +0 -152
- package/collections/ApiKeyCollection.js +0 -9
- package/collections/AssetstoreCollection.js +0 -9
- package/collections/Collection.js +0 -295
- package/collections/CollectionCollection.js +0 -9
- package/collections/FileCollection.js +0 -11
- package/collections/FolderCollection.js +0 -11
- package/collections/GroupCollection.js +0 -9
- package/collections/ItemCollection.js +0 -11
- package/collections/UserCollection.js +0 -24
- package/collections/index.js +0 -21
- package/constants.js +0 -33
- package/dialog.js +0 -128
- package/events.js +0 -6
- package/index.js +0 -31
- package/main.js +0 -21
- package/misc.js +0 -260
- package/models/AccessControlledModel.js +0 -76
- package/models/ApiKeyModel.js +0 -31
- package/models/AssetstoreModel.js +0 -43
- package/models/CollectionCreationPolicyModel.js +0 -20
- package/models/CollectionModel.js +0 -12
- package/models/FileModel.js +0 -310
- package/models/FolderModel.js +0 -33
- package/models/GroupModel.js +0 -197
- package/models/ItemModel.js +0 -72
- package/models/MetadataMixin.js +0 -88
- package/models/Model.js +0 -187
- package/models/UserModel.js +0 -189
- package/models/index.js +0 -25
- package/pluginUtils.js +0 -11
- package/rest.js +0 -216
- package/router.js +0 -58
- package/routes.js +0 -231
- package/stylesheets/apidocs/apidocs.styl +0 -50
- package/stylesheets/body/adminConsole.styl +0 -21
- package/stylesheets/body/assetstores.styl +0 -46
- package/stylesheets/body/collectionList.styl +0 -39
- package/stylesheets/body/collectionPage.styl +0 -6
- package/stylesheets/body/frontPage.styl +0 -48
- package/stylesheets/body/groupList.styl +0 -43
- package/stylesheets/body/groupPage.styl +0 -116
- package/stylesheets/body/itemPage.styl +0 -81
- package/stylesheets/body/plugins.styl +0 -61
- package/stylesheets/body/searchResultsList.styl +0 -51
- package/stylesheets/body/systemConfig.styl +0 -56
- package/stylesheets/body/userAccount.styl +0 -57
- package/stylesheets/body/userList.styl +0 -79
- package/stylesheets/body/userPage.styl +0 -6
- package/stylesheets/layout/footer.styl +0 -19
- package/stylesheets/layout/global.styl +0 -154
- package/stylesheets/layout/globalNav.styl +0 -89
- package/stylesheets/layout/header.styl +0 -29
- package/stylesheets/layout/headerUser.styl +0 -33
- package/stylesheets/layout/layout.styl +0 -75
- package/stylesheets/layout/layoutVars.styl +0 -9
- package/stylesheets/layout/loading.styl +0 -37
- package/stylesheets/layout/progressArea.styl +0 -17
- package/stylesheets/widgets/accessWidget.styl +0 -106
- package/stylesheets/widgets/browserWidget.styl +0 -9
- package/stylesheets/widgets/hierarchyWidget.styl +0 -188
- package/stylesheets/widgets/markdownWidget.styl +0 -92
- package/stylesheets/widgets/metadataWidget.styl +0 -92
- package/stylesheets/widgets/searchFieldWidget.styl +0 -70
- package/stylesheets/widgets/taskProgress.styl +0 -41
- package/stylesheets/widgets/timelineWidget.styl +0 -41
- package/stylesheets/widgets/uploadWidget.styl +0 -43
- package/stylesheets/widgets/userOtpManagementWidget.styl +0 -159
- package/templates/body/adminConsole.pug +0 -13
- package/templates/body/assetstores.pug +0 -98
- package/templates/body/collectionList.pug +0 -40
- package/templates/body/collectionPage.pug +0 -36
- package/templates/body/filesystemImport.pug +0 -41
- package/templates/body/frontPage.pug +0 -83
- package/templates/body/groupList.pug +0 -30
- package/templates/body/groupPage.pug +0 -116
- package/templates/body/itemPage.pug +0 -61
- package/templates/body/plugins.pug +0 -20
- package/templates/body/s3Import.pug +0 -35
- package/templates/body/searchResults.pug +0 -15
- package/templates/body/searchResultsType.pug +0 -13
- package/templates/body/systemConfiguration.pug +0 -221
- package/templates/body/userAccount.pug +0 -83
- package/templates/body/userList.pug +0 -43
- package/templates/body/userPage.pug +0 -40
- package/templates/layout/alert.pug +0 -5
- package/templates/layout/layout.pug +0 -12
- package/templates/layout/layoutFooter.pug +0 -11
- package/templates/layout/layoutGlobalNav.pug +0 -7
- package/templates/layout/layoutHeader.pug +0 -8
- package/templates/layout/layoutHeaderUser.pug +0 -26
- package/templates/layout/layoutProgressArea.pug +0 -1
- package/templates/layout/loginDialog.pug +0 -30
- package/templates/layout/registerDialog.pug +0 -35
- package/templates/layout/resetPasswordDialog.pug +0 -25
- package/templates/widgets/accessEditor.pug +0 -23
- package/templates/widgets/accessEditorMixins.pug +0 -57
- package/templates/widgets/accessEditorNonModal.pug +0 -11
- package/templates/widgets/accessEntry.pug +0 -32
- package/templates/widgets/apiKeyList.pug +0 -50
- package/templates/widgets/browserWidget.pug +0 -32
- package/templates/widgets/checkedActionsMenu.pug +0 -46
- package/templates/widgets/collectionInfoDialog.pug +0 -37
- package/templates/widgets/confirmDialog.pug +0 -14
- package/templates/widgets/dateTimeRangeWidget.pug +0 -20
- package/templates/widgets/dateTimeWidget.pug +0 -8
- package/templates/widgets/editApiKeyWidget.pug +0 -43
- package/templates/widgets/editAssetstoreWidget.pug +0 -78
- package/templates/widgets/editCollectionWidget.pug +0 -27
- package/templates/widgets/editFileWidget.pug +0 -21
- package/templates/widgets/editFolderWidget.pug +0 -27
- package/templates/widgets/editGroupWidget.pug +0 -54
- package/templates/widgets/editItemWidget.pug +0 -27
- package/templates/widgets/fileInfoDialog.pug +0 -33
- package/templates/widgets/fileList.pug +0 -33
- package/templates/widgets/folderInfoDialog.pug +0 -42
- package/templates/widgets/folderList.pug +0 -21
- package/templates/widgets/groupAdminList.pug +0 -33
- package/templates/widgets/groupInviteDialog.pug +0 -76
- package/templates/widgets/groupInviteList.pug +0 -14
- package/templates/widgets/groupMemberList.pug +0 -39
- package/templates/widgets/groupModList.pug +0 -23
- package/templates/widgets/hierarchyBreadcrumb.pug +0 -37
- package/templates/widgets/hierarchyPaginated.pug +0 -19
- package/templates/widgets/hierarchyWidget.pug +0 -96
- package/templates/widgets/itemBreadcrumb.pug +0 -16
- package/templates/widgets/itemList.pug +0 -27
- package/templates/widgets/jsonMetadatumEditWidget.pug +0 -13
- package/templates/widgets/jsonMetadatumView.pug +0 -6
- package/templates/widgets/loadingAnimation.pug +0 -4
- package/templates/widgets/markdownWidget.pug +0 -34
- package/templates/widgets/metadataWidget.pug +0 -16
- package/templates/widgets/metadatumEditWidget.pug +0 -15
- package/templates/widgets/metadatumView.pug +0 -5
- package/templates/widgets/newAssetstore.pug +0 -118
- package/templates/widgets/paginateWidget.pug +0 -7
- package/templates/widgets/pluginConfigBreadcrumb.pug +0 -13
- package/templates/widgets/rootSelectorWidget.pug +0 -13
- package/templates/widgets/searchField.pug +0 -10
- package/templates/widgets/searchHelp.pug +0 -12
- package/templates/widgets/searchModeSelect.pug +0 -9
- package/templates/widgets/searchResults.pug +0 -14
- package/templates/widgets/sortCollectionWidget.pug +0 -14
- package/templates/widgets/taskProgress.pug +0 -16
- package/templates/widgets/timeline.pug +0 -15
- package/templates/widgets/uploadWidget.pug +0 -15
- package/templates/widgets/uploadWidgetMixins.pug +0 -31
- package/templates/widgets/uploadWidgetNonModal.pug +0 -10
- package/templates/widgets/userOtpBegin.pug +0 -4
- package/templates/widgets/userOtpDisable.pug +0 -6
- package/templates/widgets/userOtpEnable.pug +0 -44
- package/utilities/EventStream.js +0 -177
- package/utilities/PluginUtils.js +0 -36
- package/utilities/S3UploadHandler.js +0 -303
- package/utilities/index.js +0 -9
- package/utilities/jquery/girderEnable.js +0 -19
- package/utilities/jquery/girderModal.js +0 -48
- package/version.js +0 -10
- package/views/App.js +0 -359
- package/views/View.js +0 -78
- package/views/body/AdminView.js +0 -29
- package/views/body/AssetstoresView.js +0 -235
- package/views/body/CollectionView.js +0 -188
- package/views/body/CollectionsView.js +0 -120
- package/views/body/FilesystemImportView.js +0 -83
- package/views/body/FolderView.js +0 -54
- package/views/body/FrontPageView.js +0 -47
- package/views/body/GroupView.js +0 -336
- package/views/body/GroupsView.js +0 -106
- package/views/body/ItemView.js +0 -177
- package/views/body/PluginsView.js +0 -73
- package/views/body/S3ImportView.js +0 -80
- package/views/body/SearchResultsView.js +0 -162
- package/views/body/SystemConfigurationView.js +0 -196
- package/views/body/UserAccountView.js +0 -179
- package/views/body/UserView.js +0 -165
- package/views/body/UsersView.js +0 -124
- package/views/body/index.js +0 -37
- package/views/index.js +0 -13
- package/views/layout/FooterView.js +0 -29
- package/views/layout/GlobalNavView.js +0 -103
- package/views/layout/HeaderUserView.js +0 -45
- package/views/layout/HeaderView.js +0 -83
- package/views/layout/LoginView.js +0 -100
- package/views/layout/ProgressListView.js +0 -70
- package/views/layout/RegisterView.js +0 -101
- package/views/layout/ResetPasswordView.js +0 -70
- package/views/layout/index.js +0 -19
- package/views/widgets/AccessWidget.js +0 -427
- package/views/widgets/ApiKeyListWidget.js +0 -140
- package/views/widgets/BrowserWidget.js +0 -317
- package/views/widgets/CheckedMenuWidget.js +0 -68
- package/views/widgets/CollectionInfoWidget.js +0 -40
- package/views/widgets/DateTimeRangeWidget.js +0 -179
- package/views/widgets/DateTimeWidget.js +0 -109
- package/views/widgets/EditApiKeyWidget.js +0 -122
- package/views/widgets/EditAssetstoreWidget.js +0 -148
- package/views/widgets/EditCollectionWidget.js +0 -93
- package/views/widgets/EditFileWidget.js +0 -56
- package/views/widgets/EditFolderWidget.js +0 -116
- package/views/widgets/EditGroupWidget.js +0 -125
- package/views/widgets/EditItemWidget.js +0 -110
- package/views/widgets/FileInfoWidget.js +0 -26
- package/views/widgets/FileListWidget.js +0 -151
- package/views/widgets/FolderInfoWidget.js +0 -39
- package/views/widgets/FolderListWidget.js +0 -106
- package/views/widgets/GroupAdminsWidget.js +0 -88
- package/views/widgets/GroupInvitesWidget.js +0 -56
- package/views/widgets/GroupMembersWidget.js +0 -185
- package/views/widgets/GroupModsWidget.js +0 -77
- package/views/widgets/HierarchyWidget.js +0 -1097
- package/views/widgets/ItemBreadcrumbWidget.js +0 -38
- package/views/widgets/ItemListWidget.js +0 -345
- package/views/widgets/LoadingAnimation.js +0 -17
- package/views/widgets/MarkdownWidget.js +0 -217
- package/views/widgets/MetadataWidget.js +0 -504
- package/views/widgets/NewAssetstoreWidget.js +0 -81
- package/views/widgets/PaginateWidget.js +0 -37
- package/views/widgets/PluginConfigBreadcrumbWidget.js +0 -33
- package/views/widgets/RootSelectorWidget.js +0 -192
- package/views/widgets/SearchFieldWidget.js +0 -365
- package/views/widgets/SearchPaginateWidget.js +0 -149
- package/views/widgets/SortCollectionWidget.js +0 -53
- package/views/widgets/TaskProgressWidget.js +0 -91
- package/views/widgets/TimelineWidget.js +0 -155
- package/views/widgets/UploadWidget.js +0 -340
- package/views/widgets/UserOtpManagementWidget.js +0 -105
- package/views/widgets/index.js +0 -75
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import $ from 'jquery';
|
|
2
|
-
|
|
3
|
-
import View from '@girder/core/views/View';
|
|
4
|
-
import { SORT_ASC, SORT_DESC } from '@girder/core/constants';
|
|
5
|
-
|
|
6
|
-
import SortCollectionWidgetTemplate from '@girder/core/templates/widgets/sortCollectionWidget.pug';
|
|
7
|
-
|
|
8
|
-
import 'bootstrap/js/dropdown';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* This widget is used to provide a consistent widget for sorting
|
|
12
|
-
* pages of a Collection by a chosen field.
|
|
13
|
-
*/
|
|
14
|
-
var SortCollectionWidget = View.extend({
|
|
15
|
-
events: {
|
|
16
|
-
'click a.g-collection-sort-link': function (event) {
|
|
17
|
-
var sortField = $(event.currentTarget).attr('g-sort');
|
|
18
|
-
this.collection.sortField = sortField;
|
|
19
|
-
this.collection.fetch({}, true);
|
|
20
|
-
},
|
|
21
|
-
'click a.g-sort-order-button': function (event) {
|
|
22
|
-
if (this.collection.sortDir === SORT_ASC) {
|
|
23
|
-
this.collection.sortDir = SORT_DESC;
|
|
24
|
-
} else {
|
|
25
|
-
this.collection.sortDir = SORT_ASC;
|
|
26
|
-
}
|
|
27
|
-
this.collection.fetch({}, true);
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
|
|
31
|
-
initialize: function (settings) {
|
|
32
|
-
this.collection = settings.collection;
|
|
33
|
-
this.fields = settings.fields;
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Do not call render() until the collection has been fetched once.
|
|
38
|
-
*/
|
|
39
|
-
render: function () {
|
|
40
|
-
this.$el.html(SortCollectionWidgetTemplate({
|
|
41
|
-
collection: this.collection,
|
|
42
|
-
fields: this.fields
|
|
43
|
-
}));
|
|
44
|
-
if (this.collection.sortDir === SORT_ASC) {
|
|
45
|
-
this.$('.g-down').addClass('hide');
|
|
46
|
-
} else {
|
|
47
|
-
this.$('.g-up').addClass('hide');
|
|
48
|
-
}
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
export default SortCollectionWidget;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { sprintf } from 'sprintf-js';
|
|
2
|
-
|
|
3
|
-
import View from '@girder/core/views/View';
|
|
4
|
-
|
|
5
|
-
import TaskProgressTemplate from '@girder/core/templates/widgets/taskProgress.pug';
|
|
6
|
-
|
|
7
|
-
import '@girder/core/stylesheets/widgets/taskProgress.styl';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* This widget renders the state of a progress notification.
|
|
11
|
-
*/
|
|
12
|
-
var TaskProgressWidget = View.extend({
|
|
13
|
-
|
|
14
|
-
initialize: function (settings) {
|
|
15
|
-
this.progress = settings.progress;
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
render: function () {
|
|
19
|
-
var width = '0', barClass = [], progressClass = [], percentText = '',
|
|
20
|
-
timeLeftText = '';
|
|
21
|
-
|
|
22
|
-
if (this.progress.data.state === 'active') {
|
|
23
|
-
if (this.progress.data.total <= 0) {
|
|
24
|
-
width = '100%';
|
|
25
|
-
barClass.push('progress-bar-warning');
|
|
26
|
-
progressClass.push('progress-striped', 'active');
|
|
27
|
-
} else if (this.progress.data.current <= 0) {
|
|
28
|
-
width = '0';
|
|
29
|
-
percentText = '0%';
|
|
30
|
-
} else if (this.progress.data.current >= this.progress.data.total) {
|
|
31
|
-
percentText = width = '100%';
|
|
32
|
-
} else {
|
|
33
|
-
var percent = (100 * this.progress.data.current /
|
|
34
|
-
this.progress.data.total);
|
|
35
|
-
width = Math.round(percent) + '%';
|
|
36
|
-
percentText = percent.toFixed(1) + '%';
|
|
37
|
-
var timeLeft = parseInt(this.progress.estimatedTotalTime - (
|
|
38
|
-
this.progress.updatedTime - this.progress.startTime), 10);
|
|
39
|
-
if (timeLeft >= 3600) {
|
|
40
|
-
timeLeftText = sprintf('%d:%02d:%02d left',
|
|
41
|
-
timeLeft / 3600, (timeLeft / 60) % 60, timeLeft % 60);
|
|
42
|
-
} else if (timeLeft > 0) {
|
|
43
|
-
timeLeftText = sprintf('%d:%02d left',
|
|
44
|
-
timeLeft / 60, timeLeft % 60);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
} else if (this.progress.data.state === 'success') {
|
|
48
|
-
width = '100%';
|
|
49
|
-
barClass.push('progress-bar-success');
|
|
50
|
-
|
|
51
|
-
this._scheduleHide(5000);
|
|
52
|
-
} else if (this.progress.data.state === 'error') {
|
|
53
|
-
width = '100%';
|
|
54
|
-
barClass.push('progress-bar-danger');
|
|
55
|
-
|
|
56
|
-
this._scheduleHide(10000);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.$el.html(TaskProgressTemplate({
|
|
60
|
-
progress: this.progress,
|
|
61
|
-
width: width,
|
|
62
|
-
barClass: barClass.join(' '),
|
|
63
|
-
progressClass: progressClass.join(' '),
|
|
64
|
-
percentText: percentText,
|
|
65
|
-
timeLeftText: timeLeftText
|
|
66
|
-
}));
|
|
67
|
-
return this;
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Renders an update of the progress object.
|
|
72
|
-
*/
|
|
73
|
-
update: function (progress) {
|
|
74
|
-
this.progress = progress;
|
|
75
|
-
this.render();
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Schedule a hide event to be triggered in the future.
|
|
80
|
-
*/
|
|
81
|
-
_scheduleHide: function (ms) {
|
|
82
|
-
window.setTimeout(() => {
|
|
83
|
-
this.$el.fadeOut(500, () => {
|
|
84
|
-
this.remove();
|
|
85
|
-
this.trigger('g:hide', this.progress);
|
|
86
|
-
});
|
|
87
|
-
}, ms);
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
export default TaskProgressWidget;
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import _ from 'underscore';
|
|
2
|
-
|
|
3
|
-
import View from '@girder/core/views/View';
|
|
4
|
-
|
|
5
|
-
import TimelineTemplate from '@girder/core/templates/widgets/timeline.pug';
|
|
6
|
-
|
|
7
|
-
import '@girder/core/stylesheets/widgets/timelineWidget.styl';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* This widget displays a timeline of events. This is visualized as a line (a bar)
|
|
11
|
-
* with two sorts of primitives overlaid:
|
|
12
|
-
*
|
|
13
|
-
* 1. Segments: spans of time, with a start and end.
|
|
14
|
-
* 2. Points: a single point in time. Points always display on top of segments.
|
|
15
|
-
*
|
|
16
|
-
* Any number of these primitives can be displayed on the timeline, so long as they
|
|
17
|
-
* are bounded between the specified startTime and endTime. The time values for
|
|
18
|
-
* startTime, endTime, and for the primitives can be specified either as numeric
|
|
19
|
-
* values (i.e. a relative offset in time), or as date strings that can be parsed
|
|
20
|
-
* by JavaScript, or as Date objects. For obvious reasons, in a single instance of
|
|
21
|
-
* this widget, it is not possible to mix the numeric/relative values with datestamp
|
|
22
|
-
* values.
|
|
23
|
-
*/
|
|
24
|
-
var TimelineWidget = View.extend({
|
|
25
|
-
/**
|
|
26
|
-
* Initialize the timeline widget.
|
|
27
|
-
*
|
|
28
|
-
* @param settings.startTime The numeric value or timestamp representing where
|
|
29
|
-
* the timeline should start.
|
|
30
|
-
* @param settings.endTime The numeric value or timestamp representing where
|
|
31
|
-
* the timeline should end. Must be greater than the startTime value. All
|
|
32
|
-
* segments and points should be bounded within the interval [startTime, endTime].
|
|
33
|
-
* @param [settings.numeric=false] If the time values being passed in are simply
|
|
34
|
-
* relative, scalar values (e.g. number of seconds since start) rather than
|
|
35
|
-
* timestamps, set this to true.
|
|
36
|
-
* @param [settings.startLabel] Pass to show a label for the start of the timeline.
|
|
37
|
-
* @param [settings.endLabel] Pass to show a label for the end of the timeline.
|
|
38
|
-
* @param [settings.defaultSegmentClass='g-segment-default'] A CSS class set
|
|
39
|
-
* on segments that do not specify a class.
|
|
40
|
-
* @param [settings.defaultPointClass='g-point-default'] A CSS class set
|
|
41
|
-
* on points that do not specify a class.
|
|
42
|
-
* @param [settings.segments=[]] A list of segments. Each element of the list
|
|
43
|
-
* should be an object with the following keys:
|
|
44
|
-
* - start: A number or timestamp representing
|
|
45
|
-
* - end: A number of timestamp representing the end of this segment.
|
|
46
|
-
* - [class]: A CSS class name to apply to the segment. Uses the
|
|
47
|
-
* widget's defaultSegmentClass if this key is not set.
|
|
48
|
-
* - [tooltip]: A tooltip value for this segment. Tooltips containing the
|
|
49
|
-
* special token "%r" will have that token expanded into the
|
|
50
|
-
* elapsed time between start and end.
|
|
51
|
-
* @param [settings.points=[]] A list of points. Each element of the list should
|
|
52
|
-
* be an object with the following keys:
|
|
53
|
-
* - time: A number or timestamp representing the location of the point.
|
|
54
|
-
* - [class]: A CSS class name to apply to the point. Uses the
|
|
55
|
-
* widget's defaultPointClass if this key is not set.
|
|
56
|
-
* - [tooltip]: A tooltip value for this point. Tooltips containing the
|
|
57
|
-
* special token "%t" will have that token expanded into the
|
|
58
|
-
* time value for that point.
|
|
59
|
-
*/
|
|
60
|
-
initialize: function (settings) {
|
|
61
|
-
this.startTime = settings.startTime;
|
|
62
|
-
this.endTime = settings.endTime;
|
|
63
|
-
this.segments = settings.segments || [];
|
|
64
|
-
this.points = settings.points || [];
|
|
65
|
-
this.numeric = !!settings.numeric;
|
|
66
|
-
this.startLabel = settings.startLabel;
|
|
67
|
-
this.endLabel = settings.endLabel;
|
|
68
|
-
this.defaultSegmentClass = settings.defaultSegmentClass || 'g-segment-default';
|
|
69
|
-
this.defaultPointClass = settings.defaultPointClass || 'g-point-default';
|
|
70
|
-
|
|
71
|
-
this._processData();
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
// Processes the points and segments for display in the widget
|
|
75
|
-
_processData: function () {
|
|
76
|
-
if (!this.numeric) {
|
|
77
|
-
this.startTime = new Date(this.startTime);
|
|
78
|
-
this.endTime = new Date(this.endTime);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (this.endTime <= this.startTime) {
|
|
82
|
-
console.error('Timeline widget: end time must be after start time.');
|
|
83
|
-
this._processedSegments = [];
|
|
84
|
-
this._processedPoints = [];
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
var range = this.endTime - this.startTime;
|
|
89
|
-
|
|
90
|
-
this._processedSegments = _.map(this.segments, function (segment) {
|
|
91
|
-
var start = this.numeric ? segment.start : new Date(segment.start);
|
|
92
|
-
var end = this.numeric ? segment.end : new Date(segment.end);
|
|
93
|
-
var classes = segment.class ? [segment.class] : [this.defaultSegmentClass];
|
|
94
|
-
var color = segment.color ? `background-color: ${segment.color}` : '';
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
class: classes.join(' '),
|
|
98
|
-
left: (100 * (start - this.startTime) / range).toFixed(1) + '%',
|
|
99
|
-
width: (100 * (end - start) / range).toFixed(1) + '%',
|
|
100
|
-
tooltip: this._segmentTooltip(segment, {
|
|
101
|
-
range: this.numeric ? end - start : (end - start) / 1000
|
|
102
|
-
}),
|
|
103
|
-
color
|
|
104
|
-
};
|
|
105
|
-
}, this);
|
|
106
|
-
|
|
107
|
-
this._processedPoints = _.map(this.points, function (point) {
|
|
108
|
-
var time = this.numeric ? point.time : new Date(point.time);
|
|
109
|
-
var classes = point.class ? [point.class] : [this.defaultPointClass];
|
|
110
|
-
var color = point.color ? `background-color: ${point.color}` : '';
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
class: classes.join(' '),
|
|
114
|
-
left: (100 * (time - this.startTime) / range).toFixed(1) + '%',
|
|
115
|
-
tooltip: this._pointTooltip(point, {
|
|
116
|
-
time: time
|
|
117
|
-
}),
|
|
118
|
-
color
|
|
119
|
-
};
|
|
120
|
-
}, this);
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
_segmentTooltip: function (segment, info) {
|
|
124
|
-
if (!segment.tooltip) {
|
|
125
|
-
return null;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return segment.tooltip.replace('%r', info.range);
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
_pointTooltip: function (point, info) {
|
|
132
|
-
if (!point.tooltip) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (this.numeric) {
|
|
137
|
-
return point.tooltip.replace('%t', info.time);
|
|
138
|
-
} else {
|
|
139
|
-
return point.tooltip.replace('%t', info.time.toISOString());
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
render: function () {
|
|
144
|
-
this.$el.html(TimelineTemplate({
|
|
145
|
-
segments: this._processedSegments,
|
|
146
|
-
points: this._processedPoints,
|
|
147
|
-
startLabel: this.startLabel,
|
|
148
|
-
endLabel: this.endLabel
|
|
149
|
-
}));
|
|
150
|
-
|
|
151
|
-
return this;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
export default TimelineWidget;
|
|
@@ -1,340 +0,0 @@
|
|
|
1
|
-
import $ from 'jquery';
|
|
2
|
-
import _ from 'underscore';
|
|
3
|
-
|
|
4
|
-
import FileModel from '@girder/core/models/FileModel';
|
|
5
|
-
import View from '@girder/core/views/View';
|
|
6
|
-
import { formatSize } from '@girder/core/misc';
|
|
7
|
-
import { handleClose, handleOpen } from '@girder/core/dialog';
|
|
8
|
-
|
|
9
|
-
import UploadWidgetTemplate from '@girder/core/templates/widgets/uploadWidget.pug';
|
|
10
|
-
import UploadWidgetNonModalTemplate from '@girder/core/templates/widgets/uploadWidgetNonModal.pug';
|
|
11
|
-
|
|
12
|
-
import '@girder/core/stylesheets/widgets/uploadWidget.styl';
|
|
13
|
-
|
|
14
|
-
import '@girder/core/utilities/jquery/girderEnable';
|
|
15
|
-
import '@girder/core/utilities/jquery/girderModal';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* This widget is used to upload files to a folder. Pass a folder model
|
|
19
|
-
* to its constructor as the parent folder that will be uploaded into.
|
|
20
|
-
* The events:
|
|
21
|
-
* itemComplete: Triggered each time an individual item is finished uploading.
|
|
22
|
-
* finished: Triggered when the entire set of items is uploaded.
|
|
23
|
-
*/
|
|
24
|
-
var UploadWidget = View.extend({
|
|
25
|
-
events: {
|
|
26
|
-
'submit #g-upload-form': function (e) {
|
|
27
|
-
e.preventDefault();
|
|
28
|
-
this.startUpload();
|
|
29
|
-
},
|
|
30
|
-
'click .g-resume-upload': function () {
|
|
31
|
-
this.$('.g-upload-error-message').html('');
|
|
32
|
-
this.currentFile.resumeUpload();
|
|
33
|
-
},
|
|
34
|
-
'click .g-restart-upload': function () {
|
|
35
|
-
this.$('.g-upload-error-message').html('');
|
|
36
|
-
this.uploadNextFile();
|
|
37
|
-
},
|
|
38
|
-
'change #g-files': function () {
|
|
39
|
-
var files = this.$('#g-files')[0].files;
|
|
40
|
-
|
|
41
|
-
if (files.length) {
|
|
42
|
-
this.files = files;
|
|
43
|
-
this.filesChanged();
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
'click .g-drop-zone': function () {
|
|
47
|
-
this.$('#g-files').trigger('click');
|
|
48
|
-
},
|
|
49
|
-
'dragenter .g-drop-zone': function (e) {
|
|
50
|
-
e.stopPropagation();
|
|
51
|
-
e.preventDefault();
|
|
52
|
-
e.originalEvent.dataTransfer.dropEffect = 'copy';
|
|
53
|
-
this.$('.g-drop-zone')
|
|
54
|
-
.addClass('g-dropzone-show')
|
|
55
|
-
.html('<i class="icon-bullseye"/> Drop files here');
|
|
56
|
-
},
|
|
57
|
-
'dragleave .g-drop-zone': function (e) {
|
|
58
|
-
e.stopPropagation();
|
|
59
|
-
e.preventDefault();
|
|
60
|
-
this.$('.g-drop-zone')
|
|
61
|
-
.removeClass('g-dropzone-show')
|
|
62
|
-
.html('<i class="icon-docs"/> Browse or drop files');
|
|
63
|
-
},
|
|
64
|
-
'dragover .g-drop-zone': function (e) {
|
|
65
|
-
var dataTransfer = e.originalEvent.dataTransfer;
|
|
66
|
-
if (!dataTransfer) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
// The following two lines enable drag and drop from the chrome download bar
|
|
70
|
-
var allowed = dataTransfer.effectAllowed;
|
|
71
|
-
dataTransfer.dropEffect = (allowed === 'move' || allowed === 'linkMove') ? 'move' : 'copy';
|
|
72
|
-
|
|
73
|
-
e.preventDefault();
|
|
74
|
-
},
|
|
75
|
-
'drop .g-drop-zone': 'filesDropped'
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* This widget has several configuration options to control its view and
|
|
80
|
-
* behavior. The following keys can be passed in the settings object:
|
|
81
|
-
*
|
|
82
|
-
* @param [parent] If the parent object is known when instantiating this
|
|
83
|
-
* upload widget, pass the object here.
|
|
84
|
-
* @param [parentType=folder] If the parent type is known when instantiating this
|
|
85
|
-
* upload widget, pass the object here. Otherwise set noParent: true and
|
|
86
|
-
* set it later, prior to starting the upload.
|
|
87
|
-
* @param [noParent=false] If the parent object being uploaded into is not known
|
|
88
|
-
* at the time of widget instantiation, pass noParent: true. Callers must
|
|
89
|
-
* ensure that the parent is set by the time uploadNextFile() actually gets
|
|
90
|
-
* called.
|
|
91
|
-
* @param [title="Upload files"] Title for the widget. This is highly recommended
|
|
92
|
-
* when rendering as a modal dialog. To disable rendering of the title, simply
|
|
93
|
-
* pass a falsy object.
|
|
94
|
-
* @param [modal=true] This widget normally renders as a modal dialog. Pass
|
|
95
|
-
* modal: false to disable the modal behavior and simply render underneath a
|
|
96
|
-
* parent element.
|
|
97
|
-
* @param [overrideStart=false] Some callers will want to hook into the pressing
|
|
98
|
-
* of the start upload button and add their own logic prior to actually sending
|
|
99
|
-
* the files. To do so, set overrideStart: true and bind to the "g:uploadStarted"
|
|
100
|
-
* event of this widget. The caller is then responsible for calling "uploadNextFile()"
|
|
101
|
-
* on the widget when they have completed their actions and are ready to actually
|
|
102
|
-
* send the files.
|
|
103
|
-
* @param [multiFile=true] By default, this widget allows selection of multiple
|
|
104
|
-
* files. Set this to false to only allow a single file to be chosen.
|
|
105
|
-
* @param [otherParams={}] An object containing other parameters to pass into the
|
|
106
|
-
* upload initialization endpoint, or a function that returns such an object. If a
|
|
107
|
-
* function, will be called when the upload is started.
|
|
108
|
-
*
|
|
109
|
-
* Other events:
|
|
110
|
-
* - "g:filesChanged": This is triggered any time the user changes the
|
|
111
|
-
* file selection, either by dropping or browsing and selecting new files.
|
|
112
|
-
* Handlers will receive a single argument, which is the list of chosen files.
|
|
113
|
-
* - "g:uploadFinished": When all files have been successfully uploaded,
|
|
114
|
-
* this event is fired.
|
|
115
|
-
*/
|
|
116
|
-
initialize: function (settings) {
|
|
117
|
-
if (settings.noParent) {
|
|
118
|
-
this.parent = null;
|
|
119
|
-
this.parentType = null;
|
|
120
|
-
} else {
|
|
121
|
-
this.parent = settings.parent || settings.folder;
|
|
122
|
-
this.parentType = settings.parentType || 'folder';
|
|
123
|
-
}
|
|
124
|
-
this.files = [];
|
|
125
|
-
this.totalSize = 0;
|
|
126
|
-
this.title = _.has(settings, 'title') ? settings.title : 'Upload files';
|
|
127
|
-
this.modal = _.has(settings, 'modal') ? settings.modal : true;
|
|
128
|
-
this.multiFile = _.has(settings, 'multiFile') ? settings.multiFile : this.parentType !== 'file';
|
|
129
|
-
this.overrideStart = settings.overrideStart || false;
|
|
130
|
-
this.otherParams = settings.otherParams || {};
|
|
131
|
-
|
|
132
|
-
this._browseText = this.multiFile ? 'Browse or drop files here' : 'Browse or drop a file here';
|
|
133
|
-
this._noneSelectedText = this.multiFile ? 'No files selected' : 'No file selected';
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
render: function () {
|
|
137
|
-
var templateParams = {
|
|
138
|
-
parent: this.parent,
|
|
139
|
-
parentType: this.parentType,
|
|
140
|
-
title: this.title,
|
|
141
|
-
multiFile: this.multiFile,
|
|
142
|
-
browseText: this._browseText,
|
|
143
|
-
noneSelectedText: this._noneSelectedText
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
if (this.modal) {
|
|
147
|
-
this.$el.html(UploadWidgetTemplate(templateParams));
|
|
148
|
-
|
|
149
|
-
var dialogid;
|
|
150
|
-
if (this.parentType === 'file') {
|
|
151
|
-
dialogid = this.parent.get('_id');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
this.$el.girderModal(this).on('hidden.bs.modal', () => {
|
|
155
|
-
/* If we are showing the resume option, we have a partial upload
|
|
156
|
-
* that should be deleted, since the user has no way to get back
|
|
157
|
-
* to it. */
|
|
158
|
-
if ($('.g-resume-upload').length && this.currentFile) {
|
|
159
|
-
this.currentFile.abortUpload();
|
|
160
|
-
}
|
|
161
|
-
handleClose('upload', undefined, dialogid);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
handleOpen('upload', undefined, dialogid);
|
|
165
|
-
} else {
|
|
166
|
-
this.$el.html(UploadWidgetNonModalTemplate(templateParams));
|
|
167
|
-
}
|
|
168
|
-
return this;
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
filesDropped: function (e) {
|
|
172
|
-
e.stopPropagation();
|
|
173
|
-
e.preventDefault();
|
|
174
|
-
|
|
175
|
-
this.$('.g-drop-zone')
|
|
176
|
-
.removeClass('g-dropzone-show')
|
|
177
|
-
.html(`<i class="icon-docs"/> ${this._browseText}`);
|
|
178
|
-
|
|
179
|
-
var dataTransfer = e.originalEvent.dataTransfer;
|
|
180
|
-
|
|
181
|
-
// Require all dropped items to be files
|
|
182
|
-
if (!_.every(dataTransfer.items, (item) => this._isFile(item))) {
|
|
183
|
-
this.$('.g-upload-error-message').html('Only files may be uploaded.');
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
this.files = dataTransfer.files;
|
|
187
|
-
|
|
188
|
-
if (!this.multiFile && this.files.length > 1) {
|
|
189
|
-
// If in single-file mode and the user drops multiple files,
|
|
190
|
-
// we just take the first one.
|
|
191
|
-
this.files = [this.files[0]];
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
this.filesChanged();
|
|
195
|
-
},
|
|
196
|
-
|
|
197
|
-
filesChanged: function () {
|
|
198
|
-
if (this.files.length === 0) {
|
|
199
|
-
this.$('.g-overall-progress-message').text(this._noneSelectedText);
|
|
200
|
-
this.setUploadEnabled(false);
|
|
201
|
-
} else {
|
|
202
|
-
this.totalSize = 0;
|
|
203
|
-
_.each(this.files, function (file) {
|
|
204
|
-
this.totalSize += file.size;
|
|
205
|
-
}, this);
|
|
206
|
-
|
|
207
|
-
var msg;
|
|
208
|
-
|
|
209
|
-
if (this.files.length > 1) {
|
|
210
|
-
msg = 'Selected ' + this.files.length + ' files';
|
|
211
|
-
} else {
|
|
212
|
-
msg = 'Selected <b>' + this.files[0].name + '</b>';
|
|
213
|
-
}
|
|
214
|
-
this.$('.g-overall-progress-message').html('<i class="icon-ok"/> ' +
|
|
215
|
-
msg + ' (' + formatSize(this.totalSize) +
|
|
216
|
-
') -- Press start button');
|
|
217
|
-
this.setUploadEnabled(true);
|
|
218
|
-
this.$('.g-progress-overall,.g-progress-current').addClass('hide');
|
|
219
|
-
this.$('.g-current-progress-message').empty();
|
|
220
|
-
this.$('.g-upload-error-message').empty();
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
this.trigger('g:filesChanged', this.files);
|
|
224
|
-
},
|
|
225
|
-
|
|
226
|
-
startUpload: function () {
|
|
227
|
-
this.setUploadEnabled(false);
|
|
228
|
-
this.$('.g-drop-zone').addClass('hide');
|
|
229
|
-
this.$('.g-progress-overall').removeClass('hide');
|
|
230
|
-
this.$('.g-upload-error-message').empty();
|
|
231
|
-
|
|
232
|
-
if (this.multiFile) {
|
|
233
|
-
this.$('.g-progress-current').removeClass('hide');
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
this.currentIndex = 0;
|
|
237
|
-
this.overallProgress = 0;
|
|
238
|
-
this.trigger('g:uploadStarted');
|
|
239
|
-
|
|
240
|
-
if (!this.overrideStart) {
|
|
241
|
-
this.uploadNextFile();
|
|
242
|
-
}
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Enable or disable the start upload button.
|
|
247
|
-
*
|
|
248
|
-
* @param state {bool} Truthy for enabled, falsy for disabled.
|
|
249
|
-
*/
|
|
250
|
-
setUploadEnabled: function (state) {
|
|
251
|
-
this.$('.g-start-upload').girderEnable(state);
|
|
252
|
-
},
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Initializes the upload of a file by requesting the upload token
|
|
256
|
-
* from the server. If successful, this will call _uploadChunk to send the
|
|
257
|
-
* actual bytes from the file if it is of non-zero length.
|
|
258
|
-
*/
|
|
259
|
-
uploadNextFile: function () {
|
|
260
|
-
if (this.currentIndex >= this.files.length) {
|
|
261
|
-
// All files have finished
|
|
262
|
-
if (this.modal) {
|
|
263
|
-
this.$el.modal('hide');
|
|
264
|
-
}
|
|
265
|
-
this.trigger('g:uploadFinished', {
|
|
266
|
-
files: this.files,
|
|
267
|
-
totalSize: this.totalSize
|
|
268
|
-
});
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
this.currentFile = this.parentType === 'file' ? this.parent : new FileModel();
|
|
273
|
-
|
|
274
|
-
this.currentFile.on('g:upload.complete', function () {
|
|
275
|
-
this.files[this.currentIndex].id = this.currentFile.id;
|
|
276
|
-
this.currentIndex += 1;
|
|
277
|
-
this.uploadNextFile();
|
|
278
|
-
}, this).on('g:upload.chunkSent', function (info) {
|
|
279
|
-
this.overallProgress += info.bytes;
|
|
280
|
-
}, this).on('g:upload.progress', function (info) {
|
|
281
|
-
var currentProgress = info.startByte + info.loaded;
|
|
282
|
-
|
|
283
|
-
this.$('.g-progress-current>.progress-bar').css('width',
|
|
284
|
-
Math.ceil(100 * currentProgress / info.total) + '%');
|
|
285
|
-
this.$('.g-progress-overall>.progress-bar').css('width',
|
|
286
|
-
Math.ceil(100 * (this.overallProgress + info.loaded) /
|
|
287
|
-
this.totalSize) + '%');
|
|
288
|
-
this.$('.g-current-progress-message').html(
|
|
289
|
-
'<i class="icon-doc-text"/>' + (this.currentIndex + 1) + ' of ' +
|
|
290
|
-
this.files.length + ' - <b>' + info.file.name + '</b>: ' +
|
|
291
|
-
formatSize(currentProgress) + ' / ' +
|
|
292
|
-
formatSize(info.total)
|
|
293
|
-
);
|
|
294
|
-
this.$('.g-overall-progress-message').html('Overall progress: ' +
|
|
295
|
-
formatSize(this.overallProgress + info.loaded) + ' / ' +
|
|
296
|
-
formatSize(this.totalSize));
|
|
297
|
-
}, this).on('g:upload.error', function (info) {
|
|
298
|
-
var html = info.message + ' <a class="g-resume-upload">' +
|
|
299
|
-
'Click to resume upload</a>';
|
|
300
|
-
$('.g-upload-error-message').html(html);
|
|
301
|
-
}, this).on('g:upload.errorStarting', function (info) {
|
|
302
|
-
var html = info.message + ' <a class="g-restart-upload">' +
|
|
303
|
-
'Click to restart upload</a>';
|
|
304
|
-
$('.g-upload-error-message').html(html);
|
|
305
|
-
}, this);
|
|
306
|
-
|
|
307
|
-
if (this.parentType === 'file') {
|
|
308
|
-
this.currentFile.updateContents(this.files[this.currentIndex]);
|
|
309
|
-
} else {
|
|
310
|
-
var otherParams = this.otherParams;
|
|
311
|
-
if (_.isFunction(this.otherParams)) {
|
|
312
|
-
otherParams = this.otherParams(this);
|
|
313
|
-
}
|
|
314
|
-
this.currentFile.upload(this.parent, this.files[this.currentIndex], null, otherParams);
|
|
315
|
-
}
|
|
316
|
-
},
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* Check whether a DataTransferItem from a drag and drop operation
|
|
320
|
-
* represents a file, as opposed to a directory, URI, string, or other
|
|
321
|
-
* entity.
|
|
322
|
-
* @param {DataTransferItem} item - The item from a drag and drop operation.
|
|
323
|
-
* @returns {boolean} True if item represents a file.
|
|
324
|
-
*/
|
|
325
|
-
_isFile: function (item) {
|
|
326
|
-
var getAsEntry = item.getAsEntry;
|
|
327
|
-
if (!_.isFunction(getAsEntry)) {
|
|
328
|
-
getAsEntry = item.webkitGetAsEntry;
|
|
329
|
-
}
|
|
330
|
-
if (!_.isFunction(getAsEntry)) {
|
|
331
|
-
// Unsupported; assume item is file
|
|
332
|
-
return true;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
var entry = getAsEntry.call(item);
|
|
336
|
-
return entry && entry.isFile;
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
export default UploadWidget;
|