From f3942c2e6fe161040518d06eb3bc45d12c5a6d7f Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Fri, 8 Apr 2022 14:02:09 +0200 Subject: [PATCH] SSDM-12468 : ELN Table : poor performance of value truncating mechanism - move truncating logic from ELN to the table widget core --- openbis_ng_ui/src/js/common/messages.js | 4 + .../js/components/common/grid/GridCell.jsx | 78 +++++++++++++++---- .../components/common/grid/GridController.js | 3 +- .../js/components/users/common/UsersGrid.jsx | 2 +- .../webapps/eln-lims/html/js/util/FormUtil.js | 48 +----------- .../AdvancedSearch/AdvancedSearchView.js | 2 +- .../js/views/DataGrid/DataGridController.js | 4 +- .../views/DataGrid/ExperimentDataGridUtil.js | 2 +- .../js/views/DataGrid/SampleDataGridUtil.js | 2 +- 9 files changed, 76 insertions(+), 69 deletions(-) diff --git a/openbis_ng_ui/src/js/common/messages.js b/openbis_ng_ui/src/js/common/messages.js index 6eddc089198..208b7da10ab 100644 --- a/openbis_ng_ui/src/js/common/messages.js +++ b/openbis_ng_ui/src/js/common/messages.js @@ -102,6 +102,7 @@ const keys = { LABEL: 'LABEL', LAST_NAME: 'LAST_NAME', LAST_PAGE: 'LAST_PAGE', + LESS: 'LESS', LEVEL: 'LEVEL', LOGIN: 'LOGIN', MAIN_DATA_SET_PATH: 'MAIN_DATA_SET_PATH', @@ -110,6 +111,7 @@ const keys = { MATERIAL_TYPE: 'MATERIAL_TYPE', MATERIAL_TYPES: 'MATERIAL_TYPES', META_DATA: 'META_DATA', + MORE: 'MORE', NAME: 'NAME', NEW_COLLECTION_TYPE: 'NEW_COLLECTION_TYPE', NEW_DATA_SET_TYPE: 'NEW_DATA_SET_TYPE', @@ -336,6 +338,7 @@ const messages_en = { [keys.LABEL]: 'Label', [keys.LAST_NAME]: 'Last Name', [keys.LAST_PAGE]: 'Last Page', + [keys.LESS]: 'Less', [keys.LEVEL]: 'Level', [keys.LOGIN]: 'Login', [keys.MAIN_DATA_SET_PATH]: 'Main Data Set Path', @@ -344,6 +347,7 @@ const messages_en = { [keys.MATERIAL_TYPES]: 'Material Types', [keys.MATERIAL_TYPE]: 'Material Type', [keys.META_DATA]: 'Meta Data', + [keys.MORE]: 'More', [keys.NAME]: 'Name', [keys.NEW_COLLECTION_TYPE]: 'New Collection Type', [keys.NEW_DATA_SET_TYPE]: 'New Data Set Type', diff --git a/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx b/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx index 0e3b2dbb8f2..8a2fa7e31dc 100644 --- a/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx +++ b/openbis_ng_ui/src/js/components/common/grid/GridCell.jsx @@ -2,8 +2,12 @@ import _ from 'lodash' import React from 'react' import { withStyles } from '@material-ui/core/styles' import TableCell from '@material-ui/core/TableCell' +import Link from '@material-ui/core/Link' +import messages from '@src/js/common/messages.js' import logger from '@src/js/common/logger.js' +const TRUNCATE_HEIGHT = 50 + const styles = theme => ({ cell: { paddingTop: theme.spacing(1), @@ -15,50 +19,63 @@ const styles = theme => ({ content: '"\\a0"' } }, - wrap: { - whiteSpace: 'normal' - }, nowrap: { whiteSpace: 'nowrap' + }, + truncate: { + maxHeight: TRUNCATE_HEIGHT + 'px', + overflow: 'hidden' } }) class GridCell extends React.PureComponent { constructor(props) { super(props) + + this.state = { + renderMore: false, + moreOpen: false + } this.ref = React.createRef() + this.handleMoreClick = this.handleMoreClick.bind(this) } componentDidMount() { this.renderDOMValue() + this.maybeScheduleRenderMore() } - componentDidUpdate() { - this.renderDOMValue() + handleMoreClick() { + this.setState(state => ({ + moreOpen: !state.moreOpen + })) } render() { logger.log(logger.DEBUG, 'GridCell.render') const { column, className, classes } = this.props + const { moreOpen } = this.state const cellClasses = [classes.cell] - if (column.wrappable) { - cellClasses.push(classes.wrap) - } else { - cellClasses.push(classes.nowrap) - } if (className) { cellClasses.push(className) } + const divClasses = [] + if (column.nowrap) { + divClasses.push(classes.nowrap) + } + if (column.truncate && !moreOpen) { + divClasses.push(classes.truncate) + } + return ( - <TableCell - ref={this.ref} - key={column.name} - classes={{ root: cellClasses.join(' ') }} - > - {column.renderDOMValue ? null : this.renderValue()} + <TableCell key={column.name} classes={{ root: cellClasses.join(' ') }}> + <div ref={this.ref} className={divClasses.join(' ')}> + {column.renderDOMValue ? null : this.renderValue()} + </div> + {this.renderMore()} </TableCell> ) } @@ -97,6 +114,35 @@ class GridCell extends React.PureComponent { }) } } + + renderMore() { + const { renderMore, moreOpen } = this.state + + if (!renderMore) { + return null + } + + return ( + <div> + <Link onClick={this.handleMoreClick}> + {moreOpen ? messages.get(messages.LESS) : messages.get(messages.MORE)} + </Link> + </div> + ) + } + + maybeScheduleRenderMore() { + const { column } = this.props + if ( + column.truncate && + this.ref.current && + this.ref.current.scrollHeight > TRUNCATE_HEIGHT + ) { + setTimeout(() => { + this.setState({ renderMore: true }) + }, 1) + } + } } export default withStyles(styles)(GridCell) diff --git a/openbis_ng_ui/src/js/components/common/grid/GridController.js b/openbis_ng_ui/src/js/components/common/grid/GridController.js index 6c7a4df5e86..1870d74fd49 100644 --- a/openbis_ng_ui/src/js/components/common/grid/GridController.js +++ b/openbis_ng_ui/src/js/components/common/grid/GridController.js @@ -365,10 +365,11 @@ export default class GridController { sortable: column.sortable === undefined ? true : column.sortable, filterable: column.filterable === undefined ? true : column.filterable, visible: column.visible === undefined ? true : column.visible, - wrappable: column.wrappable === undefined ? true : column.wrappable, configurable: column.configurable === undefined ? true : column.configurable, exportable: column.exportable === undefined ? true : column.exportable, + nowrap: column.nowrap === undefined ? false : column.nowrap, + truncate: column.truncate === undefined ? false : column.truncate, metadata: column.metadata === undefined ? {} : column.metadata } } diff --git a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx index 97f4a0c49a3..b247f9558d5 100644 --- a/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx +++ b/openbis_ng_ui/src/js/components/users/common/UsersGrid.jsx @@ -49,7 +49,7 @@ class UsersGrid extends React.PureComponent { { name: 'email', label: messages.get(messages.EMAIL), - wrappable: false, + nowrap: true, getValue: ({ row }) => row.email.value }, { diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js index cf496c14ff8..0c6d163cbff 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/util/FormUtil.js @@ -2285,47 +2285,6 @@ var FormUtil = new function() { return id; } - this.renderTruncatedGridValue = function(container, value){ - var MAX_HEIGHT = 100 - - var $value = $("<div>") - $value.css("max-height", MAX_HEIGHT + "px") - $value.css("overflow", "hidden") - - if(_.isString(value)){ - $value.text(value) - }else{ - $value.append(value) - } - - $value.css("min-width", Math.min($value.text().length / 5, 15) + "em") - - if(container === null || container === undefined){ - return $value - } - - $value.css("visibility", "hidden").appendTo(container) - var valueHeight = $value.get(0).scrollHeight - $value.remove() - $value.css("visibility", "") - - if(valueHeight > MAX_HEIGHT){ - var $toggle = $("<a>").text("more") - $toggle.click(function(){ - if($toggle.text() === "more"){ - $value.css("max-height", "") - $toggle.text("less") - }else{ - $value.css("max-height", MAX_HEIGHT + "px") - $toggle.text("more") - } - }) - return $("<div>").append($value).append($toggle) - }else{ - return $value - } - } - this.renderMultilineVarcharGridValue = function(row, params, propertyType){ return this.renderCustomWidgetGridValue(row, params, propertyType) } @@ -2359,8 +2318,7 @@ var FormUtil = new function() { return $tooltip } }else{ - $value = $("<div>").html(FormUtil.sanitizeRichHTMLText(value)) - return this.renderTruncatedGridValue(params.container, $value) + return $("<div>").html(FormUtil.sanitizeRichHTMLText(value)) } }else if(customWidget === 'Spreadsheet'){ $value = $("<img>", { src : "./img/table.svg", "width": "16px", "height": "16px"}) @@ -2374,7 +2332,7 @@ var FormUtil = new function() { value.split('\n').forEach(function(line){ $("<div>").text(line).appendTo($value) }) - return this.renderTruncatedGridValue(params.container, $value) + return $value } $value.tooltipster({ @@ -2398,7 +2356,7 @@ var FormUtil = new function() { value.split('\n').forEach(function(line){ $("<div>").text(line).appendTo($value) }) - return this.renderTruncatedGridValue(params.container, $value) + return $value } } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js index bf7be122f37..b97773a19fa 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/AdvancedSearch/AdvancedSearchView.js @@ -1124,7 +1124,7 @@ function AdvancedSearchView(advancedSearchController, advancedSearchModel) { render: renderValue, renderFilter: renderFilter, sortable : !isGlobalSearch && propertyType.dataType !== "XML", - truncate: propertyType.dataType === "VARCHAR", + truncate: true, metadata: { dataType: propertyType.dataType } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js index 05e2163cb2a..9da148d5242 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/DataGridController.js @@ -158,9 +158,6 @@ function DataGridController( if(value === null || value === undefined || value === ""){ return }else{ - if(column.truncate){ - value = FormUtil.renderTruncatedGridValue(params.container, value) - } if(_.isString(value)){ $(params.container).empty().text(value) }else{ @@ -194,6 +191,7 @@ function DataGridController( index === columns.length - 1), configurable: !column.hide && !column.canNotBeHidden, exportable: column.isExportable, + truncate: column.truncate, metadata: column.metadata, } }) diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js index c30326d7cb0..ffed04c1ce5 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/ExperimentDataGridUtil.js @@ -146,7 +146,7 @@ var ExperimentDataGridUtil = new function() { property : propertyCodes[idx], isExportable: true, sortable : true, - truncate: propertyType.dataType === "VARCHAR", + truncate: true, render: renderValue }); } diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js index bfe1f947426..b54df5203f6 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/views/DataGrid/SampleDataGridUtil.js @@ -250,7 +250,7 @@ var SampleDataGridUtil = new function() { isExportable: true, filterable : true, sortable : propertyType.dataType !== "XML", - truncate: propertyType.dataType === "VARCHAR", + truncate: true, metadata: { dataType: propertyType.dataType }, -- GitLab