Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e9f65ad
Revert "Revert "Add ability to run a profile/explain right from the q…
GnaneshKunal Feb 6, 2023
172fc39
Revert "Revert "Fix comments - https://github.com/RedisInsight/RedisI…
GnaneshKunal Feb 6, 2023
c52b2cd
Revert "Revert "- Move queryProfile to parent and create a new teleme…
GnaneshKunal Feb 6, 2023
20c4b38
Revert "Revert "- Add null checks for generate profile command functi…
GnaneshKunal Feb 6, 2023
f16ae8d
RI-4101:
GnaneshKunal Feb 6, 2023
b13fbdd
- Resolve review comments - https://github.com/RedisInsight/RedisInsi…
GnaneshKunal Feb 7, 2023
8c21aa2
Merge pull request #1691 from RedisInsight/feature/RI-3726_profile_ex…
GnaneshKunal Feb 8, 2023
3f73c80
- Properly parse tags
GnaneshKunal Feb 9, 2023
3109fce
Merge pull request #1719 from RedisInsight/fe/bugfix-RI-3726_profile_…
GnaneshKunal Feb 13, 2023
84014cf
FIX RI-4187: run query profile function inside a closure to avoid unn…
GnaneshKunal Feb 14, 2023
da2b047
Move back handle query profile implementation outside
GnaneshKunal Feb 14, 2023
402dfd4
wrap `profileType` in brackets
GnaneshKunal Feb 14, 2023
3d3d102
Merge pull request #1736 from RedisInsight/fe/bugfix-RI-3726_profile_…
GnaneshKunal Feb 14, 2023
6420582
- Allow RediSearch plugin to also display Profile command data.
GnaneshKunal Feb 15, 2023
0104b41
Allow redisearch module to show aggregate profile results as well
GnaneshKunal Feb 15, 2023
9361692
Merge pull request #1739 from RedisInsight/fe/bugfix-RI-4101
GnaneshKunal Feb 15, 2023
dbdb2ac
Add support for geo command
GnaneshKunal Feb 15, 2023
32bb07a
Merge pull request #1740 from RedisInsight/fe/bugfix/RI-3726_profile_…
GnaneshKunal Feb 16, 2023
ea92929
Separate out FT.PROFILE and other search commands and set the default
GnaneshKunal Feb 16, 2023
28b3692
Merge pull request #1747 from RedisInsight/fe/bugfix-RI-3726_profile_…
GnaneshKunal Feb 16, 2023
8d3cfeb
- Add port support which distinguishes when the node has multiple out…
GnaneshKunal Feb 18, 2023
0d6025a
Define edge colors
GnaneshKunal Feb 18, 2023
6803bb4
Move node/edge colors to constants
GnaneshKunal Feb 20, 2023
b6889af
Merge pull request #1754 from RedisInsight/fe/bugfix-RI-3726_profile_…
GnaneshKunal Feb 21, 2023
c515cb9
- Add support for parsing fuzzy output
GnaneshKunal Feb 23, 2023
ff6b6a3
Parse additional aggregate coordinator info
GnaneshKunal Feb 23, 2023
0ab7363
Merge pull request #1777 from RedisInsight/fe/bugfix-RI-3726_profile_…
GnaneshKunal Feb 24, 2023
63c840f
Merge remote-tracking branch 'origin/main' into fe/RI-3726_profile_ex…
GnaneshKunal Feb 24, 2023
f3ed15d
Merge pull request #1779 from RedisInsight/fe/RI-3726_profile_explain…
GnaneshKunal Feb 25, 2023
44bff8f
- Remove edge target marker
GnaneshKunal Feb 26, 2023
ea5c9b9
Use redisinsight-plugin-sdk's formatReply to show not support for
GnaneshKunal Feb 26, 2023
3ab4d54
Add missing 'onQueryProfile' retrieval from props
GnaneshKunal Feb 27, 2023
c59aad9
- Use exampd parser to parse tag expressions as well.
GnaneshKunal Feb 27, 2023
9ad92ec
Add support for displaying number types
GnaneshKunal Feb 27, 2023
900c016
- Add parsing of WILDCARD_EMPTY response
GnaneshKunal Feb 27, 2023
481a8f8
Build RI-explain command
GnaneshKunal Feb 28, 2023
8f78558
Fix bottom height to show up scrollbar
GnaneshKunal Feb 28, 2023
d77109d
#RI-4244 - fix workbench icon issue
AmirAllayarovSofteq Feb 28, 2023
98bf81b
Merge pull request #1790 from RedisInsight/fe/bugfix/RI-4244_workbenc…
vlad-dargel Feb 28, 2023
a4c5c79
Merge pull request #1781 from RedisInsight/fe/bugfix/RI-3726_profile_…
vlad-dargel Feb 28, 2023
095126b
Merge branch 'main' into feature/RI-3726_profile_explain
rsergeenko Feb 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions redisinsight/ui/src/assets/img/workbench/vis_tag_cloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion redisinsight/ui/src/components/query-card/QueryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import cx from 'classnames'
import { EuiLoadingContent, keys } from '@elastic/eui'
import { useParams } from 'react-router-dom'

import { WBQueryType } from 'uiSrc/pages/workbench/constants'
import { WBQueryType, ProfileQueryType } from 'uiSrc/pages/workbench/constants'
import { RunQueryMode, ResultsMode, ResultsSummary } from 'uiSrc/slices/interfaces/workbench'
import {
getWBQueryType,
Expand Down Expand Up @@ -44,6 +44,7 @@ export interface Props {
onQueryDelete: () => void
onQueryReRun: () => void
onQueryOpen: () => void
onQueryProfile: (type: ProfileQueryType) => void
}

const getDefaultPlugin = (views: IPluginVisualization[], query: string) =>
Expand Down Expand Up @@ -75,6 +76,7 @@ const QueryCard = (props: Props) => {
createdAt,
onQueryOpen,
onQueryDelete,
onQueryProfile,
onQueryReRun,
loading,
emptyCommand,
Expand Down Expand Up @@ -186,6 +188,7 @@ const QueryCard = (props: Props) => {
setSelectedValue={changeViewTypeSelected}
onQueryDelete={onQueryDelete}
onQueryReRun={onQueryReRun}
onQueryProfile={onQueryProfile}
/>
{isOpen && (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { numberWithSpaces } from 'uiSrc/utils/numbers'
import { ThemeContext } from 'uiSrc/contexts/themeContext'
import { appPluginsSelector } from 'uiSrc/slices/app/plugins'
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
import { getViewTypeOptions, WBQueryType } from 'uiSrc/pages/workbench/constants'
import { getViewTypeOptions, WBQueryType, getProfileViewTypeOptions, ProfileQueryType, isCommandAllowedForProfile } from 'uiSrc/pages/workbench/constants'
import { IPluginVisualization } from 'uiSrc/slices/interfaces'
import { RunQueryMode, ResultsMode, ResultsSummary } from 'uiSrc/slices/interfaces/workbench'
import { appRedisCommandsSelector } from 'uiSrc/slices/app/redis-commands'
Expand Down Expand Up @@ -70,6 +70,7 @@ export interface Props {
setSelectedValue: (type: WBQueryType, value: string) => void
onQueryDelete: () => void
onQueryReRun: () => void
onQueryProfile: (type: ProfileQueryType) => void
}

const getExecutionTimeString = (value: number): string => {
Expand Down Expand Up @@ -109,6 +110,7 @@ const QueryCardHeader = (props: Props) => {
setSelectedValue,
onQueryDelete,
onQueryReRun,
onQueryProfile,
db,
} = props

Expand Down Expand Up @@ -237,6 +239,30 @@ const QueryCardHeader = (props: Props) => {
}
})

const profileOptions: EuiSuperSelectOption<any>[] = (getProfileViewTypeOptions() as any[]).map((item) => {
const { value, id, text } = item
return {
value: id ?? value,
inputDisplay: (
<div className={cx(styles.dropdownOption, styles.dropdownProfileOption)}>
<EuiIcon
className={styles.iconDropdownOption}
type="visTagCloud"
data-testid={`view-type-selected-${value}-${id}`}
/>
</div>
),
dropdownDisplay: (
<div className={cx(styles.dropdownOption, styles.dropdownProfileOption)}>
<span>{truncateText(text, 20)}</span>
</div>
),
'data-test-subj': `profile-type-option-${value}-${id}`,
}
})

const canCommandProfile = isCommandAllowedForProfile(query)

const indexForSeparator = findIndex(pluginsOptions, (option) => !option.internal)
if (indexForSeparator > -1) {
modifiedOptions.splice(indexForSeparator + 1, 0, {
Expand Down Expand Up @@ -320,6 +346,26 @@ const QueryCardHeader = (props: Props) => {
</EuiToolTip>
)}
</EuiFlexItem>
{isOpen && canCommandProfile && !summaryText && (
<EuiFlexItem
grow={false}
className={cx(styles.buttonIcon, styles.viewTypeIcon)}
onClick={onDropDownViewClick}
>
<div className={styles.dropdownWrapper}>
<div className={styles.dropdown}>
<EuiSuperSelect
options={profileOptions}
itemClassName={cx(styles.changeViewItem, styles.dropdownProfileItem)}
className={cx(styles.changeView, styles.dropdownProfileIcon)}
valueOfSelected={ProfileQueryType.Profile}
onChange={(value: ProfileQueryType) => onQueryProfile(value)}
data-testid="run-profile-type"
/>
</div>
</div>
</EuiFlexItem>
)}
<EuiFlexItem
grow={false}
className={cx(styles.buttonIcon, styles.viewTypeIcon)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@ $marginIcon: 12px;
height: 40px;
}

.dropdownProfileIcon {
padding: inherit !important;
:global {
.euiSuperSelectControl.euiFormControlLayoutIcons {
display: none !important;
}
}
}

.dropdownProfileOption {
display: inherit !important;
}

.dropdownProfileItem {
:global {
.euiContextMenu__icon {
display: none !important;
}
}
}

.dropdown {
width: 168px;
position: absolute;
Expand Down
12 changes: 12 additions & 0 deletions redisinsight/ui/src/packages/redisearch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
"iconLight": "./dist/table_view_icon_light.svg",
"description": "RediSearch default plugin",
"default": true
},
{
"id": "redisearch-profile",
"name": "Table",
"activationMethod": "renderRediSearch",
"matchCommands": [
"FT.PROFILE"
],
"iconDark": "./dist/table_view_icon_dark.svg",
"iconLight": "./dist/table_view_icon_light.svg",
"description": "RediSearch default plugin",
"default": false
}
],
"devDependencies": {
Expand Down
19 changes: 14 additions & 5 deletions redisinsight/ui/src/packages/redisearch/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
parseSearchRawResponse,
parseAggregateRawResponse
} from './utils'
import { Command } from './constants'
import { Command, ProfileType } from './constants'
import { TableInfoResult, TableResult } from './components'

interface Props {
Expand All @@ -35,16 +35,25 @@ const App = (props: Props) => {
return <TableInfoResult query={command} result={result} />
}

if (commandUpper.startsWith(Command.Aggregate)) {
const [matched, ...arrayResponse] = response
const isProfileCommand = commandUpper.startsWith(Command.Profile)
const profileQueryType = command?.split(' ')?.[2]

if (
commandUpper.startsWith(Command.Aggregate)
|| (isProfileCommand && profileQueryType.toUpperCase() === ProfileType.Aggregate)
) {
const [matched, ...arrayResponse] = isProfileCommand ? response[0] : response
setHeaderText(`Matched:${matched}`)

const result = parseAggregateRawResponse(arrayResponse)
return <TableResult query={command} result={result} matched={matched} />
}

if (commandUpper.startsWith(Command.Search)) {
const [matched, ...arrayResponse] = response
if (
commandUpper.startsWith(Command.Search)
|| (isProfileCommand && profileQueryType.toUpperCase() === ProfileType.Search)
) {
const [matched, ...arrayResponse] = isProfileCommand ? response[0] : response
setHeaderText(`Matched:${matched}`)

const result = parseSearchRawResponse(command, arrayResponse)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ export enum Command {
Search = 'FT.SEARCH',
Aggregate = 'FT.AGGREGATE',
Info = 'FT.INFO',
Profile = 'FT.PROFILE',
}

export enum ProfileType {
Search = 'SEARCH',
Aggregate = 'AGGREGATE',
}

export enum CommandArgument {
Expand Down
1 change: 1 addition & 0 deletions redisinsight/ui/src/packages/ri-explain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# RI-Explain plugin
72 changes: 72 additions & 0 deletions redisinsight/ui/src/packages/ri-explain/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"author": {
"name": "Redis Ltd.",
"email": "support@redis.com",
"url": "https://redis.com/redis-enterprise/redis-insight"
},
"bugs": {
"url": "https://github.com/"
},
"description": "Show Profile/Explain Visualization",
"source": "./src/main.tsx",
"styles": "./dist/styles.css",
"main": "./dist/index.js",
"name": "explain-plugin",
"version": "0.0.1",
"scripts": {
"start": "cross-env NODE_ENV=development parcel serve src/index.html",
"build": "rimraf dist && cross-env NODE_ENV=production concurrently \"yarn build:js && yarn minify:js\" \"yarn build:css\" \"yarn build:assets\"",
"build-lite": "rm dist/*.js && cross-env NODE_ENV=production concurrently \"yarn build:js && yarn minify:js\"",
"build:js": "parcel build src/main.tsx --dist-dir dist",
"build:css": "parcel build src/styles/styles.less --dist-dir dist",
"build:assets": "parcel build src/assets/**/* --dist-dir dist",
"minify:js": "terser -- dist/main.js > dist/index.js && rimraf dist/main.js"
},
"targets": {
"main": false,
"module": {
"includeNodeModules": true
}
},
"visualizations": [
{
"id": "profile-explain-viz",
"name": "Visualization",
"activationMethod": "renderCore",
"matchCommands": [
"FT.EXPLAIN",
"FT.EXPLAINCLI",
"FT.PROFILE",
"GRAPH.EXPLAIN",
"GRAPH.PROFILE"
],
"iconDark": "./dist/profile_icon_dark.svg",
"iconLight": "./dist/profile_icon_light.svg",
"description": "Profile/Explain plugin Visualization",
"default": true
}
],
"devDependencies": {
"@parcel/compressor-brotli": "^2.0.0",
"@parcel/compressor-gzip": "^2.0.0",
"@parcel/transformer-less": "^2.3.2",
"concurrently": "^6.3.0",
"cross-env": "^7.0.3",
"parcel": "^2.0.0",
"rimraf": "^3.0.2",
"terser": "^5.9.0"
},
"dependencies": {
"@antv/hierarchy": "^0.6.8",
"@antv/x6": "^2.1.3",
"@antv/x6-react-shape": "^2.1.0",
"@elastic/eui": "34.6.0",
"@emotion/react": "^11.7.1",
"classnames": "^2.3.1",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"redisinsight-plugin-sdk": "^1.1.0",
"uuid": "^9.0.0"
}
}
25 changes: 25 additions & 0 deletions redisinsight/ui/src/packages/ri-explain/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import Explain from './Explain'

export function App(props: { command?: string, data: any }) {

const ErrorResponse = HandleError(props)

if (ErrorResponse !== null) return ErrorResponse

return (
<div id="mainApp" style={{ height: "100%", width: '100%', overflow: 'hidden'}}>
<Explain command={props.command || ''} data={props.data}/>
</div>
)
}

function HandleError(props: { command?: string, data: any }): JSX.Element | null {
const { data: [{ response = '', status = '' } = {}] = [] } = props

if (status === 'fail') {
return <div className="responseFail">{JSON.stringify(response)}</div>
}

return null
}
Loading