@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,508 @@
1
+ import $ from 'jquery';
2
+ import _ from 'underscore';
3
+
4
+ import View from '@girder/core/views/View';
5
+ import { AccessType } from '@girder/core/constants';
6
+ import { confirm } from '@girder/core/dialog';
7
+ import events from '@girder/core/events';
8
+ import { localeSort } from '@girder/core/misc';
9
+
10
+ import JsonMetadatumEditWidgetTemplate from '@girder/core/templates/widgets/jsonMetadatumEditWidget.pug';
11
+ import JsonMetadatumViewTemplate from '@girder/core/templates/widgets/jsonMetadatumView.pug';
12
+ import MetadataWidgetTemplate from '@girder/core/templates/widgets/metadataWidget.pug';
13
+ import MetadatumEditWidgetTemplate from '@girder/core/templates/widgets/metadatumEditWidget.pug';
14
+ import MetadatumViewTemplate from '@girder/core/templates/widgets/metadatumView.pug';
15
+
16
+ import '@girder/core/stylesheets/widgets/metadataWidget.styl';
17
+
18
+ import JSONEditor from 'jsoneditor/dist/jsoneditor.js'; // can't 'jsoneditor'
19
+ import 'jsoneditor/dist/jsoneditor.css';
20
+
21
+ import 'bootstrap/js/dropdown';
22
+
23
+ var MetadatumWidget = View.extend({
24
+ className: 'g-widget-metadata-row',
25
+
26
+ events: {
27
+ 'click .g-widget-metadata-edit-button': 'editMetadata'
28
+ },
29
+
30
+ initialize: function (settings) {
31
+ if (!_.has(this.parentView.modes, settings.mode)) {
32
+ throw new Error('Unsupported metadatum mode ' + settings.mode + ' detected.');
33
+ }
34
+
35
+ this.mode = settings.mode;
36
+ this.key = settings.key;
37
+ this.value = settings.value;
38
+ this.accessLevel = settings.accessLevel;
39
+ this.parentView = settings.parentView;
40
+ this.fieldName = settings.fieldName;
41
+ this.apiPath = settings.apiPath;
42
+ this.onMetadataEdited = settings.onMetadataEdited;
43
+ this.onMetadataAdded = settings.onMetadataAdded;
44
+ },
45
+
46
+ _validate: function (from, to, value) {
47
+ var newMode = this.parentView.modes[to];
48
+
49
+ if (_.has(newMode, 'validation') &&
50
+ _.has(newMode.validation, 'from') &&
51
+ _.has(newMode.validation.from, from)) {
52
+ var validate = newMode.validation.from[from][0];
53
+ var msg = newMode.validation.from[from][1];
54
+
55
+ if (!validate(value)) {
56
+ events.trigger('g:alert', {
57
+ text: msg,
58
+ type: 'warning'
59
+ });
60
+ return false;
61
+ }
62
+ }
63
+
64
+ return true;
65
+ },
66
+
67
+ // @todo too much duplication with editMetadata
68
+ toggleEditor: function (event, newEditorMode, existingEditor, overrides) {
69
+ var fromEditorMode = (existingEditor instanceof JsonMetadatumEditWidget) ? 'json' : 'simple';
70
+ var newValue = (overrides || {}).value || existingEditor.$el.attr('g-value');
71
+ if (!this._validate(fromEditorMode, newEditorMode, newValue)) {
72
+ return;
73
+ }
74
+
75
+ var row = existingEditor.$el;
76
+ existingEditor.destroy();
77
+ row.addClass('editing').empty();
78
+
79
+ var opts = _.extend({
80
+ el: row,
81
+ item: this.parentView.item,
82
+ key: row.attr('g-key'),
83
+ value: row.attr('g-value'),
84
+ accessLevel: this.accessLevel,
85
+ newDatum: false,
86
+ parentView: this,
87
+ fieldName: this.fieldName,
88
+ apiPath: this.apiPath,
89
+ onMetadataEdited: this.onMetadataEdited,
90
+ onMetadataAdded: this.onMetadataAdded
91
+ }, overrides || {});
92
+
93
+ this.parentView.modes[newEditorMode].editor(opts).render();
94
+ },
95
+
96
+ editMetadata: function () {
97
+ this.$el.addClass('editing');
98
+ this.$el.empty();
99
+
100
+ var opts = {
101
+ item: this.parentView.item,
102
+ key: this.$el.attr('g-key'),
103
+ value: this.$el.attr('g-value'),
104
+ accessLevel: this.accessLevel,
105
+ newDatum: false,
106
+ parentView: this,
107
+ fieldName: this.fieldName,
108
+ apiPath: this.apiPath,
109
+ onMetadataEdited: this.onMetadataEdited,
110
+ onMetadataAdded: this.onMetadataAdded
111
+ };
112
+
113
+ // If they're trying to open false, null, 6, etc which are not stored as strings
114
+ if (this.mode === 'json') {
115
+ try {
116
+ var jsonValue = JSON.parse(this.$el.attr('g-value'));
117
+
118
+ if (jsonValue !== undefined && !_.isObject(jsonValue)) {
119
+ opts.value = jsonValue;
120
+ }
121
+ } catch (e) {
122
+ // ignore
123
+ }
124
+ }
125
+
126
+ this.parentView.modes[this.mode].editor(opts)
127
+ .render()
128
+ .$el.appendTo(this.$el);
129
+ },
130
+
131
+ render: function () {
132
+ this.$el.attr({
133
+ 'g-key': this.key,
134
+ 'g-value': _.bind(this.parentView.modes[this.mode].displayValue, this)()
135
+ }).empty();
136
+
137
+ this.$el.html(this.parentView.modes[this.mode].template({
138
+ key: this.key,
139
+ value: _.bind(this.parentView.modes[this.mode].displayValue, this)(),
140
+ accessLevel: this.accessLevel,
141
+ AccessType: AccessType
142
+ }));
143
+
144
+ return this;
145
+ }
146
+ });
147
+
148
+ var MetadatumEditWidget = View.extend({
149
+ events: {
150
+ 'click .g-widget-metadata-cancel-button': 'cancelEdit',
151
+ 'click .g-widget-metadata-save-button': 'save',
152
+ 'click .g-widget-metadata-delete-button': 'deleteMetadatum',
153
+ 'click .g-widget-metadata-toggle-button': function (event) {
154
+ var editorType;
155
+ // @todo modal
156
+ // in the future this event will have the new editorType (assuming a dropdown)
157
+ if (this instanceof JsonMetadatumEditWidget) {
158
+ editorType = 'simple';
159
+ } else {
160
+ editorType = 'json';
161
+ }
162
+
163
+ this.parentView.toggleEditor(event, editorType, this, {
164
+ // Save state before toggling editor
165
+ key: this.$el.find('.g-widget-metadata-key-input').val(),
166
+ value: this.getCurrentValue()
167
+ });
168
+ }
169
+ },
170
+
171
+ initialize: function (settings) {
172
+ this.item = settings.item;
173
+ this.key = settings.key || '';
174
+ this.fieldName = settings.fieldName || 'meta';
175
+ this.value = (settings.value !== undefined) ? settings.value : '';
176
+ this.accessLevel = settings.accessLevel;
177
+ this.newDatum = settings.newDatum;
178
+ this.fieldName = settings.fieldName;
179
+ this.apiPath = settings.apiPath;
180
+ this.onMetadataEdited = settings.onMetadataEdited;
181
+ this.onMetadataAdded = settings.onMetadataAdded;
182
+ },
183
+
184
+ editTemplate: MetadatumEditWidgetTemplate,
185
+
186
+ getCurrentValue: function () {
187
+ return this.$el.find('.g-widget-metadata-value-input').val();
188
+ },
189
+
190
+ deleteMetadatum: function (event) {
191
+ event.stopImmediatePropagation();
192
+ const target = $(event.currentTarget);
193
+ var metadataList = target.parent().parent();
194
+ var params = {
195
+ text: 'Are you sure you want to delete the metadatum <b>' +
196
+ _.escape(this.key) + '</b>?',
197
+ escapedHtml: true,
198
+ yesText: 'Delete',
199
+ confirmCallback: () => {
200
+ this.item.removeMetadata(this.key, function () {
201
+ metadataList.remove();
202
+ }, null, {
203
+ field: this.fieldName,
204
+ path: this.apiPath
205
+ });
206
+ }
207
+ };
208
+ confirm(params);
209
+ },
210
+
211
+ cancelEdit: function (event) {
212
+ event.stopImmediatePropagation();
213
+ const target = $(event.currentTarget);
214
+ var curRow = target.parent().parent();
215
+ if (this.newDatum) {
216
+ curRow.remove();
217
+ } else {
218
+ this.parentView.render();
219
+ }
220
+ },
221
+
222
+ save: function (event, value) {
223
+ event.stopImmediatePropagation();
224
+ const target = $(event.currentTarget);
225
+ var curRow = target.parent(),
226
+ tempKey = curRow.find('.g-widget-metadata-key-input').val(),
227
+ tempValue = (value !== undefined) ? value : curRow.find('.g-widget-metadata-value-input').val();
228
+
229
+ if (this.newDatum && tempKey === '') {
230
+ events.trigger('g:alert', {
231
+ text: 'A key is required for all metadata.',
232
+ type: 'warning'
233
+ });
234
+ return;
235
+ }
236
+
237
+ var saveCallback = () => {
238
+ this.key = tempKey;
239
+ this.value = tempValue;
240
+
241
+ this.parentView.key = this.key;
242
+ this.parentView.value = this.value;
243
+
244
+ if (this instanceof JsonMetadatumEditWidget) {
245
+ this.parentView.mode = 'json';
246
+ } else {
247
+ this.parentView.mode = 'simple';
248
+ }
249
+
250
+ this.parentView.render();
251
+
252
+ this.newDatum = false;
253
+ };
254
+
255
+ var errorCallback = function (out) {
256
+ events.trigger('g:alert', {
257
+ text: out.message,
258
+ type: 'danger'
259
+ });
260
+ };
261
+
262
+ if (this.newDatum) {
263
+ if (this.onMetadataAdded) {
264
+ this.onMetadataAdded(tempKey, tempValue, saveCallback, errorCallback);
265
+ } else {
266
+ this.item.addMetadata(tempKey, tempValue, saveCallback, errorCallback, {
267
+ field: this.fieldName,
268
+ path: this.apiPath
269
+ });
270
+ }
271
+ } else {
272
+ if (this.onMetadataEdited) {
273
+ this.onMetadataEdited(tempKey, this.key, tempValue, saveCallback, errorCallback);
274
+ } else {
275
+ this.item.editMetadata(tempKey, this.key, tempValue, saveCallback, errorCallback, {
276
+ field: this.fieldName,
277
+ path: this.apiPath
278
+ });
279
+ }
280
+ }
281
+ },
282
+
283
+ render: function () {
284
+ this.$el.html(this.editTemplate({
285
+ item: this.item,
286
+ key: this.key,
287
+ value: this.value,
288
+ accessLevel: this.accessLevel,
289
+ newDatum: this.newDatum,
290
+ AccessType: AccessType
291
+ }));
292
+ this.$el.find('.g-widget-metadata-key-input').trigger('focus');
293
+
294
+ return this;
295
+ }
296
+ });
297
+
298
+ var JsonMetadatumEditWidget = MetadatumEditWidget.extend({
299
+ editTemplate: JsonMetadatumEditWidgetTemplate,
300
+
301
+ getCurrentValue: function () {
302
+ return this.editor.getText();
303
+ },
304
+
305
+ save: function (event) {
306
+ try {
307
+ MetadatumEditWidget.prototype.save.call(
308
+ this, event, this.editor.get());
309
+ } catch (err) {
310
+ events.trigger('g:alert', {
311
+ text: 'The field contains invalid JSON and can not be saved.',
312
+ type: 'warning'
313
+ });
314
+ }
315
+ },
316
+
317
+ render: function () {
318
+ MetadatumEditWidget.prototype.render.apply(this, arguments);
319
+
320
+ const jsonEditorEl = this.$el.find('.g-json-editor');
321
+ this.editor = new JSONEditor(jsonEditorEl[0], {
322
+ mode: 'tree',
323
+ modes: ['code', 'tree'],
324
+ onError: () => {
325
+ events.trigger('g:alert', {
326
+ text: 'The field contains invalid JSON and can not be viewed in Tree Mode.',
327
+ type: 'warning'
328
+ });
329
+ }
330
+ });
331
+
332
+ if (this.value !== undefined) {
333
+ this.editor.setText(JSON.stringify(this.value));
334
+ this.editor.expandAll();
335
+ }
336
+
337
+ return this;
338
+ }
339
+ });
340
+
341
+ /**
342
+ * This widget shows a list of metadata in a given item.
343
+ */
344
+ var MetadataWidget = View.extend({
345
+ events: {
346
+ 'click .g-add-json-metadata': function (event) {
347
+ this.addMetadata(event, 'json');
348
+ },
349
+ 'click .g-add-simple-metadata': function (event) {
350
+ this.addMetadata(event, 'simple');
351
+ }
352
+ },
353
+
354
+ /**
355
+ * Creates a widget to display and optionally edit metadata fields.
356
+ *
357
+ * @param settings.item {Model} The model object whose metadata to display.
358
+ * Can be any model type that inherits MetadataMixin.
359
+ * @param [settings.fieldName='meta'] {string} The name of the model attribute
360
+ * to display/edit. The model attribute with this name should be an object
361
+ * whose top level keys represent metadata keys.
362
+ * @param [settings.title='Metadata'] {string} Title for the widget.
363
+ * @param [settings.apiPath] {string} The relative API path to use when editing
364
+ * metadata keys for this model. Defaults to using the MetadataMixin default path.
365
+ * @param [settings.accessLevel=AccessType.READ] {AccessType} The
366
+ * access level for this widget. Use READ for read-only, or WRITE (or greater)
367
+ * for adding editing capabilities as well.
368
+ * @param [settings.onMetadataAdded] {Function} A custom callback for when a
369
+ * new metadata key is added to the list. If passed, will override the
370
+ * default behavior of calling MetadataMixin.addMetadata.
371
+ * @param [settings.onMetadataEdited] {Function} A custom callback for when an
372
+ * existing metadata key is updated. If passed, will override the default
373
+ * behavior of calling MetadataMixin.editMetadata.
374
+ */
375
+ initialize: function (settings) {
376
+ this.item = settings.item;
377
+ this.fieldName = settings.fieldName || 'meta';
378
+ this.title = settings.title || 'Metadata';
379
+ this.apiPath = settings.apiPath;
380
+ this.accessLevel = settings.accessLevel;
381
+ this.onMetadataEdited = settings.onMetadataEdited;
382
+ this.onMetadataAdded = settings.onMetadataAdded;
383
+
384
+ this.item.on('g:changed', function () {
385
+ this.render();
386
+ }, this);
387
+ this.render();
388
+ },
389
+
390
+ modes: {
391
+ simple: {
392
+ editor: function (args) {
393
+ return new MetadatumEditWidget(args);
394
+ },
395
+ displayValue: function () {
396
+ return this.value;
397
+ },
398
+ template: MetadatumViewTemplate
399
+ },
400
+ json: {
401
+ editor: function (args) {
402
+ if (args.value !== undefined) {
403
+ args.value = JSON.parse(args.value);
404
+ }
405
+ return new JsonMetadatumEditWidget(args);
406
+ },
407
+ displayValue: function () {
408
+ return JSON.stringify(this.value, null, 4);
409
+ },
410
+ validation: {
411
+ from: {
412
+ simple: [
413
+ function (value) {
414
+ try {
415
+ JSON.parse(value);
416
+ return true;
417
+ } catch (e) {
418
+ // ignore
419
+ }
420
+
421
+ return false;
422
+ },
423
+ 'The simple field is not valid JSON and can not be converted.'
424
+ ]
425
+ }
426
+ },
427
+ template: JsonMetadatumViewTemplate
428
+ }
429
+ },
430
+
431
+ setItem: function (item) {
432
+ this.item = item;
433
+ return this;
434
+ },
435
+
436
+ // Does not support modal editing
437
+ getModeFromValue: function (value) {
438
+ return _.isString(value) ? 'simple' : 'json';
439
+ },
440
+
441
+ addMetadata: function (event, mode) {
442
+ var EditWidget = this.modes[mode].editor;
443
+ var value = (mode === 'json') ? '{}' : '';
444
+
445
+ var widget = new MetadatumWidget({
446
+ className: 'g-widget-metadata-row editing',
447
+ mode: mode,
448
+ key: '',
449
+ value: value,
450
+ item: this.item,
451
+ fieldName: this.fieldName,
452
+ apiPath: this.apiPath,
453
+ accessLevel: this.accessLevel,
454
+ parentView: this,
455
+ onMetadataEdited: this.onMetadataEdited,
456
+ onMetadataAdded: this.onMetadataAdded
457
+ });
458
+ widget.$el.appendTo(this.$('.g-widget-metadata-container'));
459
+
460
+ new EditWidget({
461
+ item: this.item,
462
+ key: '',
463
+ value: value,
464
+ fieldName: this.fieldName,
465
+ apiPath: this.apiPath,
466
+ accessLevel: this.accessLevel,
467
+ newDatum: true,
468
+ parentView: widget,
469
+ onMetadataEdited: this.onMetadataEdited,
470
+ onMetadataAdded: this.onMetadataAdded
471
+ })
472
+ .render()
473
+ .$el.appendTo(widget.$el);
474
+ },
475
+
476
+ render: function () {
477
+ var metaDict = this.item.get(this.fieldName) || {};
478
+ var metaKeys = Object.keys(metaDict);
479
+ metaKeys.sort(localeSort);
480
+
481
+ // Metadata header
482
+ this.$el.html(MetadataWidgetTemplate({
483
+ item: this.item,
484
+ title: this.title,
485
+ accessLevel: this.accessLevel,
486
+ AccessType: AccessType
487
+ }));
488
+
489
+ // Append each metadatum
490
+ _.each(metaKeys, function (metaKey) {
491
+ this.$el.find('.g-widget-metadata-container').append(new MetadatumWidget({
492
+ mode: this.getModeFromValue(metaDict[metaKey]),
493
+ key: metaKey,
494
+ value: metaDict[metaKey],
495
+ accessLevel: this.accessLevel,
496
+ parentView: this,
497
+ fieldName: this.fieldName,
498
+ apiPath: this.apiPath,
499
+ onMetadataEdited: this.onMetadataEdited,
500
+ onMetadataAdded: this.onMetadataAdded
501
+ }).render().$el);
502
+ }, this);
503
+
504
+ return this;
505
+ }
506
+ });
507
+
508
+ export default MetadataWidget;
@@ -0,0 +1,72 @@
1
+ import AssetstoreModel from '@girder/core/models/AssetstoreModel';
2
+ import View from '@girder/core/views/View';
3
+ import { AssetstoreType } from '@girder/core/constants';
4
+
5
+ import NewAssetstoreTemplate from '@girder/core/templates/widgets/newAssetstore.pug';
6
+
7
+ import 'bootstrap/js/collapse';
8
+ import 'bootstrap/js/transition';
9
+
10
+ import '@girder/core/utilities/jquery/girderEnable';
11
+
12
+ /**
13
+ * This widget is for creating new assetstores. The parent view is responsible
14
+ * for checking admin privileges before rendering this widget.
15
+ */
16
+ var NewAssetstoreWidget = View.extend({
17
+ events: {
18
+ 'submit #g-new-fs-form': function (e) {
19
+ this.createAssetstore(e, this.$('#g-new-fs-error'), {
20
+ type: AssetstoreType.FILESYSTEM,
21
+ name: this.$('#g-new-fs-name').val(),
22
+ root: this.$('#g-new-fs-root').val()
23
+ });
24
+ },
25
+
26
+ 'submit #g-new-s3-form': function (e) {
27
+ this.createAssetstore(e, this.$('#g-new-s3-error'), {
28
+ type: AssetstoreType.S3,
29
+ name: this.$('#g-new-s3-name').val(),
30
+ bucket: this.$('#g-new-s3-bucket').val(),
31
+ prefix: this.$('#g-new-s3-prefix').val(),
32
+ accessKeyId: this.$('#g-new-s3-access-key-id').val(),
33
+ secret: this.$('#g-new-s3-secret').val(),
34
+ service: this.$('#g-new-s3-service').val(),
35
+ region: this.$('#g-new-s3-region').val(),
36
+ readOnly: this.$('#g-new-s3-readonly').is(':checked'),
37
+ inferCredentials: this.$('#g-new-s3-infercredentials').is(':checked'),
38
+ serverSideEncryption: this.$('#g-new-s3-sse').is(':checked'),
39
+ allowS3AcceleratedTransfer: this.$('#g-new-s3-accelerated-endpoint').is(':checked')
40
+ });
41
+ }
42
+ },
43
+
44
+ render: function () {
45
+ this.$el.html(NewAssetstoreTemplate());
46
+ return this;
47
+ },
48
+
49
+ /**
50
+ * Call this to make the request to the server to create the assetstore.
51
+ * @param e The submit event from the form.
52
+ * @param container The element to write the error message into.
53
+ * @param data The form data to POST to /assetstore
54
+ */
55
+ createAssetstore: function (e, container, data) {
56
+ e.preventDefault();
57
+ this.$('.g-new-assetstore-submit').girderEnable(false);
58
+ container.empty();
59
+
60
+ var assetstore = new AssetstoreModel();
61
+ assetstore.set(data);
62
+ assetstore.on('g:saved', function () {
63
+ this.$('.g-new-assetstore-submit').girderEnable(true);
64
+ this.trigger('g:created', assetstore);
65
+ }, this).on('g:error', function (err) {
66
+ this.$('.g-new-assetstore-submit').girderEnable(true);
67
+ container.text(err.responseJSON.message);
68
+ }, this).save();
69
+ }
70
+ });
71
+
72
+ export default NewAssetstoreWidget;
@@ -0,0 +1,37 @@
1
+ import View from '@girder/core/views/View';
2
+
3
+ import PaginateWidgetTemplate from '@girder/core/templates/widgets/paginateWidget.pug';
4
+
5
+ /**
6
+ * This widget is used to provide a consistent widget for iterating amongst
7
+ * pages of a Collection.
8
+ */
9
+ var PaginateWidget = View.extend({
10
+ events: {
11
+ 'click .g-page-next:not(.disabled)': function () {
12
+ this.collection.fetchNextPage();
13
+ },
14
+ 'click .g-page-prev:not(.disabled)': function () {
15
+ this.collection.fetchPreviousPage();
16
+ }
17
+ },
18
+
19
+ initialize: function (settings) {
20
+ this.collection = settings.collection;
21
+ },
22
+
23
+ /**
24
+ * Do not call render() until the collection has been fetched once.
25
+ */
26
+ render: function () {
27
+ this.$el.html(PaginateWidgetTemplate({
28
+ collection: this.collection
29
+ }));
30
+
31
+ this.$('.g-page-next').girderEnable(this.collection.hasNextPage());
32
+ this.$('.g-page-prev').girderEnable(this.collection.hasPreviousPage());
33
+ return this;
34
+ }
35
+ });
36
+
37
+ export default PaginateWidget;
@@ -0,0 +1,33 @@
1
+ import router from '@girder/core/router';
2
+ import View from '@girder/core/views/View';
3
+
4
+ import PluginConfigBreadcrumbTemplate from '@girder/core/templates/widgets/pluginConfigBreadcrumb.pug';
5
+
6
+ /**
7
+ * This widget provides a consistent breadcrumb to be displayed on the admin
8
+ * configuration pages for plugins.
9
+ */
10
+ var PluginConfigBreadcrumbWidget = View.extend({
11
+ events: {
12
+ 'click a.g-admin-console-link': function () {
13
+ router.navigate('admin', { trigger: true });
14
+ },
15
+ 'click a.g-plugins-link': function () {
16
+ router.navigate('plugins', { trigger: true });
17
+ }
18
+ },
19
+
20
+ initialize: function (settings) {
21
+ this.pluginName = settings.pluginName;
22
+ },
23
+
24
+ render: function () {
25
+ this.$el.html(PluginConfigBreadcrumbTemplate({
26
+ pluginName: this.pluginName
27
+ }));
28
+
29
+ return this;
30
+ }
31
+ });
32
+
33
+ export default PluginConfigBreadcrumbWidget;