1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Merge branch 'master' into fix/store.loadAll

# Conflicts:
#	src/renderer/api/kube-watch-api.ts
#	src/renderer/components/app.tsx
#	src/renderer/components/item-object-list/item-list-layout.tsx
This commit is contained in:
Roman 2021-02-01 17:57:36 +02:00
commit cd1c8fbd16
41 changed files with 604 additions and 397 deletions

View File

@ -12,7 +12,7 @@ endif
binaries/client:
yarn download-bins
node_modules:
node_modules: yarn.lock
yarn install --frozen-lockfile
yarn check --verify-tree --integrity

View File

@ -2796,7 +2796,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -3226,6 +3227,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@ -4367,6 +4369,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@ -4381,6 +4384,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@ -4390,6 +4394,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
"dev": true,
"optional": true,
"requires": {
"lru-cache": "^6.0.0"
}
@ -4399,6 +4404,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
@ -4407,7 +4413,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -5398,7 +5405,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.3",
@ -6275,7 +6283,8 @@
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==",
"dev": true
"dev": true,
"optional": true
},
"v8-to-istanbul": {
"version": "7.0.0",

View File

@ -2868,7 +2868,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -3298,6 +3299,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@ -4460,6 +4462,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@ -4474,6 +4477,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@ -4483,6 +4487,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
"dev": true,
"optional": true,
"requires": {
"lru-cache": "^6.0.0"
}
@ -4492,6 +4497,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
@ -4500,7 +4506,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -5516,7 +5523,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.3",
@ -6406,7 +6414,8 @@
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==",
"dev": true
"dev": true,
"optional": true
},
"v8-to-istanbul": {
"version": "7.0.0",

View File

@ -2816,7 +2816,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -3246,6 +3247,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@ -4394,6 +4396,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@ -4408,6 +4411,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
@ -5434,7 +5438,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.3",
@ -6311,7 +6316,8 @@
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==",
"dev": true
"dev": true,
"optional": true
},
"v8-to-istanbul": {
"version": "7.0.0",

View File

@ -2796,7 +2796,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -3226,6 +3227,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@ -4382,6 +4384,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@ -4396,6 +4399,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@ -4405,6 +4409,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
"dev": true,
"optional": true,
"requires": {
"lru-cache": "^6.0.0"
}
@ -4414,6 +4419,7 @@
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
@ -4422,7 +4428,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -5438,7 +5445,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.3",
@ -6315,7 +6323,8 @@
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz",
"integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==",
"dev": true
"dev": true,
"optional": true
},
"v8-to-istanbul": {
"version": "7.0.0",

View File

@ -2901,7 +2901,8 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
"dev": true,
"optional": true
},
"har-schema": {
"version": "2.0.0",
@ -3337,6 +3338,7 @@
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"optional": true,
"requires": {
"is-docker": "^2.0.0"
}
@ -4533,6 +4535,7 @@
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
"dev": true,
"optional": true,
"requires": {
"growly": "^1.3.0",
"is-wsl": "^2.2.0",
@ -4547,6 +4550,7 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@ -4556,6 +4560,7 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
"dev": true,
"optional": true,
"requires": {
"lru-cache": "^6.0.0"
}
@ -4564,13 +4569,15 @@
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true
"dev": true,
"optional": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"optional": true,
"requires": {
"isexe": "^2.0.0"
}
@ -4579,7 +4586,8 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
"dev": true,
"optional": true
}
}
},
@ -5595,7 +5603,8 @@
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
"dev": true,
"optional": true
},
"signal-exit": {
"version": "3.0.3",

View File

@ -4,7 +4,7 @@ import { exec } from "child_process";
const AppPaths: Partial<Record<NodeJS.Platform, string>> = {
"win32": "./dist/win-unpacked/Lens.exe",
"linux": "./dist/linux-unpacked/kontena-lens",
"linux": "./dist/linux-unpacked/lens",
"darwin": "./dist/mac/Lens.app/Contents/MacOS/Lens",
};

View File

@ -2,7 +2,7 @@
"name": "kontena-lens",
"productName": "Lens",
"description": "Lens - The Kubernetes IDE",
"version": "4.1.0-alpha.0",
"version": "4.1.0-alpha.1",
"main": "static/build/main.js",
"copyright": "© 2020, Mirantis, Inc.",
"license": "MIT",
@ -42,7 +42,7 @@
"typedocs-extensions-api": "yarn run typedoc --ignoreCompilerErrors --readme docs/extensions/typedoc-readme.md.tpl --name @k8slens/extensions --out docs/extensions/api --mode library --excludePrivate --hideBreadcrumbs --includes src/ src/extensions/extension-api.ts"
},
"config": {
"bundledKubectlVersion": "1.17.15",
"bundledKubectlVersion": "1.18.15",
"bundledHelmVersion": "3.4.2"
},
"engines": {
@ -103,7 +103,11 @@
],
"linux": {
"category": "Network",
"executableName": "lens",
"artifactName": "${productName}-${version}.${arch}.${ext}",
"target": [
"deb",
"rpm",
"snap",
"AppImage"
],

View File

@ -23,10 +23,10 @@ const kubectlMap: Map<string, string> = new Map([
["1.14", "1.14.10"],
["1.15", "1.15.11"],
["1.16", "1.16.15"],
["1.17", bundledVersion],
["1.18", "1.18.14"],
["1.19", "1.19.5"],
["1.20", "1.20.0"]
["1.17", "1.17.17"],
["1.18", bundledVersion],
["1.19", "1.19.7"],
["1.20", "1.20.2"]
]);
const packageMirrors: Map<string, string> = new Map([
["default", "https://storage.googleapis.com/kubernetes-release/release"],

View File

@ -11,8 +11,11 @@ import { navigation } from "../../navigation";
import { ItemListLayout } from "../item-object-list/item-list-layout";
import { SearchInputUrl } from "../input";
enum sortBy {
enum columnId {
name = "name",
description = "description",
version = "version",
appVersion = "app-version",
repo = "repo",
}
@ -53,13 +56,15 @@ export class HelmCharts extends Component<Props> {
return (
<>
<ItemListLayout
isConfigurable
tableId="helm_charts"
className="HelmCharts"
store={helmChartStore}
isClusterScoped={true}
isSelectable={false}
sortingCallbacks={{
[sortBy.name]: (chart: HelmChart) => chart.getName(),
[sortBy.repo]: (chart: HelmChart) => chart.getRepository(),
[columnId.name]: (chart: HelmChart) => chart.getName(),
[columnId.repo]: (chart: HelmChart) => chart.getRepository(),
}}
searchFilters={[
(chart: HelmChart) => chart.getName(),
@ -74,13 +79,12 @@ export class HelmCharts extends Component<Props> {
<SearchInputUrl placeholder={`Search Helm Charts`} />
)}
renderTableHeader={[
{ className: "icon" },
{ title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Description", className: "description" },
{ title: "Version", className: "version" },
{ title: "App Version", className: "app-version" },
{ title: "Repository", className: "repository", sortBy: sortBy.repo },
{ className: "icon", showWithColumn: columnId.name },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ title: "Description", className: "description", id: columnId.description },
{ title: "Version", className: "version", id: columnId.version },
{ title: "App Version", className: "app-version", id: columnId.appVersion },
{ title: "Repository", className: "repository", sortBy: columnId.repo, id: columnId.repo },
]}
renderTableContents={(chart: HelmChart) => [
<figure key="image">
@ -93,7 +97,8 @@ export class HelmCharts extends Component<Props> {
chart.getDescription(),
chart.getVersion(),
chart.getAppVersion(),
{ title: chart.getRepository(), className: chart.getRepository().toLowerCase() }
{ title: chart.getRepository(), className: chart.getRepository().toLowerCase() },
{ className: "menu" }
]}
detailsItem={this.selectedChart}
onDetails={this.showDetails}

View File

@ -14,11 +14,13 @@ import { ItemListLayout } from "../item-object-list/item-list-layout";
import { HelmReleaseMenu } from "./release-menu";
import { secretsStore } from "../+config-secrets/secrets.store";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
revision = "revision",
chart = "chart",
version = "version",
appVersion = "app-version",
status = "status",
updated = "update"
}
@ -81,16 +83,18 @@ export class HelmReleases extends Component<Props> {
return (
<>
<ItemListLayout
isConfigurable
tableId="helm_releases"
className="HelmReleases"
store={releaseStore}
dependentStores={[secretsStore]}
sortingCallbacks={{
[sortBy.name]: (release: HelmRelease) => release.getName(),
[sortBy.namespace]: (release: HelmRelease) => release.getNs(),
[sortBy.revision]: (release: HelmRelease) => release.getRevision(),
[sortBy.chart]: (release: HelmRelease) => release.getChart(),
[sortBy.status]: (release: HelmRelease) => release.getStatus(),
[sortBy.updated]: (release: HelmRelease) => release.getUpdated(false, false),
[columnId.name]: (release: HelmRelease) => release.getName(),
[columnId.namespace]: (release: HelmRelease) => release.getNs(),
[columnId.revision]: (release: HelmRelease) => release.getRevision(),
[columnId.chart]: (release: HelmRelease) => release.getChart(),
[columnId.status]: (release: HelmRelease) => release.getStatus(),
[columnId.updated]: (release: HelmRelease) => release.getUpdated(false, false),
}}
searchFilters={[
(release: HelmRelease) => release.getName(),
@ -101,14 +105,14 @@ export class HelmReleases extends Component<Props> {
]}
renderHeaderTitle="Releases"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Chart", className: "chart", sortBy: sortBy.chart },
{ title: "Revision", className: "revision", sortBy: sortBy.revision },
{ title: "Version", className: "version" },
{ title: "App Version", className: "app-version" },
{ title: "Status", className: "status", sortBy: sortBy.status },
{ title: "Updated", className: "updated", sortBy: sortBy.updated },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Chart", className: "chart", sortBy: columnId.chart, id: columnId.chart },
{ title: "Revision", className: "revision", sortBy: columnId.revision, id: columnId.revision },
{ title: "Version", className: "version", id: columnId.version },
{ title: "App Version", className: "app-version", id: columnId.appVersion },
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
{ title: "Updated", className: "updated", sortBy: columnId.updated, id: columnId.updated },
]}
renderTableContents={(release: HelmRelease) => {
const version = release.getVersion();

View File

@ -11,13 +11,15 @@ import { Badge } from "../badge";
import { cssNames } from "../../utils";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
metrics = "metrics",
minPods = "min-pods",
maxPods = "max-pods",
replicas = "replicas",
age = "age",
status = "status"
}
interface Props extends RouteComponentProps<IHpaRouteParams> {
@ -37,28 +39,30 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="configuration_hpa"
className="HorizontalPodAutoscalers" store={hpaStore}
sortingCallbacks={{
[sortBy.name]: (item: HorizontalPodAutoscaler) => item.getName(),
[sortBy.namespace]: (item: HorizontalPodAutoscaler) => item.getNs(),
[sortBy.minPods]: (item: HorizontalPodAutoscaler) => item.getMinPods(),
[sortBy.maxPods]: (item: HorizontalPodAutoscaler) => item.getMaxPods(),
[sortBy.replicas]: (item: HorizontalPodAutoscaler) => item.getReplicas()
[columnId.name]: (item: HorizontalPodAutoscaler) => item.getName(),
[columnId.namespace]: (item: HorizontalPodAutoscaler) => item.getNs(),
[columnId.minPods]: (item: HorizontalPodAutoscaler) => item.getMinPods(),
[columnId.maxPods]: (item: HorizontalPodAutoscaler) => item.getMaxPods(),
[columnId.replicas]: (item: HorizontalPodAutoscaler) => item.getReplicas()
}}
searchFilters={[
(item: HorizontalPodAutoscaler) => item.getSearchFields()
]}
renderHeaderTitle="Horizontal Pod Autoscalers"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Metrics", className: "metrics" },
{ title: "Min Pods", className: "min-pods", sortBy: sortBy.minPods },
{ title: "Max Pods", className: "max-pods", sortBy: sortBy.maxPods },
{ title: "Replicas", className: "replicas", sortBy: sortBy.replicas },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Status", className: "status" },
{ title: "Name", className: "name", sortBy: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Metrics", className: "metrics", id: columnId.metrics },
{ title: "Min Pods", className: "min-pods", sortBy: columnId.minPods, id: columnId.minPods },
{ title: "Max Pods", className: "max-pods", sortBy: columnId.maxPods, id: columnId.maxPods },
{ title: "Replicas", className: "replicas", sortBy: columnId.replicas, id: columnId.replicas },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Status", className: "status", id: columnId.status },
]}
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
hpa.getName(),

View File

@ -9,7 +9,7 @@ import React from "react";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { LimitRange } from "../../api/endpoints/limit-range.api";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
age = "age",
@ -23,12 +23,14 @@ export class LimitRanges extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="configuration_limitranges"
className="LimitRanges"
store={limitRangeStore}
sortingCallbacks={{
[sortBy.name]: (item: LimitRange) => item.getName(),
[sortBy.namespace]: (item: LimitRange) => item.getNs(),
[sortBy.age]: (item: LimitRange) => item.metadata.creationTimestamp,
[columnId.name]: (item: LimitRange) => item.getName(),
[columnId.namespace]: (item: LimitRange) => item.getNs(),
[columnId.age]: (item: LimitRange) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: LimitRange) => item.getName(),
@ -36,10 +38,10 @@ export class LimitRanges extends React.Component<Props> {
]}
renderHeaderTitle={"Limit Ranges"}
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(limitRange: LimitRange) => [
limitRange.getName(),

View File

@ -9,7 +9,7 @@ import { KubeObjectListLayout } from "../kube-object";
import { IConfigMapsRouteParams } from "./config-maps.route";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
keys = "keys",
@ -24,12 +24,14 @@ export class ConfigMaps extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="configuration_configmaps"
className="ConfigMaps" store={configMapsStore}
sortingCallbacks={{
[sortBy.name]: (item: ConfigMap) => item.getName(),
[sortBy.namespace]: (item: ConfigMap) => item.getNs(),
[sortBy.keys]: (item: ConfigMap) => item.getKeys(),
[sortBy.age]: (item: ConfigMap) => item.metadata.creationTimestamp,
[columnId.name]: (item: ConfigMap) => item.getName(),
[columnId.namespace]: (item: ConfigMap) => item.getNs(),
[columnId.keys]: (item: ConfigMap) => item.getKeys(),
[columnId.age]: (item: ConfigMap) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: ConfigMap) => item.getSearchFields(),
@ -37,11 +39,11 @@ export class ConfigMaps extends React.Component<Props> {
]}
renderHeaderTitle="Config Maps"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Keys", className: "keys", sortBy: sortBy.keys },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Keys", className: "keys", sortBy: columnId.keys, id: columnId.keys },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(configMap: ConfigMap) => [
configMap.getName(),

View File

@ -7,7 +7,7 @@ import { PodDisruptionBudget } from "../../api/endpoints/poddisruptionbudget.api
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
minAvailable = "min-available",
@ -25,30 +25,32 @@ export class PodDisruptionBudgets extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="configuration_distribution_budgets"
className="PodDisruptionBudgets"
store={podDisruptionBudgetsStore}
sortingCallbacks={{
[sortBy.name]: (pdb: PodDisruptionBudget) => pdb.getName(),
[sortBy.namespace]: (pdb: PodDisruptionBudget) => pdb.getNs(),
[sortBy.minAvailable]: (pdb: PodDisruptionBudget) => pdb.getMinAvailable(),
[sortBy.maxUnavailable]: (pdb: PodDisruptionBudget) => pdb.getMaxUnavailable(),
[sortBy.currentHealthy]: (pdb: PodDisruptionBudget) => pdb.getCurrentHealthy(),
[sortBy.desiredHealthy]: (pdb: PodDisruptionBudget) => pdb.getDesiredHealthy(),
[sortBy.age]: (pdb: PodDisruptionBudget) => pdb.getAge(),
[columnId.name]: (pdb: PodDisruptionBudget) => pdb.getName(),
[columnId.namespace]: (pdb: PodDisruptionBudget) => pdb.getNs(),
[columnId.minAvailable]: (pdb: PodDisruptionBudget) => pdb.getMinAvailable(),
[columnId.maxUnavailable]: (pdb: PodDisruptionBudget) => pdb.getMaxUnavailable(),
[columnId.currentHealthy]: (pdb: PodDisruptionBudget) => pdb.getCurrentHealthy(),
[columnId.desiredHealthy]: (pdb: PodDisruptionBudget) => pdb.getDesiredHealthy(),
[columnId.age]: (pdb: PodDisruptionBudget) => pdb.getAge(),
}}
searchFilters={[
(pdb: PodDisruptionBudget) => pdb.getSearchFields(),
]}
renderHeaderTitle="Pod Disruption Budgets"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Min Available", className: "min-available", sortBy: sortBy.minAvailable },
{ title: "Max Unavailable", className: "max-unavailable", sortBy: sortBy.maxUnavailable },
{ title: "Current Healthy", className: "current-healthy", sortBy: sortBy.currentHealthy },
{ title: "Desired Healthy", className: "desired-healthy", sortBy: sortBy.desiredHealthy },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Min Available", className: "min-available", sortBy: columnId.minAvailable, id: columnId.minAvailable },
{ title: "Max Unavailable", className: "max-unavailable", sortBy: columnId.maxUnavailable, id: columnId.maxUnavailable },
{ title: "Current Healthy", className: "current-healthy", sortBy: columnId.currentHealthy, id: columnId.currentHealthy },
{ title: "Desired Healthy", className: "desired-healthy", sortBy: columnId.desiredHealthy, id: columnId.desiredHealthy },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(pdb: PodDisruptionBudget) => {
return [

View File

@ -10,7 +10,7 @@ import { resourceQuotaStore } from "./resource-quotas.store";
import { IResourceQuotaRouteParams } from "./resource-quotas.route";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
age = "age"
@ -25,11 +25,13 @@ export class ResourceQuotas extends React.Component<Props> {
return (
<>
<KubeObjectListLayout
isConfigurable
tableId="configuration_quotas"
className="ResourceQuotas" store={resourceQuotaStore}
sortingCallbacks={{
[sortBy.name]: (item: ResourceQuota) => item.getName(),
[sortBy.namespace]: (item: ResourceQuota) => item.getNs(),
[sortBy.age]: (item: ResourceQuota) => item.metadata.creationTimestamp,
[columnId.name]: (item: ResourceQuota) => item.getName(),
[columnId.namespace]: (item: ResourceQuota) => item.getNs(),
[columnId.age]: (item: ResourceQuota) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: ResourceQuota) => item.getSearchFields(),
@ -37,10 +39,10 @@ export class ResourceQuotas extends React.Component<Props> {
]}
renderHeaderTitle="Resource Quotas"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(resourceQuota: ResourceQuota) => [
resourceQuota.getName(),

View File

@ -11,7 +11,7 @@ import { Badge } from "../badge";
import { secretsStore } from "./secrets.store";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
labels = "labels",
@ -29,14 +29,16 @@ export class Secrets extends React.Component<Props> {
return (
<>
<KubeObjectListLayout
isConfigurable
tableId="configuration_secrets"
className="Secrets" store={secretsStore}
sortingCallbacks={{
[sortBy.name]: (item: Secret) => item.getName(),
[sortBy.namespace]: (item: Secret) => item.getNs(),
[sortBy.labels]: (item: Secret) => item.getLabels(),
[sortBy.keys]: (item: Secret) => item.getKeys(),
[sortBy.type]: (item: Secret) => item.type,
[sortBy.age]: (item: Secret) => item.metadata.creationTimestamp,
[columnId.name]: (item: Secret) => item.getName(),
[columnId.namespace]: (item: Secret) => item.getNs(),
[columnId.labels]: (item: Secret) => item.getLabels(),
[columnId.keys]: (item: Secret) => item.getKeys(),
[columnId.type]: (item: Secret) => item.type,
[columnId.age]: (item: Secret) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: Secret) => item.getSearchFields(),
@ -44,13 +46,13 @@ export class Secrets extends React.Component<Props> {
]}
renderHeaderTitle="Secrets"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Labels", className: "labels", sortBy: sortBy.labels },
{ title: "Keys", className: "keys", sortBy: sortBy.keys },
{ title: "Type", className: "type", sortBy: sortBy.type },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Labels", className: "labels", sortBy: columnId.labels, id: columnId.labels },
{ title: "Keys", className: "keys", sortBy: columnId.keys, id: columnId.keys },
{ title: "Type", className: "type", sortBy: columnId.type, id: columnId.type },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(secret: Secret) => [
secret.getName(),

View File

@ -19,7 +19,7 @@ export const crdGroupsUrlParam = createPageParam<string[]>({
defaultValue: [],
});
enum sortBy {
enum columnId {
kind = "kind",
group = "group",
version = "version",
@ -47,14 +47,16 @@ export class CrdList extends React.Component {
render() {
const selectedGroups = this.groups;
const sortingCallbacks = {
[sortBy.kind]: (crd: CustomResourceDefinition) => crd.getResourceKind(),
[sortBy.group]: (crd: CustomResourceDefinition) => crd.getGroup(),
[sortBy.version]: (crd: CustomResourceDefinition) => crd.getVersion(),
[sortBy.scope]: (crd: CustomResourceDefinition) => crd.getScope(),
[columnId.kind]: (crd: CustomResourceDefinition) => crd.getResourceKind(),
[columnId.group]: (crd: CustomResourceDefinition) => crd.getGroup(),
[columnId.version]: (crd: CustomResourceDefinition) => crd.getVersion(),
[columnId.scope]: (crd: CustomResourceDefinition) => crd.getScope(),
};
return (
<KubeObjectListLayout
isConfigurable
tableId="crd"
className="CrdList"
isClusterScoped={true}
store={crdStore}
@ -97,11 +99,11 @@ export class CrdList extends React.Component {
};
}}
renderTableHeader={[
{ title: "Resource", className: "kind", sortBy: sortBy.kind },
{ title: "Group", className: "group", sortBy: sortBy.group },
{ title: "Version", className: "version", sortBy: sortBy.group },
{ title: "Scope", className: "scope", sortBy: sortBy.scope },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Resource", className: "kind", sortBy: columnId.kind, id: columnId.kind },
{ title: "Group", className: "group", sortBy: columnId.group, id: columnId.group },
{ title: "Version", className: "version", sortBy: columnId.version, id: columnId.version },
{ title: "Scope", className: "scope", sortBy: columnId.scope, id: columnId.scope },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(crd: CustomResourceDefinition) => [
<Link key="link" to={crd.getResourceUrl()} onClick={stopPropagation}>

View File

@ -16,7 +16,7 @@ import { parseJsonPath } from "../../utils/jsonPath";
interface Props extends RouteComponentProps<ICRDRouteParams> {
}
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
age = "age",
@ -55,9 +55,9 @@ export class CrdResources extends React.Component<Props> {
const isNamespaced = crd.isNamespaced();
const extraColumns = crd.getPrinterColumns(false); // Cols with priority bigger than 0 are shown in details
const sortingCallbacks: { [sortBy: string]: TableSortCallback } = {
[sortBy.name]: (item: KubeObject) => item.getName(),
[sortBy.namespace]: (item: KubeObject) => item.getNs(),
[sortBy.age]: (item: KubeObject) => item.metadata.creationTimestamp,
[columnId.name]: (item: KubeObject) => item.getName(),
[columnId.namespace]: (item: KubeObject) => item.getNs(),
[columnId.age]: (item: KubeObject) => item.metadata.creationTimestamp,
};
extraColumns.forEach(column => {
@ -66,6 +66,8 @@ export class CrdResources extends React.Component<Props> {
return (
<KubeObjectListLayout
isConfigurable
tableId="crd_resources"
className="CrdResources"
isClusterScoped={!isNamespaced}
store={store}
@ -75,18 +77,19 @@ export class CrdResources extends React.Component<Props> {
]}
renderHeaderTitle={crd.getResourceTitle()}
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
isNamespaced && { title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
isNamespaced && { title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
...extraColumns.map(column => {
const { name } = column;
return {
title: name,
className: name.toLowerCase(),
sortBy: name
sortBy: name,
id: name
};
}),
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(crdInstance: KubeObject) => [
crdInstance.getName(),

View File

@ -12,11 +12,13 @@ import { cssNames, IClassName, stopPropagation } from "../../utils";
import { Icon } from "../icon";
import { lookupApiLink } from "../../api/kube-api";
enum sortBy {
enum columnId {
message = "message",
namespace = "namespace",
object = "object",
type = "type",
count = "count",
source = "source",
age = "age",
}
@ -39,15 +41,17 @@ export class Events extends React.Component<Props> {
const events = (
<KubeObjectListLayout
{...layoutProps}
isConfigurable
tableId="events"
className={cssNames("Events", className, { compact })}
store={eventStore}
isSelectable={false}
sortingCallbacks={{
[sortBy.namespace]: (event: KubeEvent) => event.getNs(),
[sortBy.type]: (event: KubeEvent) => event.involvedObject.kind,
[sortBy.object]: (event: KubeEvent) => event.involvedObject.name,
[sortBy.count]: (event: KubeEvent) => event.count,
[sortBy.age]: (event: KubeEvent) => event.metadata.creationTimestamp,
[columnId.namespace]: (event: KubeEvent) => event.getNs(),
[columnId.type]: (event: KubeEvent) => event.involvedObject.kind,
[columnId.object]: (event: KubeEvent) => event.involvedObject.name,
[columnId.count]: (event: KubeEvent) => event.count,
[columnId.age]: (event: KubeEvent) => event.metadata.creationTimestamp,
}}
searchFilters={[
(event: KubeEvent) => event.getSearchFields(),
@ -72,13 +76,13 @@ export class Events extends React.Component<Props> {
})
)}
renderTableHeader={[
{ title: "Message", className: "message" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Type", className: "type", sortBy: sortBy.type },
{ title: "Involved Object", className: "object", sortBy: sortBy.object },
{ title: "Source", className: "source" },
{ title: "Count", className: "count", sortBy: sortBy.count },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Message", className: "message", id: columnId.message },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Type", className: "type", sortBy: columnId.type, id: columnId.type },
{ title: "Involved Object", className: "object", sortBy: columnId.object, id: columnId.object },
{ title: "Source", className: "source", id: columnId.source },
{ title: "Count", className: "count", sortBy: columnId.count, id: columnId.count },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(event: KubeEvent) => {
const { involvedObject, type, message } = event;

View File

@ -11,7 +11,7 @@ import { INamespacesRouteParams } from "./namespaces.route";
import { namespaceStore } from "./namespace.store";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
labels = "labels",
age = "age",
@ -27,12 +27,14 @@ export class Namespaces extends React.Component<Props> {
<TabLayout>
<KubeObjectListLayout
isClusterScoped
isConfigurable
tableId="namespaces"
className="Namespaces" store={namespaceStore}
sortingCallbacks={{
[sortBy.name]: (ns: Namespace) => ns.getName(),
[sortBy.labels]: (ns: Namespace) => ns.getLabels(),
[sortBy.age]: (ns: Namespace) => ns.metadata.creationTimestamp,
[sortBy.status]: (ns: Namespace) => ns.getStatus(),
[columnId.name]: (ns: Namespace) => ns.getName(),
[columnId.labels]: (ns: Namespace) => ns.getLabels(),
[columnId.age]: (ns: Namespace) => ns.metadata.creationTimestamp,
[columnId.status]: (ns: Namespace) => ns.getStatus(),
}}
searchFilters={[
(item: Namespace) => item.getSearchFields(),
@ -40,11 +42,11 @@ export class Namespaces extends React.Component<Props> {
]}
renderHeaderTitle="Namespaces"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Labels", className: "labels", sortBy: sortBy.labels },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Status", className: "status", sortBy: sortBy.status },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Labels", className: "labels", sortBy: columnId.labels, id: columnId.labels },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
]}
renderTableContents={(item: Namespace) => [
item.getName(),

View File

@ -9,9 +9,10 @@ import { endpointStore } from "./endpoints.store";
import { KubeObjectListLayout } from "../kube-object";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
endpoints = "endpoints",
age = "age",
}
@ -23,22 +24,24 @@ export class Endpoints extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="network_endpoints"
className="Endpoints" store={endpointStore}
sortingCallbacks={{
[sortBy.name]: (endpoint: Endpoint) => endpoint.getName(),
[sortBy.namespace]: (endpoint: Endpoint) => endpoint.getNs(),
[sortBy.age]: (endpoint: Endpoint) => endpoint.metadata.creationTimestamp,
[columnId.name]: (endpoint: Endpoint) => endpoint.getName(),
[columnId.namespace]: (endpoint: Endpoint) => endpoint.getNs(),
[columnId.age]: (endpoint: Endpoint) => endpoint.metadata.creationTimestamp,
}}
searchFilters={[
(endpoint: Endpoint) => endpoint.getSearchFields()
]}
renderHeaderTitle="Endpoints"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Endpoints", className: "endpoints" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Endpoints", className: "endpoints", id: columnId.endpoints },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(endpoint: Endpoint) => [
endpoint.getName(),

View File

@ -9,9 +9,11 @@ import { ingressStore } from "./ingress.store";
import { KubeObjectListLayout } from "../kube-object";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
loadBalancers ="load-balancers",
rules = "rules",
age = "age",
}
@ -23,11 +25,13 @@ export class Ingresses extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="network_ingresses"
className="Ingresses" store={ingressStore}
sortingCallbacks={{
[sortBy.name]: (ingress: Ingress) => ingress.getName(),
[sortBy.namespace]: (ingress: Ingress) => ingress.getNs(),
[sortBy.age]: (ingress: Ingress) => ingress.metadata.creationTimestamp,
[columnId.name]: (ingress: Ingress) => ingress.getName(),
[columnId.namespace]: (ingress: Ingress) => ingress.getNs(),
[columnId.age]: (ingress: Ingress) => ingress.metadata.creationTimestamp,
}}
searchFilters={[
(ingress: Ingress) => ingress.getSearchFields(),
@ -35,12 +39,12 @@ export class Ingresses extends React.Component<Props> {
]}
renderHeaderTitle="Ingresses"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "LoadBalancers", className: "loadbalancers" },
{ title: "Rules", className: "rules" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "LoadBalancers", className: "loadbalancers", id: columnId.loadBalancers },
{ title: "Rules", className: "rules", id: columnId.rules },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(ingress: Ingress) => [
ingress.getName(),

View File

@ -9,9 +9,10 @@ import { INetworkPoliciesRouteParams } from "./network-policies.route";
import { networkPolicyStore } from "./network-policy.store";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
types = "types",
age = "age",
}
@ -23,22 +24,24 @@ export class NetworkPolicies extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="network_policies"
className="NetworkPolicies" store={networkPolicyStore}
sortingCallbacks={{
[sortBy.name]: (item: NetworkPolicy) => item.getName(),
[sortBy.namespace]: (item: NetworkPolicy) => item.getNs(),
[sortBy.age]: (item: NetworkPolicy) => item.metadata.creationTimestamp,
[columnId.name]: (item: NetworkPolicy) => item.getName(),
[columnId.namespace]: (item: NetworkPolicy) => item.getNs(),
[columnId.age]: (item: NetworkPolicy) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: NetworkPolicy) => item.getSearchFields(),
]}
renderHeaderTitle="Network Policies"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Policy Types", className: "type" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Policy Types", className: "type", id: columnId.types },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(item: NetworkPolicy) => [
item.getName(),

View File

@ -10,12 +10,13 @@ import { Badge } from "../badge";
import { serviceStore } from "./services.store";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
selector = "selector",
ports = "port",
clusterIp = "cluster-ip",
externalIp = "external-ip",
age = "age",
type = "type",
status = "status",
@ -29,16 +30,18 @@ export class Services extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="network_services"
className="Services" store={serviceStore}
sortingCallbacks={{
[sortBy.name]: (service: Service) => service.getName(),
[sortBy.namespace]: (service: Service) => service.getNs(),
[sortBy.selector]: (service: Service) => service.getSelector(),
[sortBy.ports]: (service: Service) => (service.spec.ports || []).map(({ port }) => port)[0],
[sortBy.clusterIp]: (service: Service) => service.getClusterIp(),
[sortBy.type]: (service: Service) => service.getType(),
[sortBy.age]: (service: Service) => service.metadata.creationTimestamp,
[sortBy.status]: (service: Service) => service.getStatus(),
[columnId.name]: (service: Service) => service.getName(),
[columnId.namespace]: (service: Service) => service.getNs(),
[columnId.selector]: (service: Service) => service.getSelector(),
[columnId.ports]: (service: Service) => (service.spec.ports || []).map(({ port }) => port)[0],
[columnId.clusterIp]: (service: Service) => service.getClusterIp(),
[columnId.type]: (service: Service) => service.getType(),
[columnId.age]: (service: Service) => service.metadata.creationTimestamp,
[columnId.status]: (service: Service) => service.getStatus(),
}}
searchFilters={[
(service: Service) => service.getSearchFields(),
@ -47,16 +50,16 @@ export class Services extends React.Component<Props> {
]}
renderHeaderTitle="Services"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Type", className: "type", sortBy: sortBy.type },
{ title: "Cluster IP", className: "clusterIp", sortBy: sortBy.clusterIp, },
{ title: "Ports", className: "ports", sortBy: sortBy.ports },
{ title: "External IP", className: "externalIp" },
{ title: "Selector", className: "selector", sortBy: sortBy.selector },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Status", className: "status", sortBy: sortBy.status },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Type", className: "type", sortBy: columnId.type, id: columnId.type },
{ title: "Cluster IP", className: "clusterIp", sortBy: columnId.clusterIp, id: columnId.clusterIp },
{ title: "Ports", className: "ports", sortBy: columnId.ports, id: columnId.ports },
{ title: "External IP", className: "externalIp", id: columnId.externalIp },
{ title: "Selector", className: "selector", sortBy: columnId.selector, id: columnId.selector },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
]}
renderTableContents={(service: Service) => [
service.getName(),

View File

@ -17,7 +17,7 @@ import upperFirst from "lodash/upperFirst";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { Badge } from "../badge/badge";
enum sortBy {
enum columnId {
name = "name",
cpu = "cpu",
memory = "memory",
@ -135,21 +135,23 @@ export class Nodes extends React.Component<Props> {
return (
<TabLayout>
<KubeObjectListLayout
isConfigurable
tableId="nodes"
className="Nodes"
store={nodesStore} isClusterScoped
isReady={nodesStore.isLoaded}
dependentStores={[podsStore]}
isSelectable={false}
sortingCallbacks={{
[sortBy.name]: (node: Node) => node.getName(),
[sortBy.cpu]: (node: Node) => nodesStore.getLastMetricValues(node, ["cpuUsage"]),
[sortBy.memory]: (node: Node) => nodesStore.getLastMetricValues(node, ["memoryUsage"]),
[sortBy.disk]: (node: Node) => nodesStore.getLastMetricValues(node, ["fsUsage"]),
[sortBy.conditions]: (node: Node) => node.getNodeConditionText(),
[sortBy.taints]: (node: Node) => node.getTaints().length,
[sortBy.roles]: (node: Node) => node.getRoleLabels(),
[sortBy.age]: (node: Node) => node.metadata.creationTimestamp,
[sortBy.version]: (node: Node) => node.getKubeletVersion(),
[columnId.name]: (node: Node) => node.getName(),
[columnId.cpu]: (node: Node) => nodesStore.getLastMetricValues(node, ["cpuUsage"]),
[columnId.memory]: (node: Node) => nodesStore.getLastMetricValues(node, ["memoryUsage"]),
[columnId.disk]: (node: Node) => nodesStore.getLastMetricValues(node, ["fsUsage"]),
[columnId.conditions]: (node: Node) => node.getNodeConditionText(),
[columnId.taints]: (node: Node) => node.getTaints().length,
[columnId.roles]: (node: Node) => node.getRoleLabels(),
[columnId.age]: (node: Node) => node.metadata.creationTimestamp,
[columnId.version]: (node: Node) => node.getKubeletVersion(),
}}
searchFilters={[
(node: Node) => node.getSearchFields(),
@ -159,16 +161,16 @@ export class Nodes extends React.Component<Props> {
]}
renderHeaderTitle="Nodes"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "CPU", className: "cpu", sortBy: sortBy.cpu },
{ title: "Memory", className: "memory", sortBy: sortBy.memory },
{ title: "Disk", className: "disk", sortBy: sortBy.disk },
{ title: "Taints", className: "taints", sortBy: sortBy.taints },
{ title: "Roles", className: "roles", sortBy: sortBy.roles },
{ title: "Version", className: "version", sortBy: sortBy.version },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Conditions", className: "conditions", sortBy: sortBy.conditions },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "CPU", className: "cpu", sortBy: columnId.cpu, id: columnId.cpu },
{ title: "Memory", className: "memory", sortBy: columnId.memory, id: columnId.memory },
{ title: "Disk", className: "disk", sortBy: columnId.disk, id: columnId.disk },
{ title: "Taints", className: "taints", sortBy: columnId.taints, id: columnId.taints },
{ title: "Roles", className: "roles", sortBy: columnId.roles, id: columnId.roles },
{ title: "Version", className: "version", sortBy: columnId.version, id: columnId.version },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Conditions", className: "conditions", sortBy: columnId.conditions, id: columnId.conditions },
]}
renderTableContents={(node: Node) => {
const tooltipId = `node-taints-${node.getId()}`;

View File

@ -7,7 +7,7 @@ import { podSecurityPoliciesStore } from "./pod-security-policies.store";
import { PodSecurityPolicy } from "../../api/endpoints";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
volumes = "volumes",
privileged = "privileged",
@ -19,14 +19,16 @@ export class PodSecurityPolicies extends React.Component {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="access_roles"
className="PodSecurityPolicies"
isClusterScoped={true}
store={podSecurityPoliciesStore}
sortingCallbacks={{
[sortBy.name]: (item: PodSecurityPolicy) => item.getName(),
[sortBy.volumes]: (item: PodSecurityPolicy) => item.getVolumes(),
[sortBy.privileged]: (item: PodSecurityPolicy) => +item.isPrivileged(),
[sortBy.age]: (item: PodSecurityPolicy) => item.metadata.creationTimestamp,
[columnId.name]: (item: PodSecurityPolicy) => item.getName(),
[columnId.volumes]: (item: PodSecurityPolicy) => item.getVolumes(),
[columnId.privileged]: (item: PodSecurityPolicy) => +item.isPrivileged(),
[columnId.age]: (item: PodSecurityPolicy) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: PodSecurityPolicy) => item.getSearchFields(),
@ -35,11 +37,11 @@ export class PodSecurityPolicies extends React.Component {
]}
renderHeaderTitle="Pod Security Policies"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Privileged", className: "privileged", sortBy: sortBy.privileged },
{ title: "Volumes", className: "volumes", sortBy: sortBy.volumes },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Privileged", className: "privileged", sortBy: columnId.privileged, id: columnId.privileged },
{ title: "Volumes", className: "volumes", sortBy: columnId.volumes, id: columnId.volumes },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(item: PodSecurityPolicy) => {
return [

View File

@ -9,10 +9,11 @@ import { IStorageClassesRouteParams } from "./storage-classes.route";
import { storageClassStore } from "./storage-class.store";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
age = "age",
provisioner = "provision",
default = "default",
reclaimPolicy = "reclaim",
}
@ -24,13 +25,15 @@ export class StorageClasses extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="storage_classes"
className="StorageClasses"
store={storageClassStore} isClusterScoped
sortingCallbacks={{
[sortBy.name]: (item: StorageClass) => item.getName(),
[sortBy.age]: (item: StorageClass) => item.metadata.creationTimestamp,
[sortBy.provisioner]: (item: StorageClass) => item.provisioner,
[sortBy.reclaimPolicy]: (item: StorageClass) => item.reclaimPolicy,
[columnId.name]: (item: StorageClass) => item.getName(),
[columnId.age]: (item: StorageClass) => item.metadata.creationTimestamp,
[columnId.provisioner]: (item: StorageClass) => item.provisioner,
[columnId.reclaimPolicy]: (item: StorageClass) => item.reclaimPolicy,
}}
searchFilters={[
(item: StorageClass) => item.getSearchFields(),
@ -38,12 +41,12 @@ export class StorageClasses extends React.Component<Props> {
]}
renderHeaderTitle="Storage Classes"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Provisioner", className: "provisioner", sortBy: sortBy.provisioner },
{ title: "Reclaim Policy", className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
{ title: "Default", className: "is-default" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Provisioner", className: "provisioner", sortBy: columnId.provisioner, id: columnId.provisioner },
{ title: "Reclaim Policy", className: "reclaim-policy", sortBy: columnId.reclaimPolicy, id: columnId.reclaimPolicy },
{ title: "Default", className: "is-default", id: columnId.default },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(storageClass: StorageClass) => [
storageClass.getName(),

View File

@ -13,7 +13,7 @@ import { stopPropagation } from "../../utils";
import { storageClassApi } from "../../api/endpoints";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
pods = "pods",
@ -31,17 +31,19 @@ export class PersistentVolumeClaims extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="storage_volume_claims"
className="PersistentVolumeClaims"
store={volumeClaimStore}
dependentStores={[podsStore]}
sortingCallbacks={{
[sortBy.name]: (pvc: PersistentVolumeClaim) => pvc.getName(),
[sortBy.namespace]: (pvc: PersistentVolumeClaim) => pvc.getNs(),
[sortBy.pods]: (pvc: PersistentVolumeClaim) => pvc.getPods(podsStore.items).map(pod => pod.getName()),
[sortBy.status]: (pvc: PersistentVolumeClaim) => pvc.getStatus(),
[sortBy.size]: (pvc: PersistentVolumeClaim) => unitsToBytes(pvc.getStorage()),
[sortBy.storageClass]: (pvc: PersistentVolumeClaim) => pvc.spec.storageClassName,
[sortBy.age]: (pvc: PersistentVolumeClaim) => pvc.metadata.creationTimestamp,
[columnId.name]: (pvc: PersistentVolumeClaim) => pvc.getName(),
[columnId.namespace]: (pvc: PersistentVolumeClaim) => pvc.getNs(),
[columnId.pods]: (pvc: PersistentVolumeClaim) => pvc.getPods(podsStore.items).map(pod => pod.getName()),
[columnId.status]: (pvc: PersistentVolumeClaim) => pvc.getStatus(),
[columnId.size]: (pvc: PersistentVolumeClaim) => unitsToBytes(pvc.getStorage()),
[columnId.storageClass]: (pvc: PersistentVolumeClaim) => pvc.spec.storageClassName,
[columnId.age]: (pvc: PersistentVolumeClaim) => pvc.metadata.creationTimestamp,
}}
searchFilters={[
(item: PersistentVolumeClaim) => item.getSearchFields(),
@ -49,14 +51,14 @@ export class PersistentVolumeClaims extends React.Component<Props> {
]}
renderHeaderTitle="Persistent Volume Claims"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Storage class", className: "storageClass", sortBy: sortBy.storageClass },
{ title: "Size", className: "size", sortBy: sortBy.size },
{ title: "Pods", className: "pods", sortBy: sortBy.pods },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Status", className: "status", sortBy: sortBy.status },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Storage class", className: "storageClass", sortBy: columnId.storageClass, id: columnId.storageClass },
{ title: "Size", className: "size", sortBy: columnId.size, id: columnId.size },
{ title: "Pods", className: "pods", sortBy: columnId.pods, id: columnId.pods },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
]}
renderTableContents={(pvc: PersistentVolumeClaim) => {
const pods = pvc.getPods(podsStore.items);

View File

@ -11,10 +11,11 @@ import { volumesStore } from "./volumes.store";
import { pvcApi, storageClassApi } from "../../api/endpoints";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
storageClass = "storage-class",
capacity = "capacity",
claim = "claim",
status = "status",
age = "age",
}
@ -27,14 +28,16 @@ export class PersistentVolumes extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="storage_volumes"
className="PersistentVolumes"
store={volumesStore} isClusterScoped
sortingCallbacks={{
[sortBy.name]: (item: PersistentVolume) => item.getName(),
[sortBy.storageClass]: (item: PersistentVolume) => item.spec.storageClassName,
[sortBy.capacity]: (item: PersistentVolume) => item.getCapacity(true),
[sortBy.status]: (item: PersistentVolume) => item.getStatus(),
[sortBy.age]: (item: PersistentVolume) => item.metadata.creationTimestamp,
[columnId.name]: (item: PersistentVolume) => item.getName(),
[columnId.storageClass]: (item: PersistentVolume) => item.spec.storageClassName,
[columnId.capacity]: (item: PersistentVolume) => item.getCapacity(true),
[columnId.status]: (item: PersistentVolume) => item.getStatus(),
[columnId.age]: (item: PersistentVolume) => item.metadata.creationTimestamp,
}}
searchFilters={[
(item: PersistentVolume) => item.getSearchFields(),
@ -42,13 +45,13 @@ export class PersistentVolumes extends React.Component<Props> {
]}
renderHeaderTitle="Persistent Volumes"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Storage Class", className: "storageClass", sortBy: sortBy.storageClass },
{ title: "Capacity", className: "capacity", sortBy: sortBy.capacity },
{ title: "Claim", className: "claim" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Status", className: "status", sortBy: sortBy.status },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Storage Class", className: "storageClass", sortBy: columnId.storageClass, id: columnId.storageClass },
{ title: "Capacity", className: "capacity", sortBy: columnId.capacity, id: columnId.capacity },
{ title: "Claim", className: "claim", id: columnId.claim },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
]}
renderTableContents={(volume: PersistentVolume) => {
const { claimRef, storageClassName } = volume.spec;

View File

@ -10,7 +10,7 @@ import { KubeObjectListLayout } from "../kube-object";
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
bindings = "bindings",
@ -25,13 +25,15 @@ export class RoleBindings extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="access_role_bindings"
className="RoleBindings"
store={roleBindingsStore}
sortingCallbacks={{
[sortBy.name]: (binding: RoleBinding) => binding.getName(),
[sortBy.namespace]: (binding: RoleBinding) => binding.getNs(),
[sortBy.bindings]: (binding: RoleBinding) => binding.getSubjectNames(),
[sortBy.age]: (binding: RoleBinding) => binding.metadata.creationTimestamp,
[columnId.name]: (binding: RoleBinding) => binding.getName(),
[columnId.namespace]: (binding: RoleBinding) => binding.getNs(),
[columnId.bindings]: (binding: RoleBinding) => binding.getSubjectNames(),
[columnId.age]: (binding: RoleBinding) => binding.metadata.creationTimestamp,
}}
searchFilters={[
(binding: RoleBinding) => binding.getSearchFields(),
@ -39,11 +41,11 @@ export class RoleBindings extends React.Component<Props> {
]}
renderHeaderTitle="Role Bindings"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Bindings", className: "bindings", sortBy: sortBy.bindings },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Bindings", className: "bindings", sortBy: columnId.bindings, id: columnId.bindings },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(binding: RoleBinding) => [
binding.getName(),

View File

@ -10,7 +10,7 @@ import { KubeObjectListLayout } from "../kube-object";
import { AddRoleDialog } from "./add-role-dialog";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
age = "age",
@ -25,22 +25,24 @@ export class Roles extends React.Component<Props> {
return (
<>
<KubeObjectListLayout
isConfigurable
tableId="access_roles"
className="Roles"
store={rolesStore}
sortingCallbacks={{
[sortBy.name]: (role: Role) => role.getName(),
[sortBy.namespace]: (role: Role) => role.getNs(),
[sortBy.age]: (role: Role) => role.metadata.creationTimestamp,
[columnId.name]: (role: Role) => role.getName(),
[columnId.namespace]: (role: Role) => role.getNs(),
[columnId.age]: (role: Role) => role.metadata.creationTimestamp,
}}
searchFilters={[
(role: Role) => role.getSearchFields(),
]}
renderHeaderTitle="Roles"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(role: Role) => [
role.getName(),

View File

@ -15,7 +15,7 @@ import { CreateServiceAccountDialog } from "./create-service-account-dialog";
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
age = "age",
@ -30,21 +30,23 @@ export class ServiceAccounts extends React.Component<Props> {
return (
<>
<KubeObjectListLayout
isConfigurable
tableId="access_service_accounts"
className="ServiceAccounts" store={serviceAccountsStore}
sortingCallbacks={{
[sortBy.name]: (account: ServiceAccount) => account.getName(),
[sortBy.namespace]: (account: ServiceAccount) => account.getNs(),
[sortBy.age]: (account: ServiceAccount) => account.metadata.creationTimestamp,
[columnId.name]: (account: ServiceAccount) => account.getName(),
[columnId.namespace]: (account: ServiceAccount) => account.getNs(),
[columnId.age]: (account: ServiceAccount) => account.metadata.creationTimestamp,
}}
searchFilters={[
(account: ServiceAccount) => account.getSearchFields(),
]}
renderHeaderTitle="Service Accounts"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(account: ServiceAccount) => [
account.getName(),

View File

@ -18,12 +18,13 @@ import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { ConfirmDialog } from "../confirm-dialog/confirm-dialog";
import { Notifications } from "../notifications/notifications";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
schedule = "schedule",
suspend = "suspend",
active = "active",
lastSchedule = "schedule",
lastSchedule = "last-schedule",
age = "age",
}
@ -35,15 +36,17 @@ export class CronJobs extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_cronjobs"
className="CronJobs" store={cronJobStore}
dependentStores={[jobStore, eventStore]}
sortingCallbacks={{
[sortBy.name]: (cronJob: CronJob) => cronJob.getName(),
[sortBy.namespace]: (cronJob: CronJob) => cronJob.getNs(),
[sortBy.suspend]: (cronJob: CronJob) => cronJob.getSuspendFlag(),
[sortBy.active]: (cronJob: CronJob) => cronJobStore.getActiveJobsNum(cronJob),
[sortBy.lastSchedule]: (cronJob: CronJob) => cronJob.getLastScheduleTime(),
[sortBy.age]: (cronJob: CronJob) => cronJob.metadata.creationTimestamp,
[columnId.name]: (cronJob: CronJob) => cronJob.getName(),
[columnId.namespace]: (cronJob: CronJob) => cronJob.getNs(),
[columnId.suspend]: (cronJob: CronJob) => cronJob.getSuspendFlag(),
[columnId.active]: (cronJob: CronJob) => cronJobStore.getActiveJobsNum(cronJob),
[columnId.lastSchedule]: (cronJob: CronJob) => cronJob.getLastScheduleTime(),
[columnId.age]: (cronJob: CronJob) => cronJob.metadata.creationTimestamp,
}}
searchFilters={[
(cronJob: CronJob) => cronJob.getSearchFields(),
@ -51,14 +54,14 @@ export class CronJobs extends React.Component<Props> {
]}
renderHeaderTitle="Cron Jobs"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Schedule", className: "schedule" },
{ title: "Suspend", className: "suspend", sortBy: sortBy.suspend },
{ title: "Active", className: "active", sortBy: sortBy.active },
{ title: "Last schedule", className: "last-schedule", sortBy: sortBy.lastSchedule },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Schedule", className: "schedule", id: columnId.schedule },
{ title: "Suspend", className: "suspend", sortBy: columnId.suspend, id: columnId.suspend },
{ title: "Active", className: "active", sortBy: columnId.active, id: columnId.active },
{ title: "Last schedule", className: "last-schedule", sortBy: columnId.lastSchedule, id: columnId.lastSchedule },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(cronJob: CronJob) => [
cronJob.getName(),

View File

@ -13,10 +13,11 @@ import { IDaemonSetsRouteParams } from "../+workloads";
import { Badge } from "../badge";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
pods = "pods",
labels = "labels",
age = "age",
}
@ -38,13 +39,15 @@ export class DaemonSets extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_daemonsets"
className="DaemonSets" store={daemonSetStore}
dependentStores={[podsStore, nodesStore, eventStore]}
sortingCallbacks={{
[sortBy.name]: (daemonSet: DaemonSet) => daemonSet.getName(),
[sortBy.namespace]: (daemonSet: DaemonSet) => daemonSet.getNs(),
[sortBy.pods]: (daemonSet: DaemonSet) => this.getPodsLength(daemonSet),
[sortBy.age]: (daemonSet: DaemonSet) => daemonSet.metadata.creationTimestamp,
[columnId.name]: (daemonSet: DaemonSet) => daemonSet.getName(),
[columnId.namespace]: (daemonSet: DaemonSet) => daemonSet.getNs(),
[columnId.pods]: (daemonSet: DaemonSet) => this.getPodsLength(daemonSet),
[columnId.age]: (daemonSet: DaemonSet) => daemonSet.metadata.creationTimestamp,
}}
searchFilters={[
(daemonSet: DaemonSet) => daemonSet.getSearchFields(),
@ -52,12 +55,12 @@ export class DaemonSets extends React.Component<Props> {
]}
renderHeaderTitle="Daemon Sets"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Pods", className: "pods", sortBy: sortBy.pods },
{ className: "warning" },
{ title: "Node Selector", className: "labels" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Pods", className: "pods", sortBy: columnId.pods, id: columnId.pods },
{ className: "warning", showWithColumn: columnId.pods },
{ title: "Node Selector", className: "labels", id: columnId.labels },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(daemonSet: DaemonSet) => [
daemonSet.getName(),

View File

@ -23,9 +23,10 @@ import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-obje
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
import { Notifications } from "../notifications";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
pods = "pods",
replicas = "replicas",
age = "age",
condition = "condition",
@ -55,14 +56,16 @@ export class Deployments extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_deployments"
className="Deployments" store={deploymentStore}
dependentStores={[replicaSetStore, podsStore, nodesStore, eventStore]}
sortingCallbacks={{
[sortBy.name]: (deployment: Deployment) => deployment.getName(),
[sortBy.namespace]: (deployment: Deployment) => deployment.getNs(),
[sortBy.replicas]: (deployment: Deployment) => deployment.getReplicas(),
[sortBy.age]: (deployment: Deployment) => deployment.metadata.creationTimestamp,
[sortBy.condition]: (deployment: Deployment) => deployment.getConditionsText(),
[columnId.name]: (deployment: Deployment) => deployment.getName(),
[columnId.namespace]: (deployment: Deployment) => deployment.getNs(),
[columnId.replicas]: (deployment: Deployment) => deployment.getReplicas(),
[columnId.age]: (deployment: Deployment) => deployment.metadata.creationTimestamp,
[columnId.condition]: (deployment: Deployment) => deployment.getConditionsText(),
}}
searchFilters={[
(deployment: Deployment) => deployment.getSearchFields(),
@ -70,13 +73,13 @@ export class Deployments extends React.Component<Props> {
]}
renderHeaderTitle="Deployments"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Pods", className: "pods" },
{ title: "Replicas", className: "replicas", sortBy: sortBy.replicas },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Conditions", className: "conditions", sortBy: sortBy.condition },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Pods", className: "pods", id: columnId.pods },
{ title: "Replicas", className: "replicas", sortBy: columnId.replicas, id: columnId.replicas },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Conditions", className: "conditions", sortBy: columnId.condition, id: columnId.condition },
]}
renderTableContents={(deployment: Deployment) => [
deployment.getName(),

View File

@ -12,9 +12,10 @@ import { IJobsRouteParams } from "../+workloads";
import kebabCase from "lodash/kebabCase";
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
completions = "completions",
conditions = "conditions",
age = "age",
}
@ -27,25 +28,27 @@ export class Jobs extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_jobs"
className="Jobs" store={jobStore}
dependentStores={[podsStore, eventStore]}
sortingCallbacks={{
[sortBy.name]: (job: Job) => job.getName(),
[sortBy.namespace]: (job: Job) => job.getNs(),
[sortBy.conditions]: (job: Job) => job.getCondition() != null ? job.getCondition().type : "",
[sortBy.age]: (job: Job) => job.metadata.creationTimestamp,
[columnId.name]: (job: Job) => job.getName(),
[columnId.namespace]: (job: Job) => job.getNs(),
[columnId.conditions]: (job: Job) => job.getCondition() != null ? job.getCondition().type : "",
[columnId.age]: (job: Job) => job.metadata.creationTimestamp,
}}
searchFilters={[
(job: Job) => job.getSearchFields(),
]}
renderHeaderTitle="Jobs"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Completions", className: "completions" },
{ className: "warning" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Conditions", className: "conditions", sortBy: sortBy.conditions },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Completions", className: "completions", id: columnId.completions },
{ className: "warning", showWithColumn: columnId.completions },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
{ title: "Conditions", className: "conditions", sortBy: columnId.conditions, id: columnId.conditions },
]}
renderTableContents={(job: Job) => {
const condition = job.getCondition();

View File

@ -14,7 +14,7 @@ import { Icon } from "../icon/icon";
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
import { ReplicaSetScaleDialog } from "./replicaset-scale-dialog";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
desired = "desired",
@ -31,27 +31,29 @@ export class ReplicaSets extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_replicasets"
className="ReplicaSets" store={replicaSetStore}
sortingCallbacks={{
[sortBy.name]: (replicaSet: ReplicaSet) => replicaSet.getName(),
[sortBy.namespace]: (replicaSet: ReplicaSet) => replicaSet.getNs(),
[sortBy.desired]: (replicaSet: ReplicaSet) => replicaSet.getDesired(),
[sortBy.current]: (replicaSet: ReplicaSet) => replicaSet.getCurrent(),
[sortBy.ready]: (replicaSet: ReplicaSet) => replicaSet.getReady(),
[sortBy.age]: (replicaSet: ReplicaSet) => replicaSet.metadata.creationTimestamp,
[columnId.name]: (replicaSet: ReplicaSet) => replicaSet.getName(),
[columnId.namespace]: (replicaSet: ReplicaSet) => replicaSet.getNs(),
[columnId.desired]: (replicaSet: ReplicaSet) => replicaSet.getDesired(),
[columnId.current]: (replicaSet: ReplicaSet) => replicaSet.getCurrent(),
[columnId.ready]: (replicaSet: ReplicaSet) => replicaSet.getReady(),
[columnId.age]: (replicaSet: ReplicaSet) => replicaSet.metadata.creationTimestamp,
}}
searchFilters={[
(replicaSet: ReplicaSet) => replicaSet.getSearchFields(),
]}
renderHeaderTitle="Replica Sets"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Desired", className: "desired", sortBy: sortBy.desired },
{ title: "Current", className: "current", sortBy: sortBy.current },
{ title: "Ready", className: "ready", sortBy: sortBy.ready },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ className: "warning", showWithColumn: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Desired", className: "desired", sortBy: columnId.desired, id: columnId.desired },
{ title: "Current", className: "current", sortBy: columnId.current, id: columnId.current },
{ title: "Ready", className: "ready", sortBy: columnId.ready, id: columnId.ready },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(replicaSet: ReplicaSet) => [
replicaSet.getName(),

View File

@ -17,9 +17,10 @@ import { MenuItem } from "../menu/menu";
import { Icon } from "../icon/icon";
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
enum sortBy {
enum columnId {
name = "name",
namespace = "namespace",
pods = "pods",
age = "age",
replicas = "replicas",
}
@ -38,25 +39,27 @@ export class StatefulSets extends React.Component<Props> {
render() {
return (
<KubeObjectListLayout
isConfigurable
tableId="workload_statefulsets"
className="StatefulSets" store={statefulSetStore}
dependentStores={[podsStore, nodesStore, eventStore]}
sortingCallbacks={{
[sortBy.name]: (statefulSet: StatefulSet) => statefulSet.getName(),
[sortBy.namespace]: (statefulSet: StatefulSet) => statefulSet.getNs(),
[sortBy.age]: (statefulSet: StatefulSet) => statefulSet.metadata.creationTimestamp,
[sortBy.replicas]: (statefulSet: StatefulSet) => statefulSet.getReplicas(),
[columnId.name]: (statefulSet: StatefulSet) => statefulSet.getName(),
[columnId.namespace]: (statefulSet: StatefulSet) => statefulSet.getNs(),
[columnId.age]: (statefulSet: StatefulSet) => statefulSet.metadata.creationTimestamp,
[columnId.replicas]: (statefulSet: StatefulSet) => statefulSet.getReplicas(),
}}
searchFilters={[
(statefulSet: StatefulSet) => statefulSet.getSearchFields(),
]}
renderHeaderTitle="Stateful Sets"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Pods", className: "pods" },
{ title: "Replicas", className: "replicas", sortBy: sortBy.replicas },
{ className: "warning" },
{ title: "Age", className: "age", sortBy: sortBy.age },
{ title: "Name", className: "name", sortBy: columnId.name, id: columnId.name },
{ title: "Namespace", className: "namespace", sortBy: columnId.namespace, id: columnId.namespace },
{ title: "Pods", className: "pods", id: columnId.pods },
{ title: "Replicas", className: "replicas", sortBy: columnId.replicas, id: columnId.replicas },
{ className: "warning", showWithColumn: columnId.replicas },
{ title: "Age", className: "age", sortBy: columnId.age, id: columnId.age },
]}
renderTableContents={(statefulSet: StatefulSet) => [
statefulSet.getName(),

View File

@ -4,8 +4,6 @@ import "@testing-library/jest-dom/extend-expect";
import { DockTabs } from "../dock-tabs";
import { dockStore, IDockTab, TabKind } from "../dock.store";
import { createResourceTab } from "../create-resource.store";
import { createTerminalTab } from "../terminal.store";
import { observable } from "mobx";
const onChangeTab = jest.fn();
@ -25,11 +23,19 @@ const getTabKinds = () => dockStore.tabs.map(tab => tab.kind);
describe("<DockTabs />", () => {
beforeEach(() => {
createTerminalTab();
createResourceTab();
createTerminalTab();
createResourceTab();
createTerminalTab();
const terminalTab: IDockTab = { id: "terminal1", kind: TabKind.TERMINAL, title: "Terminal" };
const createResourceTab: IDockTab = { id: "create", kind: TabKind.CREATE_RESOURCE, title: "Create resource" };
const editResourceTab: IDockTab = { id: "edit", kind: TabKind.EDIT_RESOURCE, title: "Edit resource" };
const installChartTab: IDockTab = { id: "install", kind: TabKind.INSTALL_CHART, title: "Install chart" };
const logsTab: IDockTab = { id: "logs", kind: TabKind.POD_LOGS, title: "Logs" };
dockStore.tabs.push(
terminalTab,
createResourceTab,
editResourceTab,
installChartTab,
logsTab
);
});
afterEach(() => {
@ -72,9 +78,9 @@ describe("<DockTabs />", () => {
expect(getTabKinds()).toEqual([
TabKind.TERMINAL,
TabKind.CREATE_RESOURCE,
TabKind.TERMINAL,
TabKind.CREATE_RESOURCE,
TabKind.TERMINAL
TabKind.EDIT_RESOURCE,
TabKind.INSTALL_CHART,
TabKind.POD_LOGS
]);
});
@ -90,7 +96,7 @@ describe("<DockTabs />", () => {
const tabs = container.querySelectorAll(".Tab");
expect(tabs.length).toBe(1);
expect(getTabKinds()).toEqual([TabKind.TERMINAL]);
expect(getTabKinds()).toEqual([TabKind.EDIT_RESOURCE]);
});
it("closes all tabs", () => {
@ -123,7 +129,7 @@ describe("<DockTabs />", () => {
TabKind.TERMINAL,
TabKind.TERMINAL,
TabKind.CREATE_RESOURCE,
TabKind.TERMINAL
TabKind.EDIT_RESOURCE
]);
});

View File

@ -2,7 +2,80 @@
Here you can find description of changes we've built into each release. While we try our best to make each upgrade automatic and as smooth as possible, there may be some cases where you might need to do something to ensure the application works smoothly. So please read through the release highlights!
## 4.0.2 (current version)
## 4.1.0-alpha.1 (current version)
- Change: list views default to a namespace (insted of listing resources from all namespaces)
- Generic logs view with Pod selector
- Possibility to add custom Helm repository through Lens
- Possibility to change visibility of Pod list columns
- Suspend / resume buttons for CronJobs
- Dock tabs context menu
- Display node column in Pod list
- Unify age column output with kubectl
- Use dark colors in Dock regardless of active theme
- Improve Pod tolerations layout
- Lens metrics: scrape only lens-metrics namespace
- Lens metrics: Prometheus v2.19.3
- Export PodDetailsList component to extension API
- Export Wizard components to extension API
- Export NamespaceSelect component to extension API
## 4.0.8
- Fix: extension cluster sub-menu/page periodic re-render
- Fix: app hang on boot if started from command line & oh-my-zsh prompts for auto-update
## 4.0.7
- Fix: typo in Prometheus Ingress metrics
- Fix: catch xterm.js fit error
- Fix: Windows tray icon click
- Fix: error on Kubernetes >= 1.20 on object edit
- Fix: multiline log wrapping
- Fix: prevent clusters from initializing multiple times
- Fix: show default workspace on first boot
## 4.0.6
- Don't open Lens at OS login by default
- Disable GPU acceleration by setting an env variable
- Catch HTTP Errors in case pod metrics resources do not exist or access is forbidden
- Check is persistent volume claims resource to allowed for user
- Share react-router and react-router-dom libraries to extensions
- Fix: long list cropping in sidebar
- Fix: k0s distribution detection
- Fix: Preserve line breaks when copying logs
- Fix: error on api watch on complex api versions
## 4.0.5
- Fix: add missing Kubernetes distro detectors
- Fix: improve how Workloads Overview is loaded
- Fix: race conditions on extension loader
- Fix: pod logs scrolling issues
- Fix: render node list before metrics are available
- Fix: kube-state-metrics v1.9.7
- Fix: CRD sidebar expand/collapse
- Fix: disable oh-my-zsh auto-update prompt when resolving shell environment
- Add kubectl 1.20 support to Lens Smart Terminal
- Optimise performance during cluster connect
## 4.0.4
- Fix errors on Kubernetes v1.20
- Update bundled kubectl to v1.17.15
- Fix: MacOS error on shutdown
- Fix: Kubernetes distribution detection
- Fix: error while displaying CRDs with column which type is an object
## 4.0.3
- Fix: install in-tree extensions before others
- Fix: bundle all dependencies in in-tree extensions
- Fix: display error dialog if extensions couldn't be loaded
- Fix: ensure only one app instance
## 4.0.2
We are aware some users are encountering issues and regressions from previous version. Many of these issues are something we have not seen as part of our automated or manual testing process. To make it worse, some of them are really difficult to reproduce. We want to ensure we are putting all our energy and effort trying to resolve these issues. We hope you are patient. Expect to see new patch releases still in the coming days! Fixes in this version: