mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-06-09 01:36:52 +00:00
Compare commits
9 Commits
31.0-dev52
...
31.0-dev61
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e03db7b09b | ||
|
|
de533730d3 | ||
|
|
d834fcc3cb | ||
|
|
1624b0d7b9 | ||
|
|
9715bb046b | ||
|
|
65e5ebe23c | ||
|
|
30986c3b22 | ||
|
|
1e167f2757 | ||
|
|
149e86d050 |
38
.github/workflows/acceptance_tests_on_pr.yml
vendored
Normal file
38
.github/workflows/acceptance_tests_on_pr.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
name: Acceptance tests on PR
|
||||||
|
|
||||||
|
on: push
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: acceptance-tests-on-pr-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-tests:
|
||||||
|
name: Run tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ contains(github.event.head_commit.message, '#run_acceptance_tests') }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up Go 1.17
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: '^1.17'
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup acceptance test
|
||||||
|
run: ./acceptanceTests/setup.sh
|
||||||
|
|
||||||
|
- name: Create k8s users and change context
|
||||||
|
env:
|
||||||
|
USERNAME_UNRESTRICTED: user-with-clusterwide-access
|
||||||
|
USERNAME_RESTRICTED: user-with-restricted-access
|
||||||
|
run: |
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_UNRESTRICTED}"
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_RESTRICTED}"
|
||||||
|
kubectl apply -f cli/cmd/permissionFiles/permissions-all-namespaces-tap.yaml
|
||||||
|
kubectl config use-context ${USERNAME_UNRESTRICTED}
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: make acceptance-test
|
||||||
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Check extensions modified files
|
- name: Check extensions modified files
|
||||||
id: ext_modified_files
|
id: ext_modified_files
|
||||||
run: devops/check_modified_files.sh tap/extensions/
|
run: devops/check_modified_files.sh tap/extensions/ tap/api/
|
||||||
|
|
||||||
- name: Extensions Test
|
- name: Extensions Test
|
||||||
if: github.event_name == 'push' || steps.ext_modified_files.outputs.matched == 'true'
|
if: github.event_name == 'push' || steps.ext_modified_files.outputs.matched == 'true'
|
||||||
@@ -64,4 +64,3 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
|
|
||||||
|
|||||||
@@ -87,8 +87,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.7.2/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
ADD https://github.com/up9inc/basenine/releases/download/v0.7.3/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
||||||
ADD https://github.com/up9inc/basenine/releases/download/v0.7.2/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
ADD https://github.com/up9inc/basenine/releases/download/v0.7.3/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}" && \
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ require (
|
|||||||
github.com/nav-inc/datetime v0.1.3
|
github.com/nav-inc/datetime v0.1.3
|
||||||
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/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220413173135-69508ca741d7
|
github.com/up9inc/basenine/client/go v0.0.0-20220419100955-e2ca51087607
|
||||||
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
|
||||||
github.com/up9inc/mizu/tap/api v0.0.0
|
github.com/up9inc/mizu/tap/api v0.0.0
|
||||||
|
|||||||
@@ -681,8 +681,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-20220413173135-69508ca741d7 h1:9aciby1Byjn50gVXpOuvWSe48GdSK1uS2bcBKMZYHKI=
|
github.com/up9inc/basenine/client/go v0.0.0-20220419100955-e2ca51087607 h1:UqxUSkOYOmsLZWQtMSk02ttnhdRwBRLOLt2aDiS9tEk=
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220413173135-69508ca741d7/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
|
github.com/up9inc/basenine/client/go v0.0.0-20220419100955-e2ca51087607/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=
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package entries
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
basenine "github.com/up9inc/basenine/client/go"
|
basenine "github.com/up9inc/basenine/client/go"
|
||||||
@@ -64,7 +65,7 @@ func (e *BasenineEntriesProvider) GetEntry(singleEntryRequest *models.SingleEntr
|
|||||||
}
|
}
|
||||||
err = json.Unmarshal(bytes, &entry)
|
err = json.Unmarshal(bytes, &entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.New(string(bytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
extension := app.ExtensionsMap[entry.Protocol.Name]
|
extension := app.ExtensionsMap[entry.Protocol.Name]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ require (
|
|||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/spf13/cobra v1.3.0
|
github.com/spf13/cobra v1.3.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/up9inc/basenine/server/lib v0.0.0-20220413173135-69508ca741d7
|
github.com/up9inc/basenine/server/lib v0.0.0-20220419100955-e2ca51087607
|
||||||
github.com/up9inc/mizu/shared v0.0.0
|
github.com/up9inc/mizu/shared v0.0.0
|
||||||
github.com/up9inc/mizu/tap/api v0.0.0
|
github.com/up9inc/mizu/tap/api v0.0.0
|
||||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
|
|||||||
@@ -600,8 +600,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69
|
|||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/up9inc/basenine/server/lib v0.0.0-20220413173135-69508ca741d7 h1:3Mi+0tQFVHXYcrFhwH/h6/2b0tayLcYeFPXyzDV3rvc=
|
github.com/up9inc/basenine/server/lib v0.0.0-20220419100955-e2ca51087607 h1:gCOwbfjsLslDw63yj/3l9d5TH7ikhIWHd7j0lE9U26U=
|
||||||
github.com/up9inc/basenine/server/lib v0.0.0-20220413173135-69508ca741d7/go.mod h1:v0hIh31iwDGbkkdeSSppdMNm1oIigfCA2mG2XajKnf8=
|
github.com/up9inc/basenine/server/lib v0.0.0-20220419100955-e2ca51087607/go.mod h1:v0hIh31iwDGbkkdeSSppdMNm1oIigfCA2mG2XajKnf8=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||||
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
||||||
|
|||||||
@@ -805,14 +805,20 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
|
|||||||
agentResources := applyconfcore.ResourceRequirements().WithRequests(agentResourceRequests).WithLimits(agentResourceLimits)
|
agentResources := applyconfcore.ResourceRequirements().WithRequests(agentResourceRequests).WithLimits(agentResourceLimits)
|
||||||
agentContainer.WithResources(agentResources)
|
agentContainer.WithResources(agentResources)
|
||||||
|
|
||||||
nodeSelectorRequirement := applyconfcore.NodeSelectorRequirement()
|
matchFields := make([]*applyconfcore.NodeSelectorTermApplyConfiguration, 0)
|
||||||
nodeSelectorRequirement.WithKey("kubernetes.io/hostname")
|
for _, nodeName := range nodeNames {
|
||||||
nodeSelectorRequirement.WithOperator(core.NodeSelectorOpIn)
|
nodeSelectorRequirement := applyconfcore.NodeSelectorRequirement()
|
||||||
nodeSelectorRequirement.WithValues(nodeNames...)
|
nodeSelectorRequirement.WithKey("metadata.name")
|
||||||
nodeSelectorTerm := applyconfcore.NodeSelectorTerm()
|
nodeSelectorRequirement.WithOperator(core.NodeSelectorOpIn)
|
||||||
nodeSelectorTerm.WithMatchExpressions(nodeSelectorRequirement)
|
nodeSelectorRequirement.WithValues(nodeName)
|
||||||
|
|
||||||
|
nodeSelectorTerm := applyconfcore.NodeSelectorTerm()
|
||||||
|
nodeSelectorTerm.WithMatchFields(nodeSelectorRequirement)
|
||||||
|
matchFields = append(matchFields, nodeSelectorTerm)
|
||||||
|
}
|
||||||
|
|
||||||
nodeSelector := applyconfcore.NodeSelector()
|
nodeSelector := applyconfcore.NodeSelector()
|
||||||
nodeSelector.WithNodeSelectorTerms(nodeSelectorTerm)
|
nodeSelector.WithNodeSelectorTerms(matchFields...)
|
||||||
nodeAffinity := applyconfcore.NodeAffinity()
|
nodeAffinity := applyconfcore.NodeAffinity()
|
||||||
nodeAffinity.WithRequiredDuringSchedulingIgnoredDuringExecution(nodeSelector)
|
nodeAffinity.WithRequiredDuringSchedulingIgnoredDuringExecution(nodeSelector)
|
||||||
affinity := applyconfcore.Affinity()
|
affinity := applyconfcore.Affinity()
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ type RequestResponsePair struct {
|
|||||||
Response GenericMessage `json:"response"`
|
Response GenericMessage `json:"response"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Protocol` is modified in the later stages of data propagation. Therefore it's not a pointer.
|
|
||||||
type OutputChannelItem struct {
|
type OutputChannelItem struct {
|
||||||
|
// `Protocol` is modified in later stages of data propagation. Therefore, it's not a pointer.
|
||||||
Protocol Protocol
|
Protocol Protocol
|
||||||
Capture Capture
|
Capture Capture
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/amqp/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/amqp/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/http/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/http/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/kafka/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/kafka/\* expect
|
||||||
|
|||||||
@@ -13,4 +13,4 @@ test-pull-bin:
|
|||||||
|
|
||||||
test-pull-expect:
|
test-pull-expect:
|
||||||
@mkdir -p expect
|
@mkdir -p expect
|
||||||
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect7/redis/\* expect
|
@[ "${skipexpect}" ] && echo "Skipping downloading expected JSONs" || gsutil -o 'GSUtil:parallel_process_count=5' -o 'GSUtil:parallel_thread_count=5' -m cp -r gs://static.up9.io/mizu/test-pcap/expect8/redis/\* expect
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"node-fetch": "^3.1.1",
|
"node-fetch": "^3.1.1",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"protobuf-decoder": "^0.1.0",
|
"protobuf-decoder": "^0.1.2",
|
||||||
"react-graph-vis": "^1.0.7",
|
"react-graph-vis": "^1.0.7",
|
||||||
"react-lowlight": "^3.0.0",
|
"react-lowlight": "^3.0.0",
|
||||||
"react-router-dom": "^6.2.1",
|
"react-router-dom": "^6.2.1",
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import TrafficViewerApiAtom from "../../recoil/TrafficViewerApi";
|
|||||||
import TrafficViewerApi from "./TrafficViewerApi";
|
import TrafficViewerApi from "./TrafficViewerApi";
|
||||||
import focusedEntryIdAtom from "../../recoil/focusedEntryId";
|
import focusedEntryIdAtom from "../../recoil/focusedEntryId";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
import {TOAST_CONTAINER_ID} from "../../configs/Consts";
|
import {MAX_ENTRIES, TOAST_CONTAINER_ID} from "../../configs/Consts";
|
||||||
import tappingStatusAtom from "../../recoil/tappingStatus";
|
import tappingStatusAtom from "../../recoil/tappingStatus";
|
||||||
import leftOffTopAtom from "../../recoil/leftOffTop";
|
import leftOffTopAtom from "../../recoil/leftOffTop";
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ export const EntriesList: React.FC<EntriesListProps> = ({
|
|||||||
setIsLoadingTop(false);
|
setIsLoadingTop(false);
|
||||||
|
|
||||||
const newEntries = [...data.data.reverse(), ...entries];
|
const newEntries = [...data.data.reverse(), ...entries];
|
||||||
if(newEntries.length > 10000) {
|
if(newEntries.length > MAX_ENTRIES) {
|
||||||
newEntries.splice(10000, newEntries.length - 10000)
|
newEntries.splice(MAX_ENTRIES, newEntries.length - MAX_ENTRIES)
|
||||||
}
|
}
|
||||||
setEntries(newEntries);
|
setEntries(newEntries);
|
||||||
|
|
||||||
@@ -125,9 +125,9 @@ export const EntriesList: React.FC<EntriesListProps> = ({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newEntries = [...entries];
|
const newEntries = [...entries];
|
||||||
if (newEntries.length > 10000) {
|
if (newEntries.length > MAX_ENTRIES) {
|
||||||
setLeftOffTop(newEntries[0].id);
|
setLeftOffTop(newEntries[0].id);
|
||||||
newEntries.splice(0, newEntries.length - 10000)
|
newEntries.splice(0, newEntries.length - MAX_ENTRIES)
|
||||||
setNoMoreDataTop(false);
|
setNoMoreDataTop(false);
|
||||||
setEntries(newEntries);
|
setEntries(newEntries);
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ export const EntriesList: React.FC<EntriesListProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.footer}>
|
<div className={styles.footer}>
|
||||||
<div>Displaying <b id="entries-length">{entries?.length}</b> results out of <b
|
<div>Displaying <b id="entries-length">{entries?.length > MAX_ENTRIES ? MAX_ENTRIES : entries?.length}</b> results out of <b
|
||||||
id="total-entries">{queriedTotal}</b> total
|
id="total-entries">{queriedTotal}</b> total
|
||||||
</div>
|
</div>
|
||||||
{startTime !== 0 && <div>Started listening at <span style={{
|
{startTime !== 0 && <div>Started listening at <span style={{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import styles from "./EntrySections.module.sass";
|
import styles from "./EntrySections.module.sass";
|
||||||
import React, {useState} from "react";
|
import React, { useState } from "react";
|
||||||
import {SyntaxHighlighter} from "../../UI/SyntaxHighlighter/index";
|
import { SyntaxHighlighter } from "../../UI/SyntaxHighlighter/index";
|
||||||
import CollapsibleContainer from "../../UI/CollapsibleContainer";
|
import CollapsibleContainer from "../../UI/CollapsibleContainer";
|
||||||
import FancyTextDisplay from "../../UI/FancyTextDisplay";
|
import FancyTextDisplay from "../../UI/FancyTextDisplay";
|
||||||
import Queryable from "../../UI/Queryable";
|
import Queryable from "../../UI/Queryable";
|
||||||
import Checkbox from "../../UI/Checkbox";
|
import Checkbox from "../../UI/Checkbox";
|
||||||
import ProtobufDecoder from "protobuf-decoder";
|
import ProtobufDecoder from "protobuf-decoder";
|
||||||
import {default as jsonBeautify} from "json-beautify";
|
import { default as jsonBeautify } from "json-beautify";
|
||||||
import {default as xmlBeautify} from "xml-formatter";
|
import { default as xmlBeautify } from "xml-formatter";
|
||||||
|
|
||||||
interface EntryViewLineProps {
|
interface EntryViewLineProps {
|
||||||
label: string;
|
label: string;
|
||||||
@@ -18,40 +18,40 @@ interface EntryViewLineProps {
|
|||||||
useTooltip?: boolean;
|
useTooltip?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntryViewLine: React.FC<EntryViewLineProps> = ({label, value, selector = "", overrideQueryValue = "", displayIconOnMouseOver = true, useTooltip = true}) => {
|
const EntryViewLine: React.FC<EntryViewLineProps> = ({ label, value, selector = "", overrideQueryValue = "", displayIconOnMouseOver = true, useTooltip = true }) => {
|
||||||
let query: string;
|
let query: string;
|
||||||
if (!selector) {
|
if (!selector) {
|
||||||
query = "";
|
query = "";
|
||||||
} else if (overrideQueryValue) {
|
} else if (overrideQueryValue) {
|
||||||
query = `${selector} == ${overrideQueryValue}`;
|
query = `${selector} == ${overrideQueryValue}`;
|
||||||
} else if (typeof(value) == "string") {
|
} else if (typeof (value) == "string") {
|
||||||
query = `${selector} == "${JSON.stringify(value).slice(1, -1)}"`;
|
query = `${selector} == "${JSON.stringify(value).slice(1, -1)}"`;
|
||||||
} else {
|
} else {
|
||||||
query = `${selector} == ${value}`;
|
query = `${selector} == ${value}`;
|
||||||
}
|
}
|
||||||
return (label && <tr className={styles.dataLine}>
|
return (label && <tr className={styles.dataLine}>
|
||||||
<td className={`${styles.dataKey}`}>
|
<td className={`${styles.dataKey}`}>
|
||||||
<Queryable
|
<Queryable
|
||||||
query={query}
|
query={query}
|
||||||
style={{float: "right", height: "18px"}}
|
style={{ float: "right", height: "18px" }}
|
||||||
iconStyle={{marginRight: "20px"}}
|
iconStyle={{ marginRight: "20px" }}
|
||||||
flipped={true}
|
flipped={true}
|
||||||
useTooltip={useTooltip}
|
useTooltip={useTooltip}
|
||||||
displayIconOnMouseOver={displayIconOnMouseOver}
|
displayIconOnMouseOver={displayIconOnMouseOver}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</Queryable>
|
</Queryable>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<FancyTextDisplay
|
<FancyTextDisplay
|
||||||
className={styles.dataValue}
|
className={styles.dataValue}
|
||||||
text={value}
|
text={value}
|
||||||
applyTextEllipsis={false}
|
applyTextEllipsis={false}
|
||||||
flipped={true}
|
flipped={true}
|
||||||
displayIconOnMouseOver={true}
|
displayIconOnMouseOver={true}
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
</tr>) || null;
|
</tr>) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -63,11 +63,11 @@ interface EntrySectionCollapsibleTitleProps {
|
|||||||
query?: string,
|
query?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntrySectionCollapsibleTitle: React.FC<EntrySectionCollapsibleTitleProps> = ({title, color, expanded, setExpanded, query = ""}) => {
|
const EntrySectionCollapsibleTitle: React.FC<EntrySectionCollapsibleTitleProps> = ({ title, color, expanded, setExpanded, query = "" }) => {
|
||||||
return <div className={styles.title}>
|
return <div className={styles.title}>
|
||||||
<div
|
<div
|
||||||
className={`${styles.button} ${expanded ? styles.expanded : ''}`}
|
className={`${styles.button} ${expanded ? styles.expanded : ''}`}
|
||||||
style={{backgroundColor: color}}
|
style={{ backgroundColor: color }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setExpanded(!expanded)
|
setExpanded(!expanded)
|
||||||
}}
|
}}
|
||||||
@@ -90,12 +90,12 @@ interface EntrySectionContainerProps {
|
|||||||
query?: string,
|
query?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntrySectionContainer: React.FC<EntrySectionContainerProps> = ({title, color, children, query = ""}) => {
|
export const EntrySectionContainer: React.FC<EntrySectionContainerProps> = ({ title, color, children, query = "" }) => {
|
||||||
const [expanded, setExpanded] = useState(true);
|
const [expanded, setExpanded] = useState(true);
|
||||||
return <CollapsibleContainer
|
return <CollapsibleContainer
|
||||||
className={styles.collapsibleContainer}
|
className={styles.collapsibleContainer}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
title={<EntrySectionCollapsibleTitle title={title} color={color} expanded={expanded} setExpanded={setExpanded} query={query}/>}
|
title={<EntrySectionCollapsibleTitle title={title} color={color} expanded={expanded} setExpanded={setExpanded} query={query} />}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</CollapsibleContainer>
|
</CollapsibleContainer>
|
||||||
@@ -130,6 +130,7 @@ export const EntryBodySection: React.FC<EntryBodySectionProps> = ({
|
|||||||
|
|
||||||
const isBase64Encoding = encoding === 'base64';
|
const isBase64Encoding = encoding === 'base64';
|
||||||
const supportsPrettying = supportedFormats.some(format => contentType?.indexOf(format) > -1);
|
const supportsPrettying = supportedFormats.some(format => contentType?.indexOf(format) > -1);
|
||||||
|
const [isDecodeGrpc, setIsDecodeGrpc] = useState(true);
|
||||||
|
|
||||||
const formatTextBody = (body: any): string => {
|
const formatTextBody = (body: any): string => {
|
||||||
if (!decodeBase64) return body;
|
if (!decodeBase64) return body;
|
||||||
@@ -141,7 +142,7 @@ export const EntryBodySection: React.FC<EntryBodySectionProps> = ({
|
|||||||
if (jsonLikeFormats.some(format => contentType?.indexOf(format) > -1)) {
|
if (jsonLikeFormats.some(format => contentType?.indexOf(format) > -1)) {
|
||||||
if (!isPretty) return bodyBuf;
|
if (!isPretty) return bodyBuf;
|
||||||
return jsonBeautify(JSON.parse(bodyBuf), null, 2, 80);
|
return jsonBeautify(JSON.parse(bodyBuf), null, 2, 80);
|
||||||
} else if (xmlLikeFormats.some(format => contentType?.indexOf(format) > -1)) {
|
} else if (xmlLikeFormats.some(format => contentType?.indexOf(format) > -1)) {
|
||||||
if (!isPretty) return bodyBuf;
|
if (!isPretty) return bodyBuf;
|
||||||
return xmlBeautify(bodyBuf, {
|
return xmlBeautify(bodyBuf, {
|
||||||
indentation: ' ',
|
indentation: ' ',
|
||||||
@@ -157,49 +158,55 @@ export const EntryBodySection: React.FC<EntryBodySectionProps> = ({
|
|||||||
return jsonBeautify(protobufDecoded, null, 2, 80);
|
return jsonBeautify(protobufDecoded, null, 2, 80);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
if(isDecodeGrpc)
|
||||||
|
setIsDecodeGrpc(false);
|
||||||
|
if (!String(error).includes("More than one message in")){
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return bodyBuf;
|
return bodyBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
{content && content?.length > 0 && <EntrySectionContainer
|
{content && content?.length > 0 && <EntrySectionContainer
|
||||||
title={title}
|
title={title}
|
||||||
color={color}
|
color={color}
|
||||||
query={`${selector} == r".*"`}
|
query={`${selector} == r".*"`}
|
||||||
>
|
>
|
||||||
<div style={{display: 'flex', alignItems: 'center', alignContent: 'center', margin: "5px 0"}}>
|
<div style={{ display: 'flex', alignItems: 'center', alignContent: 'center', margin: "5px 0" }}>
|
||||||
{supportsPrettying && <div style={{paddingTop: 3}}>
|
{supportsPrettying && <div style={{ paddingTop: 3 }}>
|
||||||
<Checkbox checked={isPretty} onToggle={() => {setIsPretty(!isPretty)}}/>
|
<Checkbox checked={isPretty} onToggle={() => { setIsPretty(!isPretty) }} />
|
||||||
</div>}
|
</div>}
|
||||||
{supportsPrettying && <span style={{marginLeft: '.2rem'}}>Pretty</span>}
|
{supportsPrettying && <span style={{ marginLeft: '.2rem' }}>Pretty</span>}
|
||||||
|
|
||||||
<div style={{paddingTop: 3, paddingLeft: supportsPrettying ? 20 : 0}}>
|
<div style={{ paddingTop: 3, paddingLeft: supportsPrettying ? 20 : 0 }}>
|
||||||
<Checkbox checked={showLineNumbers} onToggle={() => {setShowLineNumbers(!showLineNumbers)}}/>
|
<Checkbox checked={showLineNumbers} onToggle={() => { setShowLineNumbers(!showLineNumbers) }} />
|
||||||
</div>
|
</div>
|
||||||
<span style={{marginLeft: '.2rem'}}>Line numbers</span>
|
<span style={{ marginLeft: '.2rem' }}>Line numbers</span>
|
||||||
|
{isBase64Encoding && <div style={{ paddingTop: 3, paddingLeft: 20 }}>
|
||||||
{isBase64Encoding && <div style={{paddingTop: 3, paddingLeft: 20}}>
|
<Checkbox checked={decodeBase64} onToggle={() => { setDecodeBase64(!decodeBase64) }} />
|
||||||
<Checkbox checked={decodeBase64} onToggle={() => {setDecodeBase64(!decodeBase64)}}/>
|
|
||||||
</div>}
|
</div>}
|
||||||
{isBase64Encoding && <span style={{marginLeft: '.2rem'}}>Decode Base64</span>}
|
{isBase64Encoding && <span style={{ marginLeft: '.2rem' }}>Decode Base64</span>}
|
||||||
</div>
|
{!isDecodeGrpc && <span style={{ fontSize: '12px', color: '#DB2156', marginLeft: '.8rem' }}>More than one message in protobuf payload is not supported</span>}
|
||||||
|
</div>
|
||||||
|
|
||||||
<SyntaxHighlighter
|
<SyntaxHighlighter
|
||||||
code={formatTextBody(content)}
|
code={formatTextBody(content)}
|
||||||
showLineNumbers={showLineNumbers}
|
showLineNumbers={showLineNumbers}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</EntrySectionContainer>}
|
</EntrySectionContainer>}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface EntrySectionProps {
|
interface EntrySectionProps {
|
||||||
title: string,
|
title: string,
|
||||||
color: string,
|
color: string,
|
||||||
arrayToIterate: any[],
|
arrayToIterate: any[],
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntryTableSection: React.FC<EntrySectionProps> = ({title, color, arrayToIterate}) => {
|
export const EntryTableSection: React.FC<EntrySectionProps> = ({ title, color, arrayToIterate }) => {
|
||||||
let arrayToIterateSorted: any[];
|
let arrayToIterateSorted: any[];
|
||||||
if (arrayToIterate) {
|
if (arrayToIterate) {
|
||||||
arrayToIterateSorted = arrayToIterate.sort((a, b) => {
|
arrayToIterateSorted = arrayToIterate.sort((a, b) => {
|
||||||
@@ -220,7 +227,7 @@ export const EntryTableSection: React.FC<EntrySectionProps> = ({title, color, ar
|
|||||||
<EntrySectionContainer title={title} color={color}>
|
<EntrySectionContainer title={title} color={color}>
|
||||||
<table>
|
<table>
|
||||||
<tbody id={`tbody-${title}`}>
|
<tbody id={`tbody-${title}`}>
|
||||||
{arrayToIterateSorted.map(({name, value, selector}, index) => <EntryViewLine
|
{arrayToIterateSorted.map(({ name, value, selector }, index) => <EntryViewLine
|
||||||
key={index}
|
key={index}
|
||||||
label={name}
|
label={name}
|
||||||
value={value}
|
value={value}
|
||||||
@@ -228,7 +235,7 @@ export const EntryTableSection: React.FC<EntrySectionProps> = ({title, color, ar
|
|||||||
/>)}
|
/>)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</EntrySectionContainer> : <span/>
|
</EntrySectionContainer> : <span />
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
@@ -247,7 +254,7 @@ interface EntryPolicySectionCollapsibleTitleProps {
|
|||||||
setExpanded: any;
|
setExpanded: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const EntryPolicySectionCollapsibleTitle: React.FC<EntryPolicySectionCollapsibleTitleProps> = ({label, matched, expanded, setExpanded}) => {
|
const EntryPolicySectionCollapsibleTitle: React.FC<EntryPolicySectionCollapsibleTitleProps> = ({ label, matched, expanded, setExpanded }) => {
|
||||||
return <div className={styles.title}>
|
return <div className={styles.title}>
|
||||||
<span
|
<span
|
||||||
className={`${styles.button}
|
className={`${styles.button}
|
||||||
@@ -260,8 +267,8 @@ const EntryPolicySectionCollapsibleTitle: React.FC<EntryPolicySectionCollapsible
|
|||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<tr className={styles.dataLine}>
|
<tr className={styles.dataLine}>
|
||||||
<td className={`${styles.dataKey} ${styles.rulesTitleSuccess}`}>{label}</td>
|
<td className={`${styles.dataKey} ${styles.rulesTitleSuccess}`}>{label}</td>
|
||||||
<td className={`${styles.dataKey} ${matched === 'Success' ? styles.rulesMatchedSuccess : styles.rulesMatchedFailure}`}>{matched}</td>
|
<td className={`${styles.dataKey} ${matched === 'Success' ? styles.rulesMatchedSuccess : styles.rulesMatchedFailure}`}>{matched}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -273,28 +280,28 @@ interface EntryPolicySectionContainerProps {
|
|||||||
children?: any;
|
children?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntryPolicySectionContainer: React.FC<EntryPolicySectionContainerProps> = ({label, matched, children}) => {
|
export const EntryPolicySectionContainer: React.FC<EntryPolicySectionContainerProps> = ({ label, matched, children }) => {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
return <CollapsibleContainer
|
return <CollapsibleContainer
|
||||||
className={styles.collapsibleContainer}
|
className={styles.collapsibleContainer}
|
||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
title={<EntryPolicySectionCollapsibleTitle label={label} matched={matched} expanded={expanded} setExpanded={setExpanded}/>}
|
title={<EntryPolicySectionCollapsibleTitle label={label} matched={matched} expanded={expanded} setExpanded={setExpanded} />}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</CollapsibleContainer>
|
</CollapsibleContainer>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({title, color, latency, arrayToIterate}) => {
|
export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({ title, color, latency, arrayToIterate }) => {
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
{
|
{
|
||||||
arrayToIterate && arrayToIterate.length > 0 ?
|
arrayToIterate && arrayToIterate.length > 0 ?
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<EntrySectionContainer title={title} color={color}>
|
<EntrySectionContainer title={title} color={color}>
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{arrayToIterate.map(({rule, matched}, index) => {
|
{arrayToIterate.map(({ rule, matched }, index) => {
|
||||||
return (
|
return (
|
||||||
<EntryPolicySectionContainer key={index} label={rule.Name} matched={matched && (rule.Type === 'slo' ? rule.ResponseTime >= latency : true)? "Success" : "Failure"}>
|
<EntryPolicySectionContainer key={index} label={rule.Name} matched={matched && (rule.Type === 'slo' ? rule.ResponseTime >= latency : true) ? "Success" : "Failure"}>
|
||||||
{
|
{
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{
|
{
|
||||||
@@ -330,11 +337,11 @@ export const EntryTablePolicySection: React.FC<EntryPolicySectionProps> = ({titl
|
|||||||
</EntryPolicySectionContainer>
|
</EntryPolicySectionContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</EntrySectionContainer>
|
</EntrySectionContainer>
|
||||||
</React.Fragment> : <span className={styles.noRules}>No rules could be applied to this request.</span>
|
</React.Fragment> : <span className={styles.noRules}>No rules could be applied to this request.</span>
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
@@ -347,7 +354,7 @@ interface EntryContractSectionProps {
|
|||||||
contractContent: string,
|
contractContent: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EntryContractSection: React.FC<EntryContractSectionProps> = ({color, requestReason, responseReason, contractContent}) => {
|
export const EntryContractSection: React.FC<EntryContractSectionProps> = ({ color, requestReason, responseReason, contractContent }) => {
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
{requestReason && <EntrySectionContainer title="Request" color={color}>
|
{requestReason && <EntrySectionContainer title="Request" color={color}>
|
||||||
{requestReason}
|
{requestReason}
|
||||||
|
|||||||
@@ -1,19 +1,22 @@
|
|||||||
import React, { CSSProperties } from "react";
|
import React from "react";
|
||||||
import styles from "./style/InformationIcon.module.sass"
|
import styles from "./style/InformationIcon.module.sass"
|
||||||
|
|
||||||
const DEFUALT_LINK = "https://getmizu.io/docs"
|
const DEFUALT_LINK = "https://getmizu.io/docs"
|
||||||
|
|
||||||
export interface InformationIconProps {
|
interface LinkProps {
|
||||||
link?: string,
|
link?: string,
|
||||||
style?: CSSProperties
|
className?: string
|
||||||
|
title?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InformationIcon: React.FC<InformationIconProps> = ({ link, style }) => {
|
export const Link: React.FC<LinkProps> = ({ link, className, title, children }) => {
|
||||||
return <React.Fragment>
|
return <a href={link} className={className} title={title} target="_blank">
|
||||||
<a href={DEFUALT_LINK ? DEFUALT_LINK : link} style={style} className={styles.linkStyle} title="documentation" target="_blank">
|
{children}
|
||||||
<span>Docs</span>
|
</a>
|
||||||
</a>
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const InformationIcon: React.FC<LinkProps> = ({ className }) => {
|
||||||
|
return <Link title="documentation" className={`${styles.linkStyle} ${className}`} link={DEFUALT_LINK}>
|
||||||
|
<span>Docs</span>
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
@@ -5,10 +5,10 @@ import Tooltip from "./Tooltip";
|
|||||||
import Checkbox from "./Checkbox"
|
import Checkbox from "./Checkbox"
|
||||||
import { StatusBar } from "./StatusBar";
|
import { StatusBar } from "./StatusBar";
|
||||||
import CustomModal from "./CustomModal";
|
import CustomModal from "./CustomModal";
|
||||||
import { InformationIcon } from "./InformationIcon";
|
import { InformationIcon, Link } from "./InformationIcon";
|
||||||
import SelectList from "./SelectList";
|
import SelectList from "./SelectList";
|
||||||
import NoDataMessage from "./NoDataMessage";
|
import NoDataMessage from "./NoDataMessage";
|
||||||
|
|
||||||
|
|
||||||
export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage }
|
export { LoadingOverlay, Select, Tabs, Tooltip, Checkbox, CustomModal, InformationIcon, SelectList, NoDataMessage, Link }
|
||||||
export { StatusBar }
|
export { StatusBar }
|
||||||
@@ -1 +1,2 @@
|
|||||||
export const TOAST_CONTAINER_ID = "Common";
|
export const TOAST_CONTAINER_ID = "Common";
|
||||||
|
export const MAX_ENTRIES = 10000;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
"node-fetch": "^3.1.1",
|
"node-fetch": "^3.1.1",
|
||||||
"node-sass": "^6.0.0",
|
"node-sass": "^6.0.0",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"protobuf-decoder": "^0.1.0",
|
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-copy-to-clipboard": "^5.0.3",
|
"react-copy-to-clipboard": "^5.0.3",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user