From 6e6bcec77e7721620ca97855009222f657ffb00f Mon Sep 17 00:00:00 2001 From: leon-up9 <97597983+leon-up9@users.noreply.github.com> Date: Mon, 6 Jun 2022 16:40:23 +0300 Subject: [PATCH] Ui/TRA-4586_add-insertion-filter-to-settings-page (#1127) * working query input * removed prop * splited to diffrent events * export alias * PR comments Co-authored-by: Leon <> --- .../src/components/TrafficViewer/Filters.tsx | 91 +++++++++++++------ .../TrafficViewer/TrafficViewer.tsx | 46 +++------- ui-common/src/components/UI/index.ts | 5 +- ui-common/src/index.tsx | 1 + ui-common/src/recoil/TrafficViewerApi/atom.ts | 2 +- 5 files changed, 77 insertions(+), 68 deletions(-) diff --git a/ui-common/src/components/TrafficViewer/Filters.tsx b/ui-common/src/components/TrafficViewer/Filters.tsx index d7c9b696b..2788fcd49 100644 --- a/ui-common/src/components/TrafficViewer/Filters.tsx +++ b/ui-common/src/components/TrafficViewer/Filters.tsx @@ -1,36 +1,43 @@ -import React, {useRef, useState} from "react"; +import React, { FC, useEffect, useMemo, useRef, useState } from "react"; import styles from '../style/Filters.module.sass'; -import {Button, Grid, Modal, Box, Typography, Backdrop, Fade, Divider} from "@material-ui/core"; +import { Button, Grid, Modal, Box, Typography, Backdrop, Fade, Divider, debounce } from "@material-ui/core"; import CodeEditor from '@uiw/react-textarea-code-editor'; import MenuBookIcon from '@material-ui/icons/MenuBook'; -import {SyntaxHighlighter} from "../UI/SyntaxHighlighter/index"; +import { SyntaxHighlighter } from "../UI/SyntaxHighlighter/index"; import filterUIExample1 from "assets/filter-ui-example-1.png" import filterUIExample2 from "assets/filter-ui-example-2.png" import variables from '../../variables.module.scss'; -import {useRecoilState, useRecoilValue} from "recoil"; +import { useRecoilState, useRecoilValue } from "recoil"; import queryAtom from "../../recoil/query"; import useKeyPress from "../../hooks/useKeyPress" import shortcutsKeyboard from "../../configs/shortcutsKeyboard" -import trafficViewerApiAtom from "../../recoil/TrafficViewerApi" +import TrafficViewerApiAtom from "../../recoil/TrafficViewerApi/atom"; interface FiltersProps { - backgroundColor: string reopenConnection: any; } -export const Filters: React.FC = ({backgroundColor, reopenConnection}) => { +export const Filters: React.FC = ({ reopenConnection }) => { + const [query, setQuery] = useRecoilState(queryAtom); + const api: any = useRecoilValue(TrafficViewerApiAtom) + return
+ onQueryChange={(query) => { setQuery(query?.trim()); }} validateQuery={api?.validateQuery} />
; }; +type OnQueryChange = { valid: boolean, message: string, query: string } + interface QueryFormProps { - backgroundColor: string - reopenConnection: any; + reopenConnection?: any; + query: string + onQueryChange?: (query: string) => void + validateQuery: (query: string) => Promise<{ valid: boolean, message: string }>; + onValidationChanged?: (event: OnQueryChange) => void } export const modalStyle = { @@ -47,20 +54,57 @@ export const modalStyle = { color: '#000', }; -export const QueryForm: React.FC = ({backgroundColor, reopenConnection}) => { +export const CodeEditorWrap: FC = ({ query, onQueryChange, validateQuery, onValidationChanged }) => { + const [queryBackgroundColor, setQueryBackgroundColor] = useState("#f5f5f5"); + const handleQueryChange = useMemo( + () => + debounce(async (query: string) => { + if (!query) { + setQueryBackgroundColor("#f5f5f5"); + onValidationChanged && onValidationChanged({ query: query, message: "", valid: true }) + } else { + const data = await validateQuery(query); + if (!data) { + return; + } + if (data.valid) { + setQueryBackgroundColor("#d2fad2"); + } else { + setQueryBackgroundColor("#fad6dc"); + } + onValidationChanged && onValidationChanged({ query: query, message: data.message, valid: data.valid }) + } + }, 500), + [onValidationChanged, validateQuery] + ) as (query: string) => void; + + useEffect(() => { + handleQueryChange(query); + }, [query, handleQueryChange]); + + return onQueryChange(event.target.value)} + padding={8} + style={{ + fontSize: 14, + backgroundColor: `${queryBackgroundColor}`, + fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace', + }} + /> +} + +export const QueryForm: React.FC = ({ validateQuery, reopenConnection, query, onQueryChange, onValidationChanged }) => { const formRef = useRef(null); - const [query, setQuery] = useRecoilState(queryAtom); const [openModal, setOpenModal] = useState(false); const handleOpenModal = () => setOpenModal(true); const handleCloseModal = () => setOpenModal(false); - const handleChange = async (e) => { - setQuery(e.target.value.trim()); - } - const handleSubmit = (e) => { reopenConnection(); e.preventDefault(); @@ -86,18 +130,7 @@ export const QueryForm: React.FC = ({backgroundColor, reopenConn }} > diff --git a/ui-common/src/components/TrafficViewer/TrafficViewer.tsx b/ui-common/src/components/TrafficViewer/TrafficViewer.tsx index af385a51e..6f1af8574 100644 --- a/ui-common/src/components/TrafficViewer/TrafficViewer.tsx +++ b/ui-common/src/components/TrafficViewer/TrafficViewer.tsx @@ -1,24 +1,23 @@ -import React, {useEffect, useMemo, useRef, useState} from "react"; -import {Filters} from "./Filters"; -import {EntriesList} from "./EntriesList"; -import {makeStyles} from "@material-ui/core"; +import React, { useEffect, useRef, useState } from "react"; +import { Filters } from "./Filters"; +import { EntriesList } from "./EntriesList"; +import { makeStyles } from "@material-ui/core"; import TrafficViewerStyles from "./TrafficViewer.module.sass"; import styles from '../style/EntriesList.module.sass'; -import {EntryDetailed} from "./EntryDetailed"; +import { EntryDetailed } from "./EntryDetailed"; import playIcon from 'assets/run.svg'; import pauseIcon from 'assets/pause.svg'; import variables from '../../variables.module.scss'; -import {ToastContainer} from 'react-toastify'; -import debounce from 'lodash/debounce'; -import {RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState} from "recoil"; +import { ToastContainer } from 'react-toastify'; +import { RecoilRoot, RecoilState, useRecoilState, useRecoilValue, useSetRecoilState } from "recoil"; import entriesAtom from "../../recoil/entries"; import focusedEntryIdAtom from "../../recoil/focusedEntryId"; import queryAtom from "../../recoil/query"; import trafficViewerApiAtom from "../../recoil/TrafficViewerApi" import TrafficViewerApi from "./TrafficViewerApi"; -import {StatusBar} from "../UI/StatusBar"; +import { StatusBar } from "../UI/StatusBar"; import tappingStatusAtom from "../../recoil/tappingStatus/atom"; -import {TOAST_CONTAINER_ID} from "../../configs/Consts"; +import { TOAST_CONTAINER_ID } from "../../configs/Consts"; import leftOffTopAtom from "../../recoil/leftOffTop"; import { DEFAULT_LEFTOFF, DEFAULT_FETCH, DEFAULT_FETCH_TIMEOUT_MS } from '../../hooks/useWS'; @@ -70,34 +69,12 @@ export const TrafficViewer: React.FC = ({ const [isSnappedToBottom, setIsSnappedToBottom] = useState(true); const [wsReadyState, setWsReadyState] = useState(0); - const [queryBackgroundColor, setQueryBackgroundColor] = useState("#f5f5f5"); - const setLeftOffTop = useSetRecoilState(leftOffTopAtom); const scrollableRef = useRef(null); - const handleQueryChange = useMemo( - () => - debounce(async (query: string) => { - if (!query) { - setQueryBackgroundColor("#f5f5f5"); - } else { - const data = await trafficViewerApiProp.validateQuery(query); - if (!data) { - return; - } - if (data.valid) { - setQueryBackgroundColor("#d2fad2"); - } else { - setQueryBackgroundColor("#fad6dc"); - } - } - }, 500), - [] - ) as (query: string) => void; - useEffect(() => { - handleQueryChange(query); - }, [query, handleQueryChange]); + + useEffect(() => { if(shouldCloseWebSocket){ @@ -262,7 +239,6 @@ export const TrafficViewer: React.FC = ({ {
diff --git a/ui-common/src/components/UI/index.ts b/ui-common/src/components/UI/index.ts index b4d6c904b..4dc123178 100644 --- a/ui-common/src/components/UI/index.ts +++ b/ui-common/src/components/UI/index.ts @@ -9,6 +9,5 @@ import { InformationIcon, Link } from "./InformationIcon"; import SelectList from "./SelectList"; import NoDataMessage from "./NoDataMessage"; - -export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage, Link } -export { StatusBar } \ No newline at end of file +export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage, Link }; +export { StatusBar } diff --git a/ui-common/src/index.tsx b/ui-common/src/index.tsx index ac1252d49..0439fd03a 100644 --- a/ui-common/src/index.tsx +++ b/ui-common/src/index.tsx @@ -5,6 +5,7 @@ import useWS, { DEFAULT_LEFTOFF } from './hooks/useWS'; import OasModal from './components/OasModal/OasModal'; import { ServiceMapModal } from './components/ServiceMapModal/ServiceMapModal'; +export { CodeEditorWrap as QueryForm } from './components/TrafficViewer/Filters'; export { UI, StatusBar, OasModal, ServiceMapModal } export { useWS, DEFAULT_LEFTOFF } export default TrafficViewer; diff --git a/ui-common/src/recoil/TrafficViewerApi/atom.ts b/ui-common/src/recoil/TrafficViewerApi/atom.ts index 418f0dc10..92d5c07e0 100644 --- a/ui-common/src/recoil/TrafficViewerApi/atom.ts +++ b/ui-common/src/recoil/TrafficViewerApi/atom.ts @@ -3,7 +3,7 @@ import TrafficViewerApi from "../../components/TrafficViewer/TrafficViewerApi"; const TrafficViewerApiAtom = atom({ key: "TrafficViewerApiAtom", - default: {} as TrafficViewerApi + default: {} }); export default TrafficViewerApiAtom;