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

16689
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 {useRecoilState} from "recoil";
import serviceMapModalOpenAtom from "./recoil/serviceMapModalOpen";
import OasModal from './components/OasModal/OasModal';
import oasModalOpenAtom from './recoil/oasModalOpen/atom';
const App = () => {
const [analyzeStatus, setAnalyzeStatus] = useState(null);
const [serviceMapModalOpen, setServiceMapModalOpen] = useRecoilState(serviceMapModalOpenAtom);
const [oasModalOpen, setOasModalOpen] = useRecoilState(oasModalOpenAtom)
return (
<div className="mizuApp">
@ -20,6 +23,10 @@ const App = () => {
onOpen={() => setServiceMapModalOpen(true)}
onClose={() => setServiceMapModalOpen(false)}
/>}
{window["isOasEnabled"] && <OasModal
openModal={oasModalOpen}
handleCloseModal={() => setOasModalOpen(false)}
/>}
</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,44 +1,86 @@
import { Box, Fade, FormControl, MenuItem, Modal } from "@material-ui/core";
import { useEffect, useState } from "react";
import { Box, Fade, FormControl, MenuItem, Modal, Backdrop, ListSubheader } from "@material-ui/core";
import { useCallback, useEffect, useState } from "react";
import { RedocStandalone } from "redoc";
import Api from "../../helpers/api";
import { Select } from "../UI/Select";
import closeIcon from "../assets/closeIcon.svg";
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 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 [oasServices, setOasServices] = useState([])
const [oasServices, setOasServices] = useState([] as string[])
const [selectedServiceName, setSelectedServiceName] = useState("");
const [selectedServiceSpec, setSelectedServiceSpec] = useState(null);
const [resolvedServices, setResolvedServices] = useState([]);
const [unResolvedServices, setUnResolvedServices] = useState([]);
const onSelectedOASService = useCallback( async (selectedService) => {
if (!!selectedService){
setSelectedServiceName(selectedService);
if(oasServices.length === 0){
return
}
try {
const data = await api.getOasByService(selectedService);
setSelectedServiceSpec(data);
} catch (e) {
toast.error("Error occurred while fetching service OAS spec");
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]);
}, [openModal,resolvedArrayBuilder]);
const onSelectedOASService = async (selectedService) => {
setSelectedServiceName(selectedService);
if(oasServices.length === 0){
return
}
try {
const data = await api.getOasByService(selectedService);
setSelectedServiceSpec(data);
} catch (e) {
toast.error("Error occurred while fetching service OAS spec");
console.error(e);
}
};
return (
<Modal
@ -47,43 +89,50 @@ const OasModal = ({ openModal, handleCloseModal }) => {
open={openModal}
onClose={handleCloseModal}
closeAfterTransition
hideBackdrop={true}
style={{ overflow: "auto", backgroundColor: "#ffffff", color:"black" }}
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={openModal}>
<Box>
<div
style={{
display: "flex",
justifyContent: "space-between",
padding: "1%",
}}
>
<div style={{ marginLeft: "40%" }}>
<FormControl>
<Select
labelId="service-select-label"
id="service-select"
label="Show OAS"
placeholder="Show OAS"
value={selectedServiceName}
onChange={onSelectedOASService}
>
{oasServices.map((service) => (
<MenuItem key={service} value={service}>
{service}
</MenuItem>
))}
</Select>
</FormControl>
<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>
<Select
labelId="service-select-label"
id="service-select"
placeholder="Show OAS"
value={selectedServiceName}
onChange={onSelectedOASService}
>
<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}>
{service}
</MenuItem>
))}
</Select>
</FormControl>
</div>
</div>
<div style={{ cursor: "pointer" }}>
<img src={closeIcon} alt="Back" onClick={handleCloseModal} />
<img src={closeIcon} alt="close" onClick={handleCloseModal} />
</div>
</div>
{selectedServiceSpec && <RedocStandalone spec={selectedServiceSpec} />}
<div className="NotSelectedMessage">
{!selectedServiceName && noOasServiceSelectedMessage}
<div className={style.redoc}>
{selectedServiceSpec && <RedocStandalone
spec={selectedServiceSpec}
options={redocThemeOptions}/>}
</div>
</Box>
</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 websocketConnectionAtom, {WsConnectionStatus} from "../../../recoil/wsConnection";
import queryAtom from "../../../recoil/query";
import OasModal from "../../OasModal/OasModal";
import {useCommonStyles} from "../../../helpers/commonStyle"
import {TLSWarning} from "../../TLSWarning/TLSWarning";
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
import serviceMap from "../../assets/serviceMap.svg";
import services from "../../assets/services.svg";
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
const useLayoutStyles = makeStyles(() => ({
details: {
@ -59,6 +59,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
const [focusedEntryId, setFocusedEntryId] = useRecoilState(focusedEntryIdAtom);
const [wsConnection, setWsConnection] = useRecoilState(websocketConnectionAtom);
const setServiceMapModalOpen = useSetRecoilState(serviceMapModalOpenAtom);
const [openOasModal, setOpenOasModal] = useRecoilState(oasModalOpenAtom);
const query = useRecoilValue(queryAtom);
const [noMoreDataTop, setNoMoreDataTop] = useState(false);
@ -75,10 +76,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
const [startTime, setStartTime] = useState(0);
const scrollableRef = useRef(null);
const [openOasModal, setOpenOasModal] = useState(false);
const handleCloseModal = () => setOpenOasModal(false);
const [showTLSWarning, setShowTLSWarning] = useState(false);
const [userDismissedTLSWarning, setUserDismissedTLSWarning] = useState(false);
const [addressesWithTLS, setAddressesWithTLS] = useState(new Set<string>());
@ -283,7 +280,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
</div>
</div>
</div>
<div style={{ display: 'flex' }}>
<div style={{ display: 'flex', height: "100%" }}>
{window["isOasEnabled"] && <Button
startIcon={<img className="custom" src={services} alt="services"></img>}
size="large"
@ -306,10 +303,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
</Button>}
</div>
</div>
{window["isOasEnabled"] && <OasModal
openModal={openOasModal}
handleCloseModal={handleCloseModal}
/>}
{<div className="TrafficPage-Container">
<div className="TrafficPage-ListContainer">
<Filters

View File

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

View File

@ -2,7 +2,6 @@ import Tooltip from "./Tooltip";
import React from "react";
import {makeStyles} from '@material-ui/core/styles';
import variables from '../../variables.module.scss';
interface Tab {
tab: string,
disabled?: boolean,
@ -27,7 +26,7 @@ const useTabsStyles = makeStyles((theme) => ({
height: 40,
paddingTop: 15
},
tab: {
display: 'inline-block',
textTransform: 'uppercase',
@ -40,7 +39,7 @@ const useTabsStyles = makeStyles((theme) => ({
},
active: {
fontWeight: theme.typography.fontWeightBold,
fontWeight: 600,
color: variables.fontColor,
cursor: 'unset',
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;
}
gelAlloasServicesInOneSpec = async () => {
const response = await this.client.get("/oas/all");
return response.data;
}
validateQuery = async (query) => {
if (this.source) {
this.source.cancel();

View File

@ -146,3 +146,11 @@ button
::-webkit-scrollbar-corner
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;