clusters-menu

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman committed 2020-07-09 12:29:46 +03:00
1 parent ba4f5cb47d
commit a440f60ea3
9 files changed
+109 -73

No files matched your search

+6 -8
View File
@@ -35,7 +35,9 @@ export class UserStore extends BaseStore<UserStoreModel> {
}
@observable lastSeenAppVersion = "0.0.0"
@observable seenContexts = observable.set();
@observable seenContexts: string[] = [];
@observable newContexts: string[] = []; // todo: detect new contexts from .kube/config since last open
@observable preferences: UserPreferences = {
allowTelemetry: true,
colorTheme: "dark",
@@ -54,16 +56,12 @@ export class UserStore extends BaseStore<UserStoreModel> {
@action
protected fromStore(data: Partial<UserStoreModel> = {}) {
const { lastSeenAppVersion, seenContexts, preferences } = data
const { lastSeenAppVersion, seenContexts = [], preferences } = data
if (lastSeenAppVersion) {
this.lastSeenAppVersion = lastSeenAppVersion;
}
if (seenContexts) {
this.seenContexts = observable.set(seenContexts);
}
if (preferences) {
Object.assign(this.preferences, preferences);
}
this.seenContexts = seenContexts;
Object.assign(this.preferences, preferences);
}
toJSON() {
@@ -1,15 +1,50 @@
.ClustersMenu {
@include hidden-scrollbar;
$menuBgc: #252729;
padding: $padding;
background: #252729;
padding: $padding * 1.5;
background: $menuBgc;
.add-cluster {
cursor: pointer;
opacity: 0.4;
position: relative;
&:hover {
opacity: .75;
.Icon.add {
border-radius: $radius;
padding: $padding / 3;
color: $menuBgc !important;
background: white !important;
font-weight: bold;
cursor: pointer;
opacity: 0.4;
&.active {
opacity: 1;
}
&:hover {
box-shadow: none;
opacity: .75;
}
}
// todo: reuse in cluster-icon.tsx
.Badge.new-contexts {
$boxSize: 17px;
$offset: -7px;
position: absolute;
font-size: $font-size-small;
right: $offset;
bottom: $offset;
line-height: $boxSize;
min-width: $boxSize;
min-height: $boxSize;
text-align: center;
color: white;
background: $colorSuccess;
font-weight: normal;
border-radius: 50%;
padding: 0;
}
}
}
@@ -6,11 +6,16 @@ import React from "react";
import { observer } from "mobx-react";
import { _i18n } from "../../i18n";
import { t, Trans } from "@lingui/macro";
import { ClusterId, clusterStore } from "../../../common/cluster-store";
import { userStore } from "../../../common/user-store";
import { clusterStore } from "../../../common/cluster-store";
import { WorkspaceId } from "../../../common/workspace-store";
import { ClusterIcon } from "../+cluster-settings/cluster-icon";
import { Icon } from "../icon";
import { cssNames, IClassName } from "../../utils";
import { Badge } from "../badge";
// fixme: allow to rearrange clusters with drag&drop
// fixme: make add-icon's tooltip visible on init
interface Props {
className?: IClassName;
@@ -28,43 +33,30 @@ export class ClustersMenu extends React.Component<Props> {
console.log('navigate: /add-cluster')
}
showContextMenu = (clusterId: ClusterId) => {
showContextMenu = (cluster: Cluster) => {
const { Menu, MenuItem } = remote
const menu = new Menu();
menu.append(new MenuItem({
label: _i18n._(t`Settings`),
click: () => {
console.log(`navigate to cluster=${clusterId} settings`)
}
}))
// fixme: don't show item if cluster wasn't active during runtime
menu.append(new MenuItem({
label: _i18n._(t`Disconnect`),
click: () => {
console.log(`disconnect cluster=${clusterId} and navigate to landing-page`)
}
}))
click: () => console.log(`navigate to cluster settings`, cluster)
}));
if (cluster.initialized) {
menu.append(new MenuItem({
label: _i18n._(t`Disconnect`),
click: () => console.log(`disconnect cluster and navigate to workspaces`, cluster)
}))
}
menu.popup({
window: remote.getCurrentWindow()
})
}
// fixme: allow to rearrange clusters with drag&drop
render() {
const { workspaceId, className } = this.props;
const clusters = clusterStore.getByWorkspaceId(workspaceId);
const addClusterTooltip = (
<div className="flex column gaps">
<p><Trans>This is the quick launch menu.</Trans></p>
<p>
<Trans>
Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button.
</Trans>
</p>
</div>
)
const { newContexts } = userStore;
return (
<div className={cssNames("ClustersMenu flex gaps column", className)}>
{clusters.map(cluster => {
@@ -75,18 +67,28 @@ export class ClustersMenu extends React.Component<Props> {
cluster={cluster}
className={cssNames({ active: isActive })}
onClick={() => this.selectCluster(cluster)}
onContextMenu={() => this.showContextMenu(cluster.id)}
onContextMenu={() => this.showContextMenu(cluster)}
/>
)
})}
{/* todo: add badge for "newContexts" since last visit */}
{/* fixme: make tooltip visible on init + remove following to mouse pos */}
<Icon
big material="add"
className="add-cluster"
tooltip={{ children: addClusterTooltip }}
onClick={this.addCluster}
/>
<div className="add-cluster">
<Icon
big material="add" className="add" onClick={this.addCluster}
tooltip={(
<div className="flex column gaps">
<p><Trans>This is the quick launch menu.</Trans></p>
<p>
<Trans>
Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button.
</Trans>
</p>
</div>
)}
/>
{newContexts.length > 0 && (
<Badge className="new-contexts" label={newContexts.length}/>
)}
</div>
</div>
);
}
@@ -1,13 +1,14 @@
.Workspaces {
display: grid;
grid-template-areas: "draggable draggable" "menu lens-view" "bottom-bar bottom-bar";
grid-template-rows: 20px 1fr min-content;
grid-template-rows: auto 1fr min-content;
grid-template-columns: min-content 1fr;
height: 100%;
.draggable-top {
@include set-draggable;
grid-area: draggable;
height: 25px;
}
#lens-view {
+8 -8
View File
@@ -33,18 +33,13 @@
height: var(--big-size);
}
> span {
width: 100%;
height: 100%;
}
// material-icon
&.material {
> span {
> .icon {
font-family: "Material Icons";
font-size: inherit;
font-weight: normal;
font-style: normal;
font-weight: inherit;
font-style: inherit;
display: inline-block;
line-height: 1;
text-transform: none;
@@ -68,6 +63,11 @@
&.svg {
box-sizing: content-box;
> .icon {
width: 100%;
height: 100%;
}
svg {
pointer-events: none;
width: 100%;
+2 -2
View File
@@ -87,12 +87,12 @@ export class Icon extends React.PureComponent<IconProps> {
// render as inline svg-icon
if (svg) {
const svgIconText = require("!!raw-loader!./" + svg + ".svg").default;
iconContent = <span dangerouslySetInnerHTML={{ __html: svgIconText }}/>;
iconContent = <span className="icon" dangerouslySetInnerHTML={{ __html: svgIconText }}/>;
}
// render as material-icon
if (material) {
iconContent = <span className="material-icons">{material}</span>;
iconContent = <span className="icon">{material}</span>;
}
// wrap icon's content passed from decorator