diff --git a/.github/workflows/aws_publisher.yml b/.github/workflows/aws_publisher.yml
index 9d74a2804..6aa70fa91 100644
--- a/.github/workflows/aws_publisher.yml
+++ b/.github/workflows/aws_publisher.yml
@@ -19,7 +19,7 @@ on:
jobs:
build-ami:
name: Build AMI
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- name: Clone infra repo
run: |
diff --git a/.github/workflows/backend_tests.yml b/.github/workflows/backend_tests.yml
index 06b9a6d1c..8a3ffe2d3 100644
--- a/.github/workflows/backend_tests.yml
+++ b/.github/workflows/backend_tests.yml
@@ -15,7 +15,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- name: Checkout
diff --git a/.github/workflows/block_merge.yml b/.github/workflows/block_merge.yml
index db26a946d..c689d45b0 100644
--- a/.github/workflows/block_merge.yml
+++ b/.github/workflows/block_merge.yml
@@ -4,7 +4,7 @@ on:
types: [opened, labeled, unlabeled, synchronize]
jobs:
block_merge:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: mheap/github-action-required-labels@v5
with:
diff --git a/.github/workflows/branch-deploy.yml b/.github/workflows/branch-deploy.yml
index f073dff71..107a93116 100644
--- a/.github/workflows/branch-deploy.yml
+++ b/.github/workflows/branch-deploy.yml
@@ -12,7 +12,7 @@ permissions:
jobs:
build:
if: ${{ github.event.label.name == 'status/feature_testing' || github.event.label.name == 'status/feature_testing_public' }}
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
@@ -75,7 +75,7 @@ jobs:
tag: ${{ steps.extract_branch.outputs.tag }}
make-branch-env:
needs: build
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- name: clone
run: |
diff --git a/.github/workflows/branch-remove.yml b/.github/workflows/branch-remove.yml
index a3177011b..d700ea976 100644
--- a/.github/workflows/branch-remove.yml
+++ b/.github/workflows/branch-remove.yml
@@ -10,7 +10,7 @@ permissions:
jobs:
remove:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
if: ${{ (github.event.label.name == 'status/feature_testing' || github.event.label.name == 'status/feature_testing_public') || (github.event.action == 'closed' && (contains(github.event.pull_request.labels.*.name, 'status/feature_testing') || contains(github.event.pull_request.labels.*.name, 'status/feature_testing_public'))) }}
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/build-public-image.yml b/.github/workflows/build-public-image.yml
index de5e33b51..86f90ad9c 100644
--- a/.github/workflows/build-public-image.yml
+++ b/.github/workflows/build-public-image.yml
@@ -11,7 +11,7 @@ permissions:
jobs:
build:
if: ${{ github.event.label.name == 'status/image_testing' }}
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index a29477928..57f5a0251 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -23,7 +23,7 @@ permissions:
jobs:
analyze:
name: Analyze
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
diff --git a/.github/workflows/cve.yml b/.github/workflows/cve.yml
index 13535c65c..d53913521 100644
--- a/.github/workflows/cve.yml
+++ b/.github/workflows/cve.yml
@@ -10,7 +10,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/delete-public-image.yml b/.github/workflows/delete-public-image.yml
index 5294307d8..8e3f2dd7c 100644
--- a/.github/workflows/delete-public-image.yml
+++ b/.github/workflows/delete-public-image.yml
@@ -6,7 +6,7 @@ on:
jobs:
remove:
if: ${{ github.event.label.name == 'status/image_testing' || ( github.event.action == 'closed' && (contains(github.event.pull_request.labels, 'status/image_testing'))) }}
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- name: get branch name
id: extract_branch
diff --git a/.github/workflows/e2e-automation.yml b/.github/workflows/e2e-automation.yml
index 0313784b7..6303001a3 100644
--- a/.github/workflows/e2e-automation.yml
+++ b/.github/workflows/e2e-automation.yml
@@ -21,7 +21,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/e2e-manual.yml b/.github/workflows/e2e-manual.yml
index 2668897ae..d554bdaa2 100644
--- a/.github/workflows/e2e-manual.yml
+++ b/.github/workflows/e2e-manual.yml
@@ -20,7 +20,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index f7509c1df..72e7c92e1 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -16,7 +16,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/e2e-weekly.yml b/.github/workflows/e2e-weekly.yml
index 4e238ead9..d8275e473 100644
--- a/.github/workflows/e2e-weekly.yml
+++ b/.github/workflows/e2e-weekly.yml
@@ -8,7 +8,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/frontend_tests.yml b/.github/workflows/frontend_tests.yml
index 9aa4a6110..4be3239d4 100644
--- a/.github/workflows/frontend_tests.yml
+++ b/.github/workflows/frontend_tests.yml
@@ -11,7 +11,7 @@ jobs:
env:
CI: true
NODE_ENV: dev
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 472dadbca..503656b2d 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -10,7 +10,7 @@ permissions:
jobs:
build:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
permissions:
contents: read
packages: write
diff --git a/.github/workflows/md-links.yml b/.github/workflows/md-links.yml
index ee3379558..b885e014d 100644
--- a/.github/workflows/md-links.yml
+++ b/.github/workflows/md-links.yml
@@ -14,7 +14,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/pr_linter.yml b/.github/workflows/pr_linter.yml
index ef5bd8b25..f4562345f 100644
--- a/.github/workflows/pr_linter.yml
+++ b/.github/workflows/pr_linter.yml
@@ -6,7 +6,7 @@ permissions:
checks: write
jobs:
task-check:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: kentaro-m/task-completed-checker-action@v0.1.2
with:
diff --git a/.github/workflows/release-serde-api.yml b/.github/workflows/release-serde-api.yml
index 86aa61a75..af5b1db0d 100644
--- a/.github/workflows/release-serde-api.yml
+++ b/.github/workflows/release-serde-api.yml
@@ -7,7 +7,7 @@ permissions:
jobs:
release-serde-api:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index efa859a79..2ae221180 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -8,7 +8,7 @@ permissions:
jobs:
release:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
permissions:
contents: write
packages: write
@@ -95,7 +95,7 @@ jobs:
cache-to: type=local,dest=/tmp/.buildx-cache
charts:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
needs: release
steps:
- name: Repository Dispatch
diff --git a/.github/workflows/release_drafter.yml b/.github/workflows/release_drafter.yml
index dc8f689ea..6614c88aa 100644
--- a/.github/workflows/release_drafter.yml
+++ b/.github/workflows/release_drafter.yml
@@ -18,7 +18,7 @@ permissions:
jobs:
update_release_draft:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
diff --git a/.github/workflows/separate_env_public_create.yml b/.github/workflows/separate_env_public_create.yml
index 5449482db..b7bb630e1 100644
--- a/.github/workflows/separate_env_public_create.yml
+++ b/.github/workflows/separate_env_public_create.yml
@@ -12,7 +12,7 @@ permissions:
jobs:
build:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -76,7 +76,7 @@ jobs:
tag: ${{ steps.extract_branch.outputs.tag }}
separate-env-create:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
needs: build
steps:
- name: clone
diff --git a/.github/workflows/separate_env_public_remove.yml b/.github/workflows/separate_env_public_remove.yml
index 2ada624e2..0eb48cd4a 100644
--- a/.github/workflows/separate_env_public_remove.yml
+++ b/.github/workflows/separate_env_public_remove.yml
@@ -9,7 +9,7 @@ on:
jobs:
separate-env-remove:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- name: clone
run: |
diff --git a/.github/workflows/welcome-first-time-contributors.yml b/.github/workflows/welcome-first-time-contributors.yml
index 3ec8e8a34..1ac861055 100644
--- a/.github/workflows/welcome-first-time-contributors.yml
+++ b/.github/workflows/welcome-first-time-contributors.yml
@@ -12,7 +12,7 @@ permissions:
pull-requests: write
jobs:
welcome:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@v1
with:
diff --git a/.github/workflows/workflow_linter.yml b/.github/workflows/workflow_linter.yml
index 47925a9cf..728aaa251 100644
--- a/.github/workflows/workflow_linter.yml
+++ b/.github/workflows/workflow_linter.yml
@@ -10,7 +10,7 @@ permissions:
jobs:
build-and-test:
- runs-on: gha-private-runner
+ runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
diff --git a/frontend/.prettierrc b/frontend/.prettierrc
index e88e08a44..2c6ddbf69 100644
--- a/frontend/.prettierrc
+++ b/frontend/.prettierrc
@@ -6,5 +6,6 @@
"jsxSingleQuote": false,
"bracketSpacing": true,
"bracketSameLine": false,
- "arrowParens": "always"
+ "arrowParens": "always",
+ "endOfLine": "lf"
}
diff --git a/frontend/index.html b/frontend/index.html
index 693664306..0041f6efa 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -5,8 +5,7 @@
-
-
+
diff --git a/frontend/package.json b/frontend/package.json
index cb7919927..540c85a88 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -50,8 +50,9 @@
"scripts": {
"start": "vite",
"dev": "vite",
- "gen:sources": "rimraf src/generated-sources && openapi-generator-cli generate",
- "build": "vite build",
+ "clean": "rimraf ./src/generated-sources",
+ "gen:sources": "pnpm clean && openapi-generator-cli generate",
+ "build": "pnpm gen:sources && tsc --noEmit && vite build",
"preview": "vite preview",
"lint": "eslint --ext .tsx,.ts src/",
"lint:fix": "eslint --ext .tsx,.ts src/ --fix",
@@ -103,6 +104,7 @@
"ts-node": "^10.9.1",
"ts-prune": "^0.10.3",
"typescript": "^4.7.4",
+ "vite-plugin-checker": "^0.6.4",
"vite-plugin-ejs": "^1.6.4"
},
"engines": {
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index 757bbc622..427aeadf1 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -264,6 +264,9 @@ devDependencies:
typescript:
specifier: ^4.7.4
version: 4.7.4
+ vite-plugin-checker:
+ specifier: ^0.6.4
+ version: 0.6.4(eslint@8.48.0)(typescript@4.7.4)(vite@4.5.2)
vite-plugin-ejs:
specifier: ^1.6.4
version: 1.6.4
@@ -333,7 +336,7 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.0
- '@babel/code-frame': 7.18.6
+ '@babel/code-frame': 7.23.5
'@babel/generator': 7.18.9
'@babel/helper-compilation-targets': 7.18.9(@babel/core@7.18.9)
'@babel/helper-module-transforms': 7.18.9
@@ -443,7 +446,7 @@ packages:
'@babel/helper-module-imports': 7.18.6
'@babel/helper-simple-access': 7.18.6
'@babel/helper-split-export-declaration': 7.18.6
- '@babel/helper-validator-identifier': 7.18.6
+ '@babel/helper-validator-identifier': 7.22.20
'@babel/template': 7.18.6
'@babel/traverse': 7.23.9(supports-color@5.5.0)
'@babel/types': 7.18.9
@@ -680,7 +683,7 @@ packages:
resolution: {integrity: sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/code-frame': 7.18.6
+ '@babel/code-frame': 7.23.5
'@babel/parser': 7.18.9
'@babel/types': 7.18.9
dev: false
@@ -3792,6 +3795,15 @@ packages:
universalify: 2.0.0
dev: true
+ /fs-extra@11.2.0:
+ resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
+ engines: {node: '>=14.14'}
+ dependencies:
+ graceful-fs: 4.2.10
+ jsonfile: 6.1.0
+ universalify: 2.0.0
+ dev: true
+
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
@@ -5295,7 +5307,6 @@ packages:
engines: {node: '>=8'}
dependencies:
path-key: 3.1.1
- dev: false
/nwsapi@2.2.0:
resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==}
@@ -6397,6 +6408,10 @@ packages:
resolution: {integrity: sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==}
dev: false
+ /tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+ dev: true
+
/tmp@0.0.33:
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
engines: {node: '>=0.6.0'}
@@ -6706,6 +6721,57 @@ packages:
convert-source-map: 1.7.0
dev: false
+ /vite-plugin-checker@0.6.4(eslint@8.48.0)(typescript@4.7.4)(vite@4.5.2):
+ resolution: {integrity: sha512-2zKHH5oxr+ye43nReRbC2fny1nyARwhxdm0uNYp/ERy4YvU9iZpNOsueoi/luXw5gnpqRSvjcEPxXbS153O2wA==}
+ engines: {node: '>=14.16'}
+ peerDependencies:
+ eslint: '>=7'
+ meow: ^9.0.0
+ optionator: ^0.9.1
+ stylelint: '>=13'
+ typescript: '*'
+ vite: '>=2.0.0'
+ vls: '*'
+ vti: '*'
+ vue-tsc: '>=1.3.9'
+ peerDependenciesMeta:
+ eslint:
+ optional: true
+ meow:
+ optional: true
+ optionator:
+ optional: true
+ stylelint:
+ optional: true
+ typescript:
+ optional: true
+ vls:
+ optional: true
+ vti:
+ optional: true
+ vue-tsc:
+ optional: true
+ dependencies:
+ '@babel/code-frame': 7.23.5
+ ansi-escapes: 4.3.2
+ chalk: 4.1.2
+ chokidar: 3.5.2
+ commander: 8.3.0
+ eslint: 8.48.0
+ fast-glob: 3.3.2
+ fs-extra: 11.2.0
+ npm-run-path: 4.0.1
+ semver: 7.5.4
+ strip-ansi: 6.0.1
+ tiny-invariant: 1.3.3
+ typescript: 4.7.4
+ vite: 4.5.2(@types/node@20.11.17)(sass@1.66.1)
+ vscode-languageclient: 7.0.0
+ vscode-languageserver: 7.0.0
+ vscode-languageserver-textdocument: 1.0.11
+ vscode-uri: 3.0.8
+ dev: true
+
/vite-plugin-ejs@1.6.4:
resolution: {integrity: sha512-23p1RS4PiA0veXY5/gHZ60pl3pPvd8NEqdBsDgxNK8nM1rjFFDcVb0paNmuipzCgNP/Y0f/Id22M7Il4kvZ2jA==}
dependencies:
@@ -6765,6 +6831,46 @@ packages:
optionalDependencies:
fsevents: 2.3.2
+ /vscode-jsonrpc@6.0.0:
+ resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==}
+ engines: {node: '>=8.0.0 || >=10.0.0'}
+ dev: true
+
+ /vscode-languageclient@7.0.0:
+ resolution: {integrity: sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==}
+ engines: {vscode: ^1.52.0}
+ dependencies:
+ minimatch: 3.1.2
+ semver: 7.5.4
+ vscode-languageserver-protocol: 3.16.0
+ dev: true
+
+ /vscode-languageserver-protocol@3.16.0:
+ resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==}
+ dependencies:
+ vscode-jsonrpc: 6.0.0
+ vscode-languageserver-types: 3.16.0
+ dev: true
+
+ /vscode-languageserver-textdocument@1.0.11:
+ resolution: {integrity: sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA==}
+ dev: true
+
+ /vscode-languageserver-types@3.16.0:
+ resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==}
+ dev: true
+
+ /vscode-languageserver@7.0.0:
+ resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==}
+ hasBin: true
+ dependencies:
+ vscode-languageserver-protocol: 3.16.0
+ dev: true
+
+ /vscode-uri@3.0.8:
+ resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
+ dev: true
+
/w3c-hr-time@1.0.2:
resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}
deprecated: Use your platform's native performance.now() and performance.timeOrigin.
diff --git a/frontend/public/favicon/favicon.ico b/frontend/public/favicon/favicon.ico
deleted file mode 100644
index 2774ebccf..000000000
Binary files a/frontend/public/favicon/favicon.ico and /dev/null differ
diff --git a/frontend/public/favicon/icon.svg b/frontend/public/favicon/favicon.svg
similarity index 77%
rename from frontend/public/favicon/icon.svg
rename to frontend/public/favicon/favicon.svg
index d31960515..fc31bcf4a 100644
--- a/frontend/public/favicon/icon.svg
+++ b/frontend/public/favicon/favicon.svg
@@ -2,14 +2,16 @@
-
-
+
+
diff --git a/frontend/src/components/App.tsx b/frontend/src/components/App.tsx
index 43abc60bd..f3d6d88cd 100644
--- a/frontend/src/components/App.tsx
+++ b/frontend/src/components/App.tsx
@@ -50,7 +50,7 @@ const App: React.FC = () => {
- }>
+ }>
diff --git a/frontend/src/components/Brokers/BrokersList/BrokersList.tsx b/frontend/src/components/Brokers/BrokersList/BrokersList.tsx
index f869269fa..bdc1f9c00 100644
--- a/frontend/src/components/Brokers/BrokersList/BrokersList.tsx
+++ b/frontend/src/components/Brokers/BrokersList/BrokersList.tsx
@@ -1,27 +1,15 @@
-import React from 'react';
+import React, { useMemo } from 'react';
import { ClusterName } from 'redux/interfaces';
import { useNavigate } from 'react-router-dom';
import PageHeading from 'components/common/PageHeading/PageHeading';
-import * as Metrics from 'components/common/Metrics';
import useAppParams from 'lib/hooks/useAppParams';
+import Table from 'components/common/NewTable';
+import { clusterBrokerPath } from 'lib/paths';
import { useBrokers } from 'lib/hooks/api/brokers';
import { useClusterStats } from 'lib/hooks/api/clusters';
-import Table, { LinkCell, SizeCell } from 'components/common/NewTable';
-import CheckMarkRoundIcon from 'components/common/Icons/CheckMarkRoundIcon';
-import { ColumnDef } from '@tanstack/react-table';
-import { clusterBrokerPath } from 'lib/paths';
-import { keyBy } from 'lib/functions/keyBy';
-import Tooltip from 'components/common/Tooltip/Tooltip';
-import ColoredCell from 'components/common/NewTable/ColoredCell';
-
-import SkewHeader from './SkewHeader/SkewHeader';
-import * as S from './BrokersList.styled';
-const NA = 'N/A';
-const NA_DISK_USAGE = {
- segmentCount: NA,
- segmentSize: NA,
-};
+import { BrokersMetrics } from './BrokersMetrics/BrokersMetrics';
+import { getBrokersTableColumns, getBrokersTableRows } from './lib';
const BrokersList: React.FC = () => {
const navigate = useNavigate();
@@ -41,202 +29,35 @@ const BrokersList: React.FC = () => {
version,
} = clusterStats;
- const rows = React.useMemo(() => {
- if (!brokers || brokers.length === 0) {
- return [];
- }
-
- const diskUsageByBroker = keyBy(diskUsage, 'brokerId');
-
- return brokers.map((broker) => {
- const diskUse = diskUsageByBroker[broker.id] || NA_DISK_USAGE;
-
- return {
- brokerId: broker.id,
- size: diskUse.segmentSize,
- count: diskUse.segmentCount,
- port: broker.port,
- host: broker.host,
- partitionsLeader: broker.partitionsLeader,
- partitionsSkew: broker.partitionsSkew,
- leadersSkew: broker.leadersSkew,
- inSyncPartitions: broker.inSyncPartitions,
- };
- });
- }, [diskUsage, brokers]);
-
- const columns = React.useMemo[]>(
- () => [
- {
- header: 'Broker ID',
- accessorKey: 'brokerId',
- // eslint-disable-next-line react/no-unstable-nested-components
- cell: ({ getValue }) => (
-
- ()}`}
- to={encodeURIComponent(`${getValue()}`)}
- />
- {getValue() === activeControllers && (
- }
- content="Active Controller"
- placement="right"
- />
- )}
-
- ),
- },
- {
- header: 'Disk usage',
- accessorKey: 'size',
- // eslint-disable-next-line react/no-unstable-nested-components
- cell: ({ getValue, table, cell, column, renderValue, row }) =>
- getValue() === NA ? (
- NA
- ) : (
-
- ),
- },
- {
- // eslint-disable-next-line react/no-unstable-nested-components
- header: () => ,
- accessorKey: 'partitionsSkew',
- // eslint-disable-next-line react/no-unstable-nested-components
- cell: ({ getValue }) => {
- const value = getValue();
- return (
- = 10 && value < 20}
- attention={value >= 20}
- />
- );
- },
- },
- { header: 'Leaders', accessorKey: 'partitionsLeader' },
- {
- header: 'Leader skew',
- accessorKey: 'leadersSkew',
- // eslint-disable-next-line react/no-unstable-nested-components
- cell: ({ getValue }) => {
- const value = getValue();
- return (
- = 10 && value < 20}
- attention={value >= 20}
- />
- );
- },
- },
- {
- header: 'Online partitions',
- accessorKey: 'inSyncPartitions',
- // eslint-disable-next-line react/no-unstable-nested-components
- cell: ({ getValue, row }) => {
- const value = getValue();
- return (
-
- );
- },
- },
- { header: 'Port', accessorKey: 'port' },
- {
- header: 'Host',
- accessorKey: 'host',
- },
- ],
- []
+ const rows = useMemo(
+ () =>
+ getBrokersTableRows({
+ brokers,
+ diskUsage,
+ activeControllers,
+ onlinePartitionCount,
+ offlinePartitionCount,
+ }),
+ [diskUsage, activeControllers, brokers]
);
- const replicas = (inSyncReplicasCount ?? 0) + (outOfSyncReplicasCount ?? 0);
- const areAllInSync = inSyncReplicasCount && replicas === inSyncReplicasCount;
- const partitionIsOffline = offlinePartitionCount && offlinePartitionCount > 0;
-
- const isActiveControllerUnKnown = typeof activeControllers === 'undefined';
+ const columns = useMemo(() => getBrokersTableColumns(), []);
return (
<>
-
-
-
- {brokerCount}
-
-
- {isActiveControllerUnKnown ? (
- No Active Controller
- ) : (
- activeControllers
- )}
-
- {version}
-
-
-
- {partitionIsOffline ? (
- {onlinePartitionCount}
- ) : (
- onlinePartitionCount
- )}
-
- {` of ${
- (onlinePartitionCount || 0) + (offlinePartitionCount || 0)
- }
- `}
-
-
-
- {!underReplicatedPartitionCount ? (
-
- {underReplicatedPartitionCount}
-
- ) : (
- {underReplicatedPartitionCount}
- )}
-
-
- {areAllInSync ? (
- replicas
- ) : (
- {inSyncReplicasCount}
- )}
- of {replicas}
-
-
- {outOfSyncReplicasCount}
-
-
-
+
+
+
theme.circularAlert.color.error};
+`;
diff --git a/frontend/src/components/Brokers/BrokersList/BrokersMetrics/BrokersMetrics.tsx b/frontend/src/components/Brokers/BrokersList/BrokersMetrics/BrokersMetrics.tsx
new file mode 100644
index 000000000..5c1600806
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/BrokersMetrics/BrokersMetrics.tsx
@@ -0,0 +1,105 @@
+import React from 'react';
+import * as Metrics from 'components/common/Metrics';
+
+import * as S from './BrokersMetrics.styled';
+
+type BrokersMetricsProps = {
+ brokerCount: number | undefined;
+ inSyncReplicasCount: number | undefined;
+ outOfSyncReplicasCount: number | undefined;
+ offlinePartitionCount: number | undefined;
+ activeControllers: number | undefined;
+ onlinePartitionCount: number | undefined;
+ underReplicatedPartitionCount: number | undefined;
+ version: string | undefined;
+};
+
+export const BrokersMetrics = ({
+ brokerCount,
+ version,
+ activeControllers,
+ outOfSyncReplicasCount,
+ inSyncReplicasCount,
+ offlinePartitionCount,
+ underReplicatedPartitionCount,
+ onlinePartitionCount,
+}: BrokersMetricsProps) => {
+ const replicas = (inSyncReplicasCount ?? 0) + (outOfSyncReplicasCount ?? 0);
+ const areAllInSync = inSyncReplicasCount && replicas === inSyncReplicasCount;
+ const partitionIsOffline = offlinePartitionCount && offlinePartitionCount > 0;
+
+ const isActiveControllerUnKnown = typeof activeControllers === 'undefined';
+
+ return (
+
+
+
+ {brokerCount}
+
+
+
+ {isActiveControllerUnKnown ? (
+ No Active Controller
+ ) : (
+ activeControllers
+ )}
+
+
+ {version}
+
+
+
+
+ {partitionIsOffline ? (
+ {onlinePartitionCount}
+ ) : (
+ onlinePartitionCount
+ )}
+
+ {` of ${(onlinePartitionCount || 0) + (offlinePartitionCount || 0)}
+ `}
+
+
+
+
+ {!underReplicatedPartitionCount ? (
+
+ {underReplicatedPartitionCount}
+
+ ) : (
+ {underReplicatedPartitionCount}
+ )}
+
+
+
+ {areAllInSync ? (
+ replicas
+ ) : (
+ {inSyncReplicasCount}
+ )}
+ of {replicas}
+
+
+
+ {outOfSyncReplicasCount}
+
+
+
+ );
+};
diff --git a/frontend/src/components/Brokers/BrokersList/BrokersList.styled.ts b/frontend/src/components/Brokers/BrokersList/TableCells/TableCells.styled.ts
similarity index 64%
rename from frontend/src/components/Brokers/BrokersList/BrokersList.styled.ts
rename to frontend/src/components/Brokers/BrokersList/TableCells/TableCells.styled.ts
index 964e64368..718f952eb 100644
--- a/frontend/src/components/Brokers/BrokersList/BrokersList.styled.ts
+++ b/frontend/src/components/Brokers/BrokersList/TableCells/TableCells.styled.ts
@@ -10,7 +10,3 @@ export const RowCell = styled.div`
padding-left: 6px;
}
`;
-
-export const DangerText = styled.span`
- color: ${({ theme }) => theme.circularAlert.color.error};
-`;
diff --git a/frontend/src/components/Brokers/BrokersList/TableCells/TableCells.tsx b/frontend/src/components/Brokers/BrokersList/TableCells/TableCells.tsx
new file mode 100644
index 000000000..5d6039fbf
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/TableCells/TableCells.tsx
@@ -0,0 +1,97 @@
+import React from 'react';
+import { BrokersTableRow } from 'components/Brokers/BrokersList/lib/types';
+import { CellContext } from '@tanstack/react-table';
+import { LinkCell } from 'components/common/NewTable';
+import Tooltip from 'components/common/Tooltip/Tooltip';
+import CheckMarkRoundIcon from 'components/common/Icons/CheckMarkRoundIcon';
+import { NA } from 'components/Brokers/BrokersList/lib';
+import ColoredCell from 'components/common/NewTable/ColoredCell';
+import SizeCellCount from 'components/common/NewTable/SizeCellCount';
+
+import * as S from './TableCells.styled';
+
+type BrokerIdProps = CellContext;
+
+export const BrokerId = ({ getValue, row }: BrokerIdProps) => {
+ const { activeControllers } = row.original;
+ const brokerId = getValue();
+
+ return (
+
+
+ {brokerId === activeControllers && (
+ }
+ content="Active Controller"
+ placement="right"
+ />
+ )}
+
+ );
+};
+
+type DiscUsageProps = CellContext;
+
+export const DiscUsage = ({
+ getValue,
+ table,
+ cell,
+ column,
+ renderValue,
+ row,
+}: DiscUsageProps) => {
+ if (getValue() === undefined) return NA;
+
+ return (
+
+ );
+};
+
+type ScewProps = CellContext<
+ BrokersTableRow,
+ BrokersTableRow['partitionsSkew'] | BrokersTableRow['leadersSkew']
+>;
+
+export const Skew = ({ getValue }: ScewProps) => {
+ const skew = getValue();
+ const value = skew ? `${skew.toFixed(2)}%` : '-';
+
+ return (
+ = 10 && skew < 20}
+ attention={skew !== undefined && skew >= 20}
+ />
+ );
+};
+
+type OnlinePartitionsProps = CellContext<
+ BrokersTableRow,
+ BrokersTableRow['onlinePartitionCount']
+>;
+
+export const OnlinePartitions = ({ row }: OnlinePartitionsProps) => {
+ const { onlinePartitionCount, offlinePartitionCount } = row.original;
+
+ if (
+ onlinePartitionCount === undefined ||
+ offlinePartitionCount === undefined
+ ) {
+ return null;
+ }
+
+ return (
+ 0}
+ />
+ );
+};
diff --git a/frontend/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx b/frontend/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx
index e98f28e52..9dc40591e 100644
--- a/frontend/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx
+++ b/frontend/src/components/Brokers/BrokersList/__test__/BrokersList.spec.tsx
@@ -72,11 +72,13 @@ describe('BrokersList Component', () => {
},
}));
renderComponent();
- const onlineWidget = screen.getByText(
+ const onlineWidgets = screen.getAllByText(
clusterStatsPayload.onlinePartitionCount
);
- expect(onlineWidget).toBeInTheDocument();
- expect(onlineWidget).toHaveStyle({ color: '#E51A1A' });
+ onlineWidgets.forEach((widget) => {
+ expect(widget).toBeInTheDocument();
+ expect(widget).toHaveStyle({ color: '#E51A1A' });
+ });
});
it('shows right count when offlinePartitionCount > 0', async () => {
(useClusterStats as jest.Mock).mockImplementation(() => ({
@@ -154,49 +156,24 @@ describe('BrokersList Component', () => {
expect(screen.queryByRole('tooltip')).not.toBeInTheDocument()
);
});
+ });
+ });
- describe('when diskUsage', () => {
- describe('is empty', () => {
- beforeEach(() => {
- (useClusterStats as jest.Mock).mockImplementation(() => ({
- data: { ...clusterStatsPayload, diskUsage: undefined },
- }));
- });
-
- it('renders list of all brokers', async () => {
- renderComponent();
- expect(screen.getByRole('table')).toBeInTheDocument();
- expect(screen.getAllByRole('row').length).toEqual(3);
- });
- });
-
- describe('was NOT set for second broker', () => {
- beforeEach(() => {
- (useClusterStats as jest.Mock).mockImplementation(() => ({
- data: {
- ...clusterStatsPayload,
- diskUsage: [clusterStatsPayload.diskUsage[0]],
- },
- }));
- });
-
- it('renders list of all brokers', async () => {
- renderComponent();
- expect(screen.getByRole('table')).toBeInTheDocument();
- expect(screen.getAllByRole('row').length).toEqual(3);
- });
- });
- });
+ describe('when diskUsage is empty', () => {
+ beforeEach(() => {
+ (useBrokers as jest.Mock).mockImplementation(() => ({
+ data: brokersPayload,
+ }));
+ (useClusterStats as jest.Mock).mockImplementation(() => ({
+ data: { ...clusterStatsPayload, diskUsage: undefined },
+ }));
});
- describe('when the brokers list is empty', () => {
+ describe('when it has no brokers', () => {
beforeEach(() => {
(useBrokers as jest.Mock).mockImplementation(() => ({
data: [],
}));
- (useClusterStats as jest.Mock).mockImplementation(() => ({
- data: clusterStatsPayload,
- }));
});
it('renders empty table', async () => {
@@ -207,6 +184,22 @@ describe('BrokersList Component', () => {
).toBeInTheDocument();
});
});
+
+ it('renders list of all brokers', async () => {
+ renderComponent();
+ expect(screen.getByRole('table')).toBeInTheDocument();
+ expect(screen.getAllByRole('row').length).toEqual(3);
+ });
+ it('opens broker when row clicked', async () => {
+ renderComponent();
+ await userEvent.click(screen.getByRole('cell', { name: '100' }));
+
+ await waitFor(() =>
+ expect(mockedUsedNavigate).toBeCalledWith(
+ clusterBrokerPath(clusterName, '100')
+ )
+ );
+ });
});
});
});
diff --git a/frontend/src/components/Brokers/BrokersList/lib/constants.ts b/frontend/src/components/Brokers/BrokersList/lib/constants.ts
new file mode 100644
index 000000000..48e4e0cb4
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/lib/constants.ts
@@ -0,0 +1,5 @@
+export const NA = 'N/A';
+export const NA_DISK_USAGE = {
+ segmentCount: NA,
+ segmentSize: NA,
+};
diff --git a/frontend/src/components/Brokers/BrokersList/lib/index.ts b/frontend/src/components/Brokers/BrokersList/lib/index.ts
new file mode 100644
index 000000000..7a616f8d2
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/lib/index.ts
@@ -0,0 +1,3 @@
+export * from './utils';
+export * from './constants';
+export * from './types';
diff --git a/frontend/src/components/Brokers/BrokersList/lib/types.ts b/frontend/src/components/Brokers/BrokersList/lib/types.ts
new file mode 100644
index 000000000..7928862a1
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/lib/types.ts
@@ -0,0 +1,13 @@
+export type BrokersTableRow = {
+ brokerId: number;
+ size: number | undefined;
+ count: number | undefined;
+ port: number | undefined;
+ host: string | undefined;
+ partitionsLeader: number | undefined;
+ partitionsSkew: number | undefined;
+ leadersSkew: number | undefined;
+ onlinePartitionCount: number | undefined;
+ offlinePartitionCount: number | undefined;
+ activeControllers: number | undefined;
+};
diff --git a/frontend/src/components/Brokers/BrokersList/lib/utils.ts b/frontend/src/components/Brokers/BrokersList/lib/utils.ts
new file mode 100644
index 000000000..1eb6b2886
--- /dev/null
+++ b/frontend/src/components/Brokers/BrokersList/lib/utils.ts
@@ -0,0 +1,78 @@
+import { Broker, BrokerDiskUsage } from 'generated-sources';
+import * as Cell from 'components/Brokers/BrokersList/TableCells/TableCells';
+import { createColumnHelper } from '@tanstack/react-table';
+import { keyBy } from 'lib/functions/keyBy';
+import SkewHeader from 'components/Brokers/BrokersList/SkewHeader/SkewHeader';
+
+import { BrokersTableRow } from './types';
+import { NA_DISK_USAGE } from './constants';
+
+type GetBrokersTableRowsParams = {
+ brokers: Broker[] | undefined;
+ diskUsage: BrokerDiskUsage[] | undefined;
+ activeControllers: number | undefined;
+ onlinePartitionCount: number | undefined;
+ offlinePartitionCount: number | undefined;
+};
+
+export const getBrokersTableRows = ({
+ brokers = [],
+ diskUsage = [],
+ activeControllers,
+ onlinePartitionCount,
+ offlinePartitionCount,
+}: GetBrokersTableRowsParams): BrokersTableRow[] => {
+ if (!brokers || brokers.length === 0) {
+ return [];
+ }
+
+ const diskUsageByBroker = keyBy(diskUsage, 'brokerId');
+
+ return brokers.map((broker) => {
+ const diskUse = diskUsageByBroker[broker.id] || NA_DISK_USAGE;
+
+ return {
+ brokerId: broker.id,
+ size: diskUse.segmentSize,
+ count: diskUse.segmentCount,
+ port: broker.port,
+ host: broker.host,
+ partitionsLeader: broker.partitionsLeader,
+ partitionsSkew: broker.partitionsSkew,
+ leadersSkew: broker.leadersSkew,
+ onlinePartitionCount,
+ offlinePartitionCount,
+ activeControllers,
+ };
+ });
+};
+
+export const getBrokersTableColumns = () => {
+ const columnHelper = createColumnHelper();
+
+ return [
+ columnHelper.accessor('brokerId', {
+ header: 'Broker ID',
+ cell: Cell.BrokerId,
+ }),
+ columnHelper.accessor('size', {
+ header: 'Disk usage',
+ cell: Cell.DiscUsage,
+ }),
+ columnHelper.accessor('partitionsSkew', {
+ header: SkewHeader,
+ cell: Cell.Skew,
+ }),
+ columnHelper.accessor('partitionsLeader', { header: 'Leaders' }),
+ columnHelper.accessor('leadersSkew', {
+ header: 'Leader skew',
+ cell: Cell.Skew,
+ }),
+ columnHelper.accessor('onlinePartitionCount', {
+ header: 'Online partitions',
+ cell: Cell.OnlinePartitions,
+ }),
+ columnHelper.accessor('port', { header: 'Port' }),
+ columnHelper.accessor('host', { header: 'Host' }),
+ ];
+};
diff --git a/frontend/src/components/NavBar/NavBar.styled.ts b/frontend/src/components/NavBar/NavBar.styled.ts
index 8c4dd6f5b..d9013dcdd 100644
--- a/frontend/src/components/NavBar/NavBar.styled.ts
+++ b/frontend/src/components/NavBar/NavBar.styled.ts
@@ -130,18 +130,20 @@ export const Hyperlink = styled(Link)(
align-items: center;
gap: 8px;
- margin: 0;
+ margin: 0 0 0 8px;
padding: 0.5rem 0.75rem;
font-family: Inter, sans-serif;
font-style: normal;
font-weight: bold;
- font-size: 12px;
+ font-size: 22px;
line-height: 16px;
color: ${theme.default.color.normal};
+
&:hover {
color: ${theme.default.color.normal};
}
+
text-decoration: none;
word-break: break-word;
cursor: pointer;
diff --git a/frontend/src/components/NavBar/NavBar.tsx b/frontend/src/components/NavBar/NavBar.tsx
index e025c892c..1a58c7e7b 100644
--- a/frontend/src/components/NavBar/NavBar.tsx
+++ b/frontend/src/components/NavBar/NavBar.tsx
@@ -69,7 +69,7 @@ const NavBar: React.FC = ({ onBurgerClick }) => {
- Kafbat UI
+ kafbat UI
diff --git a/frontend/src/components/NavBar/__tests__/NavBar.spec.tsx b/frontend/src/components/NavBar/__tests__/NavBar.spec.tsx
index 2e37613ba..a94d941e5 100644
--- a/frontend/src/components/NavBar/__tests__/NavBar.spec.tsx
+++ b/frontend/src/components/NavBar/__tests__/NavBar.spec.tsx
@@ -20,13 +20,13 @@ describe('NavBar', () => {
})),
});
- render();
+ render();
});
it('correctly renders header', () => {
const header = screen.getByLabelText('Page Header');
expect(header).toBeInTheDocument();
- expect(within(header).getByText('Kafbat UI')).toBeInTheDocument();
+ expect(within(header).getByText('kafbat UI')).toBeInTheDocument();
expect(within(header).getAllByRole('separator').length).toEqual(3);
expect(
within(header).getByRole('button', burgerButtonOptions)
diff --git a/frontend/src/components/PageContainer/__tests__/PageContainer.spec.tsx b/frontend/src/components/PageContainer/__tests__/PageContainer.spec.tsx
index ca91cd207..b6d654ea5 100644
--- a/frontend/src/components/PageContainer/__tests__/PageContainer.spec.tsx
+++ b/frontend/src/components/PageContainer/__tests__/PageContainer.spec.tsx
@@ -9,9 +9,11 @@ import { Cluster, ServerStatus } from 'generated-sources';
const burgerButtonOptions = { name: 'burger' };
jest.mock('components/Version/Version', () => () => Version
);
+
interface DataType {
data: Cluster[] | undefined;
}
+
jest.mock('lib/hooks/api/clusters');
const mockedNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
@@ -30,7 +32,7 @@ describe('Page Container', () => {
})),
});
render(
-
+
child
,
{
diff --git a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx
index 347623d22..99eb6bac4 100644
--- a/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx
+++ b/frontend/src/components/Topics/Topic/Messages/Filters/Filters.tsx
@@ -13,7 +13,7 @@ import {
} from 'generated-sources';
import React, { useContext } from 'react';
import omitBy from 'lodash/omitBy';
-import { useNavigate, useLocation, useSearchParams } from 'react-router-dom';
+import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
import MultiSelect from 'components/common/MultiSelect/MultiSelect.styled';
import { Option } from 'react-multi-select-component';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
@@ -55,11 +55,17 @@ export interface FiltersProps {
meta: TopicMessageConsuming;
isFetching: boolean;
messageEventType?: string;
+
addMessage(content: { message: TopicMessage; prepend: boolean }): void;
+
resetMessages(): void;
+
updatePhase(phase: string): void;
+
updateMeta(meta: TopicMessageConsuming): void;
+
setIsFetching(status: boolean): void;
+
setMessageType(messageType: string): void;
}
@@ -152,7 +158,7 @@ const Filters: React.FC = ({
const [queryType, setQueryType] = React.useState(
activeFilter.name
- ? MessageFilterType.GROOVY_SCRIPT
+ ? MessageFilterType.CEL_SCRIPT
: MessageFilterType.STRING_CONTAINS
);
const [query, setQuery] = React.useState(searchParams.get('q') || '');
@@ -205,10 +211,7 @@ const Filters: React.FC = ({
const handleFiltersSubmit = (currentOffset: string) => {
const nextAttempt = Number(searchParams.get('attempt') || 0) + 1;
const props: Query = {
- q:
- queryType === MessageFilterType.GROOVY_SCRIPT
- ? activeFilter.code
- : query,
+ q: queryType === MessageFilterType.CEL_SCRIPT ? activeFilter.code : query,
filterQueryType: queryType,
attempt: nextAttempt,
limit: PER_PAGE,
@@ -309,7 +312,7 @@ const Filters: React.FC = ({
JSON.stringify({ index, ...newActiveFilter })
);
setActiveFilter({ index, ...newActiveFilter });
- setQueryType(MessageFilterType.GROOVY_SCRIPT);
+ setQueryType(MessageFilterType.CEL_SCRIPT);
};
const composeMessageFilter = (filter: FilterEdit): ActiveMessageFilter => ({
diff --git a/frontend/src/components/common/Logo/Logo.styled.ts b/frontend/src/components/common/Logo/Logo.styled.ts
new file mode 100644
index 000000000..51d649c62
--- /dev/null
+++ b/frontend/src/components/common/Logo/Logo.styled.ts
@@ -0,0 +1,5 @@
+import styled from 'styled-components';
+
+export const Logo = styled.svg`
+ fill: ${({ theme }) => theme.logo.color};
+`;
diff --git a/frontend/src/components/common/Logo/Logo.tsx b/frontend/src/components/common/Logo/Logo.tsx
index b209f32b2..d149d6511 100644
--- a/frontend/src/components/common/Logo/Logo.tsx
+++ b/frontend/src/components/common/Logo/Logo.tsx
@@ -1,19 +1,18 @@
import React from 'react';
+import * as S from './Logo.styled';
+
const Logo: React.FC = () => {
return (
-
+
+
);
};
diff --git a/frontend/src/components/common/NewTable/SizeCell.tsx b/frontend/src/components/common/NewTable/SizeCell.tsx
index 7a230be81..4b472b5bd 100644
--- a/frontend/src/components/common/NewTable/SizeCell.tsx
+++ b/frontend/src/components/common/NewTable/SizeCell.tsx
@@ -2,16 +2,15 @@ import React from 'react';
import { CellContext } from '@tanstack/react-table';
import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-type AsAny = any;
-
-const SizeCell: React.FC<
- CellContext & { renderSegments?: boolean; precision?: number }
-> = ({ getValue, row, renderSegments = false, precision = 0 }) => (
- <>
+const SizeCell = ({
+ getValue,
+ precision = 0,
+}: CellContext & {
+ precision?: number;
+}) => {
+ return (
()} precision={precision} />
- {renderSegments ? `, ${row?.original.count} segment(s)` : null}
- >
-);
+ );
+};
export default SizeCell;
diff --git a/frontend/src/components/common/NewTable/SizeCellCount.tsx b/frontend/src/components/common/NewTable/SizeCellCount.tsx
new file mode 100644
index 000000000..80df59b9f
--- /dev/null
+++ b/frontend/src/components/common/NewTable/SizeCellCount.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { CellContext } from '@tanstack/react-table';
+import BytesFormatted from 'components/common/BytesFormatted/BytesFormatted';
+
+const SizeCellCount = ({
+ getValue,
+ row,
+ precision = 0,
+}: CellContext & {
+ precision?: number;
+}) => {
+ return (
+ <>
+ ()}
+ precision={precision}
+ />
+ {`, ${row.original.count} segment(s)`}
+ >
+ );
+};
+
+export default SizeCellCount;
diff --git a/frontend/src/components/common/NewTable/Table.tsx b/frontend/src/components/common/NewTable/Table.tsx
index 42d406b4f..df4421c98 100644
--- a/frontend/src/components/common/NewTable/Table.tsx
+++ b/frontend/src/components/common/NewTable/Table.tsx
@@ -1,20 +1,20 @@
import React from 'react';
+import type {
+ ColumnDef,
+ OnChangeFn,
+ PaginationState,
+ Row,
+ SortingState,
+} from '@tanstack/react-table';
import {
flexRender,
getCoreRowModel,
getExpandedRowModel,
+ getPaginationRowModel,
getSortedRowModel,
useReactTable,
- getPaginationRowModel,
} from '@tanstack/react-table';
-import type {
- Row,
- SortingState,
- OnChangeFn,
- PaginationState,
- ColumnDef,
-} from '@tanstack/react-table';
-import { useSearchParams, useLocation } from 'react-router-dom';
+import { useLocation, useSearchParams } from 'react-router-dom';
import { PER_PAGE } from 'lib/constants';
import { Button } from 'components/common/Button/Button';
import Input from 'components/common/Input/Input';
@@ -26,10 +26,13 @@ import ExpanderCell from './ExpanderCell';
import SelectRowCell from './SelectRowCell';
import SelectRowHeader from './SelectRowHeader';
-export interface TableProps {
+export interface TableProps {
data: TData[];
pageCount?: number;
- columns: ColumnDef[];
+
+ // https://github.com/TanStack/table/issues/4382
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ columns: ColumnDef[];
// Server-side processing: sorting, pagination
serverSideProcessing?: boolean;
@@ -118,7 +121,7 @@ const getSortingFromSearchParams = (searchParams: URLSearchParams) => {
* - use URLSearchParams to get the pagination and sorting state from the url for your server side processing.
*/
-function Table({
+function Table({
data,
pageCount,
columns,
@@ -134,7 +137,7 @@ function Table({
onRowHover,
onMouseLeave,
setRowId,
-}: TableProps) {
+}: TableProps) {
const [searchParams, setSearchParams] = useSearchParams();
const location = useLocation();
const [rowSelection, setRowSelection] = React.useState({});
diff --git a/frontend/src/components/common/NewTable/__test__/Table.spec.tsx b/frontend/src/components/common/NewTable/__test__/Table.spec.tsx
index e31a88846..b22e7c0ec 100644
--- a/frontend/src/components/common/NewTable/__test__/Table.spec.tsx
+++ b/frontend/src/components/common/NewTable/__test__/Table.spec.tsx
@@ -94,7 +94,7 @@ const columns: ColumnDef[] = [
const ExpandedRow: React.FC = () => I am expanded row
;
-interface Props extends TableProps {
+interface Props extends TableProps {
path?: string;
}
diff --git a/frontend/src/components/common/PageLoader/PageLoader.styled.ts b/frontend/src/components/common/PageLoader/PageLoader.styled.ts
index f38f21c0b..36c5848e0 100644
--- a/frontend/src/components/common/PageLoader/PageLoader.styled.ts
+++ b/frontend/src/components/common/PageLoader/PageLoader.styled.ts
@@ -1,10 +1,15 @@
import styled from 'styled-components';
-export const Wrapper = styled.div`
+export interface PageLoaderProps {
+ fullSize?: boolean;
+}
+
+export const Wrapper = styled.div`
display: flex;
justify-content: center;
align-items: center;
- padding-top: 15%;
height: 100%;
width: 100%;
+ background-color: ${({ theme }) => theme.default.backgroundColor};
+ ${({ fullSize }) => (fullSize ? `min-height: 100vh;` : 'padding-top: 15%;')}
`;
diff --git a/frontend/src/components/common/PageLoader/PageLoader.tsx b/frontend/src/components/common/PageLoader/PageLoader.tsx
index 674ab0f0c..b568357dd 100644
--- a/frontend/src/components/common/PageLoader/PageLoader.tsx
+++ b/frontend/src/components/common/PageLoader/PageLoader.tsx
@@ -2,9 +2,10 @@ import React from 'react';
import Spinner from 'components/common/Spinner/Spinner';
import * as S from './PageLoader.styled';
+import { PageLoaderProps } from './PageLoader.styled';
-const PageLoader: React.FC = () => (
-
+const PageLoader: React.FC = ({ fullSize }) => (
+
);
diff --git a/frontend/src/lib/hooks/api/__tests__/topics.spec.ts b/frontend/src/lib/hooks/api/__tests__/topics.spec.ts
index 34b864fd4..802368495 100644
--- a/frontend/src/lib/hooks/api/__tests__/topics.spec.ts
+++ b/frontend/src/lib/hooks/api/__tests__/topics.spec.ts
@@ -77,7 +77,6 @@ describe('Topics hooks', () => {
minInSyncReplicas: 0,
cleanupPolicy: '',
retentionMs: 0,
- retentionBytes: 0,
maxMessageBytes: 0,
customParams: [],
};
diff --git a/frontend/src/lib/hooks/useAppParams.tsx b/frontend/src/lib/hooks/useAppParams.tsx
index 8cd1ebfff..773b6ccb6 100644
--- a/frontend/src/lib/hooks/useAppParams.tsx
+++ b/frontend/src/lib/hooks/useAppParams.tsx
@@ -1,7 +1,19 @@
import { Params, useParams } from 'react-router-dom';
+import { ClusterNameRoute } from 'lib/paths';
export default function useAppParams<
T extends { [K in keyof Params]?: string }
>() {
- return useParams() as T;
+ const params = useParams() as T;
+
+ const hasClusterName = (
+ checkingParams: T
+ ): checkingParams is T & ClusterNameRoute =>
+ typeof checkingParams.clusterName !== 'undefined';
+
+ if (hasClusterName(params)) {
+ params.clusterName = decodeURIComponent(params.clusterName);
+ }
+
+ return params;
}
diff --git a/frontend/src/lib/paths.ts b/frontend/src/lib/paths.ts
index 9cee7ca28..62b19568c 100644
--- a/frontend/src/lib/paths.ts
+++ b/frontend/src/lib/paths.ts
@@ -24,7 +24,12 @@ export const accessErrorPage = '/403';
export const clusterPath = (
clusterName: ClusterName = RouteParams.clusterName
-) => `/ui/clusters/${clusterName}`;
+) =>
+ `/ui/clusters/${
+ clusterName === RouteParams.clusterName
+ ? clusterName
+ : encodeURIComponent(clusterName)
+ }`;
export type ClusterNameRoute = { clusterName: ClusterName };
diff --git a/frontend/src/theme/theme.ts b/frontend/src/theme/theme.ts
index 8426d3c2f..44e19eb5b 100644
--- a/frontend/src/theme/theme.ts
+++ b/frontend/src/theme/theme.ts
@@ -35,15 +35,15 @@ const Colors = {
'60': '#29A352',
},
brand: {
- '5': '#E8E8FC',
- '10': '#D1D1FA',
- '15': '#B8BEF9',
- '20': '#A3A3F5',
- '30': '#7E7EF1',
- '40': '#6666FF',
- '50': '#4C4CFF',
- '60': '#1717CF',
- '70': '#1414B8',
+ '5': '#F1F2F3',
+ '10': '#E3E6E8',
+ '15': '#D5DADD',
+ '20': '#C7CED1',
+ '30': '#ABB5BA',
+ '40': '#8F9CA3',
+ '50': '#2F3639',
+ '60': '#22282A',
+ '70': '#171A1C',
},
red: {
'10': '#FAD1D1',
@@ -313,6 +313,9 @@ const baseTheme = {
export const theme = {
...baseTheme,
+ logo: {
+ color: Colors.brand[70],
+ },
version: {
currentVersion: {
color: Colors.neutral[30],
@@ -389,8 +392,8 @@ export const theme = {
primary: {
backgroundColor: {
normal: Colors.brand[50],
- hover: Colors.brand[60],
- active: Colors.brand[70],
+ hover: Colors.brand[70],
+ active: Colors.brand[60],
disabled: Colors.neutral[5],
},
color: {
@@ -756,6 +759,9 @@ export type ThemeType = typeof theme;
export const darkTheme: ThemeType = {
...baseTheme,
+ logo: {
+ color: '#FDFDFD',
+ },
version: {
currentVersion: {
color: Colors.neutral[50],
@@ -831,13 +837,13 @@ export const darkTheme: ThemeType = {
button: {
primary: {
backgroundColor: {
- normal: Colors.brand[30],
- hover: Colors.brand[20],
- active: Colors.brand[10],
- disabled: Colors.neutral[75],
+ normal: Colors.brand[10],
+ hover: Colors.brand[5],
+ active: Colors.brand[20],
+ disabled: Colors.brand[60],
},
color: {
- normal: Colors.neutral[0],
+ normal: Colors.neutral[70],
disabled: Colors.neutral[60],
},
invertedColors: {
@@ -848,9 +854,9 @@ export const darkTheme: ThemeType = {
},
secondary: {
backgroundColor: {
- normal: Colors.blue[80],
- hover: Colors.blue[70],
- active: Colors.blue[60],
+ normal: Colors.brand[50],
+ hover: Colors.brand[70],
+ active: Colors.brand[60],
disabled: Colors.neutral[75],
},
color: {
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts
index b4cdd022a..63856bd6d 100644
--- a/frontend/vite.config.ts
+++ b/frontend/vite.config.ts
@@ -7,19 +7,34 @@ import {
import react from '@vitejs/plugin-react-swc';
import tsconfigPaths from 'vite-tsconfig-paths';
import { ViteEjsPlugin } from 'vite-plugin-ejs';
+import checker from 'vite-plugin-checker';
export default defineConfig(({ mode }) => {
process.env = { ...process.env, ...loadEnv(mode, process.cwd()) };
+ const isDevMode = mode === 'development';
+ const isProxy = process.env.VITE_DEV_PROXY;
+
+ const defaultPlugins = [
+ react(),
+ tsconfigPaths(),
+ ViteEjsPlugin({
+ PUBLIC_PATH: !isDevMode ? 'PUBLIC-PATH-VARIABLE' : '',
+ }),
+ ];
+
+ const prodPlugins = [...defaultPlugins, splitVendorChunkPlugin()];
+
+ const devPlugins = [
+ ...defaultPlugins,
+ checker({
+ overlay: { initialIsOpen: false },
+ typescript: true,
+ eslint: { lintCommand: 'eslint --ext .tsx,.ts src/' },
+ }),
+ ];
const defaultConfig: UserConfigExport = {
- plugins: [
- react(),
- tsconfigPaths(),
- splitVendorChunkPlugin(),
- ViteEjsPlugin({
- PUBLIC_PATH: mode !== 'development' ? 'PUBLIC-PATH-VARIABLE' : '',
- }),
- ],
+ plugins: isDevMode ? devPlugins : prodPlugins,
server: {
port: 3000,
},
@@ -59,25 +74,29 @@ export default defineConfig(({ mode }) => {
'process.env.VITE_COMMIT': `"${process.env.VITE_COMMIT}"`,
},
};
- const proxy = process.env.VITE_DEV_PROXY;
- if (mode === 'development' && proxy) {
+
+ const proxyDevServerConfig = {
+ ...defaultConfig.server,
+ open: true,
+ proxy: {
+ '/api': {
+ target: isProxy,
+ changeOrigin: true,
+ secure: false,
+ },
+ '/actuator/info': {
+ target: isProxy,
+ changeOrigin: true,
+ secure: false,
+ },
+ },
+ };
+
+ if (isDevMode && isProxy) {
return {
...defaultConfig,
server: {
- ...defaultConfig.server,
- open: true,
- proxy: {
- '/api': {
- target: proxy,
- changeOrigin: true,
- secure: false,
- },
- '/actuator/info': {
- target: proxy,
- changeOrigin: true,
- secure: false,
- },
- },
+ ...proxyDevServerConfig,
},
};
}