Skip to content

Commit

Permalink
Update Mango query explain page to show parsed view (#1415)
Browse files Browse the repository at this point in the history
  • Loading branch information
mharrigan26 committed Nov 17, 2023
1 parent c711c5e commit 1b2c7e4
Show file tree
Hide file tree
Showing 18 changed files with 903 additions and 22 deletions.
2 changes: 1 addition & 1 deletion app/addons/components/__tests__/badges.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('Badges', () => {

it('supports custom label formatters', () => {
const el = mount(
<ReactComponents.BadgeList elements={['foo', 'bar']} removeBadge={() => {}} getLabel={(el) => { return el + 'foo'; }} />
<ReactComponents.BadgeList elements={['foo', 'bar']} removeBadge={() => {}} showClose={true} getLabel={(el) => { return el + 'foo'; }} />
);

expect(el.find('.badge').first().text()).toBe('foofoo×');
Expand Down
49 changes: 37 additions & 12 deletions app/addons/components/components/badge.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
// the License.

import PropTypes from 'prop-types';
import { Tooltip, OverlayTrigger } from 'react-bootstrap';

import React from "react";
import ReactDOM from "react-dom";

export class BadgeList extends React.Component {
static propTypes = {
elements: PropTypes.array.isRequired,
removeBadge: PropTypes.func.isRequired
removeBadge: PropTypes.func.isRequired,
showClose: PropTypes.bool,
tagExplanations: PropTypes.object
};

static defaultProps = {
Expand All @@ -28,7 +31,9 @@ export class BadgeList extends React.Component {

getId (el) {
return el;
}
},
showClose: false,
tagExplanations: null
};

getBadges = () => {
Expand All @@ -37,7 +42,10 @@ export class BadgeList extends React.Component {
label={this.props.getLabel(el)}
key={i}
id={el}
remove={this.removeBadge} />;
remove={this.removeBadge}
showClose={this.props.showClose}
showTooltip={!!this.props.tagExplanations}
tooltip={this.props.tagExplanations ? this.props.tagExplanations[el] : ''} />;
}.bind(this));
};

Expand All @@ -57,7 +65,15 @@ export class BadgeList extends React.Component {
export class Badge extends React.Component {
static propTypes = {
label: PropTypes.string.isRequired,
remove: PropTypes.func.isRequired
remove: PropTypes.func.isRequired,
showClose: PropTypes.bool,
showTooltip: PropTypes.bool,
tooltip: PropTypes.string
};
static defaultProps = {
showClose: false,
showTooltip: false,
tooltip: ''
};

remove = (e) => {
Expand All @@ -66,17 +82,26 @@ export class Badge extends React.Component {
};

render() {
const className = "badge " + this.props.label.replace(' ', '-');
const tooltip = <Tooltip id="graveyard-tooltip">{this.props.tooltip}</Tooltip>;

return (
<li className="badge">
<li className={className}>
<div className="remove-filter">
<span>{this.props.label}</span>
<a
href="#"
onClick={this.remove}
data-bypass="true"
className="ms-1">
{this.props.showTooltip ?
<OverlayTrigger placement="top" overlay={tooltip}>
<span>{this.props.label}</span>
</OverlayTrigger> :
<span>{this.props.label}</span>}
{ this.props.showClose ?
<a
href="#"
onClick={this.remove}
data-bypass="true"
className="ms-1">
&times;
</a>
</a>
: null}
</div>
</li>
);
Expand Down
93 changes: 93 additions & 0 deletions app/addons/documents/assets/scss/mango-query.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,96 @@
}
}
}

.explain-view-toggle {
margin-bottom: 1rem;
}

.explain-json-response {
padding-left: 0rem;
margin-top: 1rem;
}

.explain-plan-section-title {
font-size: 1rem;
i {
margin-left: 0.5rem;
}
}

.explain-reasons-legend-modal {
max-width: none!important;
width: 50%!important;

.table-wrapper {
max-height: 300px;
overflow-y: scroll;
}
}

.explain-index-panel {
background-color: $cf-white;
margin-left: 0.25rem !important;
margin-right: 0.25rem !important;
padding: 0.5rem;
border-top: 1px solid $cf-border-color01;
border-bottom: 1px solid $cf-border-color01;
word-break: break-all;
font-size: 0.875rem;

.index-ddoc-name {
font-size: 0.75rem;
}

.index-extra-info {
word-break: normal;
}

i.icon {
margin-left: 0.5rem;
}

ul.component-badgelist {
margin-bottom: 0;
margin-top: 0;
}

li.badge {
margin-left: 0;
padding-left: 0;

div.remove-filter {
padding: 0.5rem;
background-color: $cf-info;
border-radius: 5px;
span {
padding: 0;
margin: 0;
color: $cf-white;
font-size: 14px;
}
}
}

li.covering {
div.remove-filter {
background-color: $cf-primary;
span {
color: $cf-white;
}
}
}

li.partitioned {
div.remove-filter {
background-color: $cf-tab-element-badge;
span {
color: $cf-white;
}
}
}

.fonticon-attention-circled {
margin-right: 4px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class ChangesTabContent extends React.Component {
<div className="changes-header">
<AddFilterForm filter={(label) => this.props.removeFilter(label)} addFilter={this.addFilter}
hasFilter={this.hasFilter} />
<ReactComponents.BadgeList elements={this.props.filters} removeBadge={(label) => this.props.removeFilter(label)} />
<ReactComponents.BadgeList elements={this.props.filters} removeBadge={(label) => this.props.removeFilter(label)} showClose={true} />
</div>
);
}
Expand Down
58 changes: 58 additions & 0 deletions app/addons/documents/mango/__tests__/mango.components.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import MangoQueryEditor from '../components/MangoQueryEditor';
import MangoIndexEditor from '../components/MangoIndexEditor';
import mangoReducer from '../mango.reducers';
import '../../base';
import ExplainPage from '../components/ExplainPage';
import {explainPlan, explainPlanCandidates} from './sampleexplainplan';

const restore = utils.restore;
const databaseName = 'testdb';
Expand Down Expand Up @@ -324,3 +326,59 @@ describe('MangoQueryEditor', function () {
expect(warning.text()).toContain('sample warning');
});
});

describe('Explain Page', function() {
const defaultProps = {
viewFormat: 'parsed',
isReasonsModalVisible: false,
onViewFormatChange: (() => {}),
resetState: (() => {}),
hideReasonsModal: (() => {}),
showReasonsModal: (() => {}),
};

it('shows suitable/unsuitable indexes when available', function() {
const wrapper = mount(
<ExplainPage {...defaultProps} explainPlan={explainPlanCandidates} />
);
expect(wrapper.find('#explain-parsed-view .btn.active.btn-cf-secondary')).toHaveLength(1);
const headers = wrapper.find('.explain-plan-section-title');
const panels = wrapper.find('.row.explain-index-panel');
expect(headers).toHaveLength(3);
expect(panels).toHaveLength(5);

expect((headers.get(0)).props.children).toContain('Selected Index');
expect((panels.get(1)).props.children[0]).toMatchObject(/foo-json-index/);

expect((headers.get(1)).props.children).toContain('Suitable Indexes');
expect((panels.get(1)).props.children[0]).toMatchObject(/foo-test-json-index/);

expect((headers.get(2)).props.children).toContain('Unsuitable Indexes');
expect((panels.get(2)).props.children[0]).toMatchObject(/_all_docs/);
});

it('toggles between parsed and json, with no candidate indexes', function() {
let spy = sinon.spy();
const wrapper = mount(
<ExplainPage {...defaultProps} explainPlan={explainPlan} onViewFormatChange={spy} />
);

expect(wrapper.find('#explain-parsed-view .btn.active.btn-cf-secondary')).toHaveLength(1);
expect(wrapper.find('.explain-plan-section-title')).toHaveLength(1);
expect(((wrapper.find('.explain-plan-section-title')).get(0)).props.children).toContain('Selected Index');
wrapper.find('button#explain-json-view').simulate('click');
expect(spy.calledOnce).toBeTruthy();
});

it('toggles between json and parsed', function() {
let spy = sinon.spy();
const wrapper = mount(
<ExplainPage {...defaultProps} explainPlan={explainPlan} onViewFormatChange={spy} viewFormat={'json'} />
);

expect(wrapper.find('#explain-json-view .btn.active.btn-cf-secondary')).toHaveLength(1);
expect(((wrapper.find('.explain-plan-section-title')).get(0)).props.children).toContain('JSON Response');
wrapper.find('button#explain-parsed-view').simulate('click');
expect(spy.calledOnce).toBeTruthy();
});
});

0 comments on commit 1b2c7e4

Please sign in to comment.