Skip to content

Commit c515cb9

Browse files
committed
- Add support for parsing fuzzy output
- Remove collapse for profile commands
1 parent b6889af commit c515cb9

File tree

3 files changed

+113
-75
lines changed

3 files changed

+113
-75
lines changed

redisinsight/ui/src/packages/ri-explain/src/Explain.tsx

Lines changed: 78 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function getEdgeColor(isDarkTheme: boolean) {
4848

4949
export default function Explain(props: IExplain): JSX.Element {
5050
const command = props.command.split(' ')[0].toLowerCase()
51-
5251
if (command.startsWith('graph')) {
5352
const info = props.data[0].response
5453
const resp = ParseGraphV2(info)
@@ -140,7 +139,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
140139
const container = useRef<HTMLDivElement | null>(null)
141140

142141
const [done, setDone] = useState(false)
143-
const [collapse, setCollapse] = useState(true)
142+
const [collapse, setCollapse] = useState(type !== CoreType.Profile)
144143
const [isFullScreen, setIsFullScreen] = useState(false)
145144
const [core, setCore] = useState<Graph>()
146145

@@ -151,15 +150,15 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
151150
if (isFullScreen) {
152151
setIsFullScreen(true)
153152
const height = Math.max((b?.height || 585) + 100, parent.document.body.offsetHeight)
154-
if (collapse) {
153+
if (type !== CoreType.Profile && collapse) {
155154
core?.resize(width, window.outerHeight - 250)
156155
core?.positionContent("top")
157156
} else {
158157
core?.resize(width, height)
159158
}
160159
} else {
161160
setIsFullScreen(false)
162-
if (collapse) {
161+
if (type !== CoreType.Profile && collapse) {
163162
core?.resize(width, 400)
164163
core?.positionContent("top")
165164
} else {
@@ -236,45 +235,6 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
236235
})
237236
})
238237

239-
const ele = document.querySelector("#container-parent")
240-
241-
let pos = { top: 0, left: 0, x: 0, y: 0 }
242-
243-
const mouseMoveHandler = function (e) {
244-
// How far the mouse has been moved
245-
const dx = e.clientX - pos.x
246-
const dy = e.clientY - pos.y
247-
248-
// Scroll the element
249-
if (ele) {
250-
ele.scrollTop = pos.top - dy
251-
ele.scrollLeft = pos.left - dx
252-
}
253-
}
254-
255-
256-
const mouseUpHandler = function () {
257-
document.removeEventListener('mousemove', mouseMoveHandler)
258-
document.removeEventListener('mouseup', mouseUpHandler)
259-
}
260-
261-
262-
const mouseDownHandler = function (e) {
263-
pos = {
264-
// The current scroll
265-
left: ele?.scrollLeft || 0,
266-
top: ele?.scrollTop || 0,
267-
// Get the current mouse position
268-
x: e.clientX,
269-
y: e.clientY,
270-
}
271-
272-
document.addEventListener('mousemove', mouseMoveHandler)
273-
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
274-
}
275-
276-
ele?.addEventListener('mousedown', mouseDownHandler)
277-
278238
resize()
279239

280240
const result = Hierarchy.compactBox(data, {
@@ -426,7 +386,47 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
426386

427387
}, [done])
428388

429-
if (collapse) {
389+
const ele = document.querySelector("#container-parent")
390+
391+
let pos = { top: 0, left: 0, x: 0, y: 0 }
392+
393+
const mouseMoveHandler = function (e) {
394+
// How far the mouse has been moved
395+
const dx = e.clientX - pos.x
396+
const dy = e.clientY - pos.y
397+
398+
// Scroll the element
399+
if (ele) {
400+
ele.scrollTop = pos.top - dy
401+
ele.scrollLeft = pos.left - dx
402+
}
403+
}
404+
405+
406+
const mouseUpHandler = function () {
407+
document.removeEventListener('mousemove', mouseMoveHandler)
408+
document.removeEventListener('mouseup', mouseUpHandler)
409+
}
410+
411+
412+
const mouseDownHandler = function (e) {
413+
pos = {
414+
// The current scroll
415+
left: ele?.scrollLeft || 0,
416+
top: ele?.scrollTop || 0,
417+
// Get the current mouse position
418+
x: e.clientX,
419+
y: e.clientY,
420+
}
421+
422+
document.addEventListener('mousemove', mouseMoveHandler)
423+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
424+
}
425+
426+
ele?.addEventListener('mousedown', mouseDownHandler)
427+
428+
429+
if (type !== CoreType.Profile && collapse) {
430430
core?.resize(undefined, isFullScreen ? (window.outerHeight - 250) : 400)
431431
core?.positionContent("top")
432432
} else {
@@ -435,23 +435,24 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
435435

436436
return (
437437
<div>
438-
{ collapse && <div style={{ paddingTop: '50px' }}></div> }
438+
{ type !== CoreType.Profile && collapse && <div style={{ paddingTop: '50px' }}></div> }
439439
<div
440440
id="container-parent"
441441
style={{
442-
height: isFullScreen ? (window.outerHeight - 170) + 'px' : collapse ? '500px' : '585px',
442+
height: isFullScreen ? (window.outerHeight - 170) + 'px' : type !== CoreType.Profile && collapse ? '500px' : '585px',
443443
width: '100%',
444444
overflow: 'auto',
445445
}}
446446
>
447447
<div style={{ margin: 0, width: '100vw' }} ref={container} id="container" />
448-
{ !collapse && (
448+
{ !(collapse) && (
449449
<div className="ZoomMenu">
450450
{
451451
[
452452
{
453453
name: 'Zoom In',
454454
onClick: () => {
455+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
455456
core?.zoom(0.5)
456457
core?.resize(undefined, core?.getContentBBox().height + 50)
457458
},
@@ -460,6 +461,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
460461
{
461462
name: 'Zoom Out',
462463
onClick: () => {
464+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
463465
core && Math.floor(core.zoom()) <= 0.5 ? core?.zoom(0) : core?.zoom(-0.5)
464466
core?.resize(undefined, core?.getContentBBox().height + 50)
465467
},
@@ -468,6 +470,7 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
468470
{
469471
name: 'Reset Zoom',
470472
onClick: () => {
473+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
471474
core?.zoomTo(1)
472475
core?.resize(undefined, core?.getContentBBox().height + 50)
473476
},
@@ -486,32 +489,35 @@ function ExplainDraw({data, type, module, profilingTime}: {data: any, type: Core
486489
}
487490
</div>
488491
)}
489-
<div
490-
style={{ paddingBottom: (isFullScreen && profilingTime && ModuleType.Search ? '60px' : '35px')}}
491-
className="CollapseButton"
492-
onClick={e => {
493-
e.preventDefault()
494-
if (!collapse) { // About to collapse?
495-
core?.zoomTo(1)
496-
core?.resize(undefined, core?.getContentBBox().height + 50)
492+
{ type !== CoreType.Profile &&
493+
<div
494+
style={{ paddingBottom: (isFullScreen && profilingTime && ModuleType.Search ? '60px' : '35px')}}
495+
className="CollapseButton"
496+
onClick={e => {
497+
e.preventDefault()
498+
setTimeout(() => document.addEventListener('mouseup', mouseUpHandler), 100)
499+
if (!collapse) { // About to collapse?
500+
core?.zoomTo(1)
501+
core?.resize(undefined, core?.getContentBBox().height + 50)
502+
}
503+
setCollapse(!collapse)
504+
}}
505+
>
506+
{
507+
collapse
508+
?
509+
<>
510+
<div>Expand</div>
511+
<EuiIcon className="NodeIcon" size="m" type="arrowDown" />
512+
</>
513+
:
514+
<>
515+
<div>Collapse</div>
516+
<EuiIcon className="NodeIcon" size="m" type="arrowUp" />
517+
</>
497518
}
498-
setCollapse(!collapse)
499-
}}
500-
>
501-
{
502-
collapse
503-
?
504-
<>
505-
<div>Expand</div>
506-
<EuiIcon className="NodeIcon" size="m" type="arrowDown" />
507-
</>
508-
:
509-
<>
510-
<div>Collapse</div>
511-
<EuiIcon className="NodeIcon" size="m" type="arrowUp" />
512-
</>
513-
}
514-
</div>
519+
</div>
520+
}
515521
{ profilingTime &&
516522
(
517523
module === ModuleType.Search &&

redisinsight/ui/src/packages/ri-explain/src/Node.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function ExplainNode(props: INodeProps) {
3131
<div className="InfoData">
3232
<EuiToolTip delay='long' content={infoData}><span>{infoData}</span></EuiToolTip>
3333
</div>
34-
{subType && [EntityType.GEO, EntityType.NUMERIC, EntityType.TEXT, EntityType.TAG].includes(subType) && <div className="Type">{subType}</div> }
34+
{subType && [EntityType.GEO, EntityType.NUMERIC, EntityType.TEXT, EntityType.TAG, EntityType.FUZZY].includes(subType) && <div className="Type">{subType}</div> }
3535
</div>
3636
</div>
3737
{

redisinsight/ui/src/packages/ri-explain/src/parser.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ enum TokenType {
99

1010
UNION = 'UNION',
1111
INTERSECT = 'INTERSECT',
12+
FUZZY_EXPR = 'FUZZY_EXPR',
1213
GEO_EXPR = 'GEO_EXPR',
1314
TAG_EXPR = 'TAG_EXPR',
1415
NUMERIC = 'NUMERIC',
@@ -182,6 +183,8 @@ class Lexer {
182183
let tokenType = KEYWORDS[literal] || TokenType.IDENTIFIER
183184
if (literal.startsWith('TAG:')) {
184185
tokenType = TokenType.TAG_EXPR
186+
} else if (literal === 'FUZZY') {
187+
tokenType = TokenType.FUZZY_EXPR
185188
} else if (literal === 'GEO') {
186189
tokenType = TokenType.GEO_EXPR
187190
} else if (literal.startsWith('@') && literal.endsWith(':UNION')) {
@@ -212,6 +215,7 @@ export enum EntityType {
212215

213216
// These are used exclusively in FT.PROFILE
214217
GEO = 'GEO',
218+
FUZZY = 'FUZZY',
215219
TEXT = 'TEXT',
216220
TAG = 'TAG',
217221

@@ -467,7 +471,9 @@ class Parser {
467471
} else if (this.CurrentToken.T === TokenType.TAG_EXPR) {
468472
Exprs.push(this.parseTagExpr())
469473
} else if (this.CurrentToken.T === TokenType.GEO_EXPR) {
470-
Exprs.push(this.parseTagExpr())
474+
Exprs.push(this.parseGeoExpr())
475+
} else if (this.CurrentToken.T === TokenType.FUZZY_EXPR) {
476+
Exprs.push(this.parseFuzzyExpr())
471477
}
472478

473479
this.nextToken()
@@ -513,7 +519,9 @@ class Parser {
513519
} else if (this.CurrentToken.T === TokenType.TAG_EXPR) {
514520
Exprs.push(this.parseTagExpr())
515521
} else if (this.CurrentToken.T === TokenType.GEO_EXPR) {
516-
Exprs.push(this.parseTagExpr())
522+
Exprs.push(this.parseGeoExpr())
523+
} else if (this.CurrentToken.T === TokenType.FUZZY_EXPR) {
524+
Exprs.push(this.parseFuzzyExpr())
517525
}
518526

519527
this.nextToken()
@@ -536,6 +544,28 @@ class Parser {
536544
return new Expr(str, EntityType.TEXT)
537545
}
538546

547+
parseFuzzyExpr() {
548+
assertToken(TokenType.FUZZY_EXPR, this.CurrentToken.T)
549+
550+
this.nextToken()
551+
552+
assertToken(TokenType.LBRACE, this.CurrentToken.T)
553+
554+
this.nextToken()
555+
556+
assertToken(TokenType.IDENTIFIER, this.CurrentToken.T)
557+
558+
let identifierData = this.CurrentToken.Data;
559+
560+
this.nextToken()
561+
562+
assertToken(TokenType.RBRACE, this.CurrentToken?.T)
563+
564+
this.nextToken()
565+
566+
return new Expr(identifierData, EntityType.FUZZY)
567+
}
568+
539569
parseGeoExpr() {
540570
assertToken(TokenType.GEO_EXPR, this.CurrentToken.T)
541571

@@ -712,6 +742,8 @@ function Parse(data: string): SearchExpr {
712742
return p.parseTagExpr()
713743
} else if (p.CurrentToken.T === TokenType.GEO_EXPR) {
714744
return p.parseGeoExpr()
745+
} else if (p.CurrentToken.T === TokenType.FUZZY_EXPR) {
746+
return p.parseFuzzyExpr()
715747
} else {
716748
return p.parseExpr()
717749
}

0 commit comments

Comments
 (0)