diff --git a/src/actions/LoadLabels.js b/src/actions/LoadLabels.js index 639124cc..a7295648 100644 --- a/src/actions/LoadLabels.js +++ b/src/actions/LoadLabels.js @@ -3,6 +3,7 @@ import { setLabels } from "./setLabels"; import setLoading from "./setLoading"; import { setApiError } from "./setApiError"; import { errorHandler } from "./errorHandler"; +import { setLabelsBrowserOpen } from "./setLabelsBrowserOpen"; export default function loadLabels(apiUrl) { const origin = window.location.origin; @@ -21,9 +22,9 @@ export default function loadLabels(apiUrl) { mode: "cors", }; - return async (dispatch) => { + return function (dispatch) { - await axios.get(`${url.trim()}/loki/api/v1/labels`, options) + axios.get(`${url.trim()}/loki/api/v1/labels`, options) ?.then((response) => { if(response){ if(response?.data?.data === []) console.log('no labels found') @@ -35,13 +36,19 @@ export default function loadLabels(apiUrl) { values: [], })); dispatch(setLabels(labels || [])); + dispatch(setApiError('')) } + }else { + dispatch(setLoading(false)) + dispatch(setApiError('API Not Found, Please adjust API URL')) + dispatch(setLabelsBrowserOpen(true)) + dispatch(setLabels([])) } }).catch(error => { console.log(error) - dispatch(setLoading(false)) + dispatch(setLoading(false)) const {message,status} = errorHandler(url, error) dispatch(setLabels([])) diff --git a/src/actions/createAlert.js b/src/actions/createAlert.js index 788530cf..c6f7629c 100644 --- a/src/actions/createAlert.js +++ b/src/actions/createAlert.js @@ -1,7 +1,6 @@ import store from '../store/store'; export const createAlert = ( action) => (dispatch) => { - console.log(action) const notifications = store.getState().notifications notifications.push({ message: action.message, diff --git a/src/actions/loadLabelValues.js b/src/actions/loadLabelValues.js index baf189ca..486e7a03 100644 --- a/src/actions/loadLabelValues.js +++ b/src/actions/loadLabelValues.js @@ -47,6 +47,9 @@ export default function loadLabelValues(label, labelList, apiUrl) { } }); dispatch(setLabels(lsList)) + } else if(!response) { + dispatch(setApiError('URL NOT FOUND')) + dispatch(setLabelValues([])) } dispatch(setLoading(false)); @@ -56,8 +59,8 @@ export default function loadLabelValues(label, labelList, apiUrl) { }).catch(error => { dispatch(setLoading(false)) const { message } = errorHandler(url, error) - dispatch(setApiError(message)) - + dispatch(setApiError(message || 'API NOT FOUND')) + dispatch(setLabelValues([])) console.err(error) }) } diff --git a/src/actions/loadLogs.js b/src/actions/loadLogs.js index acf9efe2..ab946366 100644 --- a/src/actions/loadLogs.js +++ b/src/actions/loadLogs.js @@ -3,7 +3,7 @@ import setLogs from "./setLogs"; import setLoading from "./setLoading"; import store from "../store/store"; import setMatrixData from "./setMatrixData"; -import {nanoid} from 'nanoid' +import { nanoid } from "nanoid"; import { findRangeByLabel } from "../plugins/daterangepicker/utils"; import { setStartTime, setStopTime } from "./"; // *query : LogQl Query @@ -14,110 +14,117 @@ import { setStartTime, setStopTime } from "./"; // *direction : Determines sort order of logs. Either forward or backward. Default is backward export default function loadLogs() { - // const step = 120 - // const direction = 'backward' - const localStore = store.getState(); - const { query, limit, step, apiUrl, label: rangeLabel } = localStore; - let { start: startTs, stop: stopTs } = localStore; + // const step = 120 + // const direction = 'backward' + const localStore = store.getState(); + const { query, limit, step, apiUrl, label: rangeLabel } = localStore; + let { start: startTs, stop: stopTs } = localStore; - if (findRangeByLabel(rangeLabel)) { - ({ dateStart: startTs, dateEnd: stopTs } = - findRangeByLabel(rangeLabel)); - } + if (findRangeByLabel(rangeLabel)) { + ({ dateStart: startTs, dateEnd: stopTs } = findRangeByLabel(rangeLabel)); + } - store.dispatch(setStartTime(startTs)); - store.dispatch(setStopTime(stopTs)); + store.dispatch(setStartTime(startTs)); + store.dispatch(setStopTime(stopTs)); - const origin = window.location.origin; - const url = apiUrl; - const parsedTime ="&start=" + - startTs?.getTime() + - "000000" + - "&end=" + - stopTs?.getTime() + - "000000"; + const origin = window.location.origin; + const url = apiUrl; + const parsedTime = + "&start=" + + startTs?.getTime() + + "000000" + + "&end=" + + stopTs?.getTime() + + "000000"; - const queryStep = `&step=${step || 120}`; + const queryStep = `&step=${step || 120}`; - const encodedQuery = `${encodeURIComponent(query)}`; + const encodedQuery = `${encodeURIComponent(query)}`; - const getUrl = `${url}/loki/api/v1/query_range?query=${encodedQuery}&limit=${limit}${parsedTime}${queryStep}`; + const getUrl = `${url}/loki/api/v1/query_range?query=${encodedQuery}&limit=${limit}${parsedTime}${queryStep}`; - const options = { - method: "GET", - headers: { - "Content-Type": "application/javascript", - "Access-Control-Allow-Origin": origin, - }, - }; + const options = { + method: "GET", + headers: { + "Content-Type": "application/javascript", + "Access-Control-Allow-Origin": origin, + }, + }; - const fromNanoSec = (ts) => parseInt(ts / 1000000); // stream type will come in Nanoseconds - const toMiliseC = (ts) => parseInt(ts * 1000); // matrix type will come without millisec - const getTimestamp = (type) => (ts) => - type === "streams" - ? fromNanoSec(ts) - : type === "matrix" - ? toMiliseC(ts) - : ts; - const mapStreams = (streams, messages, type) => { - streams.forEach((stream) => { - stream.values.forEach((log, i) => { - let [ts, text] = log; - messages.push({ - type, - timestamp: getTimestamp(type)(ts), - text, - tags: - type === "streams" - ? stream.stream - : type === "matrix" - ? stream.metric - : {}, - showTs: true, - showLabels: false, - id: nanoid(), - }); - }); + const fromNanoSec = (ts) => parseInt(ts / 1000000); // stream type will come in Nanoseconds + const toMiliseC = (ts) => parseInt(ts * 1000); // matrix type will come without millisec + const getTimestamp = (type) => (ts) => + type === "streams" + ? fromNanoSec(ts) + : type === "matrix" + ? toMiliseC(ts) + : ts; + const mapStreams = (streams, messages, type) => { + streams.forEach((stream) => { + stream.values.forEach((log, i) => { + let [ts, text] = log; + messages.push({ + type, + timestamp: getTimestamp(type)(ts), + text, + tags: + type === "streams" + ? stream.stream + : type === "matrix" + ? stream.metric + : {}, + showTs: true, + showLabels: false, + id: nanoid(), }); - }; + }); + }); + }; - //const mapMatrix - return function (dispatch) { - dispatch(setLoading(true)); - dispatch(setLogs([])); - dispatch(setMatrixData([])); + //const mapMatrix + return async function (dispatch) { + dispatch(setLoading(true)); + dispatch(setLogs([])); + dispatch(setMatrixData([])); + + await axios + .get(getUrl, options) + ?.then((response) => { + if (response?.data?.data) { + let messages = []; + const result = response?.data?.data?.result; // array + const type = response?.data?.data?.resultType; + if (type === "streams") { + mapStreams(result, messages, type); + dispatch(setMatrixData([])); + const messSorted = messages?.sort((a, b) => + a.timestamp < b.timestamp ? 1 : -1 + ); + if (messSorted) { + dispatch(setLogs(messSorted || [])); - axios - .get(getUrl, options) - ?.then((response) => { - if (response?.data?.data) { - let messages = []; - const result = response?.data?.data?.result; // array - const type = response?.data?.data?.resultType; - if (type === "streams") { - mapStreams(result, messages, type); - dispatch(setMatrixData([])); - const messSorted = messages?.sort((a, b) => (a.timestamp < b.timestamp) ? 1 : -1); - dispatch(setLogs(messSorted || [])); - dispatch(setLoading(false)); - } + dispatch(setLoading(false)); + } + } - if (type === "matrix") { - const idResult = result.map( m => ({...m,id:nanoid()})) - dispatch(setMatrixData(idResult || [])); - dispatch(setLoading(false)); - } - dispatch(setLoading(false)); - } else { - dispatch(setLogs([])); - dispatch(setMatrixData([])); - dispatch(setLoading(false)); - } - dispatch(setLoading(false)); - }) - .catch((error) => { - dispatch(setLoading(false)); - console.log(error); - }); - }; + if (type === "matrix") { + const idResult = result.map((m) => ({ ...m, id: nanoid() })); + dispatch(setMatrixData(idResult || [])); + dispatch(setLoading(false)); + } + dispatch(setLoading(false)); + } else { + dispatch(setLogs([])); + dispatch(setMatrixData([])); + dispatch(setLoading(false)); + } + dispatch(setLoading(false)); + }) + .catch((error) => { + dispatch(setLogs([])); + dispatch(setMatrixData([])); + dispatch(setLoading(false)); + console.log(error); + }); + }; } diff --git a/src/components/LabelBrowser/QueryBar.js b/src/components/LabelBrowser/QueryBar.js index 440d337c..e00fbc22 100644 --- a/src/components/LabelBrowser/QueryBar.js +++ b/src/components/LabelBrowser/QueryBar.js @@ -125,6 +125,7 @@ export const QueryBar = () => { const handleInputKeyDown = (e) => { if (e.code === "Enter" && e.ctrlKey) { + dispatch(setLoading(true)) onSubmit(e); } }; @@ -143,6 +144,7 @@ export const QueryBar = () => { dispatch(setQueryHistory(historyUpdated)); dispatch(setLabelsBrowserOpen(false)); decodeQuery(query, apiUrl); + dispatch(setLoading(true)) dispatch(loadLogs()); const storedUrl = saveUrl.add({ data: window.location.href, diff --git a/src/components/LabelBrowser/ValuesList.js b/src/components/LabelBrowser/ValuesList.js index efeb26ba..00078184 100644 --- a/src/components/LabelBrowser/ValuesList.js +++ b/src/components/LabelBrowser/ValuesList.js @@ -43,7 +43,7 @@ export const ValuesList = (props) => { const dispatch = useDispatch() const debug = useSelector((store) => store.debug) const apiUrl = useSelector((store) => store.apiUrl) - if(debug) console.log('🚧 LOGIC/LabelBrowser/ValuesList', apiUrl) + //if(debug) console.log('🚧 LOGIC/LabelBrowser/ValuesList', apiUrl) const labelsBrowserOpen = useSelector((store) => store.labelsBrowserOpen) const CLEAR = "clear" diff --git a/src/components/LogView.js b/src/components/LogView.js index 646f1319..e33f47a9 100644 --- a/src/components/LogView.js +++ b/src/components/LogView.js @@ -193,9 +193,9 @@ class LogView extends Component { matrixData={this.getMatrixForChart()} /> ) : null} - {this.props.messages.length < 1 && + {(this.props.messages.length < 1 && this.getMatrixForChart().length < 1 && - !this.props.loading && ( + !this.props.loading) && ( { "Please adjust search parameters and click on ‘Show Logs’ button" diff --git a/src/components/StatusBar/StatusBar.js b/src/components/StatusBar/StatusBar.js index b760a2d8..b192a225 100644 --- a/src/components/StatusBar/StatusBar.js +++ b/src/components/StatusBar/StatusBar.js @@ -5,14 +5,13 @@ import LinkIcon from "@mui/icons-material/Link"; import AdapterDateFns from "@mui/lab/AdapterDateFns"; import LocalizationProvider from "@mui/lab/LocalizationProvider"; import { - createAlert, - setApiError, - setIsSubmit, - setQueryLimit, - setQueryStep, - setStartTime, - setStopTime, - setTimeRangeLabel, + createAlert, + setIsSubmit, + setQueryLimit, + setQueryStep, + setStartTime, + setStopTime, + setTimeRangeLabel, } from "../../actions"; import isDate from "date-fns/isDate"; import { setApiUrl } from "../../actions/setApiUrl"; @@ -21,239 +20,231 @@ import { DATE_TIME_RANGE } from "../../plugins/daterangepicker/consts"; import { findRangeByLabel } from "../../plugins/daterangepicker/utils"; import { UpdateStateFromQueryParams } from "../UpdateStateFromQueryParams"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; -import store from "../../store/store"; import loadLabels from "../../actions/LoadLabels"; import localUrl from "../../services/localUrl"; import setLinksHistory from "../../actions/setLinksHistory"; import { Tooltip } from "@mui/material"; import { notificationTypes } from "../../plugins/notifications/consts"; +import setLogs from "../../actions/setLogs"; +import setMatrixData from "../../actions/setMatrixData"; +import loadLogs from "../../actions/loadLogs"; +import { setLabelsBrowserOpen } from "../../actions/setLabelsBrowserOpen"; export default function StatusBar() { - return ( -
-
- {"cLoki - -
- -
- -
-
- ); + return ( +
+
+ {"cLoki + +
+ +
+ +
+
+ ); } export function StatusBarInput(props) { - const { label, value, dispatchAction, type } = props; - const dispatch = useDispatch(); - const handleStatusInputChange = (e) => { - dispatch(dispatchAction(e.target.value)); - }; + const { label, value, dispatchAction, type } = props; + const dispatch = useDispatch(); + const handleStatusInputChange = (e) => { + dispatch(dispatchAction(e.target.value)); + }; + + return ( +
+ {label} + +
+ ); +} - return ( -
- {label} +export function ApiSelector() { + const apiUrl = useSelector((store) => store.apiUrl); + const apiError = useSelector((store) => store.apiErrors); + const [editedUrl, setEditedUrl] = useState(apiUrl); + const [apiSelectorOpen, setApiSelectorOpen] = useState(false); + const dispatch = useDispatch(); + const API_URL = "API URL"; + useEffect(() => { + setEditedUrl(apiUrl); + }, []); + + useEffect(() => { + setEditedUrl(apiUrl); + }, [apiUrl]); + + useEffect(() => { + if (apiError.length > 0) { + setApiSelectorOpen(true); + dispatch(setLogs([])); + dispatch(setMatrixData([])); + } else { + setApiSelectorOpen(false); + dispatch(loadLogs()); + } + }, [apiError]); + + const handleApiUrlOpen = (e = null) => { + e?.preventDefault(); + apiSelectorOpen ? setApiSelectorOpen(false) : setApiSelectorOpen(true); + }; + + const handleIntputChange = (e) => { + e.preventDefault(); + setEditedUrl(e.target.value); + }; + const onUrlSubmit = (e) => { + dispatch(setApiUrl(editedUrl)); + dispatch(loadLabels(editedUrl)); + + dispatch(setLabelsBrowserOpen(false)); + }; + + return ( +
+
+ + {apiSelectorOpen ? ( +
+ {API_URL} -
- ); + +
+ ) : null} +
+
+ ); } -export function ApiSelector() { - const apiUrl = useSelector((store) => store.apiUrl); - const apiError = useSelector((store) => store.apiErrors); - const [editedUrl, setEditedUrl] = useState(apiUrl); - const [apiSelectorOpen, setApiSelectorOpen] = useState(false); - const dispatch = useDispatch(); - const [isError, setIsError] = useState(true); - const API_URL = "API URL"; - useEffect(() => { - setEditedUrl(apiUrl); - }, []); - - useEffect(() => { - setEditedUrl(apiUrl); - }, [apiUrl]); - - useEffect(() => { - if (isError) { - setApiSelectorOpen(true); - } else { - setApiSelectorOpen(false); - setIsError(false); - } - }, [isError]); - - useEffect(() => { - if (apiError.length > 0) { - setIsError(true); - setApiSelectorOpen(true); - } - }, [apiError]); - - const handleApiUrlOpen = (e = null) => { - e?.preventDefault(); - apiSelectorOpen ? setApiSelectorOpen(false) : setApiSelectorOpen(true); - }; - - const handleIntputChange = (e) => { - e.preventDefault(); - setEditedUrl(e.target.value); - }; - const onUrlSubmit = (e) => { - dispatch(setApiError("")); - dispatch(setApiUrl(editedUrl)); - dispatch(loadLabels(apiUrl)); - const isError = store.getState().apiErrors.length === 0; - if (isError) { - handleApiUrlOpen(); +export function StatusBarSelectors() { + const startTs = useSelector((store) => store.start); + const stopTs = useSelector((store) => store.stop); + const queryLimit = useSelector((store) => store.limit); + const queryStep = useSelector((store) => store.step); + const query = useSelector((store) => store.query); + const [copied, setCopied] = useState(false); + const dispatch = useDispatch(); + const [open, setOpen] = useState(); + const LINK_COPIED = "Link Copied To Clipboard"; + const saveUrl = localUrl(); + const initialDateRange = () => { + try { + const ls = JSON.parse(localStorage.getItem(DATE_TIME_RANGE)); + if (ls?.label !== "" && typeof ls.label !== "undefined") { + const range = findRangeByLabel(ls?.label); + ls.dateStart = range.dateStart; + ls.dateEnd = range.dateEnd; + } else { + ls.dateStart = new Date(ls.dateStart); + ls.dateEnd = new Date(ls.dateEnd); + } + + UpdateStateFromQueryParams(); + return ls; + } catch (e) { + if (isDate(startTs) && isDate(stopTs)) { + return { dateStart: startTs, dateEnd: stopTs }; + } + } + }; + const isOpen = (e) => { + e?.preventDefault(); + setOpen(!open); + }; + const shareLink = (e) => { + e.preventDefault(); + const setSubmit = dispatch(setIsSubmit(true)); + setTimeout(() => { + navigator.clipboard.writeText(window.location.href).then( + function () { + if (query.length > 0) { + const storedUrl = saveUrl.add({ + data: window.location.href, + description: "From Shared URL", + }); + dispatch(setLinksHistory(storedUrl)); + } + + dispatch( + createAlert({ + type: notificationTypes.success, + message: LINK_COPIED, + }) + ); + }, + function (err) { + console.err("error on copy", err); } - }; - - return ( + ); + }, 200); + }; + return ( + +
-
- - {apiSelectorOpen ? ( -
- {API_URL} - - -
- ) : null} -
-
- ); -} - -export function StatusBarSelectors() { - const startTs = useSelector((store) => store.start); - const stopTs = useSelector((store) => store.stop); - const queryLimit = useSelector((store) => store.limit); - const queryStep = useSelector((store) => store.step); - const query = useSelector((store) => store.query); - const [copied, setCopied] = useState(false); - const dispatch = useDispatch(); - const [open, setOpen] = useState(); - const LINK_COPIED = "Link Copied To Clipboard"; - const saveUrl = localUrl(); - const initialDateRange = () => { - try { - const ls = JSON.parse(localStorage.getItem(DATE_TIME_RANGE)); - if (ls?.label !== "" && typeof ls.label !== "undefined") { - const range = findRangeByLabel(ls?.label); - ls.dateStart = range.dateStart; - ls.dateEnd = range.dateEnd; - } else { - ls.dateStart = new Date(ls.dateStart); - ls.dateEnd = new Date(ls.dateEnd); + {copied && {LINK_COPIED}} + + + + + + +
- UpdateStateFromQueryParams(); - return ls; - } catch (e) { - if (isDate(startTs) && isDate(stopTs)) { - return { dateStart: startTs, dateEnd: stopTs }; - } - } - }; - const isOpen = (e) => { - e?.preventDefault(); - setOpen(!open); - }; - const shareLink = (e) => { - e.preventDefault(); - const setSubmit = dispatch(setIsSubmit(true)); - setTimeout(() => { - navigator.clipboard.writeText(window.location.href).then( - function () { - if (query.length > 0) { - const storedUrl = saveUrl.add({ - data: window.location.href, - description: "From Shared URL", - }); - dispatch(setLinksHistory(storedUrl)); - } - - dispatch(createAlert({ - type: notificationTypes.success, - message: LINK_COPIED - })) - }, - function (err) { - console.err("error on copy", err); - } - ); - }, 200); - }; - return ( - -
-
- {copied && ( - {LINK_COPIED} - )} - - - - - - -
- - { - const isStart = isDate(dateStart); - const isEnd = isDate(dateEnd); - const isLabel = typeof label !== "undefined"; - if (isStart) dispatch(setStartTime(dateStart)); - if (isEnd) dispatch(setStopTime(dateEnd)); - if (isLabel) dispatch(setTimeRangeLabel(label)); - }} - // here - /> -
-
- ); + { + const isStart = isDate(dateStart); + const isEnd = isDate(dateEnd); + const isLabel = typeof label !== "undefined"; + if (isStart) dispatch(setStartTime(dateStart)); + if (isEnd) dispatch(setStopTime(dateEnd)); + if (isLabel) dispatch(setTimeRangeLabel(label)); + }} + /> + +
+ ); } diff --git a/src/plugins/queryhistory/index.js b/src/plugins/queryhistory/index.js index 791e61b1..404bb532 100644 --- a/src/plugins/queryhistory/index.js +++ b/src/plugins/queryhistory/index.js @@ -36,1028 +36,1001 @@ import localUrl from "../../services/localUrl"; import setLinksHistory from "../../actions/setLinksHistory"; // Alert Dialog for Clearing History function AlertDialog({ clearHistory, dialogType }) { - const [open, setOpen] = useState(false); - - const handleClickOpen = () => { - setOpen(true); - }; - - const handleClose = () => { - setOpen(false); - }; - function handleClearHistory() { - clearHistory(); - setOpen(false); - } - return ( -
- - - {"Clear History"} - - - - - Are you sure you want to clear the {dialogType} History? - - - - Click ‘Clear History’ to delete your {dialogType}{" "} - history permanently - - - - - Cancel - - - Clear History - - - -
- ); + const [open, setOpen] = useState(false); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + function handleClearHistory() { + clearHistory(); + setOpen(false); + } + return ( +
+ + + {"Clear History"} + + + + + Are you sure you want to clear the {dialogType} History? + + + + Click ‘Clear History’ to delete your {dialogType} history + permanently + + + + Cancel + + Clear History + + + +
+ ); } const blue = { - 50: "#F0F7FF", - 100: "#C2E0FF", - 200: "#80BFFF", - 300: "#66B2FF", - 400: "#3399FF", - 500: "#262626", - 600: "#0072E5", - 700: "#0059B2", - 800: "#004C99", - 900: "#003A75", + 50: "#F0F7FF", + 100: "#C2E0FF", + 200: "#80BFFF", + 300: "#66B2FF", + 400: "#3399FF", + 500: "#262626", + 600: "#0072E5", + 700: "#0059B2", + 800: "#004C99", + 900: "#003A75", }; const Tab = styled(TabUnstyled)` + color: #aaa; + cursor: pointer; + font-size: 13px; + background-color: transparent; + padding: 6px 10px; + border: none; + border-radius: 3px 3px 0px 0px; + display: flex; + justify-content: center; + align-items: center; + border-bottom: 1px solid transparent; + transition: 0.2s all; + + &:hover { + background-color: #666666; + } + + &:focus { color: #aaa; - cursor: pointer; - font-size: 13px; - background-color: transparent; - padding: 6px 10px; - border: none; border-radius: 3px 3px 0px 0px; - display: flex; - justify-content: center; - align-items: center; - border-bottom: 1px solid transparent; - transition: 0.2s all; - - &:hover { - background-color: #666666; - } - - &:focus { - color: #aaa; - border-radius: 3px 3px 0px 0px; - outline-offset: 2px; - } + outline-offset: 2px; + } - &.${tabUnstyledClasses.selected} { - color: #eee; - border-bottom: 1px solid #11abab; - } + &.${tabUnstyledClasses.selected} { + color: #eee; + border-bottom: 1px solid #11abab; + } - &.${buttonUnstyledClasses.disabled} { - opacity: 0.5; - cursor: not-allowed; - } + &.${buttonUnstyledClasses.disabled} { + opacity: 0.5; + cursor: not-allowed; + } `; const TabHistoryIcon = styled(HistoryIcon)` - height: 16px; - width: 16px; - margin-right: 3px; + height: 16px; + width: 16px; + margin-right: 3px; `; const TabHistoryStarIcon = styled(StarBorderIcon)` - height: 16px; - width: 16px; - margin-right: 3px; + height: 16px; + width: 16px; + margin-right: 3px; `; const TabHistorySettingIcon = styled(DisplaySettingsIcon)` - height: 16px; - width: 16px; - margin-right: 3px; + height: 16px; + width: 16px; + margin-right: 3px; `; const TabHistoryLinkIcon = styled(LinkIcon)` - height: 16px; - width: 16px; - margin-right: 3px; + height: 16px; + width: 16px; + margin-right: 3px; `; const TabHistorySearchIcon = styled(SearchIcon)` - height: 21px; - width: 16px; - padding: 0px 3px; - border-radius: 3px 0px 0px 3px; - background: #121212; + height: 21px; + width: 16px; + padding: 0px 3px; + border-radius: 3px 0px 0px 3px; + background: #121212; `; const TabHeaderContainer = styled.div` - padding: 0px 15px; - font-size: 13px; - display: flex; - align-items: center; - justify-content: space-between; - background: #8a8a8a50; - height: 37px; + padding: 0px 15px; + font-size: 13px; + display: flex; + align-items: center; + justify-content: space-between; + background: #8a8a8a50; + height: 37px; `; const TabPanel = styled(TabPanelUnstyled)` - width: 100%; + width: 100%; `; const TabsList = styled(TabsListUnstyled)` - min-width: 320px; - background-color: ${blue[500]}; - border-bottom: 4px solid #2e2e2e; - display: flex; - align-items: center; - align-content: space-between; + min-width: 320px; + background-color: ${blue[500]}; + border-bottom: 4px solid #2e2e2e; + display: flex; + align-items: center; + align-content: space-between; `; const EmptyHistory = styled.div` - display: flex; - align-items: center; - justify-content: center; - color: #ddd; - font-size: 14px; - flex: 1; - height: 50%; + display: flex; + align-items: center; + justify-content: center; + color: #ddd; + font-size: 14px; + flex: 1; + height: 50%; `; function EmptyHistoryDisplay({ message }) { - return {message}; + return {message}; } function QueryHistoryTabs({ - historyTabHeader, - historyTab, - starredHistoryTab, - closeButton, - linksTabHeader, - linksTab, - settingTab, - settingTabHeader, + historyTabHeader, + historyTab, + starredHistoryTab, + closeButton, + linksTabHeader, + linksTab, + settingTab, + settingTabHeader, }) { - return ( - - - - - - {"Query History"} - - - - - {"Links History"} - - - - - - Starred - - - - - Settings - - {closeButton} - - - {historyTabHeader} - {historyTab} - - - {linksTabHeader} - {linksTab} - - - {starredHistoryTab} - - {settingTabHeader} - {settingTab} - - - ); + return ( + + + + + + {"Query History"} + + + + + {"Links History"} + + + + + + Starred + + + + + Settings + + {closeButton} + + + {historyTabHeader} + {historyTab} + + + {linksTabHeader} + {linksTab} + + + {starredHistoryTab} + + {settingTabHeader} + {settingTab} + + + ); } export const theme = createTheme({ - palette: { - mode: "dark", - primary: { - main: "#ddd", - background: "#1a1a1a", - }, + palette: { + mode: "dark", + primary: { + main: "#ddd", + background: "#1a1a1a", }, + }, }); const QueryHistoryContainer = styled.div` - height: 250px; - overflow-y: auto; - &::-webkit-scrollbar { - width: 10px; - background: black; - } - - &::-webkit-scrollbar-thumb { - border-radius: 10px; - background: #444; - } + height: 250px; + overflow-y: auto; + &.starredCont { + height: 210px; + } + &::-webkit-scrollbar { + width: 10px; + background: black; + } + + &::-webkit-scrollbar-thumb { + border-radius: 10px; + background: #444; + } `; const HistoryButton = styled.button` - padding: 3px 6px; - background: #333; - border-radius: 3px; - border: none; - color: #ddd; - display: flex; - align-items: center; - justify-content: center; - margin: 0px 6px; - cursor: pointer; + padding: 3px 6px; + background: #333; + border-radius: 3px; + border: none; + color: #ddd; + display: flex; + align-items: center; + justify-content: center; + margin: 0px 6px; + cursor: pointer; `; const SettingItemContainer = styled.div` - height: 100px; - width: 240px; - display: flex; - flex-direction: column; - justify-content: space-between; - padding: 20px; - background: #333; - margin: 10px; - border-radius: 3px; - & div { - font-size: 15px; - color: orange; - } - & small { - font-size: 12px; - color: #ddd; - } + height: 100px; + width: 240px; + display: flex; + flex-direction: column; + justify-content: space-between; + padding: 20px; + background: #333; + margin: 10px; + border-radius: 3px; + & div { + font-size: 15px; + color: orange; + } + & small { + font-size: 12px; + color: #ddd; + } `; const SubmitButton = styled(HistoryButton)` - background: #11abab; + background: #11abab; `; const ClearHistoryButton = styled(HistoryButton)` - font-weight: bold; - padding: 10px 20px; - background: #088789; - margin: 0; - width: 100%; + font-weight: bold; + padding: 10px 20px; + background: #088789; + margin: 0; + width: 100%; `; const StyledCloseButton = styled(HistoryButton)` - background: none; - color: #ddd; - font-size: 14px; - height: 16px; - width: 16px; - position: absolute; - right: 0; + background: none; + color: #ddd; + font-size: 14px; + height: 16px; + width: 16px; + position: absolute; + right: 0; `; const DialogCancelButton = styled(HistoryButton)` - background: #646464; - padding: 8px 16px; + background: #646464; + padding: 8px 16px; `; const DialogConfirmButton = styled(HistoryButton)` - background: #088789; - padding: 8px 16px; + background: #088789; + padding: 8px 16px; `; const FilterInput = styled.input` - color: orange; - background: #121212; - border: none; - height: 21px; - margin: 0px 10px 0px 0px; - padding: 0px; - font-size: 13px; - border-radius: 0px 3px 3px 0px; - font-family: monospace; - font-size: 12px; - &:focus { - outline: none; - } + color: orange; + background: #121212; + border: none; + height: 21px; + margin: 0px 10px 0px 0px; + padding: 0px; + font-size: 13px; + border-radius: 0px 3px 3px 0px; + font-family: monospace; + font-size: 12px; + &:focus { + outline: none; + } +`; +const RowData = styled.span` + flex: 1; + font-family: "monospace"; + font-size: "13px"; + color: "#ddd"; + white-space: nowrap; + padding: 4px 0px; + overflow: hidden; + text-overflow: ellipsis; `; - function CloseButton({ onClose }) { - return ( - - - - ); + return ( + + + + ); } const HistoryRow = styled.div` - padding: 5px 10px; - padding-left: 12px; - background: #212121; - margin: 5px; - border-radius: 3px; - font-size: 13px; - display: flex; - justify-content: space-between; - align-items: center; - height: 30px; + padding: 5px 10px; + padding-left: 12px; + background: #212121; + margin: 5px; + border-radius: 3px; + font-size: 13px; + display: flex; + justify-content: space-between; + align-items: center; + height: 30px; `; const TimeSpan = styled.div` - @media screen and (max-width: 1370px) { - display: none; - } + @media screen and (max-width: 1370px) { + display: none; + } `; function QueryHistoryTab({ - queryHistory, - copyQuery, - handleDelete, - handleStarItem, - handleSubmit, - filtered, - emptyMessage, + queryHistory, + copyQuery, + handleDelete, + handleStarItem, + handleSubmit, + filtered, + emptyMessage, + isStarred, }) { - const [listDisplay, setListDisplay] = useState([]); - useEffect(() => { - setListDisplay(queryHistory); - }, []); - - useEffect(() => { - if (filtered.length > 0) { - setListDisplay(filtered); - } - }, [filtered]); - - useEffect(() => { - setListDisplay(queryHistory); - }, [queryHistory]); - // const listDisplay = filtered.length > 0 ? filtered : queryHistory - return ( - - {listDisplay.length > 0 ? ( - listDisplay?.map((item, index) => ( - - - {listDisplay.length - index} - - - {item.data}{" "} - - - - {format(item.timestamp, "yyyy/MM/dd HH:mm:ss")} - - -
- - copyQuery(item.data)} - > - - - - - - handleDelete(item)} - > - - - - - - handleStarItem(item)} - > - {item.starred ? ( - - ) : ( - - )} - - - - - handleSubmit(item)} - > - {"Show Logs"} - - -
-
- )) - ) : ( - - )} -
- ); -} -function LinksHistoryTab({ - linksHistory, - copyLink, - handleDelete, - handleStarLinkItem, - handleSubmit, - filtered, - emptyMessage, -}) { - const [listDisplay, setListDisplay] = useState([]); - useEffect(() => { - setListDisplay(linksHistory); - }, []); - useEffect(() => { - if (filtered.length > 0) { - setListDisplay(filtered); - } - }, [filtered]); - useEffect(() => { - setListDisplay(linksHistory); - }, [linksHistory]); - - return ( - - {listDisplay.length > 0 ? ( - listDisplay?.map((item, index) => ( - - - {listDisplay?.length - index} - - - - {decodeURIComponent(item?.params?.query)}{" "} - -
- - - {item?.params?.apiUrl} - - - - limit: {item?.params?.limit} - - step: {item?.params?.step} -
- {" "} - - - {" "} - - {item?.fromDate} - {" - "} - {item?.toDate} - -
-
- -
- - copyLink(item?.data)} - > - - - - - - handleDelete(item)} - > - - - - - - handleStarLinkItem(item)} - > - {item.starred ? ( - - ) : ( - - )} - - - - - handleSubmit(item?.data)} - > - {"Open In New Tab"} - - -
-
- )) - ) : ( - - )} -
- ); -} - -function StarredHistoryTab({ - starredQueries, - starredLinks, - handleDeleteQuery, - handleDeleteLink, - handleStarItem, - handleStarLinkItem, - handleSubmitQuery, - handleSubmitLink, - filteredLinks, - filteredQueries, - setFilteredStarLink, - setFilteredStarQuery, - filterItems, - emptyQueryMessage, - emptyLinkMessage, - copyQuery, -}) { - const [queryListDisplay, setQueryListDisplay] = useState([]); - const [linksListDisplay, setLinksListDisplay] = useState([]); - - useEffect(() => { - setQueryListDisplay(starredQueries); - setLinksListDisplay(starredLinks); - }, []); + const [listDisplay, setListDisplay] = useState([]); + useEffect(() => { + setListDisplay(queryHistory); + }, []); + + useEffect(() => { + if (filtered.length > 0) { + setListDisplay(filtered); + } + }, [filtered]); + + useEffect(() => { + setListDisplay(queryHistory); + }, [queryHistory]); + // const listDisplay = filtered.length > 0 ? filtered : queryHistory + return ( + + {listDisplay.length > 0 ? ( + listDisplay?.map((item, index) => ( + + + {listDisplay.length - index} + + + {item.data} + + {format(item.timestamp, "yyyy/MM/dd HH:mm:ss")} - useEffect(() => { - if (filteredLinks.length > 0) { - setLinksListDisplay(filteredLinks); - } - if (filteredQueries.length > 0) { - setQueryListDisplay(filteredQueries); - } - }, [filteredLinks, filteredQueries]); - - useEffect(() => { - setQueryListDisplay(starredQueries); - setLinksListDisplay(starredLinks); - }, [starredQueries, starredLinks]); - - return ( - - - Queries - Links - - - - - - - - - - - - ); +
+ + copyQuery(item.data)}> + + + + + + handleDelete(item)}> + + + + + + handleStarItem(item)}> + {item.starred ? ( + + ) : ( + + )} + + + + + handleSubmit(item)}> + {"Show Logs"} + + +
+
+ )) + ) : ( + + )} +
+ ); } - -function QueryHistoryTabHeader({ - queryHistory, - filterItems, - setFilteredItems, - searchQueriesText, +function LinksHistoryTab({ + linksHistory, + copyLink, + handleDelete, + handleStarLinkItem, + handleSubmit, + filtered, + emptyMessage, }) { - const [value, setValue] = useState(""); - - function handleValueChange(e) { - let edited = e.target.value; - setValue(edited); - const filtered = filterItems(queryHistory, edited); - if (filtered.length > 0) { - setFilteredItems(filtered); - } else { - setFilteredItems([]); - } + const [listDisplay, setListDisplay] = useState([]); + useEffect(() => { + setListDisplay(linksHistory); + }, []); + useEffect(() => { + if (filtered.length > 0) { + setListDisplay(filtered); } + }, [filtered]); + useEffect(() => { + setListDisplay(linksHistory); + }, [linksHistory]); + + return ( + + {listDisplay.length > 0 ? ( + listDisplay?.map((item, index) => ( + + + {listDisplay?.length - index} + + + {decodeURIComponent(item?.params?.query)} + - return ( -
+ + - - {" "} - - Total: {queryHistory.length} + }} + > + {" "} + {item?.params?.apiUrl} -
-
- ); -} + -function SettingHistoryTabHeader({ queryHistory, linksHistory }) { - return ( - -
limit: {item?.params?.limit} + + step: {item?.params?.step} +
- - Query History Rows: {queryHistory?.length} - - {" | "} - - Links History Rows: {linksHistory?.length} - + > + {" "} + + + {" "} + + {item?.fromDate} + {" - "} + {item?.toDate} + +
-
- ); -} -function SettingTab({ clearHistory, clearLinksHistory }) { - // const listDisplay = filtered.length > 0 ? filtered : queryHistory - return ( -
- -
Clear Query History
- - Delete all of your query history, permanently. - - -
- -
Clear Links History
- - Delete all of your links history, permanently. - - -
+ + copyLink(item?.data)}> + + + + + + handleDelete(item)}> + + + + + + handleStarLinkItem(item)}> + {item.starred ? ( + + ) : ( + + )} + + + + + handleSubmit(item?.data)}> + {"Open In New Tab"} + +
-
- ); +
+ )) + ) : ( + + )} +
+ ); } -const QueryHistoryDrawer = (props) => { - const dispatch = useDispatch(); - const historyService = localService().historyStore(); - const linkService = localUrl(); - const queryHistory = useSelector((store) => store.queryHistory); - const linksHistory = useSelector((store) => store.linksHistory); - const historyOpen = useSelector((store) => store.historyOpen); - - const [starredItems, setStarredItems] = useState([]); - const [filtered, setFiltered] = useState([]); - const [linksFiltered, setLinksFiltered] = useState([]); - const [linksStarredFiltered, setLinksStarredFiltered] = useState([]); - const [starredFiltered, setStarredFiltered] = useState([]); - const [linksStarredItems, setLinksStarredItems] = useState(false); - - function handleDelete(id) { - const removed = historyService.remove(id); - dispatch(setQueryHistory(removed)); - dispatch(createAlert({ - message: "Query deleted succesfully", - type: notificationTypes.info - })) - } +function StarredHistoryTab({ + starredQueries, + starredLinks, + handleDeleteQuery, + handleDeleteLink, + handleStarItem, + handleStarLinkItem, + handleSubmitQuery, + handleSubmitLink, + filteredLinks, + filteredQueries, + setFilteredStarLink, + setFilteredStarQuery, + filterItems, + emptyQueryMessage, + emptyLinkMessage, + copyQuery, +}) { + const [queryListDisplay, setQueryListDisplay] = useState([]); + const [linksListDisplay, setLinksListDisplay] = useState([]); - function handleLinkDelete(id) { - const removed = linkService.remove(id); - dispatch(setLinksHistory(removed)); - } + useEffect(() => { + setQueryListDisplay(starredQueries); + setLinksListDisplay(starredLinks); + }, []); - function handleSubmit(item) { - dispatch(setQuery(item.data)); - dispatch(loadLogs()); + useEffect(() => { + if (filteredLinks.length > 0) { + setLinksListDisplay(filteredLinks); } - - function handleLinkSubmit(link) { - window.open(link); + if (filteredQueries.length > 0) { + setQueryListDisplay(filteredQueries); } + }, [filteredLinks, filteredQueries]); + + useEffect(() => { + setQueryListDisplay(starredQueries); + setLinksListDisplay(starredLinks); + }, [starredQueries, starredLinks]); + + return ( + + + Queries + Links + + + + + + + + + + + + ); +} - useEffect(() => { - const starred = queryHistory?.filter((f) => f.starred) || []; - const linksStarred = linksHistory?.filter((f) => f.starred) || []; - setLinksStarredItems(linksStarred); - setStarredItems(starred); - }, [queryHistory, linksHistory]); - - function handleStarItem(item) { - const updatedItem = { ...item, starred: item.starred ? false : true }; - const updated = historyService.update(updatedItem); - dispatch(setQueryHistory(updated)); - if (updatedItem.starred) { - dispatch(createAlert({ - message: "Query starred succesfully", - type: notificationTypes.success - })) - } else { - dispatch(createAlert({ - message: "Query unstarred succesfully", - type: notificationTypes.success - })) - } - } - function handleStarLinkItem(item) { - const updatedItem = { ...item, starred: item.starred ? false : true }; - const updated = linkService.update(updatedItem); - dispatch(setLinksHistory(updated)); - if (updatedItem.starred) { - dispatch(createAlert({ - message: "Link starred succesfully", - type: notificationTypes.success - })) - } else { - dispatch(createAlert({ - message: "Link unstarred succesfully", - type: notificationTypes.success - })) - } - } - function copyQuery(item) { - navigator.clipboard.writeText(item).then( - function () { - if (item.length > 0) { - dispatch(createAlert({ - message: "Query copied succesfully", - type: notificationTypes.success - })) - } - }, - function (err) { - console.err("error on copy", err); - } - ); - } - function handleClose() { - dispatch(setHistoryOpen(false)); - } - function clearHistory() { - const historyClean = historyService.clean(); - dispatch(setQueryHistory(historyClean)); - if (historyClean?.length < 1) { - dispatch(createAlert({ - message: "Query History cleared succesfully", - type: notificationTypes.info - })) - } +function QueryHistoryTabHeader({ + queryHistory, + filterItems, + setFilteredItems, + searchQueriesText, +}) { + const [value, setValue] = useState(""); + + function handleValueChange(e) { + let edited = e.target.value; + setValue(edited); + const filtered = filterItems(queryHistory, edited); + if (filtered.length > 0) { + setFilteredItems(filtered); + } else { + setFilteredItems([]); } + } + + return ( + +
+ + {" "} + Total: {queryHistory.length} +
+
+ ); +} - function clearLinksHistory() { - const historyClean = linkService.clean(); - dispatch(setLinksHistory(historyClean)); - if (historyClean?.length < 1) { - dispatch(createAlert({ - message: "Links History cleared succesfully", - type: notificationTypes.info - })) - } - } +function SettingHistoryTabHeader({ queryHistory, linksHistory }) { + return ( + +
+ + Query History Rows: {queryHistory?.length} + + {" | "} + + Links History Rows: {linksHistory?.length} + +
+
+ ); +} - function filterItems(list, item) { - return list?.filter((f) => - f.data.toLowerCase().includes(item.toLowerCase()) - ); - } +function SettingTab({ clearHistory, clearLinksHistory }) { + // const listDisplay = filtered.length > 0 ? filtered : queryHistory + return ( + +
+ +
Clear Query History
+ Delete all of your query history, permanently. + +
+ +
Clear Links History
+ Delete all of your links history, permanently. + +
+
+
+ ); +} - function setFilteredItems(list) { - setFiltered(list); +const QueryHistoryDrawer = (props) => { + const dispatch = useDispatch(); + const historyService = localService().historyStore(); + const linkService = localUrl(); + const queryHistory = useSelector((store) => store.queryHistory); + const linksHistory = useSelector((store) => store.linksHistory); + const historyOpen = useSelector((store) => store.historyOpen); + + const [starredItems, setStarredItems] = useState([]); + const [filtered, setFiltered] = useState([]); + const [linksFiltered, setLinksFiltered] = useState([]); + const [linksStarredFiltered, setLinksStarredFiltered] = useState([]); + const [starredFiltered, setStarredFiltered] = useState([]); + const [linksStarredItems, setLinksStarredItems] = useState(false); + + function handleDelete(id) { + const removed = historyService.remove(id); + dispatch(setQueryHistory(removed)); + dispatch( + createAlert({ + message: "Query deleted succesfully", + type: notificationTypes.info, + }) + ); + } + + function handleLinkDelete(id) { + const removed = linkService.remove(id); + dispatch(setLinksHistory(removed)); + } + + function handleSubmit(item) { + dispatch(setQuery(item.data)); + dispatch(loadLogs()); + } + + function handleLinkSubmit(link) { + window.open(link); + } + function filterItems(list, item) { + return list?.filter((f) => + f.data.toLowerCase().includes(item.toLowerCase()) + ); + } + function setFilteredItems(list) { + setFiltered(list); + } + + function setFilterLinkItems(list) { + setLinksFiltered(list); + } + + function filterStarred(starred) { + setStarredFiltered(starred); + } + + function filterLinkStarred(starred) { + setLinksStarredFiltered(starred); + } + useEffect(() => { + const starred = queryHistory?.filter((f) => f.starred) || []; + const linksStarred = linksHistory?.filter((f) => f.starred) || []; + setLinksStarredItems(linksStarred); + setStarredItems(starred); + }, [queryHistory, linksHistory]); + + function handleStarItem(item) { + const updatedItem = { ...item, starred: item.starred ? false : true }; + const updated = historyService.update(updatedItem); + dispatch(setQueryHistory(updated)); + if (updatedItem.starred) { + dispatch( + createAlert({ + message: "Query starred succesfully", + type: notificationTypes.success, + }) + ); + } else { + dispatch( + createAlert({ + message: "Query unstarred succesfully", + type: notificationTypes.success, + }) + ); } - - function setFilterLinkItems(list) { - setLinksFiltered(list); + } + function handleStarLinkItem(item) { + const updatedItem = { ...item, starred: item.starred ? false : true }; + const updated = linkService.update(updatedItem); + dispatch(setLinksHistory(updated)); + if (updatedItem.starred) { + dispatch( + createAlert({ + message: "Link starred succesfully", + type: notificationTypes.success, + }) + ); + } else { + dispatch( + createAlert({ + message: "Link unstarred succesfully", + type: notificationTypes.success, + }) + ); } - - function filterStarred(starred) { - setStarredFiltered(starred); + } + function copyQuery(item) { + navigator.clipboard.writeText(item).then( + function () { + if (item.length > 0) { + dispatch( + createAlert({ + message: "Query copied succesfully", + type: notificationTypes.success, + }) + ); + } + }, + function (err) { + console.err("error on copy", err); + } + ); + } + function handleClose() { + dispatch(setHistoryOpen(false)); + } + function clearHistory() { + const historyClean = historyService.clean(); + dispatch(setQueryHistory(historyClean)); + if (historyClean?.length < 1) { + dispatch( + createAlert({ + message: "Query History cleared succesfully", + type: notificationTypes.info, + }) + ); } - - function filterLinkStarred(starred) { - setLinksStarredFiltered(starred); + } + + function clearLinksHistory() { + const historyClean = linkService.clean(); + dispatch(setLinksHistory(historyClean)); + if (historyClean?.length < 1) { + dispatch( + createAlert({ + message: "Links History cleared succesfully", + type: notificationTypes.info, + }) + ); } - - return ( - - - - } - historyTab={ - - } - linksTabHeader={ - - } - linksTab={ - - } - starredTabHeader={ - - } - starredTab={ - - } - starredHistoryTab={ - - } - settingTabHeader={ - - } - settingTab={ - - } - closeButton={} - /> - - - ); + } + return ( + + + + } + historyTab={ + + } + linksTabHeader={ + + } + linksTab={ + + } + starredTabHeader={ + + } + starredTab={ + + } + starredHistoryTab={ + + } + settingTabHeader={ + + } + settingTab={ + + } + closeButton={} + /> + + + ); }; const QueryHistory = () => { - return ; + return ; }; export default QueryHistory;