mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
workspaces: extract bottom-bar to separated component
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
507e2dcfee
commit
ba4f5cb47d
@ -1,4 +1,4 @@
|
|||||||
import { action, observable, toJS } from "mobx";
|
import { action, computed, observable, toJS } from "mobx";
|
||||||
import { v4 as uuid } from "uuid"
|
import { v4 as uuid } from "uuid"
|
||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import { Cluster } from "../main/cluster";
|
import { Cluster } from "../main/cluster";
|
||||||
@ -38,10 +38,6 @@ export interface ClusterPreferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
||||||
@observable activeCluster: ClusterId;
|
|
||||||
@observable clusters = observable.map<ClusterId, Cluster>();
|
|
||||||
@observable removedClusters = observable.map<ClusterId, Cluster>();
|
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
super({
|
super({
|
||||||
configName: "lens-cluster-store",
|
configName: "lens-cluster-store",
|
||||||
@ -52,14 +48,20 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@observable activeCluster: ClusterId;
|
||||||
|
@observable removedClusters = observable.map<ClusterId, Cluster>();
|
||||||
|
@observable clusters = observable.map<ClusterId, Cluster>();
|
||||||
|
|
||||||
|
@computed get clustersList() {
|
||||||
|
return Array.from(this.clusters.values());
|
||||||
|
}
|
||||||
|
|
||||||
getById(id: ClusterId): Cluster {
|
getById(id: ClusterId): Cluster {
|
||||||
return this.clusters.get(id);
|
return this.clusters.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
getByWorkspaceId(workspaceId: string): Cluster[] {
|
getByWorkspaceId(workspaceId: string): Cluster[] {
|
||||||
return Array.from(this.clusters.values()).filter(cluster => {
|
return this.clustersList.filter(cluster => cluster.workspace === workspaceId)
|
||||||
return cluster.workspace === workspaceId;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -116,10 +118,9 @@ export class ClusterStore extends BaseStore<ClusterStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toJSON(): ClusterStoreModel {
|
toJSON(): ClusterStoreModel {
|
||||||
const clusters = Array.from(this.clusters).map(([id, cluster]) => cluster.toJSON());
|
|
||||||
return toJS({
|
return toJS({
|
||||||
activeCluster: this.activeCluster,
|
activeCluster: this.activeCluster,
|
||||||
clusters: clusters,
|
clusters: this.clustersList.map(cluster => cluster.toJSON()),
|
||||||
}, {
|
}, {
|
||||||
recurseEverything: true
|
recurseEverything: true
|
||||||
})
|
})
|
||||||
|
|||||||
@ -20,16 +20,7 @@ export interface UserPreferences {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class UserStore extends BaseStore<UserStoreModel> {
|
export class UserStore extends BaseStore<UserStoreModel> {
|
||||||
@observable lastSeenAppVersion = "0.0.0"
|
private constructor() {
|
||||||
@observable seenContexts = observable.set();
|
|
||||||
|
|
||||||
@observable preferences: UserPreferences = {
|
|
||||||
allowTelemetry: true,
|
|
||||||
colorTheme: "dark",
|
|
||||||
downloadMirror: "default",
|
|
||||||
};
|
|
||||||
|
|
||||||
protected constructor() {
|
|
||||||
super({
|
super({
|
||||||
configName: "lens-user-store",
|
configName: "lens-user-store",
|
||||||
confOptions: {
|
confOptions: {
|
||||||
@ -43,6 +34,14 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@observable lastSeenAppVersion = "0.0.0"
|
||||||
|
@observable seenContexts = observable.set();
|
||||||
|
@observable preferences: UserPreferences = {
|
||||||
|
allowTelemetry: true,
|
||||||
|
colorTheme: "dark",
|
||||||
|
downloadMirror: "default",
|
||||||
|
};
|
||||||
|
|
||||||
get hasNewAppVersion() {
|
get hasNewAppVersion() {
|
||||||
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { action, observable } from "mobx";
|
import { action, computed, observable, toJS } from "mobx";
|
||||||
import { BaseStore } from "./base-store";
|
import { BaseStore } from "./base-store";
|
||||||
import { clusterStore } from "./cluster-store"
|
import { clusterStore } from "./cluster-store"
|
||||||
|
|
||||||
@ -18,6 +18,12 @@ export interface Workspace {
|
|||||||
export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
||||||
static readonly defaultId: WorkspaceId = "default"
|
static readonly defaultId: WorkspaceId = "default"
|
||||||
|
|
||||||
|
private constructor() {
|
||||||
|
super({
|
||||||
|
configName: "lens-workspace-store",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@observable currentWorkspace = WorkspaceStore.defaultId;
|
@observable currentWorkspace = WorkspaceStore.defaultId;
|
||||||
|
|
||||||
@observable workspaces = observable.map<WorkspaceId, Workspace>({
|
@observable workspaces = observable.map<WorkspaceId, Workspace>({
|
||||||
@ -27,10 +33,8 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
private constructor() {
|
@computed get workspacesList() {
|
||||||
super({
|
return Array.from(this.workspaces.values());
|
||||||
configName: "lens-workspace-store",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getById(id: WorkspaceId): Workspace {
|
getById(id: WorkspaceId): Workspace {
|
||||||
@ -82,11 +86,12 @@ export class WorkspaceStore extends BaseStore<WorkspaceStoreModel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toJSON(): WorkspaceStoreModel {
|
toJSON(): WorkspaceStoreModel {
|
||||||
const { currentWorkspace, workspaces } = this;
|
return toJS({
|
||||||
return {
|
currentWorkspace: this.currentWorkspace,
|
||||||
currentWorkspace: currentWorkspace,
|
workspaces: this.workspacesList,
|
||||||
workspaces: Array.from(workspaces.values()),
|
}, {
|
||||||
}
|
recurseEverything: true
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { appName, appProto, isMac, staticDir, staticProto } from "../common/vars
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import { format as formatUrl } from "url"
|
import { format as formatUrl } from "url"
|
||||||
import initMenu from "./menu"
|
import initMenu from "./menu"
|
||||||
import * as proxy from "./proxy"
|
import { LensProxy, listen } from "./proxy"
|
||||||
import { WindowManager } from "./window-manager";
|
import { WindowManager } from "./window-manager";
|
||||||
import { ClusterManager } from "./cluster-manager";
|
import { ClusterManager } from "./cluster-manager";
|
||||||
import AppUpdater from "./app-updater"
|
import AppUpdater from "./app-updater"
|
||||||
@ -21,9 +21,9 @@ import { workspaceStore } from "../common/workspace-store";
|
|||||||
import { tracker } from "../common/tracker";
|
import { tracker } from "../common/tracker";
|
||||||
import logger from "./logger"
|
import logger from "./logger"
|
||||||
|
|
||||||
let windowManager: WindowManager = null;
|
let windowManager: WindowManager;
|
||||||
let clusterManager: ClusterManager = null;
|
let clusterManager: ClusterManager;
|
||||||
let proxyServer: proxy.LensProxy = null;
|
let proxyServer: LensProxy;
|
||||||
|
|
||||||
mangleProxyEnv()
|
mangleProxyEnv()
|
||||||
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
if (app.commandLine.getSwitchValue("proxy-server") !== "") {
|
||||||
@ -68,7 +68,7 @@ async function main() {
|
|||||||
|
|
||||||
// run proxy
|
// run proxy
|
||||||
try {
|
try {
|
||||||
proxyServer = proxy.listen(port, clusterManager)
|
proxyServer = listen(port, clusterManager)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Could not start proxy (127.0.0:${port}): ${error.message}`)
|
logger.error(`Could not start proxy (127.0.0:${port}): ${error.message}`)
|
||||||
await dialog.showErrorBox("Lens Error", `Could not start proxy (127.0.0:${port}): ${error.message || "unknown error"}`)
|
await dialog.showErrorBox("Lens Error", `Could not start proxy (127.0.0:${port}): ${error.message || "unknown error"}`)
|
||||||
@ -85,7 +85,9 @@ async function main() {
|
|||||||
windowManager.loadURL(vmURL)
|
windowManager.loadURL(vmURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on("ready", main)
|
// Events
|
||||||
|
|
||||||
|
app.on("ready", main);
|
||||||
app.on('window-all-closed', function () {
|
app.on('window-all-closed', function () {
|
||||||
// On OS X it is common for applications and their menu bar
|
// On OS X it is common for applications and their menu bar
|
||||||
// to stay active until the user quits explicitly with Cmd + Q
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||||
|
|||||||
10
src/renderer/components/+workspaces/bottom-bar.scss
Normal file
10
src/renderer/components/+workspaces/bottom-bar.scss
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
.WorkspacesBottomBar {
|
||||||
|
font-size: $font-size-small;
|
||||||
|
background-color: #3d90ce;
|
||||||
|
padding: $padding / 2 $padding;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
#workspace {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/renderer/components/+workspaces/bottom-bar.tsx
Normal file
52
src/renderer/components/+workspaces/bottom-bar.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import "./bottom-bar.scss"
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import { observable } from "mobx";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Trans } from "@lingui/macro";
|
||||||
|
import { Icon } from "../icon";
|
||||||
|
import { Menu, MenuItem } from "../menu";
|
||||||
|
import { prevDefault } from "../../utils";
|
||||||
|
import { workspaceStore } from "../../../common/workspace-store";
|
||||||
|
|
||||||
|
// todo: remove dummy actions + console.log
|
||||||
|
|
||||||
|
@observer
|
||||||
|
export class WorkspacesBottomBar extends React.Component {
|
||||||
|
@observable menuVisible = false;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { currentWorkspace, workspacesList } = workspaceStore;
|
||||||
|
return (
|
||||||
|
<div className="WorkspacesBottomBar flex gaps">
|
||||||
|
<div id="workspace" className="workspace flex align-center box right">
|
||||||
|
<Icon small material="layers"/> {currentWorkspace}
|
||||||
|
</div>
|
||||||
|
<Menu
|
||||||
|
usePortal
|
||||||
|
htmlFor="workspace"
|
||||||
|
className="WorkspacesMenu"
|
||||||
|
isOpen={this.menuVisible}
|
||||||
|
open={() => this.menuVisible = true}
|
||||||
|
close={() => this.menuVisible = false}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
to="/workspaces"
|
||||||
|
className="workspaces-title"
|
||||||
|
onClick={prevDefault(() => console.log('/navigate: workspaces page'))}>
|
||||||
|
<Trans>Workspaces</Trans>
|
||||||
|
</Link>
|
||||||
|
{workspacesList.map(workspace => {
|
||||||
|
const { id, name, description } = workspace;
|
||||||
|
return (
|
||||||
|
<MenuItem key={id} onClick={() => console.log(`navigate: /workspaces/${id}`)} title={description}>
|
||||||
|
<Icon small material="layers"/> {name}
|
||||||
|
</MenuItem>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,29 +5,21 @@
|
|||||||
grid-template-columns: min-content 1fr;
|
grid-template-columns: min-content 1fr;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
> .draggable-top {
|
.draggable-top {
|
||||||
@include set-draggable;
|
@include set-draggable;
|
||||||
grid-area: draggable;
|
grid-area: draggable;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .ClusterMenu {
|
#lens-view {
|
||||||
grid-area: menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .lens-container {
|
|
||||||
grid-area: lens-view;
|
grid-area: lens-view;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .bottom-bar {
|
.ClusterMenu {
|
||||||
grid-area: bottom-bar;
|
grid-area: menu;
|
||||||
font-size: $font-size-small;
|
}
|
||||||
background-color: #3d90ce;
|
|
||||||
padding: $padding / 2 $padding;
|
|
||||||
color: white;
|
|
||||||
|
|
||||||
#workspace {
|
.WorkspacesBottomBar {
|
||||||
cursor: pointer;
|
grid-area: bottom-bar;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,61 +1,18 @@
|
|||||||
import "./workspaces.scss"
|
import "./workspaces.scss"
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import { Link } from "react-router-dom";
|
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { workspaceStore } from "../../../common/workspace-store";
|
|
||||||
import { Icon } from "../icon";
|
|
||||||
import { ClustersMenu } from "./clusters-menu";
|
import { ClustersMenu } from "./clusters-menu";
|
||||||
import { Menu, MenuItem } from "../menu";
|
import { WorkspacesBottomBar } from "./bottom-bar";
|
||||||
import { prevDefault } from "../../utils";
|
|
||||||
|
|
||||||
// todo: support `workspaceId` in URL
|
// todo: support `workspaceId` in URL
|
||||||
|
|
||||||
@observer
|
|
||||||
export class Workspaces extends React.Component {
|
export class Workspaces extends React.Component {
|
||||||
@observable menuVisible = false;
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { currentWorkspace, workspaces } = workspaceStore;
|
|
||||||
return (
|
return (
|
||||||
<div className="Workspaces">
|
<div className="Workspaces">
|
||||||
<div className="draggable-top"/>
|
<div className="draggable-top"/>
|
||||||
|
<div id="lens-view"/>
|
||||||
<ClustersMenu/>
|
<ClustersMenu/>
|
||||||
|
<WorkspacesBottomBar/>
|
||||||
<div className="lens-container">
|
|
||||||
{/*todo: replace with BrowserView */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="bottom-bar flex justify-flex-end">
|
|
||||||
<div id="workspace" className="workspace flex align-center">
|
|
||||||
<Icon small material="layers"/> {currentWorkspace}
|
|
||||||
</div>
|
|
||||||
<Menu
|
|
||||||
usePortal
|
|
||||||
htmlFor="workspace"
|
|
||||||
className="WorkspacesMenu"
|
|
||||||
isOpen={this.menuVisible}
|
|
||||||
open={() => this.menuVisible = true}
|
|
||||||
close={() => this.menuVisible = false}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
to="/workspaces"
|
|
||||||
className="workspaces-title"
|
|
||||||
onClick={prevDefault(() => console.log('/navigate: workspaces page'))}>
|
|
||||||
<Trans>Workspaces</Trans>
|
|
||||||
</Link>
|
|
||||||
{Array.from(workspaces.values()).map(workspace => {
|
|
||||||
const { id, name, description } = workspace;
|
|
||||||
return (
|
|
||||||
<MenuItem key={id} onClick={() => console.log(`navigate: /workspaces/${id}`)} title={description}>
|
|
||||||
<Icon small material="layers"/> {name}
|
|
||||||
</MenuItem>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</Menu>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user