diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 02ae36727e..f7b3529b74 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -18,13 +18,3 @@ template: | ## Changes since $PREVIOUS_TAG $CHANGES - - ### Download - - - Lens v$RESOLVED_VERSION - Linux - - [AppImage](https://github.com/lensapp/lens/releases/download/v$RESOLVED_VERSION/Lens-$RESOLVED_VERSION.x86_64.AppImage) - - [DEB](https://github.com/lensapp/lens/releases/download/v$RESOLVED_VERSION/Lens-$RESOLVED_VERSION.amd64.deb) - - [RPM](https://github.com/lensapp/lens/releases/download/v$RESOLVED_VERSION/Lens-$RESOLVED_VERSION.x86_64.rpm) - - [Snapcraft](https://snapcraft.io/kontena-lens) - - [Lens v$RESOLVED_VERSION - MacOS](https://github.com/lensapp/lens/releases/download/v$RESOLVED_VERSION/Lens-$RESOLVED_VERSION.dmg) - - [Lens v$RESOLVED_VERSION - Windows](https://github.com/lensapp/lens/releases/download/v$RESOLVED_VERSION/Lens-Setup-$RESOLVED_VERSION.exe) diff --git a/Makefile b/Makefile index 428a70ae23..d8a6a35462 100644 --- a/Makefile +++ b/Makefile @@ -73,10 +73,10 @@ else endif $(extension_node_modules): - cd $(@:/node_modules=) && npm install --no-audit --no-fund + cd $(@:/node_modules=) && ../../node_modules/.bin/npm install --no-audit --no-fund $(extension_dists): src/extensions/npm/extensions/dist - cd $(@:/dist=) && npm run build + cd $(@:/dist=) && ../../node_modules/.bin/npm run build .PHONY: build-extensions build-extensions: node_modules $(extension_node_modules) $(extension_dists) @@ -104,8 +104,8 @@ build-npm: build-extension-types copy-extension-themes src/extensions/npm/extens build-extension-types: src/extensions/npm/extensions/dist .PHONY: publish-npm -publish-npm: build-npm - npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" +publish-npm: node_modules build-npm + ./node_modules/.bin/npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}" cd src/extensions/npm/extensions && npm publish --access=public .PHONY: docs diff --git a/extensions/kube-object-event-status/webpack.config.js b/extensions/kube-object-event-status/webpack.config.js index a35cf40850..6d5de7a2f8 100644 --- a/extensions/kube-object-event-status/webpack.config.js +++ b/extensions/kube-object-event-status/webpack.config.js @@ -6,6 +6,9 @@ module.exports = [ context: __dirname, target: "electron-renderer", mode: "production", + optimization: { + minimize: false + }, module: { rules: [ { diff --git a/extensions/metrics-cluster-feature/webpack.config.js b/extensions/metrics-cluster-feature/webpack.config.js index 8d3ea196ba..2df74b3e35 100644 --- a/extensions/metrics-cluster-feature/webpack.config.js +++ b/extensions/metrics-cluster-feature/webpack.config.js @@ -6,6 +6,9 @@ module.exports = [ context: __dirname, target: "electron-renderer", mode: "production", + optimization: { + minimize: false + }, module: { rules: [ { diff --git a/extensions/node-menu/webpack.config.js b/extensions/node-menu/webpack.config.js index a35cf40850..6d5de7a2f8 100644 --- a/extensions/node-menu/webpack.config.js +++ b/extensions/node-menu/webpack.config.js @@ -6,6 +6,9 @@ module.exports = [ context: __dirname, target: "electron-renderer", mode: "production", + optimization: { + minimize: false + }, module: { rules: [ { diff --git a/extensions/pod-menu/webpack.config.js b/extensions/pod-menu/webpack.config.js index a35cf40850..6d5de7a2f8 100644 --- a/extensions/pod-menu/webpack.config.js +++ b/extensions/pod-menu/webpack.config.js @@ -6,6 +6,9 @@ module.exports = [ context: __dirname, target: "electron-renderer", mode: "production", + optimization: { + minimize: false + }, module: { rules: [ { diff --git a/package.json b/package.json index 378b2428f4..a9bea801ad 100644 --- a/package.json +++ b/package.json @@ -186,6 +186,7 @@ "filehound": "^1.17.4", "filenamify": "^4.1.0", "fs-extra": "^9.0.1", + "grapheme-splitter": "^1.0.4", "handlebars": "^4.7.6", "http-proxy": "^1.18.1", "immer": "^8.0.1", @@ -262,6 +263,7 @@ "@types/npm": "^2.0.31", "@types/progress-bar-webpack-plugin": "^2.1.0", "@types/proper-lockfile": "^4.1.1", + "@types/randomcolor": "^0.5.5", "@types/react": "^17.0.0", "@types/react-beautiful-dnd": "^13.0.0", "@types/react-dom": "^17.0.0", @@ -278,7 +280,6 @@ "@types/tar": "^4.0.4", "@types/tcp-port-used": "^1.0.0", "@types/tempy": "^0.3.0", - "@types/terser-webpack-plugin": "^3.0.0", "@types/universal-analytics": "^0.4.4", "@types/url-parse": "^1.4.3", "@types/uuid": "^8.3.0", @@ -326,8 +327,9 @@ "postinstall-postinstall": "^2.1.0", "prettier": "^2.2.0", "progress-bar-webpack-plugin": "^2.1.0", + "randomcolor": "^0.6.2", "raw-loader": "^4.0.1", - "react-beautiful-dnd": "^13.0.0", + "react-beautiful-dnd": "^13.1.0", "react-refresh": "^0.9.0", "react-router-dom": "^5.2.0", "react-select": "^3.1.0", @@ -337,11 +339,10 @@ "sharp": "^0.26.1", "spectron": "11.0.0", "style-loader": "^1.2.1", - "terser-webpack-plugin": "^3.0.3", "ts-jest": "^26.1.0", "ts-loader": "^7.0.5", "ts-node": "^8.10.2", - "type-fest": "^0.18.0", + "type-fest": "^1.0.2", "typedoc": "0.17.0-3", "typedoc-plugin-markdown": "^2.4.0", "typeface-roboto": "^0.0.75", diff --git a/src/common/__tests__/catalog-entity-registry.test.ts b/src/common/__tests__/catalog-entity-registry.test.ts index da85af3e3d..1a53865241 100644 --- a/src/common/__tests__/catalog-entity-registry.test.ts +++ b/src/common/__tests__/catalog-entity-registry.test.ts @@ -1,12 +1,10 @@ import { observable, reaction } from "mobx"; import { WebLink } from "../catalog-entities"; -import { CatalogEntityRegistry } from "../catalog-entity-registry"; +import { CatalogEntityRegistry } from "../catalog"; describe("CatalogEntityRegistry", () => { let registry: CatalogEntityRegistry; const entity = new WebLink({ - apiVersion: "entity.k8slens.dev/v1alpha1", - kind: "WebLink", metadata: { uid: "test", name: "test-link", @@ -17,7 +15,7 @@ describe("CatalogEntityRegistry", () => { url: "https://k8slens.dev" }, status: { - phase: "ok" + phase: "valid" } }); diff --git a/src/common/catalog-entities/icons/kubernetes.svg b/src/common/catalog-entities/icons/kubernetes.svg new file mode 100644 index 0000000000..b4a9068420 --- /dev/null +++ b/src/common/catalog-entities/icons/kubernetes.svg @@ -0,0 +1,46 @@ + + + + + + diff --git a/src/common/catalog-entities/kubernetes-cluster.ts b/src/common/catalog-entities/kubernetes-cluster.ts index fda4927944..c2dae01b74 100644 --- a/src/common/catalog-entities/kubernetes-cluster.ts +++ b/src/common/catalog-entities/kubernetes-cluster.ts @@ -1,11 +1,10 @@ -import { EventEmitter } from "events"; -import { observable } from "mobx"; -import { catalogCategoryRegistry } from "../catalog-category-registry"; -import { CatalogCategory, CatalogEntity, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenuContext, CatalogEntityData, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity"; +import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; +import { CatalogEntity, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; import { clusterDisconnectHandler } from "../cluster-ipc"; import { ClusterStore } from "../cluster-store"; import { requestMain } from "../ipc"; import { productName } from "../vars"; +import { CatalogCategory, CatalogCategorySpec } from "../catalog"; export type KubernetesClusterSpec = { kubeconfigPath: string; @@ -16,32 +15,19 @@ export interface KubernetesClusterStatus extends CatalogEntityStatus { phase: "connected" | "disconnected"; } -export class KubernetesCluster implements CatalogEntity { +export class KubernetesCluster extends CatalogEntity { public readonly apiVersion = "entity.k8slens.dev/v1alpha1"; public readonly kind = "KubernetesCluster"; - @observable public metadata: CatalogEntityMetadata; - @observable public status: KubernetesClusterStatus; - @observable public spec: KubernetesClusterSpec; - - constructor(data: CatalogEntityData) { - this.metadata = data.metadata; - this.status = data.status as KubernetesClusterStatus; - this.spec = data.spec as KubernetesClusterSpec; - } - - getId() { - return this.metadata.uid; - } - - getName() { - return this.metadata.name; - } async onRun(context: CatalogEntityActionContext) { context.navigate(`/cluster/${this.metadata.uid}`); } - async onDetailsOpen() { + onDetailsOpen(): void { + // + } + + onSettingsOpen(): void { // } @@ -81,13 +67,14 @@ export class KubernetesCluster implements CatalogEntity { } } -export class KubernetesClusterCategory extends EventEmitter implements CatalogCategory { +export class KubernetesClusterCategory extends CatalogCategory { public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; public readonly kind = "CatalogCategory"; public metadata = { - name: "Kubernetes Clusters" + name: "Kubernetes Clusters", + icon: require(`!!raw-loader!./icons/kubernetes.svg`).default // eslint-disable-line }; - public spec = { + public spec: CatalogCategorySpec = { group: "entity.k8slens.dev", versions: [ { @@ -113,10 +100,6 @@ export class KubernetesClusterCategory extends EventEmitter implements CatalogCa }); }); } - - getId() { - return `${this.spec.group}/${this.spec.names.kind}`; - } } catalogCategoryRegistry.add(new KubernetesClusterCategory()); diff --git a/src/common/catalog-entities/web-link.ts b/src/common/catalog-entities/web-link.ts index db52fe0eb6..24a1893c19 100644 --- a/src/common/catalog-entities/web-link.ts +++ b/src/common/catalog-entities/web-link.ts @@ -1,6 +1,5 @@ -import { observable } from "mobx"; -import { CatalogCategory, CatalogEntity, CatalogEntityData, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog-entity"; -import { catalogCategoryRegistry } from "../catalog-category-registry"; +import { CatalogCategory, CatalogEntity, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog"; +import { catalogCategoryRegistry } from "../catalog/catalog-category-registry"; export interface WebLinkStatus extends CatalogEntityStatus { phase: "valid" | "invalid"; @@ -10,45 +9,33 @@ export type WebLinkSpec = { url: string; }; -export class WebLink implements CatalogEntity { +export class WebLink extends CatalogEntity { public readonly apiVersion = "entity.k8slens.dev/v1alpha1"; public readonly kind = "KubernetesCluster"; - @observable public metadata: CatalogEntityMetadata; - @observable public status: WebLinkStatus; - @observable public spec: WebLinkSpec; - - constructor(data: CatalogEntityData) { - this.metadata = data.metadata; - this.status = data.status as WebLinkStatus; - this.spec = data.spec as WebLinkSpec; - } - - getId() { - return this.metadata.uid; - } - - getName() { - return this.metadata.name; - } async onRun() { window.open(this.spec.url, "_blank"); } - async onDetailsOpen() { - // + public onSettingsOpen(): void { + return; } - async onContextMenuOpen() { - // + public onDetailsOpen(): void { + return; + } + + public onContextMenuOpen(): void { + return; } } -export class WebLinkCategory implements CatalogCategory { +export class WebLinkCategory extends CatalogCategory { public readonly apiVersion = "catalog.k8slens.dev/v1alpha1"; public readonly kind = "CatalogCategory"; public metadata = { - name: "Web Links" + name: "Web Links", + icon: "link" }; public spec = { group: "entity.k8slens.dev", @@ -62,10 +49,6 @@ export class WebLinkCategory implements CatalogCategory { kind: "WebLink" } }; - - getId() { - return `${this.spec.group}/${this.spec.names.kind}`; - } } catalogCategoryRegistry.add(new WebLinkCategory()); diff --git a/src/common/catalog-entity.ts b/src/common/catalog-entity.ts deleted file mode 100644 index 8430381368..0000000000 --- a/src/common/catalog-entity.ts +++ /dev/null @@ -1,94 +0,0 @@ -export interface CatalogCategoryVersion { - name: string; - entityClass: { new(data: CatalogEntityData): CatalogEntity }; -} - -export interface CatalogCategory { - apiVersion: string; - kind: string; - metadata: { - name: string; - } - spec: { - group: string; - versions: CatalogCategoryVersion[]; - names: { - kind: string; - } - } - getId: () => string; -} - -export type CatalogEntityMetadata = { - uid: string; - name: string; - description?: string; - source?: string; - labels: { - [key: string]: string; - } - [key: string]: string | object; -}; - -export type CatalogEntityStatus = { - phase: string; - reason?: string; - message?: string; - active?: boolean; -}; - -export interface CatalogEntityActionContext { - navigate: (url: string) => void; - setCommandPaletteContext: (context?: CatalogEntity) => void; -} - -export type CatalogEntityContextMenu = { - icon: string; - title: string; - onlyVisibleForSource?: string; // show only if empty or if matches with entity source - onClick: () => Promise; - confirm?: { - message: string; - } -}; - -export type CatalogEntitySettingsMenu = { - group?: string; - title: string; - components: { - View: React.ComponentType - }; -}; - -export interface CatalogEntityContextMenuContext { - navigate: (url: string) => void; - menuItems: CatalogEntityContextMenu[]; -} - -export interface CatalogEntitySettingsContext { - menuItems: CatalogEntityContextMenu[]; -} - -export interface CatalogEntityAddMenuContext { - navigate: (url: string) => void; - menuItems: CatalogEntityContextMenu[]; -} - -export type CatalogEntityData = { - apiVersion: string; - kind: string; - metadata: CatalogEntityMetadata; - status: CatalogEntityStatus; - spec: { - [key: string]: any; - } -}; - -export interface CatalogEntity extends CatalogEntityData { - getId: () => string; - getName: () => string; - onRun: (context: CatalogEntityActionContext) => Promise; - onDetailsOpen: (context: CatalogEntityActionContext) => Promise; - onContextMenuOpen: (context: CatalogEntityContextMenuContext) => Promise; - onSettingsOpen?: (context: CatalogEntitySettingsContext) => Promise; -} diff --git a/src/common/catalog-category-registry.ts b/src/common/catalog/catalog-category-registry.ts similarity index 88% rename from src/common/catalog-category-registry.ts rename to src/common/catalog/catalog-category-registry.ts index d8d65564de..13e81aa165 100644 --- a/src/common/catalog-category-registry.ts +++ b/src/common/catalog/catalog-category-registry.ts @@ -1,5 +1,5 @@ import { action, computed, observable, toJS } from "mobx"; -import { CatalogCategory, CatalogEntityData } from "./catalog-entity"; +import { CatalogCategory, CatalogEntityData, CatalogEntityKindData } from "./catalog-entity"; export class CatalogCategoryRegistry { @observable protected categories: CatalogCategory[] = []; @@ -20,7 +20,7 @@ export class CatalogCategoryRegistry { return this.categories.find((c) => c.spec.group === group && c.spec.names.kind === kind) as T; } - getEntityForData(data: CatalogEntityData) { + getEntityForData(data: CatalogEntityData & CatalogEntityKindData) { const category = this.getCategoryForEntity(data); if (!category) { @@ -39,7 +39,7 @@ export class CatalogCategoryRegistry { return new specVersion.entityClass(data); } - getCategoryForEntity(data: CatalogEntityData) { + getCategoryForEntity(data: CatalogEntityData & CatalogEntityKindData) { const splitApiVersion = data.apiVersion.split("/"); const group = splitApiVersion[0]; diff --git a/src/common/catalog-entity-registry.ts b/src/common/catalog/catalog-entity-registry.ts similarity index 100% rename from src/common/catalog-entity-registry.ts rename to src/common/catalog/catalog-entity-registry.ts diff --git a/src/common/catalog/catalog-entity.ts b/src/common/catalog/catalog-entity.ts new file mode 100644 index 0000000000..fdd443ae54 --- /dev/null +++ b/src/common/catalog/catalog-entity.ts @@ -0,0 +1,143 @@ +import { EventEmitter } from "events"; +import { observable } from "mobx"; + +type ExtractEntityMetadataType = Entity extends CatalogEntity ? Metadata : never; +type ExtractEntityStatusType = Entity extends CatalogEntity ? Status : never; +type ExtractEntitySpecType = Entity extends CatalogEntity ? Spec : never; + +export type CatalogEntityConstructor = ( + (new (data: CatalogEntityData< + ExtractEntityMetadataType, + ExtractEntityStatusType, + ExtractEntitySpecType + >) => Entity) +); + +export interface CatalogCategoryVersion { + name: string; + entityClass: CatalogEntityConstructor; +} + +export interface CatalogCategorySpec { + group: string; + versions: CatalogCategoryVersion[]; + names: { + kind: string; + }; +} + +export abstract class CatalogCategory extends EventEmitter { + abstract readonly apiVersion: string; + abstract readonly kind: string; + abstract metadata: { + name: string; + icon: string; + }; + abstract spec: CatalogCategorySpec; + + public getId(): string { + return `${this.spec.group}/${this.spec.names.kind}`; + } +} + +export interface CatalogEntityMetadata { + uid: string; + name: string; + description?: string; + source?: string; + labels: Record; + [key: string]: string | object; +} + +export interface CatalogEntityStatus { + phase: string; + reason?: string; + message?: string; + active?: boolean; +} + +export interface CatalogEntityActionContext { + navigate: (url: string) => void; + setCommandPaletteContext: (context?: CatalogEntity) => void; +} + +export interface CatalogEntityContextMenu { + icon: string; + title: string; + onlyVisibleForSource?: string; // show only if empty or if matches with entity source + onClick: () => Promise; + confirm?: { + message: string; + } +} + +export interface CatalogEntitySettingsMenu { + group?: string; + title: string; + components: { + View: React.ComponentType + }; +} + +export interface CatalogEntityContextMenuContext { + navigate: (url: string) => void; + menuItems: CatalogEntityContextMenu[]; +} + +export interface CatalogEntitySettingsContext { + menuItems: CatalogEntityContextMenu[]; +} + +export interface CatalogEntityAddMenuContext { + navigate: (url: string) => void; + menuItems: CatalogEntityContextMenu[]; +} + +export type CatalogEntitySpec = Record; + +export interface CatalogEntityData< + Metadata extends CatalogEntityMetadata = CatalogEntityMetadata, + Status extends CatalogEntityStatus = CatalogEntityStatus, + Spec extends CatalogEntitySpec = CatalogEntitySpec, +> { + metadata: Metadata; + status: Status; + spec: Spec; +} + +export interface CatalogEntityKindData { + readonly apiVersion: string; + readonly kind: string; +} + +export abstract class CatalogEntity< + Metadata extends CatalogEntityMetadata = CatalogEntityMetadata, + Status extends CatalogEntityStatus = CatalogEntityStatus, + Spec extends CatalogEntitySpec = CatalogEntitySpec, +> implements CatalogEntityKindData { + public abstract readonly apiVersion: string; + public abstract readonly kind: string; + + @observable metadata: Metadata; + @observable status: Status; + @observable spec: Spec; + + constructor(data: CatalogEntityData) { + this.metadata = data.metadata; + this.status = data.status; + this.spec = data.spec; + } + + public getId(): string { + return this.metadata.uid; + } + + public getName(): string { + return this.metadata.name; + } + + public abstract onRun?(context: CatalogEntityActionContext): void | Promise; + public abstract onDetailsOpen(context: CatalogEntityActionContext): void | Promise; + public abstract onContextMenuOpen(context: CatalogEntityContextMenuContext): void | Promise; + public abstract onSettingsOpen(context: CatalogEntitySettingsContext): void | Promise; +} diff --git a/src/common/catalog/index.ts b/src/common/catalog/index.ts new file mode 100644 index 0000000000..d359a7f678 --- /dev/null +++ b/src/common/catalog/index.ts @@ -0,0 +1,3 @@ +export * from "./catalog-category-registry"; +export * from "./catalog-entity"; +export * from "./catalog-entity-registry"; diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index 6f26bab2da..16a077277e 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -19,3 +19,6 @@ export * from "./downloadFile"; export * from "./escapeRegExp"; export * from "./tar"; export * from "./type-narrowing"; +import * as iter from "./iter"; + +export { iter }; diff --git a/src/common/utils/iter.ts b/src/common/utils/iter.ts new file mode 100644 index 0000000000..f364ce4aee --- /dev/null +++ b/src/common/utils/iter.ts @@ -0,0 +1,25 @@ +/** + * Create a new type safe empty Iterable + * @returns An `Iterable` that yields 0 items + */ +export function* newEmpty(): Iterable { + return; +} + +/** + * Creates a new `Iterable` that yields at most n items from src. + * Does not modify `src` which can be used later. + * @param src An initial iterator + * @param n The maximum number of elements to take from src. Yields up to the floor of `n` and 0 items if n < 0 + */ +export function* take(src: Iterable, n: number): Iterable { + outer: for (let i = 0; i < n; i += 1) { + for (const item of src) { + yield item; + continue outer; + } + + // if we are here that means that `src` has been exhausted. Don't bother trying again. + break outer; + } +} diff --git a/src/extensions/core-api/catalog.ts b/src/extensions/core-api/catalog.ts index a24569c609..ccf07e3048 100644 --- a/src/extensions/core-api/catalog.ts +++ b/src/extensions/core-api/catalog.ts @@ -1,8 +1,7 @@ -import { CatalogEntity } from "../../common/catalog-entity"; -import { catalogEntityRegistry as registry } from "../../common/catalog-entity-registry"; +import { CatalogEntity, catalogEntityRegistry as registry } from "../../common/catalog"; -export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog-category-registry"; +export { catalogCategoryRegistry as catalogCategories } from "../../common/catalog/catalog-category-registry"; export * from "../../common/catalog-entities"; export class CatalogEntityRegistry { diff --git a/src/extensions/interfaces/catalog.ts b/src/extensions/interfaces/catalog.ts index 916742076b..0d8bd3b6cf 100644 --- a/src/extensions/interfaces/catalog.ts +++ b/src/extensions/interfaces/catalog.ts @@ -1 +1 @@ -export * from "../../common/catalog-entity"; +export * from "../../common/catalog/catalog-entity"; diff --git a/src/extensions/lens-main-extension.ts b/src/extensions/lens-main-extension.ts index 473f031665..d01243aac1 100644 --- a/src/extensions/lens-main-extension.ts +++ b/src/extensions/lens-main-extension.ts @@ -2,8 +2,7 @@ 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 { catalogEntityRegistry } from "../common/catalog-entity-registry"; -import { CatalogEntity } from "../common/catalog-entity"; +import { CatalogEntity, catalogEntityRegistry } from "../common/catalog"; import { IObservableArray } from "mobx"; export class LensMainExtension extends LensExtension { diff --git a/src/extensions/registries/command-registry.ts b/src/extensions/registries/command-registry.ts index 45af9121a1..c8c4eedb75 100644 --- a/src/extensions/registries/command-registry.ts +++ b/src/extensions/registries/command-registry.ts @@ -3,7 +3,7 @@ import { BaseRegistry } from "./base-registry"; import { action, observable } from "mobx"; import { LensExtension } from "../lens-extension"; -import { CatalogEntity } from "../../common/catalog-entity"; +import { CatalogEntity } from "../../common/catalog"; export type CommandContext = { entity?: CatalogEntity; diff --git a/src/extensions/registries/entity-setting-registry.ts b/src/extensions/registries/entity-setting-registry.ts index 8dd5ce6f25..444f816b0a 100644 --- a/src/extensions/registries/entity-setting-registry.ts +++ b/src/extensions/registries/entity-setting-registry.ts @@ -1,5 +1,5 @@ import type React from "react"; -import { CatalogEntity } from "../../common/catalog-entity"; +import { CatalogEntity } from "../../common/catalog"; import { BaseRegistry } from "./base-registry"; export interface EntitySettingViewProps { @@ -15,8 +15,9 @@ export interface EntitySettingRegistration { kind: string; apiVersions: string[]; source?: string; - id?: string; components: EntitySettingComponents; + id?: string; + priority?: number; } export interface RegisteredEntitySetting extends EntitySettingRegistration { @@ -32,17 +33,17 @@ export class EntitySettingRegistry extends BaseRegistry { + let items = this.getItems().filter((item) => { return item.kind === kind && item.apiVersions.includes(apiVersion); }); if (source) { - return items.filter((item) => { + items = items.filter((item) => { return !item.source || item.source === source; }); - } else { - return items; } + + return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50)); } } diff --git a/src/extensions/registries/kube-object-detail-registry.ts b/src/extensions/registries/kube-object-detail-registry.ts index 9c79b662ea..475b6bd75a 100644 --- a/src/extensions/registries/kube-object-detail-registry.ts +++ b/src/extensions/registries/kube-object-detail-registry.ts @@ -16,15 +16,9 @@ export class KubeObjectDetailRegistry extends BaseRegistry { return item.kind === kind && item.apiVersions.includes(apiVersion); - }).map((item) => { - if (item.priority === null) { - item.priority = 50; - } - - return item; }); - return items.sort((a, b) => b.priority - a.priority); + return items.sort((a, b) => (b.priority ?? 50) - (a.priority ?? 50)); } } diff --git a/src/main/catalog-pusher.ts b/src/main/catalog-pusher.ts index ffe8cc17d0..73b9b9d580 100644 --- a/src/main/catalog-pusher.ts +++ b/src/main/catalog-pusher.ts @@ -1,6 +1,6 @@ import { autorun, toJS } from "mobx"; import { broadcastMessage, subscribeToBroadcast, unsubscribeFromBroadcast } from "../common/ipc"; -import { CatalogEntityRegistry} from "../common/catalog-entity-registry"; +import { CatalogEntityRegistry} from "../common/catalog"; import "../common/catalog-entities/kubernetes-cluster"; export class CatalogPusher { diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 0a413584f8..c1485881e4 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -7,9 +7,8 @@ import { Cluster } from "./cluster"; import logger from "./logger"; import { apiKubePrefix } from "../common/vars"; import { Singleton } from "../common/utils"; -import { CatalogEntity } from "../common/catalog-entity"; +import { CatalogEntity, catalogEntityRegistry } from "../common/catalog"; import { KubernetesCluster } from "../common/catalog-entities/kubernetes-cluster"; -import { catalogEntityRegistry } from "../common/catalog-entity-registry"; const clusterOwnerRef = "ClusterManager"; diff --git a/src/main/index.ts b/src/main/index.ts index 9a2b97234e..42f965fe89 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -30,7 +30,7 @@ import { bindBroadcastHandlers } from "../common/ipc"; import { startUpdateChecking } from "./app-updater"; import { IpcRendererNavigationEvents } from "../renderer/navigation/events"; import { CatalogPusher } from "./catalog-pusher"; -import { catalogEntityRegistry } from "../common/catalog-entity-registry"; +import { catalogEntityRegistry } from "../common/catalog"; import { HotbarStore } from "../common/hotbar-store"; import { HelmRepoManager } from "./helm/helm-repo-manager"; diff --git a/src/renderer/api/__tests__/catalog-entity-registry.test.ts b/src/renderer/api/__tests__/catalog-entity-registry.test.ts index 2b36086856..e7c14f587c 100644 --- a/src/renderer/api/__tests__/catalog-entity-registry.test.ts +++ b/src/renderer/api/__tests__/catalog-entity-registry.test.ts @@ -1,6 +1,6 @@ import { CatalogEntityRegistry } from "../catalog-entity-registry"; import "../../../common/catalog-entities"; -import { catalogCategoryRegistry } from "../../../common/catalog-category-registry"; +import { catalogCategoryRegistry } from "../../../common/catalog/catalog-category-registry"; describe("CatalogEntityRegistry", () => { describe("updateItems", () => { diff --git a/src/renderer/api/catalog-category-registry.ts b/src/renderer/api/catalog-category-registry.ts new file mode 100644 index 0000000000..9ebeb6e9ea --- /dev/null +++ b/src/renderer/api/catalog-category-registry.ts @@ -0,0 +1 @@ +export { catalogCategoryRegistry } from "../../common/catalog"; diff --git a/src/renderer/api/catalog-entity-registry.ts b/src/renderer/api/catalog-entity-registry.ts index 12450023ee..ea0537bda3 100644 --- a/src/renderer/api/catalog-entity-registry.ts +++ b/src/renderer/api/catalog-entity-registry.ts @@ -1,7 +1,6 @@ import { action, observable } from "mobx"; import { broadcastMessage, subscribeToBroadcast } from "../../common/ipc"; -import { CatalogCategory, CatalogEntity, CatalogEntityData } from "../../common/catalog-entity"; -import { catalogCategoryRegistry, CatalogCategoryRegistry } from "../../common/catalog-category-registry"; +import { CatalogCategory, CatalogEntity, CatalogEntityData, catalogCategoryRegistry, CatalogCategoryRegistry, CatalogEntityKindData } from "../../common/catalog"; import "../../common/catalog-entities"; export class CatalogEntityRegistry { @@ -10,13 +9,13 @@ export class CatalogEntityRegistry { constructor(private categoryRegistry: CatalogCategoryRegistry) {} init() { - subscribeToBroadcast("catalog:items", (ev, items: CatalogEntityData[]) => { + subscribeToBroadcast("catalog:items", (ev, items: (CatalogEntityData & CatalogEntityKindData)[]) => { this.updateItems(items); }); broadcastMessage("catalog:broadcast"); } - @action updateItems(items: CatalogEntityData[]) { + @action updateItems(items: (CatalogEntityData & CatalogEntityKindData)[]) { this._items.forEach((item, index) => { const foundIndex = items.findIndex((i) => i.apiVersion === item.apiVersion && i.kind === item.kind && i.metadata.uid === item.metadata.uid); diff --git a/src/renderer/api/catalog-entity.ts b/src/renderer/api/catalog-entity.ts index ad82af10e6..705baebf36 100644 --- a/src/renderer/api/catalog-entity.ts +++ b/src/renderer/api/catalog-entity.ts @@ -1,16 +1,17 @@ import { navigate } from "../navigation"; import { commandRegistry } from "../../extensions/registries"; -import { CatalogEntity } from "../../common/catalog-entity"; +import { CatalogEntity } from "../../common/catalog"; export { CatalogCategory, CatalogEntity, CatalogEntityData, + CatalogEntityKindData, CatalogEntityActionContext, CatalogEntityAddMenuContext, CatalogEntityContextMenu, CatalogEntityContextMenuContext -} from "../../common/catalog-entity"; +} from "../../common/catalog"; export const catalogEntityRunContext = { navigate: (url: string) => navigate(url), diff --git a/src/renderer/components/+catalog/catalog-entity.store.ts b/src/renderer/components/+catalog/catalog-entity.store.ts index 49043fed70..5a9652eb4f 100644 --- a/src/renderer/components/+catalog/catalog-entity.store.ts +++ b/src/renderer/components/+catalog/catalog-entity.store.ts @@ -3,7 +3,7 @@ import { catalogEntityRegistry } from "../../api/catalog-entity-registry"; import { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity"; import { ItemObject, ItemStore } from "../../item.store"; import { autobind } from "../../utils"; -import { CatalogCategory } from "../../../common/catalog-entity"; +import { CatalogCategory } from "../../../common/catalog"; export class CatalogEntityItem implements ItemObject { constructor(public entity: CatalogEntity) {} @@ -44,6 +44,15 @@ export class CatalogEntityItem implements ItemObject { return this.entity.metadata.source || "unknown"; } + get searchFields() { + return [ + this.name, + this.id, + this.phase, + ...this.labels.map((value, key) => `${key}=${value}`) + ]; + } + onRun(ctx: CatalogEntityActionContext) { this.entity.onRun(ctx); } diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx index 806c103dd9..0179d0dc3a 100644 --- a/src/renderer/components/+catalog/catalog.tsx +++ b/src/renderer/components/+catalog/catalog.tsx @@ -16,7 +16,7 @@ import { autobind } from "../../utils"; import { Notifications } from "../notifications"; import { ConfirmDialog } from "../confirm-dialog"; import { Tab, Tabs } from "../tabs"; -import { catalogCategoryRegistry } from "../../../common/catalog-category-registry"; +import { catalogCategoryRegistry } from "../../../common/catalog"; import { CatalogAddButton } from "./catalog-add-button"; enum sortBy { @@ -157,9 +157,12 @@ export class Catalog extends React.Component { [sortBy.source]: (item: CatalogEntityItem) => item.source, [sortBy.status]: (item: CatalogEntityItem) => item.phase, }} + searchFilters={[ + (entity: CatalogEntityItem) => entity.searchFields, + ]} renderTableHeader={[ { title: "Name", className: "name", sortBy: sortBy.name }, - { title: "Source", className: "source" }, + { title: "Source", className: "source", sortBy: sortBy.source }, { title: "Labels", className: "labels" }, { title: "Status", className: "status", sortBy: sortBy.status }, ]} diff --git a/src/renderer/components/hotbar/hotbar-icon.scss b/src/renderer/components/hotbar/hotbar-icon.scss index 00ddebe716..dd83604950 100644 --- a/src/renderer/components/hotbar/hotbar-icon.scss +++ b/src/renderer/components/hotbar/hotbar-icon.scss @@ -16,8 +16,9 @@ background-color: var(--primary); } - div.default { - background-color: var(--halfGray); + &.interactive { + margin-left: -3px; + border: 3px solid var(--clusterMenuBackground); } &.active { @@ -35,6 +36,22 @@ } } + .badge { + color: $textColorAccent; + position: absolute; + right: 0; + bottom: 0; + margin: -$padding; + font-size: $font-size-small; + background: $clusterMenuBackground; + color: white; + padding: 0px; + border-radius: 50%; + svg { + width: 13px; + } + } + img { width: var(--size); height: var(--size); @@ -45,11 +62,8 @@ left: 30px; min-width: 250px; - ul { - li { - font-size: 12px; - - } + li.MenuItem { + font-size: 0.9em; } } } diff --git a/src/renderer/components/hotbar/hotbar-icon.tsx b/src/renderer/components/hotbar/hotbar-icon.tsx index 485be6f5ee..262985a78d 100644 --- a/src/renderer/components/hotbar/hotbar-icon.tsx +++ b/src/renderer/components/hotbar/hotbar-icon.tsx @@ -2,16 +2,19 @@ import "./hotbar-icon.scss"; import React, { DOMAttributes } from "react"; import { observer } from "mobx-react"; -import { cssNames, IClassName } from "../../utils"; +import { cssNames, IClassName, iter } from "../../utils"; import { Tooltip } from "../tooltip"; import { Avatar } from "@material-ui/core"; -import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog-entity"; +import { CatalogEntity, CatalogEntityContextMenu, CatalogEntityContextMenuContext } from "../../../common/catalog"; import { Menu, MenuItem } from "../menu"; import { Icon } from "../icon"; -import { observable } from "mobx"; +import { computed, observable } from "mobx"; import { navigate } from "../../navigation"; import { HotbarStore } from "../../../common/hotbar-store"; import { ConfirmDialog } from "../confirm-dialog"; +import randomColor from "randomcolor"; +import { catalogCategoryRegistry } from "../../api/catalog-category-registry"; +import GraphemeSplitter from "grapheme-splitter"; interface Props extends DOMAttributes { entity: CatalogEntity; @@ -21,6 +24,22 @@ interface Props extends DOMAttributes { isActive?: boolean; } +function getNameParts(name: string): string[] { + const byWhitespace = name.split(/\s+/); + + if (byWhitespace.length > 1) { + return byWhitespace; + } + + const byDashes = name.split(/[-_]+/); + + if (byDashes.length > 1) { + return byDashes; + } + + return name.split(/@+/); +} + @observer export class HotbarIcon extends React.Component { @observable.deep private contextMenu: CatalogEntityContextMenuContext; @@ -33,25 +52,32 @@ export class HotbarIcon extends React.Component { }; } - get iconString() { - let splittedName = this.props.entity.metadata.name.split(" "); + @computed get iconString() { + const [rawFirst, rawSecond, rawThird] = getNameParts(this.props.entity.metadata.name); + const splitter = new GraphemeSplitter(); + const first = splitter.iterateGraphemes(rawFirst); + const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first; + const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty(); - if (splittedName.length === 1) { - splittedName = splittedName[0].split("-"); + return [ + ...iter.take(first, 1), + ...iter.take(second, 1), + ...iter.take(third, 1), + ].filter(Boolean).join(""); + } + + get badgeIcon() { + const className = "badge"; + const category = catalogCategoryRegistry.getCategoryForEntity(this.props.entity); + + if (!category) { + return ; } - if (splittedName.length === 1) { - splittedName = splittedName[0].split("@"); - } - - splittedName = splittedName.map((part) => part.replace(/\W/g, "")); - - if (splittedName.length === 1) { - return splittedName[0].substring(0, 2); - } else if (splittedName.length === 2) { - return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1); + if (category.metadata.icon.includes("; } else { - return splittedName[0].substring(0, 1) + splittedName[1].substring(0, 1) + splittedName[2].substring(0, 1); + return ; } } @@ -82,6 +108,12 @@ export class HotbarIcon extends React.Component { } } + generateAvatarStyle(entity: CatalogEntity): React.CSSProperties { + return { + "backgroundColor": randomColor({ seed: entity.metadata.name, luminosity: "dark" }) + }; + } + render() { const { entity, errorClass, isActive, @@ -101,7 +133,16 @@ export class HotbarIcon extends React.Component { return (
{entity.metadata.name} - {this.iconString} + + {this.iconString} + + { this.badgeIcon } { render() { const { className } = this.props; - const hotbarIndex = HotbarStore.getInstance().activeHotbarIndex + 1; + const hotbarStore = HotbarStore.getInstance(); + const hotbar = hotbarStore.getActive(); + const activeIndexDisplay = hotbarStore.activeHotbarIndex + 1; return (
@@ -98,7 +101,13 @@ export class HotbarMenu extends React.Component {
this.previous()} />
- this.openSelector()} /> + this.openSelector()} /> + + {hotbar.name} +
this.next()} />
diff --git a/src/renderer/components/icon/icon.tsx b/src/renderer/components/icon/icon.tsx index 806784dfcf..246e68414d 100644 --- a/src/renderer/components/icon/icon.tsx +++ b/src/renderer/components/icon/icon.tsx @@ -94,7 +94,7 @@ export class Icon extends React.PureComponent { // render as inline svg-icon if (svg) { - const svgIconText = require(`!!raw-loader!./${svg}.svg`).default; + const svgIconText = svg.includes("; } diff --git a/webpack.renderer.ts b/webpack.renderer.ts index 1c0da17313..5b125bfbcb 100755 --- a/webpack.renderer.ts +++ b/webpack.renderer.ts @@ -3,7 +3,6 @@ import path from "path"; import webpack from "webpack"; import HtmlWebpackPlugin from "html-webpack-plugin"; import MiniCssExtractPlugin from "mini-css-extract-plugin"; -import TerserPlugin from "terser-webpack-plugin"; import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; import ProgressBarPlugin from "progress-bar-webpack-plugin"; import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin"; @@ -59,20 +58,7 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura ] }, optimization: { - minimize: isProduction, - minimizer: [ - new TerserPlugin({ - cache: true, - parallel: true, - sourceMap: true, - extractComments: { - condition: "some", - banner: [ - `OpenLens - Open Source Kubernetes IDE. Copyright ${new Date().getFullYear()} OpenLens Authors` - ].join("\n") - } - }) - ], + minimize: false }, module: { diff --git a/yarn.lock b/yarn.lock index 206c497941..f1704da1c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -253,10 +253,10 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" - integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec" + integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA== dependencies: regenerator-runtime "^0.13.4" @@ -925,13 +925,6 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@npmcli/move-file@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" - integrity sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw== - dependencies: - mkdirp "^1.0.4" - "@panva/asn1.js@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6" @@ -1274,7 +1267,7 @@ resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.6.tgz#ed8fc802c45b8e8f54419c2d054e55c9ea344356" integrity sha512-GRTZLeLJ8ia00ZH8mxMO8t0aC9M1N9bN461Z2eaRurJo6Fpa+utgCwLzI4jQHcrdzuzp5WPN9jRwpsCQ1VhJ5w== -"@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -1558,6 +1551,11 @@ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== +"@types/randomcolor@^0.5.5": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@types/randomcolor/-/randomcolor-0.5.5.tgz#6d8af5f87c6bec1e338ae2d0739056cc2e5720fd" + integrity sha512-PywdYff3F8lGO3BggkCXaPFH0Ue/2Y7xliihoQNkxCGPJ4w7VTMfgcmSMIE6gOVAEu9Wx42JRSuRREVG3AUrtg== + "@types/range-parser@*": version "1.2.3" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" @@ -1584,6 +1582,16 @@ dependencies: "@types/react" "*" +"@types/react-redux@^7.1.16": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react-router-dom@^5.1.6": version "5.1.6" resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.6.tgz#07b14e7ab1893a837c8565634960dc398564b1fb" @@ -1754,14 +1762,6 @@ dependencies: tempy "*" -"@types/terser-webpack-plugin@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/terser-webpack-plugin/-/terser-webpack-plugin-3.0.0.tgz#8c5781922ce60611037b28186baf192e28780a03" - integrity sha512-K5C7izOT8rR4qiE2vfXcQNEJN4lT9cq/2qJgpMUWR2HsjDW/KVrHx2CaHuaXvaqDNsRmdELPLaxeJHiI4GjVrA== - dependencies: - "@types/webpack" "*" - terser "^4.6.13" - "@types/testing-library__jest-dom@^5.9.1": version "5.9.5" resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.5.tgz#5bf25c91ad2d7b38f264b12275e5c92a66d849b0" @@ -3281,29 +3281,6 @@ cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3: unique-filename "^1.1.1" y18n "^4.0.0" -cacache@^15.0.4: - version "15.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.4.tgz#b2c23cf4ac4f5ead004fb15a0efb0a20340741f1" - integrity sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw== - dependencies: - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^5.1.1" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.0" - tar "^6.0.2" - unique-filename "^1.1.1" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -5934,15 +5911,6 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - find-npm-prefix@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" @@ -6568,7 +6536,7 @@ graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2 resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= -grapheme-splitter@^1.0.2: +grapheme-splitter@^1.0.2, grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== @@ -9069,7 +9037,7 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -9402,27 +9370,6 @@ minimist@~0.0.1: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz#55f7839307d74859d6e8ada9c3ebe72cec216a34" - integrity sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ== - dependencies: - minipass "^3.0.0" - minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" @@ -9431,7 +9378,7 @@ minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: safe-buffer "^5.1.2" yallist "^3.0.0" -minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0: version "3.1.3" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== @@ -9445,14 +9392,6 @@ minizlib@^1.2.1: dependencies: minipass "^2.9.0" -minizlib@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" - integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -9490,7 +9429,7 @@ mkdirp-classic@^0.5.2: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@1.x, mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -10605,7 +10544,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== @@ -10645,13 +10584,6 @@ p-map@^2.0.0: resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-retry@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" @@ -11016,7 +10948,7 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -11481,6 +11413,11 @@ randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +randomcolor@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/randomcolor/-/randomcolor-0.6.2.tgz#7a57362ae1a1278439aeed2c15e5deb8ea33f56d" + integrity sha512-Mn6TbyYpFgwFuQ8KJKqf3bqqY9O1y37/0jgSK/61PUxV4QfIMv0+K2ioq8DfOjkBslcjwSzRfIDEXfzA9aCx7A== + randomfill@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" @@ -11522,16 +11459,16 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-beautiful-dnd@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz#f70cc8ff82b84bc718f8af157c9f95757a6c3b40" - integrity sha512-87It8sN0ineoC3nBW0SbQuTFXM6bUqM62uJGY4BtTf0yzPl8/3+bHMWkgIe0Z6m8e+gJgjWxefGRVfpE3VcdEg== +react-beautiful-dnd@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz#ec97c81093593526454b0de69852ae433783844d" + integrity sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA== dependencies: - "@babel/runtime" "^7.8.4" + "@babel/runtime" "^7.9.2" css-box-model "^1.2.0" memoize-one "^5.1.1" raf-schd "^4.0.2" - react-redux "^7.1.1" + react-redux "^7.2.0" redux "^4.0.4" use-memo-one "^1.1.1" @@ -11551,7 +11488,7 @@ react-input-autosize@^2.2.2: dependencies: prop-types "^15.5.8" -react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -11561,16 +11498,17 @@ react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-i resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== -react-redux@^7.1.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985" - integrity sha512-T+VfD/bvgGTUA74iW9d2i5THrDQWbweXP0AVNI8tNd1Rk5ch1rnMiJkDD67ejw7YBKM4+REvcvqRuWJb7BLuEg== +react-redux@^7.2.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.3.tgz#4c084618600bb199012687da9e42123cca3f0be9" + integrity sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w== dependencies: - "@babel/runtime" "^7.5.5" - hoist-non-react-statics "^3.3.0" + "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" + hoist-non-react-statics "^3.3.2" loose-envify "^1.4.0" prop-types "^15.7.2" - react-is "^16.9.0" + react-is "^16.13.1" react-refresh@^0.9.0: version "0.9.0" @@ -11875,7 +11813,7 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -redux@^4.0.4: +redux@^4.0.0, redux@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== @@ -12948,13 +12886,6 @@ ssri@^6.0.0, ssri@^6.0.1: dependencies: figgy-pudding "^3.5.1" -ssri@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" - integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== - dependencies: - minipass "^3.1.1" - stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" @@ -13417,18 +13348,6 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13: safe-buffer "^5.1.2" yallist "^3.0.3" -tar@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39" - integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.0" - mkdirp "^1.0.3" - yallist "^4.0.0" - tar@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" @@ -13507,22 +13426,7 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.0.3.tgz#23bda2687b197f878a743373b9411d917adc2e45" - integrity sha512-bZFnotuIKq5Rqzrs+qIwFzGdKdffV9epG5vDSEbYzvKAhPeR5RbbrQysfPgbIIMhNAQtZD2hGwBfSKUXjXZZZw== - dependencies: - cacache "^15.0.4" - find-cache-dir "^3.3.1" - jest-worker "^26.0.0" - p-limit "^2.3.0" - schema-utils "^2.6.6" - serialize-javascript "^3.1.0" - source-map "^0.6.1" - terser "^4.6.13" - webpack-sources "^1.4.3" - -terser@^4.1.2, terser@^4.6.13, terser@^4.6.3: +terser@^4.1.2, terser@^4.6.3: version "4.7.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.7.0.tgz#15852cf1a08e3256a80428e865a2fa893ffba006" integrity sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw== @@ -13858,11 +13762,6 @@ type-fest@^0.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== -type-fest@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.0.tgz#2edfa6382d48653707344f7fccdb0443d460e8d6" - integrity sha512-fbDukFPnJBdn2eZ3RR+5mK2slHLFd6gYHY7jna1KWWy4Yr4XysHuCdXRzy+RiG/HwG4WJat00vdC2UHky5eKiQ== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -13878,6 +13777,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.0.2.tgz#3f9c39982859f385c77c38b7e5f1432b8a3661c6" + integrity sha512-a720oz3Kjbp3ll0zkeN9qjRhO7I34MKMhPGQiQJAmaZQZQ1lo+NWThK322f7sXV+kTg9B1Ybt16KgBXWgteT8w== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -14519,7 +14423,7 @@ webpack-node-externals@^1.7.2: resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== -webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==