@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.
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,38 +0,0 @@
1
- import $ from 'jquery';
2
-
3
- import router from '@girder/core/router';
4
- import View from '@girder/core/views/View';
5
-
6
- import ItemBreadcrumbTemplate from '@girder/core/templates/widgets/itemBreadcrumb.pug';
7
-
8
- /**
9
- * Renders the a breadcrumb for the item page
10
- */
11
- var ItemBreadcrumbWidget = View.extend({
12
- events: {
13
- 'click a.g-item-breadcrumb-link': function (event) {
14
- var link = $(event.currentTarget);
15
- router.navigate(link.data('type') + '/' + link.data('id'),
16
- { trigger: true });
17
- },
18
- 'click a.g-hierarchy-level-up': function () {
19
- var folder = this.parentChain.pop().object;
20
- router.navigate('folder/' + folder._id, { trigger: true });
21
- }
22
- },
23
-
24
- initialize: function (settings) {
25
- this.parentChain = settings.parentChain;
26
- this.render();
27
- },
28
-
29
- render: function () {
30
- this.$el.html(ItemBreadcrumbTemplate({
31
- parentChain: this.parentChain
32
- }));
33
-
34
- return this;
35
- }
36
- });
37
-
38
- export default ItemBreadcrumbWidget;
@@ -1,345 +0,0 @@
1
- import $ from 'jquery';
2
- import _ from 'underscore';
3
-
4
- import ItemCollection from '@girder/core/collections/ItemCollection';
5
- import LoadingAnimation from '@girder/core/views/widgets/LoadingAnimation';
6
- import View from '@girder/core/views/View';
7
- import { formatSize } from '@girder/core/misc';
8
- import { restRequest } from '@girder/core/rest';
9
-
10
- import ItemListTemplate from '@girder/core/templates/widgets/itemList.pug';
11
-
12
- /**
13
- * This widget shows a list of items under a given folder.
14
- */
15
- var ItemListWidget = View.extend({
16
- events: {
17
- 'click a.g-item-list-link': function (event) {
18
- event.preventDefault();
19
- var cid = $(event.currentTarget).attr('g-item-cid');
20
- this.trigger('g:itemClicked', this.collection.get(cid), event);
21
- },
22
- 'click a.g-show-more-items': function () {
23
- this.collection.fetchNextPage();
24
- },
25
- 'change .g-list-checkbox': function (event) {
26
- const target = $(event.currentTarget);
27
- const cid = target.attr('g-item-cid');
28
- if (target.prop('checked')) {
29
- this.checked.push(cid);
30
- } else {
31
- const idx = this.checked.indexOf(cid);
32
- if (idx !== -1) {
33
- this.checked.splice(idx, 1);
34
- }
35
- }
36
- this.trigger('g:checkboxesChanged');
37
- }
38
- },
39
-
40
- initialize: function (settings) {
41
- this.checked = [];
42
- this._checkboxes = settings.checkboxes;
43
- this._downloadLinks = (
44
- _.has(settings, 'downloadLinks') ? settings.downloadLinks : true);
45
- this._viewLinks = (
46
- _.has(settings, 'viewLinks') ? settings.viewLinks : true);
47
- this._showSizes = (
48
- _.has(settings, 'showSizes') ? settings.showSizes : true);
49
- this._highlightItem = (
50
- _.has(settings, 'highlightItem') ? settings.highlightItem : false);
51
- this._paginated = (
52
- _.has(settings, 'paginated') ? settings.paginated : false);
53
-
54
- this.accessLevel = settings.accessLevel;
55
- this.public = settings.public;
56
- this._selectedItem = settings.selectedItem;
57
-
58
- new LoadingAnimation({
59
- el: this.$el,
60
- parentView: this
61
- }).render();
62
-
63
- this.collection = new ItemCollection();
64
- this.collection.append = true; // Append, don't replace pages
65
- this.collection.filterFunc = settings.itemFilter;
66
- this.currentPage = 1; // By default we want to be on the first page
67
-
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;
75
- }
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');
129
- },
130
-
131
- render: function () {
132
- this.checked = [];
133
- // If we set a selected item in the beginning we will center the selection while loading
134
- if (this._selectedItem && this._highlightItem) {
135
- this.scrollPositionObserver();
136
- }
137
-
138
- this.$el.html(ItemListTemplate({
139
- items: this.collection.toArray(),
140
- isParentPublic: this.public,
141
- hasMore: this.collection.hasNextPage(),
142
- formatSize: formatSize,
143
- checkboxes: this._checkboxes,
144
- downloadLinks: this._downloadLinks,
145
- viewLinks: this._viewLinks,
146
- showSizes: this._showSizes,
147
- highlightItem: this._highlightItem,
148
- selectedItemId: (this._selectedItem || {}).id,
149
- paginated: this._paginated
150
-
151
- }));
152
-
153
- return this;
154
- },
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
- },
179
- /**
180
- * Insert an item into the collection and re-render it.
181
- */
182
- insertItem: function (item) {
183
- if (this.accessLevel !== undefined) {
184
- item.set('_accessLevel', this.accessLevel);
185
- }
186
- this.collection.add(item);
187
- this.trigger('g:changed');
188
- this.render();
189
- },
190
-
191
- /**
192
- * Set all item checkboxes to a certain checked state. The event
193
- * g:checkboxesChanged is triggered once after checking/unchecking everything.
194
- * @param {bool} checked The checked state.
195
- */
196
- checkAll: function (checked) {
197
- this.$('.g-list-checkbox').prop('checked', checked);
198
-
199
- this.checked = [];
200
- if (checked) {
201
- this.collection.each(function (model) {
202
- this.checked.push(model.cid);
203
- }, this);
204
- }
205
-
206
- this.trigger('g:checkboxesChanged');
207
- },
208
-
209
- /**
210
- * Select (highlight) an item in the list.
211
- * @param item An ItemModel instance representing the item to select.
212
- */
213
- selectItem: function (item) {
214
- this.$('li.g-item-list-entry').removeClass('g-selected');
215
- this.$('a.g-item-list-link[g-item-cid=' + item.cid + ']')
216
- .parents('li.g-item-list-entry').addClass('g-selected');
217
- },
218
-
219
- /**
220
- * Return the currently selected item, or null if there is no selected item.
221
- */
222
- getSelectedItem: function () {
223
- var el = this.$('li.g-item-list-entry.g-selected');
224
- if (!el.length) {
225
- return null;
226
- }
227
- var cid = $('.g-item-list-link', $(el[0])).attr('g-item-cid');
228
- return this.collection.get(cid);
229
- },
230
-
231
- recomputeChecked: function () {
232
- this.checked = _.map(this.$('.g-list-checkbox:checked'), function (checkbox) {
233
- return $(checkbox).attr('g-item-cid');
234
- }, this);
235
- },
236
-
237
- centerSelected: function () {
238
- const widgetcontainer = this.$el.parents('.g-hierarchy-widget-container');
239
- const selected = this.$('li.g-item-list-entry.g-selected');
240
- if (widgetcontainer.length > 0 && selected.length > 0) {
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;
250
- if (this.tempScrollPos === undefined) {
251
- this.tempScrollPos = scrollPos;
252
- }
253
- // Call a custom scroll event to prevent thinking the user initiated it
254
- const e = new CustomEvent('scroll', { detail: 'selected_item_scroll' });
255
- widgetcontainer[0].scrollTop = scrollPos;
256
- widgetcontainer[0].dispatchEvent(e);
257
- }
258
- },
259
- /**
260
- * This will look at the position of the selected item and update it as images load and
261
- * the DOM reflows
262
- */
263
- scrollPositionObserver: function () {
264
- // Set the default selected height for the selected item
265
- const target = this.$('.g-item-list');
266
- if (window.MutationObserver && target.length > 0) {
267
- // Default items to monitor for the scroll position
268
- const widgetcontainer = this.$el.parents('.g-hierarchy-widget-container');
269
- // If the observer already exists disconnect it so it can be recreated
270
- if (this.observer && this.observer.disconnect) {
271
- this.observer.disconnect();
272
- }
273
-
274
- // Event handler for loading images declared once
275
- const onLoadImage = (event) => {
276
- if (this.observer) {
277
- this.centerSelected();
278
- }
279
- };
280
-
281
- this.observer = new MutationObserver((mutations) => {
282
- // for every mutation
283
- _.each(mutations, (mutation) => {
284
- // If no nodes are added we can return
285
- if (!mutation.addedNodes) {
286
- return;
287
- }
288
-
289
- // for every added node
290
- _.each(mutation.addedNodes, (node) => {
291
- if (node.className && node.className.indexOf('g-item-list') !== -1) {
292
- // We want to do a onetime scroll to position if the screen is idle
293
- if (window.requestIdleCallback) {
294
- // Processing time is 2 seconds, but should finish much faster
295
- requestIdleCallback(() => {
296
- this.centerSelected();
297
- }, { timeout: 2000 });
298
- } else {
299
- this.centerSelected();
300
- }
301
- }
302
-
303
- // For any images added we wait until loaded and rescroll to the selected
304
- if (_.isFunction(node.getElementsByTagName)) {
305
- this.$('img', node).on('load', onLoadImage);
306
- }
307
- });
308
- });
309
- });
310
-
311
- // bind mutation observer to a specific element (probably a div somewhere)
312
- this.observer.observe(target.parent()[0], { childList: true, subtree: true });
313
-
314
- // Remove event listeners and disconnect observer
315
- const unbindDisconnect = () => {
316
- if (this.observer) {
317
- widgetcontainer.unbind('scroll.observerscroll');
318
- widgetcontainer.unbind('wheel.observerscroll');
319
- widgetcontainer.unbind('click.observerscroll');
320
- this.observer.disconnect();
321
- this.observer = null;
322
- this.tempScrollPos = undefined;
323
- // Prevents scrolling when user clicks 'show more...'
324
- this._highlightItem = false;
325
- }
326
- };
327
-
328
- // Add in scroll event to monitor the scrollPos to prevent unnecessary updates and also kill observer when user scrolls
329
- widgetcontainer.bind('scroll.observerscroll', (evt) => {
330
- if (this.tempScrollPos !== undefined && this.tempScrollPos !== widgetcontainer[0].scrollTop) {
331
- this.tempScrollPos = widgetcontainer[0].scrollTop;
332
- // If the event detail is not 'selected_item_scroll' the scroll should be a user initiated scroll
333
- if (evt.detail !== 'selected_item_scroll') {
334
- unbindDisconnect();
335
- }
336
- }
337
- });
338
- // Backup function to kill observer if user clicks an item, moves scrollwheel, or touchpad equivalent
339
- widgetcontainer.bind('wheel.selectionobserver', unbindDisconnect);
340
- widgetcontainer.bind('click.selectionobserver', unbindDisconnect);
341
- }
342
- }
343
- });
344
-
345
- export default ItemListWidget;
@@ -1,17 +0,0 @@
1
- import View from '@girder/core/views/View';
2
-
3
- import LoadingAnimationTemplate from '@girder/core/templates/widgets/loadingAnimation.pug';
4
-
5
- import '@girder/core/stylesheets/layout/loading.styl';
6
-
7
- /**
8
- * This widget can be used to display a small loading animation.
9
- */
10
- var LoadingAnimation = View.extend({
11
- render: function () {
12
- this.$el.html(LoadingAnimationTemplate());
13
- return this;
14
- }
15
- });
16
-
17
- export default LoadingAnimation;
@@ -1,217 +0,0 @@
1
- import _ from 'underscore';
2
-
3
- import FileModel from '@girder/core/models/FileModel';
4
- import View from '@girder/core/views/View';
5
- import events from '@girder/core/events';
6
- import { renderMarkdown, formatSize } from '@girder/core/misc';
7
-
8
- import MarkdownWidgetTemplate from '@girder/core/templates/widgets/markdownWidget.pug';
9
-
10
- import '@girder/core/stylesheets/widgets/markdownWidget.styl';
11
-
12
- import '@girder/core/utilities/jquery/girderEnable';
13
-
14
- import 'bootstrap/js/tab';
15
-
16
- /**
17
- * A simple widget for editing markdown text with a preview tab.
18
- */
19
- var MarkdownWidget = View.extend({
20
- events: {
21
- 'show.bs.tab .g-preview-link': function () {
22
- renderMarkdown(this.val().trim() || 'Nothing to show',
23
- this.$('.g-markdown-preview'));
24
- },
25
-
26
- 'shown.bs.tab .g-write-link': function () {
27
- this.$('.g-markdown-text').trigger('focus');
28
- },
29
-
30
- 'click .g-browse': function () {
31
- this.$('.g-file-input').trigger('click');
32
- },
33
-
34
- 'change .g-file-input': function (e) {
35
- var files = e.target.files;
36
-
37
- if (files.length) {
38
- this.files = files;
39
- this.filesAdded();
40
- }
41
- },
42
-
43
- 'dragenter .g-markdown-drop-zone': function (e) {
44
- e.stopPropagation();
45
- e.preventDefault();
46
- e.originalEvent.dataTransfer.dropEffect = 'copy';
47
- this.$('.g-markdown-text,.g-upload-footer').addClass('dragover');
48
- },
49
-
50
- 'dragleave .g-markdown-drop-zone': function (e) {
51
- e.stopPropagation();
52
- e.preventDefault();
53
- this.$('.g-markdown-text,.g-upload-footer').removeClass('dragover');
54
- },
55
-
56
- 'dragover .g-markdown-drop-zone': function (e) {
57
- e.originalEvent.dataTransfer.dropEffect = 'copy';
58
- this.$('.g-markdown-text,.g-upload-footer').addClass('dragover');
59
- },
60
-
61
- 'drop .g-markdown-drop-zone': function (e) {
62
- e.stopPropagation();
63
- e.preventDefault();
64
- this.$('.g-markdown-text,.g-upload-footer').removeClass('dragover');
65
- this.files = e.originalEvent.dataTransfer.files;
66
- this.filesAdded();
67
- }
68
- },
69
-
70
- /**
71
- * @param [settings.text=''] Initial markdown text.
72
- * @param [settings.placeholder=''] Text area placeholder.
73
- * @param [settings.prefix='markdown'] Prefix for element IDs in case
74
- * multiple of these widgets are rendered simultaneously.
75
- * @param [settings.enableUploads=false] Whether to allow uploading files
76
- * inline into the markdown.
77
- * @param [settings.maxUploadSize=10 MB] Max upload size in bytes.
78
- * @param [settings.parent] If enableUploads is true, set this to the object
79
- * into which files should be uploaded.
80
- * @param [settings.allowedExtensions=null] If you want to restrict to
81
- * certain file extensions, set this to a list of (lowercase) extensions,
82
- * not including periods. E.g.: ["png", "jpg", "jpeg"]
83
- */
84
- initialize: function (settings) {
85
- this.text = settings.text || '';
86
- this.placeholder = settings.placeholder || '';
87
- this.prefix = settings.prefix || 'markdown';
88
- this.enableUploads = settings.enableUploads || false;
89
- this.parent = settings.parent || null;
90
- this.maxUploadSize = settings.maxUploadSize || 1024 * 1024 * 10;
91
- this.allowedExtensions = settings.allowedExtensions || null;
92
- this.files = [];
93
- },
94
-
95
- filesAdded: function () {
96
- try {
97
- this.validateFiles();
98
- } catch (err) {
99
- events.trigger('g:alert', {
100
- type: 'danger',
101
- text: err.message,
102
- icon: 'cancel',
103
- timeout: 5000
104
- });
105
- return;
106
- }
107
-
108
- var file = this.files[0];
109
- var fileModel = new FileModel();
110
-
111
- fileModel.on('g:upload.complete', function () {
112
- var val = this.$('.g-markdown-text').val();
113
- val += '![' + file.name + '](' + fileModel.downloadUrl() + ')\n';
114
-
115
- this.$('.g-upload-overlay').addClass('hide');
116
- this.$('.g-markdown-text').girderEnable(true).val(val);
117
-
118
- this.trigger('g:fileUploaded', {
119
- file: file,
120
- model: fileModel
121
- });
122
- }, this).on('g:upload.progress', function (info) {
123
- var currentProgress = info.startByte + info.loaded;
124
- this.$('.g-markdown-upload-progress>.progress-bar').css('width',
125
- Math.ceil(100 * currentProgress / info.total) + '%');
126
- this.$('.g-markdown-upload-progress-message').text(
127
- 'Uploading ' + info.file.name + ' - ' +
128
- formatSize(currentProgress) + ' / ' +
129
- formatSize(info.total)
130
- );
131
- }, this).on('g:upload.error', function (info) {
132
- events.trigger('g:alert', {
133
- type: 'danger',
134
- text: info.message,
135
- icon: 'cancel',
136
- timeout: 5000
137
- });
138
- this.$('.g-upload-overlay').addClass('hide');
139
- this.$('.g-markdown-text').girderEnable(true);
140
- }, this).on('g:upload.errorStarting', function (info) {
141
- events.trigger('g:alert', {
142
- type: 'danger',
143
- text: info.message,
144
- icon: 'cancel',
145
- timeout: 5000
146
- });
147
- this.$('.g-upload-overlay').addClass('hide');
148
- this.$('.g-markdown-text').girderEnable(true);
149
- }, this).upload(this.parent, file);
150
-
151
- this.$('.g-upload-overlay').removeClass('hide');
152
- this.$('.g-markdown-text').girderEnable(false);
153
- },
154
-
155
- /**
156
- * Validate a selection of files. If invalid, throws an object containing
157
- * a "message" field.
158
- */
159
- validateFiles: function (files) {
160
- files = files || this.files;
161
-
162
- if (this.files.length !== 1) {
163
- throw new Error('Please add only one file at a time.');
164
- }
165
-
166
- var file = files[0],
167
- ext = file.name.split('.').pop().toLowerCase();
168
-
169
- if (this.maxUploadSize && file.size > this.maxUploadSize) {
170
- throw new Error(
171
- 'That file is too large. You may only attach files ' +
172
- 'up to ' + formatSize(this.maxUploadSize) + '.'
173
- );
174
- }
175
-
176
- if (this.allowedExtensions && !_.contains(this.allowedExtensions, ext)) {
177
- throw new Error(
178
- 'Only files with the following extensions are allowed: ' +
179
- this.allowedExtensions.join(', ') + '.'
180
- );
181
- }
182
- },
183
-
184
- render: function () {
185
- this.$el.html(MarkdownWidgetTemplate({
186
- text: this.text,
187
- placeholder: this.placeholder,
188
- prefix: this.prefix,
189
- enableUploads: this.enableUploads
190
- }));
191
-
192
- return this;
193
- },
194
-
195
- /**
196
- * Get or set the current markdown text. Call with no arguments to return
197
- * the current value, or call with one argument to set the value to that.
198
- */
199
- val: function () {
200
- if (arguments.length) {
201
- return this.$('.g-markdown-text').val(arguments[0]);
202
- } else {
203
- return this.$('.g-markdown-text').val();
204
- }
205
- },
206
-
207
- /**
208
- * Normally, calling render() on this widget will reset it to its initial text
209
- * value. Call this to set the text value that should be shown on re-render
210
- * to the current value of the text area.
211
- */
212
- saveText: function () {
213
- this.text = this.val();
214
- }
215
- });
216
-
217
- export default MarkdownWidget;