-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.js
110 lines (95 loc) · 2.93 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import React, { useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { AccountPicker } from 'nr1';
import patterns from './patterns';
import styles from './index.scss';
const NRQL_STYLES = {
keyword: 'color: #AA1BC8;',
function: 'color: #3B79B8;',
string: 'color: #4F8400;',
numeric: 'color: #AB6400;',
operator: 'color: #3D808A;',
};
const lexer = (nrql) =>
patterns.reduce(
(acc, { name, regex } = {}) =>
acc.replace(
regex,
(match) => `<span style="${NRQL_STYLES[name]}">${match}</span>`
),
nrql
);
const NrqlEditor = ({
query = 'SELECT * FROM Transaction',
accountId,
onSave,
saveButtonText = 'Run',
}) => {
const [nrql, setNrql] = useState('');
const [selectedAccountId, setSelectedAccountId] = useState();
const [displayNode, setDisplayNode] = useState();
useEffect(() => setSelectedAccountId(accountId), [accountId]);
useEffect(() => setNrql(query), [query]);
const scrollHandler = useCallback(
({ target: { scrollTop = 0 } = {} } = {}) => {
if (displayNode) displayNode.scrollTop = scrollTop;
},
[displayNode]
);
const displayNodeHandler = useCallback((node) => setDisplayNode(node), []);
const saveHandler = useCallback(() => {
if (onSave) onSave({ query: nrql, accountId: selectedAccountId });
}, [nrql, selectedAccountId, onSave]);
const keyDownHandler = useCallback(
(e) => {
const { keyCode, shiftKey } = e;
if (keyCode === 13 && !shiftKey) {
e.preventDefault();
saveHandler();
}
},
[saveHandler]
);
return (
<div className={styles['nrql-editor']}>
<div className={styles['account-picker']}>
<AccountPicker
value={selectedAccountId}
onChange={(_, value) => setSelectedAccountId(value)}
/>
</div>
<div className={styles['color-coded-nrql']}>
<div className={styles.editor}>
<textarea
className={`u-unstyledInput ${styles.entry}`}
autoComplete="off"
autoCorrect="off"
spellCheck="false"
value={nrql}
onChange={({ target: { value } = {} } = {}) => setNrql(value)}
onScroll={scrollHandler}
onKeyDown={keyDownHandler}
/>
<pre ref={displayNodeHandler} className={styles.display}>
<code dangerouslySetInnerHTML={{ __html: lexer(nrql) }} />
</pre>
</div>
</div>
<div className={styles.actions}>
<div>Use ⏎ to {saveButtonText.toLowerCase()}</div>
<div className={styles['bump-right']}>
<button className={styles['small-button']} onClick={saveHandler}>
{saveButtonText}
</button>
</div>
</div>
</div>
);
};
NrqlEditor.propTypes = {
query: PropTypes.string,
accountId: PropTypes.number,
onSave: PropTypes.func,
saveButtonText: PropTypes.string,
};
export default NrqlEditor;