Extensions loading (#795)

Signed-off-by: Roman <ixrock@gmail.com>

Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com>
Co-authored-by: Lauri Nevala <lauri.nevala@gmail.com>
This commit is contained in:
authored and GitHub committed 2020-09-09 13:00:25 +03:00
1 parent 4250523fe4
commit f1b03990ea
31 files changed
+564 -66

No files matched your search

+2
View File
@@ -4,6 +4,7 @@ import { render } from "react-dom";
import { isMac } from "../common/vars";
import { userStore } from "../common/user-store";
import { workspaceStore } from "../common/workspace-store";
import { extensionStore } from "../extensions/extension-store";
import { clusterStore, getHostedClusterId } from "../common/cluster-store";
import { i18nStore } from "./i18n";
import { themeStore } from "./theme.store";
@@ -23,6 +24,7 @@ export async function bootstrap(App: AppComponent) {
userStore.load(),
workspaceStore.load(),
clusterStore.load(),
extensionStore.load(),
i18nStore.init(),
themeStore.init(),
]);
@@ -0,0 +1,11 @@
import { RouteProps } from "react-router";
import { buildURL } from "../../navigation";
export const extensionsRoute: RouteProps = {
path: "/extensions"
}
export interface IExtensionsRouteParams {
}
export const extensionsURL = buildURL<IExtensionsRouteParams>(extensionsRoute.path);
@@ -0,0 +1,4 @@
.Extensions {
$spacing: $padding * 2;
padding: $spacing;
}
@@ -0,0 +1,31 @@
import "./extensions.scss"
import React from "react";
import { observer } from "mobx-react";
import { extensionStore } from "../../../extensions/extension-store";
import { WizardLayout } from "../layout/wizard-layout";
import { Icon } from "../icon";
@observer
export class Extensions extends React.Component {
// todo: add input-select to customize extensions loading folder(s)
renderInfoPanel() {
return (
<div className="info-panel flex gaps align-center">
<Icon material="info"/>
<p>Extensions available to install</p>
</div>
);
}
render() {
const { installed: installedExtensions } = extensionStore;
return (
<WizardLayout className="Extensions" infoPanel={this.renderInfoPanel()}>
<h2>Extensions</h2>
<pre>
{JSON.stringify(installedExtensions.toJSON(), null, 2)}
</pre>
</WizardLayout>
);
}
}
@@ -0,0 +1,2 @@
export * from "./extensions.route"
export * from "./extensions"
@@ -4,7 +4,6 @@
position: relative;
border-radius: $radius;
padding: $radius;
margin-bottom: $padding * 2;
user-select: none;
cursor: pointer;
@@ -11,6 +11,7 @@ import { Workspaces, workspacesRoute } from "../+workspaces";
import { AddCluster, addClusterRoute } from "../+add-cluster";
import { ClusterView } from "./cluster-view";
import { ClusterSettings, clusterSettingsRoute } from "../+cluster-settings";
import { Extensions, extensionsRoute } from "../+extensions";
import { clusterViewRoute, clusterViewURL, getMatchedCluster, getMatchedClusterId } from "./cluster-view.route";
import { clusterStore } from "../../../common/cluster-store";
import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views";
@@ -60,6 +61,7 @@ export class ClusterManager extends React.Component {
<Route component={AddCluster} {...addClusterRoute}/>
<Route component={ClusterView} {...clusterViewRoute}/>
<Route component={ClusterSettings} {...clusterSettingsRoute}/>
<Route component={Extensions} {...extensionsRoute}/>
<Redirect exact to={this.startUrl}/>
</Switch>
</main>
@@ -16,10 +16,10 @@
.clusters {
@include hidden-scrollbar;
padding: 0 $spacing; // extra spacing for cluster-icon's badge
margin-bottom: $spacing;
margin-bottom: $margin;
> :last-child {
margin-bottom: $margin;
.ClusterIcon {
margin-bottom: $margin * 1.5;
}
&:empty {
@@ -67,4 +67,14 @@
pointer-events: none;
}
}
> .dynamic-pages {
&:not(:empty) {
padding-top: $spacing;
}
.Icon {
--size: 40px;
}
}
}
@@ -21,8 +21,7 @@ import { ConfirmDialog } from "../confirm-dialog";
import { clusterIpc } from "../../../common/cluster-ipc";
import { clusterViewURL, getMatchedClusterId } from "./cluster-view.route";
import { DragDropContext, Droppable, Draggable, DropResult, DroppableProvided, DraggableProvided } from "react-beautiful-dnd";
// fixme: allow to rearrange clusters with drag&drop
import { dynamicPages } from "./register-page";
interface Props {
className?: IClassName;
@@ -149,6 +148,12 @@ export class ClustersMenu extends React.Component<Props> {
<Badge className="counter" label={newContexts.size} tooltip={<Trans>new</Trans>} />
)}
</div>
<div className="dynamic-pages">
{Array.from(dynamicPages.all).map(([path, { MenuIcon }]) => {
if (!MenuIcon) return;
return <MenuIcon onClick={() => navigate(path)}/>
})}
</div>
</div>
);
}
@@ -0,0 +1,28 @@
// Dynamic pages
import React from "react";
import { observable } from "mobx";
import type { IconProps } from "../icon";
export interface PageComponents {
Main: React.ComponentType<any>;
MenuIcon: React.ComponentType<IconProps>;
}
export class PagesStore {
all = observable.map<string, PageComponents>();
getComponents(path: string): PageComponents | null {
return this.all.get(path);
}
register(path: string, components: PageComponents) {
this.all.set(path, components);
}
unregister(path: string) {
this.all.delete(path);
}
}
export const dynamicPages = new PagesStore();
+6
View File
@@ -11,9 +11,15 @@ import { ErrorBoundary } from "./components/error-boundary";
import { WhatsNew, whatsNewRoute } from "./components/+whats-new";
import { Notifications } from "./components/notifications";
import { ConfirmDialog } from "./components/confirm-dialog";
import { extensionStore } from "../extensions/extension-store";
import { getLensRuntime } from "../extensions/lens-runtime";
@observer
export class LensApp extends React.Component {
componentDidMount() {
extensionStore.autoEnableOnLoad(getLensRuntime);
}
render() {
return (
<I18nProvider i18n={_i18n}>