mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-08-08 03:54:18 +00:00
Make ScrollableFeed
virtualized by replacing react-scrollable-feed
with react-scrollable-feed-virtualized
(#268)
* Make `ScrollableFeed` virtualized by replacing `react-scrollable-feed` with `react-scrollable-feed-virtualized` * fix get new entries button * Fix the not populated `Protocol` struct in case of `GetEntries` endpoint is called Co-authored-by: Liraz Yehezkel <lirazy@up9.com>
This commit is contained in:
parent
30f07479cb
commit
616eccb2cf
@ -102,8 +102,14 @@ type MizuEntry struct {
|
|||||||
ID uint `gorm:"primarykey"`
|
ID uint `gorm:"primarykey"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
ProtocolName string `json:"protocolKey" gorm:"column:protocolKey"`
|
ProtocolName string `json:"protocolName" gorm:"column:protocolName"`
|
||||||
|
ProtocolLongName string `json:"protocolLongName" gorm:"column:protocolLongName"`
|
||||||
|
ProtocolAbbreviation string `json:"protocolAbbreviation" gorm:"column:protocolVersion"`
|
||||||
ProtocolVersion string `json:"protocolVersion" gorm:"column:protocolVersion"`
|
ProtocolVersion string `json:"protocolVersion" gorm:"column:protocolVersion"`
|
||||||
|
ProtocolBackgroundColor string `json:"protocolBackgroundColor" gorm:"column:protocolBackgroundColor"`
|
||||||
|
ProtocolForegroundColor string `json:"protocolForegroundColor" gorm:"column:protocolForegroundColor"`
|
||||||
|
ProtocolFontSize int8 `json:"protocolFontSize" gorm:"column:protocolFontSize"`
|
||||||
|
ProtocolReferenceLink string `json:"protocolReferenceLink" gorm:"column:protocolReferenceLink"`
|
||||||
Entry string `json:"entry,omitempty" gorm:"column:entry"`
|
Entry string `json:"entry,omitempty" gorm:"column:entry"`
|
||||||
EntryId string `json:"entryId" gorm:"column:entryId"`
|
EntryId string `json:"entryId" gorm:"column:entryId"`
|
||||||
Url string `json:"url" gorm:"column:url"`
|
Url string `json:"url" gorm:"column:url"`
|
||||||
@ -162,11 +168,19 @@ type DataUnmarshaler interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bed *BaseEntryDetails) UnmarshalData(entry *MizuEntry) error {
|
func (bed *BaseEntryDetails) UnmarshalData(entry *MizuEntry) error {
|
||||||
entryUrl := entry.Url
|
bed.Protocol = Protocol{
|
||||||
service := entry.Service
|
Name: entry.ProtocolName,
|
||||||
|
LongName: entry.ProtocolLongName,
|
||||||
|
Abbreviation: entry.ProtocolAbbreviation,
|
||||||
|
Version: entry.ProtocolVersion,
|
||||||
|
BackgroundColor: entry.ProtocolBackgroundColor,
|
||||||
|
ForegroundColor: entry.ProtocolForegroundColor,
|
||||||
|
FontSize: entry.ProtocolFontSize,
|
||||||
|
ReferenceLink: entry.ProtocolReferenceLink,
|
||||||
|
}
|
||||||
bed.Id = entry.EntryId
|
bed.Id = entry.EntryId
|
||||||
bed.Url = entryUrl
|
bed.Url = entry.Url
|
||||||
bed.Service = service
|
bed.Service = entry.Service
|
||||||
bed.Summary = entry.Path
|
bed.Summary = entry.Path
|
||||||
bed.StatusCode = entry.Status
|
bed.StatusCode = entry.Status
|
||||||
bed.Method = entry.Method
|
bed.Method = entry.Method
|
||||||
|
@ -268,7 +268,13 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
|||||||
entryBytes, _ := json.Marshal(item.Pair)
|
entryBytes, _ := json.Marshal(item.Pair)
|
||||||
return &api.MizuEntry{
|
return &api.MizuEntry{
|
||||||
ProtocolName: protocol.Name,
|
ProtocolName: protocol.Name,
|
||||||
|
ProtocolLongName: protocol.LongName,
|
||||||
|
ProtocolAbbreviation: protocol.Abbreviation,
|
||||||
ProtocolVersion: protocol.Version,
|
ProtocolVersion: protocol.Version,
|
||||||
|
ProtocolBackgroundColor: protocol.BackgroundColor,
|
||||||
|
ProtocolForegroundColor: protocol.ForegroundColor,
|
||||||
|
ProtocolFontSize: protocol.FontSize,
|
||||||
|
ProtocolReferenceLink: protocol.ReferenceLink,
|
||||||
EntryId: entryId,
|
EntryId: entryId,
|
||||||
Entry: string(entryBytes),
|
Entry: string(entryBytes),
|
||||||
Url: fmt.Sprintf("%s%s", service, summary),
|
Url: fmt.Sprintf("%s%s", service, summary),
|
||||||
|
@ -173,7 +173,13 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
|||||||
entryBytes, _ := json.Marshal(item.Pair)
|
entryBytes, _ := json.Marshal(item.Pair)
|
||||||
return &api.MizuEntry{
|
return &api.MizuEntry{
|
||||||
ProtocolName: protocol.Name,
|
ProtocolName: protocol.Name,
|
||||||
|
ProtocolLongName: protocol.LongName,
|
||||||
|
ProtocolAbbreviation: protocol.Abbreviation,
|
||||||
ProtocolVersion: item.Protocol.Version,
|
ProtocolVersion: item.Protocol.Version,
|
||||||
|
ProtocolBackgroundColor: protocol.BackgroundColor,
|
||||||
|
ProtocolForegroundColor: protocol.ForegroundColor,
|
||||||
|
ProtocolFontSize: protocol.FontSize,
|
||||||
|
ProtocolReferenceLink: protocol.ReferenceLink,
|
||||||
EntryId: entryId,
|
EntryId: entryId,
|
||||||
Entry: string(entryBytes),
|
Entry: string(entryBytes),
|
||||||
Url: fmt.Sprintf("%s%s", service, path),
|
Url: fmt.Sprintf("%s%s", service, path),
|
||||||
|
@ -143,7 +143,13 @@ func (d dissecting) Analyze(item *api.OutputChannelItem, entryId string, resolve
|
|||||||
entryBytes, _ := json.Marshal(item.Pair)
|
entryBytes, _ := json.Marshal(item.Pair)
|
||||||
return &api.MizuEntry{
|
return &api.MizuEntry{
|
||||||
ProtocolName: _protocol.Name,
|
ProtocolName: _protocol.Name,
|
||||||
|
ProtocolLongName: _protocol.LongName,
|
||||||
|
ProtocolAbbreviation: _protocol.Abbreviation,
|
||||||
ProtocolVersion: _protocol.Version,
|
ProtocolVersion: _protocol.Version,
|
||||||
|
ProtocolBackgroundColor: _protocol.BackgroundColor,
|
||||||
|
ProtocolForegroundColor: _protocol.ForegroundColor,
|
||||||
|
ProtocolFontSize: _protocol.FontSize,
|
||||||
|
ProtocolReferenceLink: _protocol.ReferenceLink,
|
||||||
EntryId: entryId,
|
EntryId: entryId,
|
||||||
Entry: string(entryBytes),
|
Entry: string(entryBytes),
|
||||||
Url: fmt.Sprintf("%s%s", service, summary),
|
Url: fmt.Sprintf("%s%s", service, summary),
|
||||||
|
22792
ui/package-lock.json
generated
22792
ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,8 +12,8 @@
|
|||||||
"@types/node": "^12.20.10",
|
"@types/node": "^12.20.10",
|
||||||
"@types/react": "^17.0.3",
|
"@types/react": "^17.0.3",
|
||||||
"@types/react-dom": "^17.0.3",
|
"@types/react-dom": "^17.0.3",
|
||||||
"jsonpath": "^1.1.1",
|
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.21.1",
|
||||||
|
"jsonpath": "^1.1.1",
|
||||||
"node-sass": "^5.0.0",
|
"node-sass": "^5.0.0",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"protobuf-decoder": "^0.1.0",
|
"protobuf-decoder": "^0.1.0",
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"react-copy-to-clipboard": "^5.0.3",
|
"react-copy-to-clipboard": "^5.0.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-scripts": "4.0.3",
|
"react-scripts": "4.0.3",
|
||||||
"react-scrollable-feed": "^1.3.0",
|
"react-scrollable-feed-virtualized": "^1.4.2",
|
||||||
"react-syntax-highlighter": "^15.4.3",
|
"react-syntax-highlighter": "^15.4.3",
|
||||||
"typescript": "^4.2.4",
|
"typescript": "^4.2.4",
|
||||||
"web-vitals": "^1.1.1"
|
"web-vitals": "^1.1.1"
|
||||||
|
@ -2,7 +2,7 @@ import {EntryItem} from "./EntryListItem/EntryListItem";
|
|||||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from "react";
|
import React, {useCallback, useEffect, useMemo, useRef, useState} from "react";
|
||||||
import styles from './style/EntriesList.module.sass';
|
import styles from './style/EntriesList.module.sass';
|
||||||
import spinner from './assets/spinner.svg';
|
import spinner from './assets/spinner.svg';
|
||||||
import ScrollableFeed from "react-scrollable-feed";
|
import ScrollableFeedVirtualized from "react-scrollable-feed-virtualized";
|
||||||
import {StatusType} from "./Filters";
|
import {StatusType} from "./Filters";
|
||||||
import Api from "../helpers/api";
|
import Api from "../helpers/api";
|
||||||
import down from "./assets/downImg.svg";
|
import down from "./assets/downImg.svg";
|
||||||
@ -77,9 +77,6 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
|||||||
}
|
}
|
||||||
setIsLoadingTop(false);
|
setIsLoadingTop(false);
|
||||||
const newEntries = [...data, ...entries];
|
const newEntries = [...data, ...entries];
|
||||||
if(newEntries.length >= 1000) {
|
|
||||||
newEntries.splice(1000);
|
|
||||||
}
|
|
||||||
setEntries(newEntries);
|
setEntries(newEntries);
|
||||||
|
|
||||||
if(scrollTo) {
|
if(scrollTo) {
|
||||||
@ -100,10 +97,6 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
|||||||
}
|
}
|
||||||
scrollTo = document.getElementById(filteredEntries?.[filteredEntries.length -1]?.id);
|
scrollTo = document.getElementById(filteredEntries?.[filteredEntries.length -1]?.id);
|
||||||
let newEntries = [...entries, ...data];
|
let newEntries = [...entries, ...data];
|
||||||
if(newEntries.length >= 1000) {
|
|
||||||
setNoMoreDataTop(false);
|
|
||||||
newEntries = newEntries.slice(-1000);
|
|
||||||
}
|
|
||||||
setEntries(newEntries);
|
setEntries(newEntries);
|
||||||
if(scrollTo) {
|
if(scrollTo) {
|
||||||
scrollTo.scrollIntoView({behavior: "smooth"});
|
scrollTo.scrollIntoView({behavior: "smooth"});
|
||||||
@ -116,19 +109,20 @@ export const EntriesList: React.FC<EntriesListProps> = ({entries, setEntries, fo
|
|||||||
{isLoadingTop && <div className={styles.spinnerContainer}>
|
{isLoadingTop && <div className={styles.spinnerContainer}>
|
||||||
<img alt="spinner" src={spinner} style={{height: 25}}/>
|
<img alt="spinner" src={spinner} style={{height: 25}}/>
|
||||||
</div>}
|
</div>}
|
||||||
<ScrollableFeed ref={scrollableRef} onScroll={(isAtBottom) => onScrollEvent(isAtBottom)}>
|
<ScrollableFeedVirtualized ref={scrollableRef} itemHeight={48} marginTop={10} onScroll={(isAtBottom) => onScrollEvent(isAtBottom)}>
|
||||||
{noMoreDataTop && !connectionOpen && <div id="noMoreDataTop" className={styles.noMoreDataAvailable}>No more data available</div>}
|
{noMoreDataTop && !connectionOpen && <div id="noMoreDataTop" className={styles.noMoreDataAvailable}>No more data available</div>}
|
||||||
{filteredEntries.map(entry => <EntryItem key={entry.id}
|
{filteredEntries.map(entry => <EntryItem key={entry.id}
|
||||||
entry={entry}
|
entry={entry}
|
||||||
setFocusedEntryId={setFocusedEntryId}
|
setFocusedEntryId={setFocusedEntryId}
|
||||||
isSelected={focusedEntryId === entry.id}/>)}
|
isSelected={focusedEntryId === entry.id}
|
||||||
|
style={{}}/>)}
|
||||||
|
</ScrollableFeedVirtualized>
|
||||||
{!connectionOpen && !noMoreDataBottom && <div className={styles.fetchButtonContainer}>
|
{!connectionOpen && !noMoreDataBottom && <div className={styles.fetchButtonContainer}>
|
||||||
<div className={styles.styledButton} onClick={() => getNewEntries()}>Fetch more entries</div>
|
<div className={styles.styledButton} onClick={() => getNewEntries()}>Fetch more entries</div>
|
||||||
</div>}
|
</div>}
|
||||||
</ScrollableFeed>
|
|
||||||
<button type="button"
|
<button type="button"
|
||||||
className={`${styles.btnLive} ${scrollableList ? styles.showButton : styles.hideButton}`}
|
className={`${styles.btnLive} ${scrollableList ? styles.showButton : styles.hideButton}`}
|
||||||
onClick={(_) => scrollableRef.current.scrollToBottom()}>
|
onClick={(_) => scrollableRef.current.jumpToBottom()}>
|
||||||
<img alt="down" src={down} />
|
<img alt="down" src={down} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,9 +38,10 @@ interface EntryProps {
|
|||||||
entry: Entry;
|
entry: Entry;
|
||||||
setFocusedEntryId: (id: string) => void;
|
setFocusedEntryId: (id: string) => void;
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
|
style: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected}) => {
|
export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSelected, style}) => {
|
||||||
const classification = getClassification(entry.statusCode)
|
const classification = getClassification(entry.statusCode)
|
||||||
let ingoingIcon;
|
let ingoingIcon;
|
||||||
let outgoingIcon;
|
let outgoingIcon;
|
||||||
@ -103,7 +104,13 @@ export const EntryItem: React.FC<EntryProps> = ({entry, setFocusedEntryId, isSel
|
|||||||
className={`${styles.row}
|
className={`${styles.row}
|
||||||
${isSelected ? styles.rowSelected : backgroundColor}`}
|
${isSelected ? styles.rowSelected : backgroundColor}`}
|
||||||
onClick={() => setFocusedEntryId(entry.id)}
|
onClick={() => setFocusedEntryId(entry.id)}
|
||||||
style={{border: isSelected ? `1px ${entry.protocol.backgroundColor} solid` : "1px transparent solid"}}
|
style={{
|
||||||
|
border: isSelected ? `1px ${entry.protocol.backgroundColor} solid` : "1px transparent solid",
|
||||||
|
position: "absolute",
|
||||||
|
top: style['top'],
|
||||||
|
marginTop: style['marginTop'],
|
||||||
|
width: "calc(100% - 25px)",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Protocol protocol={entry.protocol} horizontal={false}/>
|
<Protocol protocol={entry.protocol} horizontal={false}/>
|
||||||
{((entry.protocol.name === "http" && "statusCode" in entry) || entry.statusCode !== 0) && <div>
|
{((entry.protocol.name === "http" && "statusCode" in entry) || entry.statusCode !== 0) && <div>
|
||||||
|
@ -86,10 +86,6 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus, onTLS
|
|||||||
}
|
}
|
||||||
if (!focusedEntryId) setFocusedEntryId(entry.id)
|
if (!focusedEntryId) setFocusedEntryId(entry.id)
|
||||||
let newEntries = [...entries];
|
let newEntries = [...entries];
|
||||||
if (entries.length === 1000) {
|
|
||||||
newEntries = newEntries.splice(1);
|
|
||||||
setNoMoreDataTop(false);
|
|
||||||
}
|
|
||||||
setEntries([...newEntries, entry])
|
setEntries([...newEntries, entry])
|
||||||
if(listEntry.current) {
|
if(listEntry.current) {
|
||||||
if(isScrollable(listEntry.current.firstChild)) {
|
if(isScrollable(listEntry.current.firstChild)) {
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
flex-direction: column
|
flex-direction: column
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
flex-grow: 1
|
flex-grow: 1
|
||||||
padding-top: 20px
|
|
||||||
|
|
||||||
.footer
|
.footer
|
||||||
display: flex
|
display: flex
|
||||||
|
Loading…
Reference in New Issue
Block a user