diff --git a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowser.jsx b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowser.jsx index 4e4ad0ba389eba29b232fb38386d8e95ad6dcb64..f306d4f7cad2df71004085214d5ff9d7a3241419 100644 --- a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowser.jsx +++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowser.jsx @@ -1,9 +1,18 @@ import React from 'react' +import Browser from '@src/js/components/common/browser/Browser.jsx' +import ToolBrowserController from '@src/js/components/tools/browser/ToolBrowserController.js' import logger from '@src/js/common/logger.js' -export default class ToolBrowser extends React.Component { +class ToolBrowser extends React.Component { + constructor(props) { + super(props) + this.controller = this.props.controller || new ToolBrowserController() + } + render() { logger.log(logger.DEBUG, 'ToolBrowser.render') - return 'ToolBrowser' + return <Browser controller={this.controller} /> } } + +export default ToolBrowser diff --git a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js new file mode 100644 index 0000000000000000000000000000000000000000..9c9f18b2e7be7eaf7ac75dbe05849550aa824014 --- /dev/null +++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js @@ -0,0 +1,141 @@ +import openbis from '@src/js/services/openbis.js' +import actions from '@src/js/store/actions/actions.js' +import pages from '@src/js/common/consts/pages.js' +import objectType from '@src/js/common/consts/objectType.js' +import objectOperation from '@src/js/common/consts/objectOperation.js' +import BrowserController from '@src/js/components/common/browser/BrowserController.js' + +export default class ToolBrowserController extends BrowserController { + doGetPage() { + return pages.TOOLS + } + + async doLoadNodes() { + return Promise.all([ + openbis.searchPlugins( + new openbis.PluginSearchCriteria(), + new openbis.PluginFetchOptions() + ) + ]).then(([plugins]) => { + const dynamicPropertyPluginNodes = plugins + .getObjects() + .filter( + plugin => plugin.pluginType === openbis.PluginType.DYNAMIC_PROPERTY + ) + .map(plugin => { + return { + id: `dynamicPropertyPlugin/${plugin.name}`, + text: plugin.name, + object: { + type: objectType.DYNAMIC_PROPERTY_PLUGIN, + id: plugin.name + }, + canMatchFilter: true, + canRemove: true + } + }) + + const entityValidationPluginNodes = plugins + .getObjects() + .filter( + plugin => plugin.pluginType === openbis.PluginType.ENTITY_VALIDATION + ) + .map(plugin => { + return { + id: `entityValidationPlugin/${plugin.name}`, + text: plugin.name, + object: { + type: objectType.ENTITY_VALIDATION_PLUGIN, + id: plugin.name + }, + canMatchFilter: true, + canRemove: true + } + }) + + let nodes = [ + { + id: 'dynamicPropertyPlugins', + text: 'Dynamic Property Plugins', + children: dynamicPropertyPluginNodes, + childrenType: objectType.NEW_DYNAMIC_PROPERTY_PLUGIN, + canAdd: true + }, + { + id: 'entityValidationPlugins', + text: 'Entity Validation Plugins', + children: entityValidationPluginNodes, + childrenType: objectType.NEW_ENTITY_VALIDATION_PLUGIN, + canAdd: true + } + ] + + return nodes + }) + } + + doNodeAdd(node) { + if (node && node.childrenType) { + this.context.dispatch( + actions.objectNew(this.getPage(), node.childrenType) + ) + } + } + + doNodeRemove(node) { + if (!node.object) { + return Promise.resolve() + } + + const { type, id } = node.object + const reason = 'deleted via ng_ui' + + return this._prepareRemoveOperations(type, id, reason) + .then(operations => { + const options = new openbis.SynchronousOperationExecutionOptions() + options.setExecuteInOrder(true) + return openbis.executeOperations(operations, options) + }) + .then(() => { + this.context.dispatch(actions.objectDelete(this.getPage(), type, id)) + }) + .catch(error => { + this.context.dispatch(actions.errorChange(error)) + }) + } + + _prepareRemoveOperations(type, id, reason) { + if ( + type === objectType.DYNAMIC_PROPERTY_PLUGIN || + type === objectType.ENTITY_VALIDATION_PLUGIN + ) { + return this._prepareRemovePluginOperations(id, reason) + } else { + throw new Error('Unsupported type: ' + type) + } + } + + _prepareRemovePluginOperations(id, reason) { + const options = new openbis.PluginDeletionOptions() + options.setReason(reason) + return Promise.resolve([ + new openbis.DeletePluginsOperation( + [new openbis.PluginPermId(id)], + options + ) + ]) + } + + doGetObservedModifications() { + return { + [objectType.DYNAMIC_PROPERTY_PLUGIN]: [ + objectOperation.CREATE, + objectOperation.DELETE + ], + [objectType.ENTITY_VALIDATION_PLUGIN]: [ + objectOperation.CREATE, + objectOperation.DELETE + ] + } + } +} diff --git a/openbis_ng_ui/src/js/services/openbis/dto.js b/openbis_ng_ui/src/js/services/openbis/dto.js index 7389cf14e4dd5f2baec95812a44975395dc704af..6f43292034f3b1e53db919f13123df94fb3dfa17 100644 --- a/openbis_ng_ui/src/js/services/openbis/dto.js +++ b/openbis_ng_ui/src/js/services/openbis/dto.js @@ -53,6 +53,8 @@ const CLASS_FULL_NAMES = [ 'as/dto/person/update/PersonUpdate', 'as/dto/person/update/UpdatePersonsOperation', 'as/dto/plugin/PluginType', + 'as/dto/plugin/delete/PluginDeletionOptions', + 'as/dto/plugin/delete/DeletePluginsOperation', 'as/dto/plugin/fetchoptions/PluginFetchOptions', 'as/dto/plugin/id/PluginPermId', 'as/dto/plugin/search/PluginSearchCriteria', diff --git a/openbis_ng_ui/srcTest/js/components/AppComponentTest.js b/openbis_ng_ui/srcTest/js/components/AppComponentTest.js index ea692cf30a149542938cfa9e57ceeb82d2b99536..852dc0e60abc0b72e49cadbcb013349ca6fec7fd 100644 --- a/openbis_ng_ui/srcTest/js/components/AppComponentTest.js +++ b/openbis_ng_ui/srcTest/js/components/AppComponentTest.js @@ -25,6 +25,7 @@ export default class AppComponentTest extends ComponentTest { openbis.mockSearchVocabularies([]) openbis.mockSearchPersons([]) openbis.mockSearchGroups([]) + openbis.mockSearchPlugins([]) } async login(app) { diff --git a/openbis_ng_ui/srcTest/js/services/openbis/api.js b/openbis_ng_ui/srcTest/js/services/openbis/api.js index f33f891bb32d77e7a5203dad3a3da7d51e1ceeea..59878ffc65bc180a125653d3060c203061da5d8f 100644 --- a/openbis_ng_ui/srcTest/js/services/openbis/api.js +++ b/openbis_ng_ui/srcTest/js/services/openbis/api.js @@ -85,6 +85,12 @@ const mockSearchVocabularies = vocabularies => { searchVocabularies.mockReturnValue(Promise.resolve(searchResult)) } +const mockSearchPlugins = plugins => { + const searchResult = new dto.SearchResult() + searchResult.setObjects(plugins) + searchPlugins.mockReturnValue(Promise.resolve(searchResult)) +} + export default { login, logout, @@ -127,5 +133,6 @@ export default { mockSearchPersons, mockSearchSampleTypes, mockSearchPropertyTypes, - mockSearchVocabularies + mockSearchVocabularies, + mockSearchPlugins } diff --git a/openbis_ng_ui/srcTest/js/services/openbis/dto.js b/openbis_ng_ui/srcTest/js/services/openbis/dto.js index 904b252629c4395b60da553ca24b4758a49c9213..ee785c5fe1ffb8220e3e2c8ba1840ca18e411791 100644 --- a/openbis_ng_ui/srcTest/js/services/openbis/dto.js +++ b/openbis_ng_ui/srcTest/js/services/openbis/dto.js @@ -30,6 +30,7 @@ import DeleteAuthorizationGroupsOperation from 'as/dto/authorizationgroup/delete import DeleteDataSetTypesOperation from 'as/dto/dataset/delete/DeleteDataSetTypesOperation' import DeleteExperimentTypesOperation from 'as/dto/experiment/delete/DeleteExperimentTypesOperation' import DeleteMaterialTypesOperation from 'as/dto/material/delete/DeleteMaterialTypesOperation' +import DeletePluginsOperation from 'as/dto/plugin/delete/DeletePluginsOperation' import DeletePropertyTypesOperation from 'as/dto/property/delete/DeletePropertyTypesOperation' import DeleteRoleAssignmentsOperation from 'as/dto/roleassignment/delete/DeleteRoleAssignmentsOperation' import DeleteSampleTypesOperation from 'as/dto/sample/delete/DeleteSampleTypesOperation' @@ -60,6 +61,7 @@ import PersonPermId from 'as/dto/person/id/PersonPermId' import PersonSearchCriteria from 'as/dto/person/search/PersonSearchCriteria' import PersonUpdate from 'as/dto/person/update/PersonUpdate' import Plugin from 'as/dto/plugin/Plugin' +import PluginDeletionOptions from 'as/dto/plugin/delete/PluginDeletionOptions' import PluginFetchOptions from 'as/dto/plugin/fetchoptions/PluginFetchOptions' import PluginPermId from 'as/dto/plugin/id/PluginPermId' import PluginSearchCriteria from 'as/dto/plugin/search/PluginSearchCriteria' @@ -162,6 +164,7 @@ const dto = { DeleteDataSetTypesOperation, DeleteExperimentTypesOperation, DeleteMaterialTypesOperation, + DeletePluginsOperation, DeletePropertyTypesOperation, DeleteRoleAssignmentsOperation, DeleteSampleTypesOperation, @@ -192,6 +195,7 @@ const dto = { PersonSearchCriteria, PersonUpdate, Plugin, + PluginDeletionOptions, PluginFetchOptions, PluginPermId, PluginSearchCriteria,