-
HTTP Proxy server. Used for communicating with Kubernetes API.
-
this.proxyServer = value}
- theme="round-black"
- />
-
- {'A HTTP proxy server URL (format: http://:).'}
-
+
+
+ Add Cluster
+ {this.renderKubeConfigSource()}
+ {this.renderContextSelector()}
+
- )}
- {this.error && (
- {this.error}
- )}
-
-
-
+ {this.showSettings && (
+
+
HTTP Proxy server. Used for communicating with Kubernetes API.
+
this.proxyServer = value}
+ theme="round-black"
+ />
+
+ {'A HTTP proxy server URL (format: http://:).'}
+
+
+ )}
+ {this.error && (
+ {this.error}
+ )}
+
+
+
+
);
}
}
diff --git a/src/renderer/components/+extensions/extensions.tsx b/src/renderer/components/+extensions/extensions.tsx
index 14a22f7061..ffefee0fca 100644
--- a/src/renderer/components/+extensions/extensions.tsx
+++ b/src/renderer/components/+extensions/extensions.tsx
@@ -7,7 +7,7 @@ import { t, Trans } from "@lingui/macro";
import { _i18n } from "../../i18n";
import { Button } from "../button";
import { WizardLayout } from "../layout/wizard-layout";
-import { Input, InputValidators } from "../input";
+import { DropFileInput, Input, InputValidators } from "../input";
import { Icon } from "../icon";
import { PageLayout } from "../layout/page-layout";
import { CopyToClick } from "../copy-to-click/copy-to-click";
@@ -35,7 +35,7 @@ export class Extensions extends React.Component {
return extensionManager.localFolderPath;
}
- selectPackedExtensionsDialog = async () => {
+ selectLocalExtensionsDialog = async () => {
const { dialog, BrowserWindow, app } = remote;
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
defaultPath: app.getPath("downloads"),
@@ -51,15 +51,23 @@ export class Extensions extends React.Component {
}
}
+ // todo
installFromUrl = () => {
if (!this.downloadUrl) {
this.input?.focus();
return;
}
-
+ console.log('Install from URL', this.downloadUrl);
}
+ // todo
installFromLocalPath = (filePaths: string[]) => {
+ console.log('Install select from dialog', filePaths)
+ }
+
+ // todo
+ installOnDrop = (files: File[]) => {
+ console.log('Install from D&D', files);
}
renderInfo() {
@@ -104,7 +112,7 @@ export class Extensions extends React.Component {
Pro-Tip 1: you can download extension archive.tgz via npm by{" "}
@@ -163,19 +171,21 @@ export class Extensions extends React.Component {
render() {
return (
Extensions}>
-
- this.search = value}
- />
-
- {this.renderExtensions()}
-
-
+
+
+ this.search = value}
+ />
+
+ {this.renderExtensions()}
+
+
+
);
}
diff --git a/src/renderer/components/copy-to-click/copy-to-click.tsx b/src/renderer/components/copy-to-click/copy-to-click.tsx
index ba11941e9f..53b86e4247 100644
--- a/src/renderer/components/copy-to-click/copy-to-click.tsx
+++ b/src/renderer/components/copy-to-click/copy-to-click.tsx
@@ -47,9 +47,8 @@ export class CopyToClick extends React.Component {
try {
const rootElem = this.rootReactElem;
return React.cloneElement(rootElem, {
- ...(rootElem || {}).props,
onClick: this.onClick,
- })
+ });
} catch (err) {
logger.error(`Invalid usage components/CopyToClick usage. Children must contain root html element.`, { err: String(err) })
return this.rootReactElem;
diff --git a/src/renderer/components/input/drop-file-input.scss b/src/renderer/components/input/drop-file-input.scss
new file mode 100644
index 0000000000..3675d5b843
--- /dev/null
+++ b/src/renderer/components/input/drop-file-input.scss
@@ -0,0 +1,9 @@
+.DropFileInput {
+ &.droppable {
+ box-shadow: 0 0 0 5px $primary; // fixme: might not work sometimes
+
+ > * {
+ pointer-events: none;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/renderer/components/input/drop-file-input.tsx b/src/renderer/components/input/drop-file-input.tsx
new file mode 100644
index 0000000000..013401c25c
--- /dev/null
+++ b/src/renderer/components/input/drop-file-input.tsx
@@ -0,0 +1,76 @@
+import "./drop-file-input.scss"
+import React from "react"
+import { autobind, cssNames, IClassName } from "../../utils";
+import { observable } from "mobx";
+import { observer } from "mobx-react";
+import logger from "../../../main/logger";
+
+export interface DropFileInputProps extends React.DOMAttributes {
+ className?: IClassName;
+ disabled?: boolean;
+ onDropFiles(files: File[], meta: DropFileMeta): void;
+}
+
+export interface DropFileMeta {
+ evt: React.DragEvent;
+}
+
+@observer
+export class DropFileInput extends React.Component {
+ @observable dropAreaActive = false;
+
+ @autobind()
+ onDragEnter() {
+ this.dropAreaActive = true;
+ }
+
+ @autobind()
+ onDragLeave() {
+ this.dropAreaActive = false;
+ }
+
+ @autobind()
+ onDragOver(evt: React.DragEvent) {
+ if (this.props.onDragOver) {
+ this.props.onDragOver(evt);
+ }
+ evt.preventDefault(); // enable onDrop()-callback
+ evt.dataTransfer.dropEffect = "move";
+ }
+
+ @autobind()
+ onDrop(evt: React.DragEvent) {
+ if (this.props.onDrop) {
+ this.props.onDrop(evt);
+ }
+ this.dropAreaActive = false;
+ const files = Array.from(evt.dataTransfer.files);
+ if (files.length > 0) {
+ this.props.onDropFiles(files, { evt });
+ }
+ }
+
+ render() {
+ const { disabled, className } = this.props;
+ const { onDragEnter, onDragLeave, onDragOver, onDrop } = this;
+ try {
+ const contentElem = React.Children.only(this.props.children) as React.ReactElement>;
+ const isValidContentElem = React.isValidElement(contentElem);
+ if (!disabled && isValidContentElem) {
+ const contentElemProps: React.HTMLProps = {
+ className: cssNames("DropFileInput", className, {
+ droppable: this.dropAreaActive,
+ }),
+ onDragEnter: onDragEnter,
+ onDragLeave: onDragLeave,
+ onDragOver: onDragOver,
+ onDrop: onDrop,
+ };
+ return React.cloneElement(contentElem, contentElemProps);
+ }
+ } catch (err) {
+ logger.error("Invalid root content-element for DropFileInput", { err: String(err) })
+ return this.props.children;
+ }
+ }
+}
diff --git a/src/renderer/components/input/index.ts b/src/renderer/components/input/index.ts
index fc930e45d2..2e807d0be6 100644
--- a/src/renderer/components/input/index.ts
+++ b/src/renderer/components/input/index.ts
@@ -2,3 +2,4 @@ export * from './input';
export * from './search-input';
export * from './search-input-url';
export * from './file-input';
+export * from './drop-file-input';
diff --git a/src/renderer/components/layout/wizard-layout.tsx b/src/renderer/components/layout/wizard-layout.tsx
index cd911b62ca..712be9d886 100644
--- a/src/renderer/components/layout/wizard-layout.tsx
+++ b/src/renderer/components/layout/wizard-layout.tsx
@@ -11,7 +11,6 @@ export interface WizardLayoutProps extends React.DOMAttributes {
infoPanelClass?: IClassName;
infoPanel?: React.ReactNode;
centered?: boolean; // Centering content horizontally
- contentProps?: React.DOMAttributes
}
@observer
@@ -19,7 +18,7 @@ export class WizardLayout extends React.Component {
render() {
const {
className, contentClass, infoPanelClass, infoPanel, header, headerClass, centered,
- children, contentProps = {}, ...props
+ children, ...props
} = this.props;
return (
@@ -28,7 +27,7 @@ export class WizardLayout extends React.Component {
{header}
)}
-