Restructure to monorepo (#6907)

* wip: restructure to monorepo

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor create-release-pr to a package

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* build fixes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* github workflow fixes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix typo

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* add webpack-env types to core

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix github workflows

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor/fix integration tests

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* lint fix

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* yarn run dev

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* eslint settings for vscode

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* move templates to right package

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* open-lens build fixes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* integration test fix

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix nx task dependencies

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* use bash shell for unit tests in test workflow

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix test:unit for windows

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix win-ca webpack error in open-lens

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix win-ca webpack error in open-lens

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix build:app on windows

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* remove ELECTRON_BUILDER_EXTRA_ARGS

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* sync src/ from master

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* remove Makefile from core

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen authored and GitHub committed 2023-01-24 10:46:26 -08:00
1 parent 0066ca4ea2
commit 2657df2293
3321 files changed
+28699 -11447

No files matched your search

@@ -0,0 +1,18 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import type React from "react";
export interface StatusBarItem {
origin?: string;
component: React.ComponentType<any>;
position: "left" | "right";
visible: IComputedValue<boolean>;
}
export const statusBarItemInjectionToken = getInjectionToken<StatusBarItem>({
id: "status-bar-item",
});
@@ -0,0 +1,88 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { Injectable } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
import type { IComputedValue } from "mobx";
import { computed } from "mobx";
import { extensionRegistratorInjectionToken } from "../../../extensions/extension-loader/extension-registrator-injection-token";
import type { LensRendererExtension } from "../../../extensions/lens-renderer-extension";
import type { StatusBarItem } from "./status-bar-item-injection-token";
import { statusBarItemInjectionToken } from "./status-bar-item-injection-token";
import type { StatusBarRegistration } from "./status-bar-registration";
import React from "react";
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
import loggerInjectable from "../../../common/logger.injectable";
import type { Logger } from "../../../common/logger";
const statusBarItemRegistratorInjectable = getInjectable({
id: "status-bar-item-registrator",
instantiate: (di) => (extension) => {
const rendererExtension = extension as LensRendererExtension;
const getRandomId = di.inject(getRandomIdInjectable);
const logger = di.inject(loggerInjectable);
return rendererExtension.statusBarItems.flatMap(
toItemInjectableFor(rendererExtension, getRandomId, logger),
);
},
injectionToken: extensionRegistratorInjectionToken,
});
export default statusBarItemRegistratorInjectable;
const toItemInjectableFor = (extension: LensRendererExtension, getRandomId: () => string, logger: Logger) => {
return (registration: StatusBarRegistration): Injectable<StatusBarItem, StatusBarItem, void>[] => {
const id = `${getRandomId()}-status-bar-item-for-extension-${extension.sanitizedExtensionId}`;
let component: React.ComponentType;
let position: "left" | "right";
const visible: IComputedValue<boolean> | undefined = registration?.visible;
if (registration?.item) {
const { item } = registration;
position = "right";
component =
() => (
<>
{
typeof item === "function"
? item()
: item
}
</>
);
} else if (registration?.components) {
const { position: pos = "right", Item } = registration.components;
if (pos !== "left" && pos !== "right") {
throw new TypeError("StatusBarRegistration.components.position must be either 'right' or 'left'");
}
position = pos;
component = Item;
} else {
logger.warn("StatusBarRegistration must have valid item or components field");
return [];
}
return [getInjectable({
id,
instantiate: () => ({
origin: extension.sanitizedExtensionId,
component,
position,
visible: visible ?? computed(() => true),
}),
injectionToken: statusBarItemInjectionToken,
})];
};
};
@@ -0,0 +1,69 @@
/**
* 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 type { IComputedValue } from "mobx";
import { computed } from "mobx";
import type { StatusBarItemProps } from "./status-bar-registration";
import type { StatusBarItem } from "./status-bar-item-injection-token";
import { statusBarItemInjectionToken } from "./status-bar-item-injection-token";
import { computedInjectManyInjectable } from "@ogre-tools/injectable-extension-for-mobx";
interface StatusItem {
origin?: string;
component: React.ComponentType<StatusBarItemProps>;
}
export interface StatusBarItems {
right: StatusItem[];
left: StatusItem[];
}
interface Dependencies {
registrations: IComputedValue<StatusBarItem[]>;
}
function getStatusBarItems({ registrations }: Dependencies): IComputedValue<StatusBarItems> {
return computed(() => {
const res: StatusBarItems = {
left: [],
right: [],
};
for (const registration of registrations.get()) {
const { position = "right", component, visible, origin } = registration;
if (!visible.get()) {
continue;
}
res[position].push({
origin,
component,
});
}
// This is done so that the first ones registered are closest to the corner
res.right.reverse();
return res;
});
}
const statusBarItemsInjectable = getInjectable({
id: "status-bar-items",
instantiate: (di) => {
const computedInjectMany = di.inject(
computedInjectManyInjectable,
);
return getStatusBarItems({
registrations: computedInjectMany(statusBarItemInjectionToken),
});
},
});
export default statusBarItemsInjectable;
@@ -0,0 +1,48 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { IComputedValue } from "mobx";
/**
* The props for StatusBar item component
*/
export interface StatusBarItemProps {}
/**
* The type defining the registration of a status bar item
*/
export interface StatusBarComponents {
/**
* The component for this registrations
*/
Item: React.ComponentType<StatusBarItemProps>;
/**
* The side of the bottom bar to place this component.
*
* @default "right"
*/
position?: "left" | "right";
}
/**
* The type for registering status bar items from the LensRendererExtension
*/
export interface StatusBarRegistration {
/**
* @deprecated use {@link StatusBarRegistration.components} instead
*/
item?: React.ReactNode | (() => React.ReactNode);
/**
* The newer API, allows for registering a component instead of a ReactNode
*/
components?: StatusBarComponents;
/**
* If specified, controls item visibility
*/
visible?: IComputedValue<boolean>;
}
@@ -0,0 +1,42 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
.StatusBar {
--status-bar-height: 21px;
color: white;
grid-area: status-bar;
background-color: var(--blue);
height: var(--status-bar-height);
font-size: var(--font-size-small);
display: inline-grid;
grid-template-columns: 1fr 1fr;
}
.leftSide {
display: flex;
align-items: center;
padding-inline-start: calc(var(--padding) / 2);
}
.rightSide {
display: flex;
align-items: center;
justify-content: flex-end;
padding-inline-end: calc(var(--padding) / 2);
}
.item {
height: 100%;
padding-inline: var(--padding);
display: flex;
align-items: center;
&:hover {
cursor: pointer;
background-color: #ffffff33;
}
}
@@ -0,0 +1,125 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import "@testing-library/jest-dom/extend-expect";
import type { IObservableArray } from "mobx";
import { computed, observable } from "mobx";
import type { StatusBarItems } from "./status-bar-items.injectable";
import statusBarItemsInjectable from "./status-bar-items.injectable";
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import type { ApplicationBuilder } from "../test-utils/get-application-builder";
import { getApplicationBuilder } from "../test-utils/get-application-builder";
import getRandomIdInjectable from "../../../common/utils/get-random-id.injectable";
describe("<StatusBar />", () => {
let statusBarItems: IObservableArray<any>;
let builder: ApplicationBuilder;
beforeEach(async () => {
statusBarItems = observable.array([]);
builder = getApplicationBuilder();
builder.beforeWindowStart((windowDi) => {
windowDi.unoverride(getRandomIdInjectable);
windowDi.permitSideEffects(getRandomIdInjectable);
windowDi.override(directoryForUserDataInjectable, () => "some-directory-for-user-data");
});
builder.extensions.enable({
id: "some-id",
name: "some-name",
rendererOptions: {
statusBarItems,
},
});
});
it("renders w/o errors", async () => {
const { container } = await builder.render();
expect(container).toBeInstanceOf(HTMLElement);
});
it.each([
undefined,
"hello",
6,
null,
[],
[{}],
{},
])("renders w/o errors when registrations are not type compliant (%p)", async val => {
statusBarItems.replace([val]);
await expect(builder.render()).resolves.toBeTruthy();
});
it("renders items [{item: React.ReactNode}] (4.0.0-rc.1)", async () => {
const testId = "testId";
const text = "heee";
builder.beforeWindowStart((windowDi) => {
windowDi.override(statusBarItemsInjectable, () => computed(() => ({
right: [ { origin: testId, component: () => <span data-testid={testId} >{text}</span> }],
left: [],
}) as StatusBarItems));
});
const { getByTestId } = await builder.render();
expect(getByTestId(testId)).toHaveTextContent(text);
});
it("renders items [{item: () => React.ReactNode}] (4.0.0-rc.1+)", async () => {
const testId = "testId";
const text = "heee";
statusBarItems.replace([{
item: () => <span data-testid={testId} >{text}</span>,
}]);
const { getByTestId } = await builder.render();
expect(getByTestId(testId)).toHaveTextContent(text);
});
it("sort positioned items properly", async () => {
statusBarItems.replace([
{
components: {
Item: () => <div data-testid="sortedElem">right1</div>,
},
},
{
components: {
Item: () => <div data-testid="sortedElem">right2</div>,
position: "right",
},
},
{
components: {
Item: () => <div data-testid="sortedElem">left1</div>,
position: "left",
},
},
{
components: {
Item: () => <div data-testid="sortedElem">left2</div>,
position: "left",
},
},
]);
const { getAllByTestId } = await builder.render();
const elems = getAllByTestId("sortedElem");
const positions = elems.map(elem => elem.textContent);
expect(positions).toEqual(["left1", "left2", "right2", "right1"]);
});
});
@@ -0,0 +1,56 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import styles from "./status-bar.module.scss";
import React from "react";
import { observer } from "mobx-react";
import { withInjectables } from "@ogre-tools/injectable-react";
import type { StatusBarItems } from "./status-bar-items.injectable";
import statusBarItemsInjectable from "./status-bar-items.injectable";
import type { IComputedValue } from "mobx";
export interface StatusBarProps {}
interface Dependencies {
items: IComputedValue<StatusBarItems>;
}
const NonInjectedStatusBar = observer(({ items }: Dependencies & StatusBarProps) => {
const { left, right } = items.get();
return (
<div className={styles.StatusBar} data-testid="status-bar">
<div className={styles.leftSide} data-testid="status-bar-left">
{left.map((Item, index) => (
<div
className={styles.item}
key={index}
data-origin={Item.origin}>
{<Item.component/>}
</div>
))}
</div>
<div className={styles.rightSide} data-testid="status-bar-right">
{right.map((Item, index) => (
<div
className={styles.item}
key={index}
data-origin={Item.origin}>
{<Item.component/>}
</div>
))}
</div>
</div>
);
});
export const StatusBar = withInjectables<Dependencies, StatusBarProps>(NonInjectedStatusBar, {
getProps: (di, props) => ({
items: di.inject(statusBarItemsInjectable),
...props,
}),
});