1
0
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:
Roman 2020-11-11 13:58:44 +02:00
commit ab097c410c
74 changed files with 4195 additions and 136 deletions

View File

@ -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 }}

View 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)

View File

@ -0,0 +1,8 @@
install-deps:
npm install
build: install-deps
npm run build
test:
npm run test

File diff suppressed because it is too large Load Diff

View 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"
}
}

View 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)
},
]
}

View 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
}
}

View 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"
]
}

View 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'),
},
},
];

View File

@ -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: {}

View File

@ -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",

View File

@ -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,
}

View File

@ -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[]) {

View File

@ -0,0 +1 @@
export * from "./registrations"

View 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"

View File

@ -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[] = []

View File

@ -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"

View 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();

View File

@ -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"

View File

@ -0,0 +1,11 @@
export type KubeObjectStatus = {
level: KubeObjectStatusLevel;
text: string;
timestamp?: string;
}
export enum KubeObjectStatusLevel {
INFO = 1,
WARNING = 2,
CRITICAL = 3
}

View File

@ -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)) : "");
}
}

View File

@ -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 {

View File

@ -6,6 +6,10 @@
flex: 1.5;
}
&.warning {
@include table-cell-warning;
}
&.metrics {
flex: 1.5;
}

View File

@ -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(),

View File

@ -4,6 +4,10 @@
flex: 2;
}
&.warning {
@include table-cell-warning;
}
&.keys {
flex: 2.5;
}

View File

@ -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(),

View File

@ -4,6 +4,10 @@
flex: 2;
}
&.warning {
@include table-cell-warning;
}
&.keys {
flex: 2.5;
}

View File

@ -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(),

View File

@ -1,2 +1,7 @@
.ResourceQuotas {
.TableCell {
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),
]}

View File

@ -4,6 +4,10 @@
flex: 1.5;
}
&.warning {
@include table-cell-warning;
}
&.labels {
@include table-cell-labels-offsets;
}

View File

@ -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(", "),

View File

@ -4,6 +4,10 @@
flex: 2;
}
&.warning {
@include table-cell-warning;
}
&.labels {
flex: 4;
@include table-cell-labels-offsets;

View File

@ -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() },

View File

@ -3,5 +3,9 @@
&.endpoints {
flex-grow: 5.0;
}
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),

View File

@ -3,5 +3,9 @@
&.rules {
flex-grow: 3.0;
}
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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>),

View File

@ -1,2 +1,7 @@
.NetworkPolicies {
.TableCell {
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),

View File

@ -4,6 +4,10 @@
flex: 0.6;
}
&.warning {
@include table-cell-warning;
}
&.age {
flex: 0.4;
}

View File

@ -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(),

View File

@ -7,6 +7,10 @@
text-overflow: ellipsis;
}
&.warning {
@include table-cell-warning;
}
&.cpu {
flex: 1.0;
align-self: center;

View File

@ -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),

View File

@ -4,6 +4,10 @@
&.volumes {
flex-grow: 2;
}
&.warning {
@include table-cell-warning;
}
}
}
}

View File

@ -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(),

View File

@ -3,5 +3,9 @@
&.is-default {
flex: .5;
}
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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,

View File

@ -6,6 +6,10 @@
flex-grow: 3;
}
&.warning {
@include table-cell-warning;
}
&.storage {
flex: 0.6;
}

View File

@ -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}

View File

@ -6,6 +6,10 @@
flex-grow: 3;
}
&.warning {
@include table-cell-warning;
}
&.storage {
flex: 0.6;
}

View File

@ -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>,

View File

@ -2,4 +2,10 @@
.help-icon {
margin-left: $margin / 2;
}
.TableCell {
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),

View File

@ -2,4 +2,10 @@
.help-icon {
margin-left: $margin / 2;
}
.TableCell {
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),
]}

View File

@ -1,2 +1,7 @@
.ServiceAccounts {
.TableCell {
&.warning {
@include table-cell-warning;
}
}
}

View File

@ -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(),
]}

View File

@ -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(),

View File

@ -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(),
]}

View File

@ -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),
]}

View File

@ -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,

View File

@ -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>

View File

@ -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(),

View File

@ -19,6 +19,10 @@
flex-grow: 2;
}
&.warning {
@include table-cell-warning;
}
&.namespace {
flex-grow: 1.2;
}

View File

@ -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>

View File

@ -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(),
]}
/>

View File

@ -172,6 +172,10 @@ a {
color: $colorError;
}
.warning {
color: $colorWarning;
}
.contrast {
color: $textColorAccent;
}

View File

@ -0,0 +1 @@
export * from "./kube-object-status-icon"

View File

@ -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;
}
}
}

View File

@ -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>
)
}}
/>
)
}
}

View File

@ -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()}

View File

@ -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

View File

@ -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"