Compare commits

...

3 Commits

Author SHA1 Message Date
AmitUp9
274fbeb34a warning cleaning from console (#1187)
* warning cleaning from console

* code cleaning
2022-07-06 13:13:04 +03:00
leon-up9
38c05a6634 UI/feature flag for replay modal (#1186)
* context added

* import added

* chnages

* ui enabled

* moved to Consts

* changes to recoil

* change

* new useEffect

Co-authored-by: Leon <>
2022-07-06 11:19:46 +03:00
leon-up9
d857935889 move icon to right side (#1185)
Co-authored-by: Leon <>
2022-07-05 16:35:03 +03:00
13 changed files with 98 additions and 71 deletions

View File

@@ -6,6 +6,7 @@ import { ReactComponent as ReplayIcon } from './replay.svg';
import styles from './EntryViewer.module.sass';
import { Tabs } from "../../UI";
import replayRequestModalOpenAtom from "../../../recoil/replayRequestModalOpen";
import entryDetailedConfigAtom, { EntryDetailedConfig } from "../../../recoil/entryDetailedConfig";
const enabledProtocolsForReplay = ["http"]
@@ -16,10 +17,11 @@ export enum TabsEnum {
export const AutoRepresentation: React.FC<any> = ({ representation, color, openedTab = TabsEnum.Request, isDisplayReplay = false }) => {
const entryData = useRecoilValue(entryDataAtom)
const { isReplayEnabled } = useRecoilValue<EntryDetailedConfig>(entryDetailedConfigAtom)
const setIsOpenRequestModal = useSetRecoilState(replayRequestModalOpenAtom)
const isReplayDisplayed = useCallback(() => {
return enabledProtocolsForReplay.find(x => x === entryData.protocol.name) && isDisplayReplay
}, [entryData.protocol.name, isDisplayReplay])
return enabledProtocolsForReplay.find(x => x === entryData.protocol.name) && isDisplayReplay && isReplayEnabled
}, [entryData.protocol.name, isDisplayReplay, isReplayEnabled])
const { request, response } = JSON.parse(representation);
@@ -27,20 +29,18 @@ export const AutoRepresentation: React.FC<any> = ({ representation, color, opene
const arr = [
{
tab: 'Request',
badge: isReplayDisplayed() && <span title="Replay Request"><ReplayIcon fill={color} stroke={color} style={{ marginLeft: "10px", cursor: "pointer", height: "22px" }} onClick={() => setIsOpenRequestModal(true)} /></span>
badge: null
}]
if (response) {
arr.push(
{
tab: 'Response',
badge: null
}
);
arr.push({
tab: 'Response',
badge: null
});
}
return arr
}, [color, isReplayDisplayed, response, setIsOpenRequestModal]);
}, [response]);
const [currentTab, setCurrentTab] = useState(TABS[0].tab);
@@ -66,6 +66,7 @@ export const AutoRepresentation: React.FC<any> = ({ representation, color, opene
{<div className={styles.body}>
<div className={styles.bodyHeader}>
<Tabs tabs={TABS} currentTab={currentTab} color={color} onChange={setCurrentTab} leftAligned />
{isReplayDisplayed() && <span title="Replay Request"><ReplayIcon fill={color} stroke={color} style={{ marginLeft: "10px", cursor: "pointer", height: "22px" }} onClick={() => setIsOpenRequestModal(true)} /></span>}
</div>
{getOpenedTabIndex() === TabsEnum.Request && <React.Fragment>
<SectionsRepresentation data={request} color={color} requestRepresentation={request} />

View File

@@ -52,8 +52,13 @@
border-radius: 4px
padding: 10px
position: relative
.bodyHeader
padding: 0 1rem
display: flex
align-items: center
justify-content: space-between
.endpointURL
font-size: .75rem
display: block

View File

@@ -22,6 +22,7 @@ import leftOffTopAtom from "../../recoil/leftOffTop";
import { DEFAULT_LEFTOFF, DEFAULT_FETCH, DEFAULT_FETCH_TIMEOUT_MS } from '../../hooks/useWS';
import ReplayRequestModalContainer from "../modals/ReplayRequestModal/ReplayRequestModal";
import replayRequestModalOpenAtom from "../../recoil/replayRequestModalOpen";
import entryDetailedConfigAtom, { EntryDetailedConfig } from "../../recoil/entryDetailedConfig";
const useLayoutStyles = makeStyles(() => ({
details: {
@@ -51,18 +52,22 @@ interface TrafficViewerProps {
webSocketUrl: string,
shouldCloseWebSocket: boolean,
setShouldCloseWebSocket: (flag: boolean) => void,
isDemoBannerView: boolean
isDemoBannerView: boolean,
entryDetailedConfig: EntryDetailedConfig
}
export const TrafficViewer: React.FC<TrafficViewerProps> = ({
trafficViewerApiProp,
actionButtons, isShowStatusBar, webSocketUrl,
shouldCloseWebSocket, setShouldCloseWebSocket, isDemoBannerView
}) => {
trafficViewerApiProp,
webSocketUrl,
actionButtons,
isShowStatusBar, isDemoBannerView,
shouldCloseWebSocket, setShouldCloseWebSocket,
entryDetailedConfig }) => {
const classes = useLayoutStyles();
const setEntries = useSetRecoilState(entriesAtom);
const setFocusedEntryId = useSetRecoilState(focusedEntryIdAtom);
const setEntryDetailedConfigAtom = useSetRecoilState(entryDetailedConfigAtom)
const query = useRecoilValue(queryAtom);
const setTrafficViewerApiState = useSetRecoilState(trafficViewerApiAtom as RecoilState<TrafficViewerApi>)
const [tappingStatus, setTappingStatus] = useRecoilState(tappingStatusAtom);
@@ -183,6 +188,10 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
};
}, []);
useEffect(() => {
setEntryDetailedConfigAtom(entryDetailedConfig)
}, [entryDetailedConfig, setEntryDetailedConfigAtom])
const getConnectionIndicator = () => {
switch (wsReadyState) {
case WebSocket.OPEN:
@@ -258,7 +267,7 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
</div>
</div>
<div className={classes.details} id="rightSideContainer">
<EntryDetailed/>
<EntryDetailed />
</div>
</div>}
</div>
@@ -266,25 +275,19 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
};
const MemorizedTrafficViewer = React.memo(TrafficViewer)
const TrafficViewerContainer: React.FC<TrafficViewerProps> = ({
trafficViewerApiProp,
actionButtons, isShowStatusBar = true,
webSocketUrl, shouldCloseWebSocket, setShouldCloseWebSocket, isDemoBannerView
}) => {
const TrafficViewerContainer: React.FC<TrafficViewerProps> = (props) => {
return <RecoilRoot>
<MemorizedTrafficViewer actionButtons={actionButtons} isShowStatusBar={isShowStatusBar} webSocketUrl={webSocketUrl}
shouldCloseWebSocket={shouldCloseWebSocket} setShouldCloseWebSocket={setShouldCloseWebSocket} trafficViewerApiProp={trafficViewerApiProp}
isDemoBannerView={isDemoBannerView}/>
<MemorizedTrafficViewer {...props} />
<ToastContainer enableMultiContainer containerId={TOAST_CONTAINER_ID}
position="bottom-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover/>
position="bottom-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover />
<ReplayRequestModalContainer />
</RecoilRoot>
}

View File

@@ -74,6 +74,7 @@ $modalMargin-from-edge : 35px
width: -moz-available
width: -webkit-fill-available
width: fill-available
width: strech
max-width: 200px
box-shadow: 0px 1px 5px #979797
margin-left: 10px

View File

@@ -1,5 +1,4 @@
import styles from "./TimelineBarChart.module.sass";
import { ALL_PROTOCOLS, StatsMode } from "../TrafficStatsModal"
import React, { useEffect, useMemo, useState } from "react";
import {
BarChart,
@@ -9,6 +8,7 @@ import {
Tooltip,
} from "recharts";
import { Utils } from "../../../../helpers/Utils";
import { ALL_PROTOCOLS, StatsMode } from "../consts";
interface TimelineBarChartProps {
timeLineBarChartMode: string;

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useMemo, useState } from "react";
import { Cell, Legend, Pie, PieChart, Tooltip } from "recharts";
import { Utils } from "../../../../helpers/Utils";
import { ALL_PROTOCOLS, StatsMode as PieChartMode } from "../TrafficStatsModal"
import { ALL_PROTOCOLS ,StatsMode as PieChartMode } from "../consts"
const RADIAN = Math.PI / 180;
const renderCustomizedLabel = ({

View File

@@ -7,6 +7,7 @@ import { TimelineBarChart } from "./TimelineBarChart/TimelineBarChart";
import refreshIcon from "assets/refresh.svg";
import { useCommonStyles } from "../../../helpers/commonStyle";
import { LoadingWrapper } from "../../UI/withLoading/withLoading";
import { ALL_PROTOCOLS, StatsMode } from "./consts";
const modalStyle = {
position: 'absolute',
@@ -22,19 +23,12 @@ const modalStyle = {
color: '#000',
};
export enum StatsMode {
REQUESTS = "entriesCount",
VOLUME = "volumeSizeBytes"
}
interface TrafficStatsModalProps {
isOpen: boolean;
onClose: () => void;
getTrafficStatsDataApi: () => Promise<any>
}
export const ALL_PROTOCOLS = "ALL";
export const TrafficStatsModal: React.FC<TrafficStatsModalProps> = ({ isOpen, onClose, getTrafficStatsDataApi }) => {
const modes = Object.keys(StatsMode).filter(x => !(parseInt(x) >= 0));

View File

@@ -0,0 +1,5 @@
export const ALL_PROTOCOLS = "ALL";
export enum StatsMode {
REQUESTS = "entriesCount",
VOLUME = "volumeSizeBytes"
}

View File

@@ -7,6 +7,5 @@ import { ServiceMapModal } from './components/modals/ServiceMapModal/ServiceMapM
import { TrafficStatsModal } from './components/modals/TrafficStatsModal/TrafficStatsModal';
export { CodeEditorWrap as QueryForm } from './components/Filters/Filters';
export { UI, StatusBar, OasModal, ServiceMapModal, TrafficStatsModal }
export { UI, StatusBar, OasModal, ServiceMapModal, TrafficStatsModal, TrafficViewer }
export { useWS, DEFAULT_LEFTOFF }
export default TrafficViewer;

View File

@@ -0,0 +1,12 @@
import { atom } from "recoil";
const entryDetailedConfigAtom = atom({
key: "entryDetailedConfigAtom",
default: null
});
export type EntryDetailedConfig = {
isReplayEnabled: boolean
}
export default entryDetailedConfigAtom;

View File

@@ -0,0 +1,3 @@
import atom from "./atom"
export type { EntryDetailedConfig } from "./atom"
export default atom

View File

@@ -5,13 +5,14 @@ import debounce from 'lodash/debounce';
import { useRecoilState } from "recoil";
import { useCommonStyles } from "../../../helpers/commonStyle"
import serviceMapModalOpenAtom from "../../../recoil/serviceMapModalOpen";
import TrafficViewer from "@up9/mizu-common"
import { TrafficViewer } from "@up9/mizu-common"
import "@up9/mizu-common/dist/index.css"
import oasModalOpenAtom from "../../../recoil/oasModalOpen/atom";
import serviceMap from "../../assets/serviceMap.svg";
import services from "../../assets/services.svg";
import trafficStatsIcon from "../../assets/trafficStats.svg";
import trafficStatsModalOpenAtom from "../../../recoil/trafficStatsModalOpen";
import { REPLAY_ENABLED } from "../../../consts";
const api = Api.getInstance();
@@ -40,39 +41,41 @@ export const TrafficPage: React.FC = () => {
}, 500);
const actionButtons = <div style={{ display: 'flex', height: "100%" }}>
{window["isOasEnabled"] && <Button
startIcon={<img className="custom" src={services} alt="services" />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
style={{ marginRight: 25, textTransform: 'unset' }}
onClick={handleOpenOasModal}>
Service Catalog
</Button>}
{window["isServiceMapEnabled"] && <Button
startIcon={<img src={serviceMap} className="custom" alt="service-map" style={{ marginRight: "8%" }} />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
onClick={openServiceMapModalDebounce}
style={{ marginRight: 25, textTransform: 'unset' }}>
Service Map
</Button>}
{window["isOasEnabled"] && <Button
startIcon={<img className="custom" src={services} alt="services" />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
style={{ marginRight: 25, textTransform: 'unset' }}
onClick={handleOpenOasModal}>
Service Catalog
</Button>}
{window["isServiceMapEnabled"] && <Button
startIcon={<img src={serviceMap} className="custom" alt="service-map" style={{ marginRight: "8%" }} />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
onClick={openServiceMapModalDebounce}
style={{ marginRight: 25, textTransform: 'unset' }}>
Service Map
</Button>}
<Button
startIcon={<img className="custom" src={trafficStatsIcon} alt="services" />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
style={{ textTransform: 'unset' }}
onClick={handleOpenStatsModal}>
startIcon={<img className="custom" src={trafficStatsIcon} alt="services" />}
size="large"
variant="contained"
className={commonClasses.outlinedButton + " " + commonClasses.imagedButton}
style={{ textTransform: 'unset' }}
onClick={handleOpenStatsModal}>
Traffic Stats
</Button>
</div>
</div>
return (
<>
<TrafficViewer webSocketUrl={MizuWebsocketURL} shouldCloseWebSocket={shouldCloseWebSocket} setShouldCloseWebSocket={setShouldCloseWebSocket}
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!(openOasModal || serviceMapModalOpen || trafficStatsModalOpen)} isDemoBannerView={false} />
trafficViewerApiProp={trafficViewerApi} actionButtons={actionButtons} isShowStatusBar={!(openOasModal || serviceMapModalOpen || trafficStatsModalOpen)} isDemoBannerView={false} entryDetailedConfig={{
isReplayEnabled: REPLAY_ENABLED
}} />
</>
);
};

View File

@@ -1,2 +1,3 @@
export const adminUsername = "admin";
export const TOAST_CONTAINER_ID = "Community";
export const REPLAY_ENABLED = true;