diff --git a/.eslintrc.js b/.eslintrc.js index 4854713f0e..33d28967ff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + const packageJson = require("./package.json"); module.exports = { @@ -27,9 +48,11 @@ module.exports = { sourceType: "module", }, plugins: [ - "unused-imports" + "header", + "unused-imports", ], rules: { + "header/header": [2, "./license-header"], "indent": ["error", 2, { "SwitchCase": 1, }], @@ -72,6 +95,7 @@ module.exports = { "plugin:@typescript-eslint/recommended", ], plugins: [ + "header", "unused-imports" ], parserOptions: { @@ -79,6 +103,7 @@ module.exports = { sourceType: "module", }, rules: { + "header/header": [2, "./license-header"], "no-invalid-this": "off", "@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/explicit-function-return-type": "off", @@ -127,6 +152,7 @@ module.exports = { ], parser: "@typescript-eslint/parser", plugins: [ + "header", "unused-imports" ], extends: [ @@ -139,6 +165,7 @@ module.exports = { jsx: true, }, rules: { + "header/header": [2, "./license-header"], "no-invalid-this": "off", "@typescript-eslint/no-invalid-this": ["error"], "@typescript-eslint/explicit-function-return-type": "off", diff --git a/.github/workflows/license-header.yml b/.github/workflows/license-header.yml index 92db815acd..daba6a9ca9 100644 --- a/.github/workflows/license-header.yml +++ b/.github/workflows/license-header.yml @@ -7,7 +7,7 @@ on: branches: - master jobs: - test: + css: runs-on: ubuntu-latest steps: @@ -23,16 +23,4 @@ jobs: set -e export PATH=${PATH}:`go env GOPATH`/bin - addlicense -check -l mit -c "OpenLens Authors" *.ts* - - addlicense -check -l mit -c "OpenLens Authors" src/common/**/*.ts* - addlicense -check -l mit -c "OpenLens Authors" src/common/**/*.?css - - addlicense -check -l mit -c "OpenLens Authors" src/main/**/*.ts* - - addlicense -check -l mit -c "OpenLens Authors" src/renderer/**/*.ts* - addlicense -check -l mit -c "OpenLens Authors" src/renderer/**/*.?css - - addlicense -check -l mit -c "OpenLens Authors" src/extensions/**/*.ts* - - addlicense -check -l mit -c "OpenLens Authors" extensions/**/*.ts* + addlicense -check -l mit -c "OpenLens Authors" src/**/*.?css diff --git a/__mocks__/@linguiMacro.ts b/__mocks__/@linguiMacro.ts index a1154b42dd..88be664f85 100644 --- a/__mocks__/@linguiMacro.ts +++ b/__mocks__/@linguiMacro.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ module.exports = { Trans: ({ children }: { children: React.ReactNode }) => children, t: (message: string) => message diff --git a/__mocks__/electron.ts b/__mocks__/electron.ts index 1b531fb8d7..8a8408db88 100644 --- a/__mocks__/electron.ts +++ b/__mocks__/electron.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ module.exports = { require: jest.fn(), match: jest.fn(), diff --git a/__mocks__/imageMock.ts b/__mocks__/imageMock.ts index f053ebf797..31effc071f 100644 --- a/__mocks__/imageMock.ts +++ b/__mocks__/imageMock.ts @@ -1 +1,21 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ module.exports = {}; diff --git a/__mocks__/styleMock.ts b/__mocks__/styleMock.ts index f053ebf797..31effc071f 100644 --- a/__mocks__/styleMock.ts +++ b/__mocks__/styleMock.ts @@ -1 +1,21 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ module.exports = {}; diff --git a/build/build_tray_icon.ts b/build/build_tray_icon.ts index 3aded6fdf5..9669783631 100644 --- a/build/build_tray_icon.ts +++ b/build/build_tray_icon.ts @@ -1,5 +1,23 @@ -// Generate tray icons from SVG to PNG + different sizes and colors (B&W) -// Command: `yarn build:tray-icons` +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import path from "path"; import sharp from "sharp"; import jsdom from "jsdom"; diff --git a/build/download_helm.ts b/build/download_helm.ts index 7a3dc62a72..703684066b 100644 --- a/build/download_helm.ts +++ b/build/download_helm.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import { helmCli } from "../src/main/helm/helm-cli"; helmCli.ensureBinary(); diff --git a/build/download_kubectl.ts b/build/download_kubectl.ts index f046b23e30..c4ae90a702 100644 --- a/build/download_kubectl.ts +++ b/build/download_kubectl.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import packageInfo from "../package.json"; import fs from "fs"; import request from "request"; diff --git a/build/notarize.js b/build/notarize.js index ef4144993c..959f526ddd 100644 --- a/build/notarize.js +++ b/build/notarize.js @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ const { notarize } = require("electron-notarize"); exports.default = async function notarizing(context) { diff --git a/build/set_build_version.ts b/build/set_build_version.ts index c18abbca9c..df48a1da13 100644 --- a/build/set_build_version.ts +++ b/build/set_build_version.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import * as fs from "fs"; import * as path from "path"; import appInfo from "../package.json"; diff --git a/build/set_npm_version.ts b/build/set_npm_version.ts index 9b433349fb..b7614103a2 100644 --- a/build/set_npm_version.ts +++ b/build/set_npm_version.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import * as fs from "fs"; import * as path from "path"; import packageInfo from "../src/extensions/npm/extensions/package.json"; diff --git a/docs/custom_theme/main.html b/docs/custom_theme/main.html index b6ad2467dd..94d9808cc7 100644 --- a/docs/custom_theme/main.html +++ b/docs/custom_theme/main.html @@ -1,12 +1 @@ {% extends "base.html" %} - -{% block analytics %} - - - -{% endblock %} \ No newline at end of file diff --git a/docs/extensions/guides/README.md b/docs/extensions/guides/README.md index 06bbbe9e3c..012794a39e 100644 --- a/docs/extensions/guides/README.md +++ b/docs/extensions/guides/README.md @@ -24,6 +24,7 @@ Each guide or code sample includes the following: | [KubeObjectListLayout](kube-object-list-layout.md) | | | [Working with mobx](working-with-mobx.md) | | | [Protocol Handlers](protocol-handlers.md) | | +| [Sending Data between main and renderer](ipc.md) | | ## Samples diff --git a/docs/extensions/guides/ipc.md b/docs/extensions/guides/ipc.md new file mode 100644 index 0000000000..91d811bdf0 --- /dev/null +++ b/docs/extensions/guides/ipc.md @@ -0,0 +1,131 @@ +# Inter Process Communication + +A Lens Extension can utilize IPC to send information between its `LensRendererExtension` and its `LensMainExtension`. +This is useful when wanting to communicate directly within your extension. +For example, if a user logs into a service that your extension is a facade for and `main` needs to know some information so that you can start syncing items to the `Catalog`, this would be a good way to send that information along. + +IPC channels are blocked off per extension. +Meaning that each extension can only communicate with itself. + +## Types of IPC + +There are two flavours of IPC that are provided: + +- Event based +- Request based + +### Event Based IPC + +This is the same as an [Event Emitter](https://nodejs.org/api/events.html#events_class_eventemitter) but is not limited to just one Javascript process. +This is a good option when you need to report that something has happened but you don't need a response. + +This is a fully two-way form of communication. +Both `LensMainExtension` and `LensRendererExtension` can do this sort of IPC. + +### Request Based IPC + +This is more like a Remote Procedure Call (RPC). +With this sort of IPC the caller waits for the result from the other side. +This is accomplished by returning a `Promise` which needs to be `await`-ed. + +This is a unidirectional form of communication. +Only `LensRendererExtension` can initiate this kind of request, and only `LensMainExtension` can and respond this this kind of request. + +## Registering IPC Handlers and Listeners + +The general terminology is as follows: + +- A "handler" is the function that responds to a "Request Based IPC" event. +- A "listener" is the function that is called when a "Event Based IPC" event is emitted. + +To register either a handler or a listener, you should do something like the following: + +`main.ts`: +```typescript +import { LensMainExtension, Interface, Types, Store } from "@k8slens/extensions"; +import { registerListeners, IpcMain } from "./helpers/main"; + +export class ExampleExtensionMain extends LensMainExtension { + onActivate() { + IpcMain.createInstance(this); + } +} +``` + +This file shows that you need to create an instance of the store to be able to use IPC. +Lens will automatically clean up that store and all the handlers on deactivation and uninstall. + +--- + +`helpers/main.ts`: +```typescript +import { Store } from "@k8slens/extensions"; + +export class IpcMain extends Store.MainIpcStore { + constructor(extension: LensMainExtension) { + super(extension); + + this.listenIpc("initialize", onInitialize); + } +} + +function onInitialize(event: Types.IpcMainEvent, id: string) { + console.log(`starting to initialize: ${id}`); +} +``` + +In other files, it is not necessary to pass around any instances. +It should be able to just call `getInstance()` everywhere in your extension as needed. + +--- + +`renderer.ts`: +```typescript +import { LensRendererExtension, Interface, Types } from "@k8slens/extensions"; +import { IpcRenderer } from "./helpers/renderer"; + +export class ExampleExtensionRenderer extends LensRendererExtension { + onActivate() { + const ipc = IpcRenderer.createInstance(this); + + setTimeout(() => ipc.broadcastIpc("initialize", "an-id"), 5000); + } +} +``` + +It is also needed to create an instance to broadcast messages too. + +--- + +`helpers/renderer.ts`: +```typescript +import { Store } from "@k8slens/extensions"; + +export class IpcMain extends Store.RendererIpcStore {} +``` + +It is necessary to create child classes of these `abstract class`'s in your extension before you can use them. + +--- + +As this example shows: the channel names *must* be the same. +It should also be noted that "listeners" and "handlers" are specific to either `LensRendererExtension` and `LensMainExtension`. +There is no behind the scenes transfer of these functions. + +If you want to register a "handler" you would call `Store.MainIpcStore.handleIpc(...)` instead. +The cleanup of these handlers is handled by Lens itself. + +`Store.RendererIpcStore.broadcastIpc(...)` and `Store.MainIpcStore.broadcastIpc(...)` sends an event to all renderer frames and to main. +Because of this, no matter where you broadcast from, all listeners in `main` and `renderer` will be notified. + +### Allowed Values + +This IPC mechanism utilizes the [Structured Clone Algorithm](developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) for serialization. +This means that more types than what are JSON serializable can be used, but not all the information will be passed through. + +## Using IPC + +Calling IPC is very simple. +If you are meaning to do an event based call, merely call `broadcastIpc(, ...)` from within your extension. + +If you are meaning to do a request based call from `renderer`, you should do `const res = await Store.RendererIpcStore.invokeIpc(, ...));` instead. diff --git a/extensions/kube-object-event-status/webpack.config.js b/extensions/kube-object-event-status/webpack.config.js index 6d5de7a2f8..33fd38ade7 100644 --- a/extensions/kube-object-event-status/webpack.config.js +++ b/extensions/kube-object-event-status/webpack.config.js @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ const path = require("path"); module.exports = [ diff --git a/extensions/metrics-cluster-feature/webpack.config.js b/extensions/metrics-cluster-feature/webpack.config.js index 2df74b3e35..0c42651e40 100644 --- a/extensions/metrics-cluster-feature/webpack.config.js +++ b/extensions/metrics-cluster-feature/webpack.config.js @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ const path = require("path"); module.exports = [ diff --git a/extensions/node-menu/webpack.config.js b/extensions/node-menu/webpack.config.js index 6d5de7a2f8..33fd38ade7 100644 --- a/extensions/node-menu/webpack.config.js +++ b/extensions/node-menu/webpack.config.js @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ const path = require("path"); module.exports = [ diff --git a/extensions/pod-menu/webpack.config.js b/extensions/pod-menu/webpack.config.js index 6d5de7a2f8..33fd38ade7 100644 --- a/extensions/pod-menu/webpack.config.js +++ b/extensions/pod-menu/webpack.config.js @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ const path = require("path"); module.exports = [ diff --git a/integration/__tests__/app.tests.ts b/integration/__tests__/app.tests.ts index 5f0fe9df04..c3a93200d2 100644 --- a/integration/__tests__/app.tests.ts +++ b/integration/__tests__/app.tests.ts @@ -1,5 +1,22 @@ /** - * @jest-environment node + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* diff --git a/integration/__tests__/cluster-pages.tests.ts b/integration/__tests__/cluster-pages.tests.ts index e2e9d14e2a..e0afc15c4c 100644 --- a/integration/__tests__/cluster-pages.tests.ts +++ b/integration/__tests__/cluster-pages.tests.ts @@ -1,9 +1,23 @@ -/* - Cluster tests are run if there is a pre-existing minikube cluster. Before running cluster tests the TEST_NAMESPACE - namespace is removed, if it exists, from the minikube cluster. Resources are created as part of the cluster tests in the - TEST_NAMESPACE namespace. This is done to minimize destructive impact of the cluster tests on an existing minikube - cluster and vice versa. -*/ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import { Application } from "spectron"; import * as utils from "../helpers/utils"; import { minikubeReady, waitForMinikubeDashboard } from "../helpers/minikube"; diff --git a/integration/__tests__/command-palette.tests.ts b/integration/__tests__/command-palette.tests.ts index 6f924f5524..118897b842 100644 --- a/integration/__tests__/command-palette.tests.ts +++ b/integration/__tests__/command-palette.tests.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import { Application } from "spectron"; import * as utils from "../helpers/utils"; diff --git a/integration/helpers/minikube.ts b/integration/helpers/minikube.ts index df2110ba92..50e325ccf0 100644 --- a/integration/helpers/minikube.ts +++ b/integration/helpers/minikube.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import { spawnSync } from "child_process"; import { Application } from "spectron"; diff --git a/integration/helpers/utils.ts b/integration/helpers/utils.ts index bb41e65bdd..9ce33b21c3 100644 --- a/integration/helpers/utils.ts +++ b/integration/helpers/utils.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import { Application } from "spectron"; import * as util from "util"; import { exec } from "child_process"; diff --git a/license-header b/license-header new file mode 100644 index 0000000000..1300dcadc0 --- /dev/null +++ b/license-header @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + diff --git a/mkdocs.yml b/mkdocs.yml index 0496f3001e..7001e41ce5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,6 +7,9 @@ repo_name: GitHub repo_url: https://github.com/lensapp/lens copyright: Copyright © 2021 Mirantis Inc. - All rights reserved. edit_uri: "" +google_analytics: + - UA-159377374-2 + - auto nav: - Overview: README.md - Getting Started: getting-started/README.md @@ -35,6 +38,7 @@ nav: - Stores: extensions/guides/stores.md - Working with MobX: extensions/guides/working-with-mobx.md - Protocol Handlers: extensions/guides/protocol-handlers.md + - IPC: extensions/guides/ipc.md - Testing and Publishing: - Testing Extensions: extensions/testing-and-publishing/testing.md - Publishing Extensions: extensions/testing-and-publishing/publishing.md diff --git a/package.json b/package.json index 9ec8d849fe..626966f5d2 100644 --- a/package.json +++ b/package.json @@ -292,7 +292,6 @@ "@types/tar": "^4.0.4", "@types/tcp-port-used": "^1.0.0", "@types/tempy": "^0.3.0", - "@types/universal-analytics": "^0.4.4", "@types/url-parse": "^1.4.3", "@types/uuid": "^8.3.0", "@types/webdriverio": "^4.13.0", @@ -316,6 +315,7 @@ "electron-builder": "^22.10.5", "electron-notarize": "^0.3.0", "eslint": "^7.7.0", + "eslint-plugin-header": "^3.1.1", "eslint-plugin-react": "^7.21.5", "eslint-plugin-unused-imports": "^1.0.1", "file-loader": "^6.0.0", diff --git a/src/common/__tests__/hotbar-store.test.ts b/src/common/__tests__/hotbar-store.test.ts index 92e5a3f35b..51002fee23 100644 --- a/src/common/__tests__/hotbar-store.test.ts +++ b/src/common/__tests__/hotbar-store.test.ts @@ -20,7 +20,6 @@ */ import mockFs from "mock-fs"; -import { CatalogEntityItem } from "../../renderer/components/+catalog/catalog-entity.store"; import { ClusterStore } from "../cluster-store"; import { HotbarStore } from "../hotbar-store"; @@ -159,10 +158,9 @@ describe("HotbarStore", () => { it("adds items", () => { const hotbarStore = HotbarStore.createInstance(); - const entity = new CatalogEntityItem(testCluster); hotbarStore.load(); - hotbarStore.addToHotbar(entity); + hotbarStore.addToHotbar(testCluster); const items = hotbarStore.getActive().items.filter(Boolean); expect(items.length).toEqual(1); @@ -170,10 +168,9 @@ describe("HotbarStore", () => { it("removes items", () => { const hotbarStore = HotbarStore.createInstance(); - const entity = new CatalogEntityItem(testCluster); hotbarStore.load(); - hotbarStore.addToHotbar(entity); + hotbarStore.addToHotbar(testCluster); hotbarStore.removeFromHotbar("test"); const items = hotbarStore.getActive().items.filter(Boolean); @@ -182,10 +179,9 @@ describe("HotbarStore", () => { it("does nothing if removing with invalid uid", () => { const hotbarStore = HotbarStore.createInstance(); - const entity = new CatalogEntityItem(testCluster); hotbarStore.load(); - hotbarStore.addToHotbar(entity); + hotbarStore.addToHotbar(testCluster); hotbarStore.removeFromHotbar("invalid uid"); const items = hotbarStore.getActive().items.filter(Boolean); @@ -194,14 +190,11 @@ describe("HotbarStore", () => { it("moves item to empty cell", () => { const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); - const minikube = new CatalogEntityItem(minikubeCluster); - const aws = new CatalogEntityItem(awsCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); - hotbarStore.addToHotbar(minikube); - hotbarStore.addToHotbar(aws); + hotbarStore.addToHotbar(testCluster); + hotbarStore.addToHotbar(minikubeCluster); + hotbarStore.addToHotbar(awsCluster); expect(hotbarStore.getActive().items[5]).toBeNull(); @@ -213,14 +206,11 @@ describe("HotbarStore", () => { it("moves items down", () => { const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); - const minikube = new CatalogEntityItem(minikubeCluster); - const aws = new CatalogEntityItem(awsCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); - hotbarStore.addToHotbar(minikube); - hotbarStore.addToHotbar(aws); + hotbarStore.addToHotbar(testCluster); + hotbarStore.addToHotbar(minikubeCluster); + hotbarStore.addToHotbar(awsCluster); // aws -> test hotbarStore.restackItems(2, 0); @@ -232,14 +222,11 @@ describe("HotbarStore", () => { it("moves items up", () => { const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); - const minikube = new CatalogEntityItem(minikubeCluster); - const aws = new CatalogEntityItem(awsCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); - hotbarStore.addToHotbar(minikube); - hotbarStore.addToHotbar(aws); + hotbarStore.addToHotbar(testCluster); + hotbarStore.addToHotbar(minikubeCluster); + hotbarStore.addToHotbar(awsCluster); // test -> aws hotbarStore.restackItems(0, 2); @@ -251,10 +238,9 @@ describe("HotbarStore", () => { it("does nothing when item moved to same cell", () => { const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); + hotbarStore.addToHotbar(testCluster); hotbarStore.restackItems(0, 0); expect(hotbarStore.getActive().items[0].entity.uid).toEqual("test"); @@ -262,15 +248,12 @@ describe("HotbarStore", () => { it("new items takes first empty cell", () => { const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); - const minikube = new CatalogEntityItem(minikubeCluster); - const aws = new CatalogEntityItem(awsCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); - hotbarStore.addToHotbar(aws); + hotbarStore.addToHotbar(testCluster); + hotbarStore.addToHotbar(awsCluster); hotbarStore.restackItems(0, 3); - hotbarStore.addToHotbar(minikube); + hotbarStore.addToHotbar(minikubeCluster); expect(hotbarStore.getActive().items[0].entity.uid).toEqual("minikube"); }); @@ -282,10 +265,9 @@ describe("HotbarStore", () => { console.error = jest.fn(); const hotbarStore = HotbarStore.createInstance(); - const test = new CatalogEntityItem(testCluster); hotbarStore.load(); - hotbarStore.addToHotbar(test); + hotbarStore.addToHotbar(testCluster); expect(() => hotbarStore.restackItems(-5, 0)).toThrow(); expect(() => hotbarStore.restackItems(2, -1)).toThrow(); diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index cd217d3a02..7c6727ada5 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -21,11 +21,12 @@ import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; import { CatalogEntity, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; -import { clusterDisconnectHandler } from "../cluster-ipc"; +import { clusterActivateHandler, clusterDisconnectHandler } from "../cluster-ipc"; import { ClusterStore } from "../cluster-store"; import { requestMain } from "../ipc"; import { productName } from "../vars"; import { CatalogCategory, CatalogCategorySpec } from "../catalog"; +import { app } from "electron"; export type KubernetesClusterSpec = { kubeconfigPath: string; @@ -40,6 +41,38 @@ export class KubernetesCluster extends CatalogEntity { + if (app) { + const cluster = ClusterStore.getInstance().getById(this.metadata.uid); + + if (!cluster) return; + + await cluster.activate(); + + return; + } + + await requestMain(clusterActivateHandler, this.metadata.uid, false); + + return; + } + + async disconnect(): Promise { + if (app) { + const cluster = ClusterStore.getInstance().getById(this.metadata.uid); + + if (!cluster) return; + + cluster.disconnect(); + + return; + } + + await requestMain(clusterDisconnectHandler, this.metadata.uid, false); + + return; + } + async onRun(context: CatalogEntityActionContext) { context.navigate(`/cluster/${this.metadata.uid}`); } diff --git a/src/common/hotbar-store.ts b/src/common/hotbar-store.ts index 2841c16046..53c1c5b3ef 100644 --- a/src/common/hotbar-store.ts +++ b/src/common/hotbar-store.ts @@ -23,8 +23,8 @@ import { action, comparer, observable, toJS } from "mobx"; import { BaseStore } from "./base-store"; import migrations from "../migrations/hotbar-store"; import * as uuid from "uuid"; -import { CatalogEntityItem } from "../renderer/components/+catalog/catalog-entity.store"; import isNull from "lodash/isNull"; +import { CatalogEntity } from "./catalog"; export interface HotbarItem { entity: { @@ -81,8 +81,12 @@ export class HotbarStore extends BaseStore { } } + hotbarIndex(id: string) { + return this.hotbars.findIndex((hotbar) => hotbar.id === id); + } + get activeHotbarIndex() { - return this.hotbars.findIndex((hotbar) => hotbar.id === this.activeHotbarId); + return this.hotbarIndex(this.activeHotbarId); } get initialItems() { @@ -147,15 +151,15 @@ export class HotbarStore extends BaseStore { } @action - addToHotbar(item: CatalogEntityItem, cellIndex = -1) { + addToHotbar(item: CatalogEntity, cellIndex = -1) { const hotbar = this.getActive(); const newItem = { entity: { - uid: item.id, - name: item.name, - source: item.source + uid: item.metadata.uid, + name: item.metadata.name, + source: item.metadata.source }}; - if (hotbar.items.find(i => i?.entity.uid === item.id)) { + if (hotbar.items.find(i => i?.entity.uid === item.metadata.uid)) { return; } diff --git a/src/common/ipc/ipc.ts b/src/common/ipc/ipc.ts index 74305e0484..66e591e765 100644 --- a/src/common/ipc/ipc.ts +++ b/src/common/ipc/ipc.ts @@ -42,35 +42,33 @@ function getSubFrames(): ClusterFrameInfo[] { return toJS(Array.from(clusterFrameMap.values()), { recurseEverything: true }); } -export async function broadcastMessage(channel: string, ...args: any[]) { +export function broadcastMessage(channel: string, ...args: any[]) { const views = (webContents || remote?.webContents)?.getAllWebContents(); if (!views) return; - if (ipcRenderer) { - ipcRenderer.send(channel, ...args); - } else if (ipcMain) { - ipcMain.emit(channel, ...args); - } + ipcRenderer?.send(channel, ...args); + ipcMain?.emit(channel, ...args); - for (const view of views) { - const type = view.getType(); + const subFramesP = ipcRenderer + ? requestMain(subFramesChannel) + : Promise.resolve(getSubFrames()); - logger.silly(`[IPC]: broadcasting "${channel}" to ${type}=${view.id}`, { args }); - view.send(channel, ...args); + subFramesP + .then(subFrames => { + for (const view of views) { + try { + logger.silly(`[IPC]: broadcasting "${channel}" to ${view.getType()}=${view.id}`, { args }); + view.send(channel, ...args); - try { - const subFrames: ClusterFrameInfo[] = ipcRenderer - ? await requestMain(subFramesChannel) - : getSubFrames(); - - for (const frameInfo of subFrames) { - view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); + for (const frameInfo of subFrames) { + view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args); + } + } catch (error) { + logger.error("[IPC]: failed to send IPC message", { error: String(error) }); + } } - } catch (error) { - logger.error("[IPC]: failed to send IPC message", { error: String(error) }); - } - } + }); } export function subscribeToBroadcast(channel: string, listener: (...args: any[]) => any) { diff --git a/src/common/ipc/type-enforced-ipc.ts b/src/common/ipc/type-enforced-ipc.ts index 1c4c7d301d..035ffcd77e 100644 --- a/src/common/ipc/type-enforced-ipc.ts +++ b/src/common/ipc/type-enforced-ipc.ts @@ -19,10 +19,12 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { ipcMain } from "electron"; import { EventEmitter } from "events"; import logger from "../../main/logger"; +import { Disposer } from "../utils"; -export type HandlerEvent = Parameters[1]>[0]; +export type ListenerEvent = Parameters[1]>[0]; export type ListVerifier = (args: unknown[]) => args is T; export type Rest = T extends [any, ...infer R] ? R : []; @@ -34,22 +36,22 @@ export type Rest = T extends [any, ...infer R] ? R : []; * @param verifier The function to be called to verify that the args are the correct type */ export function onceCorrect< - EM extends EventEmitter, - L extends (event: HandlerEvent, ...args: any[]) => any + IPC extends EventEmitter, + Listener extends (event: ListenerEvent, ...args: any[]) => any >({ source, channel, listener, verifier, }: { - source: EM, - channel: string | symbol, - listener: L, - verifier: ListVerifier>>, + source: IPC, + channel: string, + listener: Listener, + verifier: ListVerifier>>, }): void { - function handler(event: HandlerEvent, ...args: unknown[]): void { + function wrappedListener(event: ListenerEvent, ...args: unknown[]): void { if (verifier(args)) { - source.removeListener(channel, handler); // remove immediately + source.removeListener(channel, wrappedListener); // remove immediately (async () => (listener(event, ...args)))() // might return a promise, or throw, or reject .catch((error: any) => logger.error("[IPC]: channel once handler threw error", { channel, error })); @@ -58,7 +60,7 @@ export function onceCorrect< } } - source.on(channel, handler); + source.on(channel, wrappedListener); } /** @@ -68,25 +70,53 @@ export function onceCorrect< * @param verifier The function to be called to verify that the args are the correct type */ export function onCorrect< - EM extends EventEmitter, - L extends (event: HandlerEvent, ...args: any[]) => any + IPC extends EventEmitter, + Listener extends (event: ListenerEvent, ...args: any[]) => any >({ source, channel, listener, verifier, }: { - source: EM, - channel: string | symbol, - listener: L, - verifier: ListVerifier>>, -}): void { - source.on(channel, (event, ...args: unknown[]) => { + source: IPC, + channel: string, + listener: Listener, + verifier: ListVerifier>>, +}): Disposer { + function wrappedListener(event: ListenerEvent, ...args: unknown[]) { if (verifier(args)) { (async () => (listener(event, ...args)))() // might return a promise, or throw, or reject .catch(error => logger.error("[IPC]: channel on handler threw error", { channel, error })); } else { logger.error("[IPC]: channel was emitted with invalid data", { channel, args }); } - }); + } + + source.on(channel, wrappedListener); + + return () => source.off(channel, wrappedListener); +} + +export function handleCorrect< + Handler extends (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any, +>({ + channel, + handler, + verifier, +}: { + channel: string, + handler: Handler, + verifier: ListVerifier>>, +}): Disposer { + function wrappedHandler(event: Electron.IpcMainInvokeEvent, ...args: unknown[]): ReturnType { + if (verifier(args)) { + return handler(event, ...args); + } + + throw new TypeError(`Invalid args for invoke on channel: ${channel}`); + } + + ipcMain.handle(channel, wrappedHandler); + + return () => ipcMain.removeHandler(channel); } diff --git a/src/extensions/core-api/index.ts b/src/extensions/core-api/index.ts index 258fdbb6af..4fdca344d9 100644 --- a/src/extensions/core-api/index.ts +++ b/src/extensions/core-api/index.ts @@ -31,6 +31,7 @@ import * as Util from "./utils"; import * as ClusterFeature from "./cluster-feature"; import * as Interface from "../interfaces"; import * as Catalog from "./catalog"; +import * as Types from "./types"; export { App, @@ -39,5 +40,6 @@ export { ClusterFeature, Interface, Store, + Types, Util, }; diff --git a/src/extensions/core-api/stores.ts b/src/extensions/core-api/stores.ts index 17eac539d6..a9dfe9bf1e 100644 --- a/src/extensions/core-api/stores.ts +++ b/src/extensions/core-api/stores.ts @@ -20,3 +20,5 @@ */ export { ExtensionStore } from "../extension-store"; +export { MainIpcStore } from "../main-ipc-store"; +export { RendererIpcStore } from "../renderer-ipc-store"; diff --git a/src/extensions/core-api/types.ts b/src/extensions/core-api/types.ts new file mode 100644 index 0000000000..ed78b5c017 --- /dev/null +++ b/src/extensions/core-api/types.ts @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +export type IpcMainInvokeEvent = Electron.IpcMainInvokeEvent; +export type IpcRendererEvent = Electron.IpcRendererEvent; +export type IpcMainEvent = Electron.IpcMainEvent; diff --git a/src/extensions/ipc-store.ts b/src/extensions/ipc-store.ts new file mode 100644 index 0000000000..541f7b2914 --- /dev/null +++ b/src/extensions/ipc-store.ts @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +import { Singleton } from "../common/utils"; +import { LensExtension } from "./lens-extension"; +import { createHash } from "crypto"; +import { broadcastMessage } from "../common/ipc"; + +export const IpcPrefix = Symbol(); + +export abstract class IpcStore extends Singleton { + readonly [IpcPrefix]: string; + + constructor(protected extension: LensExtension) { + super(); + this[IpcPrefix] = createHash("sha256").update(extension.id).digest("hex"); + } + + broadcastIpc(channel: string, ...args: any[]): void { + broadcastMessage(`extensions@${this[IpcPrefix]}:${channel}`, ...args); + } +} diff --git a/src/extensions/lens-extension.ts b/src/extensions/lens-extension.ts index cf9077209c..d9df2c9993 100644 --- a/src/extensions/lens-extension.ts +++ b/src/extensions/lens-extension.ts @@ -23,7 +23,8 @@ import type { InstalledExtension } from "./extension-discovery"; import { action, observable, reaction } from "mobx"; import { FilesystemProvisionerStore } from "../main/extension-filesystem"; import logger from "../main/logger"; -import { ProtocolHandlerRegistration } from "./registries/protocol-handler-registry"; +import { ProtocolHandlerRegistration } from "./registries"; +import { disposer } from "../common/utils"; export type LensExtensionId = string; // path to manifest (package.json) export type LensExtensionConstructor = new (...args: ConstructorParameters) => LensExtension; @@ -37,6 +38,8 @@ export interface LensExtensionManifest { lens?: object; // fixme: add more required fields for validation } +export const Disposers = Symbol(); + export class LensExtension { readonly id: LensExtensionId; readonly manifest: LensExtensionManifest; @@ -46,6 +49,7 @@ export class LensExtension { protocolHandlers: ProtocolHandlerRegistration[] = []; @observable private isEnabled = false; + [Disposers] = disposer(); constructor({ id, manifest, manifestPath, isBundled }: InstalledExtension) { this.id = id; @@ -62,6 +66,10 @@ export class LensExtension { return this.manifest.version; } + get description() { + return this.manifest.description; + } + /** * getExtensionFileFolder returns the path to an already created folder. This * folder is for the sole use of this extension. @@ -73,15 +81,11 @@ export class LensExtension { return FilesystemProvisionerStore.getInstance().requestDirectory(this.id); } - get description() { - return this.manifest.description; - } - @action async enable() { if (this.isEnabled) return; this.isEnabled = true; - this.onActivate(); + this.onActivate?.(); logger.info(`[EXTENSION]: enabled ${this.name}@${this.version}`); } @@ -89,7 +93,8 @@ export class LensExtension { async disable() { if (!this.isEnabled) return; this.isEnabled = false; - this.onDeactivate(); + this.onDeactivate?.(); + this[Disposers](); logger.info(`[EXTENSION]: disabled ${this.name}@${this.version}`); } @@ -125,12 +130,12 @@ export class LensExtension { }; } - protected onActivate() { - // mock + protected onActivate(): void { + return; } - protected onDeactivate() { - // mock + protected onDeactivate(): void { + return; } } diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 7ae2f06693..b02456c6d4 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -19,12 +19,12 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import type { MenuRegistration } from "./registries/menu-registry"; import { LensExtension } from "./lens-extension"; import { WindowManager } from "../main/window-manager"; import { getExtensionPageUrl } from "./registries/page-registry"; import { CatalogEntity, catalogEntityRegistry } from "../common/catalog"; import { IObservableArray } from "mobx"; +import { MenuRegistration } from "./registries"; export class LensMainExtension extends LensExtension { appMenus: MenuRegistration[] = []; diff --git a/src/extensions/main-ipc-store.ts b/src/extensions/main-ipc-store.ts new file mode 100644 index 0000000000..1f9241a8b1 --- /dev/null +++ b/src/extensions/main-ipc-store.ts @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +import { ipcMain } from "electron"; +import { IpcPrefix, IpcStore } from "./ipc-store"; +import { Disposers } from "./lens-extension"; +import { LensMainExtension } from "./lens-main-extension"; + +export abstract class MainIpcStore extends IpcStore { + constructor(extension: LensMainExtension) { + super(extension); + extension[Disposers].push(() => MainIpcStore.resetInstance()); + } + + handleIpc(channel: string, handler: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any): void { + const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`; + + ipcMain.handle(prefixedChannel, handler); + this.extension[Disposers].push(() => ipcMain.removeHandler(prefixedChannel)); + } + + listenIpc(channel: string, listener: (event: Electron.IpcMainEvent, ...args: any[]) => any): void { + const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`; + + ipcMain.addListener(prefixedChannel, listener); + this.extension[Disposers].push(() => ipcMain.removeListener(prefixedChannel, listener)); + } +} diff --git a/src/extensions/registries/index.ts b/src/extensions/registries/index.ts index 13d07b2249..7056206daf 100644 --- a/src/extensions/registries/index.ts +++ b/src/extensions/registries/index.ts @@ -32,3 +32,4 @@ export * from "./kube-object-status-registry"; export * from "./command-registry"; export * from "./entity-setting-registry"; export * from "./welcome-menu-registry"; +export * from "./protocol-handler-registry"; diff --git a/src/extensions/renderer-ipc-store.ts b/src/extensions/renderer-ipc-store.ts new file mode 100644 index 0000000000..930027d0e2 --- /dev/null +++ b/src/extensions/renderer-ipc-store.ts @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +import { ipcRenderer } from "electron"; +import { IpcPrefix, IpcStore } from "./ipc-store"; +import { Disposers } from "./lens-extension"; +import { LensRendererExtension } from "./lens-renderer-extension"; + +export abstract class RendererIpcStore extends IpcStore { + constructor(extension: LensRendererExtension) { + super(extension); + extension[Disposers].push(() => RendererIpcStore.resetInstance()); + } + + listenIpc(channel: string, listener: (event: Electron.IpcRendererEvent, ...args: any[]) => any): void { + const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`; + + ipcRenderer.addListener(prefixedChannel, listener); + this.extension[Disposers].push(() => ipcRenderer.removeListener(prefixedChannel, listener)); + } + + invokeIpc(channel: string, ...args: any[]): Promise { + const prefixedChannel = `extensions@${this[IpcPrefix]}:${channel}`; + + return ipcRenderer.invoke(prefixedChannel, ...args); + } +} diff --git a/src/jest.setup.ts b/src/jest.setup.ts index d8c6ce9161..4feade0f1f 100644 --- a/src/jest.setup.ts +++ b/src/jest.setup.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + import fetchMock from "jest-fetch-mock"; // rewire global.fetch to call 'fetchMock' fetchMock.enableMocks(); diff --git a/src/main/shell-session/node-shell-session.ts b/src/main/shell-session/node-shell-session.ts index 1848716380..92831939ed 100644 --- a/src/main/shell-session/node-shell-session.ts +++ b/src/main/shell-session/node-shell-session.ts @@ -77,7 +77,7 @@ export class NodeShellSession extends ShellSession { }], containers: [{ name: "shell", - image: "docker.io/alpine:3.12", + image: "docker.io/alpine:3.13", securityContext: { privileged: true, }, @@ -120,6 +120,11 @@ export class NodeShellSession extends ShellSession { }); } + protected exit() { + super.exit(); + this.deleteNodeShellPod(); + } + protected deleteNodeShellPod() { this .kc diff --git a/src/migrations/cluster-store/2.0.0-beta.2.ts b/src/migrations/cluster-store/2.0.0-beta.2.ts index ccc8932e70..0d54588194 100644 --- a/src/migrations/cluster-store/2.0.0-beta.2.ts +++ b/src/migrations/cluster-store/2.0.0-beta.2.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + /* Early store format had the kubeconfig directly under context name, this moves it under the kubeConfig key */ diff --git a/src/migrations/cluster-store/2.4.1.ts b/src/migrations/cluster-store/2.4.1.ts index aa6936e432..59d4ef21dc 100644 --- a/src/migrations/cluster-store/2.4.1.ts +++ b/src/migrations/cluster-store/2.4.1.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Cleans up a store that had the state related data stored import { migration } from "../migration-wrapper"; diff --git a/src/migrations/cluster-store/2.6.0-beta.2.ts b/src/migrations/cluster-store/2.6.0-beta.2.ts index 596d16c31f..ffe303a28d 100644 --- a/src/migrations/cluster-store/2.6.0-beta.2.ts +++ b/src/migrations/cluster-store/2.6.0-beta.2.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Move cluster icon from root to preferences import { migration } from "../migration-wrapper"; diff --git a/src/migrations/cluster-store/2.6.0-beta.3.ts b/src/migrations/cluster-store/2.6.0-beta.3.ts index 779fff7e7d..9ec844fe65 100644 --- a/src/migrations/cluster-store/2.6.0-beta.3.ts +++ b/src/migrations/cluster-store/2.6.0-beta.3.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + import { migration } from "../migration-wrapper"; import yaml from "js-yaml"; @@ -42,4 +63,3 @@ export default migration({ } } }); - diff --git a/src/migrations/cluster-store/2.7.0-beta.0.ts b/src/migrations/cluster-store/2.7.0-beta.0.ts index 2f02a047f4..a23d3be991 100644 --- a/src/migrations/cluster-store/2.7.0-beta.0.ts +++ b/src/migrations/cluster-store/2.7.0-beta.0.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Add existing clusters to "default" workspace import { migration } from "../migration-wrapper"; diff --git a/src/migrations/cluster-store/2.7.0-beta.1.ts b/src/migrations/cluster-store/2.7.0-beta.1.ts index cb3934d422..06439063c6 100644 --- a/src/migrations/cluster-store/2.7.0-beta.1.ts +++ b/src/migrations/cluster-store/2.7.0-beta.1.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Add id for clusters and store them to array import { migration } from "../migration-wrapper"; import { v4 as uuid } from "uuid"; diff --git a/src/migrations/cluster-store/3.6.0-beta.1.ts b/src/migrations/cluster-store/3.6.0-beta.1.ts index ca2d0ccbed..df51510f23 100644 --- a/src/migrations/cluster-store/3.6.0-beta.1.ts +++ b/src/migrations/cluster-store/3.6.0-beta.1.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Move embedded kubeconfig into separate file and add reference to it to cluster settings // convert file path cluster icons to their base64 encoded versions diff --git a/src/migrations/cluster-store/index.ts b/src/migrations/cluster-store/index.ts index 4a71d4f7ad..b80911bbfe 100644 --- a/src/migrations/cluster-store/index.ts +++ b/src/migrations/cluster-store/index.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Cluster store migrations import version200Beta2 from "./2.0.0-beta.2"; diff --git a/src/migrations/cluster-store/snap.ts b/src/migrations/cluster-store/snap.ts index 74b89aad9c..c0a0430603 100644 --- a/src/migrations/cluster-store/snap.ts +++ b/src/migrations/cluster-store/snap.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Fix embedded kubeconfig paths under snap config import { migration } from "../migration-wrapper"; diff --git a/src/migrations/hotbar-store/5.0.0-alpha.0.ts b/src/migrations/hotbar-store/5.0.0-alpha.0.ts index 58d7073761..2e666fe54c 100644 --- a/src/migrations/hotbar-store/5.0.0-alpha.0.ts +++ b/src/migrations/hotbar-store/5.0.0-alpha.0.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Cleans up a store that had the state related data stored import { Hotbar } from "../../common/hotbar-store"; import { ClusterStore } from "../../common/cluster-store"; diff --git a/src/migrations/hotbar-store/5.0.0-alpha.2.ts b/src/migrations/hotbar-store/5.0.0-alpha.2.ts index 060fa9f542..57459de8c8 100644 --- a/src/migrations/hotbar-store/5.0.0-alpha.2.ts +++ b/src/migrations/hotbar-store/5.0.0-alpha.2.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Cleans up a store that had the state related data stored import { Hotbar } from "../../common/hotbar-store"; import { migration } from "../migration-wrapper"; diff --git a/src/migrations/hotbar-store/5.0.0-beta.5.ts b/src/migrations/hotbar-store/5.0.0-beta.5.ts index fe6ff8dd68..33e39f2a13 100644 --- a/src/migrations/hotbar-store/5.0.0-beta.5.ts +++ b/src/migrations/hotbar-store/5.0.0-beta.5.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + import type { Hotbar } from "../../common/hotbar-store"; import { migration } from "../migration-wrapper"; import { catalogEntityRegistry } from "../../renderer/api/catalog-entity-registry"; diff --git a/src/migrations/hotbar-store/index.ts b/src/migrations/hotbar-store/index.ts index d6824e8df0..fabedee4b7 100644 --- a/src/migrations/hotbar-store/index.ts +++ b/src/migrations/hotbar-store/index.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Hotbar store migrations import version500alpha0 from "./5.0.0-alpha.0"; diff --git a/src/migrations/migration-wrapper.ts b/src/migrations/migration-wrapper.ts index 39015b81fb..db363513de 100644 --- a/src/migrations/migration-wrapper.ts +++ b/src/migrations/migration-wrapper.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + import Config from "conf"; import { isTestEnv } from "../common/vars"; diff --git a/src/migrations/user-store/2.1.0-beta.4.ts b/src/migrations/user-store/2.1.0-beta.4.ts index e8f6500b05..eace0dd367 100644 --- a/src/migrations/user-store/2.1.0-beta.4.ts +++ b/src/migrations/user-store/2.1.0-beta.4.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Add / reset "lastSeenAppVersion" import { migration } from "../migration-wrapper"; diff --git a/src/migrations/user-store/5.0.0-alpha.3.ts b/src/migrations/user-store/5.0.0-alpha.3.ts index ae90b85525..57692c0bc0 100644 --- a/src/migrations/user-store/5.0.0-alpha.3.ts +++ b/src/migrations/user-store/5.0.0-alpha.3.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // Switch representation of hiddenTableColumns in store import { migration } from "../migration-wrapper"; diff --git a/src/migrations/user-store/file-name-migration.ts b/src/migrations/user-store/file-name-migration.ts index 0abe6b280b..e0c848d3a8 100644 --- a/src/migrations/user-store/file-name-migration.ts +++ b/src/migrations/user-store/file-name-migration.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + import fse from "fs-extra"; import { app, remote } from "electron"; import path from "path"; diff --git a/src/migrations/user-store/index.ts b/src/migrations/user-store/index.ts index c8733fdd8a..cf345b1bfb 100644 --- a/src/migrations/user-store/index.ts +++ b/src/migrations/user-store/index.ts @@ -1,3 +1,24 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + // User store migrations import version210Beta4 from "./2.1.0-beta.4"; diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx index 2fb6ce8f9f..3f0505d3c1 100644 --- a/src/renderer/components/+catalog/catalog.tsx +++ b/src/renderer/components/+catalog/catalog.tsx @@ -68,7 +68,7 @@ export class Catalog extends React.Component { } addToHotbar(item: CatalogEntityItem): void { - HotbarStore.getInstance().addToHotbar(item); + HotbarStore.getInstance().addToHotbar(item.entity); } onDetails(item: CatalogEntityItem) { @@ -137,7 +137,7 @@ export class Catalog extends React.Component { return ( item.onContextMenuOpen(this.contextMenu)}> this.addToHotbar(item) }> - Add to Hotbar + Pin to Hotbar { menuItems.map((menuItem, index) => ( diff --git a/src/renderer/components/+catalog/material-tooltip/material-tooltip.tsx b/src/renderer/components/+catalog/material-tooltip/material-tooltip.tsx index dbfd8b5323..0427f1ca78 100644 --- a/src/renderer/components/+catalog/material-tooltip/material-tooltip.tsx +++ b/src/renderer/components/+catalog/material-tooltip/material-tooltip.tsx @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import React from "react"; import { makeStyles, Tooltip, TooltipProps } from "@material-ui/core"; diff --git a/src/renderer/components/+workloads-deployments/deployment-details.tsx b/src/renderer/components/+workloads-deployments/deployment-details.tsx index 641eae79e7..112953e63a 100644 --- a/src/renderer/components/+workloads-deployments/deployment-details.tsx +++ b/src/renderer/components/+workloads-deployments/deployment-details.tsx @@ -42,6 +42,8 @@ import { KubeObjectMeta } from "../kube-object/kube-object-meta"; import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry"; import { ResourceType } from "../cluster-settings/components/cluster-metrics-setting"; import { ClusterStore } from "../../../common/cluster-store"; +import { replicaSetStore } from "../+workloads-replicasets/replicasets.store"; +import { DeploymentReplicaSets } from "./deployment-replicasets"; interface Props extends KubeObjectDetailsProps { } @@ -55,6 +57,7 @@ export class DeploymentDetails extends React.Component { componentDidMount() { podsStore.reloadAll(); + replicaSetStore.reloadAll(); } componentWillUnmount() { @@ -69,6 +72,7 @@ export class DeploymentDetails extends React.Component { const nodeSelector = deployment.getNodeSelectors(); const selectors = deployment.getSelectors(); const childPods = deploymentStore.getChildPods(deployment); + const replicaSets = replicaSetStore.getReplicaSetsByOwner(deployment); const metrics = deploymentStore.metrics; const isMetricHidden = ClusterStore.getInstance().isMetricHidden(ResourceType.Deployment); @@ -131,6 +135,7 @@ export class DeploymentDetails extends React.Component { + ); diff --git a/src/renderer/components/+workloads-deployments/deployment-replicasets.scss b/src/renderer/components/+workloads-deployments/deployment-replicasets.scss new file mode 100644 index 0000000000..0c04f54709 --- /dev/null +++ b/src/renderer/components/+workloads-deployments/deployment-replicasets.scss @@ -0,0 +1,36 @@ +.DeploymentDetails { + .ReplicaSets { + position: relative; + min-height: 80px; + + .Table { + margin: 0 (-$margin * 3); + } + + .TableCell { + &:first-child { + margin-left: $margin; + } + + &:last-child { + margin-right: $margin; + } + + &.name { + flex-grow: 2; + } + + &.warning { + @include table-cell-warning; + } + + &.namespace { + flex-grow: 1.2; + } + + &.actions { + @include table-cell-action; + } + } + } +} diff --git a/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx b/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx new file mode 100644 index 0000000000..8fbce9564d --- /dev/null +++ b/src/renderer/components/+workloads-deployments/deployment-replicasets.tsx @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import "./deployment-replicasets.scss"; + +import React from "react"; +import { observer } from "mobx-react"; +import { ReplicaSet } from "../../api/endpoints"; +import { KubeObjectMenu, KubeObjectMenuProps } from "../kube-object/kube-object-menu"; +import { Spinner } from "../spinner"; +import { prevDefault, stopPropagation } from "../../utils"; +import { DrawerTitle } from "../drawer"; +import { Table, TableCell, TableHead, TableRow } from "../table"; +import { KubeObjectStatusIcon } from "../kube-object-status-icon"; +import { replicaSetStore } from "../+workloads-replicasets/replicasets.store"; +import { showDetails } from "../kube-object"; + + +enum sortBy { + name = "name", + namespace = "namespace", + pods = "pods", + age = "age", +} + +interface Props { + replicaSets: ReplicaSet[]; +} + +@observer +export class DeploymentReplicaSets extends React.Component { + private sortingCallbacks = { + [sortBy.name]: (replicaSet: ReplicaSet) => replicaSet.getName(), + [sortBy.namespace]: (replicaSet: ReplicaSet) => replicaSet.getNs(), + [sortBy.age]: (replicaSet: ReplicaSet) => replicaSet.metadata.creationTimestamp, + [sortBy.pods]: (replicaSet: ReplicaSet) => this.getPodsLength(replicaSet), + }; + + getPodsLength(replicaSet: ReplicaSet) { + return replicaSetStore.getChildPods(replicaSet).length; + } + + render() { + const { replicaSets } = this.props; + + if (!replicaSets.length && !replicaSetStore.isLoaded) return ( +
+ ); + if (!replicaSets.length) return null; + + return ( +
+ + + + Name + + Namespace + Pods + Age + + + { + replicaSets.map(replica => { + return ( + showDetails(replica.selfLink, false))} + > + {replica.getName()} + + {replica.getNs()} + {this.getPodsLength(replica)} + {replica.getAge()} + + + + + ); + }) + } +
+
+ ); + } +} + +export function ReplicaSetMenu(props: KubeObjectMenuProps) { + return ( + + ); +} diff --git a/src/renderer/components/hotbar/hotbar-cell.tsx b/src/renderer/components/hotbar/hotbar-cell.tsx index c9e75e08fd..e22eed14f0 100644 --- a/src/renderer/components/hotbar/hotbar-cell.tsx +++ b/src/renderer/components/hotbar/hotbar-cell.tsx @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import "./hotbar-menu.scss"; import "./hotbar.commands"; diff --git a/src/renderer/components/hotbar/hotbar-display-label.ts b/src/renderer/components/hotbar/hotbar-display-label.ts new file mode 100644 index 0000000000..0489e2600f --- /dev/null +++ b/src/renderer/components/hotbar/hotbar-display-label.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +import { HotbarStore } from "../../../common/hotbar-store"; + +function hotbarIndex(id: string) { + return HotbarStore.getInstance().hotbarIndex(id) + 1; +} + +export function hotbarDisplayLabel(id: string) : string { + const hotbar = HotbarStore.getInstance().getById(id); + + return `${hotbarIndex(id)}: ${hotbar.name}`; +} + +export function hotbarDisplayIndex(id: string) : string { + return hotbarIndex(id).toString(); +} diff --git a/src/renderer/components/hotbar/hotbar-entity-icon.tsx b/src/renderer/components/hotbar/hotbar-entity-icon.tsx index 52a93990ee..e71ab2fdb2 100644 --- a/src/renderer/components/hotbar/hotbar-entity-icon.tsx +++ b/src/renderer/components/hotbar/hotbar-entity-icon.tsx @@ -1,23 +1,43 @@ -import "./hotbar-icon.scss"; +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ import React, { DOMAttributes } from "react"; import { observable } from "mobx"; import { observer } from "mobx-react"; -import randomColor from "randomcolor"; -import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog"; +import { CatalogEntity, CatalogEntityContextMenuContext } from "../../../common/catalog"; import { catalogCategoryRegistry } from "../../api/catalog-category-registry"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; import { navigate } from "../../navigation"; import { cssNames, IClassName } from "../../utils"; -import { ConfirmDialog } from "../confirm-dialog"; import { Icon } from "../icon"; import { HotbarIcon } from "./hotbar-icon"; +import { HotbarStore } from "../../../common/hotbar-store"; interface Props extends DOMAttributes { entity: CatalogEntity; + index: number; className?: IClassName; errorClass?: IClassName; + add: (item: CatalogEntity, index: number) => void; remove: (uid: string) => void; } @@ -57,33 +77,18 @@ export class HotbarEntityIcon extends React.Component { return catalogEntityRegistry.activeEntity?.metadata?.uid == item.getId(); } - onMenuItemClick(menuItem: CatalogEntityContextMenu) { - if (menuItem.confirm) { - ConfirmDialog.open({ - okButtonProps: { - primary: false, - accent: true, - }, - ok: () => { - menuItem.onClick(); - }, - message: menuItem.confirm.message - }); - } else { - menuItem.onClick(); - } - } - - generateAvatarStyle(entity: CatalogEntity): React.CSSProperties { - return { - "backgroundColor": randomColor({ seed: `${entity.metadata.name}-${entity.metadata.source}`, luminosity: "dark" }) - }; + isPersisted(entity: CatalogEntity) { + return HotbarStore.getInstance().getActive().items.find((item) => item?.entity?.uid === entity.metadata.uid) !== undefined; } render() { + if (!this.contextMenu) { + return null; + } + const { - entity, errorClass, remove, - children, ...elemProps + entity, errorClass, add, remove, + index, children, ...elemProps } = this.props; const className = cssNames("HotbarEntityIcon", this.props.className, { interactive: true, @@ -93,16 +98,31 @@ export class HotbarEntityIcon extends React.Component { const onOpen = async () => { await entity.onContextMenuOpen(this.contextMenu); }; + const isActive = this.isActive(entity); + const isPersisted = this.isPersisted(entity); const menuItems = this.contextMenu?.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === entity.metadata.source); + if (!isPersisted) { + menuItems.unshift({ + title: "Pin to Hotbar", + icon: "push_pin", + onClick: () => add(entity, index) + }); + } else { + menuItems.unshift({ + title: "Unpin from Hotbar", + icon: "push_pin", + onClick: () => remove(entity.metadata.uid) + }); + } + return ( .led { + div.MuiAvatar-root { + &.active { + box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent); + transition: all 0s 0.8s; + } + + &:hover { + &:not(.active) { + box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff30; + } + } + } + + .led { position: absolute; left: 3px; top: 3px; diff --git a/src/renderer/components/hotbar/hotbar-icon.tsx b/src/renderer/components/hotbar/hotbar-icon.tsx index 74971ccaea..2f681a05c1 100644 --- a/src/renderer/components/hotbar/hotbar-icon.tsx +++ b/src/renderer/components/hotbar/hotbar-icon.tsx @@ -38,7 +38,6 @@ interface Props extends DOMAttributes { uid: string; title: string; source: string; - remove: (uid: string) => void; onMenuOpen?: () => void; className?: IClassName; active?: boolean; @@ -85,8 +84,8 @@ function getNameParts(name: string): string[] { return name.split(/@+/); } -export const HotbarIcon = observer(({ menuItems = [], ...props }: Props) => { - const { uid, title, className, source, active, remove, disabled, onMenuOpen, children, ...rest } = props; +export const HotbarIcon = observer(({menuItems = [], ...props}: Props) => { + const { uid, title, active, className, source, disabled, onMenuOpen, children, ...rest } = props; const id = `hotbarIcon-${uid}`; const [menuOpen, setMenuOpen] = useState(false); @@ -135,12 +134,6 @@ export const HotbarIcon = observer(({ menuItems = [], ...props }: Props) => { toggleMenu(); }} close={() => toggleMenu()}> - { - evt.stopPropagation(); - remove(uid); - }}> - Remove from Hotbar - { menuItems.map((menuItem) => { return ( onMenuItemClick(menuItem) }> diff --git a/src/renderer/components/hotbar/hotbar-menu.tsx b/src/renderer/components/hotbar/hotbar-menu.tsx index 319b05f946..33a8d4e0b7 100644 --- a/src/renderer/components/hotbar/hotbar-menu.tsx +++ b/src/renderer/components/hotbar/hotbar-menu.tsx @@ -28,11 +28,12 @@ import { HotbarEntityIcon } from "./hotbar-entity-icon"; import { cssNames, IClassName } from "../../utils"; import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; import { defaultHotbarCells, HotbarItem, HotbarStore } from "../../../common/hotbar-store"; -import { catalogEntityRunContext } from "../../api/catalog-entity"; +import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity"; import { DragDropContext, Draggable, Droppable, DropResult } from "react-beautiful-dnd"; import { HotbarSelector } from "./hotbar-selector"; import { HotbarCell } from "./hotbar-cell"; import { HotbarIcon } from "./hotbar-icon"; +import { computed } from "mobx"; interface Props { className?: IClassName; @@ -64,6 +65,10 @@ export class HotbarMenu extends React.Component { const from = parseInt(source.droppableId); const to = parseInt(destination.droppableId); + if (!this.hotbar.items[from]) { // Dropped non-persisted item + this.hotbar.items[from] = this.items[from]; + } + HotbarStore.getInstance().restackItems(from, to); } @@ -73,14 +78,38 @@ export class HotbarMenu extends React.Component { hotbar.removeFromHotbar(uid); } + addItem(entity: CatalogEntity, index = -1) { + const hotbar = HotbarStore.getInstance(); + + hotbar.addToHotbar(entity, index); + } + getMoveAwayDirection(entityId: string, cellIndex: number) { const draggableItemIndex = this.hotbar.items.findIndex(item => item?.entity.uid == entityId); return draggableItemIndex > cellIndex ? "animateDown" : "animateUp"; } + @computed get items() { + const items = this.hotbar.items; + const activeEntity = catalogEntityRegistry.activeEntity; + + if (!activeEntity) return items; + + const emptyIndex = items.indexOf(null); + + if (emptyIndex === -1) return items; + if (items.find((item) => item?.entity?.uid === activeEntity.metadata.uid)) return items; + + const modifiedItems = [...items]; + + modifiedItems.splice(emptyIndex, 1, { entity: { uid: activeEntity.metadata.uid }}); + + return modifiedItems; + } + renderGrid() { - return this.hotbar.items.map((item, index) => { + return this.items.map((item, index) => { const entity = this.getEntity(item); return ( @@ -116,17 +145,18 @@ export class HotbarMenu extends React.Component { {entity ? ( entity.onRun(catalogEntityRunContext)} className={cssNames({ isDragging: snapshot.isDragging })} remove={this.removeItem} + add={this.addItem} /> ) : ( )} @@ -151,7 +181,7 @@ export class HotbarMenu extends React.Component { return (
- + {this.renderGrid()}
diff --git a/src/renderer/components/hotbar/hotbar-remove-command.tsx b/src/renderer/components/hotbar/hotbar-remove-command.tsx index f8b0bb993d..e60dc2bfaf 100644 --- a/src/renderer/components/hotbar/hotbar-remove-command.tsx +++ b/src/renderer/components/hotbar/hotbar-remove-command.tsx @@ -24,6 +24,7 @@ import { observer } from "mobx-react"; import { Select } from "../select"; import { computed } from "mobx"; import { HotbarStore } from "../../../common/hotbar-store"; +import { hotbarDisplayLabel } from "./hotbar-display-label"; import { CommandOverlay } from "../command-palette"; import { ConfirmDialog } from "../confirm-dialog"; @@ -31,7 +32,7 @@ import { ConfirmDialog } from "../confirm-dialog"; export class HotbarRemoveCommand extends React.Component { @computed get options() { return HotbarStore.getInstance().hotbars.map((hotbar) => { - return { value: hotbar.id, label: hotbar.name }; + return { value: hotbar.id, label: hotbarDisplayLabel(hotbar.id) }; }); } diff --git a/src/renderer/components/hotbar/hotbar-selector.tsx b/src/renderer/components/hotbar/hotbar-selector.tsx index a602cea6e6..63041a5d38 100644 --- a/src/renderer/components/hotbar/hotbar-selector.tsx +++ b/src/renderer/components/hotbar/hotbar-selector.tsx @@ -26,6 +26,7 @@ import { Badge } from "../badge"; import { Hotbar, HotbarStore } from "../../../common/hotbar-store"; import { CommandOverlay } from "../command-palette"; import { HotbarSwitchCommand } from "./hotbar-switch-command"; +import { hotbarDisplayIndex } from "./hotbar-display-label"; import { MaterialTooltip } from "../+catalog/material-tooltip/material-tooltip"; interface Props { @@ -34,7 +35,6 @@ interface Props { export function HotbarSelector({ hotbar }: Props) { const store = HotbarStore.getInstance(); - const activeIndexDisplay = store.activeHotbarIndex + 1; return (
@@ -44,7 +44,7 @@ export function HotbarSelector({ hotbar }: Props) { CommandOverlay.open()} /> diff --git a/src/renderer/components/hotbar/hotbar-switch-command.tsx b/src/renderer/components/hotbar/hotbar-switch-command.tsx index 93a7906585..1d11a02c80 100644 --- a/src/renderer/components/hotbar/hotbar-switch-command.tsx +++ b/src/renderer/components/hotbar/hotbar-switch-command.tsx @@ -27,6 +27,7 @@ import { HotbarStore } from "../../../common/hotbar-store"; import { CommandOverlay } from "../command-palette"; import { HotbarAddCommand } from "./hotbar-add-command"; import { HotbarRemoveCommand } from "./hotbar-remove-command"; +import { hotbarDisplayLabel } from "./hotbar-display-label"; @observer export class HotbarSwitchCommand extends React.Component { @@ -36,7 +37,7 @@ export class HotbarSwitchCommand extends React.Component { @computed get options() { const hotbarStore = HotbarStore.getInstance(); const options = hotbarStore.hotbars.map((hotbar) => { - return { value: hotbar.id, label: hotbar.name }; + return { value: hotbar.id, label: hotbarDisplayLabel(hotbar.id) }; }); options.push({ value: HotbarSwitchCommand.addActionId, label: "Add hotbar ..." }); diff --git a/types/command-exists.d.ts b/types/command-exists.d.ts index 634d2a035e..8f07bb978e 100644 --- a/types/command-exists.d.ts +++ b/types/command-exists.d.ts @@ -1,7 +1,23 @@ -// Type definitions for command-exists 1.2 -// Project: https://github.com/mathisonian/command-exists -// Definitions by: BendingBender -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ export = commandExists; diff --git a/types/dom.d.ts b/types/dom.d.ts index 40926b249b..bb829706f0 100644 --- a/types/dom.d.ts +++ b/types/dom.d.ts @@ -1,3 +1,23 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ export {}; declare global { diff --git a/types/font-face.d.ts b/types/font-face.d.ts index ca4282ae97..001b031477 100644 --- a/types/font-face.d.ts +++ b/types/font-face.d.ts @@ -1,5 +1,23 @@ -// https://www.w3.org/TR/css-font-loading/ -// https://developer.mozilla.org/en-US/docs/Web/API/FontFace +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ export {}; declare global { diff --git a/types/mocks.d.ts b/types/mocks.d.ts index b84bc39d0d..4c013fc930 100644 --- a/types/mocks.d.ts +++ b/types/mocks.d.ts @@ -1,4 +1,23 @@ -// Black-boxed modules without type safety +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ declare module "mac-ca" declare module "win-ca" declare module "@hapi/call" diff --git a/yarn.lock b/yarn.lock index c381d66392..44832f2ac8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1818,11 +1818,6 @@ resolved "https://registry.yarnpkg.com/@types/underscore/-/underscore-1.10.0.tgz#5cb0dff2a5f616fc8e0c61b482bf01fa20a03cec" integrity sha512-ZAbqul7QAKpM2h1PFGa5ETN27ulmqtj0QviYHasw9LffvXZvVHuraOx/FOsIPPDNGZN0Qo1nASxxSfMYOtSoCw== -"@types/universal-analytics@^0.4.4": - version "0.4.4" - resolved "https://registry.yarnpkg.com/@types/universal-analytics/-/universal-analytics-0.4.4.tgz#496a52b92b599a0112bec7c12414062de6ea8449" - integrity sha512-9g3F0SGxVr4UDd6y07bWtFnkpSSX1Ake7U7AGHgSFrwM6pF53/fV85bfxT2JLWS/3sjLCcyzoYzQlCxpkVo7wA== - "@types/url-parse@^1.4.3": version "1.4.3" resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.3.tgz#fba49d90f834951cb000a674efee3d6f20968329" @@ -5448,6 +5443,11 @@ escodegen@^1.14.1, escodegen@^1.8.1: optionalDependencies: source-map "~0.6.1" +eslint-plugin-header@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz#6ce512432d57675265fac47292b50d1eff11acd6" + integrity sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg== + eslint-plugin-react@^7.21.5: version "7.21.5" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3"