Mirror of https://github.com/roostorg/osprey
github.com/roostorg/osprey
1import * as React from 'react';
2import { Input, Menu, Select } from 'antd';
3
4import useApplicationConfigStore from '../../stores/ApplicationConfigStore';
5import QueryHistoryList from '../query_history/QueryHistoryList';
6import { QueryRecordCardTypes } from '../query_history/QueryRecordCard';
7import { SavedQueryCardTypes } from '../saved_queries/SavedQueryCard';
8import SavedQueryList from '../saved_queries/SavedQueryList';
9
10import { querySearchContext } from './QuerySearchContext';
11
12import styles from './QueryListPanel.module.css';
13
14enum QueryListPanelTabs {
15 HISTORY = 'HISTORY',
16 SAVED_QUERIES = 'SAVED_QUERIES',
17}
18
19enum QueryListFilterOptions {
20 ALL = 'ALL',
21 MINE = 'MINE',
22}
23
24const QueryListPanel = () => {
25 const currentUser = useApplicationConfigStore((state) => state.currentUser);
26 const [selectedTab, setSelectedTab] = React.useState(QueryListPanelTabs.HISTORY);
27 const [filterOption, setFilterOption] = React.useState(QueryListFilterOptions.ALL);
28 const [search, setSearch] = React.useState('');
29 const [regexEnabled, setRegexEnabled] = React.useState(false);
30 const handleMenuItemClick = (e: { key: React.Key }) => {
31 setSelectedTab(e.key as QueryListPanelTabs);
32 };
33
34 const renderQueryList = () => {
35 let user;
36
37 if (filterOption === QueryListFilterOptions.MINE) {
38 user = currentUser;
39 }
40
41 switch (selectedTab) {
42 case QueryListPanelTabs.HISTORY:
43 return <QueryHistoryList userEmail={user?.email} cardType={QueryRecordCardTypes.SIDEBAR} />;
44 case QueryListPanelTabs.SAVED_QUERIES:
45 return (
46 <SavedQueryList
47 userEmail={user?.email}
48 cardType={search.length ? SavedQueryCardTypes.DETAILED : SavedQueryCardTypes.COMPACT}
49 />
50 );
51 }
52 };
53
54 return (
55 <>
56 <RegexSearchInput
57 query={search}
58 setQuery={setSearch}
59 regexEnabled={regexEnabled}
60 setRegexEnabled={setRegexEnabled}
61 />
62 <querySearchContext.Provider value={{ query: search, regex: regexEnabled }}>
63 <div className={styles.menuWrapper}>
64 <Menu onClick={handleMenuItemClick} mode="horizontal" selectedKeys={[selectedTab]}>
65 <Menu.Item key={QueryListPanelTabs.HISTORY}>History</Menu.Item>
66 <Menu.Item key={QueryListPanelTabs.SAVED_QUERIES}>Saved Queries</Menu.Item>
67 </Menu>
68 <Select onChange={setFilterOption} className={styles.filterSelect} defaultValue={QueryListFilterOptions.ALL}>
69 <Select.Option value={QueryListFilterOptions.ALL}>All</Select.Option>
70 <Select.Option value={QueryListFilterOptions.MINE}>My Queries</Select.Option>
71 </Select>
72 </div>
73 {renderQueryList()}
74 </querySearchContext.Provider>
75 </>
76 );
77};
78
79export default QueryListPanel;
80
81const RegexToggleButton = ({
82 regexEnabled,
83 setRegexEnabled,
84}: {
85 regexEnabled: boolean;
86 setRegexEnabled: (regex: boolean) => void;
87}) => {
88 return (
89 <button
90 onClick={() => setRegexEnabled(!regexEnabled)}
91 title={regexEnabled ? 'Disable RegEx' : 'Enable RegEx'}
92 data-enabled={regexEnabled}
93 className={styles.regexButton}
94 >
95 .*
96 </button>
97 );
98};
99type RegexSearchInputProps = {
100 query: string;
101 setQuery: (query: string) => void;
102 regexEnabled: boolean;
103 setRegexEnabled: (regex: boolean) => void;
104};
105const RegexSearchInput = ({ query, regexEnabled, setQuery, setRegexEnabled }: RegexSearchInputProps) => {
106 return (
107 <Input.Search
108 value={query}
109 onInput={(e) => setQuery(e.currentTarget.value)}
110 prefix={<span style={{ color: '#00000050', width: '1ch' }}>{regexEnabled ? '/' : ''}</span>}
111 suffix={
112 <>
113 <span style={{ color: '#00000050', width: '2ch' }}>{regexEnabled ? '/g' : ''}</span>
114 <RegexToggleButton regexEnabled={regexEnabled} setRegexEnabled={setRegexEnabled} />
115 </>
116 }
117 />
118 );
119};