@girder/core 5.0.0-beta.1 → 5.0.0-beta.2

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 (239) hide show
  1. package/dist-lib/Girder_Favicon.png +0 -0
  2. package/dist-lib/Girder_Mark.png +0 -0
  3. package/dist-lib/girder-core.js +48560 -0
  4. package/dist-lib/girder-core.js.map +1 -0
  5. package/dist-lib/girder-core.umd.cjs +630 -0
  6. package/dist-lib/girder-core.umd.cjs.map +1 -0
  7. package/dist-lib/index.d.ts +1 -0
  8. package/dist-lib/src/auth.js +112 -0
  9. package/dist-lib/src/collections/ApiKeyCollection.js +9 -0
  10. package/dist-lib/src/collections/AssetstoreCollection.js +9 -0
  11. package/dist-lib/src/collections/Collection.js +295 -0
  12. package/dist-lib/src/collections/CollectionCollection.js +9 -0
  13. package/dist-lib/src/collections/FileCollection.js +11 -0
  14. package/dist-lib/src/collections/FolderCollection.js +11 -0
  15. package/dist-lib/src/collections/GroupCollection.js +9 -0
  16. package/dist-lib/src/collections/ItemCollection.js +11 -0
  17. package/dist-lib/src/collections/UserCollection.js +24 -0
  18. package/dist-lib/src/collections/index.js +21 -0
  19. package/dist-lib/src/constants.js +32 -0
  20. package/dist-lib/src/dialog.js +128 -0
  21. package/dist-lib/src/events.js +6 -0
  22. package/dist-lib/src/index.d.ts +23 -0
  23. package/dist-lib/src/index.ts +80 -0
  24. package/dist-lib/src/main.ts +45 -0
  25. package/dist-lib/src/misc.js +260 -0
  26. package/dist-lib/src/models/AccessControlledModel.js +76 -0
  27. package/dist-lib/src/models/ApiKeyModel.js +31 -0
  28. package/dist-lib/src/models/AssetstoreModel.js +43 -0
  29. package/dist-lib/src/models/CollectionCreationPolicyModel.js +20 -0
  30. package/dist-lib/src/models/CollectionModel.js +12 -0
  31. package/dist-lib/src/models/FileModel.js +310 -0
  32. package/dist-lib/src/models/FolderModel.js +33 -0
  33. package/dist-lib/src/models/GroupModel.js +197 -0
  34. package/dist-lib/src/models/ItemModel.js +72 -0
  35. package/dist-lib/src/models/MetadataMixin.js +88 -0
  36. package/dist-lib/src/models/Model.js +187 -0
  37. package/dist-lib/src/models/UserModel.js +189 -0
  38. package/dist-lib/src/models/index.js +25 -0
  39. package/dist-lib/src/pluginUtils.js +11 -0
  40. package/dist-lib/src/rest.js +221 -0
  41. package/dist-lib/src/router.js +58 -0
  42. package/dist-lib/src/routes.js +229 -0
  43. package/dist-lib/src/stylesheets/apidocs/apidocs.styl +50 -0
  44. package/dist-lib/src/stylesheets/body/adminConsole.styl +21 -0
  45. package/dist-lib/src/stylesheets/body/assetstores.styl +46 -0
  46. package/dist-lib/src/stylesheets/body/collectionList.styl +39 -0
  47. package/dist-lib/src/stylesheets/body/collectionPage.styl +6 -0
  48. package/dist-lib/src/stylesheets/body/frontPage.styl +48 -0
  49. package/dist-lib/src/stylesheets/body/groupList.styl +43 -0
  50. package/dist-lib/src/stylesheets/body/groupPage.styl +116 -0
  51. package/dist-lib/src/stylesheets/body/itemPage.styl +81 -0
  52. package/dist-lib/src/stylesheets/body/plugins.styl +61 -0
  53. package/dist-lib/src/stylesheets/body/searchResultsList.styl +51 -0
  54. package/dist-lib/src/stylesheets/body/systemConfig.styl +56 -0
  55. package/dist-lib/src/stylesheets/body/userAccount.styl +57 -0
  56. package/dist-lib/src/stylesheets/body/userList.styl +79 -0
  57. package/dist-lib/src/stylesheets/body/userPage.styl +6 -0
  58. package/dist-lib/src/stylesheets/layout/footer.styl +19 -0
  59. package/dist-lib/src/stylesheets/layout/global.styl +154 -0
  60. package/dist-lib/src/stylesheets/layout/globalNav.styl +89 -0
  61. package/dist-lib/src/stylesheets/layout/header.styl +29 -0
  62. package/dist-lib/src/stylesheets/layout/headerUser.styl +33 -0
  63. package/dist-lib/src/stylesheets/layout/layout.styl +75 -0
  64. package/dist-lib/src/stylesheets/layout/layoutVars.styl +9 -0
  65. package/dist-lib/src/stylesheets/layout/loading.styl +37 -0
  66. package/dist-lib/src/stylesheets/layout/progressArea.styl +17 -0
  67. package/dist-lib/src/stylesheets/widgets/accessWidget.styl +106 -0
  68. package/dist-lib/src/stylesheets/widgets/browserWidget.styl +9 -0
  69. package/dist-lib/src/stylesheets/widgets/hierarchyWidget.styl +188 -0
  70. package/dist-lib/src/stylesheets/widgets/markdownWidget.styl +92 -0
  71. package/dist-lib/src/stylesheets/widgets/metadataWidget.styl +92 -0
  72. package/dist-lib/src/stylesheets/widgets/searchFieldWidget.styl +70 -0
  73. package/dist-lib/src/stylesheets/widgets/taskProgress.styl +41 -0
  74. package/dist-lib/src/stylesheets/widgets/timelineWidget.styl +41 -0
  75. package/dist-lib/src/stylesheets/widgets/uploadWidget.styl +43 -0
  76. package/dist-lib/src/stylesheets/widgets/userOtpManagementWidget.styl +159 -0
  77. package/dist-lib/src/templates/body/adminConsole.pug +13 -0
  78. package/dist-lib/src/templates/body/assetstores.pug +83 -0
  79. package/dist-lib/src/templates/body/collectionList.pug +40 -0
  80. package/dist-lib/src/templates/body/collectionPage.pug +36 -0
  81. package/dist-lib/src/templates/body/filesystemImport.pug +41 -0
  82. package/dist-lib/src/templates/body/frontPage.pug +84 -0
  83. package/dist-lib/src/templates/body/groupList.pug +30 -0
  84. package/dist-lib/src/templates/body/groupPage.pug +116 -0
  85. package/dist-lib/src/templates/body/itemPage.pug +61 -0
  86. package/dist-lib/src/templates/body/plugins.pug +20 -0
  87. package/dist-lib/src/templates/body/s3Import.pug +35 -0
  88. package/dist-lib/src/templates/body/searchResults.pug +15 -0
  89. package/dist-lib/src/templates/body/searchResultsType.pug +13 -0
  90. package/dist-lib/src/templates/body/systemConfiguration.pug +199 -0
  91. package/dist-lib/src/templates/body/userAccount.pug +83 -0
  92. package/dist-lib/src/templates/body/userList.pug +43 -0
  93. package/dist-lib/src/templates/body/userPage.pug +40 -0
  94. package/dist-lib/src/templates/layout/alert.pug +5 -0
  95. package/dist-lib/src/templates/layout/layout.pug +12 -0
  96. package/dist-lib/src/templates/layout/layoutFooter.pug +11 -0
  97. package/dist-lib/src/templates/layout/layoutGlobalNav.pug +7 -0
  98. package/dist-lib/src/templates/layout/layoutHeader.pug +8 -0
  99. package/dist-lib/src/templates/layout/layoutHeaderUser.pug +26 -0
  100. package/dist-lib/src/templates/layout/layoutProgressArea.pug +1 -0
  101. package/dist-lib/src/templates/layout/loginDialog.pug +30 -0
  102. package/dist-lib/src/templates/layout/registerDialog.pug +35 -0
  103. package/dist-lib/src/templates/layout/resetPasswordDialog.pug +25 -0
  104. package/dist-lib/src/templates/widgets/accessEditor.pug +23 -0
  105. package/dist-lib/src/templates/widgets/accessEditorMixins.pug +57 -0
  106. package/dist-lib/src/templates/widgets/accessEditorNonModal.pug +11 -0
  107. package/dist-lib/src/templates/widgets/accessEntry.pug +32 -0
  108. package/dist-lib/src/templates/widgets/apiKeyList.pug +50 -0
  109. package/dist-lib/src/templates/widgets/browserWidget.pug +32 -0
  110. package/dist-lib/src/templates/widgets/checkedActionsMenu.pug +46 -0
  111. package/dist-lib/src/templates/widgets/collectionInfoDialog.pug +37 -0
  112. package/dist-lib/src/templates/widgets/confirmDialog.pug +14 -0
  113. package/dist-lib/src/templates/widgets/dateTimeRangeWidget.pug +20 -0
  114. package/dist-lib/src/templates/widgets/dateTimeWidget.pug +8 -0
  115. package/dist-lib/src/templates/widgets/editApiKeyWidget.pug +43 -0
  116. package/dist-lib/src/templates/widgets/editAssetstoreWidget.pug +66 -0
  117. package/dist-lib/src/templates/widgets/editCollectionWidget.pug +27 -0
  118. package/dist-lib/src/templates/widgets/editFileWidget.pug +21 -0
  119. package/dist-lib/src/templates/widgets/editFolderWidget.pug +27 -0
  120. package/dist-lib/src/templates/widgets/editGroupWidget.pug +54 -0
  121. package/dist-lib/src/templates/widgets/editItemWidget.pug +27 -0
  122. package/dist-lib/src/templates/widgets/fileInfoDialog.pug +33 -0
  123. package/dist-lib/src/templates/widgets/fileList.pug +33 -0
  124. package/dist-lib/src/templates/widgets/folderInfoDialog.pug +42 -0
  125. package/dist-lib/src/templates/widgets/folderList.pug +21 -0
  126. package/dist-lib/src/templates/widgets/groupAdminList.pug +33 -0
  127. package/dist-lib/src/templates/widgets/groupInviteDialog.pug +76 -0
  128. package/dist-lib/src/templates/widgets/groupInviteList.pug +14 -0
  129. package/dist-lib/src/templates/widgets/groupMemberList.pug +39 -0
  130. package/dist-lib/src/templates/widgets/groupModList.pug +23 -0
  131. package/dist-lib/src/templates/widgets/hierarchyBreadcrumb.pug +37 -0
  132. package/dist-lib/src/templates/widgets/hierarchyPaginated.pug +19 -0
  133. package/dist-lib/src/templates/widgets/hierarchyWidget.pug +96 -0
  134. package/dist-lib/src/templates/widgets/itemBreadcrumb.pug +16 -0
  135. package/dist-lib/src/templates/widgets/itemList.pug +27 -0
  136. package/dist-lib/src/templates/widgets/jsonMetadatumEditWidget.pug +13 -0
  137. package/dist-lib/src/templates/widgets/jsonMetadatumView.pug +6 -0
  138. package/dist-lib/src/templates/widgets/loadingAnimation.pug +4 -0
  139. package/dist-lib/src/templates/widgets/markdownWidget.pug +34 -0
  140. package/dist-lib/src/templates/widgets/metadataWidget.pug +16 -0
  141. package/dist-lib/src/templates/widgets/metadatumEditWidget.pug +15 -0
  142. package/dist-lib/src/templates/widgets/metadatumView.pug +5 -0
  143. package/dist-lib/src/templates/widgets/newAssetstore.pug +83 -0
  144. package/dist-lib/src/templates/widgets/paginateWidget.pug +7 -0
  145. package/dist-lib/src/templates/widgets/pluginConfigBreadcrumb.pug +13 -0
  146. package/dist-lib/src/templates/widgets/rootSelectorWidget.pug +13 -0
  147. package/dist-lib/src/templates/widgets/searchField.pug +10 -0
  148. package/dist-lib/src/templates/widgets/searchHelp.pug +12 -0
  149. package/dist-lib/src/templates/widgets/searchModeSelect.pug +9 -0
  150. package/dist-lib/src/templates/widgets/searchResults.pug +14 -0
  151. package/dist-lib/src/templates/widgets/sortCollectionWidget.pug +14 -0
  152. package/dist-lib/src/templates/widgets/taskProgress.pug +16 -0
  153. package/dist-lib/src/templates/widgets/timeline.pug +15 -0
  154. package/dist-lib/src/templates/widgets/uploadWidget.pug +15 -0
  155. package/dist-lib/src/templates/widgets/uploadWidgetMixins.pug +31 -0
  156. package/dist-lib/src/templates/widgets/uploadWidgetNonModal.pug +10 -0
  157. package/dist-lib/src/templates/widgets/userOtpBegin.pug +4 -0
  158. package/dist-lib/src/templates/widgets/userOtpDisable.pug +6 -0
  159. package/dist-lib/src/templates/widgets/userOtpEnable.pug +44 -0
  160. package/dist-lib/src/utilities/EventStream.js +177 -0
  161. package/dist-lib/src/utilities/PluginUtils.js +36 -0
  162. package/dist-lib/src/utilities/S3UploadHandler.js +303 -0
  163. package/dist-lib/src/utilities/index.js +9 -0
  164. package/dist-lib/src/utilities/jquery/girderEnable.js +19 -0
  165. package/dist-lib/src/utilities/jquery/girderModal.js +48 -0
  166. package/dist-lib/src/version.js +6 -0
  167. package/dist-lib/src/views/App.js +359 -0
  168. package/dist-lib/src/views/View.js +79 -0
  169. package/dist-lib/src/views/body/AdminView.js +29 -0
  170. package/dist-lib/src/views/body/AssetstoresView.js +234 -0
  171. package/dist-lib/src/views/body/CollectionView.js +188 -0
  172. package/dist-lib/src/views/body/CollectionsView.js +120 -0
  173. package/dist-lib/src/views/body/FilesystemImportView.js +83 -0
  174. package/dist-lib/src/views/body/FolderView.js +54 -0
  175. package/dist-lib/src/views/body/FrontPageView.js +47 -0
  176. package/dist-lib/src/views/body/GroupView.js +336 -0
  177. package/dist-lib/src/views/body/GroupsView.js +106 -0
  178. package/dist-lib/src/views/body/ItemView.js +177 -0
  179. package/dist-lib/src/views/body/PluginsView.js +73 -0
  180. package/dist-lib/src/views/body/S3ImportView.js +80 -0
  181. package/dist-lib/src/views/body/SearchResultsView.js +162 -0
  182. package/dist-lib/src/views/body/SystemConfigurationView.js +182 -0
  183. package/dist-lib/src/views/body/UserAccountView.js +179 -0
  184. package/dist-lib/src/views/body/UserView.js +165 -0
  185. package/dist-lib/src/views/body/UsersView.js +124 -0
  186. package/dist-lib/src/views/body/index.js +37 -0
  187. package/dist-lib/src/views/index.js +13 -0
  188. package/dist-lib/src/views/layout/FooterView.js +29 -0
  189. package/dist-lib/src/views/layout/GlobalNavView.js +103 -0
  190. package/dist-lib/src/views/layout/HeaderUserView.js +45 -0
  191. package/dist-lib/src/views/layout/HeaderView.js +83 -0
  192. package/dist-lib/src/views/layout/LoginView.js +100 -0
  193. package/dist-lib/src/views/layout/ProgressListView.js +70 -0
  194. package/dist-lib/src/views/layout/RegisterView.js +101 -0
  195. package/dist-lib/src/views/layout/ResetPasswordView.js +70 -0
  196. package/dist-lib/src/views/layout/index.js +19 -0
  197. package/dist-lib/src/views/widgets/AccessWidget.js +427 -0
  198. package/dist-lib/src/views/widgets/ApiKeyListWidget.js +140 -0
  199. package/dist-lib/src/views/widgets/BrowserWidget.js +317 -0
  200. package/dist-lib/src/views/widgets/CheckedMenuWidget.js +68 -0
  201. package/dist-lib/src/views/widgets/CollectionInfoWidget.js +40 -0
  202. package/dist-lib/src/views/widgets/DateTimeRangeWidget.js +180 -0
  203. package/dist-lib/src/views/widgets/DateTimeWidget.js +110 -0
  204. package/dist-lib/src/views/widgets/EditApiKeyWidget.js +122 -0
  205. package/dist-lib/src/views/widgets/EditAssetstoreWidget.js +133 -0
  206. package/dist-lib/src/views/widgets/EditCollectionWidget.js +93 -0
  207. package/dist-lib/src/views/widgets/EditFileWidget.js +56 -0
  208. package/dist-lib/src/views/widgets/EditFolderWidget.js +116 -0
  209. package/dist-lib/src/views/widgets/EditGroupWidget.js +125 -0
  210. package/dist-lib/src/views/widgets/EditItemWidget.js +110 -0
  211. package/dist-lib/src/views/widgets/FileInfoWidget.js +26 -0
  212. package/dist-lib/src/views/widgets/FileListWidget.js +151 -0
  213. package/dist-lib/src/views/widgets/FolderInfoWidget.js +39 -0
  214. package/dist-lib/src/views/widgets/FolderListWidget.js +106 -0
  215. package/dist-lib/src/views/widgets/GroupAdminsWidget.js +88 -0
  216. package/dist-lib/src/views/widgets/GroupInvitesWidget.js +56 -0
  217. package/dist-lib/src/views/widgets/GroupMembersWidget.js +185 -0
  218. package/dist-lib/src/views/widgets/GroupModsWidget.js +77 -0
  219. package/dist-lib/src/views/widgets/HierarchyWidget.js +1097 -0
  220. package/dist-lib/src/views/widgets/ItemBreadcrumbWidget.js +38 -0
  221. package/dist-lib/src/views/widgets/ItemListWidget.js +345 -0
  222. package/dist-lib/src/views/widgets/LoadingAnimation.js +17 -0
  223. package/dist-lib/src/views/widgets/MarkdownWidget.js +217 -0
  224. package/dist-lib/src/views/widgets/MetadataWidget.js +508 -0
  225. package/dist-lib/src/views/widgets/NewAssetstoreWidget.js +71 -0
  226. package/dist-lib/src/views/widgets/PaginateWidget.js +37 -0
  227. package/dist-lib/src/views/widgets/PluginConfigBreadcrumbWidget.js +33 -0
  228. package/dist-lib/src/views/widgets/RootSelectorWidget.js +192 -0
  229. package/dist-lib/src/views/widgets/SearchFieldWidget.js +365 -0
  230. package/dist-lib/src/views/widgets/SearchPaginateWidget.js +149 -0
  231. package/dist-lib/src/views/widgets/SortCollectionWidget.js +53 -0
  232. package/dist-lib/src/views/widgets/TaskProgressWidget.js +91 -0
  233. package/dist-lib/src/views/widgets/TimelineWidget.js +155 -0
  234. package/dist-lib/src/views/widgets/UploadWidget.js +340 -0
  235. package/dist-lib/src/views/widgets/UserOtpManagementWidget.js +105 -0
  236. package/dist-lib/src/views/widgets/index.js +75 -0
  237. package/dist-lib/src/vite-env.d.ts +5 -0
  238. package/dist-lib/style.css +16 -0
  239. package/package.json +1 -1
@@ -0,0 +1,20 @@
1
+ import AccessControlledModel from '@girder/core/models/AccessControlledModel';
2
+ import { restRequest } from '@girder/core/rest';
3
+
4
+ var CollectionCreationPolicyModel = AccessControlledModel.extend({
5
+ resourceName: 'system/setting/collection_creation_policy',
6
+ fetchAccess: function () {
7
+ return restRequest({
8
+ url: `${this.resourceName}/access`,
9
+ method: 'GET'
10
+ }).done((resp) => {
11
+ this.set('access', resp);
12
+ this.trigger('g:accessFetched');
13
+ return resp;
14
+ }).fail((err) => {
15
+ this.trigger('g:error', err);
16
+ });
17
+ }
18
+ });
19
+
20
+ export default CollectionCreationPolicyModel;
@@ -0,0 +1,12 @@
1
+ import _ from 'underscore';
2
+
3
+ import AccessControlledModel from '@girder/core/models/AccessControlledModel';
4
+ import MetadataMixin from '@girder/core/models/MetadataMixin';
5
+
6
+ var CollectionModel = AccessControlledModel.extend({
7
+ resourceName: 'collection'
8
+ });
9
+
10
+ _.extend(CollectionModel.prototype, MetadataMixin);
11
+
12
+ export default CollectionModel;
@@ -0,0 +1,310 @@
1
+ import _ from 'underscore';
2
+
3
+ import FolderModel from '@girder/core/models/FolderModel';
4
+ import ItemModel from '@girder/core/models/ItemModel';
5
+ import Model from '@girder/core/models/Model';
6
+ import { restRequest, uploadHandlers, getUploadChunkSize } from '@girder/core/rest';
7
+ import '@girder/core/utilities/S3UploadHandler'; // imported for side effect
8
+
9
+ var FileModel = Model.extend({
10
+ resourceName: 'file',
11
+ resumeInfo: null,
12
+
13
+ _wrapData: function (data, type) {
14
+ var wrapped = data;
15
+
16
+ if (!(data instanceof Blob)) {
17
+ if (!_.isArray(data)) {
18
+ wrapped = [data];
19
+ }
20
+ wrapped = new Blob(wrapped, {
21
+ type: type
22
+ });
23
+ }
24
+
25
+ return wrapped;
26
+ },
27
+
28
+ /**
29
+ * Upload into an existing file object (i.e. this model) to change its
30
+ * contents. This does not change the name or MIME type of the existing
31
+ * file.
32
+ * @param data A browser File object, browser Blob object, or raw data to be uploaded.
33
+ */
34
+ updateContents: function (data) {
35
+ data = this._wrapData(data);
36
+
37
+ this.upload(null, data, {
38
+ url: `file/${this.id}/contents`,
39
+ method: 'PUT',
40
+ data: {
41
+ size: data.size
42
+ }
43
+ });
44
+ },
45
+
46
+ /**
47
+ * Upload data to a new file in a given container
48
+ * @param Model A constructor for the parent model (either FolderModel or ItemModel).
49
+ * @param model The parent model to upload to, or a string containing the id thereof.
50
+ * @param data The data to upload - either a string, File object, or Blob object.
51
+ * @param name The name of the file to create (optional if data is a File).
52
+ * @param type The mime type of the file (optional).
53
+ */
54
+ _uploadToContainer: function (Model, model, data, name, type) {
55
+ if (_.isString(model)) {
56
+ model = new Model({
57
+ _id: model
58
+ });
59
+ }
60
+
61
+ data = this._wrapData(data, type);
62
+ data.name = name;
63
+
64
+ this.upload(model, data);
65
+ },
66
+
67
+ /**
68
+ * Upload data to a new file in a given folder
69
+ * @param parentFolder The parent folder to upload to, or a string containing the id thereof.
70
+ * @param data The data to upload - either a string, File object, or Blob object.
71
+ * @param name The name of the file to create (optional if data is a File).
72
+ * @param type The mime type of the file (optional).
73
+ */
74
+ uploadToFolder: function (parentFolder, data, name, type) {
75
+ this._uploadToContainer(FolderModel, parentFolder, data, name, type);
76
+ },
77
+
78
+ /**
79
+ * Upload data to a new file in a given folder
80
+ * @param parentItem The parent item to upload to, or a string containing the id thereof.
81
+ * @param data The data to upload - either a string, File object, or Blob object.
82
+ * @param name The name of the file to create (optional if data is a File).
83
+ * @param type The mime type of the file (optional).
84
+ */
85
+ uploadToItem: function (parentItem, data, name, type) {
86
+ this._uploadToContainer(ItemModel, parentItem, data, name, type);
87
+ },
88
+
89
+ /**
90
+ * Upload a file. Handles uploading into all of the core assetstore types.
91
+ * @param parentModel The parent folder or item to upload into.
92
+ * @param file The browser File object to be uploaded.
93
+ * @param [_restParams] Override the rest request parameters. This is meant
94
+ * for internal use; do not pass this parameter.
95
+ * @param [otherParams] Optional Object containing other parameters for the
96
+ * initUpload request.
97
+ */
98
+ upload: function (parentModel, file, _restParams, otherParams) {
99
+ this.startByte = 0;
100
+ this.resumeInfo = null;
101
+ this.uploadHandler = null;
102
+ _restParams = _restParams || {
103
+ url: 'file',
104
+ method: 'POST',
105
+ data: _.extend({
106
+ parentType: parentModel.resourceName,
107
+ parentId: parentModel.get('_id'),
108
+ name: file.name,
109
+ size: file.size,
110
+ mimeType: file.type
111
+ }, otherParams)
112
+ };
113
+
114
+ // Authenticate and generate the upload token for this file
115
+ restRequest(_restParams).done((upload) => {
116
+ var behavior = upload.behavior;
117
+ if (behavior && uploadHandlers[behavior]) {
118
+ this.uploadHandler = new uploadHandlers[behavior]({
119
+ upload: upload,
120
+ parentModel: parentModel,
121
+ file: file
122
+ });
123
+ this.uploadHandler.on({
124
+ 'g:upload.complete': function (params) {
125
+ this.set(params);
126
+ this.trigger('g:upload.complete', params);
127
+ this.uploadHandler = null;
128
+ },
129
+ 'g:upload.chunkSent': function (params) {
130
+ this.trigger('g:upload.chunkSent', params);
131
+ },
132
+ 'g:upload.error': function (params) {
133
+ this.trigger('g:upload.error', params);
134
+ },
135
+ 'g:upload.errorStarting': function (params) {
136
+ this.trigger('g:upload.errorStarting', params);
137
+ },
138
+ 'g:upload.progress': function (params) {
139
+ this.trigger('g:upload.progress', {
140
+ startByte: params.startByte,
141
+ loaded: params.loaded,
142
+ total: params.file.size,
143
+ file: params.file
144
+ });
145
+ }
146
+ }, this);
147
+ return this.uploadHandler.execute();
148
+ }
149
+
150
+ if (file.size > 0) {
151
+ // Begin uploading chunks of this file
152
+ this._uploadChunk(file, upload._id);
153
+ } else {
154
+ // Empty file, so we are done
155
+ this.set(upload);
156
+ this.trigger('g:upload.complete');
157
+ }
158
+ }).fail((resp) => {
159
+ var text = 'Error: ', identifier;
160
+
161
+ if (resp.status === 0) {
162
+ text += 'Connection to the server interrupted.';
163
+ } else {
164
+ text += resp.responseJSON.message;
165
+ identifier = resp.responseJSON.identifier;
166
+ }
167
+ this.trigger('g:upload.errorStarting', {
168
+ message: text,
169
+ identifier: identifier,
170
+ response: resp
171
+ });
172
+ });
173
+ },
174
+
175
+ /**
176
+ * If an error was triggered during the upload of this file, call this
177
+ * in order to attempt to resume it.
178
+ */
179
+ resumeUpload: function () {
180
+ if (this.uploadHandler !== null && this.uploadHandler.resume) {
181
+ return this.uploadHandler.resume();
182
+ }
183
+
184
+ // Request the actual offset we need to resume at
185
+ restRequest({
186
+ url: 'file/offset',
187
+ method: 'GET',
188
+ data: {
189
+ uploadId: this.resumeInfo.uploadId
190
+ },
191
+ error: null
192
+ }).done((resp) => {
193
+ this.startByte = resp.offset;
194
+ this._uploadChunk(this.resumeInfo.file, this.resumeInfo.uploadId);
195
+ }).fail((resp) => {
196
+ var msg;
197
+
198
+ if (resp.status === 0) {
199
+ msg = 'Could not connect to the server.';
200
+ } else {
201
+ msg = 'An error occurred when resuming upload, check console.';
202
+ }
203
+ this.trigger('g:upload.error', {
204
+ message: msg,
205
+ response: resp
206
+ });
207
+ });
208
+ },
209
+
210
+ abortUpload: function () {
211
+ if (!this.resumeInfo || !this.resumeInfo.uploadId) {
212
+ return;
213
+ }
214
+ restRequest({
215
+ url: 'system/uploads',
216
+ method: 'DELETE',
217
+ data: {
218
+ uploadId: this.resumeInfo.uploadId
219
+ },
220
+ error: null,
221
+ done: null
222
+ });
223
+ },
224
+
225
+ _uploadChunk: function (file, uploadId) {
226
+ var endByte = Math.min(this.startByte + getUploadChunkSize(), file.size);
227
+
228
+ this.chunkLength = endByte - this.startByte;
229
+ var sliceFn = file.webkitSlice ? 'webkitSlice' : 'slice';
230
+ var blob = file[sliceFn](this.startByte, endByte);
231
+
232
+ restRequest({
233
+ url: `file/chunk?offset=${this.startByte}&uploadId=${uploadId}`,
234
+ method: 'POST',
235
+ data: blob,
236
+ contentType: false,
237
+ processData: false,
238
+ success: (resp) => {
239
+ this.trigger('g:upload.chunkSent', {
240
+ bytes: endByte - this.startByte
241
+ });
242
+
243
+ if (endByte === file.size) {
244
+ this.startByte = 0;
245
+ this.resumeInfo = null;
246
+ this.set(resp);
247
+ this.trigger('g:upload.complete');
248
+ } else {
249
+ this.startByte = endByte;
250
+ this._uploadChunk(file, uploadId);
251
+ }
252
+ },
253
+ error: (resp) => {
254
+ var text = 'Error: ', identifier;
255
+
256
+ if (resp.status === 0) {
257
+ text += 'Connection to the server interrupted.';
258
+ } else {
259
+ text += resp.responseJSON.message;
260
+ identifier = resp.responseJSON.identifier;
261
+ }
262
+
263
+ this.resumeInfo = {
264
+ uploadId: uploadId,
265
+ file: file
266
+ };
267
+
268
+ this.trigger('g:upload.error', {
269
+ message: text,
270
+ identifier: identifier,
271
+ response: resp
272
+ });
273
+ },
274
+ xhr: () => {
275
+ // Custom XHR so we can register a progress handler
276
+ var xhr = new window.XMLHttpRequest();
277
+ xhr.upload.addEventListener('progress', (e) => {
278
+ this._uploadProgress(file, e);
279
+ });
280
+ return xhr;
281
+ }
282
+ });
283
+ },
284
+
285
+ /**
286
+ * Progress callback from XHR during upload. This will trigger useful
287
+ * progress events under the 'upload.progress' tag.
288
+ */
289
+ _uploadProgress: function (file, event) {
290
+ if (!event.lengthComputable) {
291
+ return;
292
+ }
293
+
294
+ // We only want to count bytes of the actual file, not the bytes of
295
+ // the request body corresponding to the other form parameters model
296
+ // we are also sending.
297
+ var loaded = this.chunkLength + event.loaded - event.total;
298
+
299
+ if (loaded >= 0) {
300
+ this.trigger('g:upload.progress', {
301
+ startByte: this.startByte,
302
+ loaded: loaded,
303
+ total: file.size,
304
+ file: file
305
+ });
306
+ }
307
+ }
308
+ });
309
+
310
+ export default FileModel;
@@ -0,0 +1,33 @@
1
+ import _ from 'underscore';
2
+
3
+ import AccessControlledModel from '@girder/core/models/AccessControlledModel';
4
+ import MetadataMixin from '@girder/core/models/MetadataMixin';
5
+ import { restRequest } from '@girder/core/rest';
6
+
7
+ var FolderModel = AccessControlledModel.extend({
8
+ resourceName: 'folder',
9
+
10
+ getRootPath: function () {
11
+ return restRequest({
12
+ url: `${this.resourceName}/${this.id}/rootpath`
13
+ });
14
+ },
15
+
16
+ /**
17
+ * Remove the contents of the folder.
18
+ */
19
+ removeContents: function () {
20
+ return restRequest({
21
+ url: `${this.resourceName}/${this.id}/contents`,
22
+ method: 'DELETE'
23
+ }).done(() => {
24
+ this.trigger('g:success');
25
+ }).fail((err) => {
26
+ this.trigger('g:error', err);
27
+ });
28
+ }
29
+ });
30
+
31
+ _.extend(FolderModel.prototype, MetadataMixin);
32
+
33
+ export default FolderModel;
@@ -0,0 +1,197 @@
1
+ import _ from 'underscore';
2
+
3
+ import AccessControlledModel from '@girder/core/models/AccessControlledModel';
4
+ import { AccessType } from '@girder/core/constants';
5
+ import { getCurrentUser } from '@girder/core/auth';
6
+ import { restRequest } from '@girder/core/rest';
7
+
8
+ var GroupModel = AccessControlledModel.extend({
9
+ resourceName: 'group',
10
+
11
+ /**
12
+ * Send an invitation to this group to the user identified by userId.
13
+ * Requires moderator (write) access on the group.
14
+ * @param userId The ID of the user to invite.
15
+ * @param accessType The access level to invite them as.
16
+ * @param request Set to true if this is accepting a user's request to join.
17
+ * @param [params] Additional parameters to pass with the request.
18
+ */
19
+ sendInvitation: function (userId, accessType, request, params) {
20
+ params = params || {};
21
+ return restRequest({
22
+ url: `${this.resourceName}/${this.id}/invitation`,
23
+ data: _.extend({
24
+ userId: userId,
25
+ level: accessType
26
+ }, params),
27
+ method: 'POST',
28
+ error: null
29
+ }).done((resp) => {
30
+ this.set(resp);
31
+
32
+ if (!request && userId === getCurrentUser().get('_id')) {
33
+ if (params.force) {
34
+ getCurrentUser().addToGroup(this.get('_id'));
35
+ } else {
36
+ getCurrentUser().addInvitation(this.get('_id'), accessType);
37
+ }
38
+ }
39
+ this.trigger('g:invited');
40
+ }).fail((err) => {
41
+ this.trigger('g:error', err);
42
+ });
43
+ },
44
+
45
+ /**
46
+ * Accept an invitation to join a group. Only call this if the user has
47
+ * already been invited to the group.
48
+ */
49
+ joinGroup: function () {
50
+ return restRequest({
51
+ url: `${this.resourceName}/${this.id}/member`,
52
+ method: 'POST'
53
+ }).done((resp) => {
54
+ getCurrentUser().addToGroup(this.get('_id'));
55
+ getCurrentUser().removeInvitation(this.get('_id'));
56
+
57
+ this.set(resp);
58
+
59
+ this.trigger('g:joined');
60
+ }).fail((err) => {
61
+ this.trigger('g:error', err);
62
+ });
63
+ },
64
+
65
+ /**
66
+ * This will create an invitation request on this group for the current
67
+ * user. Requires read access on the group. If the user already has an
68
+ * outstanding invitation to this group, call joinGroup instead.
69
+ */
70
+ requestInvitation: function () {
71
+ return restRequest({
72
+ url: `${this.resourceName}/${this.id}/member`,
73
+ method: 'POST'
74
+ }).done((resp) => {
75
+ this.set(resp);
76
+
77
+ this.trigger('g:inviteRequested');
78
+ }).fail((err) => {
79
+ this.trigger('g:error', err);
80
+ });
81
+ },
82
+
83
+ /**
84
+ * Promote a user to moderator or administrator. Requires admin access
85
+ * on the group.
86
+ * @param user The user model of the user being promoted
87
+ * @param level The AccessLevel (WRITE or ADMIN) to promote to
88
+ */
89
+ promoteUser: function (user, level) {
90
+ var role;
91
+ if (level === AccessType.WRITE) {
92
+ role = 'moderator';
93
+ } else if (level === AccessType.ADMIN) {
94
+ role = 'admin';
95
+ }
96
+ return restRequest({
97
+ url: `${this.resourceName}/${this.id}/${role}`,
98
+ data: {
99
+ userId: user.get('_id')
100
+ },
101
+ method: 'POST'
102
+ }).done((resp) => {
103
+ this.set(resp);
104
+
105
+ this.trigger('g:promoted');
106
+ }).fail((err) => {
107
+ this.trigger('g:error', err);
108
+ });
109
+ },
110
+
111
+ /**
112
+ * Demote a user to ordinary member status. Requires admin access on the
113
+ * group.
114
+ * @param userId The id of the user to demote.
115
+ * @param level The current access level of the user.
116
+ */
117
+ demoteUser: function (userId, level) {
118
+ var role;
119
+ if (level === AccessType.WRITE) {
120
+ role = 'moderator';
121
+ } else if (level === AccessType.ADMIN) {
122
+ role = 'admin';
123
+ }
124
+ return restRequest({
125
+ url: `${this.resourceName}/${this.id}/${role}?userId=${userId}`,
126
+ method: 'DELETE'
127
+ }).done((resp) => {
128
+ this.set(resp);
129
+
130
+ this.trigger('g:demoted');
131
+ }).fail((err) => {
132
+ this.trigger('g:error', err);
133
+ });
134
+ },
135
+
136
+ /**
137
+ * Remove a member of a group, or if the user is not already a member,
138
+ * this will simply delete any outstanding membership request or
139
+ * invitation for this user.
140
+ * @param userId The ID of the user to remove.
141
+ */
142
+ removeMember: function (userId) {
143
+ return restRequest({
144
+ url: `${this.resourceName}/${this.id}/member?userId=${userId}`,
145
+ method: 'DELETE'
146
+ }).done((resp) => {
147
+ if (userId === getCurrentUser().get('_id')) {
148
+ getCurrentUser().removeFromGroup(this.get('_id'));
149
+ }
150
+
151
+ this.set(resp);
152
+
153
+ this.trigger('g:removed');
154
+ }).fail((err) => {
155
+ this.trigger('g:error', err);
156
+ });
157
+ },
158
+
159
+ /* Check if the current user has the authority in this group to directly
160
+ * add members.
161
+ *
162
+ * @returns: true if adding members is allowed.
163
+ */
164
+ mayAddMembers: function () {
165
+ if (getCurrentUser().get('admin')) {
166
+ return true;
167
+ }
168
+ var groupAddAllowed;
169
+ var addToGroupPolicy = this.get('_addToGroupPolicy');
170
+ if (addToGroupPolicy === 'nomod' || addToGroupPolicy === 'yesmod') {
171
+ groupAddAllowed = 'mod';
172
+ } else if (addToGroupPolicy === 'noadmin' || addToGroupPolicy === 'yesadmin') {
173
+ groupAddAllowed = 'admin';
174
+ } else {
175
+ return false;
176
+ }
177
+ var addAllowed = this.get('addAllowed') || '';
178
+ if (addAllowed === 'no' || (addToGroupPolicy.substr(0, 3) !== 'yes' &&
179
+ addAllowed.substr(0, 3) !== 'yes')) {
180
+ return false;
181
+ }
182
+ if (addAllowed === 'yesadmin') {
183
+ groupAddAllowed = 'admin';
184
+ }
185
+ if (groupAddAllowed === 'admin' &&
186
+ this.get('_accessLevel') >= AccessType.ADMIN) {
187
+ return true;
188
+ }
189
+ if (groupAddAllowed === 'mod' &&
190
+ this.get('_accessLevel') >= AccessType.WRITE) {
191
+ return true;
192
+ }
193
+ return false;
194
+ }
195
+ });
196
+
197
+ export default GroupModel;
@@ -0,0 +1,72 @@
1
+ import $ from 'jquery';
2
+ import _ from 'underscore';
3
+
4
+ import FileCollection from '@girder/core/collections/FileCollection';
5
+ import FolderModel from '@girder/core/models/FolderModel';
6
+ import MetadataMixin from '@girder/core/models/MetadataMixin';
7
+ import Model from '@girder/core/models/Model';
8
+ import { restRequest } from '@girder/core/rest';
9
+
10
+ var ItemModel = Model.extend({
11
+ resourceName: 'item',
12
+
13
+ /**
14
+ * Get the access level of the item if it is set. Takes an optional callback
15
+ * to be called once the access level is fetched (or immediately if it has
16
+ * already been fetched).
17
+ */
18
+ getAccessLevel: function (callback) {
19
+ callback = callback || $.noop;
20
+
21
+ if (this.has('_accessLevel')) {
22
+ callback(this.get('_accessLevel'));
23
+ return this.get('_accessLevel');
24
+ }
25
+ if (this.parent && this.parent.getAccessLevel()) {
26
+ this.set('_accessLevel', this.parent.getAccessLevel());
27
+ callback(this.get('_accessLevel'));
28
+ return this.get('_accessLevel');
29
+ } else {
30
+ var parent = new FolderModel();
31
+ parent.set({
32
+ _id: this.get('folderId')
33
+ }).once('g:fetched', function () {
34
+ this.parent = parent;
35
+ this.set('_accessLevel', this.parent.getAccessLevel());
36
+ callback(this.get('_accessLevel'));
37
+ }, this).fetch();
38
+ }
39
+ },
40
+
41
+ /**
42
+ * Get the path to the root of the hierarchy
43
+ */
44
+ getRootPath: function (callback) {
45
+ return restRequest({
46
+ url: `${this.resourceName}/${this.id}/rootpath`
47
+ }).done((resp) => {
48
+ callback(resp);
49
+ }).fail((err) => {
50
+ this.trigger('g:error', err);
51
+ });
52
+ },
53
+
54
+ /**
55
+ * Get the files within the item.
56
+ */
57
+ getFiles: function () {
58
+ return restRequest({
59
+ url: `${this.resourceName}/${this.id}/files`
60
+ }).then((resp) => {
61
+ const fileCollection = new FileCollection(resp);
62
+ this.trigger('g:files', fileCollection);
63
+ return fileCollection;
64
+ }).fail((err) => {
65
+ this.trigger('g:error', err);
66
+ });
67
+ }
68
+ });
69
+
70
+ _.extend(ItemModel.prototype, MetadataMixin);
71
+
72
+ export default ItemModel;