Skip to content
Snippets Groups Projects
Commit 494fa7f4 authored by piotr.kupczyk@id.ethz.ch's avatar piotr.kupczyk@id.ethz.ch
Browse files

SSDM-13191 : New Navigation - migrate Admin UI from old component to new...

SSDM-13191 : New Navigation - migrate Admin UI from old component to new component - first version of the new types navigation
parent 3eda6699
No related branches found
No related tags found
1 merge request!40SSDM-13578 : 2PT : Database and V3 Implementation - include the new AFS "free"...
...@@ -29,6 +29,7 @@ const PERSONAL_ACCESS_TOKEN_GRID_ID = 'personal_access_token_grid' ...@@ -29,6 +29,7 @@ const PERSONAL_ACCESS_TOKEN_GRID_ID = 'personal_access_token_grid'
// browsers // browsers
const DATABASE_BROWSER_ID = 'database_browser' const DATABASE_BROWSER_ID = 'database_browser'
const TYPE_BROWSER_ID = 'type_browser'
export default { export default {
// app // app
...@@ -63,5 +64,6 @@ export default { ...@@ -63,5 +64,6 @@ export default {
PERSONAL_ACCESS_TOKEN_GRID_ID, PERSONAL_ACCESS_TOKEN_GRID_ID,
// browsers // browsers
DATABASE_BROWSER_ID DATABASE_BROWSER_ID,
TYPE_BROWSER_ID
} }
...@@ -2,7 +2,7 @@ import React from 'react' ...@@ -2,7 +2,7 @@ import React from 'react'
import { withStyles } from '@material-ui/core/styles' import { withStyles } from '@material-ui/core/styles'
import Content from '@src/js/components/common/content/Content.jsx' import Content from '@src/js/components/common/content/Content.jsx'
import ContentTab from '@src/js/components/common/content/ContentTab.jsx' import ContentTab from '@src/js/components/common/content/ContentTab.jsx'
import TypeBrowser from '@src/js/components/types/browser/TypeBrowser.jsx' import TypeBrowser from '@src/js/components/types/browser2/TypeBrowser.jsx'
import TypeSearch from '@src/js/components/types/search/TypeSearch.jsx' import TypeSearch from '@src/js/components/types/search/TypeSearch.jsx'
import EntityTypeForm from '@src/js/components/types/form/entitytype/EntityTypeForm.jsx' import EntityTypeForm from '@src/js/components/types/form/entitytype/EntityTypeForm.jsx'
import VocabularyTypeForm from '@src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx' import VocabularyTypeForm from '@src/js/components/types/form/vocabularytype/VocabularyTypeForm.jsx'
......
import _ from 'lodash'
import React from 'react'
import BrowserWithSettings from '@src/js/components/common/browser2/BrowserWithSettings.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)
this.controller = this.props.controller || new TypeBrowserController()
}
componentDidMount() {
this.componentDidUpdate(null)
}
componentDidUpdate(prevProps) {
const prevSelectedObject = prevProps ? prevProps.selectedObject : null
const selectedObject = this.props.selectedObject
if (!_.isEqual(prevSelectedObject, selectedObject)) {
this.controller.selectObject(this.props.selectedObject)
}
}
render() {
logger.log(logger.DEBUG, 'TypeBrowser.render')
return (
<BrowserWithSettings
id={ids.TYPE_BROWSER_ID}
controller={this.controller}
onSelectedChange={selectedObject => {
if (selectedObject) {
AppController.getInstance().objectOpen(
pages.TYPES,
selectedObject.type,
selectedObject.id
)
}
}}
/>
)
}
}
export default AppController.getInstance().withState(() => ({
selectedObject: AppController.getInstance().getSelectedObject(pages.TYPES)
}))(TypeBrowser)
import messages from '@src/js/common/messages.js'
const TYPE_ROOT = 'root'
const TYPE_WARNING = 'warning'
const TEXT_OBJECT_TYPES = messages.get(messages.OBJECT_TYPES)
const TEXT_COLLECTION_TYPES = messages.get(messages.COLLECTION_TYPES)
const TEXT_DATA_SET_TYPES = messages.get(messages.DATA_SET_TYPES)
const TEXT_MATERIAL_TYPES = messages.get(messages.MATERIAL_TYPES)
const TEXT_VOCABULARY_TYPES = messages.get(messages.VOCABULARY_TYPES)
const TEXT_PROPERTY_TYPES = messages.get(messages.PROPERTY_TYPES)
function nodeId(...parts) {
return parts.join('__')
}
export default {
nodeId,
TYPE_ROOT,
TYPE_WARNING,
TEXT_OBJECT_TYPES,
TEXT_COLLECTION_TYPES,
TEXT_DATA_SET_TYPES,
TEXT_MATERIAL_TYPES,
TEXT_VOCABULARY_TYPES,
TEXT_PROPERTY_TYPES
}
import BrowserController from '@src/js/components/common/browser2/BrowserController.js'
import TypeBrowserControllerLoadNodePath from '@src/js/components/types/browser2/TypeBrowserControllerLoadNodePath.js'
import TypeBrowserControllerLoadNodesFiltered from '@src/js/components/types/browser2/TypeBrowserControllerLoadNodesFiltered.js'
import TypeBrowserControllerLoadNodesUnfiltered from '@src/js/components/types/browser2/TypeBrowserControllerLoadNodesUnfiltered.js'
export default class TypeBrowserController extends BrowserController {
async doLoadNodePath(params) {
return await new TypeBrowserControllerLoadNodePath().doLoadNodePath(params)
}
async doLoadNodes(params) {
const { filter } = params
if (filter) {
return await new TypeBrowserControllerLoadNodesFiltered().doLoadFilteredNodes(
params
)
} else {
return await new TypeBrowserControllerLoadNodesUnfiltered().doLoadUnfilteredNodes(
params
)
}
}
}
import TypeBrowserConsts from '@src/js/components/types/browser2/TypeBrowserConsts.js'
import openbis from '@src/js/services/openbis.js'
import objectType from '@src/js/common/consts/objectType.js'
export default class TypeBrowserConstsLoadNodePath {
async doLoadNodePath(params) {
const { object } = params
if (object.type === objectType.OVERVIEW) {
if (object.id === objectType.OBJECT_TYPE) {
return this.createFolderPath(
objectType.OBJECT_TYPE,
TypeBrowserConsts.TEXT_OBJECT_TYPES
)
} else if (object.id === objectType.COLLECTION_TYPE) {
return this.createFolderPath(
objectType.COLLECTION_TYPE,
TypeBrowserConsts.TEXT_COLLECTION_TYPES
)
} else if (object.id === objectType.DATA_SET_TYPE) {
return this.createFolderPath(
objectType.DATA_SET_TYPE,
TypeBrowserConsts.TEXT_DATA_SET_TYPES
)
} else if (object.id === objectType.MATERIAL_TYPE) {
return this.createFolderPath(
objectType.MATERIAL_TYPE,
TypeBrowserConsts.TEXT_MATERIAL_TYPES
)
} else if (object.id === objectType.VOCABULARY_TYPE) {
return this.createFolderPath(
objectType.VOCABULARY_TYPE,
TypeBrowserConsts.TEXT_VOCABULARY_TYPES
)
} else if (object.id === objectType.PROPERTY_TYPE) {
return this.createFolderPath(
objectType.PROPERTY_TYPE,
TypeBrowserConsts.TEXT_PROPERTY_TYPES
)
}
} else if (object.type === objectType.OBJECT_TYPE) {
const id = new openbis.EntityTypePermId(object.id)
const fetchOptions = new openbis.SampleTypeFetchOptions()
const types = await openbis.getSampleTypes([id], fetchOptions)
const type = types[object.id]
return this.createTypePath(
object,
type,
objectType.OBJECT_TYPE,
TypeBrowserConsts.TEXT_OBJECT_TYPES
)
} else if (object.type === objectType.COLLECTION_TYPE) {
const id = new openbis.EntityTypePermId(object.id)
const fetchOptions = new openbis.ExperimentTypeFetchOptions()
const types = await openbis.getExperimentTypes([id], fetchOptions)
const type = types[object.id]
return this.createTypePath(
object,
type,
objectType.COLLECTION_TYPE,
TypeBrowserConsts.TEXT_COLLECTION_TYPES
)
} else if (object.type === objectType.DATA_SET_TYPE) {
const id = new openbis.EntityTypePermId(object.id)
const fetchOptions = new openbis.DataSetTypeFetchOptions()
const types = await openbis.getDataSetTypes([id], fetchOptions)
const type = types[object.id]
return this.createTypePath(
object,
type,
objectType.DATA_SET_TYPE,
TypeBrowserConsts.TEXT_DATA_SET_TYPES
)
} else if (object.type === objectType.MATERIAL_TYPE) {
const id = new openbis.EntityTypePermId(object.id)
const fetchOptions = new openbis.MaterialTypeFetchOptions()
const types = await openbis.getMaterialTypes([id], fetchOptions)
const type = types[object.id]
return this.createTypePath(
object,
type,
objectType.MATERIAL_TYPE,
TypeBrowserConsts.TEXT_MATERIAL_TYPES
)
} else if (object.type === objectType.VOCABULARY_TYPE) {
const id = new openbis.VocabularyPermId(object.id)
const fetchOptions = new openbis.VocabularyFetchOptions()
const types = await openbis.getVocabularies([id], fetchOptions)
const type = types[object.id]
return this.createTypePath(
object,
type,
objectType.VOCABULARY_TYPE,
TypeBrowserConsts.TEXT_VOCABULARY_TYPES
)
} else {
return null
}
}
createFolderPath(folderObjectType, folderText) {
return [
{
id: TypeBrowserConsts.nodeId(
TypeBrowserConsts.TYPE_ROOT,
folderObjectType
),
object: { type: objectType.OVERVIEW, id: folderObjectType },
text: folderText
}
]
}
createTypePath(object, type, folderObjectType, folderText) {
if (type) {
const folderPath = this.createFolderPath(folderObjectType, folderText)
return [
...folderPath,
{
id: TypeBrowserConsts.nodeId(
TypeBrowserConsts.TYPE_ROOT,
folderObjectType,
folderObjectType,
type.getCode()
),
object,
text: object.id
}
]
} else {
return null
}
}
}
import _ from 'lodash'
import TypeBrowserConsts from '@src/js/components/types/browser2/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'
import compare from '@src/js/common/compare.js'
const LOAD_LIMIT = 50
const TOTAL_LOAD_LIMIT = 500
export default class TypeBrowserConstsLoadNodesFiltered {
async doLoadFilteredNodes(params) {
const { node } = params
const [
objectTypes,
collectionTypes,
dataSetTypes,
materialTypes,
vocabularyTypes
] = await Promise.all([
this.searchObjectTypes(params),
this.searchCollectionTypes(params),
this.searchDataSetTypes(params),
this.searchMaterialTypes(params),
this.searchVocabularyTypes(params)
])
const loadedCount =
objectTypes.getObjects().length +
collectionTypes.getObjects().length +
dataSetTypes.getObjects().length +
materialTypes.getObjects().length +
vocabularyTypes.getObjects().length
const totalCount =
objectTypes.getTotalCount() +
collectionTypes.getTotalCount() +
dataSetTypes.getTotalCount() +
materialTypes.getTotalCount() +
vocabularyTypes.getTotalCount()
if (totalCount > TOTAL_LOAD_LIMIT) {
return this.tooManyResultsFound(node)
}
const result = {
nodes: [],
loadMore: {
offset: 0,
limit: TOTAL_LOAD_LIMIT,
loadedCount: loadedCount,
totalCount: totalCount,
append: false
}
}
if (node.internalRoot) {
const root = {
id: TypeBrowserConsts.TYPE_ROOT,
object: {
type: TypeBrowserConsts.TYPE_ROOT
},
canHaveChildren: true
}
root.children = this.doLoadFilteredNodes({
...params,
node: root
})
result.nodes.push(root)
} else if (node.object.type === TypeBrowserConsts.TYPE_ROOT) {
if (!_.isEmpty(objectTypes.getObjects())) {
const objectTypesNode = this.createObjectTypesNode(
params,
objectTypes.getObjects()
)
result.nodes.push(objectTypesNode)
}
if (!_.isEmpty(collectionTypes.getObjects())) {
const collectionTypesNode = this.createCollectionTypesNode(
params,
collectionTypes.getObjects()
)
result.nodes.push(collectionTypesNode)
}
if (!_.isEmpty(dataSetTypes.getObjects())) {
const dataSetTypesNode = this.createDataSetTypesNode(
params,
dataSetTypes.getObjects()
)
result.nodes.push(dataSetTypesNode)
}
if (!_.isEmpty(materialTypes.getObjects())) {
const materialTypesNode = this.createMaterialTypesNode(
params,
materialTypes.getObjects()
)
result.nodes.push(materialTypesNode)
}
if (!_.isEmpty(vocabularyTypes.getObjects())) {
const vocabularyTypesNode = this.createVocabularyTypesNode(
params,
vocabularyTypes.getObjects()
)
result.nodes.push(vocabularyTypesNode)
}
}
return result
}
tooManyResultsFound(node) {
return {
nodes: [
{
id: TypeBrowserConsts.nodeId(node.id, TypeBrowserConsts.TYPE_WARNING),
message: {
type: 'warning',
text: messages.get(messages.TOO_MANY_FILTERED_RESULTS_FOUND)
},
selectable: false
}
]
}
}
async searchObjectTypes(params) {
const { filter, offset, limit } = params
const criteria = new openbis.SampleTypeSearchCriteria()
criteria.withCode().thatContains(filter)
const fetchOptions = new openbis.SampleTypeFetchOptions()
fetchOptions.from(offset)
fetchOptions.count(limit || LOAD_LIMIT)
const result = await openbis.searchSampleTypes(criteria, fetchOptions)
return result
}
async searchCollectionTypes(params) {
const { filter, offset, limit } = params
const criteria = new openbis.ExperimentTypeSearchCriteria()
criteria.withCode().thatContains(filter)
const fetchOptions = new openbis.ExperimentTypeFetchOptions()
fetchOptions.from(offset)
fetchOptions.count(limit || LOAD_LIMIT)
const result = await openbis.searchExperimentTypes(criteria, fetchOptions)
return result
}
async searchDataSetTypes(params) {
const { filter, offset, limit } = params
const criteria = new openbis.DataSetTypeSearchCriteria()
criteria.withCode().thatContains(filter)
const fetchOptions = new openbis.DataSetTypeFetchOptions()
fetchOptions.from(offset)
fetchOptions.count(limit || LOAD_LIMIT)
const result = await openbis.searchDataSetTypes(criteria, fetchOptions)
return result
}
async searchMaterialTypes(params) {
const { filter, offset, limit } = params
const criteria = new openbis.MaterialTypeSearchCriteria()
criteria.withCode().thatContains(filter)
const fetchOptions = new openbis.MaterialTypeFetchOptions()
fetchOptions.from(offset)
fetchOptions.count(limit || LOAD_LIMIT)
const result = await openbis.searchMaterialTypes(criteria, fetchOptions)
return result
}
async searchVocabularyTypes(params) {
const { filter, offset, limit } = params
const criteria = new openbis.VocabularySearchCriteria()
criteria.withCode().thatContains(filter)
const fetchOptions = new openbis.VocabularyFetchOptions()
fetchOptions.from(offset)
fetchOptions.count(limit || LOAD_LIMIT)
const result = await openbis.searchVocabularies(criteria, fetchOptions)
return result
}
createObjectTypesNode(params, types) {
return this.createNodesFolder(
params,
types,
objectType.OBJECT_TYPE,
TypeBrowserConsts.TEXT_OBJECT_TYPES
)
}
createCollectionTypesNode(params, types) {
return this.createNodesFolder(
params,
types,
objectType.COLLECTION_TYPE,
TypeBrowserConsts.TEXT_COLLECTION_TYPES
)
}
createDataSetTypesNode(params, types) {
return this.createNodesFolder(
params,
types,
objectType.DATA_SET_TYPE,
TypeBrowserConsts.TEXT_DATA_SET_TYPES
)
}
createMaterialTypesNode(params, types) {
return this.createNodesFolder(
params,
types,
objectType.MATERIAL_TYPE,
TypeBrowserConsts.TEXT_MATERIAL_TYPES
)
}
createVocabularyTypesNode(params, types) {
return this.createNodesFolder(
params,
types,
objectType.VOCABULARY_TYPE,
TypeBrowserConsts.TEXT_VOCABULARY_TYPES
)
}
createNodesFolder(params, types, folderObjectType, folderText) {
const { node } = params
const folderNode = {
id: TypeBrowserConsts.nodeId(node.id, folderObjectType),
text: folderText,
object: {
type: objectType.OVERVIEW,
id: folderObjectType
},
canHaveChildren: true,
children: { nodes: [] },
expanded: true
}
types.sort((o1, o2) => compare(o1.code, o2.code))
types.forEach(type => {
const typeNode = {
id: TypeBrowserConsts.nodeId(
folderNode.id,
folderObjectType,
type.code
),
text: type.code,
object: {
type: folderObjectType,
id: type.code
}
}
folderNode.children.nodes.push(typeNode)
})
return folderNode
}
}
import _ from 'lodash'
import TypeBrowserConsts from '@src/js/components/types/browser2/TypeBrowserConsts.js'
import openbis from '@src/js/services/openbis.js'
import objectType from '@src/js/common/consts/objectType.js'
import compare from '@src/js/common/compare.js'
const LOAD_LIMIT = 50
export default class TypeBrowserConstsLoadNodesUnfiltered {
async doLoadUnfilteredNodes(params) {
const { node } = params
if (node.internalRoot) {
return {
nodes: [
{
id: TypeBrowserConsts.TYPE_ROOT,
object: {
type: TypeBrowserConsts.TYPE_ROOT
},
canHaveChildren: true
}
]
}
} else if (node.object.type === TypeBrowserConsts.TYPE_ROOT) {
const nodes = []
await this.addObjectTypesNode(params, nodes)
await this.addCollectionTypesNode(params, nodes)
await this.addDataSetTypesNode(params, nodes)
await this.addMaterialTypesNode(params, nodes)
await this.addVocabularyTypesNode(params, nodes)
await this.addPropertyTypesNode(params, nodes)
return {
nodes: nodes
}
} else if (node.object.type === objectType.OVERVIEW) {
if (node.object.id === objectType.OBJECT_TYPE) {
return await this.searchObjectTypes(params)
} else if (node.object.id === objectType.COLLECTION_TYPE) {
return await this.searchCollectionTypes(params)
} else if (node.object.id === objectType.DATA_SET_TYPE) {
return await this.searchDataSetTypes(params)
} else if (node.object.id === objectType.MATERIAL_TYPE) {
return await this.searchMaterialTypes(params)
} else if (node.object.id === objectType.VOCABULARY_TYPE) {
return await this.searchVocabularyTypes(params)
} else if (node.object.id === objectType.PROPERTY_TYPE) {
return await this.searchPropertyTypes(params)
}
} else {
return null
}
}
async searchObjectTypes(params) {
const criteria = new openbis.SampleTypeSearchCriteria()
const fetchOptions = new openbis.SampleTypeFetchOptions()
const result = await openbis.searchSampleTypes(criteria, fetchOptions)
return this.createNodes(params, objectType.OBJECT_TYPE, result)
}
async searchCollectionTypes(params) {
const criteria = new openbis.ExperimentTypeSearchCriteria()
const fetchOptions = new openbis.ExperimentTypeFetchOptions()
const result = await openbis.searchExperimentTypes(criteria, fetchOptions)
return this.createNodes(params, objectType.COLLECTION_TYPE, result)
}
async searchDataSetTypes(params) {
const criteria = new openbis.DataSetTypeSearchCriteria()
const fetchOptions = new openbis.DataSetTypeFetchOptions()
const result = await openbis.searchDataSetTypes(criteria, fetchOptions)
return this.createNodes(params, objectType.DATA_SET_TYPE, result)
}
async searchMaterialTypes(params) {
const criteria = new openbis.MaterialTypeSearchCriteria()
const fetchOptions = new openbis.MaterialTypeFetchOptions()
const result = await openbis.searchMaterialTypes(criteria, fetchOptions)
return this.createNodes(params, objectType.MATERIAL_TYPE, result)
}
async searchVocabularyTypes(params) {
const criteria = new openbis.VocabularySearchCriteria()
const fetchOptions = new openbis.VocabularyFetchOptions()
const result = await openbis.searchVocabularies(criteria, fetchOptions)
return this.createNodes(params, objectType.VOCABULARY_TYPE, result)
}
async addObjectTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.OBJECT_TYPE,
TypeBrowserConsts.TEXT_OBJECT_TYPES,
this.searchObjectTypes.bind(this)
)
if (folderNode) {
nodes.push(folderNode)
}
}
async addCollectionTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.COLLECTION_TYPE,
TypeBrowserConsts.TEXT_COLLECTION_TYPES,
this.searchCollectionTypes.bind(this)
)
if (folderNode) {
nodes.push(folderNode)
}
}
async addDataSetTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.DATA_SET_TYPE,
TypeBrowserConsts.TEXT_DATA_SET_TYPES,
this.searchDataSetTypes.bind(this)
)
if (folderNode) {
nodes.push(folderNode)
}
}
async addMaterialTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.MATERIAL_TYPE,
TypeBrowserConsts.TEXT_MATERIAL_TYPES,
this.searchMaterialTypes.bind(this)
)
if (folderNode) {
nodes.push(folderNode)
}
}
async addVocabularyTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.VOCABULARY_TYPE,
TypeBrowserConsts.TEXT_VOCABULARY_TYPES,
this.searchVocabularyTypes.bind(this)
)
if (folderNode) {
nodes.push(folderNode)
}
}
async addPropertyTypesNode(params, nodes) {
const folderNode = await this.createNodesFolder(
params,
objectType.PROPERTY_TYPE,
TypeBrowserConsts.TEXT_PROPERTY_TYPES,
() => []
)
if (folderNode) {
folderNode.canHaveChildren = false
nodes.push(folderNode)
}
}
createNodes(params, objectType, result) {
const { node, offset } = params
let nodes = result.getObjects().map(type => ({
id: TypeBrowserConsts.nodeId(node.id, objectType, type.getCode()),
text: type.getCode(),
object: {
type: objectType,
id: type.getCode()
}
}))
nodes.sort((n1, n2) => compare(n1.text, n2.text))
nodes = nodes.slice(offset, offset + LOAD_LIMIT)
if (_.isEmpty(nodes)) {
return null
} else {
return {
nodes: nodes,
loadMore: {
offset: offset + nodes.length,
loadedCount: offset + nodes.length,
totalCount: result.getTotalCount(),
append: offset > 0
}
}
}
}
async createNodesFolder(params, folderObjectType, folderText, search) {
const { node } = params
const folderNode = {
id: TypeBrowserConsts.nodeId(node.id, folderObjectType),
text: folderText,
object: {
type: objectType.OVERVIEW,
id: folderObjectType
},
canHaveChildren: true,
selectable: true
}
const nodes = await search({
...params,
node: folderNode
})
if (nodes) {
folderNode.children = nodes
return folderNode
} else {
return null
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment