diff --git a/openbis_ng_ui/src/js/common/consts/ids.js b/openbis_ng_ui/src/js/common/consts/ids.js index e67fb80b8c1f3e46cc19e623854aa50f873294bb..5a7846afc1fcc11bccce0fb49bf44223e9d3349b 100644 --- a/openbis_ng_ui/src/js/common/consts/ids.js +++ b/openbis_ng_ui/src/js/common/consts/ids.js @@ -11,7 +11,8 @@ const USER_ROLES_GRID_ID = 'user_roles_grid' const USER_GROUP_USERS_GRID_ID = 'user_group_users_grid' const USER_GROUP_ROLES_GRID_ID = 'user_group_roles_grid' const VOCABULARY_TERMS_GRID_ID = 'vocabulary_terms_grid' -const PLUGINS_GRID_ID = 'plugins_grid' +const DYNAMIC_PROPERTY_PLUGINS_GRID_ID = 'dynamic_property_plugins_grid' +const ENTITY_VALIDATION_PLUGINS_GRID_ID = 'entity_validation_plugins_grid' const QUERIES_GRID_ID = 'queries_grid' export default { @@ -28,6 +29,7 @@ export default { USER_GROUP_USERS_GRID_ID, USER_GROUP_ROLES_GRID_ID, VOCABULARY_TERMS_GRID_ID, - PLUGINS_GRID_ID, + DYNAMIC_PROPERTY_PLUGINS_GRID_ID, + ENTITY_VALIDATION_PLUGINS_GRID_ID, QUERIES_GRID_ID } diff --git a/openbis_ng_ui/src/js/common/consts/routes.js b/openbis_ng_ui/src/js/common/consts/routes.js index fa46b47981a6c321b9bb83472ba1ea910798c2cc..cefa0431ff2fc7cd2be25e8c4692ae6363286ba5 100644 --- a/openbis_ng_ui/src/js/common/consts/routes.js +++ b/openbis_ng_ui/src/js/common/consts/routes.js @@ -172,6 +172,14 @@ const routes = { page: pages.TOOLS, type: objectTypes.DYNAMIC_PROPERTY_PLUGIN }), + DYNAMIC_PROPERTY_PLUGIN_OVERVIEW: new Route( + '/dynamic-property-plugin-overview', + { + page: pages.TOOLS, + type: objectTypes.OVERVIEW, + id: objectTypes.DYNAMIC_PROPERTY_PLUGIN + } + ), NEW_ENTITY_VALIDATION_PLUGIN: new Route('/new-entity-validation-plugin/:id', { page: pages.TOOLS, type: objectTypes.NEW_ENTITY_VALIDATION_PLUGIN @@ -180,6 +188,14 @@ const routes = { page: pages.TOOLS, type: objectTypes.ENTITY_VALIDATION_PLUGIN }), + ENTITY_VALIDATION_PLUGIN_OVERVIEW: new Route( + '/entity-validation-plugin-overview', + { + page: pages.TOOLS, + type: objectTypes.OVERVIEW, + id: objectTypes.ENTITY_VALIDATION_PLUGIN + } + ), NEW_QUERY: new Route('/new-query/:id', { page: pages.TOOLS, type: objectTypes.NEW_QUERY @@ -188,6 +204,11 @@ const routes = { page: pages.TOOLS, type: objectTypes.QUERY }), + QUERY_OVERVIEW: new Route('/query-overview', { + page: pages.TOOLS, + type: objectTypes.OVERVIEW, + id: objectTypes.QUERY + }), DEFAULT: new DefaultRoute() } diff --git a/openbis_ng_ui/src/js/components/tools/Tools.jsx b/openbis_ng_ui/src/js/components/tools/Tools.jsx index a94357004519db31f62b803c638bb6c3244411a3..39bf19687a88565dde375c98dc158f72772d49f0 100644 --- a/openbis_ng_ui/src/js/components/tools/Tools.jsx +++ b/openbis_ng_ui/src/js/components/tools/Tools.jsx @@ -50,27 +50,40 @@ class Tools extends React.Component { ) { return <QueryForm object={object} /> } else if (object.type === objectType.SEARCH) { - return <ToolSearch objectId={object.id} /> + return <ToolSearch searchText={object.id} /> + } else if (object.type === objectType.OVERVIEW) { + return <ToolSearch objectType={object.id} /> } } renderTab(tab) { const { object, changed } = tab - const prefixes = { - [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin: ', - [objectType.NEW_DYNAMIC_PROPERTY_PLUGIN]: 'New Dynamic Property Plugin ', - [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin: ', - [objectType.NEW_ENTITY_VALIDATION_PLUGIN]: - 'New Entity Validation Plugin ', - [objectType.QUERY]: 'Query: ', - [objectType.NEW_QUERY]: 'New Query ', - [objectType.SEARCH]: 'Search: ' + let label = null + + if (object.type === objectType.OVERVIEW) { + const labels = { + [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugins', + [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugins', + [objectType.QUERY]: 'Queries' + } + label = labels[object.id] + } else { + const prefixes = { + [objectType.DYNAMIC_PROPERTY_PLUGIN]: 'Dynamic Property Plugin: ', + [objectType.NEW_DYNAMIC_PROPERTY_PLUGIN]: + 'New Dynamic Property Plugin ', + [objectType.ENTITY_VALIDATION_PLUGIN]: 'Entity Validation Plugin: ', + [objectType.NEW_ENTITY_VALIDATION_PLUGIN]: + 'New Entity Validation Plugin ', + [objectType.QUERY]: 'Query: ', + [objectType.NEW_QUERY]: 'New Query ', + [objectType.SEARCH]: 'Search: ' + } + label = prefixes[object.type] + object.id } - return ( - <ContentTab label={prefixes[object.type] + object.id} changed={changed} /> - ) + return <ContentTab label={label} changed={changed} /> } } diff --git a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js index 439e88f4adef2545b711a318860e060fc531ee1a..0da5138e3814a8164d4ba1ca2b2ba88aab49c1fe 100644 --- a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js +++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js @@ -74,6 +74,10 @@ export default class ToolBrowserController extends BrowserController { { id: 'dynamicPropertyPlugins', text: 'Dynamic Property Plugins', + object: { + type: objectType.OVERVIEW, + id: objectType.DYNAMIC_PROPERTY_PLUGIN + }, children: dynamicPropertyPluginNodes, childrenType: objectType.NEW_DYNAMIC_PROPERTY_PLUGIN, canAdd: true @@ -81,6 +85,10 @@ export default class ToolBrowserController extends BrowserController { { id: 'entityValidationPlugins', text: 'Entity Validation Plugins', + object: { + type: objectType.OVERVIEW, + id: objectType.ENTITY_VALIDATION_PLUGIN + }, children: entityValidationPluginNodes, childrenType: objectType.NEW_ENTITY_VALIDATION_PLUGIN, canAdd: true @@ -88,6 +96,10 @@ export default class ToolBrowserController extends BrowserController { { id: 'queries', text: 'Queries', + object: { + type: objectType.OVERVIEW, + id: objectType.QUERY + }, children: queryNodes, childrenType: objectType.NEW_QUERY, canAdd: true diff --git a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx index ffbc4ea51a290f999ced3dc2cd3563476005110b..1b5c8acbcd7f0d144992c22d46e5d1343760e007 100644 --- a/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx +++ b/openbis_ng_ui/src/js/components/tools/common/PluginsGrid.jsx @@ -2,6 +2,7 @@ import React from 'react' import Grid from '@src/js/components/common/grid/Grid.jsx' import PluginLink from '@src/js/components/common/link/PluginLink.jsx' import UserLink from '@src/js/components/common/link/UserLink.jsx' +import openbis from '@src/js/services/openbis.js' import logger from '@src/js/common/logger.js' class PluginsGrid extends React.PureComponent { @@ -10,6 +11,7 @@ class PluginsGrid extends React.PureComponent { const { id, + pluginType, rows, selectedRowId, onSelectedRowChange, @@ -20,7 +22,7 @@ class PluginsGrid extends React.PureComponent { <Grid id={id} controllerRef={controllerRef} - header='Plugins' + header={this.getHeader()} columns={[ { name: 'name', @@ -31,7 +33,7 @@ class PluginsGrid extends React.PureComponent { return ( <PluginLink pluginName={row.name.value} - pluginType={row.pluginType.value} + pluginType={pluginType} /> ) } @@ -41,11 +43,6 @@ class PluginsGrid extends React.PureComponent { label: 'Description', getValue: ({ row }) => row.description.value }, - { - name: 'pluginType', - label: 'Plugin Type', - getValue: ({ row }) => row.pluginType.value - }, { name: 'pluginKind', label: 'Plugin Kind', @@ -71,6 +68,16 @@ class PluginsGrid extends React.PureComponent { /> ) } + + getHeader() { + const { pluginType } = this.props + + if (pluginType === openbis.PluginType.DYNAMIC_PROPERTY) { + return 'Dynamic Property Plugins' + } else if (pluginType === openbis.PluginType.ENTITY_VALIDATION) { + return 'Entity Validation Plugins' + } + } } export default PluginsGrid diff --git a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx index e70696207d96f4417fe1ea6ea6c5b5a1d01756df..ff65e67efce71774b19e3b6a1d5e63ce4bc06798 100644 --- a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx +++ b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx @@ -4,11 +4,14 @@ import React from 'react' import GridContainer from '@src/js/components/common/grid/GridContainer.jsx' import PluginsGrid from '@src/js/components/tools/common/PluginsGrid.jsx' import QueriesGrid from '@src/js/components/tools/common/QueriesGrid.jsx' +import Message from '@src/js/components/common/form/Message.jsx' import FormUtil from '@src/js/components/common/form/FormUtil.js' import ids from '@src/js/common/consts/ids.js' +import objectTypes from '@src/js/common/consts/objectType.js' import store from '@src/js/store/store.js' import actions from '@src/js/store/actions/actions.js' import openbis from '@src/js/services/openbis.js' +import util from '@src/js/common/util.js' import logger from '@src/js/common/logger.js' class ToolSearch extends React.Component { @@ -23,75 +26,103 @@ class ToolSearch extends React.Component { } componentDidMount() { - Promise.all([this.loadPlugins(), this.loadQueries()]) - .then(([plugins, queries]) => { - this.setState(() => ({ - loaded: true, - plugins, - queries - })) - }) - .catch(error => { - store.dispatch(actions.errorChange(error)) - }) + this.load() } - loadPlugins() { - let query = this.props.objectId + async load() { + try { + await Promise.all([ + this.loadDynamicPropertyPlugins(), + this.loadEntityValidationPlugins(), + this.loadQueries() + ]) + this.setState(() => ({ + loaded: true + })) + } catch (error) { + store.dispatch(actions.errorChange(error)) + } + } - let criteria = new openbis.PluginSearchCriteria() - criteria.withName().thatContains(query) + async loadDynamicPropertyPlugins() { + if (!this.shouldLoad(objectTypes.DYNAMIC_PROPERTY_PLUGIN)) { + return + } - let fo = new openbis.PluginFetchOptions() - fo.withScript() - fo.withRegistrator() + const dynamicPropertyPlugins = await this.loadPlugins( + openbis.PluginType.DYNAMIC_PROPERTY + ) - return openbis.searchPlugins(criteria, fo).then(result => { - return result.objects - .filter(plugin => { - return ( - plugin.pluginType === openbis.PluginType.DYNAMIC_PROPERTY || - plugin.pluginType === openbis.PluginType.ENTITY_VALIDATION - ) - }) - .map(plugin => { - const entityKinds = _.get(plugin, 'entityKinds', []) - - return { - id: _.get(plugin, 'name'), - name: FormUtil.createField({ value: _.get(plugin, 'name') }), - description: FormUtil.createField({ - value: _.get(plugin, 'description') - }), - pluginType: FormUtil.createField({ - value: _.get(plugin, 'pluginType') - }), - pluginKind: FormUtil.createField({ - value: _.get(plugin, 'pluginKind') - }), - entityKind: FormUtil.createField({ - value: entityKinds.length === 1 ? entityKinds[0] : null - }), - script: FormUtil.createField({ value: _.get(plugin, 'script') }), - registrator: FormUtil.createField({ - value: _.get(plugin, 'registrator.userId') - }) - } - }) + this.setState({ + dynamicPropertyPlugins }) } - loadQueries() { - let query = this.props.objectId + async loadEntityValidationPlugins() { + if (!this.shouldLoad(objectTypes.ENTITY_VALIDATION_PLUGIN)) { + return + } - let criteria = new openbis.QuerySearchCriteria() - criteria.withName().thatContains(query) + const entityValidationPlugins = await this.loadPlugins( + openbis.PluginType.ENTITY_VALIDATION + ) + + this.setState({ + entityValidationPlugins + }) + } - let fo = new openbis.QueryFetchOptions() + async loadPlugins(pluginType) { + const criteria = new openbis.PluginSearchCriteria() + criteria.withPluginType().thatEquals(pluginType) + + const fo = new openbis.PluginFetchOptions() + fo.withScript() + fo.withRegistrator() + + const result = await openbis.searchPlugins(criteria, fo) + + return util + .filter(result.objects, this.props.searchText, ['name', 'description']) + .map(plugin => { + const entityKinds = _.get(plugin, 'entityKinds', []) + + return { + id: _.get(plugin, 'name'), + name: FormUtil.createField({ value: _.get(plugin, 'name') }), + description: FormUtil.createField({ + value: _.get(plugin, 'description') + }), + pluginKind: FormUtil.createField({ + value: _.get(plugin, 'pluginKind') + }), + entityKind: FormUtil.createField({ + value: entityKinds.length === 1 ? entityKinds[0] : null + }), + script: FormUtil.createField({ value: _.get(plugin, 'script') }), + registrator: FormUtil.createField({ + value: _.get(plugin, 'registrator.userId') + }) + } + }) + } + + async loadQueries() { + if (!this.shouldLoad(objectTypes.QUERY)) { + return + } + + const fo = new openbis.QueryFetchOptions() fo.withRegistrator() - return openbis.searchQueries(criteria, fo).then(result => { - return result.objects.map(query => ({ + const result = await openbis.searchQueries( + new openbis.QuerySearchCriteria(), + fo + ) + + const queries = util + .filter(result.objects, this.props.searchText, ['name', 'description']) + .map(query => ({ id: _.get(query, 'name'), name: FormUtil.createField({ value: _.get(query, 'name') }), description: FormUtil.createField({ @@ -116,35 +147,38 @@ class ToolSearch extends React.Component { value: _.get(query, 'registrator.userId') }) })) + + this.setState({ + queries }) } + shouldLoad(objectType) { + return this.props.objectType === objectType || !this.props.objectType + } + handleClickContainer() { this.setState({ selection: null }) } - handleSelectedPluginRowChange(row) { - if (row) { - this.setState({ - selection: { - type: 'plugin', - id: row.id - } - }) + handleSelectedRowChange(objectType) { + return row => { + if (row) { + this.setState({ + selection: { + type: objectType, + id: row.id + } + }) + } } } - handleSelectedQueryRowChange(row) { - if (row) { - this.setState({ - selection: { - type: 'query', - id: row.id - } - }) - } + getSelectedRowId(objectType) { + const { selection } = this.state + return selection && selection.type === objectType ? selection.id : null } render() { @@ -154,28 +188,103 @@ class ToolSearch extends React.Component { return null } - const { selection } = this.state - return ( <GridContainer onClick={this.handleClickContainer}> + {this.renderNoResultsFoundMessage()} + {this.renderDynamicPropertyPlugins()} + {this.renderEntityValidationPlugins()} + {this.renderQueries()} + </GridContainer> + ) + } + + renderNoResultsFoundMessage() { + const { objectType } = this.props + const { + dynamicPropertyPlugins = [], + entityValidationPlugins = [], + queries = [] + } = this.state + + if ( + !objectType && + dynamicPropertyPlugins.length === 0 && + entityValidationPlugins.length === 0 && + queries.length === 0 + ) { + return <Message type='info'>No results found.</Message> + } else { + return null + } + } + + renderDynamicPropertyPlugins() { + if ( + this.shouldRender( + objectTypes.DYNAMIC_PROPERTY_PLUGIN, + this.state.dynamicPropertyPlugins + ) + ) { + return ( <PluginsGrid - id={ids.PLUGINS_GRID_ID} - rows={this.state.plugins} - onSelectedRowChange={this.handleSelectedPluginRowChange} - selectedRowId={ - selection && selection.type === 'plugin' ? selection.id : null - } + id={ids.DYNAMIC_PROPERTY_PLUGINS_GRID_ID} + pluginType={openbis.PluginType.DYNAMIC_PROPERTY} + rows={this.state.dynamicPropertyPlugins} + onSelectedRowChange={this.handleSelectedRowChange( + objectTypes.DYNAMIC_PROPERTY_PLUGIN + )} + selectedRowId={this.getSelectedRowId( + objectTypes.DYNAMIC_PROPERTY_PLUGIN + )} /> + ) + } else { + return null + } + } + + renderEntityValidationPlugins() { + if ( + this.shouldRender( + objectTypes.ENTITY_VALIDATION_PLUGIN, + this.state.entityValidationPlugins + ) + ) { + return ( + <PluginsGrid + id={ids.ENTITY_VALIDATION_PLUGINS_GRID_ID} + pluginType={openbis.PluginType.ENTITY_VALIDATION} + rows={this.state.entityValidationPlugins} + onSelectedRowChange={this.handleSelectedRowChange( + objectTypes.ENTITY_VALIDATION_PLUGIN + )} + selectedRowId={this.getSelectedRowId( + objectTypes.ENTITY_VALIDATION_PLUGIN + )} + /> + ) + } else { + return null + } + } + + renderQueries() { + if (this.shouldRender(objectTypes.QUERY, this.state.queries)) { + return ( <QueriesGrid id={ids.QUERIES_GRID_ID} rows={this.state.queries} - onSelectedRowChange={this.handleSelectedQueryRowChange} - selectedRowId={ - selection && selection.type === 'query' ? selection.id : null - } + onSelectedRowChange={this.handleSelectedRowChange(objectTypes.QUERY)} + selectedRowId={this.getSelectedRowId(objectTypes.QUERY)} /> - </GridContainer> - ) + ) + } else { + return null + } + } + + shouldRender(objectType, types) { + return this.props.objectType === objectType || (types && types.length > 0) } }