mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge remote-tracking branch 'origin/master' into page_registry_issue_1258
# Conflicts: # src/extensions/lens-renderer-extension.ts
This commit is contained in:
commit
ab097c410c
38
.github/workflows/main.yml
vendored
38
.github/workflows/main.yml
vendored
@ -12,17 +12,17 @@ jobs:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
steps:
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install git+https://${{ secrets.GH_TOKEN }}@github.com/lensapp/mkdocs-material-insiders.git
|
||||
pip install mkdocs-git-revision-date-localized-plugin mike
|
||||
|
||||
pip install mike
|
||||
|
||||
|
||||
- name: Checkout Release from lens
|
||||
uses: actions/checkout@v2
|
||||
@ -30,34 +30,32 @@ jobs:
|
||||
repository: lensapp/lens
|
||||
|
||||
- name: git config
|
||||
run: |
|
||||
run: |
|
||||
git config --local user.email "action@github.com"
|
||||
git config --local user.name "GitHub Action"
|
||||
git pull
|
||||
|
||||
|
||||
- name: Using Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
|
||||
- name: Generate Extensions API Reference using typedocs
|
||||
run: |
|
||||
run: |
|
||||
yarn install
|
||||
yarn typedocs-extensions-api
|
||||
for filename in docs/extensions/api/**/*.md; do [ -e "$filename" ] || continue; sed -i '1s/^/---\ntitle: API Reference\n---\n/' $filename; done
|
||||
|
||||
|
||||
|
||||
- name: mkdocs deploy latest
|
||||
run: |
|
||||
run: |
|
||||
mike deploy --push latest
|
||||
|
||||
|
||||
|
||||
- name: mkdocs deploy new release / tag
|
||||
if: contains(github.ref, 'refs/tags/v')
|
||||
run: |
|
||||
run: |
|
||||
mike deploy --push--update-aliases ${{ github.ref }} latest
|
||||
mike set-default --push ${{ github.ref }}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
21
docs/extensions/typedoc-readme.md.tpl
Normal file
21
docs/extensions/typedoc-readme.md.tpl
Normal file
@ -0,0 +1,21 @@
|
||||
# Extension API Reference
|
||||
|
||||
## Modules
|
||||
|
||||
* [App](modules/_core_api_app_.md)
|
||||
* [ClusterFeature](modules/_core_api_cluster_feature_.md)
|
||||
* [EventBus](modules/_core_api_event_bus_.md)
|
||||
* [Store](modules/_core_api_stores_.md)
|
||||
* [Util](modules/_core_api_utils_.md)
|
||||
* [Component](modules/_renderer_api_components_.md)
|
||||
* [K8sApi](modules/_renderer_api_k8s_api_.md)
|
||||
* [Navigation](modules/_renderer_api_navigation_.md)
|
||||
|
||||
## Classes
|
||||
|
||||
* [LensMainExtension](classes/lensmainextension.md)
|
||||
* [LensRendererExtension](classes/lensrendererextension.md)
|
||||
|
||||
## Variables
|
||||
|
||||
* [windowManager](README.md#windowmanager)
|
||||
8
extensions/kube-object-event-status/Makefile
Normal file
8
extensions/kube-object-event-status/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
install-deps:
|
||||
npm install
|
||||
|
||||
build: install-deps
|
||||
npm run build
|
||||
|
||||
test:
|
||||
npm run test
|
||||
3512
extensions/kube-object-event-status/package-lock.json
generated
Normal file
3512
extensions/kube-object-event-status/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
extensions/kube-object-event-status/package.json
Normal file
24
extensions/kube-object-event-status/package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "kube-object-event-status",
|
||||
"version": "0.1.0",
|
||||
"description": "Adds kube object status from events",
|
||||
"renderer": "dist/renderer.js",
|
||||
"lens": {
|
||||
"metadata": {},
|
||||
"styles": []
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"dev": "npm run build --watch",
|
||||
"test": "echo NO TESTS"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@k8slens/extensions": "file:../../src/extensions/npm/extensions",
|
||||
"ts-loader": "^8.0.4",
|
||||
"typescript": "^4.0.3",
|
||||
"webpack": "^4.44.2",
|
||||
"mobx": "^5.15.5",
|
||||
"react": "^16.13.1"
|
||||
}
|
||||
}
|
||||
42
extensions/kube-object-event-status/renderer.tsx
Normal file
42
extensions/kube-object-event-status/renderer.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import { LensRendererExtension, K8sApi } from "@k8slens/extensions";
|
||||
import { resolveStatus, resolveStatusForCronJobs, resolveStatusForPods } from "./src/resolver"
|
||||
|
||||
export default class EventResourceStatusRendererExtension extends LensRendererExtension {
|
||||
kubeObjectStatusTexts = [
|
||||
{
|
||||
kind: "Pod",
|
||||
apiVersions: ["v1"],
|
||||
resolve: (pod: K8sApi.Pod) => resolveStatusForPods(pod)
|
||||
},
|
||||
{
|
||||
kind: "ReplicaSet",
|
||||
apiVersions: ["v1"],
|
||||
resolve: (replicaSet: K8sApi.ReplicaSet) => resolveStatus(replicaSet)
|
||||
},
|
||||
{
|
||||
kind: "Deployment",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (deployment: K8sApi.Deployment) => resolveStatus(deployment)
|
||||
},
|
||||
{
|
||||
kind: "StatefulSet",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (statefulSet: K8sApi.StatefulSet) => resolveStatus(statefulSet)
|
||||
},
|
||||
{
|
||||
kind: "DaemonSet",
|
||||
apiVersions: ["apps/v1"],
|
||||
resolve: (daemonSet: K8sApi.DaemonSet) => resolveStatus(daemonSet)
|
||||
},
|
||||
{
|
||||
kind: "Job",
|
||||
apiVersions: ["batch/v1"],
|
||||
resolve: (job: K8sApi.Job) => resolveStatus(job)
|
||||
},
|
||||
{
|
||||
kind: "CronJob",
|
||||
apiVersions: ["batch/v1"],
|
||||
resolve: (cronJob: K8sApi.CronJob) => resolveStatusForCronJobs(cronJob)
|
||||
},
|
||||
]
|
||||
}
|
||||
52
extensions/kube-object-event-status/src/resolver.tsx
Normal file
52
extensions/kube-object-event-status/src/resolver.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { K8sApi } from "@k8slens/extensions";
|
||||
|
||||
export function resolveStatus(object: K8sApi.KubeObject): K8sApi.KubeObjectStatus {
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
const events = (eventStore as K8sApi.EventStore).getEventsByObject(object);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
if (!events.length || !warnings.length) {
|
||||
return null;
|
||||
}
|
||||
const event = [...warnings, ...events][0]; // get latest event
|
||||
return {
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveStatusForPods(pod: K8sApi.Pod): K8sApi.KubeObjectStatus {
|
||||
if (!pod.hasIssues()) {
|
||||
return null
|
||||
}
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
const events = (eventStore as K8sApi.EventStore).getEventsByObject(pod);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
if (!events.length || !warnings.length) {
|
||||
return null;
|
||||
}
|
||||
const event = [...warnings, ...events][0]; // get latest event
|
||||
return {
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveStatusForCronJobs(cronJob: K8sApi.CronJob): K8sApi.KubeObjectStatus {
|
||||
const eventStore = K8sApi.apiManager.getStore(K8sApi.eventApi)
|
||||
let events = (eventStore as K8sApi.EventStore).getEventsByObject(cronJob);
|
||||
let warnings = events.filter(evt => evt.isWarning());
|
||||
if (cronJob.isNeverRun()) {
|
||||
events = events.filter(event => event.reason != "FailedNeedsStart");
|
||||
}
|
||||
if (!events.length || !warnings.length) {
|
||||
return null;
|
||||
}
|
||||
const event = [...warnings, ...events][0]; // get latest event
|
||||
return {
|
||||
level: K8sApi.KubeObjectStatusLevel.WARNING,
|
||||
text: `${event.message}`,
|
||||
timestamp: event.metadata.creationTimestamp
|
||||
}
|
||||
}
|
||||
26
extensions/kube-object-event-status/tsconfig.json
Normal file
26
extensions/kube-object-event-status/tsconfig.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"module": "CommonJS",
|
||||
"target": "ES2017",
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"moduleResolution": "Node",
|
||||
"sourceMap": false,
|
||||
"declaration": false,
|
||||
"strict": false,
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"./*.ts",
|
||||
"./*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"*.js"
|
||||
]
|
||||
}
|
||||
35
extensions/kube-object-event-status/webpack.config.js
Normal file
35
extensions/kube-object-event-status/webpack.config.js
Normal file
@ -0,0 +1,35 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
entry: './renderer.tsx',
|
||||
context: __dirname,
|
||||
target: "electron-renderer",
|
||||
mode: "production",
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
externals: [
|
||||
{
|
||||
"@k8slens/extensions": "var global.LensExtensions",
|
||||
"react": "var global.React",
|
||||
"mobx": "var global.Mobx"
|
||||
}
|
||||
],
|
||||
resolve: {
|
||||
extensions: [ '.tsx', '.ts', '.js' ],
|
||||
},
|
||||
output: {
|
||||
libraryTarget: "commonjs2",
|
||||
globalObject: "this",
|
||||
filename: 'renderer.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -35,7 +35,7 @@ nav:
|
||||
- Testing Extensions: extensions/testing-and-publishing/testing.md
|
||||
- Publishing Extensions: extensions/testing-and-publishing/publishing.md
|
||||
- Bundling Extensions: extensions/testing-and-publishing/bundling.md
|
||||
- API Reference: extensions/api/modules/_src_extensions_extension_api_.md
|
||||
- API Reference: extensions/api/README.md
|
||||
- Contributing:
|
||||
- Overview: contributing/README.md
|
||||
- Development: contributing/development.md
|
||||
@ -71,7 +71,6 @@ extra_css:
|
||||
|
||||
plugins:
|
||||
- search
|
||||
- git-revision-date-localized
|
||||
|
||||
markdown_extensions:
|
||||
- pymdownx.highlight: {}
|
||||
|
||||
13
package.json
13
package.json
@ -2,7 +2,7 @@
|
||||
"name": "kontena-lens",
|
||||
"productName": "Lens",
|
||||
"description": "Lens - The Kubernetes IDE",
|
||||
"version": "4.0.0-alpha.4",
|
||||
"version": "4.0.0-alpha.5",
|
||||
"main": "static/build/main.js",
|
||||
"copyright": "© 2020, Mirantis, Inc.",
|
||||
"license": "MIT",
|
||||
@ -38,8 +38,8 @@
|
||||
"download:helm": "yarn run ts-node build/download_helm.ts",
|
||||
"build:tray-icons": "yarn run ts-node build/build_tray_icon.ts",
|
||||
"lint": "eslint $@ --ext js,ts,tsx --max-warnings=0 src/",
|
||||
"mkdocs-serve-local": "yarn typedocs-extensions-api && docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -it -p 8000:8000 -v ${PWD}:/docs mkdocs-serve-local:latest",
|
||||
"typedocs-extensions-api": "npx typedoc --plugin typedoc-plugin-markdown --readme none --name @k8slens/extensions --ignoreCompilerErrors --out docs/extensions/api --mode modules --excludePrivate --includes src/ src/extensions/extension-api.ts"
|
||||
"mkdocs-serve-local": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -it -p 8000:8000 -v ${PWD}:/docs mkdocs-serve-local:latest",
|
||||
"typedocs-extensions-api": "yarn 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.11",
|
||||
@ -192,7 +192,8 @@
|
||||
"node-menu",
|
||||
"metrics-cluster-feature",
|
||||
"license-menu-item",
|
||||
"support-page"
|
||||
"support-page",
|
||||
"kube-object-event-status"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
@ -381,8 +382,8 @@
|
||||
"ts-loader": "^7.0.5",
|
||||
"ts-node": "^8.10.2",
|
||||
"type-fest": "^0.18.0",
|
||||
"typedoc": "^0.19.2",
|
||||
"typedoc-plugin-markdown": "^3.0.11",
|
||||
"typedoc": "0.17.0-3",
|
||||
"typedoc-plugin-markdown": "^2.4.0",
|
||||
"typeface-roboto": "^0.0.75",
|
||||
"typescript": "^4.0.2",
|
||||
"url-loader": "^4.1.0",
|
||||
|
||||
@ -10,6 +10,7 @@ import * as EventBus from "./event-bus"
|
||||
import * as Store from "./stores"
|
||||
import * as Util from "./utils"
|
||||
import * as ClusterFeature from "./cluster-feature"
|
||||
import * as Interface from "../interfaces"
|
||||
|
||||
// TODO: allow to expose windowManager.navigate() as Navigation.navigate() in runtime
|
||||
export let windowManager: WindowManager;
|
||||
@ -18,6 +19,7 @@ export {
|
||||
App,
|
||||
EventBus,
|
||||
ClusterFeature,
|
||||
Interface,
|
||||
Store,
|
||||
Util,
|
||||
}
|
||||
|
||||
@ -79,7 +79,9 @@ export class ExtensionLoader {
|
||||
registries.clusterPageMenuRegistry.add(...extension.clusterPageMenus),
|
||||
registries.kubeObjectMenuRegistry.add(...extension.kubeObjectMenuItems),
|
||||
registries.kubeObjectDetailRegistry.add(...extension.kubeObjectDetailItems),
|
||||
]);
|
||||
registries.kubeObjectStatusRegistry.add(...extension.kubeObjectStatusTexts)
|
||||
])
|
||||
|
||||
}
|
||||
|
||||
protected autoInitExtensions(register: (ext: LensExtension) => Function[]) {
|
||||
|
||||
1
src/extensions/interfaces/index.ts
Normal file
1
src/extensions/interfaces/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./registrations"
|
||||
7
src/extensions/interfaces/registrations.ts
Normal file
7
src/extensions/interfaces/registrations.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export type { AppPreferenceRegistration, AppPreferenceComponents } from "../registries/app-preference-registry"
|
||||
export type { ClusterFeatureRegistration, ClusterFeatureComponents } from "../registries/cluster-feature-registry"
|
||||
export type { KubeObjectDetailRegistration, KubeObjectDetailComponents } from "../registries/kube-object-detail-registry"
|
||||
export type { KubeObjectMenuRegistration, KubeObjectMenuComponents } from "../registries/kube-object-menu-registry"
|
||||
export type { KubeObjectStatusRegistration } from "../registries/kube-object-status-registry"
|
||||
export type { PageRegistration, PageComponents } from "../registries/page-registry"
|
||||
export type { StatusBarRegistration } from "../registries/status-bar-registry"
|
||||
@ -1,6 +1,6 @@
|
||||
import type {
|
||||
AppPreferenceRegistration, ClusterFeatureRegistration,
|
||||
KubeObjectMenuRegistration, KubeObjectDetailRegistration, StatusBarRegistration,
|
||||
KubeObjectMenuRegistration, KubeObjectDetailRegistration, StatusBarRegistration, KubeObjectStatusRegistration,
|
||||
PageRegistration, PageMenuRegistration, PageRegistrationCluster, PageMenuRegistrationCluster,
|
||||
} from "./registries"
|
||||
import { observable } from "mobx";
|
||||
@ -11,6 +11,7 @@ export class LensRendererExtension extends LensExtension {
|
||||
@observable.shallow clusterPages: PageRegistrationCluster[] = []
|
||||
@observable.shallow globalPageMenus: PageMenuRegistration[] = []
|
||||
@observable.shallow clusterPageMenus: PageMenuRegistrationCluster[] = []
|
||||
@observable.shallow kubeObjectStatusTexts: KubeObjectStatusRegistration[] = []
|
||||
@observable.shallow appPreferences: AppPreferenceRegistration[] = []
|
||||
@observable.shallow clusterFeatures: ClusterFeatureRegistration[] = []
|
||||
@observable.shallow statusBarItems: StatusBarRegistration[] = []
|
||||
|
||||
@ -8,3 +8,4 @@ export * from "./status-bar-registry"
|
||||
export * from "./kube-object-detail-registry";
|
||||
export * from "./kube-object-menu-registry";
|
||||
export * from "./cluster-feature-registry"
|
||||
export * from "./kube-object-status-registry"
|
||||
|
||||
18
src/extensions/registries/kube-object-status-registry.ts
Normal file
18
src/extensions/registries/kube-object-status-registry.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { KubeObject, KubeObjectStatus } from "../renderer-api/k8s-api";
|
||||
import { BaseRegistry } from "./base-registry";
|
||||
|
||||
export interface KubeObjectStatusRegistration {
|
||||
kind: string;
|
||||
apiVersions: string[];
|
||||
resolve: (object: KubeObject) => KubeObjectStatus;
|
||||
}
|
||||
|
||||
export class KubeObjectStatusRegistry extends BaseRegistry<KubeObjectStatusRegistration> {
|
||||
getItemsForKind(kind: string, apiVersion: string) {
|
||||
return this.items.filter((item) => {
|
||||
return item.kind === kind && item.apiVersions.includes(apiVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const kubeObjectStatusRegistry = new KubeObjectStatusRegistry();
|
||||
@ -2,25 +2,28 @@ export { isAllowedResource } from "../../common/rbac"
|
||||
export { apiManager } from "../../renderer/api/api-manager";
|
||||
export { KubeObjectStore } from "../../renderer/kube-object.store"
|
||||
export { KubeApi, forCluster, IKubeApiCluster } from "../../renderer/api/kube-api";
|
||||
export type { EventStore } from "../../renderer/components/+events/event.store"
|
||||
export { VersionedKubeApi } from "../../renderer/api/kube-api-versioned";
|
||||
export { KubeObject } from "../../renderer/api/kube-object";
|
||||
export { Pod, podsApi, IPodContainer, IPodContainerStatus } from "../../renderer/api/endpoints";
|
||||
export { Node, nodesApi } from "../../renderer/api/endpoints";
|
||||
export { Deployment, deploymentApi } from "../../renderer/api/endpoints";
|
||||
export { Pod, podsApi, PodsApi, IPodContainer, IPodContainerStatus } from "../../renderer/api/endpoints";
|
||||
export { Node, nodesApi, NodesApi } from "../../renderer/api/endpoints";
|
||||
export { Deployment, deploymentApi, DeploymentApi } from "../../renderer/api/endpoints";
|
||||
export { DaemonSet, daemonSetApi } from "../../renderer/api/endpoints";
|
||||
export { StatefulSet, statefulSetApi } from "../../renderer/api/endpoints";
|
||||
export { Job, jobApi } from "../../renderer/api/endpoints";
|
||||
export { CronJob, cronJobApi } from "../../renderer/api/endpoints";
|
||||
export { ConfigMap, configMapApi } from "../../renderer/api/endpoints";
|
||||
export { Secret, secretsApi, ISecretRef } from "../../renderer/api/endpoints";
|
||||
export { ReplicaSet, replicaSetApi } from "../../renderer/api/endpoints";
|
||||
export { ResourceQuota, resourceQuotaApi } from "../../renderer/api/endpoints";
|
||||
export { HorizontalPodAutoscaler, hpaApi } from "../../renderer/api/endpoints";
|
||||
export { PodDisruptionBudget, pdbApi } from "../../renderer/api/endpoints";
|
||||
export { Service, serviceApi } from "../../renderer/api/endpoints";
|
||||
export { Endpoint, endpointApi } from "../../renderer/api/endpoints";
|
||||
export { Ingress, ingressApi } from "../../renderer/api/endpoints";
|
||||
export { Ingress, ingressApi, IngressApi } from "../../renderer/api/endpoints";
|
||||
export { NetworkPolicy, networkPolicyApi } from "../../renderer/api/endpoints";
|
||||
export { PersistentVolume, persistentVolumeApi } from "../../renderer/api/endpoints";
|
||||
export { PersistentVolumeClaim, PersistentVolumeClaimsApi } from "../../renderer/api/endpoints";
|
||||
export { PersistentVolumeClaim, pvcApi, PersistentVolumeClaimsApi } from "../../renderer/api/endpoints";
|
||||
export { StorageClass, storageClassApi } from "../../renderer/api/endpoints";
|
||||
export { Namespace, namespacesApi } from "../../renderer/api/endpoints";
|
||||
export { KubeEvent, eventApi } from "../../renderer/api/endpoints";
|
||||
@ -30,3 +33,4 @@ export { RoleBinding, roleBindingApi } from "../../renderer/api/endpoints";
|
||||
export { ClusterRole, clusterRoleApi } from "../../renderer/api/endpoints";
|
||||
export { ClusterRoleBinding, clusterRoleBindingApi } from "../../renderer/api/endpoints";
|
||||
export { CustomResourceDefinition, crdApi } from "../../renderer/api/endpoints";
|
||||
export { KubeObjectStatus, KubeObjectStatusLevel} from "./kube-object-status"
|
||||
|
||||
11
src/extensions/renderer-api/kube-object-status.ts
Normal file
11
src/extensions/renderer-api/kube-object-status.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export type KubeObjectStatus = {
|
||||
level: KubeObjectStatusLevel;
|
||||
text: string;
|
||||
timestamp?: string;
|
||||
}
|
||||
|
||||
export enum KubeObjectStatusLevel {
|
||||
INFO = 1,
|
||||
WARNING = 2,
|
||||
CRITICAL = 3
|
||||
}
|
||||
@ -51,6 +51,6 @@ export class VersionedKubeApi<T extends KubeObject = any> extends KubeApi<T> {
|
||||
namespace: isNamespaced ? namespace : undefined,
|
||||
name: name,
|
||||
});
|
||||
return resourcePath + (query ? `?` + stringify(query) : "");
|
||||
return resourcePath + (query ? `?` + stringify(this.normalizeQuery(query)) : "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@ export interface IKubeApiQueryParams {
|
||||
timeoutSeconds?: number;
|
||||
limit?: number; // doesn't work with ?watch
|
||||
continue?: string; // might be used with ?limit from second request
|
||||
labelSelector?: string | string[]; // restrict list of objects by their labels, e.g. labelSelector: ["label=value"]
|
||||
fieldSelector?: string | string[]; // restrict list of objects by their fields, e.g. fieldSelector: "field=name"
|
||||
}
|
||||
|
||||
export interface IKubeApiCluster {
|
||||
@ -114,7 +116,17 @@ export class KubeApi<T extends KubeObject = any> {
|
||||
namespace: this.isNamespaced ? namespace : undefined,
|
||||
name: name,
|
||||
});
|
||||
return resourcePath + (query ? `?` + stringify(query) : "");
|
||||
return resourcePath + (query ? `?` + stringify(this.normalizeQuery(query)) : "");
|
||||
}
|
||||
|
||||
protected normalizeQuery(query: Partial<IKubeApiQueryParams> = {}) {
|
||||
if (query.labelSelector) {
|
||||
query.labelSelector = [query.labelSelector].flat().join(",")
|
||||
}
|
||||
if (query.fieldSelector) {
|
||||
query.fieldSelector = [query.fieldSelector].flat().join(",")
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
protected parseResponse(data: KubeJsonApiData | KubeJsonApiData[] | KubeJsonApiDataList, namespace?: string): any {
|
||||
|
||||
@ -6,6 +6,10 @@
|
||||
flex: 1.5;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.metrics {
|
||||
flex: 1.5;
|
||||
}
|
||||
|
||||
@ -4,14 +4,13 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IHpaRouteParams } from "./hpa.route";
|
||||
import { HorizontalPodAutoscaler, hpaApi } from "../../api/endpoints/hpa.api";
|
||||
import { HorizontalPodAutoscaler } from "../../api/endpoints/hpa.api";
|
||||
import { hpaStore } from "./hpa.store";
|
||||
import { Badge } from "../badge";
|
||||
import { cssNames } from "../../utils";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -52,6 +51,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Horizontal Pod Autoscalers</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Metrics</Trans>, className: "metrics" },
|
||||
{ title: <Trans>Min Pods</Trans>, className: "min-pods", sortBy: sortBy.minPods },
|
||||
@ -62,6 +62,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
|
||||
hpa.getName(),
|
||||
<KubeObjectStatusIcon object={hpa} />,
|
||||
hpa.getNs(),
|
||||
this.getTargets(hpa),
|
||||
hpa.getMinPods(),
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.keys {
|
||||
flex: 2.5;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IConfigMapsRouteParams } from "./config-maps.route";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -40,12 +41,14 @@ export class ConfigMaps extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Config Maps</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(configMap: ConfigMap) => [
|
||||
configMap.getName(),
|
||||
<KubeObjectStatusIcon object={configMap}/>,
|
||||
configMap.getNs(),
|
||||
configMap.getKeys().join(", "),
|
||||
configMap.getAge(),
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.keys {
|
||||
flex: 2.5;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-
|
||||
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
|
||||
import { IPodDisruptionBudgetsRouteParams } from "./pod-disruption-budgets.route";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -46,6 +47,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Pod Disruption Budgets</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Min Available</Trans>, className: "min-available", sortBy: sortBy.minAvailable },
|
||||
{ title: <Trans>Max Unavailable</Trans>, className: "max-unavailable", sortBy: sortBy.maxUnavailable },
|
||||
@ -56,6 +58,7 @@ export class PodDisruptionBudgets extends React.Component<Props> {
|
||||
renderTableContents={(pdb: PodDisruptionBudget) => {
|
||||
return [
|
||||
pdb.getName(),
|
||||
<KubeObjectStatusIcon object={pdb} />,
|
||||
pdb.getNs(),
|
||||
pdb.getMinAvailable(),
|
||||
pdb.getMaxUnavailable(),
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
.ResourceQuotas {
|
||||
.TableCell {
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ import { AddQuotaDialog } from "./add-quota-dialog";
|
||||
import { resourceQuotaStore } from "./resource-quotas.store";
|
||||
import { IResourceQuotaRouteParams } from "./resource-quotas.route";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -40,11 +41,13 @@ export class ResourceQuotas extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Resource Quotas</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(resourceQuota: ResourceQuota) => [
|
||||
resourceQuota.getName(),
|
||||
<KubeObjectStatusIcon object={resourceQuota}/>,
|
||||
resourceQuota.getNs(),
|
||||
resourceQuota.getAge(),
|
||||
]}
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
flex: 1.5;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.labels {
|
||||
@include table-cell-labels-offsets;
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import { KubeObjectListLayout } from "../kube-object";
|
||||
import { Badge } from "../badge";
|
||||
import { secretsStore } from "./secrets.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -47,6 +48,7 @@ export class Secrets extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Secrets</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
||||
@ -55,6 +57,7 @@ export class Secrets extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(secret: Secret) => [
|
||||
secret.getName(),
|
||||
<KubeObjectStatusIcon object={secret} />,
|
||||
secret.getNs(),
|
||||
secret.getLabels().map(label => <Badge key={label} label={label}/>),
|
||||
secret.getKeys().join(", "),
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.labels {
|
||||
flex: 4;
|
||||
@include table-cell-labels-offsets;
|
||||
|
||||
@ -2,16 +2,15 @@ import "./namespaces.scss"
|
||||
|
||||
import React from "react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { Namespace, namespacesApi, NamespaceStatus } from "../../api/endpoints";
|
||||
import { Namespace, NamespaceStatus } from "../../api/endpoints";
|
||||
import { AddNamespaceDialog } from "./add-namespace-dialog";
|
||||
import { TabLayout } from "../layout/tab-layout";
|
||||
import { Badge } from "../badge";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { INamespacesRouteParams } from "./namespaces.route";
|
||||
import { namespaceStore } from "./namespace.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -43,12 +42,14 @@ export class Namespaces extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Namespaces</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
||||
]}
|
||||
renderTableContents={(item: Namespace) => [
|
||||
item.getName(),
|
||||
<KubeObjectStatusIcon object={item} />,
|
||||
item.getLabels().map(label => <Badge key={label} label={label}/>),
|
||||
item.getAge(),
|
||||
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
||||
|
||||
@ -3,5 +3,9 @@
|
||||
&.endpoints {
|
||||
flex-grow: 5.0;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,12 +4,11 @@ import React from "react"
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router-dom"
|
||||
import { EndpointRouteParams } from "./endpoints.route"
|
||||
import { Endpoint, endpointApi } from "../../api/endpoints/endpoint.api"
|
||||
import { Endpoint } from "../../api/endpoints/endpoint.api"
|
||||
import { endpointStore } from "./endpoints.store";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -37,12 +36,14 @@ export class Endpoints extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Endpoints</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Endpoints</Trans>, className: "endpoints" },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(endpoint: Endpoint) => [
|
||||
endpoint.getName(),
|
||||
<KubeObjectStatusIcon object={endpoint} />,
|
||||
endpoint.getNs(),
|
||||
endpoint.toString(),
|
||||
endpoint.getAge(),
|
||||
|
||||
@ -3,5 +3,9 @@
|
||||
&.rules {
|
||||
flex-grow: 3.0;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,12 +4,11 @@ import React from "react"
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router-dom"
|
||||
import { IngressRouteParams } from "./ingresses.route"
|
||||
import { Ingress, ingressApi } from "../../api/endpoints/ingress.api"
|
||||
import { Ingress } from "../../api/endpoints/ingress.api"
|
||||
import { ingressStore } from "./ingress.store";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -38,6 +37,7 @@ export class Ingresses extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Ingresses</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>LoadBalancers</Trans>, className: "loadbalancers" },
|
||||
{ title: <Trans>Rules</Trans>, className: "rules" },
|
||||
@ -45,6 +45,7 @@ export class Ingresses extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(ingress: Ingress) => [
|
||||
ingress.getName(),
|
||||
<KubeObjectStatusIcon object={ingress} />,
|
||||
ingress.getNs(),
|
||||
ingress.getLoadBalancers().map(lb => <p key={lb}>{lb}</p>),
|
||||
ingress.getRoutes().map(route => <p key={route}>{route}</p>),
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
.NetworkPolicies {
|
||||
.TableCell {
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,12 +4,11 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { RouteComponentProps } from "react-router-dom";
|
||||
import { NetworkPolicy, networkPolicyApi } from "../../api/endpoints/network-policy.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { INetworkPoliciesRouteParams } from "./network-policies.route";
|
||||
import { networkPolicyStore } from "./network-policy.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -37,12 +36,14 @@ export class NetworkPolicies extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Network Policies</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Policy Types</Trans>, className: "type" },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(item: NetworkPolicy) => [
|
||||
item.getName(),
|
||||
<KubeObjectStatusIcon object={item} />,
|
||||
item.getNs(),
|
||||
item.getTypes().join(", "),
|
||||
item.getAge(),
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
flex: 0.6;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.age {
|
||||
flex: 0.4;
|
||||
}
|
||||
|
||||
@ -5,12 +5,11 @@ import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { IServicesRouteParams } from "./services.route";
|
||||
import { Service, serviceApi } from "../../api/endpoints/service.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { Service } from "../../api/endpoints/service.api";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { Badge } from "../badge";
|
||||
import { serviceStore } from "./services.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -50,6 +49,7 @@ export class Services extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Services</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
||||
{ title: <Trans>Cluster IP</Trans>, className: "clusterIp", sortBy: sortBy.clusterIp, },
|
||||
@ -61,6 +61,7 @@ export class Services extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(service: Service) => [
|
||||
service.getName(),
|
||||
<KubeObjectStatusIcon object={service} />,
|
||||
service.getNs(),
|
||||
service.getType(),
|
||||
service.getClusterIp(),
|
||||
|
||||
@ -7,6 +7,10 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.cpu {
|
||||
flex: 1.0;
|
||||
align-self: center;
|
||||
|
||||
@ -16,6 +16,7 @@ import { bytesToUnits } from "../../utils/convertMemory";
|
||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import upperFirst from "lodash/upperFirst";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -148,6 +149,7 @@ export class Nodes extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Nodes</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>CPU</Trans>, className: "cpu", sortBy: sortBy.cpu },
|
||||
{ title: <Trans>Memory</Trans>, className: "memory", sortBy: sortBy.memory },
|
||||
{ title: <Trans>Disk</Trans>, className: "disk", sortBy: sortBy.disk },
|
||||
@ -161,6 +163,7 @@ export class Nodes extends React.Component<Props> {
|
||||
const tooltipId = `node-taints-${node.getId()}`;
|
||||
return [
|
||||
node.getName(),
|
||||
<KubeObjectStatusIcon object={node} />,
|
||||
this.renderCpuUsage(node),
|
||||
this.renderMemoryUsage(node),
|
||||
this.renderDiskUsage(node),
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
&.volumes {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,10 +4,9 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { podSecurityPoliciesStore } from "./pod-security-policies.store";
|
||||
import { PodSecurityPolicy, pspApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -38,6 +37,7 @@ export class PodSecurityPolicies extends React.Component {
|
||||
renderHeaderTitle={<Trans>Pod Security Policies</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Privileged</Trans>, className: "privileged", sortBy: sortBy.privileged },
|
||||
{ title: <Trans>Volumes</Trans>, className: "volumes", sortBy: sortBy.volumes },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
@ -45,6 +45,7 @@ export class PodSecurityPolicies extends React.Component {
|
||||
renderTableContents={(item: PodSecurityPolicy) => {
|
||||
return [
|
||||
item.getName(),
|
||||
<KubeObjectStatusIcon object={item} />,
|
||||
item.isPrivileged() ? <Trans>Yes</Trans> : <Trans>No</Trans>,
|
||||
item.getVolumes().join(", "),
|
||||
item.getAge(),
|
||||
|
||||
@ -3,5 +3,9 @@
|
||||
&.is-default {
|
||||
flex: .5;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5,11 +5,10 @@ import { RouteComponentProps } from "react-router-dom";
|
||||
import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IStorageClassesRouteParams } from "./storage-classes.route";
|
||||
import { storageClassStore } from "./storage-class.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -41,6 +40,7 @@ export class StorageClasses extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Storage Classes</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Provisioner</Trans>, className: "provisioner", sortBy: sortBy.provisioner },
|
||||
{ title: <Trans>Reclaim Policy</Trans>, className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
|
||||
{ title: <Trans>Default</Trans>, className: "is-default" },
|
||||
@ -48,6 +48,7 @@ export class StorageClasses extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(storageClass: StorageClass) => [
|
||||
storageClass.getName(),
|
||||
<KubeObjectStatusIcon object={storageClass} />,
|
||||
storageClass.provisioner,
|
||||
storageClass.getReclaimPolicy(),
|
||||
storageClass.isDefault() ? <Trans>Yes</Trans> : null,
|
||||
|
||||
@ -6,6 +6,10 @@
|
||||
flex-grow: 3;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.storage {
|
||||
flex: 0.6;
|
||||
}
|
||||
|
||||
@ -5,8 +5,7 @@ import { observer } from "mobx-react";
|
||||
import { Link, RouteComponentProps } from "react-router-dom";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { volumeClaimStore } from "./volume-claim.store";
|
||||
import { PersistentVolumeClaim, pvcApi } from "../../api/endpoints/persistent-volume-claims.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { PersistentVolumeClaim } from "../../api/endpoints/persistent-volume-claims.api";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IVolumeClaimsRouteParams } from "./volume-claims.route";
|
||||
@ -14,7 +13,7 @@ import { unitsToBytes } from "../../utils/convertMemory";
|
||||
import { stopPropagation } from "../../utils";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import { storageClassApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -53,6 +52,7 @@ export class PersistentVolumeClaims extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Persistent Volume Claims</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Storage class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
||||
{ title: <Trans>Size</Trans>, className: "size", sortBy: sortBy.size },
|
||||
@ -68,6 +68,7 @@ export class PersistentVolumeClaims extends React.Component<Props> {
|
||||
}));
|
||||
return [
|
||||
pvc.getName(),
|
||||
<KubeObjectStatusIcon object={pvc} />,
|
||||
pvc.getNs(),
|
||||
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
||||
{storageClassName}
|
||||
|
||||
@ -6,6 +6,10 @@
|
||||
flex-grow: 3;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.storage {
|
||||
flex: 0.6;
|
||||
}
|
||||
|
||||
@ -4,15 +4,14 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { Link, RouteComponentProps } from "react-router-dom";
|
||||
import { PersistentVolume, persistentVolumeApi } from "../../api/endpoints/persistent-volume.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IVolumesRouteParams } from "./volumes.route";
|
||||
import { stopPropagation } from "../../utils";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import { volumesStore } from "./volumes.store";
|
||||
import { pvcApi, storageClassApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -46,6 +45,7 @@ export class PersistentVolumes extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Persistent Volumes</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Storage Class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
||||
{ title: <Trans>Capacity</Trans>, className: "capacity", sortBy: sortBy.capacity },
|
||||
{ title: <Trans>Claim</Trans>, className: "claim" },
|
||||
@ -59,6 +59,7 @@ export class PersistentVolumes extends React.Component<Props> {
|
||||
}));
|
||||
return [
|
||||
volume.getName(),
|
||||
<KubeObjectStatusIcon object={volume} />,
|
||||
<Link to={storageClassDetailsUrl} onClick={stopPropagation}>
|
||||
{storageClassName}
|
||||
</Link>,
|
||||
|
||||
@ -2,4 +2,10 @@
|
||||
.help-icon {
|
||||
margin-left: $margin / 2;
|
||||
}
|
||||
|
||||
.TableCell {
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,15 +4,12 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { Icon } from "../icon";
|
||||
import { IRoleBindingsRouteParams } from "../+user-management/user-management.route";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { clusterRoleBindingApi, RoleBinding, roleBindingApi } from "../../api/endpoints";
|
||||
import { RoleBinding } from "../../api/endpoints";
|
||||
import { roleBindingsStore } from "./role-bindings.store";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -44,12 +41,14 @@ export class RoleBindings extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Role Bindings</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Bindings</Trans>, className: "bindings", sortBy: sortBy.bindings },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(binding: RoleBinding) => [
|
||||
binding.getName(),
|
||||
<KubeObjectStatusIcon object={binding} />,
|
||||
binding.getSubjectNames(),
|
||||
binding.getNs() || "-",
|
||||
binding.getAge(),
|
||||
|
||||
@ -2,4 +2,10 @@
|
||||
.help-icon {
|
||||
margin-left: $margin / 2;
|
||||
}
|
||||
|
||||
.TableCell {
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { rolesStore } from "./roles.store";
|
||||
import { Role } from "../../api/endpoints";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { AddRoleDialog } from "./add-role-dialog";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -38,11 +39,13 @@ export class Roles extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Roles</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(role: Role) => [
|
||||
role.getName(),
|
||||
<KubeObjectStatusIcon object={role} />,
|
||||
role.getNs() || "-",
|
||||
role.getAge(),
|
||||
]}
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
.ServiceAccounts {
|
||||
.TableCell {
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@ import { IServiceAccountsRouteParams } from "../+user-management";
|
||||
import { serviceAccountsStore } from "./service-accounts.store";
|
||||
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 {
|
||||
name = "name",
|
||||
@ -42,11 +43,13 @@ export class ServiceAccounts extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Service Accounts</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
]}
|
||||
renderTableContents={(account: ServiceAccount) => [
|
||||
account.getName(),
|
||||
<KubeObjectStatusIcon object={account} />,
|
||||
account.getNs(),
|
||||
account.getAge(),
|
||||
]}
|
||||
|
||||
@ -13,10 +13,10 @@ import { eventStore } from "../+events/event.store";
|
||||
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { ICronJobsRouteParams } from "../+workloads";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { _i18n } from "../../i18n";
|
||||
import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
|
||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -62,11 +62,7 @@ export class CronJobs extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(cronJob: CronJob) => [
|
||||
cronJob.getName(),
|
||||
<KubeEventIcon object={cronJob} filterEvents={events => {
|
||||
if (!cronJob.isNeverRun()) return events;
|
||||
return events.filter(event => event.reason != "FailedNeedsStart");
|
||||
}
|
||||
}/>,
|
||||
<KubeObjectStatusIcon object={cronJob} />,
|
||||
cronJob.getNs(),
|
||||
cronJob.isNeverRun() ? <Trans>never</Trans> : cronJob.getSchedule(),
|
||||
cronJob.getSuspendFlag(),
|
||||
|
||||
@ -3,8 +3,7 @@ import "./daemonsets.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { DaemonSet, daemonSetApi } from "../../api/endpoints";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { DaemonSet } from "../../api/endpoints";
|
||||
import { eventStore } from "../+events/event.store";
|
||||
import { daemonSetStore } from "./daemonsets.store";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
@ -13,8 +12,7 @@ import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IDaemonSetsRouteParams } from "../+workloads";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { Badge } from "../badge";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -66,7 +64,7 @@ export class DaemonSets extends React.Component<Props> {
|
||||
daemonSet.getName(),
|
||||
daemonSet.getNs(),
|
||||
this.getPodsLength(daemonSet),
|
||||
<KubeEventIcon object={daemonSet}/>,
|
||||
<KubeObjectStatusIcon object={daemonSet}/>,
|
||||
this.renderNodeSelector(daemonSet),
|
||||
daemonSet.getAge(),
|
||||
]}
|
||||
|
||||
@ -21,9 +21,8 @@ import { _i18n } from "../../i18n";
|
||||
import { cssNames } from "../../utils";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import orderBy from "lodash/orderBy";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
import { Notifications } from "../notifications";
|
||||
|
||||
enum sortBy {
|
||||
@ -72,19 +71,19 @@ export class Deployments extends React.Component<Props> {
|
||||
renderHeaderTitle={<Trans>Deployments</Trans>}
|
||||
renderTableHeader={[
|
||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
||||
{ title: <Trans>Pods</Trans>, className: "pods" },
|
||||
{ title: <Trans>Replicas</Trans>, className: "replicas", sortBy: sortBy.replicas },
|
||||
{ className: "warning" },
|
||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
||||
{ title: <Trans>Conditions</Trans>, className: "conditions", sortBy: sortBy.condition },
|
||||
]}
|
||||
renderTableContents={(deployment: Deployment) => [
|
||||
deployment.getName(),
|
||||
<KubeObjectStatusIcon object={deployment}/>,
|
||||
deployment.getNs(),
|
||||
this.renderPods(deployment),
|
||||
deployment.getReplicas(),
|
||||
<KubeEventIcon object={deployment}/>,
|
||||
deployment.getAge(),
|
||||
this.renderConditions(deployment),
|
||||
]}
|
||||
|
||||
@ -7,13 +7,11 @@ import { Trans } from "@lingui/macro";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { jobStore } from "./job.store";
|
||||
import { eventStore } from "../+events/event.store";
|
||||
import { Job, jobApi } from "../../api/endpoints/job.api";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { Job } from "../../api/endpoints/job.api";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IJobsRouteParams } from "../+workloads";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -56,7 +54,7 @@ export class Jobs extends React.Component<Props> {
|
||||
job.getName(),
|
||||
job.getNs(),
|
||||
`${job.getCompletions()} / ${job.getDesiredCompletions()}`,
|
||||
<KubeEventIcon object={job}/>,
|
||||
<KubeObjectStatusIcon object={job}/>,
|
||||
job.getAge(),
|
||||
condition && {
|
||||
title: condition.type,
|
||||
|
||||
@ -7,7 +7,6 @@ import { Trans } from "@lingui/macro";
|
||||
import { podsStore } from "./pods.store";
|
||||
import { Pod } from "../../api/endpoints";
|
||||
import { autobind, bytesToUnits, cssNames, interval, prevDefault } from "../../utils";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { LineProgress } from "../line-progress";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
@ -15,6 +14,7 @@ import { showDetails } from "../../navigation";
|
||||
import { reaction } from "mobx";
|
||||
import { Spinner } from "../spinner";
|
||||
import { DrawerTitle } from "../drawer";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -107,7 +107,7 @@ export class PodDetailsList extends React.Component<Props> {
|
||||
onClick={prevDefault(() => showDetails(pod.selfLink, false))}
|
||||
>
|
||||
<TableCell className="name">{pod.getName()}</TableCell>
|
||||
<TableCell className="warning">{pod.hasIssues() && <KubeEventIcon object={pod}/>}</TableCell>
|
||||
<TableCell className="warning"><KubeObjectStatusIcon object={pod}/></TableCell>
|
||||
<TableCell className="namespace">{pod.getNs()}</TableCell>
|
||||
<TableCell className="cpu">{this.renderCpuUsage(`cpu-${pod.getId()}`, metrics.cpu)}</TableCell>
|
||||
<TableCell className="memory">{this.renderMemoryUsage(`memory-${pod.getId()}`, metrics.memory)}</TableCell>
|
||||
|
||||
@ -13,12 +13,13 @@ import { KubeObjectListLayout } from "../kube-object";
|
||||
import { Pod } from "../../api/endpoints";
|
||||
import { StatusBrick } from "../status-brick";
|
||||
import { cssNames, stopPropagation } from "../../utils";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import toPairs from "lodash/toPairs";
|
||||
import startCase from "lodash/startCase";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import { lookupApiLink } from "../../api/kube-api";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -100,7 +101,7 @@ export class Pods extends React.Component<Props> {
|
||||
]}
|
||||
renderTableContents={(pod: Pod) => [
|
||||
pod.getName(),
|
||||
pod.hasIssues() && <KubeEventIcon object={pod}/>,
|
||||
<KubeObjectStatusIcon object={pod} />,
|
||||
pod.getNs(),
|
||||
this.renderContainersStatus(pod),
|
||||
pod.getRestartsCount(),
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
@include table-cell-warning;
|
||||
}
|
||||
|
||||
&.namespace {
|
||||
flex-grow: 1.2;
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import { DrawerTitle } from "../drawer";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
import { showDetails } from "../../navigation";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -56,6 +57,7 @@ export class ReplicaSets extends React.Component<Props> {
|
||||
>
|
||||
<TableHead>
|
||||
<TableCell className="name" sortBy={sortBy.name}><Trans>Name</Trans></TableCell>
|
||||
<TableCell className="warning"/>
|
||||
<TableCell className="namespace" sortBy={sortBy.namespace}>Namespace</TableCell>
|
||||
<TableCell className="pods" sortBy={sortBy.pods}><Trans>Pods</Trans></TableCell>
|
||||
<TableCell className="age" sortBy={sortBy.age}><Trans>Age</Trans></TableCell>
|
||||
@ -71,6 +73,7 @@ export class ReplicaSets extends React.Component<Props> {
|
||||
onClick={prevDefault(() => showDetails(replica.selfLink, false))}
|
||||
>
|
||||
<TableCell className="name">{replica.getName()}</TableCell>
|
||||
<TableCell className="warning"><KubeObjectStatusIcon object={replica}/></TableCell>
|
||||
<TableCell className="namespace">{replica.getNs()}</TableCell>
|
||||
<TableCell className="pods">{this.getPodsLength(replica)}</TableCell>
|
||||
<TableCell className="age">{replica.getAge()}</TableCell>
|
||||
|
||||
@ -4,16 +4,14 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { RouteComponentProps } from "react-router";
|
||||
import { Trans } from "@lingui/macro";
|
||||
import { StatefulSet, statefulSetApi } from "../../api/endpoints";
|
||||
import { StatefulSet } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { statefulSetStore } from "./statefulset.store";
|
||||
import { nodesStore } from "../+nodes/nodes.store";
|
||||
import { eventStore } from "../+events/event.store";
|
||||
import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import { IStatefulSetsRouteParams } from "../+workloads";
|
||||
import { KubeEventIcon } from "../+events/kube-event-icon";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
enum sortBy {
|
||||
name = "name",
|
||||
@ -57,7 +55,7 @@ export class StatefulSets extends React.Component<Props> {
|
||||
statefulSet.getName(),
|
||||
statefulSet.getNs(),
|
||||
this.getPodsLength(statefulSet),
|
||||
<KubeEventIcon object={statefulSet}/>,
|
||||
<KubeObjectStatusIcon object={statefulSet}/>,
|
||||
statefulSet.getAge(),
|
||||
]}
|
||||
/>
|
||||
|
||||
@ -172,6 +172,10 @@ a {
|
||||
color: $colorError;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: $colorWarning;
|
||||
}
|
||||
|
||||
.contrast {
|
||||
color: $textColorAccent;
|
||||
}
|
||||
|
||||
1
src/renderer/components/kube-object-status-icon/index.ts
Normal file
1
src/renderer/components/kube-object-status-icon/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./kube-object-status-icon"
|
||||
@ -0,0 +1,32 @@
|
||||
.KubeObjectStatusIcon {
|
||||
&.warning {
|
||||
color: $golden;
|
||||
}
|
||||
}
|
||||
|
||||
.KubeObjectStatusTooltip {
|
||||
white-space: normal;
|
||||
|
||||
.level {
|
||||
padding: 4px;
|
||||
|
||||
&:not(:only-child):not(:last-child) {
|
||||
border-bottom: 1px solid $borderFaintColor;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
.Icon {
|
||||
margin-right: $margin;
|
||||
}
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin: $margin / 2
|
||||
}
|
||||
|
||||
.age {
|
||||
color: $halfGray;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
import "./kube-object-status-icon.scss";
|
||||
|
||||
import React from "react";
|
||||
import { Icon } from "../icon";
|
||||
import { KubeObject } from "../../api/kube-object";
|
||||
import { cssNames, formatDuration } from "../../utils";
|
||||
import { KubeObjectStatusRegistration, kubeObjectStatusRegistry } from "../../../extensions/registries/kube-object-status-registry"
|
||||
import { KubeObjectStatus, KubeObjectStatusLevel } from "../../..//extensions/renderer-api/k8s-api";
|
||||
import { computed } from "mobx";
|
||||
|
||||
interface Props {
|
||||
object: KubeObject;
|
||||
}
|
||||
|
||||
export class KubeObjectStatusIcon extends React.Component<Props> {
|
||||
@computed get objectStatuses() {
|
||||
const { object } = this.props;
|
||||
const registrations = kubeObjectStatusRegistry.getItemsForKind(object.kind, object.apiVersion)
|
||||
return registrations.map((item: KubeObjectStatusRegistration) => { return item.resolve(object) }).filter((item: KubeObjectStatus) => !!item)
|
||||
}
|
||||
|
||||
statusClassName(level: number): string {
|
||||
switch (level) {
|
||||
case KubeObjectStatusLevel.INFO:
|
||||
return "info"
|
||||
case KubeObjectStatusLevel.WARNING:
|
||||
return "warning"
|
||||
case KubeObjectStatusLevel.CRITICAL:
|
||||
return "error"
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
statusTitle(level: number): string {
|
||||
switch (level) {
|
||||
case KubeObjectStatusLevel.INFO:
|
||||
return "Info"
|
||||
case KubeObjectStatusLevel.WARNING:
|
||||
return "Warning"
|
||||
case KubeObjectStatusLevel.CRITICAL:
|
||||
return "Critical"
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
getAge(timestamp: string) {
|
||||
if (!timestamp) return ""
|
||||
const diff = new Date().getTime() - new Date(timestamp).getTime();
|
||||
return formatDuration(diff, true);
|
||||
}
|
||||
|
||||
renderStatuses(statuses: KubeObjectStatus[], level: number) {
|
||||
const filteredStatuses = statuses.filter((item) => item.level == level)
|
||||
|
||||
return filteredStatuses.length > 0 && (
|
||||
<div className={cssNames("level", this.statusClassName(level))}>
|
||||
<span className="title">
|
||||
{this.statusTitle(level)}
|
||||
</span>
|
||||
{ filteredStatuses.map((status, index) =>{
|
||||
return (
|
||||
<div key={`kube-resource-status-${level}-${index}`} className={cssNames("status", "msg")}>
|
||||
- {status.text} <span className="age"> · { this.getAge(status.timestamp) }</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { objectStatuses} = this
|
||||
if (!objectStatuses.length) return null
|
||||
|
||||
const sortedStatuses = objectStatuses.sort((a: KubeObjectStatus, b: KubeObjectStatus) => {
|
||||
if (a.level < b.level ) {
|
||||
return 1
|
||||
}
|
||||
if (a.level > b.level ) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
})
|
||||
|
||||
const level = this.statusClassName(sortedStatuses[0].level)
|
||||
return (
|
||||
<Icon
|
||||
material={level}
|
||||
className={cssNames("KubeObjectStatusIcon", level)}
|
||||
tooltip={{
|
||||
children: (
|
||||
<div className="KubeObjectStatusTooltip">
|
||||
{this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.CRITICAL)}
|
||||
{this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.WARNING)}
|
||||
{this.renderStatuses(sortedStatuses, KubeObjectStatusLevel.INFO)}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -5,6 +5,7 @@ import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import { lookupApiLink } from "../../api/kube-api";
|
||||
import { Link } from "react-router-dom";
|
||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||
|
||||
export interface KubeObjectMetaProps {
|
||||
object: KubeObject;
|
||||
@ -36,7 +37,7 @@ export class KubeObjectMeta extends React.Component<KubeObjectMetaProps> {
|
||||
{getAge(true, false)} <Trans>ago</Trans> ({creationTimestamp})
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Name</Trans>} hidden={this.isHidden("name")}>
|
||||
{getName()}
|
||||
{getName()} <KubeObjectStatusIcon object={object} />
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Namespace</Trans>} hidden={this.isHidden("namespace") || !getNs()}>
|
||||
{getNs()}
|
||||
|
||||
@ -2,21 +2,33 @@
|
||||
|
||||
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.0-alpha.4 (current version)
|
||||
## 4.0.0-alpha.5 (current version)
|
||||
|
||||
- Extension API
|
||||
- Improved pod logs
|
||||
- Mechanism for users to specify accessible namespaces
|
||||
- Tray icon
|
||||
- Add last-status information for container
|
||||
- Add LoadBalancer information to Ingress view
|
||||
- Move tracker to an extension
|
||||
- Add support page (as an extension)
|
||||
- Ability to restart deployment
|
||||
- Status bar visual fixes
|
||||
- Fix proxy upgrade socket timeouts
|
||||
- Fix UI staleness after network issues
|
||||
- Add +/- buttons in scale deployment popup screen
|
||||
- Update chart details when selecting another chart
|
||||
|
||||
## 3.6.8
|
||||
- Fix cluster connection issue when opening cluster settings for disconnected clusters
|
||||
- Fetch available Helm repositories from Artifact HUB
|
||||
- Check if user is cluster admin before opening cluster dashboard
|
||||
- Fix issue when application is disconnecting too fast from pod shell
|
||||
- Fix UI staleness after network issues
|
||||
|
||||
## 3.6.7
|
||||
- Fix cluster dashboard opening when cluster is initially offline
|
||||
|
||||
## 3.6.6
|
||||
- Fix labels' word boundary to cover only drawer badges
|
||||
- Fix cluster dashboard opening not to start authentication proxy twice
|
||||
|
||||
92
yarn.lock
92
yarn.lock
@ -2158,7 +2158,7 @@
|
||||
dependencies:
|
||||
"@types/webpack" "*"
|
||||
|
||||
"@types/minimatch@*":
|
||||
"@types/minimatch@*", "@types/minimatch@3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
@ -3412,6 +3412,13 @@ babel-runtime@^6.26.0:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.11.0"
|
||||
|
||||
backbone@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/backbone/-/backbone-1.4.0.tgz#54db4de9df7c3811c3f032f34749a4cd27f3bd12"
|
||||
integrity sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==
|
||||
dependencies:
|
||||
underscore ">=1.8.3"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
@ -7003,7 +7010,7 @@ handle-thing@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
|
||||
integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
|
||||
|
||||
handlebars@^4.7.6:
|
||||
handlebars@^4.7.2, handlebars@^4.7.6:
|
||||
version "4.7.6"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e"
|
||||
integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==
|
||||
@ -7142,10 +7149,10 @@ he@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
highlight.js@^10.2.0:
|
||||
version "10.3.2"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.3.2.tgz#135fd3619a00c3cbb8b4cd6dbc78d56bfcbc46f1"
|
||||
integrity sha512-3jRT7OUYsVsKvukNKZCtnvRcFyCJqSEIuIMsEybAXRiFSwpt65qjPd/Pr+UOdYt7WJlt+lj3+ypUsHiySBp/Jw==
|
||||
highlight.js@^9.18.0:
|
||||
version "9.18.3"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634"
|
||||
integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==
|
||||
|
||||
history@^4.10.1, history@^4.9.0:
|
||||
version "4.10.1"
|
||||
@ -8596,6 +8603,11 @@ jose@^1.27.1:
|
||||
dependencies:
|
||||
"@panva/asn1.js" "^1.0.0"
|
||||
|
||||
jquery@^3.4.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5"
|
||||
integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==
|
||||
|
||||
js-base64@^2.1.8:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.2.tgz#313b6274dda718f714d00b3330bbae6e38e90209"
|
||||
@ -9296,7 +9308,7 @@ lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.1
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
|
||||
lodash@^4.17.19, lodash@^4.17.20:
|
||||
lodash@^4.17.19:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
@ -9381,7 +9393,7 @@ lru-cache@^5.1.1:
|
||||
dependencies:
|
||||
yallist "^3.0.2"
|
||||
|
||||
lunr@^2.3.9:
|
||||
lunr@^2.3.8:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
|
||||
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
||||
@ -9478,16 +9490,16 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
marked@^0.8.0:
|
||||
version "0.8.2"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355"
|
||||
integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==
|
||||
|
||||
marked@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.1.0.tgz#62504ad4d11550c942935ccc5e39d64e5a4c4e50"
|
||||
integrity sha512-EkE7RW6KcXfMHy2PA7Jg0YJE1l8UPEZE8k45tylzmZM30/r1M1MUXWQfJlrSbsTeh7m/XTwHbWUENvAJZpp1YA==
|
||||
|
||||
marked@^1.1.1:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.3.tgz#58817ba348a7c9398cb94d40d12e0d08df83af57"
|
||||
integrity sha512-RQuL2i6I6Gn+9n81IDNGbL0VHnta4a+8ZhqvryXEniTb/hQNtf3i26hi1XWUhzb9BgVyWHKR3UO8MaHtKoYibw==
|
||||
|
||||
matcher@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
|
||||
@ -12905,7 +12917,7 @@ shell-env@^3.0.0:
|
||||
execa "^1.0.0"
|
||||
strip-ansi "^5.2.0"
|
||||
|
||||
shelljs@^0.8.2, shelljs@^0.8.4:
|
||||
shelljs@^0.8.2, shelljs@^0.8.3:
|
||||
version "0.8.4"
|
||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2"
|
||||
integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==
|
||||
@ -14180,34 +14192,39 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typedoc-default-themes@^0.11.4:
|
||||
version "0.11.4"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.11.4.tgz#1bc55b7c8d1132844616ff6f570e1e2cd0eb7343"
|
||||
integrity sha512-Y4Lf+qIb9NTydrexlazAM46SSLrmrQRqWiD52593g53SsmUFioAsMWt8m834J6qsp+7wHRjxCXSZeiiW5cMUdw==
|
||||
|
||||
typedoc-plugin-markdown@^3.0.11:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.0.11.tgz#358c32f4a0086c1dd2da7f56c4b46ade8a63204b"
|
||||
integrity sha512-/BE/PqnIVbQJ525czM+T3CVaA1gVN9X1Le100z8TV/Lze8LZVkuAUiHRIgw9BKYFm9IQaB88W55k4EV6uUVwYQ==
|
||||
typedoc-default-themes@0.8.0-0:
|
||||
version "0.8.0-0"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.8.0-0.tgz#80b7080837b2c9eba36c2fe06601ebe01973a0cd"
|
||||
integrity sha512-blFWppm5aKnaPOa1tpGO9MLu+njxq7P3rtkXK4QxJBNszA+Jg7x0b+Qx0liXU1acErur6r/iZdrwxp5DUFdSXw==
|
||||
dependencies:
|
||||
handlebars "^4.7.6"
|
||||
backbone "^1.4.0"
|
||||
jquery "^3.4.1"
|
||||
lunr "^2.3.8"
|
||||
underscore "^1.9.1"
|
||||
|
||||
typedoc@^0.19.2:
|
||||
version "0.19.2"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.19.2.tgz#842a63a581f4920f76b0346bb80eb2a49afc2c28"
|
||||
integrity sha512-oDEg1BLEzi1qvgdQXc658EYgJ5qJLVSeZ0hQ57Eq4JXy6Vj2VX4RVo18qYxRWz75ifAaYuYNBUCnbhjd37TfOg==
|
||||
typedoc-plugin-markdown@^2.4.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-2.4.2.tgz#2d83fe4f279643436ebc44ca2f937855b0fd9f12"
|
||||
integrity sha512-BBH+9/Uq5XbsqfzCDl8Jq4iaLXRMXRuAHZRFarAZX7df8+F3vUjDx/WHWoWqbZ/XUFzduLC2Iuy2qwsJX8SQ7A==
|
||||
dependencies:
|
||||
fs-extra "^9.0.1"
|
||||
handlebars "^4.7.6"
|
||||
highlight.js "^10.2.0"
|
||||
lodash "^4.17.20"
|
||||
lunr "^2.3.9"
|
||||
marked "^1.1.1"
|
||||
|
||||
typedoc@0.17.0-3:
|
||||
version "0.17.0-3"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.17.0-3.tgz#91996e77427ff3a208ab76595a927ee11b75e9e8"
|
||||
integrity sha512-DO2djkR4NHgzAWfNbJb2eQKsFMs+gOuYBXlQ8dOSCjkAK5DRI7ZywDufBGPUw7Ue9Qwi2Cw1DxLd3reDq8wFuQ==
|
||||
dependencies:
|
||||
"@types/minimatch" "3.0.3"
|
||||
fs-extra "^8.1.0"
|
||||
handlebars "^4.7.2"
|
||||
highlight.js "^9.18.0"
|
||||
lodash "^4.17.15"
|
||||
marked "^0.8.0"
|
||||
minimatch "^3.0.0"
|
||||
progress "^2.0.3"
|
||||
semver "^7.3.2"
|
||||
shelljs "^0.8.4"
|
||||
typedoc-default-themes "^0.11.4"
|
||||
shelljs "^0.8.3"
|
||||
typedoc-default-themes "0.8.0-0"
|
||||
|
||||
typeface-roboto@^0.0.75:
|
||||
version "0.0.75"
|
||||
@ -14248,6 +14265,11 @@ underscore@1.7.0:
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
|
||||
integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
|
||||
|
||||
underscore@>=1.8.3:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.11.0.tgz#dd7c23a195db34267186044649870ff1bab5929e"
|
||||
integrity sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw==
|
||||
|
||||
underscore@^1.9.1:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user