TRA-4256 gui oas window (#854)

* styling oas modal window

* styled oas modal

* review notes fix

* oas logo added

* small fixes

* typo
This commit is contained in:
AmitUp9 2022-03-06 12:24:49 +02:00 committed by GitHub
parent c671bc6655
commit c1d774e53c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 9514 additions and 7448 deletions

16633
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,11 +5,14 @@ import {TrafficPage} from "./components/Pages/TrafficPage/TrafficPage";
import { ServiceMapModal } from './components/ServiceMapModal/ServiceMapModal'; import { ServiceMapModal } from './components/ServiceMapModal/ServiceMapModal';
import {useRecoilState} from "recoil"; import {useRecoilState} from "recoil";
import serviceMapModalOpenAtom from "./recoil/serviceMapModalOpen"; import serviceMapModalOpenAtom from "./recoil/serviceMapModalOpen";
import OasModal from './components/OasModal/OasModal';
import oasModalOpenAtom from './recoil/oasModalOpen/atom';
const App = () => { const App = () => {
const [analyzeStatus, setAnalyzeStatus] = useState(null); const [analyzeStatus, setAnalyzeStatus] = useState(null);
const [serviceMapModalOpen, setServiceMapModalOpen] = useRecoilState(serviceMapModalOpenAtom); const [serviceMapModalOpen, setServiceMapModalOpen] = useRecoilState(serviceMapModalOpenAtom);
const [oasModalOpen, setOasModalOpen] = useRecoilState(oasModalOpenAtom)
return ( return (
<div className="mizuApp"> <div className="mizuApp">
@ -20,6 +23,10 @@ const App = () => {
onOpen={() => setServiceMapModalOpen(true)} onOpen={() => setServiceMapModalOpen(true)}
onClose={() => setServiceMapModalOpen(false)} onClose={() => setServiceMapModalOpen(false)}
/>} />}
{window["isOasEnabled"] && <OasModal
openModal={oasModalOpen}
handleCloseModal={() => setOasModalOpen(false)}
/>}
</div> </div>
); );
} }

View File

@ -0,0 +1,29 @@
@import '../../variables.module.scss'
.boxContainer
display: flex
justifyContent: space-between
padding: 10px
.selectHeader
display: flex
align-items: center
width: 100%
margin-top: -1%
.openApilogo
width: 36px
.title
color:#494677
font-family: Lato
font-size: 20px
font-weight: 600
.selectContainer
margin-left: 1%
.redoc
height: 98%
overflow-y: scroll

View File

@ -1,6 +0,0 @@
@import '../../variables.module.scss'
.NotSelectedMessage
margin-left: 41%
padding-top: 3%
font-size: large

View File

@ -1,32 +1,40 @@
import { Box, Fade, FormControl, MenuItem, Modal } from "@material-ui/core"; import { Box, Fade, FormControl, MenuItem, Modal, Backdrop, ListSubheader } from "@material-ui/core";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { RedocStandalone } from "redoc"; import { RedocStandalone } from "redoc";
import Api from "../../helpers/api"; import Api from "../../helpers/api";
import { Select } from "../UI/Select"; import { Select } from "../UI/Select";
import closeIcon from "../assets/closeIcon.svg"; import closeIcon from "../assets/closeIcon.svg";
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import './OasModal.sass' import style from './OasModal.module.sass';
import openApiLogo from '../assets/openApiLogo.png'
import { redocThemeOptions } from "./redocThemeOptions";
const modalStyle = {
position: 'absolute',
top: '6%',
left: '50%',
transform: 'translate(-50%, 0%)',
width: '89vw',
height: '82vh',
bgcolor: 'background.paper',
borderRadius: '5px',
boxShadow: 24,
p: 4,
color: '#000',
};
const api = Api.getInstance(); const api = Api.getInstance();
const noOasServiceSelectedMessage = "Please Select OasService"; const ipAddressWithPortRegex = new RegExp('([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}):([0-9]{1,5})');
const OasModal = ({ openModal, handleCloseModal }) => { const OasModal = ({ openModal, handleCloseModal }) => {
const [oasServices, setOasServices] = useState([]) const [oasServices, setOasServices] = useState([] as string[])
const [selectedServiceName, setSelectedServiceName] = useState(""); const [selectedServiceName, setSelectedServiceName] = useState("");
const [selectedServiceSpec, setSelectedServiceSpec] = useState(null); const [selectedServiceSpec, setSelectedServiceSpec] = useState(null);
const [resolvedServices, setResolvedServices] = useState([]);
const [unResolvedServices, setUnResolvedServices] = useState([]);
useEffect(() => { const onSelectedOASService = useCallback( async (selectedService) => {
(async () => { if (!!selectedService){
try {
const services = await api.getOasServices();
setOasServices(services);
} catch (e) {
console.error(e);
}
})();
}, [openModal]);
const onSelectedOASService = async (selectedService) => {
setSelectedServiceName(selectedService); setSelectedServiceName(selectedService);
if(oasServices.length === 0){ if(oasServices.length === 0){
return return
@ -38,7 +46,41 @@ const OasModal = ({ openModal, handleCloseModal }) => {
toast.error("Error occurred while fetching service OAS spec"); toast.error("Error occurred while fetching service OAS spec");
console.error(e); console.error(e);
} }
}; }
},[oasServices.length])
const resolvedArrayBuilder = useCallback(async(services) => {
const resServices = [];
const unResServices = [];
services.forEach(s => {
if(ipAddressWithPortRegex.test(s)){
unResServices.push(s);
}
else {
resServices.push(s);
}
});
resServices.sort();
unResServices.sort();
onSelectedOASService(resServices[0]);
setResolvedServices(resServices);
setUnResolvedServices(unResServices);
},[onSelectedOASService])
useEffect(() => {
(async () => {
try {
const services = await api.getOasServices();
resolvedArrayBuilder(services);
setOasServices(services);
} catch (e) {
console.error(e);
}
})();
}, [openModal,resolvedArrayBuilder]);
return ( return (
<Modal <Modal
@ -47,29 +89,34 @@ const OasModal = ({ openModal, handleCloseModal }) => {
open={openModal} open={openModal}
onClose={handleCloseModal} onClose={handleCloseModal}
closeAfterTransition closeAfterTransition
hideBackdrop={true} BackdropComponent={Backdrop}
style={{ overflow: "auto", backgroundColor: "#ffffff", color:"black" }} BackdropProps={{
> timeout: 500,
<Fade in={openModal}>
<Box>
<div
style={{
display: "flex",
justifyContent: "space-between",
padding: "1%",
}} }}
> >
<div style={{ marginLeft: "40%" }}> <Fade in={openModal}>
<Box sx={modalStyle}>
<div className={style.boxContainer}>
<div className={style.selectHeader}>
<div><img src={openApiLogo} alt="openApi" className={style.openApilogo}/></div>
<div className={style.title}>OpenAPI selected service: </div>
<div className={style.selectContainer} >
<FormControl> <FormControl>
<Select <Select
labelId="service-select-label" labelId="service-select-label"
id="service-select" id="service-select"
label="Show OAS"
placeholder="Show OAS" placeholder="Show OAS"
value={selectedServiceName} value={selectedServiceName}
onChange={onSelectedOASService} onChange={onSelectedOASService}
> >
{oasServices.map((service) => ( <ListSubheader disableSticky={true}>Resolved</ListSubheader>
{resolvedServices.map((service) => (
<MenuItem key={service} value={service}>
{service}
</MenuItem>
))}
<ListSubheader disableSticky={true}>UnResolved</ListSubheader>
{unResolvedServices.map((service) => (
<MenuItem key={service} value={service}> <MenuItem key={service} value={service}>
{service} {service}
</MenuItem> </MenuItem>
@ -77,13 +124,15 @@ const OasModal = ({ openModal, handleCloseModal }) => {
</Select> </Select>
</FormControl> </FormControl>
</div> </div>
</div>
<div style={{ cursor: "pointer" }}> <div style={{ cursor: "pointer" }}>
<img src={closeIcon} alt="Back" onClick={handleCloseModal} /> <img src={closeIcon} alt="close" onClick={handleCloseModal} />
</div> </div>
</div> </div>
{selectedServiceSpec && <RedocStandalone spec={selectedServiceSpec} />} <div className={style.redoc}>
<div className="NotSelectedMessage"> {selectedServiceSpec && <RedocStandalone
{!selectedServiceName && noOasServiceSelectedMessage} spec={selectedServiceSpec}
options={redocThemeOptions}/>}
</div> </div>
</Box> </Box>
</Fade> </Fade>

View File

@ -0,0 +1,35 @@
export const redocThemeOptions = {
theme:{
codeBlock:{
backgroundColor:"#11171a",
},
colors:{
responses:{
error:{
tabTextColor:"#1b1b29"
},
info:{
tabTextColor:"#1b1b29",
},
success:{
tabTextColor:"#0c0b1a"
},
},
text:{
primary:"#1b1b29",
secondary:"#4d4d4d"
}
},
rightPanel:{
backgroundColor:"#253237",
},
sidebar:{
backgroundColor:"#ffffff"
},
typography:{
code:{
color:"#0c0b1a"
}
}
}
}

View File

@ -18,12 +18,12 @@ import entriesAtom from "../../../recoil/entries";
import focusedEntryIdAtom from "../../../recoil/focusedEntryId"; import focusedEntryIdAtom from "../../../recoil/focusedEntryId";
import websocketConnectionAtom, {WsConnectionStatus} from "../../../recoil/wsConnection"; import websocketConnectionAtom, {WsConnectionStatus} from "../../../recoil/wsConnection";
import queryAtom from "../../../recoil/query"; import queryAtom from "../../../recoil/query";
import OasModal from "../../OasModal/OasModal";
import {useCommonStyles} from "../../../helpers/commonStyle" import {useCommonStyles} from "../../../helpers/commonStyle"
import {TLSWarning} from "../../TLSWarning/TLSWarning"; import {TLSWarning} from "../../TLSWarning/TLSWarning";
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen"; import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
import serviceMap from "../../assets/serviceMap.svg"; import serviceMap from "../../assets/serviceMap.svg";
import services from "../../assets/services.svg"; import services from "../../assets/services.svg";
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
const useLayoutStyles = makeStyles(() => ({ const useLayoutStyles = makeStyles(() => ({
details: { details: {
@ -59,6 +59,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom); const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom);
const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom); const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom);
const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom); const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom);
const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom);
const query = useRecoilValue(queryAtom); const query = useRecoilValue(queryAtom);
const [noMoreDataTop, setNoMoreDataTop] = useState(false); const [noMoreDataTop, setNoMoreDataTop] = useState(false);
@ -75,10 +76,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
const [startTime, setStartTime] = useState(0); const [startTime, setStartTime] = useState(0);
const scrollableRef = useRef(null); const scrollableRef = useRef(null);
const [openOasModal, setOpenOasModal] = useState(false);
const handleCloseModal = () => setOpenOasModal(false);
const [showTLSWarning, setShowTLSWarning] = useState(false); const [showTLSWarning, setShowTLSWarning] = useState(false);
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false); const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>()); const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>());
@ -283,7 +280,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
</div> </div>
</div> </div>
</div> </div>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex', height: "100%" }}>
{window["isOasEnabled"] && <Button {window["isOasEnabled"] && <Button
startIcon={<img className="custom" src={services} alt="services"></img>} startIcon={<img className="custom" src={services} alt="services"></img>}
size="large" size="large"
@ -306,10 +303,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
</Button>} </Button>}
</div> </div>
</div> </div>
{window["isOasEnabled"] && <OasModal
openModal={openOasModal}
handleCloseModal={handleCloseModal}
/>}
{<div className="TrafficPage-Container"> {<div className="TrafficPage-Container">
<div className="TrafficPage-ListContainer"> <div className="TrafficPage-ListContainer">
<Filters <Filters

View File

@ -81,11 +81,11 @@ interface ServiceMapModalProps {
const modalStyle = { const modalStyle = {
position: 'absolute', position: 'absolute',
top: '10%', top: '6%',
left: '50%', left: '50%',
transform: 'translate(-50%, 0%)', transform: 'translate(-50%, 0%)',
width: '80vw', width: '89vw',
height: '80vh', height: '82vh',
bgcolor: 'background.paper', bgcolor: 'background.paper',
borderRadius: '5px', borderRadius: '5px',
boxShadow: 24, boxShadow: 24,

View File

@ -2,7 +2,6 @@ import Tooltip from "./Tooltip";
import React from "react"; import React from "react";
import {makeStyles} from '@material-ui/core/styles'; import {makeStyles} from '@material-ui/core/styles';
import variables from '../../variables.module.scss'; import variables from '../../variables.module.scss';
interface Tab { interface Tab {
tab: string, tab: string,
disabled?: boolean, disabled?: boolean,
@ -40,7 +39,7 @@ const useTabsStyles = makeStyles((theme) => ({
}, },
active: { active: {
fontWeight: theme.typography.fontWeightBold, fontWeight: 600,
color: variables.fontColor, color: variables.fontColor,
cursor: 'unset', cursor: 'unset',
borderBottom: "2px solid " + variables.fontColor, borderBottom: "2px solid " + variables.fontColor,

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -84,6 +84,11 @@ export default class Api {
return response.data; return response.data;
} }
gelAlloasServicesInOneSpec = async () => {
const response = await this.client.get("/oas/all");
return response.data;
}
validateQuery = async (query) => { validateQuery = async (query) => {
if (this.source) { if (this.source) {
this.source.cancel(); this.source.cancel();

View File

@ -146,3 +146,11 @@ button
::-webkit-scrollbar-corner ::-webkit-scrollbar-corner
display: none display: none
// remove powerdby
.sc-ilfuhL
display: none !important
// enable view elements inside redoc
.sc-dwsnSq
height: 80vh !important

View File

@ -0,0 +1,8 @@
import { atom } from "recoil"
const oasModalOpenAtom = atom({
key: "oasModalOpenAtom",
default: false
})
export default oasModalOpenAtom;

View File

@ -0,0 +1,2 @@
import atom from "./atom";
export default atom;