mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-05-03 15:57:53 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
414e5cfe5a | ||
|
|
2fac0009ea | ||
|
|
36d59ede07 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -55,4 +55,4 @@ tap/extensions/*/expect
|
|||||||
*.editorconfig
|
*.editorconfig
|
||||||
|
|
||||||
# Ignore *.log files
|
# Ignore *.log files
|
||||||
*.log
|
*.log
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ RUN go build -ldflags="-extldflags=-static -s -w \
|
|||||||
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
|
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
|
||||||
|
|
||||||
# Download Basenine executable, verify the sha1sum
|
# Download Basenine executable, verify the sha1sum
|
||||||
ADD https://github.com/up9inc/basenine/releases/download/v0.8.1/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
ADD https://github.com/up9inc/basenine/releases/download/v0.8.2/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
||||||
ADD https://github.com/up9inc/basenine/releases/download/v0.8.1/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
ADD https://github.com/up9inc/basenine/releases/download/v0.8.2/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
||||||
|
|
||||||
RUN shasum -a 256 -c basenine_linux_"${GOARCH}".sha256 && \
|
RUN shasum -a 256 -c basenine_linux_"${GOARCH}".sha256 && \
|
||||||
chmod +x ./basenine_linux_"${GOARCH}" && \
|
chmod +x ./basenine_linux_"${GOARCH}" && \
|
||||||
|
|||||||
@@ -65,70 +65,70 @@ it('right side sanity test', function () {
|
|||||||
checkIllegalFilter('invalid filter');
|
checkIllegalFilter('invalid filter');
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'http',
|
filter: 'http',
|
||||||
leftSidePath: '> :nth-child(1) > :nth-child(1)',
|
leftSidePath: '> :nth-child(1) > :nth-child(1)',
|
||||||
leftSideExpectedText: 'HTTP',
|
leftSideExpectedText: 'HTTP',
|
||||||
rightSidePath: '[title=HTTP]',
|
rightSidePath: '[title=HTTP]',
|
||||||
rightSideExpectedText: 'Hypertext Transfer Protocol -- HTTP/1.1',
|
rightSideExpectedText: 'Hypertext Transfer Protocol -- HTTP/1.1',
|
||||||
applyByEnter: true
|
applyByCtrlEnter: true
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'response.status == 200',
|
filter: 'response.status == 200',
|
||||||
leftSidePath: '[title="Status Code"]',
|
leftSidePath: '[title="Status Code"]',
|
||||||
leftSideExpectedText: '200',
|
leftSideExpectedText: '200',
|
||||||
rightSidePath: '> :nth-child(2) [title="Status Code"]',
|
rightSidePath: '> :nth-child(2) [title="Status Code"]',
|
||||||
rightSideExpectedText: '200',
|
rightSideExpectedText: '200',
|
||||||
applyByEnter: false
|
applyByCtrlEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Cypress.env('shouldCheckSrcAndDest')) {
|
if (Cypress.env('shouldCheckSrcAndDest')) {
|
||||||
serviceMapCheck();
|
serviceMapCheck();
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'src.name == ""',
|
filter: 'src.name == ""',
|
||||||
leftSidePath: '[title="Source Name"]',
|
leftSidePath: '[title="Source Name"]',
|
||||||
leftSideExpectedText: '[Unresolved]',
|
leftSideExpectedText: '[Unresolved]',
|
||||||
rightSidePath: '> :nth-child(2) [title="Source Name"]',
|
rightSidePath: '> :nth-child(2) [title="Source Name"]',
|
||||||
rightSideExpectedText: '[Unresolved]',
|
rightSideExpectedText: '[Unresolved]',
|
||||||
applyByEnter: false
|
applyByCtrlEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: `dst.name == "httpbin.mizu-tests"`,
|
filter: `dst.name == "httpbin.mizu-tests"`,
|
||||||
leftSidePath: '> :nth-child(3) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
leftSidePath: '> :nth-child(3) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
||||||
leftSideExpectedText: 'httpbin.mizu-tests',
|
leftSideExpectedText: 'httpbin.mizu-tests',
|
||||||
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
||||||
rightSideExpectedText: 'httpbin.mizu-tests',
|
rightSideExpectedText: 'httpbin.mizu-tests',
|
||||||
applyByEnter: false
|
applyByCtrlEnter: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'request.method == "GET"',
|
filter: 'request.method == "GET"',
|
||||||
leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
||||||
leftSideExpectedText: 'GET',
|
leftSideExpectedText: 'GET',
|
||||||
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
||||||
rightSideExpectedText: 'GET',
|
rightSideExpectedText: 'GET',
|
||||||
applyByEnter: true
|
applyByCtrlEnter: true
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'request.path == "/get"',
|
filter: 'request.path == "/get"',
|
||||||
leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
leftSidePath: '> :nth-child(3) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
||||||
leftSideExpectedText: '/get',
|
leftSideExpectedText: '/get',
|
||||||
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
||||||
rightSideExpectedText: '/get',
|
rightSideExpectedText: '/get',
|
||||||
applyByEnter: false
|
applyByCtrlEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'src.ip == "127.0.0.1"',
|
filter: 'src.ip == "127.0.0.1"',
|
||||||
leftSidePath: '[title="Source IP"]',
|
leftSidePath: '[title="Source IP"]',
|
||||||
leftSideExpectedText: '127.0.0.1',
|
leftSideExpectedText: '127.0.0.1',
|
||||||
rightSidePath: '> :nth-child(2) [title="Source IP"]',
|
rightSidePath: '> :nth-child(2) [title="Source IP"]',
|
||||||
rightSideExpectedText: '127.0.0.1',
|
rightSideExpectedText: '127.0.0.1',
|
||||||
applyByEnter: false
|
applyByCtrlEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilterNoResults('request.method == "POST"');
|
checkFilterNoResults('request.method == "POST"');
|
||||||
@@ -182,17 +182,19 @@ function checkIllegalFilter(illegalFilterName) {
|
|||||||
|
|
||||||
function checkFilter(filterDetails) {
|
function checkFilter(filterDetails) {
|
||||||
const {
|
const {
|
||||||
name,
|
filter,
|
||||||
leftSidePath,
|
leftSidePath,
|
||||||
rightSidePath,
|
rightSidePath,
|
||||||
rightSideExpectedText,
|
rightSideExpectedText,
|
||||||
leftSideExpectedText,
|
leftSideExpectedText,
|
||||||
applyByEnter
|
applyByCtrlEnter
|
||||||
} = filterDetails;
|
} = filterDetails;
|
||||||
|
|
||||||
const entriesForDeeperCheck = 5;
|
const entriesForDeeperCheck = 5;
|
||||||
|
|
||||||
it(`checking the filter: ${name}`, function () {
|
it(`checking the filter: ${filter}`, function () {
|
||||||
|
waitForFetch50AndPause();
|
||||||
|
|
||||||
cy.get('#total-entries').should('not.have.text', '0').then(number => {
|
cy.get('#total-entries').should('not.have.text', '0').then(number => {
|
||||||
const totalEntries = number.text();
|
const totalEntries = number.text();
|
||||||
|
|
||||||
@@ -200,21 +202,23 @@ function checkFilter(filterDetails) {
|
|||||||
const element = elem[0];
|
const element = elem[0];
|
||||||
const entryId = getEntryId(element.id);
|
const entryId = getEntryId(element.id);
|
||||||
// checks the hover on the last entry (the only one in DOM at the beginning)
|
// checks the hover on the last entry (the only one in DOM at the beginning)
|
||||||
leftOnHoverCheck(entryId, leftSidePath, name);
|
leftOnHoverCheck(entryId, leftSidePath, filter);
|
||||||
|
|
||||||
cy.get('.w-tc-editor-text').clear();
|
cy.get('.w-tc-editor-text').clear();
|
||||||
// applying the filter with alt+enter or with the button
|
// applying the filter with alt+enter or with the button
|
||||||
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
|
cy.get('.w-tc-editor-text').type(`${filter}${applyByCtrlEnter ? '{ctrl+enter}' : ''}`);
|
||||||
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
||||||
if (!applyByEnter)
|
if (!applyByCtrlEnter)
|
||||||
cy.get('[type="submit"]').click();
|
cy.get('[type="submit"]').click();
|
||||||
|
|
||||||
|
waitForFetch50AndPause();
|
||||||
|
|
||||||
// only one entry in DOM after filtering, checking all checks on it
|
// only one entry in DOM after filtering, checking all checks on it
|
||||||
leftTextCheck(entryId, leftSidePath, leftSideExpectedText);
|
leftTextCheck(entryId, leftSidePath, leftSideExpectedText);
|
||||||
leftOnHoverCheck(entryId, leftSidePath, name);
|
leftOnHoverCheck(entryId, leftSidePath, filter);
|
||||||
|
|
||||||
rightTextCheck(rightSidePath, rightSideExpectedText);
|
rightTextCheck(rightSidePath, rightSideExpectedText);
|
||||||
rightOnHoverCheck(rightSidePath, name);
|
rightOnHoverCheck(rightSidePath, filter);
|
||||||
checkRightSideResponseBody();
|
checkRightSideResponseBody();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -228,7 +232,7 @@ function checkFilter(filterDetails) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// making the other 3 checks on the first X entries (longer time for each check)
|
// making the other 3 checks on the first X entries (longer time for each check)
|
||||||
deeperCheck(leftSidePath, rightSidePath, name, leftSideExpectedText, rightSideExpectedText, entriesForDeeperCheck);
|
deeperCheck(leftSidePath, rightSidePath, filter, rightSideExpectedText, entriesForDeeperCheck);
|
||||||
|
|
||||||
// reloading then waiting for the entries number to load
|
// reloading then waiting for the entries number to load
|
||||||
resizeToNormalMizu();
|
resizeToNormalMizu();
|
||||||
@@ -238,7 +242,14 @@ function checkFilter(filterDetails) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function deeperCheck(leftSidePath, rightSidePath, filterName, leftSideExpectedText, rightSideExpectedText, entriesNumToCheck) {
|
function waitForFetch50AndPause() {
|
||||||
|
// wait half a second and pause the stream to preserve the DOM
|
||||||
|
cy.wait(500);
|
||||||
|
cy.get('#pause-icon').click();
|
||||||
|
cy.get('#pause-icon').should('not.be.visible');
|
||||||
|
}
|
||||||
|
|
||||||
|
function deeperCheck(leftSidePath, rightSidePath, filterName, rightSideExpectedText, entriesNumToCheck) {
|
||||||
cy.get(`#list [id^=entry]`).each((element, index) => {
|
cy.get(`#list [id^=entry]`).each((element, index) => {
|
||||||
if (index < entriesNumToCheck) {
|
if (index < entriesNumToCheck) {
|
||||||
const entryId = getEntryId(element[0].id);
|
const entryId = getEntryId(element[0].id);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ require (
|
|||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/orcaman/concurrent-map v1.0.0
|
github.com/orcaman/concurrent-map v1.0.0
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220508080324-c66c4e1b9337
|
github.com/up9inc/basenine/client/go v0.0.0-20220509204026-c37adfc587f4
|
||||||
github.com/up9inc/mizu/logger v0.0.0
|
github.com/up9inc/mizu/logger v0.0.0
|
||||||
github.com/up9inc/mizu/shared v0.0.0
|
github.com/up9inc/mizu/shared v0.0.0
|
||||||
github.com/up9inc/mizu/tap v0.0.0
|
github.com/up9inc/mizu/tap v0.0.0
|
||||||
|
|||||||
@@ -683,8 +683,8 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn
|
|||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220508080324-c66c4e1b9337 h1:eRXRZnojrZyhbiSuGHl0EPvFtWvx1ZMrsY/bSoBzYNE=
|
github.com/up9inc/basenine/client/go v0.0.0-20220509204026-c37adfc587f4 h1:nNOrU1HVH0fnaG7GNhxCc8kNPVL035Iix7ihUF6lZT8=
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220508080324-c66c4e1b9337/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
|
github.com/up9inc/basenine/client/go v0.0.0-20220509204026-c37adfc587f4/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
|
||||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/wI2L/jsondiff v0.1.1 h1:r2TkoEet7E4JMO5+s1RCY2R0LrNPNHY6hbDeow2hRHw=
|
github.com/wI2L/jsondiff v0.1.1 h1:r2TkoEet7E4JMO5+s1RCY2R0LrNPNHY6hbDeow2hRHw=
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func (g *defaultOasGenerator) runGenerator() {
|
|||||||
g.dbMutex.Lock()
|
g.dbMutex.Lock()
|
||||||
defer g.dbMutex.Unlock()
|
defer g.dbMutex.Unlock()
|
||||||
logger.Log.Infof("Querying DB for OAS generator with query '%s'", g.entriesQuery)
|
logger.Log.Infof("Querying DB for OAS generator with query '%s'", g.entriesQuery)
|
||||||
if err := g.dbConn.Query("", g.entriesQuery, dataChan, metaChan); err != nil {
|
if err := g.dbConn.Query("latest", g.entriesQuery, dataChan, metaChan); err != nil {
|
||||||
logger.Log.Errorf("Query mode call failed: %v", err)
|
logger.Log.Errorf("Query mode call failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ BasenineReconnect:
|
|||||||
go handleMetaChannel(&wg, connection, meta)
|
go handleMetaChannel(&wg, connection, meta)
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
if err = connection.Query("", query, data, meta); err != nil {
|
if err = connection.Query("latest", query, data, meta); err != nil {
|
||||||
logger.Log.Errorf("Query mode call failed: %v", err)
|
logger.Log.Errorf("Query mode call failed: %v", err)
|
||||||
connection.Close()
|
connection.Close()
|
||||||
time.Sleep(shared.BasenineReconnectInterval * time.Second)
|
time.Sleep(shared.BasenineReconnectInterval * time.Second)
|
||||||
|
|||||||
@@ -96,8 +96,3 @@
|
|||||||
|
|
||||||
& .servicesFilterList
|
& .servicesFilterList
|
||||||
height: calc(100% - 30px - 52px)
|
height: calc(100% - 30px - 52px)
|
||||||
|
|
||||||
.totalSelected
|
|
||||||
font-size: 12px
|
|
||||||
color: $light-blue-color
|
|
||||||
font-weight: 700
|
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onClos
|
|||||||
const [checkedProtocols, setCheckedProtocols] = useState([])
|
const [checkedProtocols, setCheckedProtocols] = useState([])
|
||||||
const [checkedServices, setCheckedServices] = useState([])
|
const [checkedServices, setCheckedServices] = useState([])
|
||||||
const [serviceMapApiData, setServiceMapApiData] = useState<ServiceMapGraph>({ edges: [], nodes: [] })
|
const [serviceMapApiData, setServiceMapApiData] = useState<ServiceMapGraph>({ edges: [], nodes: [] })
|
||||||
const [servicesSearchVal, setServicesSearchVal] = useState("")
|
|
||||||
const [graphOptions, setGraphOptions] = useState(ServiceMapOptions);
|
const [graphOptions, setGraphOptions] = useState(ServiceMapOptions);
|
||||||
const [isFilterClicked, setIsFilterClicked] = useState(true)
|
const [isFilterClicked, setIsFilterClicked] = useState(true)
|
||||||
|
|
||||||
@@ -219,22 +218,14 @@ export const ServiceMapModal: React.FC<ServiceMapModalProps> = ({ isOpen, onClos
|
|||||||
<Resizeable minWidth={170} maxWidth={320}>
|
<Resizeable minWidth={170} maxWidth={320}>
|
||||||
<div className={styles.filterWrapper}>
|
<div className={styles.filterWrapper}>
|
||||||
<div className={styles.protocolsFilterList}>
|
<div className={styles.protocolsFilterList}>
|
||||||
<h3 className={styles.subSectionHeader} style={{ marginLeft: "10px" }}>
|
<SelectList items={getProtocolsForFilter} checkBoxWidth="5%" tableName={"PROTOCOLS"} multiSelect={true}
|
||||||
PROTOCOLS
|
checkedValues={checkedProtocols} setCheckedValues={onProtocolsChange} tableClassName={styles.filters}
|
||||||
<span className={styles.totalSelected}> ({checkedProtocols.length})</span>
|
inputSearchClass={styles.servicesFilterSearch} isFilterable={false}/>
|
||||||
</h3>
|
|
||||||
<SelectList items={getProtocolsForFilter} checkBoxWidth="5%" tableName={"All"} multiSelect={true}
|
|
||||||
checkedValues={checkedProtocols} setCheckedValues={onProtocolsChange} tableClassName={styles.filters} />
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.servicesFilter}>
|
<div className={styles.servicesFilter}>
|
||||||
<h3 className={styles.subSectionHeader} style={{ marginLeft: "10px" }}>
|
<div className={styles.servicesFilterList}>
|
||||||
SERVICES
|
<SelectList items={getServicesForFilter} tableName={"SERVICES"} tableClassName={styles.filters} multiSelect={true}
|
||||||
<span className={styles.totalSelected}> ({checkedServices.length})</span>
|
checkBoxWidth="5%" checkedValues={checkedServices} setCheckedValues={onServiceChanges} inputSearchClass={styles.servicesFilterSearch}/>
|
||||||
</h3>
|
|
||||||
<input className={commonClasses.textField + ` ${styles.servicesFilterSearch}`} placeholder="Search" value={servicesSearchVal} onChange={(event) => setServicesSearchVal(event.target.value)} />
|
|
||||||
<div className={styles.servicesFilterList}>
|
|
||||||
<SelectList items={getServicesForFilter} tableName={"All"} tableClassName={styles.filters} multiSelect={true} searchValue={servicesSearchVal}
|
|
||||||
checkBoxWidth="5%" checkedValues={checkedServices} setCheckedValues={onServiceChanges} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -245,13 +245,18 @@ export const TrafficViewer: React.FC<TrafficViewerProps> = ({
|
|||||||
{tappingStatus && isShowStatusBar && <StatusBar disabled={ws?.current?.readyState !== WebSocket.OPEN} isDemoBannerView={isDemoBannerView}/>}
|
{tappingStatus && isShowStatusBar && <StatusBar disabled={ws?.current?.readyState !== WebSocket.OPEN} isDemoBannerView={isDemoBannerView}/>}
|
||||||
<div className={TrafficViewerStyles.TrafficPageHeader}>
|
<div className={TrafficViewerStyles.TrafficPageHeader}>
|
||||||
<div className={TrafficViewerStyles.TrafficPageStreamStatus}>
|
<div className={TrafficViewerStyles.TrafficPageStreamStatus}>
|
||||||
<img className={TrafficViewerStyles.playPauseIcon}
|
<img id="pause-icon"
|
||||||
style={{visibility: wsReadyState === WebSocket.OPEN ? "visible" : "hidden"}} alt="pause"
|
className={TrafficViewerStyles.playPauseIcon}
|
||||||
src={pauseIcon} onClick={toggleConnection}/>
|
style={{visibility: wsReadyState === WebSocket.OPEN ? "visible" : "hidden"}}
|
||||||
<img className={TrafficViewerStyles.playPauseIcon}
|
alt="pause"
|
||||||
|
src={pauseIcon}
|
||||||
|
onClick={toggleConnection}/>
|
||||||
|
<img id="play-icon"
|
||||||
|
className={TrafficViewerStyles.playPauseIcon}
|
||||||
style={{position: "absolute", visibility: wsReadyState === WebSocket.OPEN ? "hidden" : "visible"}}
|
style={{position: "absolute", visibility: wsReadyState === WebSocket.OPEN ? "hidden" : "visible"}}
|
||||||
alt="play"
|
alt="play"
|
||||||
src={playIcon} onClick={toggleConnection}/>
|
src={playIcon}
|
||||||
|
onClick={toggleConnection}/>
|
||||||
<div className={TrafficViewerStyles.connectionText}>
|
<div className={TrafficViewerStyles.connectionText}>
|
||||||
{getConnectionTitle()}
|
{getConnectionTitle()}
|
||||||
{getConnectionIndicator()}
|
{getConnectionIndicator()}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Radio from "./Radio";
|
|||||||
import styles from './style/SelectList.module.sass'
|
import styles from './style/SelectList.module.sass'
|
||||||
import NoDataMessage from "./NoDataMessage";
|
import NoDataMessage from "./NoDataMessage";
|
||||||
import Checkbox from "./Checkbox";
|
import Checkbox from "./Checkbox";
|
||||||
|
import { useCommonStyles } from "../../helpers/commonStyle";
|
||||||
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -10,14 +11,17 @@ export interface Props {
|
|||||||
tableName: string;
|
tableName: string;
|
||||||
checkedValues?: string[];
|
checkedValues?: string[];
|
||||||
multiSelect: boolean;
|
multiSelect: boolean;
|
||||||
searchValue?: string;
|
|
||||||
setCheckedValues: (newValues) => void;
|
setCheckedValues: (newValues) => void;
|
||||||
tableClassName?
|
tableClassName?;
|
||||||
checkBoxWidth?: string
|
checkBoxWidth?: string;
|
||||||
|
inputSearchClass? : string
|
||||||
|
isFilterable? : boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const SelectList: React.FC<Props> = ({ items, tableName, checkedValues = [], multiSelect = true, searchValue = "", setCheckedValues, tableClassName,
|
const SelectList: React.FC<Props> = ({ items, tableName, checkedValues = [], multiSelect = true, setCheckedValues, tableClassName,
|
||||||
checkBoxWidth = 50 }) => {
|
checkBoxWidth = 50 ,inputSearchClass,isFilterable = true}) => {
|
||||||
|
const commonClasses = useCommonStyles();
|
||||||
|
const [searchValue, setSearchValue] = useState("")
|
||||||
const noItemsMessage = "No items to show";
|
const noItemsMessage = "No items to show";
|
||||||
const [headerChecked, setHeaderChecked] = useState(false)
|
const [headerChecked, setHeaderChecked] = useState(false)
|
||||||
|
|
||||||
@@ -73,11 +77,10 @@ const SelectList: React.FC<Props> = ({ items, tableName, checkedValues = [], mul
|
|||||||
<th style={{ width: checkBoxWidth }}><Checkbox data-cy="checkbox-all" checked={headerChecked}
|
<th style={{ width: checkBoxWidth }}><Checkbox data-cy="checkbox-all" checked={headerChecked}
|
||||||
onToggle={(isChecked) => toggleAll(isChecked)} /></th>
|
onToggle={(isChecked) => toggleAll(isChecked)} /></th>
|
||||||
<th>
|
<th>
|
||||||
{tableName}
|
All
|
||||||
</th>
|
</th>
|
||||||
</tr> :
|
</tr> :
|
||||||
<tr style={{ borderBottomWidth: "2px" }}>
|
<tr>
|
||||||
<th>{tableName}</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
const tableBody = filteredValues.length === 0 ?
|
const tableBody = filteredValues.length === 0 ?
|
||||||
@@ -100,7 +103,14 @@ const SelectList: React.FC<Props> = ({ items, tableName, checkedValues = [], mul
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return <div className={tableClassName ? tableClassName + ` ${styles.selectListTable}` : ` ${styles.selectListTable}`}>
|
return <React.Fragment>
|
||||||
|
<h3 className={styles.subSectionHeader}>
|
||||||
|
{tableName}
|
||||||
|
<span className={styles.totalSelected}> ({checkedValues.length})</span>
|
||||||
|
</h3>
|
||||||
|
{isFilterable && <input className={commonClasses.textField + ` ${inputSearchClass}`} placeholder="Search" value={searchValue}
|
||||||
|
onChange={(event) => setSearchValue(event.target.value)} data-cy="searchInput" />}
|
||||||
|
<div className={tableClassName ? tableClassName + ` ${styles.selectListTable}` : ` ${styles.selectListTable}`} style={{marginTop: !multiSelect ? "20px": ""}}>
|
||||||
<table cellPadding={5} style={{ borderCollapse: "collapse" }}>
|
<table cellPadding={5} style={{ borderCollapse: "collapse" }}>
|
||||||
<thead>
|
<thead>
|
||||||
{tableHead}
|
{tableHead}
|
||||||
@@ -110,6 +120,7 @@ const SelectList: React.FC<Props> = ({ items, tableName, checkedValues = [], mul
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SelectList;
|
export default SelectList;
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
@import '../../../variables.module'
|
@import '../../../variables.module'
|
||||||
|
@import '../../../components'
|
||||||
|
|
||||||
|
|
||||||
.selectListTable
|
.selectListTable
|
||||||
overflow: auto
|
overflow: auto
|
||||||
@@ -17,6 +19,7 @@
|
|||||||
position: sticky
|
position: sticky
|
||||||
top: 0
|
top: 0
|
||||||
background: $main-background-color
|
background: $main-background-color
|
||||||
|
font-size: 12px
|
||||||
|
|
||||||
tr
|
tr
|
||||||
border-bottom-width: 1px
|
border-bottom-width: 1px
|
||||||
@@ -27,7 +30,15 @@
|
|||||||
td
|
td
|
||||||
color: $light-gray
|
color: $light-gray
|
||||||
padding: 10px
|
padding: 10px
|
||||||
font-size: 16px
|
font-size: 11px
|
||||||
|
font-weight: 600
|
||||||
|
padding-top: 5px
|
||||||
|
padding-bottom: 5px
|
||||||
|
|
||||||
.nowrap
|
.nowrap
|
||||||
white-space: nowrap
|
white-space: nowrap
|
||||||
|
|
||||||
|
.totalSelected
|
||||||
|
font-size: 12px
|
||||||
|
color: $light-blue-color
|
||||||
|
font-weight: 700
|
||||||
|
|||||||
Reference in New Issue
Block a user