@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,427 @@
1
+ import $ from 'jquery';
2
+ import _ from 'underscore';
3
+ // Bootstrap tooltip is required by popover
4
+ import 'bootstrap/js/tooltip';
5
+ import 'bootstrap/js/popover';
6
+
7
+ import accessEditorNonModalTemplate from '@girder/core/templates/widgets/accessEditorNonModal.pug';
8
+ import accessEditorTemplate from '@girder/core/templates/widgets/accessEditor.pug';
9
+ import accessEntryTemplate from '@girder/core/templates/widgets/accessEntry.pug';
10
+ import GroupModel from '@girder/core/models/GroupModel';
11
+ import LoadingAnimation from '@girder/core/views/widgets/LoadingAnimation';
12
+ import SearchFieldWidget from '@girder/core/views/widgets/SearchFieldWidget';
13
+ import UserModel from '@girder/core/models/UserModel';
14
+ import View from '@girder/core/views/View';
15
+ import { getCurrentUser } from '@girder/core/auth';
16
+ import { AccessType } from '@girder/core/constants';
17
+ import { handleClose, handleOpen } from '@girder/core/dialog';
18
+ import { restRequest } from '@girder/core/rest';
19
+
20
+ import '@girder/core/stylesheets/widgets/accessWidget.styl';
21
+
22
+ import '@girder/core/utilities/jquery/girderModal';
23
+
24
+ /**
25
+ * This view allows users to see and control access on a resource.
26
+ */
27
+ var AccessWidget = View.extend({
28
+ events: {
29
+ 'click button.g-save-access-list': function (e) {
30
+ $(e.currentTarget).girderEnable(false);
31
+ this.saveAccessList();
32
+ },
33
+ 'click .g-close-flags-popover': function (e) {
34
+ $(e.currentTarget).parents('.g-access-action-container')
35
+ .find('.g-action-manage-flags').popover('hide');
36
+ },
37
+ 'click .g-close-public-flags-popover': function (e) {
38
+ $(e.currentTarget).parents('.g-public-container')
39
+ .find('.g-action-manage-public-flags').popover('hide');
40
+ },
41
+ 'click a.g-action-remove-access': 'removeAccessEntry',
42
+ 'change .g-public-container .radio input': 'privacyChanged',
43
+ 'change .g-flag-checkbox': '_toggleAccessFlag',
44
+ 'change .g-public-flag-checkbox': '_togglePublicAccessFlag'
45
+ },
46
+
47
+ /**
48
+ * @param settings.modelType {string} Display name for the resource type
49
+ * being edited.
50
+ * @param [settings.hideRecurseOption=false] {bool} Whether to hide the recursive
51
+ * propagation setting widgets.
52
+ * @param [settings.hideSaveButton=false] {bool} Whether to hide the "save"
53
+ * button in non-modal view. This allows for users of this widget to
54
+ * provide their own save button elsewhere on the page that can call the
55
+ * saveAccessList() method of this widget when pressed.
56
+ * @param [settings.modal=true] {bool} Whether to render the widget as a
57
+ * modal dialog or not.
58
+ */
59
+ initialize: function (settings) {
60
+ this.modelType = settings.modelType;
61
+ this.hideRecurseOption = settings.hideRecurseOption || false;
62
+ this.hideSaveButton = settings.hideSaveButton || false;
63
+ this.hidePrivacyEditor = settings.hidePrivacyEditor || false;
64
+ this.hideAccessType = settings.hideAccessType || false;
65
+ this.noAccessFlag = settings.noAccessFlag || false;
66
+ this.modal = _.has(settings, 'modal') ? settings.modal : true;
67
+ this.currentUser = getCurrentUser();
68
+ this.isAdmin = !!(this.currentUser && this.currentUser.get('admin'));
69
+ this.searchWidget = new SearchFieldWidget({
70
+ placeholder: 'Start typing a name...',
71
+ noResultsPage: true,
72
+ modes: ['prefix', 'text'],
73
+ types: ['group', 'user'],
74
+ parentView: this
75
+ }).on('g:resultClicked', this.addEntry, this);
76
+
77
+ var flagListPromise = null;
78
+ if (!this.noAccessFlag) {
79
+ flagListPromise = restRequest({
80
+ url: 'system/access_flag'
81
+ }).done((resp) => {
82
+ this.flagList = resp;
83
+ });
84
+ } else {
85
+ this.flagList = [];
86
+ }
87
+
88
+ $.when(
89
+ flagListPromise,
90
+ this.model.fetchAccess()
91
+ ).done(() => {
92
+ this.render();
93
+ });
94
+ },
95
+
96
+ render: function () {
97
+ if (!this.model.get('access') || !this.flagList) {
98
+ new LoadingAnimation({
99
+ el: this.$el,
100
+ parentView: this
101
+ }).render();
102
+ return;
103
+ }
104
+
105
+ var closeFunction;
106
+ if (this.modal && this.modelType === 'folder') {
107
+ handleOpen('folderaccess');
108
+ closeFunction = function () {
109
+ handleClose('folderaccess');
110
+ };
111
+ } else if (this.modal) {
112
+ handleOpen('access');
113
+ closeFunction = function () {
114
+ handleClose('access');
115
+ };
116
+ }
117
+
118
+ var template = this.modal ? accessEditorTemplate : accessEditorNonModalTemplate;
119
+
120
+ this.$el.html(template({
121
+ _,
122
+ model: this.model,
123
+ modelType: this.modelType,
124
+ publicFlag: this.model.get('public'),
125
+ publicFlags: this.model.get('publicFlags'),
126
+ hideRecurseOption: this.hideRecurseOption,
127
+ hideSaveButton: this.hideSaveButton,
128
+ hidePrivacyEditor: this.hidePrivacyEditor,
129
+ flagList: this.flagList,
130
+ isAdmin: this.isAdmin
131
+ }));
132
+
133
+ if (this.modal) {
134
+ this.$el.girderModal(this).on('hidden.bs.modal', closeFunction);
135
+ }
136
+
137
+ _.each(this.model.get('access').groups, function (groupAccess) {
138
+ this.$('#g-ac-list-groups').append(accessEntryTemplate({
139
+ _,
140
+ accessTypes: AccessType,
141
+ type: 'group',
142
+ flagList: this.flagList,
143
+ isAdmin: this.isAdmin,
144
+ hideAccessType: this.hideAccessType,
145
+ noAccessFlag: this.noAccessFlag,
146
+ entry: _.extend(groupAccess, {
147
+ title: groupAccess.name,
148
+ subtitle: groupAccess.description
149
+ })
150
+ }));
151
+ }, this);
152
+
153
+ _.each(this.model.get('access').users, function (userAccess) {
154
+ this.$('#g-ac-list-users').append(accessEntryTemplate({
155
+ _,
156
+ accessTypes: AccessType,
157
+ type: 'user',
158
+ flagList: this.flagList,
159
+ isAdmin: this.isAdmin,
160
+ hideAccessType: this.hideAccessType,
161
+ noAccessFlag: this.noAccessFlag,
162
+ entry: _.extend(userAccess, {
163
+ title: userAccess.name,
164
+ subtitle: userAccess.login
165
+ })
166
+ }));
167
+ }, this);
168
+ this._makeTooltips();
169
+
170
+ this.searchWidget.setElement(this.$('.g-search-field-container')).render();
171
+
172
+ this.privacyChanged();
173
+
174
+ return this;
175
+ },
176
+
177
+ _makeTooltips: function () {
178
+ // Re-binding popovers actually breaks them, so we make sure to
179
+ // only bind ones that aren't already bound.
180
+ _.each(this.$('.g-action-manage-flags'), (el) => {
181
+ if (!$(el).data('bs.popover')) {
182
+ $(el).popover({
183
+ trigger: 'manual',
184
+ placement: 'left',
185
+ viewport: {
186
+ selector: 'body',
187
+ padding: 10
188
+ },
189
+ content: function () {
190
+ return $(this).parent().find('.g-flags-popover-container').html();
191
+ },
192
+ html: true,
193
+ sanitize: false
194
+ }).on('click', function () {
195
+ $(this).popover('toggle');
196
+ });
197
+ }
198
+ });
199
+
200
+ // Re-binding popovers actually breaks them, so we make sure to
201
+ // only bind ones that aren't already bound.
202
+ _.each(this.$('.g-action-manage-public-flags'), (el) => {
203
+ if (!$(el).data('bs.popover')) {
204
+ $(el).popover({
205
+ trigger: 'manual',
206
+ placement: 'right',
207
+ viewport: {
208
+ selector: 'body',
209
+ padding: 10
210
+ },
211
+ content: function () {
212
+ return $(this).parent().find('.g-public-flags-popover-container').html();
213
+ },
214
+ html: true,
215
+ sanitize: false
216
+ }).on('click', function () {
217
+ $(this).popover('toggle');
218
+ });
219
+ }
220
+ });
221
+ },
222
+
223
+ /**
224
+ * Add a new user or group entry to the access control list UI. If the
225
+ * given user or group already has an entry there, this does nothing.
226
+ */
227
+ addEntry: function (entry) {
228
+ this.searchWidget.resetState();
229
+ if (entry.type === 'user') {
230
+ this._addUserEntry(entry);
231
+ } else if (entry.type === 'group') {
232
+ this._addGroupEntry(entry);
233
+ }
234
+ },
235
+
236
+ _addUserEntry: function (entry) {
237
+ var exists = false;
238
+ _.every(this.$('.g-user-access-entry'), function (el) {
239
+ if ($(el).attr('resourceid') === entry.id) {
240
+ exists = true;
241
+ }
242
+ return !exists;
243
+ }, this);
244
+
245
+ if (!exists) {
246
+ var model = new UserModel();
247
+ model.set('_id', entry.id).on('g:fetched', function () {
248
+ this.$('#g-ac-list-users').append(accessEntryTemplate({
249
+ _,
250
+ accessTypes: AccessType,
251
+ type: 'user',
252
+ entry: {
253
+ title: model.name(),
254
+ subtitle: model.get('login'),
255
+ id: entry.id,
256
+ level: AccessType.READ
257
+ },
258
+ isAdmin: this.isAdmin,
259
+ hideAccessType: this.hideAccessType,
260
+ noAccessFlag: this.noAccessFlag,
261
+ flagList: this.flagList
262
+ }));
263
+ this._makeTooltips();
264
+ }, this).fetch();
265
+ }
266
+ },
267
+
268
+ _addGroupEntry: function (entry) {
269
+ var exists = false;
270
+ _.every(this.$('.g-group-access-entry'), function (el) {
271
+ if ($(el).attr('resourceid') === entry.id) {
272
+ exists = true;
273
+ }
274
+ return !exists;
275
+ }, this);
276
+
277
+ if (!exists) {
278
+ var model = new GroupModel();
279
+ model.set('_id', entry.id).on('g:fetched', function () {
280
+ this.$('#g-ac-list-groups').append(accessEntryTemplate({
281
+ _,
282
+ accessTypes: AccessType,
283
+ type: 'group',
284
+ entry: {
285
+ title: model.name(),
286
+ subtitle: model.get('description'),
287
+ id: entry.id,
288
+ level: AccessType.READ
289
+ },
290
+ isAdmin: this.isAdmin,
291
+ hideAccessType: this.hideAccessType,
292
+ noAccessFlag: this.noAccessFlag,
293
+ flagList: this.flagList
294
+ }));
295
+
296
+ this._makeTooltips();
297
+ }, this).fetch();
298
+ }
299
+ },
300
+
301
+ saveAccessList: function () {
302
+ var acList = this.getAccessList();
303
+
304
+ var publicFlags = _.map(this.$('.g-public-flag-checkbox:checked'), (checkbox) => {
305
+ return $(checkbox).attr('flag');
306
+ });
307
+
308
+ this.model.set({
309
+ access: acList,
310
+ public: this.$('#g-access-public').is(':checked'),
311
+ publicFlags: publicFlags
312
+ });
313
+
314
+ var recurse = this.$('#g-apply-recursive').is(':checked');
315
+
316
+ this.model.off('g:accessListSaved', null, this)
317
+ .on('g:accessListSaved', function () {
318
+ if (this.modal) {
319
+ this.$el.modal('hide');
320
+ }
321
+
322
+ this.trigger('g:accessListSaved', {
323
+ recurse: recurse
324
+ });
325
+ }, this).updateAccess({
326
+ recurse: recurse,
327
+ progress: true
328
+ });
329
+ },
330
+
331
+ getAccessList: function () {
332
+ // Rebuild the access list
333
+ var acList = {
334
+ users: [],
335
+ groups: []
336
+ };
337
+
338
+ _.each(this.$('.g-group-access-entry'), function (el) {
339
+ var $el = $(el);
340
+ acList.groups.push({
341
+ name: $el.find('.g-desc-title').html(),
342
+ id: $el.attr('resourceid'),
343
+ level: parseInt(
344
+ $el.find('.g-access-col-right>select').val() || 0,
345
+ 10
346
+ ),
347
+ flags: _.map($el.find('.g-flag-checkbox:checked'),
348
+ (checkbox) => $(checkbox).attr('flag')
349
+ )
350
+ });
351
+ }, this);
352
+
353
+ _.each(this.$('.g-user-access-entry'), function (el) {
354
+ var $el = $(el);
355
+ acList.users.push({
356
+ login: $el.find('.g-desc-subtitle').html(),
357
+ name: $el.find('.g-desc-title').html(),
358
+ id: $el.attr('resourceid'),
359
+ level: parseInt(
360
+ $el.find('.g-access-col-right>select').val() || 0,
361
+ 10
362
+ ),
363
+ flags: _.map($el.find('.g-flag-checkbox:checked'),
364
+ (checkbox) => $(checkbox).attr('flag')
365
+ )
366
+ });
367
+ }, this);
368
+
369
+ return acList;
370
+ },
371
+
372
+ removeAccessEntry: function (event) {
373
+ var sel = '.g-user-access-entry,.g-group-access-entry';
374
+ $(event.currentTarget).parents(sel).remove();
375
+ },
376
+
377
+ privacyChanged: function () {
378
+ this.$('.g-public-container .radio').removeClass('g-selected');
379
+ var selected = this.$('.g-public-container .radio input:checked');
380
+ selected.parents('.radio').addClass('g-selected');
381
+
382
+ if (this.$('#g-access-public').is(':checked')) {
383
+ this.$('.g-action-manage-public-flags').removeClass('hide');
384
+ } else {
385
+ this.$('.g-action-manage-public-flags').addClass('hide');
386
+ }
387
+ },
388
+
389
+ _toggleAccessFlag: function (e) {
390
+ var el = $(e.currentTarget),
391
+ type = el.attr('resourcetype'),
392
+ id = el.attr('resourceid'),
393
+ flag = el.attr('flag'),
394
+ container = this.$(`.g-flags-popover-container[resourcetype='${type}'][resourceid='${id}']`);
395
+
396
+ // Since we clicked in a cloned popover element, we must apply this
397
+ // change within the original element as well.
398
+ container.find(`.g-flag-checkbox[flag="${flag}"]`)
399
+ .attr('checked', el.is(':checked') ? 'checked' : null);
400
+ this._updateFlagCount(container, '.g-flag-checkbox');
401
+ },
402
+
403
+ _togglePublicAccessFlag: function (e) {
404
+ var el = $(e.currentTarget),
405
+ flag = el.attr('flag'),
406
+ container = this.$('.g-public-flags-popover-container');
407
+
408
+ // Since we clicked in a cloned popover element, we must apply this
409
+ // change within the original element as well.
410
+ container.find(`.g-public-flag-checkbox[flag="${flag}"]`)
411
+ .attr('checked', el.is(':checked') ? 'checked' : null);
412
+ this._updateFlagCount(container, '.g-public-flag-checkbox');
413
+ },
414
+
415
+ _updateFlagCount: function (container, sel) {
416
+ const nChecked = container.find(`${sel}[checked="checked"]`).length;
417
+ const countEl = container.parent().find('.g-flag-count-indicator');
418
+ countEl.text(nChecked);
419
+ if (nChecked) {
420
+ countEl.removeClass('hide');
421
+ } else {
422
+ countEl.addClass('hide');
423
+ }
424
+ }
425
+ });
426
+
427
+ export default AccessWidget;
@@ -0,0 +1,140 @@
1
+ import $ from 'jquery';
2
+ import moment from 'moment';
3
+ // Bootstrap tooltip is required by popover
4
+ import 'bootstrap/js/tooltip';
5
+ import 'bootstrap/js/popover';
6
+
7
+ import ApiKeyCollection from '@girder/core/collections/ApiKeyCollection';
8
+ import EditApiKeyWidget from '@girder/core/views/widgets/EditApiKeyWidget';
9
+ import PaginateWidget from '@girder/core/views/widgets/PaginateWidget';
10
+ import View from '@girder/core/views/View';
11
+ import { confirm } from '@girder/core/dialog';
12
+ import events from '@girder/core/events';
13
+
14
+ import ApiKeyListTemplate from '@girder/core/templates/widgets/apiKeyList.pug';
15
+
16
+ var ApiKeyListWidget = View.extend({
17
+ events: {
18
+ 'click .g-api-key-toggle-active': function (e) {
19
+ var apiKey = this._getModelFromEvent(e);
20
+ var toggleActive = () => {
21
+ apiKey.once('g:setActive', function () {
22
+ this.render();
23
+ }, this).setActive(!apiKey.get('active'));
24
+ };
25
+
26
+ if (apiKey.get('active')) {
27
+ confirm({
28
+ text: 'Deactivating this API key will delete any existing tokens ' +
29
+ 'created with it, and will not be usable until it is activated ' +
30
+ 'again. Are you sure you want to deactivate it?',
31
+ yesText: 'Yes',
32
+ yesClass: 'btn-warning',
33
+ escapedHtml: true,
34
+ confirmCallback: toggleActive
35
+ });
36
+ } else {
37
+ toggleActive();
38
+ }
39
+ },
40
+
41
+ 'click .g-api-key-new': function () {
42
+ this._renderEditWidget();
43
+ },
44
+
45
+ 'click .g-api-key-edit': function (e) {
46
+ var apiKey = this._getModelFromEvent(e);
47
+ this._renderEditWidget(apiKey);
48
+ },
49
+
50
+ 'click .g-api-key-delete': function (e) {
51
+ var apiKey = this._getModelFromEvent(e);
52
+
53
+ confirm({
54
+ text: 'Are you sure you want to delete the API key <b>' +
55
+ apiKey.escape('name') + '</b>? Any client applications using ' +
56
+ 'this key will no longer be able to authenticate.',
57
+ yesText: 'Delete',
58
+ escapedHtml: true,
59
+ confirmCallback: () => {
60
+ apiKey.on('g:deleted', function () {
61
+ events.trigger('g:alert', {
62
+ icon: 'ok',
63
+ text: 'API key deleted.',
64
+ type: 'success',
65
+ timeout: 3000
66
+ });
67
+ this.render();
68
+ }, this).destroy();
69
+ }
70
+ });
71
+ }
72
+ },
73
+
74
+ /**
75
+ * A widget for listing and editing API keys for a user.
76
+ *
77
+ * @param settings.user {UserModel} The user whose keys to show.
78
+ */
79
+ initialize: function (settings) {
80
+ this.model = settings.user;
81
+ this.fetched = false;
82
+
83
+ this.collection = new ApiKeyCollection();
84
+ this.collection.on('g:changed', function () {
85
+ this.fetched = true;
86
+ this.render();
87
+ this.trigger('g:changed');
88
+ }, this).fetch({
89
+ userId: this.model.id
90
+ });
91
+
92
+ this.paginateWidget = new PaginateWidget({
93
+ collection: this.collection,
94
+ parentView: this
95
+ });
96
+ },
97
+
98
+ render: function () {
99
+ if (!this.fetched) {
100
+ return;
101
+ }
102
+
103
+ this.$el.html(ApiKeyListTemplate({
104
+ apiKeys: this.collection.toArray(),
105
+ moment: moment
106
+ }));
107
+
108
+ this.$('.g-show-api-key').popover({
109
+ container: this.$('.g-api-key-table'),
110
+ placement: 'top'
111
+ });
112
+
113
+ this.paginateWidget.setElement(this.$('.g-paginate-container')).render();
114
+
115
+ return this;
116
+ },
117
+
118
+ _getModelFromEvent: function (e) {
119
+ var cid = $(e.currentTarget).parents('.g-api-key-container').attr('cid');
120
+ return this.collection.get(cid);
121
+ },
122
+
123
+ _renderEditWidget: function (apiKey) {
124
+ if (!this.editApiKeyWidget) {
125
+ this.editApiKeyWidget = new EditApiKeyWidget({
126
+ el: $('#g-dialog-container'),
127
+ parentView: this
128
+ }).on('g:saved', function (model) {
129
+ if (!this.collection.get(model.cid)) {
130
+ this.collection.add(model);
131
+ }
132
+ this.render();
133
+ }, this);
134
+ }
135
+ this.editApiKeyWidget.model = apiKey || null;
136
+ this.editApiKeyWidget.render();
137
+ }
138
+ });
139
+
140
+ export default ApiKeyListWidget;