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,26 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
.Dialog {
position: fixed;
overflow: auto;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding: $unit * 5;
z-index: $zIndex-dialog;
overscroll-behavior: none; // prevent swiping with touch-pad on MacOSX
overflow: auto;
&.modal {
background: transparentize(#222, .5);
}
h5 {
color: white;
}
}
@@ -0,0 +1,187 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./dialog.scss";
import React from "react";
import { createPortal } from "react-dom";
import { disposeOnUnmount, observer } from "mobx-react";
import { reaction } from "mobx";
import { Animate } from "../animate";
import { cssNames, noop, stopPropagation } from "../../utils";
import type { ObservableHistory } from "mobx-observable-history";
import { withInjectables } from "@ogre-tools/injectable-react";
import observableHistoryInjectable from "../../navigation/observable-history.injectable";
import requestAnimationFrameInjectable from "../animate/request-animation-frame.injectable";
// todo: refactor + handle animation-end in props.onClose()?
export interface DialogProps {
className?: string;
isOpen?: boolean;
open?: () => void;
close?: () => void;
onOpen?: () => void;
onClose?: () => void;
modal?: boolean;
pinned?: boolean;
animated?: boolean;
"data-testid"?: string;
children?: React.ReactNode | React.ReactNode[];
}
interface DialogState {
isOpen: boolean;
}
interface Dependencies {
navigation: ObservableHistory<unknown>;
requestAnimationFrame: (callback: () => void) => void;
}
@observer
class NonInjectedDialog extends React.PureComponent<DialogProps & Dependencies & typeof NonInjectedDialog.defaultProps, DialogState> {
private readonly contentElem = React.createRef<HTMLDivElement>();
private readonly ref = React.createRef<HTMLDivElement>();
static defaultProps = {
isOpen: false,
open: noop,
close: noop,
onOpen: noop,
onClose: noop,
modal: true,
animated: true,
pinned: false,
};
public state: DialogState = {
isOpen: this.props.isOpen ?? false,
};
get elem() {
return this.ref.current;
}
get isOpen() {
return this.state.isOpen;
}
componentDidMount() {
if (this.isOpen) {
this.onOpen();
}
disposeOnUnmount(this, [
reaction(() => this.props.navigation.toString(), () => this.close()),
]);
}
componentDidUpdate(prevProps: DialogProps) {
const { isOpen } = this.props;
if (isOpen !== prevProps.isOpen) {
this.toggle(isOpen ?? false);
}
}
componentWillUnmount() {
if (this.isOpen) this.onClose();
}
toggle(isOpen: boolean) {
if (isOpen) this.open();
else this.close();
}
open() {
this.props.requestAnimationFrame(this.onOpen); // wait for render(), bind close-event to this.elem
this.setState({ isOpen: true });
this.props.open?.();
}
close() {
this.onClose(); // must be first to get access to dialog's content from outside
this.setState({ isOpen: false });
this.props.close?.();
}
onOpen = () => {
this.props.onOpen?.();
if (!this.props.pinned) {
if (this.elem) this.elem.addEventListener("click", this.onClickOutside);
// Using document.body target to handle keydown event before Drawer does
document.body.addEventListener("keydown", this.onEscapeKey);
}
};
onClose = () => {
this.props.onClose?.();
if (!this.props.pinned) {
if (this.elem) this.elem.removeEventListener("click", this.onClickOutside);
document.body.removeEventListener("keydown", this.onEscapeKey);
}
};
onEscapeKey = (evt: KeyboardEvent) => {
const escapeKey = evt.code === "Escape";
if (escapeKey) {
this.close();
evt.stopPropagation();
}
};
onClickOutside = (evt: MouseEvent) => {
const target = evt.target as HTMLElement;
if (!this.contentElem.current?.contains(target)) {
this.close();
evt.stopPropagation();
}
};
render() {
const { modal, animated, pinned, "data-testid": testId, className } = this.props;
let dialog = (
<div
className={cssNames("Dialog flex center", className, { modal, pinned })}
onClick={stopPropagation}
ref={this.ref}
data-testid={testId}
>
<div
className="box"
ref={this.contentElem}
>
{this.props.children}
</div>
</div>
);
if (animated) {
dialog = (
<Animate enter={this.isOpen} name="opacity-scale">
{dialog}
</Animate>
);
} else if (!this.isOpen) {
return null;
}
return createPortal(dialog, document.body);
}
}
export const Dialog = withInjectables<Dependencies, DialogProps>((props) => <NonInjectedDialog {...props} />, {
getProps: (di, props) => ({
...props,
navigation: di.inject(observableHistoryInjectable),
requestAnimationFrame: di.inject(requestAnimationFrameInjectable),
}),
});
@@ -0,0 +1,6 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export * from "./dialog";
@@ -0,0 +1,20 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
.LogsDialog {
.Wizard {
--wizard-width: 70vw;
}
.WizardStep {
.step-content {
padding: var(--wizard-spacing);
}
code {
max-height: 50vh;
}
}
}
@@ -0,0 +1,81 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./logs-dialog.scss";
import React from "react";
import type { DialogProps } from "../dialog";
import { Dialog } from "../dialog";
import { Wizard, WizardStep } from "../wizard";
import type { ShowNotification } from "../notifications";
import { Button } from "../button";
import { Icon } from "../icon";
import { clipboard } from "electron";
import { kebabCase } from "lodash/fp";
import { withInjectables } from "@ogre-tools/injectable-react";
import showSuccessNotificationInjectable from "../notifications/show-success-notification.injectable";
export interface LogsDialogProps extends DialogProps {
title: string;
logs: string;
}
interface Dependencies {
showSuccessNotification: ShowNotification;
}
const NonInjectedLogsDialog = (props: LogsDialogProps & Dependencies) => {
const {
title,
logs,
showSuccessNotification,
...dialogProps
} = props;
return (
<Dialog
{...dialogProps}
className="LogsDialog"
data-testid={`logs-dialog-for-${kebabCase(title)}`}
>
<Wizard
header={<h5>{title}</h5>}
done={dialogProps.close}
>
<WizardStep
scrollable={false}
customButtons={(
<div className="buttons flex gaps align-center justify-space-between">
<Button
plain
onClick={() => {
clipboard.writeText(logs);
showSuccessNotification(`Logs copied to clipboard.`);
}}
>
<Icon material="assignment"/>
{" Copy to clipboard"}
</Button>
<Button plain onClick={dialogProps.close}>
Close
</Button>
</div>
)}
>
<code className="block">
{logs || "There are no logs available."}
</code>
</WizardStep>
</Wizard>
</Dialog>
);
};
export const LogsDialog = withInjectables<Dependencies, LogsDialogProps>(NonInjectedLogsDialog, {
getProps: (di, props) => ({
...props,
showSuccessNotification: di.inject(showSuccessNotificationInjectable),
}),
});