@girder/core 3.2.7 → 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.
Files changed (231) hide show
  1. package/README.md +61 -0
  2. package/package.json +79 -31
  3. package/assets/Girder_Mark.png +0 -0
  4. package/auth.js +0 -152
  5. package/collections/ApiKeyCollection.js +0 -9
  6. package/collections/AssetstoreCollection.js +0 -9
  7. package/collections/Collection.js +0 -295
  8. package/collections/CollectionCollection.js +0 -9
  9. package/collections/FileCollection.js +0 -11
  10. package/collections/FolderCollection.js +0 -11
  11. package/collections/GroupCollection.js +0 -9
  12. package/collections/ItemCollection.js +0 -11
  13. package/collections/UserCollection.js +0 -24
  14. package/collections/index.js +0 -21
  15. package/constants.js +0 -33
  16. package/dialog.js +0 -128
  17. package/events.js +0 -6
  18. package/index.js +0 -31
  19. package/main.js +0 -21
  20. package/misc.js +0 -260
  21. package/models/AccessControlledModel.js +0 -76
  22. package/models/ApiKeyModel.js +0 -31
  23. package/models/AssetstoreModel.js +0 -43
  24. package/models/CollectionCreationPolicyModel.js +0 -20
  25. package/models/CollectionModel.js +0 -12
  26. package/models/FileModel.js +0 -310
  27. package/models/FolderModel.js +0 -33
  28. package/models/GroupModel.js +0 -197
  29. package/models/ItemModel.js +0 -72
  30. package/models/MetadataMixin.js +0 -88
  31. package/models/Model.js +0 -187
  32. package/models/UserModel.js +0 -189
  33. package/models/index.js +0 -25
  34. package/pluginUtils.js +0 -11
  35. package/rest.js +0 -216
  36. package/router.js +0 -58
  37. package/routes.js +0 -231
  38. package/stylesheets/apidocs/apidocs.styl +0 -50
  39. package/stylesheets/body/adminConsole.styl +0 -21
  40. package/stylesheets/body/assetstores.styl +0 -46
  41. package/stylesheets/body/collectionList.styl +0 -39
  42. package/stylesheets/body/collectionPage.styl +0 -6
  43. package/stylesheets/body/frontPage.styl +0 -48
  44. package/stylesheets/body/groupList.styl +0 -43
  45. package/stylesheets/body/groupPage.styl +0 -116
  46. package/stylesheets/body/itemPage.styl +0 -81
  47. package/stylesheets/body/plugins.styl +0 -61
  48. package/stylesheets/body/searchResultsList.styl +0 -51
  49. package/stylesheets/body/systemConfig.styl +0 -56
  50. package/stylesheets/body/userAccount.styl +0 -57
  51. package/stylesheets/body/userList.styl +0 -79
  52. package/stylesheets/body/userPage.styl +0 -6
  53. package/stylesheets/layout/footer.styl +0 -19
  54. package/stylesheets/layout/global.styl +0 -154
  55. package/stylesheets/layout/globalNav.styl +0 -89
  56. package/stylesheets/layout/header.styl +0 -29
  57. package/stylesheets/layout/headerUser.styl +0 -33
  58. package/stylesheets/layout/layout.styl +0 -75
  59. package/stylesheets/layout/layoutVars.styl +0 -9
  60. package/stylesheets/layout/loading.styl +0 -37
  61. package/stylesheets/layout/progressArea.styl +0 -17
  62. package/stylesheets/widgets/accessWidget.styl +0 -106
  63. package/stylesheets/widgets/browserWidget.styl +0 -9
  64. package/stylesheets/widgets/hierarchyWidget.styl +0 -188
  65. package/stylesheets/widgets/markdownWidget.styl +0 -92
  66. package/stylesheets/widgets/metadataWidget.styl +0 -92
  67. package/stylesheets/widgets/searchFieldWidget.styl +0 -70
  68. package/stylesheets/widgets/taskProgress.styl +0 -41
  69. package/stylesheets/widgets/timelineWidget.styl +0 -41
  70. package/stylesheets/widgets/uploadWidget.styl +0 -43
  71. package/stylesheets/widgets/userOtpManagementWidget.styl +0 -159
  72. package/templates/body/adminConsole.pug +0 -13
  73. package/templates/body/assetstores.pug +0 -98
  74. package/templates/body/collectionList.pug +0 -40
  75. package/templates/body/collectionPage.pug +0 -36
  76. package/templates/body/filesystemImport.pug +0 -41
  77. package/templates/body/frontPage.pug +0 -83
  78. package/templates/body/groupList.pug +0 -30
  79. package/templates/body/groupPage.pug +0 -116
  80. package/templates/body/itemPage.pug +0 -61
  81. package/templates/body/plugins.pug +0 -20
  82. package/templates/body/s3Import.pug +0 -35
  83. package/templates/body/searchResults.pug +0 -15
  84. package/templates/body/searchResultsType.pug +0 -13
  85. package/templates/body/systemConfiguration.pug +0 -221
  86. package/templates/body/userAccount.pug +0 -83
  87. package/templates/body/userList.pug +0 -43
  88. package/templates/body/userPage.pug +0 -40
  89. package/templates/layout/alert.pug +0 -5
  90. package/templates/layout/layout.pug +0 -12
  91. package/templates/layout/layoutFooter.pug +0 -11
  92. package/templates/layout/layoutGlobalNav.pug +0 -7
  93. package/templates/layout/layoutHeader.pug +0 -8
  94. package/templates/layout/layoutHeaderUser.pug +0 -26
  95. package/templates/layout/layoutProgressArea.pug +0 -1
  96. package/templates/layout/loginDialog.pug +0 -30
  97. package/templates/layout/registerDialog.pug +0 -35
  98. package/templates/layout/resetPasswordDialog.pug +0 -25
  99. package/templates/widgets/accessEditor.pug +0 -23
  100. package/templates/widgets/accessEditorMixins.pug +0 -57
  101. package/templates/widgets/accessEditorNonModal.pug +0 -11
  102. package/templates/widgets/accessEntry.pug +0 -32
  103. package/templates/widgets/apiKeyList.pug +0 -50
  104. package/templates/widgets/browserWidget.pug +0 -32
  105. package/templates/widgets/checkedActionsMenu.pug +0 -46
  106. package/templates/widgets/collectionInfoDialog.pug +0 -37
  107. package/templates/widgets/confirmDialog.pug +0 -14
  108. package/templates/widgets/dateTimeRangeWidget.pug +0 -20
  109. package/templates/widgets/dateTimeWidget.pug +0 -8
  110. package/templates/widgets/editApiKeyWidget.pug +0 -43
  111. package/templates/widgets/editAssetstoreWidget.pug +0 -78
  112. package/templates/widgets/editCollectionWidget.pug +0 -27
  113. package/templates/widgets/editFileWidget.pug +0 -21
  114. package/templates/widgets/editFolderWidget.pug +0 -27
  115. package/templates/widgets/editGroupWidget.pug +0 -54
  116. package/templates/widgets/editItemWidget.pug +0 -27
  117. package/templates/widgets/fileInfoDialog.pug +0 -33
  118. package/templates/widgets/fileList.pug +0 -33
  119. package/templates/widgets/folderInfoDialog.pug +0 -42
  120. package/templates/widgets/folderList.pug +0 -21
  121. package/templates/widgets/groupAdminList.pug +0 -33
  122. package/templates/widgets/groupInviteDialog.pug +0 -76
  123. package/templates/widgets/groupInviteList.pug +0 -14
  124. package/templates/widgets/groupMemberList.pug +0 -39
  125. package/templates/widgets/groupModList.pug +0 -23
  126. package/templates/widgets/hierarchyBreadcrumb.pug +0 -37
  127. package/templates/widgets/hierarchyPaginated.pug +0 -19
  128. package/templates/widgets/hierarchyWidget.pug +0 -96
  129. package/templates/widgets/itemBreadcrumb.pug +0 -16
  130. package/templates/widgets/itemList.pug +0 -27
  131. package/templates/widgets/jsonMetadatumEditWidget.pug +0 -13
  132. package/templates/widgets/jsonMetadatumView.pug +0 -6
  133. package/templates/widgets/loadingAnimation.pug +0 -4
  134. package/templates/widgets/markdownWidget.pug +0 -34
  135. package/templates/widgets/metadataWidget.pug +0 -16
  136. package/templates/widgets/metadatumEditWidget.pug +0 -15
  137. package/templates/widgets/metadatumView.pug +0 -5
  138. package/templates/widgets/newAssetstore.pug +0 -118
  139. package/templates/widgets/paginateWidget.pug +0 -7
  140. package/templates/widgets/pluginConfigBreadcrumb.pug +0 -13
  141. package/templates/widgets/rootSelectorWidget.pug +0 -13
  142. package/templates/widgets/searchField.pug +0 -10
  143. package/templates/widgets/searchHelp.pug +0 -12
  144. package/templates/widgets/searchModeSelect.pug +0 -9
  145. package/templates/widgets/searchResults.pug +0 -14
  146. package/templates/widgets/sortCollectionWidget.pug +0 -14
  147. package/templates/widgets/taskProgress.pug +0 -16
  148. package/templates/widgets/timeline.pug +0 -15
  149. package/templates/widgets/uploadWidget.pug +0 -15
  150. package/templates/widgets/uploadWidgetMixins.pug +0 -31
  151. package/templates/widgets/uploadWidgetNonModal.pug +0 -10
  152. package/templates/widgets/userOtpBegin.pug +0 -4
  153. package/templates/widgets/userOtpDisable.pug +0 -6
  154. package/templates/widgets/userOtpEnable.pug +0 -44
  155. package/utilities/EventStream.js +0 -177
  156. package/utilities/PluginUtils.js +0 -36
  157. package/utilities/S3UploadHandler.js +0 -303
  158. package/utilities/index.js +0 -9
  159. package/utilities/jquery/girderEnable.js +0 -19
  160. package/utilities/jquery/girderModal.js +0 -48
  161. package/version.js +0 -10
  162. package/views/App.js +0 -359
  163. package/views/View.js +0 -78
  164. package/views/body/AdminView.js +0 -29
  165. package/views/body/AssetstoresView.js +0 -235
  166. package/views/body/CollectionView.js +0 -188
  167. package/views/body/CollectionsView.js +0 -120
  168. package/views/body/FilesystemImportView.js +0 -83
  169. package/views/body/FolderView.js +0 -54
  170. package/views/body/FrontPageView.js +0 -47
  171. package/views/body/GroupView.js +0 -336
  172. package/views/body/GroupsView.js +0 -106
  173. package/views/body/ItemView.js +0 -177
  174. package/views/body/PluginsView.js +0 -73
  175. package/views/body/S3ImportView.js +0 -80
  176. package/views/body/SearchResultsView.js +0 -162
  177. package/views/body/SystemConfigurationView.js +0 -196
  178. package/views/body/UserAccountView.js +0 -179
  179. package/views/body/UserView.js +0 -165
  180. package/views/body/UsersView.js +0 -124
  181. package/views/body/index.js +0 -37
  182. package/views/index.js +0 -13
  183. package/views/layout/FooterView.js +0 -29
  184. package/views/layout/GlobalNavView.js +0 -103
  185. package/views/layout/HeaderUserView.js +0 -45
  186. package/views/layout/HeaderView.js +0 -83
  187. package/views/layout/LoginView.js +0 -100
  188. package/views/layout/ProgressListView.js +0 -70
  189. package/views/layout/RegisterView.js +0 -101
  190. package/views/layout/ResetPasswordView.js +0 -70
  191. package/views/layout/index.js +0 -19
  192. package/views/widgets/AccessWidget.js +0 -427
  193. package/views/widgets/ApiKeyListWidget.js +0 -140
  194. package/views/widgets/BrowserWidget.js +0 -317
  195. package/views/widgets/CheckedMenuWidget.js +0 -68
  196. package/views/widgets/CollectionInfoWidget.js +0 -40
  197. package/views/widgets/DateTimeRangeWidget.js +0 -179
  198. package/views/widgets/DateTimeWidget.js +0 -109
  199. package/views/widgets/EditApiKeyWidget.js +0 -122
  200. package/views/widgets/EditAssetstoreWidget.js +0 -148
  201. package/views/widgets/EditCollectionWidget.js +0 -93
  202. package/views/widgets/EditFileWidget.js +0 -56
  203. package/views/widgets/EditFolderWidget.js +0 -116
  204. package/views/widgets/EditGroupWidget.js +0 -125
  205. package/views/widgets/EditItemWidget.js +0 -110
  206. package/views/widgets/FileInfoWidget.js +0 -26
  207. package/views/widgets/FileListWidget.js +0 -151
  208. package/views/widgets/FolderInfoWidget.js +0 -39
  209. package/views/widgets/FolderListWidget.js +0 -106
  210. package/views/widgets/GroupAdminsWidget.js +0 -88
  211. package/views/widgets/GroupInvitesWidget.js +0 -56
  212. package/views/widgets/GroupMembersWidget.js +0 -185
  213. package/views/widgets/GroupModsWidget.js +0 -77
  214. package/views/widgets/HierarchyWidget.js +0 -1097
  215. package/views/widgets/ItemBreadcrumbWidget.js +0 -38
  216. package/views/widgets/ItemListWidget.js +0 -345
  217. package/views/widgets/LoadingAnimation.js +0 -17
  218. package/views/widgets/MarkdownWidget.js +0 -217
  219. package/views/widgets/MetadataWidget.js +0 -504
  220. package/views/widgets/NewAssetstoreWidget.js +0 -81
  221. package/views/widgets/PaginateWidget.js +0 -37
  222. package/views/widgets/PluginConfigBreadcrumbWidget.js +0 -33
  223. package/views/widgets/RootSelectorWidget.js +0 -192
  224. package/views/widgets/SearchFieldWidget.js +0 -365
  225. package/views/widgets/SearchPaginateWidget.js +0 -149
  226. package/views/widgets/SortCollectionWidget.js +0 -53
  227. package/views/widgets/TaskProgressWidget.js +0 -91
  228. package/views/widgets/TimelineWidget.js +0 -155
  229. package/views/widgets/UploadWidget.js +0 -340
  230. package/views/widgets/UserOtpManagementWidget.js +0 -105
  231. 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;