Skip to content

Commit c2e5bd3

Browse files
Merge pull request #334 from RedisInsight/redisgraph-plugin
Add redisgraph plugin
2 parents f7a28b1 + df18b96 commit c2e5bd3

27 files changed

+6098
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
dist/
3+
.parcel-cache
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# RedisGraph Plugin for RedisInsight v2
2+
3+
The example has been created using React, TypeScript, and [Elastic UI](https://elastic.github.io/eui/#/).
4+
[Parcel](https://parceljs.org/) is used to build the plugin.
5+
6+
## Running locally
7+
8+
The following commands will install dependencies and start the server to run the plugin locally:
9+
```
10+
yarn
11+
yarn start
12+
```
13+
These commands will install dependencies and start the server.
14+
15+
_Note_: Base styles are included to `index.html` from the repository.
16+
17+
This command will generate the `vendor` folder with styles and fonts of the core app. Add this folder
18+
inside the folder for your plugin and include appropriate styles to the `index.html` file.
19+
20+
```
21+
yarn build:statics - for Linux or MacOs
22+
yarn build:statics:win - for Windows
23+
```
24+
25+
## Build plugin
26+
27+
The following commands will build plugins to be used in RedisInsight:
28+
```
29+
yarn
30+
yarn build
31+
```
32+
33+
[Add](../../../../../docs/plugins/installation.md) the package.json file and the
34+
`dist` folder to the folder with your plugin, which should be located in the `plugins` folder.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"author": {
3+
"name": "Redis Ltd.",
4+
"email": "[email protected]",
5+
"url": "https://redis.com/redis-enterprise/redis-insight"
6+
},
7+
"bugs": {
8+
"url": "https://github.com/"
9+
},
10+
"description": "Show graph Visualization/table",
11+
"source": "./src/main.tsx",
12+
"styles": "./dist/styles.css",
13+
"main": "./dist/index.js",
14+
"name": "graph-plugin",
15+
"version": "0.0.1",
16+
"scripts": {
17+
"start": "cross-env NODE_ENV=development parcel serve src/index.html",
18+
"build": "rimraf dist && cross-env NODE_ENV=production concurrently \"yarn build:js && yarn minify:js\" \"yarn build:css\"",
19+
"build-lite": "rm dist/*.js && cross-env NODE_ENV=production concurrently \"yarn build:js && yarn minify:js\"",
20+
"build:js": "parcel build src/main.tsx --dist-dir dist",
21+
"build:css": "parcel build src/styles/styles.less --dist-dir dist",
22+
"minify:js": "terser -- dist/main.js > dist/index.js && rimraf dist/main.js"
23+
},
24+
"targets": {
25+
"main": false,
26+
"module": {
27+
"includeNodeModules": true
28+
}
29+
},
30+
"visualizations": [
31+
{
32+
"id": "graph-table",
33+
"name": "Table",
34+
"activationMethod": "renderGraphTable",
35+
"matchCommands": [
36+
"GRAPH.RO_QUERY",
37+
"GRAPH.QUERY"
38+
],
39+
"description": "Example of graph table plugin",
40+
"default": false
41+
},
42+
{
43+
"id": "graph-viz",
44+
"name": "Graph",
45+
"activationMethod": "renderGraph",
46+
"matchCommands": [
47+
"GRAPH.RO_QUERY",
48+
"GRAPH.QUERY"
49+
],
50+
"description": "Example of graph plugin",
51+
"default": true
52+
}
53+
],
54+
"devDependencies": {
55+
"@parcel/compressor-brotli": "^2.0.0",
56+
"@parcel/compressor-gzip": "^2.0.0",
57+
"@parcel/transformer-less": "^2.3.2",
58+
"@types/d3": "^7.1.0",
59+
"@types/react-json-tree": "^0.13.0",
60+
"concurrently": "^6.3.0",
61+
"cross-env": "^7.0.3",
62+
"parcel": "^2.0.0",
63+
"rimraf": "^3.0.2",
64+
"terser": "^5.9.0"
65+
},
66+
"dependencies": {
67+
"@elastic/eui": "34.6.0",
68+
"@emotion/react": "^11.7.1",
69+
"classnames": "^2.3.1",
70+
"d3": "^7.3.0",
71+
"prop-types": "^15.8.1",
72+
"react": "^17.0.2",
73+
"react-dom": "^17.0.2",
74+
"react-json-tree": "^0.16.1",
75+
"redisinsight-plugin-sdk": "^1.0.0"
76+
}
77+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React from 'react'
2+
import { JSONTree } from 'react-json-tree'
3+
import { ResultsParser } from './parser'
4+
import Graph from './Graph'
5+
import { Table } from './Table'
6+
7+
const isDarkTheme = document.body.classList.contains('theme_DARK')
8+
9+
const json_tree_theme = {
10+
scheme: 'solarized',
11+
author: 'ethan schoonover (http://ethanschoonover.com/solarized)',
12+
base00: '#002b36',
13+
base01: '#073642',
14+
base02: '#586e75',
15+
base03: '#657b83',
16+
base04: '#839496',
17+
base05: '#93a1a1',
18+
base06: '#eee8d5',
19+
base07: '#fdf6e3',
20+
base08: '#dc322f',
21+
base09: '#098658',
22+
base0A: '#b58900',
23+
base0B: '#A31515',
24+
base0C: '#2aa198',
25+
base0D: '#0451A5',
26+
base0E: '#6c71c4',
27+
base0F: '#d33682',
28+
}
29+
30+
export function TableApp(props: { command?: string, data: any }) {
31+
32+
const ErrorResponse = HandleError(props)
33+
34+
if (ErrorResponse !== null) return ErrorResponse
35+
36+
const tableData = ResultsParser(props.data[0].response as any)
37+
38+
return (
39+
<div className="table-view">
40+
<Table
41+
data={tableData.results}
42+
columns={tableData.headers.map(h => ({
43+
field: h,
44+
name: h,
45+
render: d => (
46+
<JSONTree
47+
invertTheme={isDarkTheme}
48+
theme={{
49+
extend: json_tree_theme,
50+
tree: ({ style }) => ({
51+
style: { ...style, backgroundColor: undefined }, // removing default background color from styles
52+
}),
53+
}}
54+
labelRenderer={(key) => key ? key : null}
55+
hideRoot
56+
data={d}
57+
/>
58+
)
59+
}))}
60+
/>
61+
</div>
62+
)
63+
}
64+
65+
66+
export function GraphApp(props: { command?: string, data: any }) {
67+
68+
const ErrorResponse = HandleError(props)
69+
70+
if (ErrorResponse !== null) return ErrorResponse
71+
72+
return (
73+
<div style={{ height: "100%" }}>
74+
<Graph graphKey={props.command.split(' ')[1]} data={props.data[0].response} />
75+
</div>
76+
)
77+
}
78+
79+
function HandleError(props: { command?: string, data: any }): JSX.Element {
80+
const { data: [{ response = '', status = '' } = {}] = [] } = props
81+
82+
if (status === 'fail') {
83+
return <div className="responseFail">{JSON.stringify(response)}</div>
84+
}
85+
86+
if (status === 'success' && typeof(response) === 'string') {
87+
return <div className="responseFail">{JSON.stringify(response)}</div>
88+
}
89+
90+
const command = props.command.split(' ')
91+
92+
if (command[command.length - 1] === '--compact') {
93+
return <div className="responseFail">'--compact' flag is currently not supported.</div>
94+
}
95+
96+
return null
97+
}

0 commit comments

Comments
 (0)