@girder/core 5.0.0-beta.1 → 5.0.0

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 (238) 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.css +2 -0
  4. package/dist-lib/girder-core.js +60421 -0
  5. package/dist-lib/girder-core.js.map +1 -0
  6. package/dist-lib/girder-core.umd.cjs +1484 -0
  7. package/dist-lib/girder-core.umd.cjs.map +1 -0
  8. package/dist-lib/index.d.ts +1 -0
  9. package/dist-lib/src/auth.js +112 -0
  10. package/dist-lib/src/collections/ApiKeyCollection.js +9 -0
  11. package/dist-lib/src/collections/AssetstoreCollection.js +10 -0
  12. package/dist-lib/src/collections/Collection.js +295 -0
  13. package/dist-lib/src/collections/CollectionCollection.js +9 -0
  14. package/dist-lib/src/collections/FileCollection.js +11 -0
  15. package/dist-lib/src/collections/FolderCollection.js +11 -0
  16. package/dist-lib/src/collections/GroupCollection.js +9 -0
  17. package/dist-lib/src/collections/ItemCollection.js +11 -0
  18. package/dist-lib/src/collections/UserCollection.js +24 -0
  19. package/dist-lib/src/collections/index.js +21 -0
  20. package/dist-lib/src/constants.js +32 -0
  21. package/dist-lib/src/dialog.js +128 -0
  22. package/dist-lib/src/events.js +6 -0
  23. package/dist-lib/src/index.ts +80 -0
  24. package/dist-lib/src/main.ts +61 -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 +83 -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 +215 -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 +70 -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 +87 -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 +119 -0
  161. package/dist-lib/src/utilities/PluginUtils.js +36 -0
  162. package/dist-lib/src/utilities/S3UploadHandler.js +263 -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 +233 -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 +177 -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 +38 -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 +124 -0
  205. package/dist-lib/src/views/widgets/EditAssetstoreWidget.js +136 -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 +72 -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 +81 -0
  237. package/dist-lib/src/vite-env.d.ts +5 -0
  238. package/package.json +17 -15
@@ -0,0 +1,73 @@
1
+ import $ from 'jquery';
2
+ import _ from 'underscore';
3
+
4
+ import router from '@girder/core/router';
5
+ import View from '@girder/core/views/View';
6
+ import { getPluginConfigRoute } from '@girder/core/utilities/PluginUtils';
7
+ import { restRequest, cancelRestRequests } from '@girder/core/rest';
8
+
9
+ import PluginsTemplate from '@girder/core/templates/body/plugins.pug';
10
+
11
+ import '@girder/core/stylesheets/body/plugins.styl';
12
+
13
+ /**
14
+ * This is the plugin management page for administrators.
15
+ */
16
+ var PluginsView = View.extend({
17
+ events: {
18
+ 'click a.g-plugin-config-link': function (evt) {
19
+ var route = $(evt.currentTarget).attr('g-route');
20
+ router.navigate(route, { trigger: true });
21
+ }
22
+ },
23
+
24
+ initialize: function (settings) {
25
+ cancelRestRequests('fetch');
26
+ if (settings.all) {
27
+ this.allPlugins = settings.all;
28
+ this.render();
29
+ } else {
30
+ // Fetch the plugin list
31
+ restRequest({
32
+ url: 'system/plugins',
33
+ method: 'GET'
34
+ })
35
+ .done((resp) => {
36
+ this.allPlugins = resp.all;
37
+ this.render();
38
+ }).fail(() => {
39
+ router.navigate('/', { trigger: true });
40
+ });
41
+ }
42
+ },
43
+
44
+ render: function () {
45
+ _.each(this.allPlugins, function (info, name) {
46
+ info.configRoute = getPluginConfigRoute(name);
47
+ }, this);
48
+
49
+ this.$el.html(PluginsTemplate({
50
+ allPlugins: this._sortPlugins(this.allPlugins)
51
+ }));
52
+
53
+ return this;
54
+ },
55
+
56
+ _sortPlugins: function (plugins) {
57
+ /* Sort a dictionary of plugins alphabetically so that the appear in a
58
+ * predictable order to the user.
59
+ *
60
+ * @param plugins: a dictionary to sort. Each entry has a .name
61
+ * attribute used for sorting.
62
+ * @returns sortedPlugins: the sorted list. */
63
+ var sortedPlugins = _.map(plugins, function (value, key) {
64
+ return { key: key, value: value };
65
+ });
66
+ sortedPlugins.sort(function (a, b) {
67
+ return a.value.name.localeCompare(b.value.name);
68
+ });
69
+ return sortedPlugins;
70
+ }
71
+ });
72
+
73
+ export default PluginsView;
@@ -0,0 +1,80 @@
1
+ import $ from 'jquery';
2
+
3
+ import BrowserWidget from '@girder/core/views/widgets/BrowserWidget';
4
+ import router from '@girder/core/router';
5
+ import View from '@girder/core/views/View';
6
+ import { restRequest } from '@girder/core/rest';
7
+
8
+ import S3ImportTemplate from '@girder/core/templates/body/s3Import.pug';
9
+
10
+ var S3ImportView = View.extend({
11
+ events: {
12
+ 'submit .g-s3-import-form': function (e) {
13
+ e.preventDefault();
14
+
15
+ var destId = this.$('#g-s3-import-dest-id').val().trim().split(/\s/)[0],
16
+ destType = this.$('#g-s3-import-dest-type').val();
17
+
18
+ this.$('.g-validation-failed-message').empty();
19
+
20
+ this.assetstore.off('g:imported').on('g:imported', function () {
21
+ router.navigate(destType + '/' + destId, { trigger: true });
22
+ }, this).on('g:error', function (resp) {
23
+ this.$('.g-validation-failed-message').text(resp.responseJSON.message);
24
+ }, this).import({
25
+ importPath: this.$('#g-s3-import-path').val().trim(),
26
+ destinationId: destId,
27
+ destinationType: destType,
28
+ progress: true
29
+ });
30
+ },
31
+ 'click .g-open-browser': '_openBrowser'
32
+ },
33
+
34
+ initialize: function (settings) {
35
+ this._browserWidgetView = new BrowserWidget({
36
+ parentView: this,
37
+ titleText: 'Destination',
38
+ helpText: 'Browse to a location to select it as the destination.',
39
+ submitText: 'Select Destination',
40
+ validate: function (model) {
41
+ const isValid = $.Deferred();
42
+ if (!model) {
43
+ isValid.reject('Please select a valid root.');
44
+ } else {
45
+ isValid.resolve();
46
+ }
47
+ return isValid.promise();
48
+ }
49
+ });
50
+ this.listenTo(this._browserWidgetView, 'g:saved', function (val) {
51
+ this.$('#g-s3-import-dest-id').val(val.id);
52
+ this.$('#g-s3-import-dest-type').val(val.get('_modelType'));
53
+ restRequest({
54
+ url: `resource/${val.id}/path`,
55
+ method: 'GET',
56
+ data: { type: val.get('_modelType') }
57
+ }).done((result) => {
58
+ // Only add the resource path if the value wasn't altered
59
+ if (this.$('#g-s3-import-dest-id').val() === val.id) {
60
+ this.$('#g-s3-import-dest-id').val(`${val.id} (${result})`);
61
+ }
62
+ });
63
+ });
64
+ this.assetstore = settings.assetstore;
65
+ this.render();
66
+ },
67
+
68
+ render: function () {
69
+ this.$el.html(S3ImportTemplate({
70
+ assetstore: this.assetstore
71
+ }));
72
+ return this;
73
+ },
74
+
75
+ _openBrowser: function () {
76
+ this._browserWidgetView.setElement($('#g-dialog-container')).render();
77
+ }
78
+ });
79
+
80
+ export default S3ImportView;
@@ -0,0 +1,162 @@
1
+ import _ from 'underscore';
2
+
3
+ import View from '@girder/core/views/View';
4
+ import { restRequest } from '@girder/core/rest';
5
+ import SearchPaginateWidget from '@girder/core/views/widgets/SearchPaginateWidget';
6
+ import SearchFieldWidget from '@girder/core/views/widgets/SearchFieldWidget';
7
+
8
+ import SearchResultsTemplate from '@girder/core/templates/body/searchResults.pug';
9
+ import SearchResultsTypeTemplate from '@girder/core/templates/body/searchResultsType.pug';
10
+ import '@girder/core/stylesheets/body/searchResultsList.styl';
11
+
12
+ /**
13
+ * This view display all the search results by instantiating a subview
14
+ * per each type found.
15
+ */
16
+ var SearchResultsView = View.extend({
17
+ initialize: function (settings) {
18
+ this._query = settings.query || '';
19
+ this._mode = settings.mode || 'text';
20
+
21
+ this._sizeOneElement = 28;
22
+ this.pageLimit = 10;
23
+
24
+ this._request = restRequest({
25
+ url: 'resource/search',
26
+ data: {
27
+ q: this._query,
28
+ mode: this._mode,
29
+ types: JSON.stringify(SearchFieldWidget.getModeTypes(this._mode)),
30
+ limit: this.pageLimit
31
+ }
32
+ });
33
+ this.render();
34
+ },
35
+
36
+ /**
37
+ * Return a consistent and semantically-meaningful type ordering.
38
+ */
39
+ _getTypeOrdering: function (resultTypes) {
40
+ // This ordering places hopefully-more relevant types first
41
+ const builtinOrdering = ['collection', 'folder', 'item', 'group', 'user'];
42
+
43
+ // _.intersection will use the ordering of its first argument
44
+ const orderedKnownTypes = _.intersection(builtinOrdering, resultTypes);
45
+ const orderedUnknownTypes = _.difference(resultTypes, builtinOrdering).sort();
46
+
47
+ return orderedKnownTypes.concat(orderedUnknownTypes);
48
+ },
49
+
50
+ render: function () {
51
+ this.$el.html(SearchResultsTemplate({
52
+ query: this._query
53
+ }));
54
+ this._subviews = {};
55
+
56
+ this._request
57
+ .done((results) => {
58
+ this.$('.g-search-pending').hide();
59
+
60
+ const resultTypes = _.keys(results);
61
+ const orderedTypes = this._getTypeOrdering(resultTypes);
62
+ _.each(orderedTypes, (type) => {
63
+ if (results[type].length) {
64
+ this._subviews[type] = new SearchResultsTypeView({
65
+ parentView: this,
66
+ query: this._query,
67
+ mode: this._mode,
68
+ type: type,
69
+ limit: this.pageLimit,
70
+ initResults: results[type],
71
+ sizeOneElement: this._sizeOneElement
72
+ })
73
+ .render();
74
+ this._subviews[type].$el
75
+ .appendTo(this.$('.g-search-results-container'));
76
+ }
77
+ });
78
+
79
+ if (_.isEmpty(this._subviews)) {
80
+ this.$('.g-search-no-results').show();
81
+ }
82
+ });
83
+
84
+ return this;
85
+ }
86
+ });
87
+
88
+ /**
89
+ * This subview display all the search results for one type.
90
+ * It also contain a pagination widget that provide a consistent widget
91
+ * for iterating amongst pages of a list of search results.
92
+ */
93
+ var SearchResultsTypeView = View.extend({
94
+ className: 'g-search-results-type-container',
95
+
96
+ initialize: function (settings) {
97
+ this._query = settings.query;
98
+ this._mode = settings.mode;
99
+ this._type = settings.type;
100
+ this._initResults = settings.initResults || [];
101
+ this._pageLimit = settings.limit || 10;
102
+ this._sizeOneElement = settings.sizeOneElement || 30;
103
+
104
+ this._paginateWidget = new SearchPaginateWidget({
105
+ parentView: this,
106
+ type: this._type,
107
+ query: this._query,
108
+ mode: this._mode,
109
+ limit: this._pageLimit
110
+ })
111
+ .on('g:changed', () => {
112
+ this._results = this._paginateWidget.results;
113
+ this.render();
114
+ });
115
+
116
+ this._results = this._initResults;
117
+ },
118
+
119
+ _getTypeName: function (type) {
120
+ const names = {
121
+ collection: 'Collections',
122
+ group: 'Groups',
123
+ user: 'Users',
124
+ folder: 'Folders',
125
+ item: 'Items'
126
+ };
127
+ return names[type] || type;
128
+ },
129
+
130
+ _getTypeIcon: function (type) {
131
+ const icons = {
132
+ user: 'user',
133
+ group: 'users',
134
+ collection: 'sitemap',
135
+ folder: 'folder',
136
+ item: 'doc-text-inv'
137
+ };
138
+ return icons[type] || 'icon-attention-alt';
139
+ },
140
+
141
+ render: function () {
142
+ this.$el.html(SearchResultsTypeTemplate({
143
+ results: this._results,
144
+ collectionName: this._getTypeName(this._type),
145
+ type: this._type,
146
+ icon: this._getTypeIcon(this._type)
147
+ }));
148
+
149
+ /* This size of the results list cannot be known until after the fetch completes. And we don't want to set
150
+ the 'min-height' to the max results size, because we'd frequently have lots of whitespace for short result
151
+ lists. Do not try to move that set in stylesheet.
152
+ */
153
+ this.$('.g-search-results-type').css('min-height', `${this._initResults.length * this._sizeOneElement}px`);
154
+ this._paginateWidget
155
+ .setElement(this.$(`#${this._type}Paginate`))
156
+ .render();
157
+
158
+ return this;
159
+ }
160
+ });
161
+
162
+ export default SearchResultsView;
@@ -0,0 +1,177 @@
1
+ import _ from 'underscore';
2
+
3
+ import AccessWidget from '@girder/core/views/widgets/AccessWidget';
4
+ import View from '@girder/core/views/View';
5
+ import events from '@girder/core/events';
6
+ import { restRequest, cancelRestRequests } from '@girder/core/rest';
7
+ import CollectionCreationPolicyModel from '@girder/core/models/CollectionCreationPolicyModel';
8
+
9
+ import SystemConfigurationTemplate from '@girder/core/templates/body/systemConfiguration.pug';
10
+
11
+ import '@girder/core/stylesheets/body/systemConfig.styl';
12
+
13
+ import 'bootstrap/js/collapse';
14
+ import 'bootstrap/js/transition';
15
+ import 'bootstrap-switch'; // /dist/js/bootstrap-switch.js',
16
+ import 'bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.css';
17
+
18
+ /**
19
+ * The system config page for administrators.
20
+ */
21
+ var SystemConfigurationView = View.extend({
22
+ events: {
23
+ 'submit .g-settings-form': function (event) {
24
+ event.preventDefault();
25
+ this.$('.g-submit-settings').girderEnable(false);
26
+ this.$('#g-settings-error-message').empty();
27
+
28
+ this.$('#g-core-collection-create-policy').val(JSON.stringify(this._covertCollectionCreationPolicy()));
29
+ var settings = _.map(this.settingsKeys, (key) => {
30
+ const element = this.$('#g-' + key.replace(/[_.]/g, '-'));
31
+
32
+ if (_.contains(
33
+ [
34
+ 'core.api_keys',
35
+ 'core.enable_password_login',
36
+ ],
37
+ key
38
+ )) { // booleans via checkboxes
39
+ return {
40
+ key,
41
+ value: element.is(':checked')
42
+ };
43
+ } else { // all other settings use $.fn.val()
44
+ return {
45
+ key,
46
+ value: element.val() || null
47
+ };
48
+ }
49
+ });
50
+
51
+ restRequest({
52
+ method: 'PUT',
53
+ url: 'system/setting',
54
+ data: {
55
+ list: JSON.stringify(settings)
56
+ },
57
+ error: null
58
+ }).done(() => {
59
+ this.$('.g-submit-settings').girderEnable(true);
60
+ events.trigger('g:alert', {
61
+ icon: 'ok',
62
+ text: 'Settings saved.',
63
+ type: 'success',
64
+ timeout: 4000
65
+ });
66
+ }).fail((resp) => {
67
+ this.$('.g-submit-settings').girderEnable(true);
68
+ this.$('#g-settings-error-message').text(resp.responseJSON.message);
69
+ });
70
+ },
71
+ },
72
+
73
+ initialize: function () {
74
+ cancelRestRequests('fetch');
75
+
76
+ var keys = [
77
+ 'core.api_keys',
78
+ 'core.contact_email_address',
79
+ 'core.brand_name',
80
+ 'core.banner_color',
81
+ 'core.privacy_notice',
82
+ 'core.cookie_lifetime',
83
+ 'core.enable_password_login',
84
+ 'core.email_from_address',
85
+ 'core.email_host',
86
+ 'core.registration_policy',
87
+ 'core.email_verification',
88
+ 'core.server_root',
89
+ 'core.smtp_host',
90
+ 'core.smtp.port',
91
+ 'core.smtp.encryption',
92
+ 'core.smtp.username',
93
+ 'core.smtp.password',
94
+ 'core.upload_minimum_chunk_size',
95
+ 'core.cors.allow_origin',
96
+ 'core.cors.allow_methods',
97
+ 'core.cors.allow_headers',
98
+ 'core.add_to_group_policy',
99
+ 'core.collection_create_policy',
100
+ 'core.user_default_folders',
101
+ ];
102
+ this.settingsKeys = keys;
103
+ restRequest({
104
+ url: 'system/setting',
105
+ method: 'GET',
106
+ data: {
107
+ list: JSON.stringify(keys)
108
+ }
109
+ }).done((resp) => {
110
+ this.settings = resp;
111
+ this.render();
112
+ });
113
+ },
114
+
115
+ render: function () {
116
+ this.$el.html(SystemConfigurationTemplate({
117
+ settings: this.settings,
118
+ JSON: window.JSON
119
+ }));
120
+
121
+ var enableCollectionCreationPolicy = this.settings['core.collection_create_policy'] ? this.settings['core.collection_create_policy'].open : false;
122
+
123
+ this.$('.g-setting-switch')
124
+ .bootstrapSwitch()
125
+ .bootstrapSwitch('state', enableCollectionCreationPolicy)
126
+ .off('switchChange.bootstrapSwitch')
127
+ .on('switchChange.bootstrapSwitch', (event, state) => {
128
+ if (state) {
129
+ this._renderCollectionCreationPolicyAccessWidget();
130
+ } else {
131
+ this.accessWidget.destroy();
132
+ this.accessWidget = null;
133
+ }
134
+ });
135
+
136
+ if (enableCollectionCreationPolicy) {
137
+ this._renderCollectionCreationPolicyAccessWidget();
138
+ }
139
+
140
+ return this;
141
+ },
142
+
143
+ _renderCollectionCreationPolicyAccessWidget: function () {
144
+ var collectionCreationPolicyModel = new CollectionCreationPolicyModel();
145
+
146
+ this.accessWidget = new AccessWidget({
147
+ el: this.$('.g-collection-create-policy-container .access-widget-container'),
148
+ modelType: 'collection_creation_policy',
149
+ model: collectionCreationPolicyModel,
150
+ parentView: this,
151
+ modal: false,
152
+ hideRecurseOption: true,
153
+ hideSaveButton: true,
154
+ hidePrivacyEditor: true,
155
+ hideAccessType: true,
156
+ noAccessFlag: true
157
+ });
158
+ },
159
+
160
+ _covertCollectionCreationPolicy: function () {
161
+ // get collection creation policy from AccessWidget and format the result properly
162
+ var settingValue = null;
163
+ if (this.$('.g-setting-switch').bootstrapSwitch('state') && this.accessWidget) {
164
+ settingValue = { open: this.$('.g-setting-switch').bootstrapSwitch('state') };
165
+ var accessList = this.accessWidget.getAccessList();
166
+ _.each(_.keys(accessList), (key) => {
167
+ settingValue[key] = _.pluck(accessList[key], 'id');
168
+ });
169
+ } else {
170
+ settingValue = this.settings['core.collection_create_policy'];
171
+ settingValue.open = false;
172
+ }
173
+ return settingValue;
174
+ }
175
+ });
176
+
177
+ export default SystemConfigurationView;
@@ -0,0 +1,179 @@
1
+ import $ from 'jquery';
2
+ import _ from 'underscore';
3
+
4
+ import ApiKeyListWidget from '@girder/core/views/widgets/ApiKeyListWidget';
5
+ import UserOtpManagementWidget from '@girder/core/views/widgets/UserOtpManagementWidget';
6
+ import router from '@girder/core/router';
7
+ import UserModel from '@girder/core/models/UserModel';
8
+ import View from '@girder/core/views/View';
9
+ import { AccessType } from '@girder/core/constants';
10
+ import events from '@girder/core/events';
11
+ import { getCurrentUser } from '@girder/core/auth';
12
+ import { cancelRestRequests } from '@girder/core/rest';
13
+
14
+ import UserAccountTemplate from '@girder/core/templates/body/userAccount.pug';
15
+
16
+ import '@girder/core/stylesheets/body/userAccount.styl';
17
+
18
+ import 'bootstrap/js/tab';
19
+
20
+ /**
21
+ * This is the view for the user account (profile) page.
22
+ */
23
+ var UserAccountView = View.extend({
24
+ events: {
25
+ 'submit #g-user-info-form': function (event) {
26
+ event.preventDefault();
27
+ this.$('#g-user-info-error-msg').empty();
28
+
29
+ var params = {
30
+ email: this.$('#g-email').val(),
31
+ firstName: this.$('#g-firstName').val(),
32
+ lastName: this.$('#g-lastName').val()
33
+ };
34
+
35
+ if (this.$('#g-admin').length > 0) {
36
+ params.admin = this.$('#g-admin').is(':checked');
37
+ }
38
+
39
+ this.user.set(params);
40
+
41
+ this.user.off('g:error').on('g:error', function (err) {
42
+ var msg = err.responseJSON.message;
43
+ this.$('#g-' + err.responseJSON.field).trigger('focus');
44
+ this.$('#g-user-info-error-msg').text(msg);
45
+ }, this).off('g:saved')
46
+ .on('g:saved', function () {
47
+ events.trigger('g:alert', {
48
+ icon: 'ok',
49
+ text: 'Info saved.',
50
+ type: 'success',
51
+ timeout: 4000
52
+ });
53
+ }, this).save();
54
+ },
55
+ 'submit #g-password-change-form': function (event) {
56
+ event.preventDefault();
57
+ this.$('#g-password-change-error-msg').empty();
58
+
59
+ if (this.$('#g-password-new').val() !==
60
+ this.$('#g-password-retype').val()) {
61
+ this.$('#g-password-change-error-msg').text(
62
+ 'Passwords do not match, try again.'
63
+ );
64
+ this.$('#g-password-retype,#g-password-new').val('');
65
+ this.$('#g-password-new').trigger('focus');
66
+ return;
67
+ }
68
+
69
+ this.user.off('g:error').on('g:error', function (err) {
70
+ var msg = err.responseJSON.message;
71
+ this.$('#g-password-change-error-msg').text(msg);
72
+ }, this).off('g:passwordChanged')
73
+ .on('g:passwordChanged', function () {
74
+ events.trigger('g:alert', {
75
+ icon: 'ok',
76
+ text: 'Password changed.',
77
+ type: 'success',
78
+ timeout: 4000
79
+ });
80
+ this.$('#g-password-old,#g-password-new,#g-password-retype').val('');
81
+ }, this);
82
+
83
+ // here and in the template, an admin user who wants to change their
84
+ // own password is intentionally forced to re-enter their old
85
+ // password
86
+ if (this.isCurrentUser) {
87
+ this.user.changePassword(
88
+ this.$('#g-password-old').val(),
89
+ this.$('#g-password-new').val()
90
+ );
91
+ } else {
92
+ this.user.adminChangePassword(this.$('#g-password-new').val());
93
+ }
94
+ }
95
+ },
96
+
97
+ initialize: function (settings) {
98
+ this.tab = settings.tab || 'info';
99
+ this.user = settings.user || getCurrentUser();
100
+ this.isCurrentUser = getCurrentUser() &&
101
+ settings.user.id === getCurrentUser().id;
102
+
103
+ this.model = this.user;
104
+ this.temporary = settings.temporary;
105
+
106
+ if (!this.user || this.user.getAccessLevel() < AccessType.WRITE) {
107
+ router.navigate('', { trigger: true });
108
+ return;
109
+ }
110
+
111
+ cancelRestRequests('fetch');
112
+
113
+ this.apiKeyListWidget = new ApiKeyListWidget({
114
+ user: this.user,
115
+ parentView: this
116
+ });
117
+
118
+ this.userOtpManagementWidget = new UserOtpManagementWidget({
119
+ user: this.user,
120
+ parentView: this
121
+ });
122
+
123
+ this.render();
124
+ },
125
+
126
+ render: function () {
127
+ if (getCurrentUser() === null) {
128
+ router.navigate('', { trigger: true });
129
+ return;
130
+ }
131
+
132
+ this.$el.html(UserAccountTemplate({
133
+ user: this.model,
134
+ isCurrentUser: this.isCurrentUser,
135
+ getCurrentUser: getCurrentUser,
136
+ temporaryToken: this.temporary
137
+ }));
138
+
139
+ _.each($('.g-account-tabs>li>a'), function (el) {
140
+ var tabLink = $(el);
141
+ tabLink.tab().on('shown.bs.tab', (e) => {
142
+ this.tab = $(e.currentTarget).attr('name');
143
+ router.navigate('useraccount/' + this.model.id + '/' + this.tab);
144
+
145
+ if (this.tab === 'apikeys') {
146
+ this.apiKeyListWidget.setElement(
147
+ this.$('.g-api-keys-list-container')).render();
148
+ } else if (this.tab === 'otp') {
149
+ this.userOtpManagementWidget
150
+ .setElement(this.$('.g-account-otp-container'))
151
+ .render();
152
+ }
153
+ });
154
+
155
+ if (tabLink.attr('name') === this.tab) {
156
+ tabLink.tab('show');
157
+ }
158
+ }, this);
159
+
160
+ return this;
161
+ }
162
+ }, {
163
+ /**
164
+ * Helper function for fetching the user by id, then render the view.
165
+ */
166
+ fetchAndInit: function (id, tab) {
167
+ var user = new UserModel();
168
+ user.set({ _id: id }).on('g:fetched', function () {
169
+ events.trigger('g:navigateTo', UserAccountView, {
170
+ user: user,
171
+ tab: tab
172
+ });
173
+ }, this).on('g:error', function () {
174
+ router.navigate('', { trigger: true });
175
+ }, this).fetch();
176
+ }
177
+ });
178
+
179
+ export default UserAccountView;