diff --git a/package-lock.json b/package-lock.json index f07f7d60fd..49ed7647e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3991,6 +3991,10 @@ "resolved": "packages/resource-templates", "link": true }, + "node_modules/@k8slens/routing": { + "resolved": "packages/routing", + "link": true + }, "node_modules/@k8slens/run-many": { "resolved": "packages/utility-features/run-many", "link": true @@ -36955,6 +36959,76 @@ "version": "1.0.0-alpha.0", "license": "MIT" }, + "packages/routing": { + "name": "@k8slens/routing", + "version": "1.0.0-alpha.0", + "license": "MIT", + "dependencies": { + "@ogre-tools/injectable": "^15.3.1", + "@ogre-tools/injectable-react": "^15.3.0", + "history": "^4.10.1", + "mobx-observable-history": "^2.0.3" + }, + "devDependencies": { + "@async-fn/jest": "^1.6.4", + "@k8slens/eslint-config": "6.5.0-alpha.1", + "@k8slens/react-testing-library-discovery": "^1.0.0-alpha.0", + "@testing-library/react": "^12.1.5", + "@testing-library/user-event": "^12.8.3" + }, + "peerDependencies": { + "auto-bind": "^4.0.0", + "lodash": "^4.17.21", + "mobx": "^6.8.0", + "mobx-react": "^7.6.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + }, + "packages/routing/node_modules/@k8slens/eslint-config": { + "version": "6.5.0-alpha.1", + "resolved": "https://registry.npmjs.org/@k8slens/eslint-config/-/eslint-config-6.5.0-alpha.1.tgz", + "integrity": "sha512-6DdfKe/iafX85GBK/UlKgz29FOIOp/UVS03bFGLyw7Vmm7pauB0FEHTAdbr3g1qG/Zcn6nxhOM3uqQyRY/uEyA==", + "dev": true, + "bin": { + "lens-lint": "bin/lint" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": ">= 5", + "@typescript-eslint/parser": ">= 5", + "eslint": ">= 7", + "eslint-config-airbnb-typescript": ">= 17", + "eslint-config-prettier": ">= 8", + "eslint-config-react-app": "^7.0.1", + "eslint-plugin-import": ">= 2", + "eslint-plugin-jest": ">= 27", + "eslint-plugin-jsx-a11y": ">= 6", + "eslint-plugin-no-unsanitized": ">= 4.0.2", + "eslint-plugin-prettier": ">= 4", + "eslint-plugin-react-hooks": ">= 4", + "eslint-plugin-security": ">= 1.6.0", + "eslint-plugin-simple-import-sort": ">= 7", + "eslint-plugin-unused-imports": ">= 2", + "eslint-plugin-xss": ">= 0.1.12", + "prettier": ">= 2" + } + }, + "packages/routing/node_modules/@testing-library/user-event": { + "version": "12.8.3", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz", + "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "packages/semver": { "name": "@k8slens/semver", "version": "6.5.0-alpha.4", @@ -37234,6 +37308,7 @@ }, "peerDependencies": { "@k8slens/button": "^1.0.0-alpha.1", + "@k8slens/routing": "^1.0.0-alpha.0", "@k8slens/utilities": "^1.0.0-alpha.1", "auto-bind": "^4.0.0", "lodash": "^4.17.21", @@ -37284,7 +37359,6 @@ "version": "12.0.1", "resolved": "https://registry.npmjs.org/@ogre-tools/injectable/-/injectable-12.0.1.tgz", "integrity": "sha512-uOx8STN2wSc9hknDSTGqViyR89Vwg7rGacwrVNchgyo48/QJsmZZz6cd1Aw3nT4vr7ekjTc2lh0Rz6zGIv47hg==", - "peer": true, "peerDependencies": { "@ogre-tools/fp": "^12.0.0", "lodash": "^4.17.21" diff --git a/packages/routing/.eslintrc.json b/packages/routing/.eslintrc.json new file mode 100644 index 0000000000..b15115cb69 --- /dev/null +++ b/packages/routing/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "@k8slens/eslint-config/eslint", + "parserOptions": { + "project": "./tsconfig.json" + } +} diff --git a/packages/routing/.swcrc b/packages/routing/.swcrc new file mode 100644 index 0000000000..4dd5c11a89 --- /dev/null +++ b/packages/routing/.swcrc @@ -0,0 +1,19 @@ +{ + "module": { + "type": "commonjs" + }, + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true, + "dynamicImport": false + }, + "transform": { + "legacyDecorator": true, + "decoratorMetadata": true + }, + "target": "es2019" + } +} + diff --git a/packages/routing/README.md b/packages/routing/README.md new file mode 100644 index 0000000000..187facd888 --- /dev/null +++ b/packages/routing/README.md @@ -0,0 +1,20 @@ +# @k8slens/error-boundary + +This package contains stuff related to creating Lens-applications. + +# Usage + +```bash +$ npm install @k8slens/error-boundary +``` + +```typescript +import { Tooltip, TooltipPosition } from "@k8slens/error-boundary"; +import { withTooltip } from "@k8slens/error-boundary"; + +import type { TooltipProps } from "@k8slens/error-boundary"; +import type { TooltipDecoratorProps } from "@k8slens/error-boundary"; + +``` + +## Extendability diff --git a/packages/routing/index.ts b/packages/routing/index.ts new file mode 100644 index 0000000000..4d4dd38454 --- /dev/null +++ b/packages/routing/index.ts @@ -0,0 +1,2 @@ + +export * from "./src/observable-history.injectable"; diff --git a/packages/routing/jest.config.js b/packages/routing/jest.config.js new file mode 100644 index 0000000000..05ec7ecd4d --- /dev/null +++ b/packages/routing/jest.config.js @@ -0,0 +1,3 @@ +const { configForReact } = require("@k8slens/jest").monorepoPackageConfig(__dirname); + +module.exports = configForReact; diff --git a/packages/routing/package.json b/packages/routing/package.json new file mode 100644 index 0000000000..9fba24e5f5 --- /dev/null +++ b/packages/routing/package.json @@ -0,0 +1,52 @@ +{ + "name": "@k8slens/routing", + "private": false, + "version": "1.0.0-alpha.0", + "description": "Highly extendable error-boundary in the Lens.", + "type": "commonjs", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/lensapp/lens.git" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "author": { + "name": "OpenLens Authors", + "email": "info@k8slens.dev" + }, + "license": "MIT", + "homepage": "https://github.com/lensapp/lens", + "scripts": { + "build": "webpack", + "lint": "lens-lint", + "lint:fix": "lens-lint --fix" + }, + "dependencies": { + "@ogre-tools/injectable": "^15.3.1", + "@ogre-tools/injectable-react": "^15.3.0", + "history": "^4.10.1", + "mobx-observable-history": "^2.0.3" + }, + "peerDependencies": { + "auto-bind": "^4.0.0", + "lodash": "^4.17.21", + "mobx": "^6.8.0", + "mobx-react": "^7.6.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@async-fn/jest": "^1.6.4", + "@k8slens/eslint-config": "6.5.0-alpha.1", + "@k8slens/react-testing-library-discovery": "^1.0.0-alpha.0", + "@testing-library/react": "^12.1.5", + "@testing-library/user-event": "^12.8.3" + } +} diff --git a/packages/routing/src/history.injectable.ts b/packages/routing/src/history.injectable.ts new file mode 100644 index 0000000000..63f725dc28 --- /dev/null +++ b/packages/routing/src/history.injectable.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { createBrowserHistory } from "history"; +import type { History } from "history"; + +const historyInjectable = getInjectable({ + id: "history", + instantiate: (): History => createBrowserHistory(), +}); + +export default historyInjectable; diff --git a/packages/routing/src/observable-history.injectable.ts b/packages/routing/src/observable-history.injectable.ts new file mode 100644 index 0000000000..1fe40d91fa --- /dev/null +++ b/packages/routing/src/observable-history.injectable.ts @@ -0,0 +1,23 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import { getInjectable } from "@ogre-tools/injectable"; +import { createObservableHistory } from "mobx-observable-history"; +import { searchParamsOptions } from "./search-params"; +import historyInjectable from "./history.injectable"; + +const observableHistoryInjectable = getInjectable({ + id: "observable-history", + + instantiate: (di) => { + const history = di.inject(historyInjectable); + const navigation = createObservableHistory(history, { + searchParams: searchParamsOptions, + }); + + return navigation; + }, +}); + +export default observableHistoryInjectable; diff --git a/packages/routing/src/search-params.ts b/packages/routing/src/search-params.ts new file mode 100644 index 0000000000..5f8c44db3a --- /dev/null +++ b/packages/routing/src/search-params.ts @@ -0,0 +1,12 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +import type { ObservableSearchParamsOptions } from "mobx-observable-history"; + +export const searchParamsOptions: ObservableSearchParamsOptions = { + skipEmpty: true, // skip empty params, e.g. "?x=&y2=" will be "?y=2" + joinArrays: false, // join multiple params with same name, e.g. "?x=1&x=2" => "?x=1,2" + joinArraysWith: ",", // param values splitter, applicable only with {joinArrays:true} +}; diff --git a/packages/routing/tailwind.config.js b/packages/routing/tailwind.config.js new file mode 100644 index 0000000000..59cf6201b3 --- /dev/null +++ b/packages/routing/tailwind.config.js @@ -0,0 +1,30 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ + +const path = require('path'); + +module.exports = { + content: [ + path.join(__dirname, "src/**/*.tsx") + ], + darkMode: "class", + theme: { + fontFamily: { + sans: ["Roboto", "Helvetica", "Arial", "sans-serif"], + }, + extend: { + colors: { + textAccent: "var(--textColorAccent)", + textPrimary: "var(--textColorPrimary)", + textTertiary: "var(--textColorTertiary)", + textDimmed: "var(--textColorDimmed)", + }, + }, + }, + variants: { + extend: {}, + }, + plugins: [], +}; diff --git a/packages/routing/tsconfig.json b/packages/routing/tsconfig.json new file mode 100644 index 0000000000..9e140d79da --- /dev/null +++ b/packages/routing/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@k8slens/typescript/config/base.json", + "include": ["**/*.ts", "**/*.tsx"], +} diff --git a/packages/routing/webpack.config.js b/packages/routing/webpack.config.js new file mode 100644 index 0000000000..1cda407f5a --- /dev/null +++ b/packages/routing/webpack.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/webpack").configForReact; diff --git a/packages/ui-components/error-boundary/package.json b/packages/ui-components/error-boundary/package.json index 769d69329a..f3d778ee55 100644 --- a/packages/ui-components/error-boundary/package.json +++ b/packages/ui-components/error-boundary/package.json @@ -37,6 +37,7 @@ "peerDependencies": { "@k8slens/button": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", + "@k8slens/routing": "^1.0.0-alpha.0", "auto-bind": "^4.0.0", "lodash": "^4.17.21", "mobx": "^6.8.0",