Skip to content

Commit 2f16a30

Browse files
authored
Merge pull request #57 from metrico/jacovinus-search-history
Search History Feature: #29
2 parents f159b64 + efefb0d commit 2f16a30

File tree

12 files changed

+1016
-71
lines changed

12 files changed

+1016
-71
lines changed

Diff for: .github/workflows/npm_build_test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
target-directory: 'view'
7979
target-branch: 'view'
8080
destination-github-username: 'lmangani'
81-
destination-repository-name: 'cloki'
81+
destination-repository-name: 'cLoki'
8282
user-email: [email protected]
8383
commit-message: Upgrade view to ${{steps.version.outputs.newTag}}
8484
- name: Deploy to gh-pages 🚀

Diff for: src/App.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ export default function App() {
1010
</Provider>
1111
);
1212

13-
}
13+
}

Diff for: src/actions/index.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
21
export * from "./setStartTime";
32
export * from "./setStopTime";
43
export * from "./setQueryLimit";
54
export * from "./setQueryStep";
65
export * from "./setRangeOpen";
7-
export * from "./setTimeRangeLabel"
6+
export * from "./setTimeRangeLabel";
87
export * from "./setApiUrl";
98
export * from "./setQuery";
109
export * from "./setIsSubmit";
1110
export * from "./setMatrixData";
11+
export * from "./setQueryHistory";
12+
export * from "./setHistoryOpen";
1213
export * from "./setApiError";
1314
export * from "./errorHandler";
1415
export * from "./setLabels";

Diff for: src/actions/setHistoryOpen.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const setHistoryOpen = (historyOpen) => (dispatch)=>{
2+
dispatch({
3+
type: 'SET_HISTORY_OPEN',
4+
historyOpen
5+
})
6+
}
7+
export default setHistoryOpen

Diff for: src/actions/setQueryHistory.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const setQueryHistory = (queryHistory) => (dispatch) => {
2+
dispatch({
3+
type: 'SET_QUERY_HISTORY',
4+
queryHistory
5+
});
6+
7+
}
8+
9+
export default setQueryHistory

Diff for: src/components/LabelBrowser/QueryBar.js

+111-60
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,138 @@
11
import React, { useState, useEffect } from "react";
2-
import { useSelector, useDispatch } from 'react-redux'
2+
import { useSelector, useDispatch } from "react-redux";
33
import { setIsSubmit, setQuery } from "../../actions";
4-
import loadLogs from "../../actions/loadLogs"
5-
import setLoading from "../../actions/setLoading"
4+
import loadLogs from "../../actions/loadLogs";
5+
import setLoading from "../../actions/setLoading";
66
import { setLabelsBrowserOpen } from "../../actions/setLabelsBrowserOpen";
7-
7+
import localService from "../../services/localService";
8+
import setQueryHistory from "../../actions/setQueryHistory";
9+
import HistoryIcon from "@mui/icons-material/History";
10+
import styled from "@emotion/styled";
11+
import setHistoryOpen from "../../actions/setHistoryOpen";
12+
import { Tooltip } from "@mui/material";
13+
import Badge from '@mui/material/Badge';
14+
15+
const HistoryButton = styled.button`
16+
background: none;
17+
color: #ddd;
18+
font-size: 14px;
19+
border: none;
20+
cursor: pointer;
21+
`;
822
export const QueryBar = () => {
923
//const [query, setQuery] = useState(props.query);
1024

11-
const dispatch = useDispatch()
12-
const labelsBrowserOpen = useSelector((store) => store.labelsBrowserOpen)
13-
const debug = useSelector(store => store.debug)
14-
const query = useSelector((store) => store.query)
15-
const isSubmit = useSelector(store => store.isSubmit)
16-
const [queryInput, setQueryInput] = useState(query)
17-
const [queryValid, setQueryValid] = useState(false)
18-
const SHOW_LOGS = "Show Logs"
19-
const LOG_BROWSER = "Log Browser"
20-
const onQueryValid = (query) => {
21-
return query !== '{' && query !== '}' && query !== '{}' && query !== '' // TODO: make a proper query validation
22-
}
25+
const dispatch = useDispatch();
26+
const historyService = localService().historyStore();
27+
const labelsBrowserOpen = useSelector((store) => store.labelsBrowserOpen);
28+
const debug = useSelector((store) => store.debug);
29+
const query = useSelector((store) => store.query);
30+
const isSubmit = useSelector((store) => store.isSubmit);
31+
const historyOpen = useSelector((store) => store.historyOpen)
32+
const [queryInput, setQueryInput] = useState(query);
33+
const [queryValid, setQueryValid] = useState(false);
34+
35+
const SHOW_LOGS = "Show Logs";
36+
const LOG_BROWSER = "Log Browser";
37+
const queryHistory = useSelector((store) => store.queryHistory)
38+
const [historyItems, setHistoryItems] = useState(queryHistory.length>0)
2339

24-
2540
useEffect(()=>{
26-
// force a query to be run after load of component
27-
if (debug) console.log('🚧 LOGIC/QueryBar/', typeof query, query.length)
28-
29-
if (onQueryValid(query && isSubmit === "true") ) {
30-
if (debug) console.log('🚧 LOGIC/QueryBar/ dispatch ', query !== "{}", query.length > 0, query !== "{}" || query.length > 1)
31-
// here
32-
dispatch(setLoading(true))
33-
34-
dispatch(loadLogs())
35-
36-
setTimeout(()=>{
37-
dispatch(setIsSubmit(false))
38-
},200)
39-
40-
} else if( !onQueryValid(query) && isSubmit === "true") {
41-
dispatch(setIsSubmit(false))
42-
}
41+
setHistoryItems(queryHistory.length>0)
42+
},[queryHistory])
4343

44-
},[])
44+
const onQueryValid = (query) => {
45+
return query !== "{" && query !== "}" && query !== "{}" && query !== ""; // TODO: make a proper query validation
46+
};
47+
48+
useEffect(() => {
49+
// force a query to be run after load of component
50+
if (debug)
51+
console.log("🚧 LOGIC/QueryBar/", typeof query, query.length);
52+
53+
if (onQueryValid(query && isSubmit === "true")) {
54+
if (debug)
55+
console.log(
56+
"🚧 LOGIC/QueryBar/ dispatch ",
57+
query !== "{}",
58+
query.length > 0,
59+
query !== "{}" || query.length > 1
60+
);
61+
// here
62+
dispatch(setLoading(true));
63+
64+
dispatch(loadLogs());
65+
66+
setTimeout(() => {
67+
dispatch(setIsSubmit(false));
68+
}, 200);
69+
} else if (!onQueryValid(query) && isSubmit === "true") {
70+
dispatch(setIsSubmit(false));
71+
}
72+
}, []);
4573

4674
useEffect(() => {
4775
setQueryInput(query);
48-
setQueryValid(onQueryValid(query))
76+
setQueryValid(onQueryValid(query));
4977
}, [query, queryInput]);
5078

51-
5279
const onValueDisplay = (e) => {
53-
e.preventDefault()
80+
e.preventDefault();
5481
const isOpen = labelsBrowserOpen ? false : true;
55-
dispatch(setLabelsBrowserOpen(isOpen))
82+
dispatch(setLabelsBrowserOpen(isOpen));
5683
};
5784

5885
const handleChange = (e) => {
5986
const qr = e.target.value;
60-
setQueryInput(qr)
61-
dispatch(setQuery(qr))
87+
setQueryInput(qr);
88+
dispatch(setQuery(qr));
6289
};
6390

6491
const onBrowserActive = () => {
65-
return !labelsBrowserOpen ? ({
66-
'borderColor': '#11abab'
67-
}) : ({})
68-
}
92+
return !labelsBrowserOpen
93+
? {
94+
borderColor: "#11abab",
95+
}
96+
: {};
97+
};
6998

7099
const handleInputKeyDown = (e) => {
71-
if (e.code === 'Enter' && e.ctrlKey) {
72-
onSubmit(e)
100+
if (e.code === "Enter" && e.ctrlKey) {
101+
onSubmit(e);
73102
}
74-
}
103+
};
75104

76105
const onSubmit = (e) => {
77106
e.preventDefault();
78-
79-
dispatch(setQuery(queryInput))
80107

81-
if (onQueryValid(query)) {
82-
dispatch(setLabelsBrowserOpen(false))
83-
dispatch(loadLogs())
108+
dispatch(setQuery(queryInput));
84109

110+
if (onQueryValid(query)) {
111+
try {
112+
const historyUpdated = historyService.add({
113+
data: query,
114+
url: window.location.hash,
115+
});
116+
dispatch(setQueryHistory(historyUpdated));
117+
dispatch(setLabelsBrowserOpen(false));
118+
dispatch(loadLogs());
119+
} catch (e) {
120+
console.log(e);
121+
}
85122
} else {
86-
87123
console.log("Please make a log query", query);
88-
89124
}
90125
};
91-
92-
93-
126+
function handleHistoryClick(e){
127+
dispatch((setHistoryOpen(!historyOpen)))
128+
}
94129
return (
95130
<div className={"query-bar-container"}>
96131
<span
97132
style={onBrowserActive()}
98-
className={"show-log-browser"} onClick={onValueDisplay}>
133+
className={"show-log-browser"}
134+
onClick={onValueDisplay}
135+
>
99136
{LOG_BROWSER}
100137
</span>
101138

@@ -104,10 +141,24 @@ export const QueryBar = () => {
104141
placeholder={"Enter a cLoki Query"}
105142
onChange={handleChange}
106143
value={queryInput}
107-
tabIndex='0'
144+
tabIndex="0"
108145
onKeyDown={handleInputKeyDown}
109146
/>
147+
<Tooltip title={'Query History ('+queryHistory.length+')'}>
148+
149+
150+
<HistoryButton
151+
style={{
152+
color: historyItems ? 'orange': '#ddd'
153+
}}
154+
onClick={e => handleHistoryClick(e)}
155+
>
156+
<HistoryIcon fontSize={"small"}/>
157+
</HistoryButton>
158+
159+
110160

161+
</Tooltip>
111162
<button
112163
disabled={!queryValid}
113164
type="submit"

Diff for: src/components/LogView.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { ZoomIn, ZoomOut } from "@mui/icons-material/";
2-
import { CircularProgress, IconButton } from "@mui/material";
2+
import { CircularProgress, } from "@mui/material";
33
import * as moment from "moment";
44
import React, { Component } from "react";
55
import { connect } from "react-redux";
66
import { setLabels } from "../actions";
77
import loadLabelValues from '../actions/loadLabelValues';
88
import ClokiChart from "../plugins/charts";
9+
import QueryHistory from "../plugins/queryhistory";
910
import store from "../store/store";
1011
import { queryBuilderWithLabels } from "./LabelBrowser/helpers/querybuilder";
1112

@@ -53,10 +54,10 @@ export const ValueTags = (props) => {
5354
return Object.entries(tags).map(
5455
([key, value], k) => (
5556
<div className={"value-tags"} key={k}>
56-
<span aria-label="Filter for value" title="Filter for value" onClick={(e) => addLabel(e, key, value)} class={'icon'}>
57+
<span aria-label="Filter for value" title="Filter for value" onClick={(e) => addLabel(e, key, value)} className={'icon'}>
5758
<ZoomIn color='primary'/>
5859
</span>
59-
<span aria-label="Filter out value" title='Filter out value' onClick={(e) => addLabel(e, key, value, true)} class={'icon'}>
60+
<span aria-label="Filter out value" title='Filter out value' onClick={(e) => addLabel(e, key, value, true)} className={'icon'}>
6061
<ZoomOut color='primary'/>
6162
</span>
6263

@@ -173,11 +174,12 @@ class LogView extends Component {
173174
letterSpacing:"1px"
174175
}}
175176
>
176-
Please Adjust Search Parameters and Click on Show Logs
177+
{"Please adjust search parameters and click on Show Logs’ button"}
177178
</span>
178179

179180
</div>
180181
)}
182+
<QueryHistory/>
181183
{this.props.loading && (
182184
<CircularProgress
183185
className={"progress"}

0 commit comments

Comments
 (0)