Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport 2022.02.xx] #8520: Reduce dashboards clutter and widget update (#8555) #8661

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,4 +156,37 @@ describe('Test for FeatureGrid component', () => {
expect(events.onTemporaryChanges).toHaveBeenCalled();
expect(events.onTemporaryChanges).toHaveBeenCalledWith(true);
});
it('Test grid with custom grid height props', () => {
ReactDOM.render(<FeatureGrid virtualScroll={false}
gridOpts= {{
rowHeight: 28,
headerRowHeight: 28,
headerFiltersHeight: 28
}}
describeFeatureType={describePois} enableColumnFilters features={museam.features}/>, document.getElementById("container"));
const gridHeaderRows = document.getElementsByClassName('react-grid-HeaderRow');
const gridRow = document.getElementsByClassName('react-grid-Row');
expect(gridHeaderRows.length).toBe(2);
const headerRowHeight = gridHeaderRows[0]?.getAttribute('height');
expect(Number(headerRowHeight)).toBe(28);
const headerFiltersHeight = gridHeaderRows[1]?.getAttribute('height');
expect(Number(headerFiltersHeight)).toBe(28);
const rowHeight = gridRow[0]?.offsetHeight;
expect(rowHeight).toBe(28);
});
it('Test grid with custom grid height props with no filter', () => {
ReactDOM.render(<FeatureGrid virtualScroll={false}
gridOpts= {{
rowHeight: 28,
headerRowHeight: 28
}}
describeFeatureType={describePois} enableColumnFilters={false} features={museam.features}/>, document.getElementById("container"));
const gridHeaderRows = document.getElementsByClassName('react-grid-HeaderRow');
const gridRow = document.getElementsByClassName('react-grid-Row');
expect(gridHeaderRows.length).toBe(1);
const headerRowHeight = gridHeaderRows[0]?.getAttribute('height');
expect(Number(headerRowHeight)).toBe(28);
const rowHeight = gridRow[0]?.offsetHeight;
expect(rowHeight).toBe(28);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export default ({
</Button>);
}
return (<Select
style={{width: 200}}
className={className}
disabled={disabled}
noResultsText="widgets.mapSwitcher.noResults"
Expand Down
5 changes: 4 additions & 1 deletion web/client/components/widgets/view/WidgetsView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ export default pure(({
style,
className = "",
toolsOptions = {},
rowHeight = 208,
rowHeight = 150,
breakpoints = { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 },
cols = { lg: 6, md: 6, sm: 4, xs: 2, xxs: 1 },
// eslint-disable-next-line no-unused-vars
widgetOpts = {},
widgets = [],
layouts,
dependencies,
Expand Down Expand Up @@ -105,6 +107,7 @@ export default pure(({
data-grid={w.dataGrid}
{...actions}
{...w}
widgetOpts={widgetOpts}
quickFilters={getEnableColumnFilters(w) ? w.quickFilters : undefined}
toolsOptions={toolsOptions}
groups={getWidgetGroups(groups, w)}
Expand Down
7 changes: 7 additions & 0 deletions web/client/components/widgets/widget/DefaultWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
LegendWidget
} from './enhancedWidgets';

const getWidgetOpts = (w) => w?.widgetOpts?.[w.widgetType];

/**
* Renders proper widget by widgetType, binding props and methods
*/
Expand All @@ -33,6 +35,7 @@ const DefaultWidget = ({
onEdit={onEdit}/>)
: w.widgetType === "table"
? <TableWidget {...w}
{...getWidgetOpts(w)}
toggleCollapse={toggleCollapse}
exportCSV={exportCSV}
dependencies={dependencies}
Expand All @@ -41,23 +44,27 @@ const DefaultWidget = ({
/>
: w.widgetType === "counter"
? <CounterWidget {...w}
{...getWidgetOpts(w)}
toggleCollapse={toggleCollapse}
dependencies={dependencies}
onDelete={onDelete}
onEdit={onEdit} />
: w.widgetType === "map"
? <MapWidget {...w}
{...getWidgetOpts(w)}
toggleCollapse={toggleCollapse}
dependencies={dependencies}
onDelete={onDelete}
onEdit={onEdit} />
: w.widgetType === "legend"
? <LegendWidget {...w}
{...getWidgetOpts(w)}
toggleCollapse={toggleCollapse}
dependencies={dependencies}
onDelete={onDelete}
onEdit={onEdit} />
: (<ChartWidget {...w}
{...getWidgetOpts(w)}
toggleCollapse={toggleCollapse}
exportCSV={exportCSV}
dependencies={dependencies}
Expand Down
11 changes: 6 additions & 5 deletions web/client/components/widgets/widget/MapWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default ({
} = {}) => {
const { size: {height: mapHeight, width: mapWidth} = {}, mapInfoControl } = map;
const enablePopupTools = mapHeight > 400 && mapWidth > 400 && mapInfoControl;
return (<WidgetContainer id={`widget-text-${id}`} title={title} confirmDelete={confirmDelete} onDelete={onDelete} toggleDeleteConfirm={toggleDeleteConfirm} headerStyle={headerStyle}
return (<WidgetContainer className={"map-widget-view"} id={`widget-text-${id}`} title={title} confirmDelete={confirmDelete} onDelete={onDelete} toggleDeleteConfirm={toggleDeleteConfirm} headerStyle={headerStyle}
icons={icons}
topRightItems={[
<MapSwitcher
Expand All @@ -56,10 +56,11 @@ export default ({
isDraggable={dataGrid.isDraggable}
>
<BorderLayout
footer={
<div style={{ height: "30px", overflow: "hidden"}}>
{loading ? <span style={{ "float": "right"}}><LoadingSpinner /></span> : null}
footer={loading
? <div className={"widget-footer"}>
<span style={{ "float": "right"}}><LoadingSpinner /></span>
</div>
: null
}>
<MapView
tools={enablePopupTools ? ['popup'] : []}
Expand All @@ -71,7 +72,7 @@ export default ({
mapStateSource={mapStateSource}
hookRegister={hookRegister}
layers={map && map.layers}
options={{ style: { margin: 10, height: 'calc(100% - 20px)' }}}
options={{ style: { margin: '0 10px 10px 10px', height: 'calc(100% - 10px)' }}}
env={env}
/>
</BorderLayout>
Expand Down
13 changes: 9 additions & 4 deletions web/client/components/widgets/widget/TableWidget.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import withSuspense from '../../misc/withSuspense';

const FeatureGridComp = withSuspense()(lazy(() => import('../../data/featuregrid/FeatureGrid')));
const FeatureGrid = errorChartState(loadingState(({ describeFeatureType }) => !describeFeatureType)(FeatureGridComp));
const DEFAULT_GRID_HEIGHT = 28;
const defaultGridOpts = ['rowHeight', 'headerRowHeight', 'headerFiltersHeight']
.reduce((acc, prop) => ({...acc, [prop]: DEFAULT_GRID_HEIGHT}), '');

export default getWidgetFilterRenderers(({
id,
Expand All @@ -45,7 +48,8 @@ export default getWidgetFilterRenderers(({
error,
pagination = {},
dataGrid = {},
virtualScroll = true
virtualScroll = true,
gridOpts = defaultGridOpts
}) =>
(<WidgetContainer
id={`widget-chart-${id}`}
Expand All @@ -59,10 +63,10 @@ export default getWidgetFilterRenderers(({
topRightItems={topRightItems}>
<BorderLayout
footer={pagination.totalFeatures ? (
<div style={{ height: "30px", overflow: "hidden"}}>
<div className={"widget-footer"}>
{loading ? <span style={{ "float": "right"}}><LoadingSpinner /></span> : null}
{error === undefined &&
<span style={{ "float": "left", margin: "5px" }} ><Message
<span className={"result-info"} ><Message
msgId={"featuregrid.resultInfoVirtual"}
msgParams={{ total: pagination.totalFeatures }} /></span>}
</div>) : null}
Expand All @@ -85,7 +89,8 @@ export default getWidgetFilterRenderers(({
size={size}
rowKey="id"
describeFeatureType={describeFeatureType}
pagination={pagination} />
pagination={pagination}
gridOpts={gridOpts}/>
</BorderLayout>
</WidgetContainer>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { compose, defaultProps } from 'recompose';
import { waitFor } from '@testing-library/react';

import describePois from '../../../../test-resources/wfs/describe-pois.json';
import museam from '../../../../test-resources/wfs/museam.json';
import tableWidget from '../../enhancers/tableWidget';
import TableWidgetComp from '../TableWidget';

Expand Down Expand Up @@ -69,6 +70,27 @@ describe('TableWidget component', () => {
waitFor(() =>expect( container.querySelector('.react-grid-Empty')).toBeTruthy())
.then(() => done());
});
it('TableWidget with default gridOpts', () => {
ReactDOM.render(<TableWidget
virtualScroll={false} describeFeatureType={describePois} enableColumnFilters features={museam.features}/>, document.getElementById("container"));
const gridHeaderRows = document.getElementsByClassName('react-grid-HeaderRow');
expect(gridHeaderRows.length).toBe(2);
const headerRowHeight = gridHeaderRows[0]?.getAttribute('height');
expect(Number(headerRowHeight)).toBe(28);
const headerFiltersHeight = gridHeaderRows[1]?.getAttribute('height');
expect(Number(headerFiltersHeight)).toBe(28);
});
it('TableWidget with custom gridOpts', () => {
ReactDOM.render(<TableWidget
gridOpts={{ headerRowHeight: 35, headerFiltersHeight: 35}}
virtualScroll={false} describeFeatureType={describePois} enableColumnFilters features={museam.features}/>, document.getElementById("container"));
const gridHeaderRows = document.getElementsByClassName('react-grid-HeaderRow');
expect(gridHeaderRows.length).toBe(2);
const headerRowHeight = gridHeaderRows[0]?.getAttribute('height');
expect(Number(headerRowHeight)).toBe(35);
const headerFiltersHeight = gridHeaderRows[1]?.getAttribute('height');
expect(Number(headerFiltersHeight)).toBe(35);
});
it('TableWidget onAddFilter', (done) => {
const _d = {...describePois, featureTypes: [{...describePois.featureTypes[0], properties: [...describePois.featureTypes[0].properties, {
"name": "FLOAT",
Expand Down
23 changes: 22 additions & 1 deletion web/client/plugins/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,33 @@ const WidgetsView = compose(
* @prop {object} cfg.cols Number of columns in this layout. default { lg: 6, md: 6, sm: 4, xs: 2, xxs: 1 }
* @prop {object} cfg.minLayoutWidth minimum size of the layout, below this size the widgets are listed in a single column
* for more info about rowHeight and cols, see https://github.com/STRML/react-grid-layout#grid-layout-props
* @prop {object} cfg.widgetOpts can be used to configure widget specific options.
* Currently, it explicitly supports table widget with following options
* @example
* {
* "name": "Dashboard",
* "cfg": {
* "rowHeight": 150,
* "cols": { lg: 6, md: 6, sm: 4, xs: 2, xxs: 1 },
* "widgetOpts": {
* "table": {
* gridOpts: {
* rowHeight: 20,
* headerRowHeight: 20,
* headerFiltersHeight: 20
* }
* }
* }
* }
* }
*/
class DashboardPlugin extends React.Component {
static propTypes = {
enabled: PropTypes.bool,
rowHeight: PropTypes.number,
cols: PropTypes.object,
minLayoutWidth: PropTypes.number
minLayoutWidth: PropTypes.number,
widgetOpts: PropTypes.object
};
static defaultProps = {
enabled: true,
Expand All @@ -145,6 +165,7 @@ class DashboardPlugin extends React.Component {
rowHeight={this.props.rowHeight}
cols={this.props.cols}
minLayoutWidth={this.props.minLayoutWidth}
widgetOpts={this.props.widgetOpts}
/>
: null;

Expand Down
1 change: 1 addition & 0 deletions web/client/themes/default/bootstrap-variables.less
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
@font-family-base: var(--ms-font-family-base, @ms-font-family-base);
@font-size-base: 14px;
@font-size-large: ceil(@font-size-base * 1.25);
@font-size-medium: ceil(@font-size-base * 1.14);
@font-size-small: ceil(@font-size-base * 0.85);
@font-size-h1: floor((@font-size-base * 1.9));
@font-size-h2: floor((@font-size-base * 1.7));
Expand Down
Loading