diff --git a/docs/contributing/promotion.md b/docs/contributing/promotion.md index 6f80ddb2b2..34d68231bd 100644 --- a/docs/contributing/promotion.md +++ b/docs/contributing/promotion.md @@ -17,11 +17,11 @@ There are many sites where you can vote, recommend, favorite and star us. Here are some nice blog posts and videos about our project for you to get some inspiration: -[Onboard AWS EKS Cluster on Lens(Kubernetes IDE)](https://dev.to/himwad05/onboard-aws-eks-cluster-on-lens-kubernetes-ide-492l) -[Using Lens to Manage All Your Kubernetes Cluster](https://medium.com/@magicmagnate/using-lens-to-manage-all-your-kubernetes-cluster-c1ef88fdb476) -[Kontena Lens - Beautiful Kubernetes UI](https://www.youtube.com/watch?v=YGgaiGdYfdI) -[Gerenciando Kubernetes com Lens e Octant](https://www.youtube.com/watch?v=h9ZqDelJLQQ) -[Walkthrough of Kubernetes IDE - Lens](https://www.youtube.com/watch?v=602aHZSdEfY) -[LENS - Interfaz Gráfica para Kubernetes en 1 PASO.](https://www.youtube.com/watch?v=DFMKcR4BqwM) +* [Onboard AWS EKS Cluster on Lens(Kubernetes IDE)](https://dev.to/himwad05/onboard-aws-eks-cluster-on-lens-kubernetes-ide-492l) +* [Using Lens to Manage All Your Kubernetes Cluster](https://medium.com/@magicmagnate/using-lens-to-manage-all-your-kubernetes-cluster-c1ef88fdb476) +* [Kontena Lens - Beautiful Kubernetes UI](https://www.youtube.com/watch?v=YGgaiGdYfdI) +* [Gerenciando Kubernetes com Lens e Octant](https://www.youtube.com/watch?v=h9ZqDelJLQQ) +* [Walkthrough of Kubernetes IDE - Lens](https://www.youtube.com/watch?v=602aHZSdEfY) +* [LENS - Interfaz Gráfica para Kubernetes en 1 PASO.](https://www.youtube.com/watch?v=DFMKcR4BqwM) Psst... If you have created some content around Lens, let us know! diff --git a/mkdocs.yml b/mkdocs.yml index b8159f8fd2..d0a58ac530 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -35,7 +35,13 @@ nav: - Publishing Extensions: extensions/testing-and-publishing/publishing.md - Bundling Extensions: extensions/testing-and-publishing/bundling.md - API Reference: extensions/api/README.md - - Contributing: contributing/README.md + - Contributing: + - Overview: contributing/README.md + - Development: contributing/development.md + - Documentation: contributing/documentation.md + - Maintainers: contributing/maintainers.md + - Promotion: contributing/promotion.md + - FAQ: faq/README.md theme: name: 'material' diff --git a/package.json b/package.json index 7a2f53f412..15bf712c1e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "dev-build": "concurrently yarn:compile:*", "dev-run": "nodemon --watch static/build/main.js --exec \"electron --inspect .\"", "dev:main": "yarn compile:main --watch", - "dev:renderer": "yarn compile:renderer --watch", + "dev:renderer": "yarn webpack-dev-server --config webpack.renderer.ts", "dev:extension-types": "yarn compile:extension-types --watch", "compile": "env NODE_ENV=production concurrently yarn:compile:*", "compile:main": "webpack --config webpack.main.ts", @@ -268,6 +268,7 @@ "@lingui/macro": "^3.0.0-13", "@lingui/react": "^3.0.0-13", "@material-ui/core": "^4.10.1", + "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", "@rollup/plugin-json": "^4.1.0", "@testing-library/jest-dom": "^5.11.5", "@testing-library/react": "^11.1.0", @@ -279,6 +280,7 @@ "@types/electron-window-state": "^2.0.34", "@types/fs-extra": "^9.0.1", "@types/hapi": "^18.0.3", + "@types/hard-source-webpack-plugin": "^1.0.1", "@types/hoist-non-react-statics": "^3.3.1", "@types/html-webpack-plugin": "^3.2.3", "@types/http-proxy": "^1.17.4", @@ -315,6 +317,7 @@ "@types/uuid": "^8.0.0", "@types/webdriverio": "^4.13.0", "@types/webpack": "^4.41.17", + "@types/webpack-dev-server": "^3.11.1", "@types/webpack-env": "^1.15.2", "@types/webpack-node-externals": "^1.7.1", "@typescript-eslint/eslint-plugin": "^4.0.0", @@ -339,6 +342,7 @@ "file-loader": "^6.0.0", "flex.box": "^3.4.4", "fork-ts-checker-webpack-plugin": "^5.0.0", + "hard-source-webpack-plugin": "^0.13.1", "hoist-non-react-statics": "^3.3.2", "html-webpack-plugin": "^4.3.0", "identity-obj-proxy": "^3.0.0", @@ -360,6 +364,7 @@ "react": "^16.14.0", "react-beautiful-dnd": "^13.0.0", "react-dom": "^16.13.1", + "react-refresh": "^0.9.0", "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-select": "^3.1.0", @@ -376,11 +381,13 @@ "ts-jest": "^26.1.0", "ts-loader": "^7.0.5", "ts-node": "^8.10.2", + "type-fest": "^0.18.0", "typeface-roboto": "^0.0.75", "typescript": "^4.0.2", "url-loader": "^4.1.0", - "webpack": "^4.43.0", + "webpack": "^4.44.2", "webpack-cli": "^3.3.11", + "webpack-dev-server": "^3.11.0", "webpack-node-externals": "^1.7.2", "xterm": "^4.6.0", "xterm-addon-fit": "^0.4.0" diff --git a/src/common/vars.ts b/src/common/vars.ts index 206aa59ce2..dd792e3bed 100644 --- a/src/common/vars.ts +++ b/src/common/vars.ts @@ -22,6 +22,7 @@ export const mainDir = path.join(contextDir, "src/main"); export const rendererDir = path.join(contextDir, "src/renderer"); export const htmlTemplate = path.resolve(rendererDir, "template.html"); export const sassCommonVars = path.resolve(rendererDir, "components/vars.scss"); +export const webpackDevServerPort = 9009 // Special runtime paths defineGlobal("__static", { diff --git a/src/extensions/renderer-api/components.ts b/src/extensions/renderer-api/components.ts index 76bf6c2b50..c051ce13e3 100644 --- a/src/extensions/renderer-api/components.ts +++ b/src/extensions/renderer-api/components.ts @@ -1,23 +1,38 @@ -// TODO: add more common re-usable UI components + refactor interfaces (Props -> ComponentProps) +// Common UI components -export * from "../../renderer/components/icon" -export * from "../../renderer/components/checkbox" -export * from "../../renderer/components/tooltip" -export * from "../../renderer/components/button" -export * from "../../renderer/components/tabs" -export * from "../../renderer/components/badge" +// layouts export * from "../../renderer/components/layout/page-layout" +export * from "../../renderer/components/layout/wizard-layout" +export * from "../../renderer/components/layout/tab-layout" + +// form-controls +export * from "../../renderer/components/button" +export * from "../../renderer/components/checkbox" +export * from "../../renderer/components/radio" +export * from "../../renderer/components/select" +export * from "../../renderer/components/slider" +export * from "../../renderer/components/input/input" + +// other components +export * from "../../renderer/components/icon" +export * from "../../renderer/components/tooltip" +export * from "../../renderer/components/tabs" +export * from "../../renderer/components/table" +export * from "../../renderer/components/badge" export * from "../../renderer/components/drawer" +export * from "../../renderer/components/dialog" +export * from "../../renderer/components/confirm-dialog"; +export * from "../../renderer/components/line-progress" +export * from "../../renderer/components/menu" +export * from "../../renderer/components/notifications" +export * from "../../renderer/components/spinner" +export * from "../../renderer/components/stepper" // kube helpers -export { KubeObjectDetailsProps, KubeObjectMenuProps } from "../../renderer/components/kube-object" -export { KubeObjectMeta } from "../../renderer/components/kube-object/kube-object-meta" -export { KubeObjectListLayout, KubeObjectListLayoutProps } from "../../renderer/components/kube-object/kube-object-list-layout"; -export { KubeEventDetails } from "../../renderer/components/+events/kube-event-details" +export * from "../../renderer/components/kube-object" +export * from "../../renderer/components/+events/kube-event-details" // specific exports -export { ConfirmDialog } from "../../renderer/components/confirm-dialog"; -export { MenuItem, SubMenu } from "../../renderer/components/menu"; -export { StatusBrick } from "../../renderer/components/status-brick"; +export * from "../../renderer/components/status-brick"; export { terminalStore, createTerminalTab } from "../../renderer/components/dock/terminal.store"; export { createPodLogsTab } from "../../renderer/components/dock/pod-logs.store"; diff --git a/src/main/router.ts b/src/main/router.ts index 976d7cac9c..a5323bf150 100644 --- a/src/main/router.ts +++ b/src/main/router.ts @@ -4,7 +4,7 @@ import http from "http" import path from "path" import { readFile } from "fs-extra" import { Cluster } from "./cluster" -import { apiPrefix, appName, publicPath } from "../common/vars"; +import { apiPrefix, appName, publicPath, isDevelopment, webpackDevServerPort } from "../common/vars"; import { helmRoute, kubeconfigRoute, metricsRoute, portForwardRoute, resourceApplierRoute, watchRoute } from "./routes"; export interface RouterRequestOpts { @@ -94,23 +94,35 @@ export class Router { return mimeTypes[path.extname(filename).slice(1)] || "text/plain" } - async handleStaticFile(filePath: string, res: http.ServerResponse) { + async handleStaticFile(filePath: string, res: http.ServerResponse, req: http.IncomingMessage) { const asset = path.join(__static, filePath); try { + const filename = path.basename(req.url); + // redirect requests to [appName].js, [appName].html /sockjs-node/ to webpack-dev-server (for hot-reload support) + const toWebpackDevServer = filename.includes(appName) || filename.includes('hot-update') || req.url.includes('sockjs-node'); + if (isDevelopment && toWebpackDevServer) { + const redirectLocation = `http://localhost:${webpackDevServerPort}` + req.url; + res.statusCode = 307; + res.setHeader('Location', redirectLocation); + res.end(); + return; + } const data = await readFile(asset); res.setHeader("Content-Type", this.getMimeType(asset)); - res.write(data) - res.end() + res.write(data); + res.end(); } catch (err) { - this.handleStaticFile(`${publicPath}/${appName}.html`, res); + this.handleStaticFile(`${publicPath}/${appName}.html`, res, req); } } protected addRoutes() { // Static assets - this.router.add({ method: 'get', path: '/{path*}' }, ({ params, response }: LensApiRequest) => { - this.handleStaticFile(params.path, response); - }); + this.router.add( + { method: 'get', path: '/{path*}' }, + ({ params, response, path, raw: { req }}: LensApiRequest) => { + this.handleStaticFile(params.path, response, req); + }); this.router.add({ method: "get", path: `${apiPrefix}/kubeconfig/service-account/{namespace}/{account}` }, kubeconfigRoute.routeServiceAccountRoute.bind(kubeconfigRoute)) diff --git a/src/renderer/api/api-manager.ts b/src/renderer/api/api-manager.ts index b178c55739..0b066f37e1 100644 --- a/src/renderer/api/api-manager.ts +++ b/src/renderer/api/api-manager.ts @@ -1,22 +1,13 @@ import type { KubeObjectStore } from "../kube-object.store"; -import type { KubeObjectDetailsProps, KubeObjectListLayoutProps, KubeObjectMenuProps } from "../components/kube-object"; -import type React from "react"; -import { observable } from "mobx"; +import { action, observable } from "mobx"; import { autobind } from "../utils"; import { KubeApi } from "./kube-api"; -export interface ApiComponents { - List?: React.ComponentType; - Menu?: React.ComponentType; - Details?: React.ComponentType; -} - @autobind() export class ApiManager { private apis = observable.map(); private stores = observable.map(); - private views = observable.map(); getApi(pathOrCallback: string | ((api: KubeApi) => boolean)) { if (typeof pathOrCallback === "string") { @@ -46,8 +37,11 @@ export class ApiManager { } } - registerStore(api: KubeApi, store: KubeObjectStore) { - this.stores.set(api, store); + @action + registerStore(store: KubeObjectStore, apis: KubeApi[] = [store.api]) { + apis.forEach(api => { + this.stores.set(api, store); + }) } getStore(api: string | KubeApi): KubeObjectStore { diff --git a/src/renderer/api/kube-api.ts b/src/renderer/api/kube-api.ts index d2373985f0..b572bd774c 100644 --- a/src/renderer/api/kube-api.ts +++ b/src/renderer/api/kube-api.ts @@ -9,7 +9,6 @@ import { kubeWatchApi } from "./kube-watch-api"; import { apiManager } from "./api-manager"; import { createKubeApiURL, parseKubeApi } from "./kube-api-parse"; import { apiKubePrefix, isDevelopment } from "../../common/vars"; -import * as URL from "url" export interface IKubeApiOptions { apiBase?: string; // base api-path for listing all resources, e.g. "/api/v1/pods" diff --git a/src/renderer/components/+cluster/cluster.store.ts b/src/renderer/components/+cluster/cluster.store.ts index 01c4e0f013..3af42297b0 100644 --- a/src/renderer/components/+cluster/cluster.store.ts +++ b/src/renderer/components/+cluster/cluster.store.ts @@ -107,4 +107,4 @@ export class ClusterStore extends KubeObjectStore { } export const clusterStore = new ClusterStore(); -apiManager.registerStore(clusterApi, clusterStore); +apiManager.registerStore(clusterStore); diff --git a/src/renderer/components/+config-autoscalers/hpa.store.ts b/src/renderer/components/+config-autoscalers/hpa.store.ts index 62b971dd5c..240f42a309 100644 --- a/src/renderer/components/+config-autoscalers/hpa.store.ts +++ b/src/renderer/components/+config-autoscalers/hpa.store.ts @@ -9,4 +9,4 @@ export class HPAStore extends KubeObjectStore { } export const hpaStore = new HPAStore(); -apiManager.registerStore(hpaApi, hpaStore); +apiManager.registerStore(hpaStore); diff --git a/src/renderer/components/+config-maps/config-maps.store.ts b/src/renderer/components/+config-maps/config-maps.store.ts index 5fd2526641..d6dcc5f916 100644 --- a/src/renderer/components/+config-maps/config-maps.store.ts +++ b/src/renderer/components/+config-maps/config-maps.store.ts @@ -9,4 +9,4 @@ export class ConfigMapsStore extends KubeObjectStore { } export const configMapsStore = new ConfigMapsStore(); -apiManager.registerStore(configMapApi, configMapsStore); +apiManager.registerStore(configMapsStore); diff --git a/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store.ts b/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store.ts index f25904119e..1eca71e1ba 100644 --- a/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store.ts +++ b/src/renderer/components/+config-pod-disruption-budgets/pod-disruption-budgets.store.ts @@ -9,4 +9,4 @@ export class PodDisruptionBudgetsStore extends KubeObjectStore { } export const resourceQuotaStore = new ResourceQuotasStore(); -apiManager.registerStore(resourceQuotaApi, resourceQuotaStore); +apiManager.registerStore(resourceQuotaStore); diff --git a/src/renderer/components/+config-secrets/secrets.store.ts b/src/renderer/components/+config-secrets/secrets.store.ts index 18f3a3e5d3..df5a78b3ac 100644 --- a/src/renderer/components/+config-secrets/secrets.store.ts +++ b/src/renderer/components/+config-secrets/secrets.store.ts @@ -9,4 +9,4 @@ export class SecretsStore extends KubeObjectStore { } export const secretsStore = new SecretsStore(); -apiManager.registerStore(secretsApi, secretsStore); +apiManager.registerStore(secretsStore); diff --git a/src/renderer/components/+custom-resources/crd-resources.tsx b/src/renderer/components/+custom-resources/crd-resources.tsx index 26c8c17e5c..3a7d726b59 100644 --- a/src/renderer/components/+custom-resources/crd-resources.tsx +++ b/src/renderer/components/+custom-resources/crd-resources.tsx @@ -10,7 +10,7 @@ import { KubeObject } from "../../api/kube-object"; import { ICRDRouteParams } from "./crd.route"; import { autorun, computed } from "mobx"; import { crdStore } from "./crd.store"; -import { SortingCallback } from "../table"; +import { TableSortCallback } from "../table"; import { apiManager } from "../../api/api-manager"; interface Props extends RouteComponentProps { @@ -50,7 +50,7 @@ export class CrdResources extends React.Component { if (!crd) return null; const isNamespaced = crd.isNamespaced(); const extraColumns = crd.getPrinterColumns(false); // Cols with priority bigger than 0 are shown in details - const sortingCallbacks: { [sortBy: string]: SortingCallback } = { + const sortingCallbacks: { [sortBy: string]: TableSortCallback } = { [sortBy.name]: (item: KubeObject) => item.getName(), [sortBy.namespace]: (item: KubeObject) => item.getNs(), [sortBy.age]: (item: KubeObject) => item.metadata.creationTimestamp, diff --git a/src/renderer/components/+custom-resources/crd.store.ts b/src/renderer/components/+custom-resources/crd.store.ts index fadb1222e2..e73bbd1fb7 100644 --- a/src/renderer/components/+custom-resources/crd.store.ts +++ b/src/renderer/components/+custom-resources/crd.store.ts @@ -14,7 +14,7 @@ function initStore(crd: CustomResourceDefinition) { const api = apiManager.getApi(apiBase) || new KubeApi({ apiBase, kind, isNamespaced }); if (!apiManager.getStore(api)) { - apiManager.registerStore(api, new CRDResourceStore(api)); + apiManager.registerStore(new CRDResourceStore(api)); } } @@ -64,4 +64,4 @@ export class CRDStore extends KubeObjectStore { export const crdStore = new CRDStore(); -apiManager.registerStore(crdApi, crdStore); +apiManager.registerStore(crdStore); diff --git a/src/renderer/components/+events/event.store.ts b/src/renderer/components/+events/event.store.ts index 23ebc7ccc9..3d8142a55f 100644 --- a/src/renderer/components/+events/event.store.ts +++ b/src/renderer/components/+events/event.store.ts @@ -49,4 +49,4 @@ export class EventStore extends KubeObjectStore { } export const eventStore = new EventStore(); -apiManager.registerStore(eventApi, eventStore); +apiManager.registerStore(eventStore); diff --git a/src/renderer/components/+events/kube-event-details.tsx b/src/renderer/components/+events/kube-event-details.tsx index 16113cd305..9716586869 100644 --- a/src/renderer/components/+events/kube-event-details.tsx +++ b/src/renderer/components/+events/kube-event-details.tsx @@ -6,15 +6,14 @@ import { Trans } from "@lingui/macro"; import { KubeObject } from "../../api/kube-object"; import { DrawerItem, DrawerTitle } from "../drawer"; import { cssNames } from "../../utils"; -import { Icon } from "../icon"; import { eventStore } from "./event.store"; -interface Props { +export interface KubeEventDetailsProps { object: KubeObject; } @observer -export class KubeEventDetails extends React.Component { +export class KubeEventDetails extends React.Component { async componentDidMount() { eventStore.loadAll(); } diff --git a/src/renderer/components/+namespaces/namespace.store.ts b/src/renderer/components/+namespaces/namespace.store.ts index c9f190be97..8874aa9233 100644 --- a/src/renderer/components/+namespaces/namespace.store.ts +++ b/src/renderer/components/+namespaces/namespace.store.ts @@ -95,4 +95,4 @@ export class NamespaceStore extends KubeObjectStore { } export const namespaceStore = new NamespaceStore(); -apiManager.registerStore(namespacesApi, namespaceStore); +apiManager.registerStore(namespaceStore); diff --git a/src/renderer/components/+network-endpoints/endpoints.store.ts b/src/renderer/components/+network-endpoints/endpoints.store.ts index 17485ec712..5d4a6b6ff7 100644 --- a/src/renderer/components/+network-endpoints/endpoints.store.ts +++ b/src/renderer/components/+network-endpoints/endpoints.store.ts @@ -9,4 +9,4 @@ export class EndpointStore extends KubeObjectStore { } export const endpointStore = new EndpointStore(); -apiManager.registerStore(endpointApi, endpointStore); +apiManager.registerStore(endpointStore); diff --git a/src/renderer/components/+network-ingresses/ingress.store.ts b/src/renderer/components/+network-ingresses/ingress.store.ts index 5f299c51e8..37156c2741 100644 --- a/src/renderer/components/+network-ingresses/ingress.store.ts +++ b/src/renderer/components/+network-ingresses/ingress.store.ts @@ -19,4 +19,4 @@ export class IngressStore extends KubeObjectStore { } export const ingressStore = new IngressStore(); -apiManager.registerStore(ingressApi, ingressStore); +apiManager.registerStore(ingressStore); diff --git a/src/renderer/components/+network-policies/network-policy.store.ts b/src/renderer/components/+network-policies/network-policy.store.ts index 74faa8db26..0f37de3ac0 100644 --- a/src/renderer/components/+network-policies/network-policy.store.ts +++ b/src/renderer/components/+network-policies/network-policy.store.ts @@ -9,4 +9,4 @@ export class NetworkPolicyStore extends KubeObjectStore { } export const networkPolicyStore = new NetworkPolicyStore(); -apiManager.registerStore(networkPolicyApi, networkPolicyStore); +apiManager.registerStore(networkPolicyStore); diff --git a/src/renderer/components/+network-services/services.store.ts b/src/renderer/components/+network-services/services.store.ts index b080297dfa..d3e3c7b983 100644 --- a/src/renderer/components/+network-services/services.store.ts +++ b/src/renderer/components/+network-services/services.store.ts @@ -9,4 +9,4 @@ export class ServiceStore extends KubeObjectStore { } export const serviceStore = new ServiceStore(); -apiManager.registerStore(serviceApi, serviceStore); +apiManager.registerStore(serviceStore); diff --git a/src/renderer/components/+nodes/nodes.store.ts b/src/renderer/components/+nodes/nodes.store.ts index 7892b005a8..8c04f55ad5 100644 --- a/src/renderer/components/+nodes/nodes.store.ts +++ b/src/renderer/components/+nodes/nodes.store.ts @@ -69,4 +69,4 @@ export class NodesStore extends KubeObjectStore { } export const nodesStore = new NodesStore() -apiManager.registerStore(nodesApi, nodesStore); +apiManager.registerStore(nodesStore); diff --git a/src/renderer/components/+pod-security-policies/pod-security-policies.store.ts b/src/renderer/components/+pod-security-policies/pod-security-policies.store.ts index d79b3d5d10..2517dcc59a 100644 --- a/src/renderer/components/+pod-security-policies/pod-security-policies.store.ts +++ b/src/renderer/components/+pod-security-policies/pod-security-policies.store.ts @@ -9,4 +9,4 @@ export class PodSecurityPoliciesStore extends KubeObjectStore } export const podSecurityPoliciesStore = new PodSecurityPoliciesStore() -apiManager.registerStore(pspApi, podSecurityPoliciesStore); +apiManager.registerStore(podSecurityPoliciesStore); diff --git a/src/renderer/components/+storage-classes/storage-class.store.ts b/src/renderer/components/+storage-classes/storage-class.store.ts index 09f658d01b..9ff90bc921 100644 --- a/src/renderer/components/+storage-classes/storage-class.store.ts +++ b/src/renderer/components/+storage-classes/storage-class.store.ts @@ -9,4 +9,4 @@ export class StorageClassStore extends KubeObjectStore { } export const storageClassStore = new StorageClassStore(); -apiManager.registerStore(storageClassApi, storageClassStore); +apiManager.registerStore(storageClassStore); diff --git a/src/renderer/components/+storage-volume-claims/volume-claim.store.ts b/src/renderer/components/+storage-volume-claims/volume-claim.store.ts index 640acf4832..ea07c4c6c1 100644 --- a/src/renderer/components/+storage-volume-claims/volume-claim.store.ts +++ b/src/renderer/components/+storage-volume-claims/volume-claim.store.ts @@ -20,4 +20,4 @@ export class VolumeClaimStore extends KubeObjectStore { } export const volumeClaimStore = new VolumeClaimStore(); -apiManager.registerStore(pvcApi, volumeClaimStore); +apiManager.registerStore(volumeClaimStore); diff --git a/src/renderer/components/+storage-volumes/volumes.store.ts b/src/renderer/components/+storage-volumes/volumes.store.ts index 1ad2ad7b91..f065c562c9 100644 --- a/src/renderer/components/+storage-volumes/volumes.store.ts +++ b/src/renderer/components/+storage-volumes/volumes.store.ts @@ -9,4 +9,4 @@ export class PersistentVolumesStore extends KubeObjectStore { } export const volumesStore = new PersistentVolumesStore(); -apiManager.registerStore(persistentVolumeApi, volumesStore); +apiManager.registerStore(volumesStore); diff --git a/src/renderer/components/+user-management-roles-bindings/role-bindings.store.ts b/src/renderer/components/+user-management-roles-bindings/role-bindings.store.ts index 9678657f19..bbef0ebd31 100644 --- a/src/renderer/components/+user-management-roles-bindings/role-bindings.store.ts +++ b/src/renderer/components/+user-management-roles-bindings/role-bindings.store.ts @@ -30,8 +30,7 @@ export class RoleBindingsStore extends KubeObjectStore { return Promise.all( namespaces.map(namespace => roleBindingApi.list({ namespace })) ).then(items => items.flat()) - } - else { + } else { return Promise.all([clusterRoleBindingApi.list(), roleBindingApi.list()]) .then(items => items.flat()) } @@ -40,8 +39,7 @@ export class RoleBindingsStore extends KubeObjectStore { protected async createItem(params: { name: string; namespace?: string }, data?: Partial) { if (params.namespace) { return roleBindingApi.create(params, data) - } - else { + } else { return clusterRoleBindingApi.create(params, data) } } @@ -58,8 +56,7 @@ export class RoleBindingsStore extends KubeObjectStore { newSubjects = uniqBy(currentSubjects.concat(addSubjects), ({ kind, name, namespace }) => { return [kind, name, namespace].join("-"); }) - } - else if (removeSubjects) { + } else if (removeSubjects) { newSubjects = difference(currentSubjects, removeSubjects); } return this.update(roleBinding, { @@ -71,5 +68,7 @@ export class RoleBindingsStore extends KubeObjectStore { export const roleBindingsStore = new RoleBindingsStore(); -apiManager.registerStore(roleBindingApi, roleBindingsStore); -apiManager.registerStore(clusterRoleBindingApi, roleBindingsStore); +apiManager.registerStore(roleBindingsStore, [ + roleBindingApi, + clusterRoleBindingApi, +]); diff --git a/src/renderer/components/+user-management-roles/roles.store.ts b/src/renderer/components/+user-management-roles/roles.store.ts index 90658b8339..e41171ee0c 100644 --- a/src/renderer/components/+user-management-roles/roles.store.ts +++ b/src/renderer/components/+user-management-roles/roles.store.ts @@ -28,8 +28,7 @@ export class RolesStore extends KubeObjectStore { return Promise.all( namespaces.map(namespace => roleApi.list({ namespace })) ).then(items => items.flat()) - } - else { + } else { return Promise.all([clusterRoleApi.list(), roleApi.list()]) .then(items => items.flat()) } @@ -38,8 +37,7 @@ export class RolesStore extends KubeObjectStore { protected async createItem(params: { name: string; namespace?: string }, data?: Partial) { if (params.namespace) { return roleApi.create(params, data) - } - else { + } else { return clusterRoleApi.create(params, data) } } @@ -47,5 +45,7 @@ export class RolesStore extends KubeObjectStore { export const rolesStore = new RolesStore(); -apiManager.registerStore(roleApi, rolesStore); -apiManager.registerStore(clusterRoleApi, rolesStore); +apiManager.registerStore(rolesStore, [ + roleApi, + clusterRoleApi, +]); \ No newline at end of file diff --git a/src/renderer/components/+user-management-service-accounts/service-accounts.store.ts b/src/renderer/components/+user-management-service-accounts/service-accounts.store.ts index a0b387508f..ff958567ae 100644 --- a/src/renderer/components/+user-management-service-accounts/service-accounts.store.ts +++ b/src/renderer/components/+user-management-service-accounts/service-accounts.store.ts @@ -14,4 +14,4 @@ export class ServiceAccountsStore extends KubeObjectStore { } export const serviceAccountsStore = new ServiceAccountsStore(); -apiManager.registerStore(serviceAccountsApi, serviceAccountsStore); +apiManager.registerStore(serviceAccountsStore); diff --git a/src/renderer/components/+workloads-cronjobs/cronjob.store.ts b/src/renderer/components/+workloads-cronjobs/cronjob.store.ts index e8fa3719ae..b1370d2104 100644 --- a/src/renderer/components/+workloads-cronjobs/cronjob.store.ts +++ b/src/renderer/components/+workloads-cronjobs/cronjob.store.ts @@ -30,4 +30,4 @@ export class CronJobStore extends KubeObjectStore { } export const cronJobStore = new CronJobStore(); -apiManager.registerStore(cronJobApi, cronJobStore); +apiManager.registerStore(cronJobStore); diff --git a/src/renderer/components/+workloads-daemonsets/daemonsets.store.ts b/src/renderer/components/+workloads-daemonsets/daemonsets.store.ts index dd59aad8ff..142079a365 100644 --- a/src/renderer/components/+workloads-daemonsets/daemonsets.store.ts +++ b/src/renderer/components/+workloads-daemonsets/daemonsets.store.ts @@ -43,4 +43,4 @@ export class DaemonSetStore extends KubeObjectStore { } export const daemonSetStore = new DaemonSetStore(); -apiManager.registerStore(daemonSetApi, daemonSetStore); +apiManager.registerStore(daemonSetStore); diff --git a/src/renderer/components/+workloads-deployments/deployments.store.ts b/src/renderer/components/+workloads-deployments/deployments.store.ts index 07fc095629..3069a84d3c 100644 --- a/src/renderer/components/+workloads-deployments/deployments.store.ts +++ b/src/renderer/components/+workloads-deployments/deployments.store.ts @@ -50,4 +50,4 @@ export class DeploymentStore extends KubeObjectStore { } export const deploymentStore = new DeploymentStore(); -apiManager.registerStore(deploymentApi, deploymentStore); +apiManager.registerStore(deploymentStore); diff --git a/src/renderer/components/+workloads-jobs/job.store.ts b/src/renderer/components/+workloads-jobs/job.store.ts index 592347062c..c387e7793d 100644 --- a/src/renderer/components/+workloads-jobs/job.store.ts +++ b/src/renderer/components/+workloads-jobs/job.store.ts @@ -42,4 +42,4 @@ export class JobStore extends KubeObjectStore { } export const jobStore = new JobStore(); -apiManager.registerStore(jobApi, jobStore); +apiManager.registerStore(jobStore); diff --git a/src/renderer/components/+workloads-pods/pods.store.ts b/src/renderer/components/+workloads-pods/pods.store.ts index fe95ba4e48..a42b5d515c 100644 --- a/src/renderer/components/+workloads-pods/pods.store.ts +++ b/src/renderer/components/+workloads-pods/pods.store.ts @@ -76,4 +76,4 @@ export class PodsStore extends KubeObjectStore { } export const podsStore = new PodsStore(); -apiManager.registerStore(podsApi, podsStore); +apiManager.registerStore(podsStore); diff --git a/src/renderer/components/+workloads-replicasets/replicasets.store.ts b/src/renderer/components/+workloads-replicasets/replicasets.store.ts index 3b91999699..765c58a4a8 100644 --- a/src/renderer/components/+workloads-replicasets/replicasets.store.ts +++ b/src/renderer/components/+workloads-replicasets/replicasets.store.ts @@ -31,4 +31,4 @@ export class ReplicaSetStore extends KubeObjectStore { } export const replicaSetStore = new ReplicaSetStore(); -apiManager.registerStore(replicaSetApi, replicaSetStore); +apiManager.registerStore(replicaSetStore); diff --git a/src/renderer/components/+workloads-statefulsets/statefulset.store.ts b/src/renderer/components/+workloads-statefulsets/statefulset.store.ts index 5bca0a19b6..a72a9447df 100644 --- a/src/renderer/components/+workloads-statefulsets/statefulset.store.ts +++ b/src/renderer/components/+workloads-statefulsets/statefulset.store.ts @@ -42,4 +42,4 @@ export class StatefulSetStore extends KubeObjectStore { } export const statefulSetStore = new StatefulSetStore(); -apiManager.registerStore(statefulSetApi, statefulSetStore); +apiManager.registerStore(statefulSetStore); diff --git a/src/renderer/components/+workspaces/workspaces.tsx b/src/renderer/components/+workspaces/workspaces.tsx index 4e25b90269..5375b4ed80 100644 --- a/src/renderer/components/+workspaces/workspaces.tsx +++ b/src/renderer/components/+workspaces/workspaces.tsx @@ -12,7 +12,7 @@ import { Icon } from "../icon"; import { Input } from "../input"; import { cssNames, prevDefault } from "../../utils"; import { Button } from "../button"; -import { isRequired, Validator } from "../input/input_validators"; +import { isRequired, InputValidator } from "../input/input_validators"; @observer export class Workspaces extends React.Component { @@ -122,7 +122,7 @@ export class Workspaces extends React.Component { editing: isEditing, default: isDefault, }); - const existenceValidator: Validator = { + const existenceValidator: InputValidator = { message: () => `Workspace '${name}' already exists`, validate: value => !workspaceStore.getByName(value.trim()) } diff --git a/src/renderer/components/badge/badge.tsx b/src/renderer/components/badge/badge.tsx index 3a70c98286..5fd80afe2a 100644 --- a/src/renderer/components/badge/badge.tsx +++ b/src/renderer/components/badge/badge.tsx @@ -4,13 +4,13 @@ import React from "react"; import { cssNames } from "../../utils/cssNames"; import { TooltipDecoratorProps, withTooltip } from "../tooltip"; -interface Props extends React.HTMLAttributes, TooltipDecoratorProps { +export interface BadgeProps extends React.HTMLAttributes, TooltipDecoratorProps { small?: boolean; label?: React.ReactNode; } @withTooltip -export class Badge extends React.Component { +export class Badge extends React.Component { render() { const { className, label, small, children, ...elemProps } = this.props; return <> diff --git a/src/renderer/components/checkbox/checkbox.tsx b/src/renderer/components/checkbox/checkbox.tsx index 505f71b70b..64a356ff3a 100644 --- a/src/renderer/components/checkbox/checkbox.tsx +++ b/src/renderer/components/checkbox/checkbox.tsx @@ -2,7 +2,7 @@ import './checkbox.scss' import React from 'react' import { autobind, cssNames } from "../../utils"; -interface Props { +export interface CheckboxProps { theme?: "dark" | "light"; className?: string; label?: React.ReactNode; @@ -12,7 +12,7 @@ interface Props { onChange?(value: T, evt: React.ChangeEvent): void; } -export class Checkbox extends React.PureComponent { +export class Checkbox extends React.PureComponent { private input: HTMLInputElement; @autobind() diff --git a/src/renderer/components/confirm-dialog/confirm-dialog.tsx b/src/renderer/components/confirm-dialog/confirm-dialog.tsx index d86d80af10..bb8be378e7 100644 --- a/src/renderer/components/confirm-dialog/confirm-dialog.tsx +++ b/src/renderer/components/confirm-dialog/confirm-dialog.tsx @@ -9,7 +9,10 @@ import { Button, ButtonProps } from "../button"; import { Dialog, DialogProps } from "../dialog"; import { Icon } from "../icon"; -export interface IConfirmDialogParams { +export interface ConfirmDialogProps extends Partial { +} + +export interface ConfirmDialogParams { ok?: () => void; labelOk?: ReactNode; labelCancel?: ReactNode; @@ -19,17 +22,14 @@ export interface IConfirmDialogParams { cancelButtonProps?: Partial } -interface Props extends Partial { -} - @observer -export class ConfirmDialog extends React.Component { +export class ConfirmDialog extends React.Component { @observable static isOpen = false; - @observable.ref static params: IConfirmDialogParams; + @observable.ref static params: ConfirmDialogParams; @observable isSaving = false; - static open(params: IConfirmDialogParams) { + static open(params: ConfirmDialogParams) { ConfirmDialog.isOpen = true; ConfirmDialog.params = params; } @@ -38,14 +38,14 @@ export class ConfirmDialog extends React.Component { ConfirmDialog.isOpen = false; } - public defaultParams: IConfirmDialogParams = { + public defaultParams: ConfirmDialogParams = { ok: noop, labelOk: Ok, labelCancel: Cancel, icon: , }; - get params(): IConfirmDialogParams { + get params(): ConfirmDialogParams { return Object.assign({}, this.defaultParams, ConfirmDialog.params); } diff --git a/src/renderer/components/drawer/drawer-item-labels.tsx b/src/renderer/components/drawer/drawer-item-labels.tsx index 30475d07fb..a3f33a27f3 100644 --- a/src/renderer/components/drawer/drawer-item-labels.tsx +++ b/src/renderer/components/drawer/drawer-item-labels.tsx @@ -2,11 +2,11 @@ import React from "react"; import { DrawerItem, DrawerItemProps } from "./drawer-item"; import { Badge } from "../badge"; -interface Props extends DrawerItemProps { +export interface DrawerItemLabelsProps extends DrawerItemProps { labels: string[]; } -export function DrawerItemLabels(props: Props) { +export function DrawerItemLabels(props: DrawerItemLabelsProps) { const { labels, ...itemProps } = props; if (!labels || !labels.length) { return null; diff --git a/src/renderer/components/drawer/drawer-param-toggler.tsx b/src/renderer/components/drawer/drawer-param-toggler.tsx index 6414c02199..c7935fc414 100644 --- a/src/renderer/components/drawer/drawer-param-toggler.tsx +++ b/src/renderer/components/drawer/drawer-param-toggler.tsx @@ -5,14 +5,14 @@ import { Icon } from "../icon"; import { cssNames } from "../../utils"; import { _i18n } from "../../i18n"; -interface Props { +export interface DrawerParamTogglerProps { label: string | number; } interface State { open?: boolean; } -export class DrawerParamToggler extends React.Component { +export class DrawerParamToggler extends React.Component { public state: State = {} toggle = () => { diff --git a/src/renderer/components/drawer/drawer-title.tsx b/src/renderer/components/drawer/drawer-title.tsx index 480a6f6bda..d368f1888d 100644 --- a/src/renderer/components/drawer/drawer-title.tsx +++ b/src/renderer/components/drawer/drawer-title.tsx @@ -2,12 +2,12 @@ import "./drawer-title.scss"; import React from "react"; import { cssNames } from "../../utils"; -interface Props { +export interface DrawerTitleProps { className?: string; title?: React.ReactNode; } -export class DrawerTitle extends React.Component { +export class DrawerTitle extends React.Component { render() { const { title, children, className } = this.props return ( diff --git a/src/renderer/components/input/input.tsx b/src/renderer/components/input/input.tsx index cd3e998a55..f0938255a6 100644 --- a/src/renderer/components/input/input.tsx +++ b/src/renderer/components/input/input.tsx @@ -3,13 +3,16 @@ import "./input.scss"; import React, { DOMAttributes, InputHTMLAttributes, TextareaHTMLAttributes } from "react"; import { autobind, cssNames, debouncePromise } from "../../utils"; import { Icon } from "../icon"; -import { conditionalValidators, Validator } from "./input_validators"; +import * as Validators from "./input_validators"; +import { InputValidator } from "./input_validators"; import isString from "lodash/isString" import isFunction from "lodash/isFunction" import isBoolean from "lodash/isBoolean" import uniqueId from "lodash/uniqueId" -type Omit = Pick> +const { conditionalValidators, ...InputValidators } = Validators; +export { InputValidators, InputValidator } + type InputElement = HTMLInputElement | HTMLTextAreaElement; type InputElementProps = InputHTMLAttributes & TextareaHTMLAttributes & DOMAttributes; @@ -25,7 +28,7 @@ export type InputProps = Omit): void; onSubmit?(value: T): void; } @@ -50,7 +53,7 @@ export class Input extends React.Component { static defaultProps = defaultProps as object; public input: InputElement; - public validators: Validator[] = []; + public validators: InputValidator[] = []; public state: State = { dirty: !!this.props.dirty, @@ -150,7 +153,7 @@ export class Input extends React.Component { }); } - private getValidatorError(value: string, { message }: Validator) { + private getValidatorError(value: string, { message }: InputValidator) { if (isFunction(message)) return message(value, this.props) return message || ""; } @@ -293,7 +296,7 @@ export class Input extends React.Component { return (