From 8131e1186f920b99dc72c1f5c4f9b4dc08a2fe6e Mon Sep 17 00:00:00 2001 From: Kartik Gupta Date: Wed, 19 Jul 2023 12:53:27 +0530 Subject: [PATCH 1/4] query schema --- src/pages/Query/Context.tsx | 3 + src/pages/Query/QueryCodeEditor.tsx | 90 ++++++----- src/pages/Query/QuerySchemaList.tsx | 19 ++- src/pages/Query/SecondaryHeader.tsx | 236 ---------------------------- src/pages/Query/index.tsx | 24 ++- src/pages/Query/styles.tsx | 52 ++++-- 6 files changed, 128 insertions(+), 296 deletions(-) delete mode 100644 src/pages/Query/SecondaryHeader.tsx diff --git a/src/pages/Query/Context.tsx b/src/pages/Query/Context.tsx index 58370b5e..19a5e448 100644 --- a/src/pages/Query/Context.tsx +++ b/src/pages/Query/Context.tsx @@ -12,6 +12,7 @@ export const defaultQueryResult = "" interface QueryPageContextState { result: SubData; + subSchemaToggle: SubData; } // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -28,9 +29,11 @@ interface QueryPageProviderProps { const QueryPageProvider: FC = ({ children }) => { const result = useSubscribeState(defaultQueryResult); + const subSchemaToggle = useSubscribeState(false); const state: QueryPageContextState = { result, + subSchemaToggle }; const methods: QueryPageContextMethods = {}; diff --git a/src/pages/Query/QueryCodeEditor.tsx b/src/pages/Query/QueryCodeEditor.tsx index 4cf620c9..80613348 100644 --- a/src/pages/Query/QueryCodeEditor.tsx +++ b/src/pages/Query/QueryCodeEditor.tsx @@ -1,28 +1,28 @@ -import React ,{ FC, useEffect } from 'react'; +import React, { FC, useEffect } from 'react'; import Editor from '@monaco-editor/react'; import { useQueryPageContext } from './Context'; import { useHeaderContext } from '@/layouts/MainLayout/Context'; -import { Box, Button ,Text } from '@mantine/core'; +import { Box, Button, Text } from '@mantine/core'; import { useQueryResult } from '@/hooks/useQueryResult'; import { ErrorMarker, errChecker } from "./ErrorMarker"; import { notifications } from '@mantine/notifications'; -import { IconPlayerPlayFilled, IconCheck, IconFileAlert } from '@tabler/icons-react'; +import { IconPlayerPlayFilled, IconCheck, IconFileAlert, IconEyeClosed, IconEye } from '@tabler/icons-react'; +import useMountedState from '@/hooks/useMountedState'; import { useQueryCodeEditorStyles } from './styles'; - const QueryCodeEditor: FC = () => { - const { state: {subLogQuery } } = useHeaderContext(); - const { state: {result } } = useQueryPageContext(); + const { state: { subLogQuery } } = useHeaderContext(); + const { state: { result, subSchemaToggle } } = useQueryPageContext(); - const { data: queryResult, getQueryData , error,resetData } = useQueryResult(); + const { data: queryResult, getQueryData, error, resetData } = useQueryResult(); const editorRef = React.useRef(); const monacoRef = React.useRef(); - + const [isSchemaOpen, setIsSchemaOpen] = useMountedState(false); const [query, setQuery] = React.useState(`SELECT * FROM ${subLogQuery.get().streamName} LIMIT 100`); const handleEditorChange = (code: any) => { setQuery(code); - errChecker(code,subLogQuery.get().streamName); + errChecker(code, subLogQuery.get().streamName); monacoRef.current?.editor.setModelMarkers( editorRef.current?.getModel(), "owner", @@ -30,14 +30,21 @@ const QueryCodeEditor: FC = () => { ); }; - useEffect(() => { + useEffect(() => { + const listener = subSchemaToggle.subscribe(setIsSchemaOpen); + return () => { + listener(); + }; + }, [subSchemaToggle.get()]); + + useEffect(() => { if (subLogQuery.get().streamName) { setQuery(`SELECT * FROM ${subLogQuery.get().streamName} LIMIT 100;`); result.set(""); } - } , [subLogQuery.get().streamName]); + }, [subLogQuery.get().streamName]); - function handleEditorDidMount(editor:any, monaco:any) { + function handleEditorDidMount(editor: any, monaco: any) { editorRef.current = editor; monacoRef.current = monaco; } @@ -52,24 +59,24 @@ const QueryCodeEditor: FC = () => { autoClose: false, withCloseButton: false, }); - const parsedQuery=query.replace(/(\r\n|\n|\r)/gm, ""); + const parsedQuery = query.replace(/(\r\n|\n|\r)/gm, ""); getQueryData(subLogQuery.get(), parsedQuery); } useEffect(() => { - if(error){ + if (error) { notifications.update({ id: 'load-data', color: 'red', title: 'Error Occured', message: 'Error Occured, please check your query and try again', - icon: , + icon: , autoClose: 2000, }); result.set(error); return; } - if(queryResult){ + if (queryResult) { result.set(JSON.stringify(queryResult?.data, null, 2)); notifications.update({ id: 'load-data', @@ -82,39 +89,42 @@ const QueryCodeEditor: FC = () => { return; } - }, [queryResult , error]); + }, [queryResult, error]); const { classes } = useQueryCodeEditorStyles(); - const { container,runQueryBtn,textContext } = classes; + const { container, runQueryBtn, textContext } = classes; return ( Query - - - - - - + + + + + + + + + ); }; diff --git a/src/pages/Query/QuerySchemaList.tsx b/src/pages/Query/QuerySchemaList.tsx index 058df05c..138cd202 100644 --- a/src/pages/Query/QuerySchemaList.tsx +++ b/src/pages/Query/QuerySchemaList.tsx @@ -1,13 +1,15 @@ import { FC, useEffect } from 'react'; import { useGetLogStreamSchema } from '@/hooks/useGetLogStreamSchema'; import { useHeaderContext } from '@/layouts/MainLayout/Context'; -import { Table, Box, Title } from '@mantine/core'; - - +import { Table, Box, Title, Button } from '@mantine/core'; +import { IconSquareRoundedXFilled } from '@tabler/icons-react'; +import { useQuerySchemaListStyles } from './styles'; +import { useQueryPageContext } from './Context'; const QuerySchemaList: FC = () => { const { data: querySchema, getDataSchema, resetData, loading, error: logStreamSchemaError } = useGetLogStreamSchema(); const { state: { subLogQuery } } = useHeaderContext(); + const { state: { subSchemaToggle } } = useQueryPageContext(); useEffect(() => { if (subLogQuery.get().streamName) { @@ -36,11 +38,16 @@ const QuerySchemaList: FC = () => { } }); - return ( +const {classes} = useQuerySchemaListStyles(); + const {actionBtn ,container}=classes; - + return ( + + Schema for {subLogQuery.get().streamName} - + + + {!(logStreamSchemaError) ? ( !loading && Boolean(querySchema) ? ( (querySchema?.fields.length) ? ( diff --git a/src/pages/Query/SecondaryHeader.tsx b/src/pages/Query/SecondaryHeader.tsx deleted file mode 100644 index 00b15e19..00000000 --- a/src/pages/Query/SecondaryHeader.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import useMountedState from '@/hooks/useMountedState'; -import { Box, Button, Menu, Text, UnstyledButton, px } from '@mantine/core'; -import { DateTimePicker } from '@mantine/dates'; -import { IconClock, IconRefresh, IconRefreshOff, } from '@tabler/icons-react'; -import dayjs from 'dayjs'; -import ms from 'ms'; -import type { FC } from 'react'; -import { Fragment, useEffect, useMemo } from 'react'; -import { FIXED_DURATIONS, REFRESH_INTERVALS, useQueryPageContext } from './Context'; -import { useQueryStyles } from './styles'; - -const SecondaryHeader: FC = () => { - const { classes } = useQueryStyles(); - const { container, innerContainer, labelStyle } = classes; - - return ( - - - Time Range - - - - - - - - ); -}; - - -const RefreshInterval: FC = () => { - const { - state: { subRefreshInterval }, - } = useQueryPageContext(); - - const [selectedInterval, setSelectedInterval] = useMountedState(subRefreshInterval.get()); - - useEffect(() => { - const listener = subRefreshInterval.subscribe((interval) => { - setSelectedInterval(interval); - }); - - return () => listener(); - }, []); - - const Icon = useMemo(() => (selectedInterval ? IconRefresh : IconRefreshOff), [selectedInterval]); - - const onSelectedInterval = (interval: number | null) => { - subRefreshInterval.set(interval); - }; - - const { classes } = useQueryStyles(); - const { intervalBtn } = classes; - - return ( - - - - - - {REFRESH_INTERVALS.map((interval) => { - if (interval === selectedInterval) return null; - - return ( - onSelectedInterval(interval)}> - {ms(interval)} - - ); - })} - - {selectedInterval !== null && ( - onSelectedInterval(null)}> - Off - - )} - - - ); -}; - -type FixedDurations = (typeof FIXED_DURATIONS)[number]; - -const TimeRange: FC = () => { - const { - state: { subLogQuery, subLogSelectedTimeRange }, - } = useQueryPageContext(); - - const [selectedRange, setSelectedRange] = useMountedState(subLogSelectedTimeRange.get()); - - useEffect(() => { - const listener = subLogSelectedTimeRange.subscribe((state) => { - setSelectedRange(state); - }); - - return () => listener(); - }, []); - - const onDurationSelect = (duration: FixedDurations) => { - subLogSelectedTimeRange.set(duration.name); - const now = dayjs(); - - subLogQuery.set((query) => { - query.startTime = now.subtract(duration.milliseconds, 'milliseconds').toDate(); - query.endTime = now.toDate(); - }); - return; - }; - - const { classes, cx } = useQueryStyles(); - const { - timeRangeBTn, - timeRangeContainer, - fixedRangeContainer, - fixedRangeBtn, - fixedRangeBtnSelected, - customRangeContainer, - } = classes; - - return ( - - - - - - - - {FIXED_DURATIONS.map((duration) => { - return ( - onDurationSelect(duration)}> - {duration.name} - - ); - })} - - - - - - - - ); -}; - -const CustomTimeRange: FC = () => { - const { - state: { subLogQuery, subLogSelectedTimeRange }, - } = useQueryPageContext(); - - const [selectedRange, setSelectedRange] = useMountedState({ - startTime: subLogQuery.get().startTime, - endTime: subLogQuery.get().endTime, - }); - - const onRangeSelect = (key: keyof typeof selectedRange, date: Date) => { - setSelectedRange((state) => { - state[key] = date; - return { ...state }; - }); - }; - - const onApply = () => { - subLogQuery.set((query) => { - query.startTime = selectedRange.startTime; - query.endTime = selectedRange.endTime; - }); - const startTime = dayjs(selectedRange.startTime).format('DD-MM-YY HH:mm'); - const endTime = dayjs(selectedRange.endTime).format('DD-MM-YY HH:mm'); - subLogSelectedTimeRange.set(`${startTime} - ${endTime}`); - }; - - const { classes } = useQueryStyles(); - const { customTimeRangeFooter, customTimeRangeApplyBtn } = classes; - - const isApplicable = useMemo(() => { - return ( - dayjs(selectedRange.startTime).isSame(subLogQuery.get().startTime, 'seconds') && - dayjs(selectedRange.endTime).isSame(subLogQuery.get().endTime, 'seconds') - ); - }, [selectedRange]); - - const isStartTimeMoreThenEndTime = useMemo(() => { - return dayjs(selectedRange.startTime).isAfter(selectedRange.endTime, 'seconds'); - }, [selectedRange]); - - return ( - - { - if (date) { - onRangeSelect('startTime', date); - } - }} - valueFormat="DD-MM-YY HH:mm" - label="From" - placeholder="Pick date and time" - /> - { - if (date) { - onRangeSelect('endTime', date); - } - }} - valueFormat="DD-MM-YY HH:mm" - label="To" - placeholder="Pick date and time" - mt="md" - /> - - - - - ); -}; - -export default SecondaryHeader; diff --git a/src/pages/Query/index.tsx b/src/pages/Query/index.tsx index a92436d6..60367733 100644 --- a/src/pages/Query/index.tsx +++ b/src/pages/Query/index.tsx @@ -1,22 +1,34 @@ import { Box } from '@mantine/core'; import { useDocumentTitle } from '@mantine/hooks'; -import { FC } from 'react'; +import { FC, useEffect } from 'react'; import { useQueryStyles } from './styles'; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; import QueryCodeEditor from './QueryCodeEditor'; import QueryResultEditor from './QueryResultEditor'; -// import QuerySchemaList from './QuerySchemaList'; +import QuerySchemaList from './QuerySchemaList'; +import { useQueryPageContext } from './Context'; +import useMountedState from '@/hooks/useMountedState'; const Logs: FC = () => { useDocumentTitle('Parseable | Query'); const { classes } = useQueryStyles(); - const { container,innerContainer1 } = classes; + const { container,innerContainer,schemaContainer } = classes; + const { state: { subSchemaToggle } } = useQueryPageContext(); + const [isSchemaOpen, setIsSchemaOpen] = useMountedState(false); + + useEffect(() => { + const listener = subSchemaToggle.subscribe(setIsSchemaOpen); + return () => { + console.log(isSchemaOpen) + listener(); + }; + }, [subSchemaToggle.get()]); return ( - + @@ -39,7 +51,9 @@ const Logs: FC = () => { - + + + diff --git a/src/pages/Query/styles.tsx b/src/pages/Query/styles.tsx index 90dc5202..ddeb70ed 100644 --- a/src/pages/Query/styles.tsx +++ b/src/pages/Query/styles.tsx @@ -3,7 +3,7 @@ import { HEADER_HEIGHT, NAVBAR_WIDTH } from '@/constants/theme'; import { createStyles } from '@mantine/core'; export const useQueryStyles = createStyles((theme) => { - const { colors, spacing } = theme; + const { colors ,shadows } = theme; const { heights, widths, } = theme.other; const sColor = colors.brandSecondary[0]; const pColor = colors.brandPrimary[0]; @@ -15,7 +15,7 @@ export const useQueryStyles = createStyles((theme) => { display: 'flex', position: 'relative', }, - innerContainer1: { + innerContainer: { position: 'relative', flex: 1, maxHeight: `calc(${heights.screen} - ${HEADER_HEIGHT}px)`, @@ -39,11 +39,11 @@ export const useQueryStyles = createStyles((theme) => { }, height: "25px", marginRight: "5px" }, - innerContainer: { - display: 'flex', - paddingTop: spacing.xxs, - marginRight: spacing.md, - }, + schemaContainer:{ + border: `${widths.px} ${colors.gray[1]} solid`, + boxShadow: shadows.sm, + maxWidth: "500px" + } }; }); @@ -60,12 +60,12 @@ export const useQueryCodeEditorStyles = createStyles((theme) => { alignItems: "center", height: "55px", padding: `${spacing.xs} ${spacing.md}` , + width:"100%" }, runQueryBtn: { color: pColor, border: "none", height: "40px", - marginLeft: "auto", '&:hover': { color: sColor, }, @@ -112,4 +112,38 @@ export const useQueryResultEditorStyles = createStyles((theme) => { fontWeight: fontWeights.bold, } }; -}); \ No newline at end of file +}); + + +export const useQuerySchemaListStyles = createStyles((theme) => { + const { colors ,spacing ,fontFamily,fontSizes} = theme; + const {fontWeights } = theme.other; + const sColor = colors.brandSecondary[0]; + + return { + container: { + display: "flex", + alignItems: "center", + borderBottom: `solid 1px ${colors.gray[2]}`, + height: "55px", + padding: `${spacing.xs} ${spacing.md}` , + justifyContent:"space-between" + ,paddingRight:0, + }, + + actionBtn: { + color: colors.gray[3], + border: "none ", + height: "40px", + '&:hover': { + color: sColor, + }, + }, + textContext: { + marginRight: spacing.md, + fontSize: fontSizes.md, + fontFamily: fontFamily, + fontWeight: fontWeights.bold, + } + }; +}); From aedd48b3a32c3c7ea7a999ad495190e855db6b3a Mon Sep 17 00:00:00 2001 From: Kartik Gupta Date: Wed, 19 Jul 2023 20:00:48 +0530 Subject: [PATCH 2/4] Query UI --- src/components/Header/styles.tsx | 7 +++-- src/components/Navbar/index.tsx | 6 ++--- src/components/Navbar/styles.tsx | 4 +-- src/layouts/MainLayout/Context.tsx | 2 +- src/pages/Logs/LogTable.tsx | 24 +++++++++++++++-- src/pages/Logs/styles.tsx | 4 +-- src/pages/Query/ErrorMarker.tsx | 2 +- src/pages/Query/QueryCodeEditor.tsx | 21 ++++++++++++--- src/pages/Query/QueryResultEditor.tsx | 4 +-- src/pages/Query/QuerySchemaList.tsx | 12 ++++----- src/pages/Query/styles.tsx | 38 ++++++++++++++++++++++----- 11 files changed, 91 insertions(+), 33 deletions(-) diff --git a/src/components/Header/styles.tsx b/src/components/Header/styles.tsx index 04783c91..188aa957 100644 --- a/src/components/Header/styles.tsx +++ b/src/components/Header/styles.tsx @@ -71,15 +71,14 @@ export const useLogQueryStyles = createStyles((theme) => { display: 'flex', justifyContent: 'center', alignItems: 'center', - - background: pColor, - color: colors.white[0], + background: colors.white[0], + color: colors.black[0], minWidth: widths[20], border: `${sizing.px} ${colors.gray[2]} solid`, padding: `${spacing.xs} ${spacing.sm}`, marginRight: spacing.xs, '&:hover': { - background: sColor, + background: colors.gray[1], }, }, diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index fcfe2124..7a0bbf93 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -171,9 +171,9 @@ const Navbar: FC = (props) => { {error && } component="button" onClick={getData} sx={{ paddingLeft: 0 }} />} - } className={userBtn} component="a" /> - } className={actionBtn} component="a" onClick={open} /> - } className={actionBtn} component="a" onClick={onSignOut} /> + } className={userBtn} component="a" /> + } className={actionBtn} component="a" onClick={open} /> + } className={actionBtn} component="a" onClick={onSignOut} /> Need any help? diff --git a/src/components/Navbar/styles.tsx b/src/components/Navbar/styles.tsx index 84fbcab1..6b0ea831 100644 --- a/src/components/Navbar/styles.tsx +++ b/src/components/Navbar/styles.tsx @@ -64,7 +64,7 @@ export const useNavbarStyles = createStyles((theme) => { }, actionBtn: { paddingLeft:"24px", - height:"56px", + height:"40px", color: theme.colors.gray[6], '&:hover *': { color: sColor, @@ -73,7 +73,7 @@ export const useNavbarStyles = createStyles((theme) => { userBtn: { paddingLeft:"24px", - height:"56px", + height:"40px", color: theme.colors.gray[6], }, diff --git a/src/layouts/MainLayout/Context.tsx b/src/layouts/MainLayout/Context.tsx index d2732e11..d1e33507 100644 --- a/src/layouts/MainLayout/Context.tsx +++ b/src/layouts/MainLayout/Context.tsx @@ -9,7 +9,7 @@ const Context = createContext({}); const { Provider } = Context; const now = dayjs(); -export const REFRESH_INTERVALS = [1000, 2000, 5000, 10000, 20000, 60000]; +export const REFRESH_INTERVALS = [10000, 30000, 60000, 300000, 600000, 1200000]; export const FIXED_DURATIONS = [ { name: 'Past 10 Minutes', diff --git a/src/pages/Logs/LogTable.tsx b/src/pages/Logs/LogTable.tsx index 84581973..167d7eab 100644 --- a/src/pages/Logs/LogTable.tsx +++ b/src/pages/Logs/LogTable.tsx @@ -25,10 +25,10 @@ const LogTable: FC = () => { state: { subLogStreamError }, } = useLogsPageContext(); const { - state: { subLogSearch ,subLogQuery }, + state: { subLogSearch ,subLogQuery , subRefreshInterval}, }= useHeaderContext(); - + const [refreshInterval, setRefreshInterval] = useMountedState(null); const [logStreamError, setLogStreamError] = useMountedState(null); const [columnToggles, setColumnToggles] = useMountedState>(new Map()); const { @@ -94,6 +94,7 @@ const LogTable: FC = () => { useEffect(() => { const streamErrorListener = subLogStreamError.subscribe(setLogStreamError); const logSearchListener = subLogSearch.subscribe(setQuerySearch); + const refreshIntervalListener = subRefreshInterval.subscribe(setRefreshInterval); const logQueryListener = subLogQuery.subscribe((query) => { if (query.streamName) { if (logsSchema) { @@ -109,11 +110,30 @@ const LogTable: FC = () => { return () => { streamErrorListener(); + refreshIntervalListener(); logQueryListener(); logSearchListener(); }; }, [logsSchema]); + useEffect(() => { + if (subRefreshInterval.get()) { + const interval = setInterval(() => { + const query = subLogQuery.get(); + if (query.streamName) { + if (logsSchema) { + resetStreamData(); + resetLogsData + } + getDataSchema(query.streamName); + getQueryData(query); + setColumnToggles(new Map()); + } + }, subRefreshInterval.get() as number); + return () => clearInterval(interval); + } + }, [refreshInterval]); + useEffect(() => { const query = subLogQuery.get(); diff --git a/src/pages/Logs/styles.tsx b/src/pages/Logs/styles.tsx index 93852be6..d9fded34 100644 --- a/src/pages/Logs/styles.tsx +++ b/src/pages/Logs/styles.tsx @@ -90,7 +90,7 @@ export const useLogTableStyles = createStyles((theme) => { }, '& td': { - height: heights[14], + height: heights[10], textAlign: 'left', verticalAlign: 'middle', border:"none !important", @@ -106,7 +106,7 @@ export const useLogTableStyles = createStyles((theme) => { }, '& td': { - height: heights[14], + height: heights[10], textAlign: 'left', verticalAlign: 'middle', border:"none !important", diff --git a/src/pages/Query/ErrorMarker.tsx b/src/pages/Query/ErrorMarker.tsx index 95286465..ea7283f1 100644 --- a/src/pages/Query/ErrorMarker.tsx +++ b/src/pages/Query/ErrorMarker.tsx @@ -27,7 +27,7 @@ export function errChecker(code: string, streamName: string) { let wordsArray=wordsString.split(' '); wordsArray.map((word:string, i:any) => { if (word.toLowerCase() === 'from' && wordsArray[i + 1]) { - if(wordsArray[i+1]!==streamName){ + if(wordsArray[i+1]!==streamName && wordsArray[i+1]!==`${streamName};`){ ErrorMarker.push({ startLineNumber: j+1, endLineNumber: j+1, diff --git a/src/pages/Query/QueryCodeEditor.tsx b/src/pages/Query/QueryCodeEditor.tsx index 80613348..f845d945 100644 --- a/src/pages/Query/QueryCodeEditor.tsx +++ b/src/pages/Query/QueryCodeEditor.tsx @@ -2,7 +2,7 @@ import React, { FC, useEffect } from 'react'; import Editor from '@monaco-editor/react'; import { useQueryPageContext } from './Context'; import { useHeaderContext } from '@/layouts/MainLayout/Context'; -import { Box, Button, Text } from '@mantine/core'; +import { Box, Button, Text ,px} from '@mantine/core'; import { useQueryResult } from '@/hooks/useQueryResult'; import { ErrorMarker, errChecker } from "./ErrorMarker"; import { notifications } from '@mantine/notifications'; @@ -11,7 +11,7 @@ import useMountedState from '@/hooks/useMountedState'; import { useQueryCodeEditorStyles } from './styles'; const QueryCodeEditor: FC = () => { - const { state: { subLogQuery } } = useHeaderContext(); + const { state: { subLogQuery,subRefreshInterval } } = useHeaderContext(); const { state: { result, subSchemaToggle } } = useQueryPageContext(); const { data: queryResult, getQueryData, error, resetData } = useQueryResult(); @@ -19,6 +19,7 @@ const QueryCodeEditor: FC = () => { const monacoRef = React.useRef(); const [isSchemaOpen, setIsSchemaOpen] = useMountedState(false); const [query, setQuery] = React.useState(`SELECT * FROM ${subLogQuery.get().streamName} LIMIT 100`); + const [refreshInterval, setRefreshInterval] = useMountedState(null); const handleEditorChange = (code: any) => { setQuery(code); @@ -30,10 +31,22 @@ const QueryCodeEditor: FC = () => { ); }; + useEffect(() => { + console.log(subRefreshInterval.get()); + if (subRefreshInterval.get()) { + const interval = setInterval(() => { + runQuery(); + }, subRefreshInterval.get() as number); + return () => clearInterval(interval); + } + }, [refreshInterval,query]); + useEffect(() => { const listener = subSchemaToggle.subscribe(setIsSchemaOpen); + const refreshIntervalListener = subRefreshInterval.subscribe(setRefreshInterval); return () => { listener(); + refreshIntervalListener(); }; }, [subSchemaToggle.get()]); @@ -99,8 +112,8 @@ const QueryCodeEditor: FC = () => { Query - - + + diff --git a/src/pages/Query/QueryResultEditor.tsx b/src/pages/Query/QueryResultEditor.tsx index 5bed4bc7..397c391a 100644 --- a/src/pages/Query/QueryResultEditor.tsx +++ b/src/pages/Query/QueryResultEditor.tsx @@ -63,8 +63,8 @@ const QueryResultEditor: FC = () => { Result - - + + diff --git a/src/pages/Query/QuerySchemaList.tsx b/src/pages/Query/QuerySchemaList.tsx index 138cd202..196c0d3d 100644 --- a/src/pages/Query/QuerySchemaList.tsx +++ b/src/pages/Query/QuerySchemaList.tsx @@ -39,12 +39,12 @@ const QuerySchemaList: FC = () => { }); const {classes} = useQuerySchemaListStyles(); - const {actionBtn ,container}=classes; + const {actionBtn ,container ,textContext ,theadSt ,tbodySt ,innercontainer}=classes; return ( - - - Schema for {subLogQuery.get().streamName} + + + Schema for {subLogQuery.get().streamName} @@ -52,13 +52,13 @@ const {classes} = useQuerySchemaListStyles(); !loading && Boolean(querySchema) ? ( (querySchema?.fields.length) ? ( - + - {renderList} + {renderList}
Feild Type
) : (

No Data

diff --git a/src/pages/Query/styles.tsx b/src/pages/Query/styles.tsx index ddeb70ed..e0ad5485 100644 --- a/src/pages/Query/styles.tsx +++ b/src/pages/Query/styles.tsx @@ -64,17 +64,19 @@ export const useQueryCodeEditorStyles = createStyles((theme) => { }, runQueryBtn: { color: pColor, - border: "none", - height: "40px", + borderColor: colors.gray[2], + height: "34px", '&:hover': { color: sColor, }, + marginInlineEnd: spacing.xs, + }, textContext: { marginRight: spacing.md, fontSize: fontSizes.md, fontFamily: fontFamily, - fontWeight: fontWeights.bold, + fontWeight: fontWeights.semibold, } }; @@ -103,13 +105,13 @@ export const useQueryResultEditorStyles = createStyles((theme) => { height: "34px", marginInlineEnd: spacing.xs, color: colors.gray[5], - borderColor:colors.gray[5] + borderColor:colors.gray[2] }, textContext: { marginRight: spacing.md, fontSize: fontSizes.md, fontFamily: fontFamily, - fontWeight: fontWeights.bold, + fontWeight: fontWeights.semibold, } }; }); @@ -122,6 +124,11 @@ export const useQuerySchemaListStyles = createStyles((theme) => { return { container: { + maxWidth: "500px", + height: "100%", + overflow: "auto", + }, + innercontainer: { display: "flex", alignItems: "center", borderBottom: `solid 1px ${colors.gray[2]}`, @@ -143,7 +150,26 @@ export const useQuerySchemaListStyles = createStyles((theme) => { marginRight: spacing.md, fontSize: fontSizes.md, fontFamily: fontFamily, - fontWeight: fontWeights.bold, + fontWeight: fontWeights.semibold, + }, + theadSt:{ + "& tr>th":{ + backgroundColor:colors.gray[0], + fontSize: fontSizes.md, + fontFamily: fontFamily, + fontWeight: fontWeights.semibold, + color:colors.gray[3], + height: "34px" + } + }, + tbodySt:{ + "& tr>td":{ + fontSize: fontSizes.md, + fontFamily: fontFamily, + borderTop:`solid 1px ${colors.gray[2]} !important`, + color:colors.gray[6], + height: "34px" + } } }; }); From 877656c9b0aed1d47bb46a20d77c333131c67554 Mon Sep 17 00:00:00 2001 From: Kartik Gupta Date: Thu, 20 Jul 2023 13:38:29 +0530 Subject: [PATCH 3/4] UI Rquested Changes --- src/components/Header/SubHeader.tsx | 42 +++++++++++++++++++++------ src/components/Header/index.tsx | 4 +-- src/components/Header/styles.tsx | 16 +++++++++- src/components/Navbar/index.tsx | 9 +++--- src/components/Navbar/styles.tsx | 7 ++++- src/pages/Logs/LogTable.tsx | 21 +++++++------- src/pages/Query/QueryCodeEditor.tsx | 24 ++++++++++----- src/pages/Query/QueryResultEditor.tsx | 4 +-- src/pages/Query/styles.tsx | 8 ++++- 9 files changed, 96 insertions(+), 39 deletions(-) diff --git a/src/components/Header/SubHeader.tsx b/src/components/Header/SubHeader.tsx index 4c9b34d9..d065210a 100644 --- a/src/components/Header/SubHeader.tsx +++ b/src/components/Header/SubHeader.tsx @@ -1,7 +1,7 @@ import useMountedState from '@/hooks/useMountedState'; import { Box, Breadcrumbs, Button, Menu, Text, TextInput, UnstyledButton, px } from '@mantine/core'; import { DateTimePicker } from '@mantine/dates'; -import { IconClock, IconRefresh, IconRefreshOff, IconSearch } from '@tabler/icons-react'; +import { IconClock, IconReload , IconRefreshOff, IconSearch } from '@tabler/icons-react'; import dayjs from 'dayjs'; import ms from 'ms'; import type { ChangeEvent, FC, KeyboardEvent } from 'react'; @@ -35,20 +35,17 @@ const SubHeader: FC = () => { Streams {streamName} - {useMatch("/:streamName/logs")? "Logs": "Query" } + {useMatch("/:streamName/logs") ? "Logs" : "Query"}
- - {useMatch("/:streamName/logs") - && - - } - + + {useMatch("/:streamName/logs") && } + {useMatch("/:streamName/logs") && }
@@ -105,6 +102,33 @@ const Search: FC = () => { ); }; +const RefreshNow: FC = () => { + const { + state: { subLogQuery, subLogSelectedTimeRange }, + } = useHeaderContext(); + + + const onRefresh = () => { + if (subLogSelectedTimeRange.get().includes('Past')) { + const now = dayjs(); + const timeDiff = subLogQuery.get().endTime.getTime() - subLogQuery.get().startTime.getTime(); + subLogQuery.set((state) => { + state.startTime = now.subtract(timeDiff).toDate(); + state.endTime = now.toDate(); + }); + } + }; + const { classes } = useLogQueryStyles(); + const { refreshNowBtn } = classes; + + return ( + + + ); +}; + const RefreshInterval: FC = () => { const { state: { subRefreshInterval }, @@ -195,7 +219,7 @@ const TimeRange: FC = () => { } = classes; return ( - + - + + diff --git a/src/pages/Query/QueryResultEditor.tsx b/src/pages/Query/QueryResultEditor.tsx index 397c391a..b07f4a87 100644 --- a/src/pages/Query/QueryResultEditor.tsx +++ b/src/pages/Query/QueryResultEditor.tsx @@ -3,7 +3,7 @@ import Editor from '@monaco-editor/react'; import { useQueryPageContext } from './Context'; import useMountedState from '@/hooks/useMountedState'; import { Box, Button, Text, px } from '@mantine/core'; -import { IconCopy, IconSearch, IconCheck } from '@tabler/icons-react'; +import { IconClipboard , IconSearch, IconCheck } from '@tabler/icons-react'; import { notifications } from '@mantine/notifications'; import { useQueryResultEditorStyles } from './styles'; @@ -63,7 +63,7 @@ const QueryResultEditor: FC = () => { Result - + diff --git a/src/pages/Query/styles.tsx b/src/pages/Query/styles.tsx index e0ad5485..9ea204a3 100644 --- a/src/pages/Query/styles.tsx +++ b/src/pages/Query/styles.tsx @@ -66,6 +66,8 @@ export const useQueryCodeEditorStyles = createStyles((theme) => { color: pColor, borderColor: colors.gray[2], height: "34px", + width: "40px", + padding: "0px", '&:hover': { color: sColor, }, @@ -103,6 +105,8 @@ export const useQueryResultEditorStyles = createStyles((theme) => { color: sColor, }, height: "34px", + width: "40px", + padding: "0px", marginInlineEnd: spacing.xs, color: colors.gray[5], borderColor:colors.gray[2] @@ -140,8 +144,10 @@ export const useQuerySchemaListStyles = createStyles((theme) => { actionBtn: { color: colors.gray[3], + height: "34px", + width: "40px", + padding: "0px", border: "none ", - height: "40px", '&:hover': { color: sColor, }, From fbc28faa9558b2ead15e0ef7e9d5149f498d6e02 Mon Sep 17 00:00:00 2001 From: Kartik Gupta Date: Thu, 20 Jul 2023 14:39:26 +0530 Subject: [PATCH 4/4] Requested changes 2 --- src/components/Header/SubHeader.tsx | 5 +++-- src/components/Header/styles.tsx | 2 +- src/pages/Logs/ViewLog.tsx | 4 ++-- src/pages/Logs/styles.tsx | 9 +++++---- src/pages/Query/QuerySchemaList.tsx | 10 ++++++---- src/pages/Query/index.tsx | 1 - src/pages/Query/styles.tsx | 13 +++++++++---- 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/components/Header/SubHeader.tsx b/src/components/Header/SubHeader.tsx index d065210a..e29bd09d 100644 --- a/src/components/Header/SubHeader.tsx +++ b/src/components/Header/SubHeader.tsx @@ -1,7 +1,7 @@ import useMountedState from '@/hooks/useMountedState'; import { Box, Breadcrumbs, Button, Menu, Text, TextInput, UnstyledButton, px } from '@mantine/core'; import { DateTimePicker } from '@mantine/dates'; -import { IconClock, IconReload , IconRefreshOff, IconSearch } from '@tabler/icons-react'; +import { IconClock,IconRefresh, IconReload , IconRefreshOff, IconSearch } from '@tabler/icons-react'; import dayjs from 'dayjs'; import ms from 'ms'; import type { ChangeEvent, FC, KeyboardEvent } from 'react'; @@ -43,9 +43,10 @@ const SubHeader: FC = () => { {useMatch("/:streamName/logs") && } + {useMatch("/:streamName/logs") && } + - {useMatch("/:streamName/logs") && } diff --git a/src/components/Header/styles.tsx b/src/components/Header/styles.tsx index d749214b..8fa294d6 100644 --- a/src/components/Header/styles.tsx +++ b/src/components/Header/styles.tsx @@ -59,7 +59,6 @@ export const useLogQueryStyles = createStyles((theme) => { innerContainer: { display: 'flex', paddingTop: spacing.xxs, - marginRight: spacing.md, }, homeIcon: { size:"24px", @@ -87,6 +86,7 @@ export const useLogQueryStyles = createStyles((theme) => { refreshNowBtn: { background: colors.white[0], padding:0, + marginRight: spacing.xs, width: "36px", color: colors.black[0], border: `${sizing.px} ${colors.gray[2]} solid`, diff --git a/src/pages/Logs/ViewLog.tsx b/src/pages/Logs/ViewLog.tsx index bc427c14..cdc62c45 100644 --- a/src/pages/Logs/ViewLog.tsx +++ b/src/pages/Logs/ViewLog.tsx @@ -106,9 +106,9 @@ const DataChip: FC = (props) => { - {[...dataList, ...dataList, ...dataList, ...dataList, ...dataList].map((data) => { + {[...dataList].map((data,i) => { return ( - + {data} ); diff --git a/src/pages/Logs/styles.tsx b/src/pages/Logs/styles.tsx index d9fded34..99114010 100644 --- a/src/pages/Logs/styles.tsx +++ b/src/pages/Logs/styles.tsx @@ -43,6 +43,8 @@ export const useLogTableStyles = createStyles((theme) => { paginationRow: { '.mantine-Pagination-control': { + border: `solid 1px ${colors.gray[2]}`, + '&:hover': { color: sColor, }, @@ -60,8 +62,7 @@ export const useLogTableStyles = createStyles((theme) => { }, tableContainer: { - position: 'relative', - boxShadow: shadows.sm, + position: 'relative' }, tableStyle: { @@ -148,6 +149,7 @@ export const useLogTableStyles = createStyles((theme) => { flexDirection: 'row', justifyContent: 'space-between', background: colors.gray[0], + borderTop: `${widths.px} ${colors.gray[1]} solid`, }, errorContainer: { @@ -169,7 +171,6 @@ export const useLogTableStyles = createStyles((theme) => { justifyContent: 'center', cursor: 'pointer', background: colors.white[0], - boxShadow: shadows.sm, padding: `0.2rem ${spacing.xs}`, border: `${widths.px} ${colors.gray[1]} solid`, borderRadius: defaultRadius, @@ -179,7 +180,7 @@ export const useLogTableStyles = createStyles((theme) => { }, limitBtnText: { - marginRight: spacing.md, + }, limitActive: { diff --git a/src/pages/Query/QuerySchemaList.tsx b/src/pages/Query/QuerySchemaList.tsx index 196c0d3d..74ebdced 100644 --- a/src/pages/Query/QuerySchemaList.tsx +++ b/src/pages/Query/QuerySchemaList.tsx @@ -1,8 +1,8 @@ import { FC, useEffect } from 'react'; import { useGetLogStreamSchema } from '@/hooks/useGetLogStreamSchema'; import { useHeaderContext } from '@/layouts/MainLayout/Context'; -import { Table, Box, Title, Button } from '@mantine/core'; -import { IconSquareRoundedXFilled } from '@tabler/icons-react'; +import { Table, Box, Title, Button, ScrollArea } from '@mantine/core'; +import { IconX } from '@tabler/icons-react'; import { useQuerySchemaListStyles } from './styles'; import { useQueryPageContext } from './Context'; @@ -39,18 +39,19 @@ const QuerySchemaList: FC = () => { }); const {classes} = useQuerySchemaListStyles(); - const {actionBtn ,container ,textContext ,theadSt ,tbodySt ,innercontainer}=classes; + const {actionBtn ,container ,textContext ,theadSt ,tbodySt ,innercontainer,scrollAreaSt}=classes; return ( Schema for {subLogQuery.get().streamName} - + {!(logStreamSchemaError) ? ( !loading && Boolean(querySchema) ? ( (querySchema?.fields.length) ? ( + @@ -60,6 +61,7 @@ const {classes} = useQuerySchemaListStyles(); {renderList}
+
) : (

No Data

) diff --git a/src/pages/Query/index.tsx b/src/pages/Query/index.tsx index 60367733..ec29c773 100644 --- a/src/pages/Query/index.tsx +++ b/src/pages/Query/index.tsx @@ -20,7 +20,6 @@ const Logs: FC = () => { useEffect(() => { const listener = subSchemaToggle.subscribe(setIsSchemaOpen); return () => { - console.log(isSchemaOpen) listener(); }; }, [subSchemaToggle.get()]); diff --git a/src/pages/Query/styles.tsx b/src/pages/Query/styles.tsx index 9ea204a3..4957c71d 100644 --- a/src/pages/Query/styles.tsx +++ b/src/pages/Query/styles.tsx @@ -66,7 +66,7 @@ export const useQueryCodeEditorStyles = createStyles((theme) => { color: pColor, borderColor: colors.gray[2], height: "34px", - width: "40px", + width: "34px", padding: "0px", '&:hover': { color: sColor, @@ -105,7 +105,7 @@ export const useQueryResultEditorStyles = createStyles((theme) => { color: sColor, }, height: "34px", - width: "40px", + width: "34px", padding: "0px", marginInlineEnd: spacing.xs, color: colors.gray[5], @@ -145,9 +145,9 @@ export const useQuerySchemaListStyles = createStyles((theme) => { actionBtn: { color: colors.gray[3], height: "34px", - width: "40px", + width: "34px", padding: "0px", - border: "none ", + borderColor:colors.gray[2], '&:hover': { color: sColor, }, @@ -176,6 +176,11 @@ export const useQuerySchemaListStyles = createStyles((theme) => { color:colors.gray[6], height: "34px" } + }, + scrollAreaSt:{ + maxWidth: "500px", + height: "calc(100% - 55px)", + overflow: "auto", } }; });