diff --git a/openbis_ng_ui/src/js/components/common/browser2/BrowserController.js b/openbis_ng_ui/src/js/components/common/browser2/BrowserController.js index 0771b44cdaec2cfd4dbcee4824f1fa406ef212e9..2be9ed59cf672a6cffb500fe605e80bde7e7ae20 100644 --- a/openbis_ng_ui/src/js/components/common/browser2/BrowserController.js +++ b/openbis_ng_ui/src/js/components/common/browser2/BrowserController.js @@ -125,11 +125,11 @@ export default class BrowserController { } async filterChange(newFilter) { - this._setFilter(newFilter, 500) + await this._setFilter(newFilter, 500) } async filterClear() { - this._setFilter(null, 0) + await this._setFilter(null, 0) } async _setFilter(newFilter, silentPeriod) { @@ -146,9 +146,16 @@ export default class BrowserController { if (util.trim(newFilter) === null) { await this.load() } else { - this.lastFilterTimeoutId = setTimeout(async () => { - await this.load() - }, silentPeriod) + return new Promise((resolve, reject) => { + this.lastFilterTimeoutId = setTimeout(async () => { + try { + await this.load() + resolve() + } catch (e) { + reject(e) + } + }, silentPeriod) + }) } } @@ -252,6 +259,10 @@ export default class BrowserController { return autoShowSelectedObject } + getTree() { + return this._getTreeController().getTree() + } + getFullTree() { return this.fullTreeController.getTree() } diff --git a/openbis_ng_ui/src/js/components/types/Types.jsx b/openbis_ng_ui/src/js/components/types/Types.jsx index 6c6862ddf98adb4aaf4616163cfdc4841a78e748..ca248816699145389d8f0b9585a8bb66fab85203 100644 --- a/openbis_ng_ui/src/js/components/types/Types.jsx +++ b/openbis_ng_ui/src/js/components/types/Types.jsx @@ -2,7 +2,7 @@ import React from 'react' import { withStyles } from '@material-ui/core/styles' import Content from '@src/js/components/common/content/Content.jsx' import ContentTab from '@src/js/components/common/content/ContentTab.jsx' -import TypeBrowser from '@src/js/components/types/browser2/TypeBrowser.jsx' +import TypeBrowser from '@src/js/components/types/browser/TypeBrowser.jsx' import TypeSearch from '@src/js/components/types/search/TypeSearch.jsx' import EntityTypeForm from '@src/js/components/types/form/entitytype/EntityTypeForm.jsx' import VocabularyTypeForm from '@src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx' diff --git a/openbis_ng_ui/src/js/components/types/browser/TypeBrowser.jsx b/openbis_ng_ui/src/js/components/types/browser/TypeBrowser.jsx index 4240f23a36900d6cfb3cbd2345a27f5b7c24017c..86f325f4a38ab5d21ea96c621ea808cfecbe5fa0 100644 --- a/openbis_ng_ui/src/js/components/types/browser/TypeBrowser.jsx +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowser.jsx @@ -1,19 +1,78 @@ +import _ from 'lodash' import React from 'react' -import Browser from '@src/js/components/common/browser/Browser.jsx' +import autoBind from 'auto-bind' +import BrowserWithOpenbis from '@src/js/components/common/browser2/BrowserWithOpenbis.jsx' +import BrowserButtonsAddRemove from '@src/js/components/common/browser2/BrowserButtonsAddRemove.jsx' import TypeBrowserController from '@src/js/components/types/browser/TypeBrowserController.js' +import AppController from '@src/js/components/AppController.js' +import pages from '@src/js/common/consts/pages.js' +import ids from '@src/js/common/consts/ids.js' import logger from '@src/js/common/logger.js' -class TypeBrowser extends React.Component { +export class TypeBrowser extends React.Component { constructor(props) { super(props) + autoBind(this) this.controller = this.props.controller || new TypeBrowserController() } + componentDidMount() { + this.componentDidUpdate({}) + } + + componentDidUpdate(prevProps) { + if (!_.isEqual(this.props.selectedObject, prevProps.selectedObject)) { + this.controller.selectObject(this.props.selectedObject) + } + + if ( + !_.isEqual( + this.props.lastObjectModifications, + prevProps.lastObjectModifications + ) + ) { + this.controller.reload(this.props.lastObjectModifications) + } + } + render() { logger.log(logger.DEBUG, 'TypeBrowser.render') - return <Browser controller={this.controller} /> + return ( + <BrowserWithOpenbis + id={ids.TYPE_BROWSER_ID} + controller={this.controller} + renderFooter={this.renderFooter} + onSelectedChange={selectedObject => { + if (selectedObject) { + AppController.getInstance().objectOpen( + pages.TYPES, + selectedObject.type, + selectedObject.id + ) + } + }} + /> + ) + } + + renderFooter() { + return ( + <div> + <BrowserButtonsAddRemove + selectedObject={this.controller.getSelectedObject()} + addEnabled={this.controller.canAddNode()} + removeEnabled={this.controller.canRemoveNode()} + onAdd={this.controller.addNode} + onRemove={this.controller.removeNode} + /> + </div> + ) } } -export default TypeBrowser +export default AppController.getInstance().withState(() => ({ + selectedObject: AppController.getInstance().getSelectedObject(pages.TYPES), + lastObjectModifications: + AppController.getInstance().getLastObjectModifications() +}))(TypeBrowser) diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserConsts.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserConsts.js similarity index 100% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserConsts.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserConsts.js diff --git a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js index d0e82d6166bebb428949bf83054d0e7fc24c8c99..51719e99c43fd56c593c73e9adccb1ed3f8301b1 100644 --- a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js @@ -1,338 +1,42 @@ -import _ from 'lodash' -import openbis from '@src/js/services/openbis.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' -import AppController from '@src/js/components/AppController.js' -import messages from '@src/js/common/messages.js' +import BrowserController from '@src/js/components/common/browser2/BrowserController.js' +import TypeBrowserControllerLoadNodePath from '@src/js/components/types/browser/TypeBrowserControllerLoadNodePath.js' +import TypeBrowserControllerLoadNodes from '@src/js/components/types/browser/TypeBrowserControllerLoadNodes.js' +import TypeBrowserControllerAddNode from '@src/js/components/types/browser/TypeBrowserControllerAddNode.js' +import TypeBrowserControllerRemoveNode from '@src/js/components/types/browser/TypeBrowserControllerRemoveNode.js' +import TypeBrowserControllerReload from '@src/js/components/types/browser/TypeBrowserControllerReload.js' export default class TypeBrowserController extends BrowserController { - doGetPage() { - return pages.TYPES + async doLoadNodePath(params) { + return await new TypeBrowserControllerLoadNodePath().doLoadNodePath(params) } - async doLoadNodes() { - return Promise.all([ - openbis.searchSampleTypes( - new openbis.SampleTypeSearchCriteria(), - new openbis.SampleTypeFetchOptions() - ), - openbis.searchExperimentTypes( - new openbis.ExperimentTypeSearchCriteria(), - new openbis.ExperimentTypeFetchOptions() - ), - openbis.searchDataSetTypes( - new openbis.DataSetTypeSearchCriteria(), - new openbis.DataSetTypeFetchOptions() - ), - openbis.searchMaterialTypes( - new openbis.MaterialTypeSearchCriteria(), - new openbis.MaterialTypeFetchOptions() - ), - openbis.searchVocabularies( - new openbis.VocabularySearchCriteria(), - new openbis.VocabularyFetchOptions() - ) - ]).then( - ([ - objectTypes, - collectionTypes, - dataSetTypes, - materialTypes, - vocabularyTypes - ]) => { - const _createNodes = (types, typeName, callback) => { - return _.map(types, type => { - const node = { - id: `${typeName}s/${type.code}`, - text: type.code, - object: { type: typeName, id: type.code }, - canMatchFilter: true, - canRemove: true - } - if (callback) { - callback(type, node) - } - return node - }) - } - - let objectTypeNodes = _createNodes( - objectTypes.getObjects(), - objectType.OBJECT_TYPE - ) - let collectionTypeNodes = _createNodes( - collectionTypes.getObjects(), - objectType.COLLECTION_TYPE - ) - let dataSetTypeNodes = _createNodes( - dataSetTypes.getObjects(), - objectType.DATA_SET_TYPE - ) - let materialTypeNodes = _createNodes( - materialTypes.getObjects(), - objectType.MATERIAL_TYPE - ) - let vocabularyTypeNodes = _createNodes( - vocabularyTypes.getObjects(), - objectType.VOCABULARY_TYPE, - (type, node) => { - node.canRemove = - !type.managedInternally || - AppController.getInstance().isSystemUser() - } - ) - - let nodes = [ - { - id: 'objectTypes', - text: messages.get(messages.OBJECT_TYPES), - object: { type: objectType.OVERVIEW, id: objectType.OBJECT_TYPE }, - children: objectTypeNodes, - childrenType: objectType.NEW_OBJECT_TYPE, - canAdd: true - }, - { - id: 'collectionTypes', - text: messages.get(messages.COLLECTION_TYPES), - object: { - type: objectType.OVERVIEW, - id: objectType.COLLECTION_TYPE - }, - children: collectionTypeNodes, - childrenType: objectType.NEW_COLLECTION_TYPE, - canAdd: true - }, - { - id: 'dataSetTypes', - text: messages.get(messages.DATA_SET_TYPES), - object: { type: objectType.OVERVIEW, id: objectType.DATA_SET_TYPE }, - children: dataSetTypeNodes, - childrenType: objectType.NEW_DATA_SET_TYPE, - canAdd: true - }, - { - id: 'materialTypes', - text: messages.get(messages.MATERIAL_TYPES), - object: { type: objectType.OVERVIEW, id: objectType.MATERIAL_TYPE }, - children: materialTypeNodes, - childrenType: objectType.NEW_MATERIAL_TYPE, - canAdd: true - }, - { - id: 'vocabularyTypes', - text: messages.get(messages.VOCABULARY_TYPES), - object: { - type: objectType.OVERVIEW, - id: objectType.VOCABULARY_TYPE - }, - children: vocabularyTypeNodes, - childrenType: objectType.NEW_VOCABULARY_TYPE, - canAdd: true - }, - { - id: 'propertyTypes', - text: messages.get(messages.PROPERTY_TYPES), - object: { - type: objectType.OVERVIEW, - id: objectType.PROPERTY_TYPE - } - } - ] - - return nodes - } - ) + async doLoadNodes(params) { + return await new TypeBrowserControllerLoadNodes().doLoadNodes(params) } - doNodeAdd(node) { - if (node && node.childrenType) { - AppController.getInstance().objectNew(this.getPage(), node.childrenType) - } - } - - async doNodeRemove(node) { - if (!node.object) { - return Promise.resolve() - } - - const { type, id } = node.object - const reason = 'deleted via ng_ui' - - try { - const operations = await this._prepareRemoveOperations(type, id, reason) - const options = new openbis.SynchronousOperationExecutionOptions() - options.setExecuteInOrder(true) - await openbis.executeOperations(operations, options) - AppController.getInstance().objectDelete(this.getPage(), type, id) - } catch (error) { - AppController.getInstance().errorChange(error) - } + async reload(objectModifications) { + new TypeBrowserControllerReload(this).reload(objectModifications) } - async _prepareRemoveOperations(type, id, reason) { - if ( - type === objectType.OBJECT_TYPE || - type === objectType.COLLECTION_TYPE || - type === objectType.DATA_SET_TYPE || - type === objectType.MATERIAL_TYPE - ) { - return await this._prepareRemoveEntityTypeOperations(type, id, reason) - } else if (type === objectType.VOCABULARY_TYPE) { - return await this._prepareRemoveVocabularyTypeOperations(type, id, reason) - } + canAddNode() { + return new TypeBrowserControllerAddNode().canAddNode( + this.getSelectedObject() + ) } - async _prepareRemoveEntityTypeOperations(type, id, reason) { - const operations = [] - - if (type === objectType.OBJECT_TYPE) { - const options = new openbis.SampleTypeDeletionOptions() - options.setReason(reason) - operations.push( - new openbis.DeleteSampleTypesOperation( - [new openbis.EntityTypePermId(id)], - options - ) - ) - } else if (type === objectType.COLLECTION_TYPE) { - const options = new openbis.ExperimentTypeDeletionOptions() - options.setReason(reason) - operations.push( - new openbis.DeleteExperimentTypesOperation( - [new openbis.EntityTypePermId(id)], - options - ) - ) - } else if (type === objectType.DATA_SET_TYPE) { - const options = new openbis.DataSetTypeDeletionOptions() - options.setReason(reason) - operations.push( - new openbis.DeleteDataSetTypesOperation( - [new openbis.EntityTypePermId(id)], - options - ) - ) - } else if (type === objectType.MATERIAL_TYPE) { - const options = new openbis.MaterialTypeDeletionOptions() - options.setReason(reason) - operations.push( - new openbis.DeleteMaterialTypesOperation( - [new openbis.EntityTypePermId(id)], - options - ) - ) - } - - const removeUnusuedPropertyTypesOperation = - await this._prepareRemoveUnusedPropertyTypesOperations(type, id) - - if (removeUnusuedPropertyTypesOperation) { - operations.push(removeUnusuedPropertyTypesOperation) - } - - return operations + async addNode() { + await new TypeBrowserControllerAddNode().doAddNode(this.getSelectedObject()) } - async _prepareRemoveUnusedPropertyTypesOperations(type, id) { - const entityKind = this.getEntityKind(type) - - const propertyAssignmentFetchOptions = - new openbis.PropertyAssignmentFetchOptions() - propertyAssignmentFetchOptions.withPropertyType() - propertyAssignmentFetchOptions.withEntityType() - - const propertyAssignments = await openbis.searchPropertyAssignments( - new openbis.PropertyAssignmentSearchCriteria(), - propertyAssignmentFetchOptions + canRemoveNode() { + return new TypeBrowserControllerRemoveNode().canRemoveNode( + this.getSelectedObject() ) - - const potentialPropertyTypesToDelete = [] - const propertyTypeUsages = {} - - propertyAssignments.objects.forEach(propertyAssignment => { - const propertyTypeCode = propertyAssignment.propertyType.code - - propertyTypeUsages[propertyTypeCode] = - (propertyTypeUsages[propertyTypeCode] || 0) + 1 - - if ( - propertyAssignment.entityType.permId.permId === id && - propertyAssignment.entityType.permId.entityKind === entityKind && - !propertyAssignment.propertyType.managedInternally - ) { - potentialPropertyTypesToDelete.push(propertyTypeCode) - } - }) - - if (potentialPropertyTypesToDelete.length > 0) { - const propertyTypesToDelete = [] - - potentialPropertyTypesToDelete.forEach(propertyTypeCode => { - if (propertyTypeUsages[propertyTypeCode] === 1) { - propertyTypesToDelete.push( - new openbis.PropertyTypePermId(propertyTypeCode) - ) - } - }) - - if (propertyTypesToDelete.length > 0) { - const options = new openbis.PropertyTypeDeletionOptions() - options.setReason('deleted via ng_ui') - return new openbis.DeletePropertyTypesOperation( - propertyTypesToDelete, - options - ) - } - } - - return null } - async _prepareRemoveVocabularyTypeOperations(type, id, reason) { - const options = new openbis.VocabularyDeletionOptions() - options.setReason(reason) - return new openbis.DeleteVocabulariesOperation( - [new openbis.VocabularyPermId(id)], - options + async removeNode() { + await new TypeBrowserControllerRemoveNode().doRemoveNode( + this.getSelectedObject() ) } - - doGetObservedModifications() { - return { - [objectType.OBJECT_TYPE]: [ - objectOperation.CREATE, - objectOperation.DELETE - ], - [objectType.COLLECTION_TYPE]: [ - objectOperation.CREATE, - objectOperation.DELETE - ], - [objectType.DATA_SET_TYPE]: [ - objectOperation.CREATE, - objectOperation.DELETE - ], - [objectType.MATERIAL_TYPE]: [ - objectOperation.CREATE, - objectOperation.DELETE - ], - [objectType.VOCABULARY_TYPE]: [ - objectOperation.CREATE, - objectOperation.DELETE - ] - } - } - - getEntityKind(type) { - if (type === objectType.OBJECT_TYPE) { - return openbis.EntityKind.SAMPLE - } else if (type === objectType.COLLECTION_TYPE) { - return openbis.EntityKind.EXPERIMENT - } else if (type === objectType.DATA_SET_TYPE) { - return openbis.EntityKind.DATA_SET - } else if (type === objectType.MATERIAL_TYPE) { - return openbis.EntityKind.MATERIAL - } - } } diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerAddNode.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerAddNode.js similarity index 91% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerAddNode.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerAddNode.js index 309be8ecdc5f3b326bcd3f009022e2dd94c54e86..5cba7129d791553f624569cdbb236c287e4ae578 100644 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerAddNode.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerAddNode.js @@ -19,11 +19,11 @@ export default class TypeBrowserControllerAddNode { ) } - doAddNode(selectedObject) { + async doAddNode(selectedObject) { if (!this.canAddNode(selectedObject)) { return } - AppController.getInstance().objectNew( + await AppController.getInstance().objectNew( pages.TYPES, NEW_OBJECT_TYPES[selectedObject.id] ) diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodePath.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodePath.js similarity index 98% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodePath.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodePath.js index 03292d84422bd4f3cf52528251857f3bc12b5464..6cf990d8d0bdcff788fe2fe2d13e15de1f50d111 100644 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodePath.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodePath.js @@ -1,4 +1,4 @@ -import TypeBrowserConsts from '@src/js/components/types/browser2/TypeBrowserConsts.js' +import TypeBrowserConsts from '@src/js/components/types/browser/TypeBrowserConsts.js' import openbis from '@src/js/services/openbis.js' import objectType from '@src/js/common/consts/objectType.js' diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodes.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodes.js similarity index 89% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodes.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodes.js index 15de855b888e5a7866c72d38340ad9f6a0153c5b..4cea1ec8391747805a3410db115375a6f06f0bdb 100644 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerLoadNodes.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerLoadNodes.js @@ -1,5 +1,5 @@ import _ from 'lodash' -import TypeBrowserConsts from '@src/js/components/types/browser2/TypeBrowserConsts.js' +import TypeBrowserConsts from '@src/js/components/types/browser/TypeBrowserConsts.js' import openbis from '@src/js/services/openbis.js' import objectType from '@src/js/common/consts/objectType.js' import messages from '@src/js/common/messages.js' @@ -111,7 +111,7 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { } async searchObjectTypes(params) { - const { filter, offset, limit } = params + const { filter, offset } = params const criteria = new openbis.SampleTypeSearchCriteria() if (filter) { @@ -120,16 +120,13 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { const fetchOptions = new openbis.SampleTypeFetchOptions() const result = await openbis.searchSampleTypes(criteria, fetchOptions) - result.criteria = { - filter, - offset, - limit - } + result.filter = filter + result.offset = offset return result } async searchCollectionTypes(params) { - const { filter, offset, limit } = params + const { filter, offset } = params const criteria = new openbis.ExperimentTypeSearchCriteria() if (filter) { @@ -138,16 +135,13 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { const fetchOptions = new openbis.ExperimentTypeFetchOptions() const result = await openbis.searchExperimentTypes(criteria, fetchOptions) - result.criteria = { - filter, - offset, - limit - } + result.filter = filter + result.offset = offset return result } async searchDataSetTypes(params) { - const { filter, offset, limit } = params + const { filter, offset } = params const criteria = new openbis.DataSetTypeSearchCriteria() if (filter) { @@ -156,16 +150,13 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { const fetchOptions = new openbis.DataSetTypeFetchOptions() const result = await openbis.searchDataSetTypes(criteria, fetchOptions) - result.criteria = { - filter, - offset, - limit - } + result.filter = filter + result.offset = offset return result } async searchMaterialTypes(params) { - const { filter, offset, limit } = params + const { filter, offset } = params const criteria = new openbis.MaterialTypeSearchCriteria() if (filter) { @@ -174,16 +165,13 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { const fetchOptions = new openbis.MaterialTypeFetchOptions() const result = await openbis.searchMaterialTypes(criteria, fetchOptions) - result.criteria = { - filter, - offset, - limit - } + result.filter = filter + result.offset = offset return result } async searchVocabularyTypes(params) { - const { filter, offset, limit } = params + const { filter, offset } = params const criteria = new openbis.VocabularySearchCriteria() if (filter) { @@ -192,11 +180,8 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { const fetchOptions = new openbis.VocabularyFetchOptions() const result = await openbis.searchVocabularies(criteria, fetchOptions) - result.criteria = { - filter, - offset, - limit - } + result.filter = filter + result.offset = offset return result } @@ -264,7 +249,7 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { }, canHaveChildren: !!result, selectable: true, - expanded: true + expanded: result && result.filter } if (result) { @@ -279,11 +264,9 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { } createNodes(parent, result, objectType) { - const { offset } = result.criteria - let objects = result.getObjects() objects.sort((o1, o2) => compare(o1.code, o2.code)) - objects = objects.slice(offset, offset + LOAD_LIMIT) + objects = objects.slice(result.offset, result.offset + LOAD_LIMIT) let nodes = objects.map(type => ({ id: TypeBrowserConsts.nodeId(parent.id, objectType, type.getCode()), @@ -300,8 +283,8 @@ export default class TypeBrowserConstsLoadNodesUnfiltered { return { nodes: nodes, loadMore: { - offset: offset + nodes.length, - loadedCount: offset + nodes.length, + offset: result.offset + nodes.length, + loadedCount: result.offset + nodes.length, totalCount: result.getTotalCount(), append: true } diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerReload.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerReload.js similarity index 100% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerReload.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerReload.js diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerRemoveNode.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerRemoveNode.js similarity index 97% rename from openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerRemoveNode.js rename to openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerRemoveNode.js index a86799dffb9a24596c606302f58849dc71b90b6b..ee5ebe2c700a1216cc6e4c3865fdc0613a1ddfb3 100644 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserControllerRemoveNode.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserControllerRemoveNode.js @@ -31,9 +31,9 @@ export default class TypeBrowserControllerRemoveNode { const options = new openbis.SynchronousOperationExecutionOptions() options.setExecuteInOrder(true) await openbis.executeOperations(operations, options) - AppController.getInstance().objectDelete(pages.TYPES, type, id) + await AppController.getInstance().objectDelete(pages.TYPES, type, id) } catch (error) { - AppController.getInstance().errorChange(error) + await AppController.getInstance().errorChange(error) } } diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowser.jsx b/openbis_ng_ui/src/js/components/types/browser2/TypeBrowser.jsx deleted file mode 100644 index c6b991c2e9774400bc5b0b435f9d802ff5e082b9..0000000000000000000000000000000000000000 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowser.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import _ from 'lodash' -import React from 'react' -import autoBind from 'auto-bind' -import BrowserWithOpenbis from '@src/js/components/common/browser2/BrowserWithOpenbis.jsx' -import BrowserButtonsAddRemove from '@src/js/components/common/browser2/BrowserButtonsAddRemove.jsx' -import TypeBrowserController from '@src/js/components/types/browser2/TypeBrowserController.js' -import AppController from '@src/js/components/AppController.js' -import pages from '@src/js/common/consts/pages.js' -import ids from '@src/js/common/consts/ids.js' -import logger from '@src/js/common/logger.js' - -class TypeBrowser extends React.Component { - constructor(props) { - super(props) - autoBind(this) - this.controller = this.props.controller || new TypeBrowserController() - } - - componentDidMount() { - this.componentDidUpdate({}) - } - - componentDidUpdate(prevProps) { - if (!_.isEqual(this.props.selectedObject, prevProps.selectedObject)) { - this.controller.selectObject(this.props.selectedObject) - } - - if ( - !_.isEqual( - this.props.lastObjectModifications, - prevProps.lastObjectModifications - ) - ) { - this.controller.reload(this.props.lastObjectModifications) - } - } - - render() { - logger.log(logger.DEBUG, 'TypeBrowser.render') - - return ( - <BrowserWithOpenbis - id={ids.TYPE_BROWSER_ID} - controller={this.controller} - renderFooter={this.renderFooter} - onSelectedChange={selectedObject => { - if (selectedObject) { - AppController.getInstance().objectOpen( - pages.TYPES, - selectedObject.type, - selectedObject.id - ) - } - }} - /> - ) - } - - renderFooter() { - return ( - <div> - <BrowserButtonsAddRemove - selectedObject={this.controller.getSelectedObject()} - addEnabled={this.controller.canAddNode()} - removeEnabled={this.controller.canRemoveNode()} - onAdd={this.controller.addNode} - onRemove={this.controller.removeNode} - /> - </div> - ) - } -} - -export default AppController.getInstance().withState(() => ({ - selectedObject: AppController.getInstance().getSelectedObject(pages.TYPES), - lastObjectModifications: - AppController.getInstance().getLastObjectModifications() -}))(TypeBrowser) diff --git a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserController.js b/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserController.js deleted file mode 100644 index f59af8844edde5293776e93ff79890b4df87ed20..0000000000000000000000000000000000000000 --- a/openbis_ng_ui/src/js/components/types/browser2/TypeBrowserController.js +++ /dev/null @@ -1,40 +0,0 @@ -import BrowserController from '@src/js/components/common/browser2/BrowserController.js' -import TypeBrowserControllerLoadNodePath from '@src/js/components/types/browser2/TypeBrowserControllerLoadNodePath.js' -import TypeBrowserControllerLoadNodes from '@src/js/components/types/browser2/TypeBrowserControllerLoadNodes.js' -import TypeBrowserControllerAddNode from '@src/js/components/types/browser2/TypeBrowserControllerAddNode.js' -import TypeBrowserControllerRemoveNode from '@src/js/components/types/browser2/TypeBrowserControllerRemoveNode.js' -import TypeBrowserControllerReload from '@src/js/components/types/browser2/TypeBrowserControllerReload.js' - -export default class TypeBrowserController extends BrowserController { - async doLoadNodePath(params) { - return await new TypeBrowserControllerLoadNodePath().doLoadNodePath(params) - } - - async doLoadNodes(params) { - return await new TypeBrowserControllerLoadNodes().doLoadNodes(params) - } - - async reload(objectModifications) { - new TypeBrowserControllerReload(this).reload(objectModifications) - } - - canAddNode() { - return new TypeBrowserControllerAddNode().canAddNode( - this.getSelectedObject() - ) - } - - addNode() { - new TypeBrowserControllerAddNode().doAddNode(this.getSelectedObject()) - } - - canRemoveNode() { - return new TypeBrowserControllerRemoveNode().canRemoveNode( - this.getSelectedObject() - ) - } - - removeNode() { - new TypeBrowserControllerRemoveNode().doRemoveNode(this.getSelectedObject()) - } -} diff --git a/openbis_ng_ui/srcTest/js/components/AppComponentOpenCloseTypes.test.js b/openbis_ng_ui/srcTest/js/components/AppComponentOpenCloseTypes.test.js index d777de208b0bf397d6c223b8a0adf76b32f2a1c5..3f7ba1129f5861a84daeecaef991e6fe75fc3862 100644 --- a/openbis_ng_ui/srcTest/js/components/AppComponentOpenCloseTypes.test.js +++ b/openbis_ng_ui/srcTest/js/components/AppComponentOpenCloseTypes.test.js @@ -23,10 +23,15 @@ async function testOpenCloseTypes() { await common.login(app) + app.getTypes().getBrowser().clickAutoShowSelected() + await app.update() + app.getTypes().getBrowser().getNodes()[0].getIcon().click() await app.update() app.getTypes().getBrowser().getNodes()[2].click() + await app.update() + app.getTypes().getBrowser().getNodes()[1].click() await app.update() diff --git a/openbis_ng_ui/srcTest/js/components/common/browser/wrapper/BrowserWrapper.js b/openbis_ng_ui/srcTest/js/components/common/browser/wrapper/BrowserWrapper.js index 8c8e5697d682079fca9cf2ad806710ecc692450a..fe3d314cb0e1d95de63d96cbffd3638dc6be2395 100644 --- a/openbis_ng_ui/srcTest/js/components/common/browser/wrapper/BrowserWrapper.js +++ b/openbis_ng_ui/srcTest/js/components/common/browser/wrapper/BrowserWrapper.js @@ -1,6 +1,9 @@ import FilterField from '@src/js/components/common/form/FilterField.jsx' import BrowserNode from '@src/js/components/common/browser/BrowserNode.jsx' +import BrowserNode2 from '@src/js/components/common/browser2/BrowserNode.jsx' import BrowserButtons from '@src/js/components/common/browser/BrowserButtons.jsx' +import BrowserButtons2 from '@src/js/components/common/browser2/BrowserButtonsAddRemove.jsx' +import BrowserNodeAutoShowSelected from '@src/js/components/common/browser2/BrowserNodeAutoShowSelected.jsx' import BaseWrapper from '@srcTest/js/components/common/wrapper/BaseWrapper.js' import FilterFieldWrapper from '@srcTest/js/components/common/form/wrapper/FilterFieldWrapper.js' import BrowserNodeWrapper from './BrowserNodeWrapper.js' @@ -11,22 +14,51 @@ export default class BrowserWrapper extends BaseWrapper { return new FilterFieldWrapper(this.findComponent(FilterField)) } + clickAutoShowSelected() { + const showSelectedWrapper = this.findComponent(BrowserNodeAutoShowSelected) + showSelectedWrapper.instance().handleClick({ + stopPropagation: function () {}, + preventDefault: function () {} + }) + } + getNodes() { return this._getNodes(this.wrapper, []) } _getNodes(wrapper, nodes) { wrapper.children().forEach(childWrapper => { + let node = null if (childWrapper.is(this.unwrapComponent(BrowserNode))) { - nodes.push(new BrowserNodeWrapper(childWrapper)) + node = new BrowserNodeWrapper(childWrapper) + } else if (childWrapper.is(this.unwrapComponent(BrowserNode2))) { + node = new BrowserNodeWrapper(childWrapper) + } + + if (node) { + if (node.getLevel() >= 0) { + nodes.push(node) + } + if (node.getExpanded()) { + this._getNodes(childWrapper, nodes) + } + } else { + this._getNodes(childWrapper, nodes) } - this._getNodes(childWrapper, nodes) }) return nodes } getButtons() { - return new BrowserButtonsWrapper(this.findComponent(BrowserButtons)) + const buttons = this.findComponent(BrowserButtons) + if (buttons.exists()) { + return new BrowserButtonsWrapper(buttons) + } + const buttons2 = this.findComponent(BrowserButtons2) + if (buttons2.exists()) { + return new BrowserButtonsWrapper(buttons2) + } + return null } toJSON() { diff --git a/openbis_ng_ui/srcTest/js/components/common/wrapper/BaseWrapper.js b/openbis_ng_ui/srcTest/js/components/common/wrapper/BaseWrapper.js index e2a57b16fe6bb0bdf38fad5f886fdaa342c7b2a5..938a7c67d410e4f2f065d96ad0842155abde68fa 100644 --- a/openbis_ng_ui/srcTest/js/components/common/wrapper/BaseWrapper.js +++ b/openbis_ng_ui/srcTest/js/components/common/wrapper/BaseWrapper.js @@ -63,27 +63,27 @@ export default class BaseWrapper { return this.wrapper.exists() } - async expectJSON(json, timeout) { - if (timeout && timeout > 0) { - const end = Date.now() + timeout - for (;;) { - try { - await this.update() - expect(this.toJSON()).toMatchObject(json) - } catch (error) { - if (Date.now() < end) { - await new Promise(resolve => { - setTimeout(() => { - resolve() - }, 10) - }) - } else { - throw error - } + async expectJSONWaiting(json, timeout) { + const end = Date.now() + timeout + for (;;) { + try { + await this.update() + expect(this.toJSON()).toMatchObject(json) + } catch (error) { + if (Date.now() < end) { + await new Promise(resolve => { + setTimeout(() => { + resolve() + }, 10) + }) + } else { + throw error } } - } else { - expect(this.toJSON()).toMatchObject(json) } } + + expectJSON(json) { + expect(this.toJSON()).toMatchObject(json) + } } diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentFilter.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentFilter.test.js deleted file mode 100644 index ebdef9e6caf88c0b190058afda2236c9a2b33d51..0000000000000000000000000000000000000000 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentFilter.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import TypeBrowserComponentTest from '@srcTest/js/components/types/browser/TypeBrowserComponentTest.js' -import fixture from '@srcTest/js/common/fixture.js' - -let common = null - -beforeEach(() => { - common = new TypeBrowserComponentTest() - common.beforeEach() -}) - -describe(TypeBrowserComponentTest.SUITE, () => { - test('filter', testFilter) -}) - -async function testFilter() { - const browser = await common.mount() - - browser.getFilter().change('ANOTHER') - await browser.update() - - browser.expectJSON({ - filter: { - value: 'ANOTHER' - }, - nodes: [ - { level: 0, text: 'Object Types' }, - { level: 1, text: fixture.ANOTHER_SAMPLE_TYPE_DTO.code }, - { level: 0, text: 'Material Types' }, - { level: 1, text: fixture.ANOTHER_MATERIAL_TYPE_DTO.code }, - { level: 0, text: 'Vocabulary Types' }, - { level: 1, text: fixture.ANOTHER_VOCABULARY_DTO.code } - ] - }) - - browser.getFilter().getClearIcon().click() - await browser.update() - - browser.expectJSON({ - filter: { - value: null - }, - nodes: [ - { level: 0, text: 'Object Types' }, - { level: 1, text: fixture.ANOTHER_SAMPLE_TYPE_DTO.code }, - { level: 1, text: fixture.TEST_SAMPLE_TYPE_DTO.code }, - { level: 0, text: 'Collection Types' }, - { level: 1, text: fixture.TEST_EXPERIMENT_TYPE_DTO.code }, - { level: 0, text: 'Data Set Types' }, - { level: 1, text: fixture.TEST_DATA_SET_TYPE_DTO.code }, - { level: 0, text: 'Material Types' }, - { level: 1, text: fixture.ANOTHER_MATERIAL_TYPE_DTO.code }, - { level: 1, text: fixture.TEST_MATERIAL_TYPE_DTO.code }, - { level: 0, text: 'Vocabulary Types' }, - { level: 1, text: fixture.ANOTHER_VOCABULARY_DTO.code }, - { level: 1, text: fixture.TEST_VOCABULARY_DTO.code }, - { level: 0, text: 'Property Types' } - ] - }) -} diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentSelect.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentSelect.test.js index 1104e369b1cdfbc0046c55d33c6557ada54f5db7..320b65aa64bc20cdf6accea8137564779e35d57d 100644 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentSelect.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserComponentSelect.test.js @@ -16,6 +16,9 @@ describe(TypeBrowserComponentTest.SUITE, () => { async function testSelectEntityKind() { const browser = await common.mount() + browser.clickAutoShowSelected() + await browser.update() + browser.expectJSON({ nodes: [ { level: 0, text: 'Object Types', selected: false }, @@ -61,6 +64,9 @@ async function testSelectEntityKind() { async function testSelectEntityType() { const browser = await common.mount() + browser.clickAutoShowSelected() + await browser.update() + browser.getNodes()[0].getIcon().click() await browser.update() diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerAddNode.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerAddNode.test.js index e6ac9bb3162fe327716ead33e26bca957beb7f16..380e97571b98ba2b6fc9b5d06526b8cc010fdd00 100644 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerAddNode.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerAddNode.test.js @@ -15,8 +15,11 @@ describe(TypeBrowserControllerTest.SUITE, () => { async function testAddNode() { await common.controller.load() - common.controller.nodeSelect('objectTypes') - common.controller.nodeAdd() + await common.controller.selectObject({ + type: objectType.OVERVIEW, + id: objectType.OBJECT_TYPE + }) + await common.controller.addNode() common.expectNewTypeAction(objectType.NEW_OBJECT_TYPE) } diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerFilter.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerFilter.test.js deleted file mode 100644 index 58505229bb8dd6ca2ebe6b535e7c6e5144f6b4b3..0000000000000000000000000000000000000000 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerFilter.test.js +++ /dev/null @@ -1,58 +0,0 @@ -import TypeBrowserControllerTest from '@srcTest/js/components/types/browser/TypeBrowserControllerTest.js' -import fixture from '@srcTest/js/common/fixture.js' - -let common = null - -beforeEach(() => { - common = new TypeBrowserControllerTest() - common.beforeEach() -}) - -describe(TypeBrowserControllerTest.SUITE, () => { - test('filter', testFilter) -}) - -async function testFilter() { - await common.controller.load() - - common.controller.filterChange('ANOTHER') - - expect(common.controller.getNodes()).toMatchObject([ - { - text: 'Object Types', - expanded: true, - selected: false, - children: [ - { - text: fixture.ANOTHER_SAMPLE_TYPE_DTO.code, - expanded: false, - selected: false - } - ] - }, - { - text: 'Material Types', - expanded: true, - selected: false, - children: [ - { - text: fixture.ANOTHER_MATERIAL_TYPE_DTO.code, - expanded: false, - selected: false - } - ] - }, - { - text: 'Vocabulary Types', - expanded: true, - selected: false, - children: [ - { - text: fixture.ANOTHER_VOCABULARY_DTO.code, - expanded: false, - selected: false - } - ] - } - ]) -} diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerLoad.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerLoad.test.js index c3a91cd7b500e5d4bf25a7f96c2b739b0d349f98..b06cdb801b67bc6caaa9610ffa4a527214848392 100644 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerLoad.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerLoad.test.js @@ -14,36 +14,39 @@ describe(TypeBrowserControllerTest.SUITE, () => { async function testLoad() { await common.controller.load() - expect(common.controller.getNodes()).toMatchObject([ - { - text: 'Object Types', - expanded: false, - selected: false - }, - { - text: 'Collection Types', - expanded: false, - selected: false - }, - { - text: 'Data Set Types', - expanded: false, - selected: false - }, - { - text: 'Material Types', - expanded: false, - selected: false - }, - { - text: 'Vocabulary Types', - expanded: false, - selected: false - }, - { - text: 'Property Types', - expanded: false, - selected: false - } - ]) + expect(common.controller.getTree()).toMatchObject({ + id: 'root', + children: [ + { + text: 'Object Types', + expanded: false, + selected: false + }, + { + text: 'Collection Types', + expanded: false, + selected: false + }, + { + text: 'Data Set Types', + expanded: false, + selected: false + }, + { + text: 'Material Types', + expanded: false, + selected: false + }, + { + text: 'Vocabulary Types', + expanded: false, + selected: false + }, + { + text: 'Property Types', + expanded: false, + selected: false + } + ] + }) } diff --git a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerRemoveNode.test.js b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerRemoveNode.test.js index b1315e22b21f108406c907989610ee1b8d8d9fc6..3dbec9aa3feba0decb2ccf99ecb53bd83283c6b6 100644 --- a/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerRemoveNode.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/browser/TypeBrowserControllerRemoveNode.test.js @@ -19,21 +19,15 @@ async function testRemoveNode() { openbis.deleteSampleTypes.mockReturnValue(Promise.resolve()) await common.controller.load() + await common.controller.changeAutoShowSelectedObject() - expect(common.controller.isRemoveNodeDialogOpen()).toBe(false) expect(openbis.deleteSampleTypes).toHaveBeenCalledTimes(0) - common.controller.nodeSelect( - 'objectTypes/' + fixture.TEST_SAMPLE_TYPE_DTO.code - ) - common.controller.nodeRemove() - - expect(common.controller.isRemoveNodeDialogOpen()).toBe(true) - expect(openbis.deleteSampleTypes).toHaveBeenCalledTimes(0) - - await common.controller.nodeRemoveConfirm() - - expect(common.controller.isRemoveNodeDialogOpen()).toBe(false) + await common.controller.selectObject({ + type: objectType.OBJECT_TYPE, + id: fixture.TEST_SAMPLE_TYPE_DTO.code + }) + await common.controller.removeNode() const createDeleteTypeOperation = typeCode => { const id = new openbis.EntityTypePermId(typeCode) diff --git a/openbis_ng_ui/srcTest/js/components/types/form/vocabularytype/VocabularyTypeFormComponentFilter.test.js b/openbis_ng_ui/srcTest/js/components/types/form/vocabularytype/VocabularyTypeFormComponentFilter.test.js index 1449194da4e171ee808cc8009a03b74ab8d97609..035f8f3f0feabc2ee0ac22234eab870150a4a6ee 100644 --- a/openbis_ng_ui/srcTest/js/components/types/form/vocabularytype/VocabularyTypeFormComponentFilter.test.js +++ b/openbis_ng_ui/srcTest/js/components/types/form/vocabularytype/VocabularyTypeFormComponentFilter.test.js @@ -40,7 +40,7 @@ async function testFilter() { form.getGrid().getColumns()[1].getFilter().change('some') await form.update() - form.expectJSON( + form.expectJSONWaiting( { grid: { columns: [ @@ -65,7 +65,7 @@ async function testFilter() { form.getGrid().getColumns()[1].getFilter().change('1') await form.update() - form.expectJSON( + form.expectJSONWaiting( { grid: { columns: [ diff --git a/openbis_ng_ui/srcTest/js/components/types/wrapper/TypesWrapper.js b/openbis_ng_ui/srcTest/js/components/types/wrapper/TypesWrapper.js index df9bdf910c8ea25fcf5dc1bc79d9007e0c7df5bf..4367098ff1d40934146874eb381a3a1d0dbe0bca 100644 --- a/openbis_ng_ui/srcTest/js/components/types/wrapper/TypesWrapper.js +++ b/openbis_ng_ui/srcTest/js/components/types/wrapper/TypesWrapper.js @@ -1,12 +1,12 @@ import Content from '@src/js/components/common/content/Content.jsx' -import TypesBrowser from '@src/js/components/types/browser/TypeBrowser.jsx' +import { TypeBrowser } from '@src/js/components/types/browser/TypeBrowser.jsx' import BaseWrapper from '@srcTest/js/components/common/wrapper/BaseWrapper.js' import BrowserWrapper from '@srcTest/js/components/common/browser/wrapper/BrowserWrapper.js' import ContentWrapper from '@srcTest/js/components/common/content/wrapper/ContentWrapper.js' export default class TypesWrapper extends BaseWrapper { getBrowser() { - return new BrowserWrapper(this.findComponent(TypesBrowser)) + return new BrowserWrapper(this.findComponent(TypeBrowser)) } getContent() {