1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Release/v5.4.4 (#5099)

* Emit AppEvent when opening Catalog and changing Catalog Category (#5071)

* Emit AppEvent when opening Catalog and changing Catalog Category.

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>

* Add getName method to CatalogCategory

Signed-off-by: Panu Horsmalahti <phorsmalahti@mirantis.com>

* Fix winston logger missing splat format (#5070)

* Fix KubeJsonApi.forCluster throwing on renderer (#5034)

* test relied on typing of newer version of ogre-tools

Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>

* release v5.4.4

Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>

Co-authored-by: Panu Horsmalahti <phorsmalahti@mirantis.com>
Co-authored-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Jim Ehrismann 2022-03-24 19:02:31 -04:00 committed by GitHub
parent 87e870b5b9
commit adcf87e939
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 179 additions and 65 deletions

View File

@ -3,7 +3,7 @@
"productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes",
"homepage": "https://github.com/lensapp/lens",
"version": "5.4.3",
"version": "5.4.4",
"main": "static/build/main.js",
"copyright": "© 2021 OpenLens Authors",
"license": "MIT",

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { CatalogCategory, CatalogCategorySpec } from "../catalog";
class TestCatalogCategory extends CatalogCategory {
public readonly apiVersion = "catalog.k8slens.dev/v1alpha1";
public readonly kind = "CatalogCategory";
public metadata = {
name: "Test Category",
icon: "",
};
public spec: CatalogCategorySpec = {
group: "entity.k8slens.dev",
versions: [],
names: {
kind: "Test",
},
};
}
describe("CatalogCategory", () => {
it("returns name", () => {
const category = new TestCatalogCategory();
expect(category.getName()).toEqual("Test Category");
});
});

View File

@ -173,6 +173,13 @@ export abstract class CatalogCategory extends (EventEmitter as new () => TypedEm
return `${this.spec.group}/${this.spec.names.kind}`;
}
/**
* Get the name of this category
*/
public getName(): string {
return this.metadata.name;
}
/**
* Add a filter for menu items of catalogAddMenu
* @param fn The function that should return a truthy value if that menu item should be displayed

View File

@ -0,0 +1,40 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { JsonApi } from "./json-api";
import { apiPrefix, isDebugging, isDevelopment } from "../vars";
import { appEventBus } from "../app-event-bus/event-bus";
export let apiBase: JsonApi;
if (typeof window === "undefined") {
appEventBus.addListener((event) => {
if (event.name !== "lens-proxy" && event.action !== "listen") return;
const params = event.params as { port?: number };
if (!params.port) return;
apiBase = new JsonApi({
serverAddress: `http://127.0.0.1:${params.port}`,
apiBase: apiPrefix,
debug: isDevelopment || isDebugging,
}, {
headers: {
"Host": `localhost:${params.port}`,
},
});
});
} else {
apiBase = new JsonApi({
serverAddress: `http://127.0.0.1:${window.location.port}`,
apiBase: apiPrefix,
debug: isDevelopment || isDebugging,
}, {
headers: {
"Host": window.location.host,
},
});
}

View File

@ -0,0 +1,20 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { isClusterPageContext } from "../utils";
import { KubeJsonApi } from "./kube-json-api";
import { apiKubePrefix, isDevelopment } from "../vars";
export const apiKube = isClusterPageContext()
? new KubeJsonApi({
serverAddress: `http://127.0.0.1:${window.location.port}`,
apiBase: apiKubePrefix,
debug: isDevelopment,
}, {
headers: {
"Host": window.location.host,
},
})
: undefined;

View File

@ -3,58 +3,5 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { JsonApi } from "./json-api";
import { KubeJsonApi } from "./kube-json-api";
import { apiKubePrefix, apiPrefix, isDebugging, isDevelopment } from "../../common/vars";
import { isClusterPageContext } from "../utils/cluster-id-url-parsing";
import { appEventBus } from "../app-event-bus/event-bus";
let apiBase: JsonApi;
let apiKube: KubeJsonApi;
if (typeof window === "undefined") {
appEventBus.addListener((event) => {
if (event.name !== "lens-proxy" && event.action !== "listen") return;
const params = event.params as { port?: number };
if (!params.port) return;
apiBase = new JsonApi({
serverAddress: `http://127.0.0.1:${params.port}`,
apiBase: apiPrefix,
debug: isDevelopment || isDebugging,
}, {
headers: {
"Host": `localhost:${params.port}`,
},
});
});
} else {
apiBase = new JsonApi({
serverAddress: `http://127.0.0.1:${window.location.port}`,
apiBase: apiPrefix,
debug: isDevelopment || isDebugging,
}, {
headers: {
"Host": window.location.host,
},
});
}
if (isClusterPageContext()) {
apiKube = new KubeJsonApi({
serverAddress: `http://127.0.0.1:${window.location.port}`,
apiBase: apiKubePrefix,
debug: isDevelopment,
}, {
headers: {
"Host": window.location.host,
},
});
}
export {
apiBase,
apiKube,
};
export { apiBase } from "./api-base";
export { apiKube } from "./api-kube";

View File

@ -5,8 +5,8 @@
import { JsonApi, JsonApiData, JsonApiError } from "./json-api";
import type { Response } from "node-fetch";
import { LensProxy } from "../../main/lens-proxy";
import { apiKubePrefix, isDebugging } from "../vars";
import { apiBase } from "./api-base";
export interface KubeJsonApiListMetadata {
resourceVersion: string;
@ -57,15 +57,15 @@ export interface KubeJsonApiError extends JsonApiError {
export class KubeJsonApi extends JsonApi<KubeJsonApiData> {
static forCluster(clusterId: string): KubeJsonApi {
const port = LensProxy.getInstance().port;
const url = new URL(apiBase.config.serverAddress);
return new this({
serverAddress: `http://127.0.0.1:${port}`,
serverAddress: apiBase.config.serverAddress,
apiBase: apiKubePrefix,
debug: isDebugging,
}, {
headers: {
"Host": `${clusterId}.localhost:${port}`,
"Host": `${clusterId}.localhost:${url.port}`,
},
});
}

View File

@ -65,6 +65,9 @@ if (ipcMain) {
}
export default winston.createLogger({
format: format.simple(),
format: format.combine(
format.splat(),
format.simple(),
),
transports,
});

View File

@ -20,6 +20,7 @@ jest.mock("winston", () => ({
label: jest.fn(),
timestamp: jest.fn(),
printf: jest.fn(),
splat: jest.fn(),
},
createLogger: jest.fn().mockReturnValue(logger),
transports: {

View File

@ -15,6 +15,7 @@ jest.mock("winston", () => ({
printf: jest.fn(),
padLevels: jest.fn(),
ms: jest.fn(),
splat: jest.fn(),
},
createLogger: jest.fn().mockReturnValue({
silly: jest.fn(),

View File

@ -21,6 +21,7 @@ jest.mock("winston", () => ({
padLevels: jest.fn(),
ms: jest.fn(),
printf: jest.fn(),
splat: jest.fn(),
},
createLogger: jest.fn().mockReturnValue(logger),
transports: {

View File

@ -52,10 +52,10 @@ function handleAutoUpdateBackChannel(event: Electron.IpcMainEvent, ...[arg]: Upd
}
autoUpdater.logger = {
info: message => logger.info(`[AUTO-UPDATE]: electron-updater:`, message),
warn: message => logger.warn(`[AUTO-UPDATE]: electron-updater:`, message),
error: message => logger.error(`[AUTO-UPDATE]: electron-updater:`, message),
debug: message => logger.debug(`[AUTO-UPDATE]: electron-updater:`, message),
info: message => logger.info(`[AUTO-UPDATE]: electron-updater: %s`, message),
warn: message => logger.warn(`[AUTO-UPDATE]: electron-updater: %s`, message),
error: message => logger.error(`[AUTO-UPDATE]: electron-updater: %s`, message),
debug: message => logger.debug(`[AUTO-UPDATE]: electron-updater: %s`, message),
};
/**

View File

@ -25,6 +25,9 @@ import { UserStore } from "../../../common/user-store";
import mockFs from "mock-fs";
import directoryForUserDataInjectable
from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import type { AppEvent } from "../../../common/app-event-bus/event-bus";
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
import { EventEmitter } from "../../../common/event-emitter";
mockWindow();
jest.mock("electron", () => ({
@ -98,6 +101,7 @@ describe("<Catalog />", () => {
let di: DependencyInjectionContainer;
let catalogEntityStore: CatalogEntityStore;
let catalogEntityRegistry: CatalogEntityRegistry;
let emitEvent: (event: AppEvent) => void;
let render: DiRender;
beforeEach(async () => {
@ -121,6 +125,14 @@ describe("<Catalog />", () => {
di.override(catalogEntityRegistryInjectable, () => catalogEntityRegistry);
emitEvent = jest.fn();
const source = new EventEmitter();
source.emit = emitEvent;
di.override(appEventBusInjectable, () => source);
catalogEntityStore = di.inject(catalogEntityStoreInjectable);
});
@ -316,4 +328,39 @@ describe("<Catalog />", () => {
userEvent.click(screen.getByTestId("detail-panel-hot-bar-icon"));
});
it("emits catalog open AppEvent", () => {
render(
<Catalog
history={history}
location={mockLocation}
match={mockMatch}
/>,
);
expect(emitEvent).toHaveBeenCalledWith( {
action: "open",
name: "catalog",
});
});
it("emits catalog change AppEvent when changing the category", () => {
render(
<Catalog
history={history}
location={mockLocation}
match={mockMatch}
/>,
);
userEvent.click(screen.getByText("Web Links"));
expect(emitEvent).toHaveBeenLastCalledWith({
action: "change-category",
name: "catalog",
params: {
category: "Web Links",
},
});
});
});

View File

@ -36,6 +36,8 @@ import getCategoryColumnsInjectable from "./get-category-columns.injectable";
import type { RegisteredCustomCategoryViewDecl } from "./custom-views.injectable";
import customCategoryViewsInjectable from "./custom-views.injectable";
import type { CustomCategoryViewComponents } from "./custom-views";
import type { AppEvent } from "../../../common/app-event-bus/event-bus";
import appEventBusInjectable from "../../../common/app-event-bus/app-event-bus.injectable";
interface Props extends RouteComponentProps<CatalogViewRouteParam> {}
@ -44,6 +46,7 @@ interface Dependencies {
catalogEntityStore: CatalogEntityStore;
getCategoryColumns: (params: GetCategoryColumnsParams) => CategoryColumns;
customCategoryViews: IComputedValue<Map<string, Map<string, RegisteredCustomCategoryViewDecl>>>;
emitEvent: (event: AppEvent) => void;
}
@observer
@ -104,6 +107,11 @@ class NonInjectedCatalog extends React.Component<Props & Dependencies> {
});
}
}));
this.props.emitEvent({
name: "catalog",
action: "open",
});
}
addToHotbar(entity: CatalogEntity): void {
@ -146,6 +154,14 @@ class NonInjectedCatalog extends React.Component<Props & Dependencies> {
onTabChange = action((tabId: string | null) => {
const activeCategory = this.categories.find(category => category.getId() === tabId);
this.props.emitEvent({
name: "catalog",
action: "change-category",
params: {
category: activeCategory ? activeCategory.getName() : "Browse",
},
});
if (activeCategory) {
navigate(catalogURL({ params: { group: activeCategory.spec.group, kind: activeCategory.spec.names.kind }}));
} else {
@ -311,6 +327,7 @@ export const Catalog = withInjectables<Dependencies, Props>( NonInjectedCatalog,
catalogPreviousActiveTabStorage: di.inject(catalogPreviousActiveTabStorageInjectable),
getCategoryColumns: di.inject(getCategoryColumnsInjectable),
customCategoryViews: di.inject(customCategoryViewsInjectable),
emitEvent: di.inject(appEventBusInjectable).emit,
...props,
}),
});