1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

tweak landing page

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen 2021-03-09 12:10:40 +02:00
parent 16baa456aa
commit e8e79955ad
5 changed files with 54 additions and 107 deletions

View File

@ -1,69 +1,10 @@
.LandingPage {
width: 100%;
height: 100%;
text-align: center;
z-index: 0;
&::after {
content: "";
background: url(../../components/icon/crane.svg) no-repeat;
background-position: 0 35%;
background-size: 85%;
background-clip: content-box;
opacity: .75;
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
z-index: -1;
.theme-light & {
opacity: 0.2;
}
}
.startup-hint {
$bgc: $mainBackground;
$arrowSize: 10px;
position: absolute;
left: 0;
top: 25px;
margin: $padding;
padding: $padding * 2;
width: 320px;
background: $bgc;
color: $textColorAccent;
filter: drop-shadow(0 0px 2px #ffffff33);
&:before {
content: "";
position: absolute;
width: 0;
height: 0;
border-top: $arrowSize solid transparent;
border-bottom: $arrowSize solid transparent;
border-right: $arrowSize solid $bgc;
right: 100%;
}
.theme-light & {
filter: drop-shadow(0 0px 2px #777);
background: white;
&:before {
border-right-color: white;
}
}
}
}
.PageLayout.LandingOverview { .PageLayout.LandingOverview {
--width: 100%; --width: 100%;
--height: 100%; --height: 100%;
text-align: center; text-align: center;
.content-wrapper { .content-wrapper {
.content { .content {

View File

@ -1,11 +1,13 @@
import "./landing-page.scss"; import "./landing-page.scss";
import React from "react"; import React from "react";
import { observable } from "mobx"; import { computed, observable } from "mobx";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import { clusterStore } from "../../../common/cluster-store"; import { clusterStore } from "../../../common/cluster-store";
import { Workspace, workspaceStore } from "../../../common/workspace-store"; import { Workspace, workspaceStore } from "../../../common/workspace-store";
import { WorkspaceOverview } from "./workspace-overview"; import { WorkspaceOverview } from "./workspace-overview";
import { PageLayout } from "../layout/page-layout"; import { PageLayout } from "../layout/page-layout";
import { Notifications } from "../notifications";
import { Icon } from "../icon";
@observer @observer
export class LandingPage extends React.Component { export class LandingPage extends React.Component {
@ -15,42 +17,28 @@ export class LandingPage extends React.Component {
return workspaceStore.currentWorkspace; return workspaceStore.currentWorkspace;
} }
renderStartupHint() { @computed
return ( get clusters() {
<div className="startup-hint flex column gaps" onMouseEnter={() => this.showHint = false}> return clusterStore.getByWorkspaceId(this.workspace.id);
<p>This is the quick launch menu.</p> }
<p>
Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button. componentDidMount() {
</p> const noClustersInScope = !this.clusters.length;
</div> const showStartupHint = this.showHint;
);
if (showStartupHint && noClustersInScope) {
Notifications.info(<><b>Welcome!</b><p>Get started by associating one or more clusters to Lens</p></>, {
timeout: 30_000
});
}
} }
render() { render() {
const clusters = clusterStore.getByWorkspaceId(this.workspace.id); const showBackButton = this.clusters.length > 0;
const noClustersInScope = !clusters.length; const header = <><Icon svg="logo-lens" big /> <h2>Workspace: {this.workspace.name}</h2></>;
const showStartupHint = this.showHint && noClustersInScope;
const header = <h2>Workspace: {this.workspace.name}</h2>;
if (this.workspace.name === "default" && noClustersInScope) {
return (
<div className="LandingPage flex">
{showStartupHint && this.renderStartupHint()}
<div className="no-clusters flex column gaps box center">
<h1>
Welcome!
</h1>
<p>
Get started by associating one or more clusters to Lens.
</p>
</div>
</div>
);
}
return ( return (
<PageLayout className="LandingOverview flex" header={header} provideBackButtonNavigation={true} showOnTop={true}> <PageLayout className="LandingOverview flex" header={header} provideBackButtonNavigation={showBackButton} showOnTop={true}>
<WorkspaceOverview workspace={this.workspace}/> <WorkspaceOverview workspace={this.workspace}/>
</PageLayout> </PageLayout>
); );

View File

@ -6,23 +6,35 @@ import { autobind } from "../../utils";
export class ClusterItem implements ItemObject { export class ClusterItem implements ItemObject {
constructor(public cluster: Cluster) {} constructor(public cluster: Cluster) {}
get name() { get name() {
return this.cluster.name; return this.cluster.name;
} }
get distribution() {
return (this.cluster.metadata["distribution"] || "unknown").toString();
}
get version() {
return this.cluster.version;
}
get connectionStatus() {
return this.cluster.online ? "connected" : "disconnected";
}
getName() { getName() {
return this.name; return this.name;
} }
get id() { get id() {
return this.cluster.id; return this.cluster.id;
} }
get clusterId() { get clusterId() {
return this.cluster.id; return this.cluster.id;
} }
getId() { getId() {
return this.id; return this.id;
} }
@ -44,6 +56,7 @@ export class WorkspaceClusterStore extends ItemStore<ClusterItem> {
() => ( () => (
clusterStore clusterStore
.getByWorkspaceId(this.workspaceId) .getByWorkspaceId(this.workspaceId)
.filter(cluster => cluster.enabled)
.map(cluster => new ClusterItem(cluster)) .map(cluster => new ClusterItem(cluster))
) )
); );
@ -56,8 +69,4 @@ export class WorkspaceClusterStore extends ItemStore<ClusterItem> {
return super.removeItem(clusterItem, () => clusterStore.removeById(clusterId)); return super.removeItem(clusterItem, () => clusterStore.removeById(clusterId));
} }
} }
async removeSelectedItems() {
return Promise.all(this.selectedItems.map(this.remove));
}
} }

View File

@ -13,7 +13,7 @@
padding: 0; padding: 0;
} }
&.online { &.connected {
color: var(--colorSuccess); color: var(--colorSuccess);
} }
} }
@ -22,6 +22,10 @@
flex: 0.1; flex: 0.1;
} }
.TableCell.distribution {
flex: 0.2;
}
.TableCell.version { .TableCell.version {
flex: 0.2; flex: 0.2;
} }

View File

@ -17,8 +17,9 @@ interface Props {
enum sortBy { enum sortBy {
name = "name", name = "name",
contextName = "contextName", distribution = "distribution",
version = "version", version = "version",
online = "online"
} }
@observer @observer
@ -44,17 +45,21 @@ export class WorkspaceOverview extends Component<Props> {
store={workspaceClusterStore} store={workspaceClusterStore}
sortingCallbacks={{ sortingCallbacks={{
[sortBy.name]: (item: ClusterItem) => item.name, [sortBy.name]: (item: ClusterItem) => item.name,
[sortBy.version]: (item: ClusterItem) => item.cluster.version, [sortBy.distribution]: (item: ClusterItem) => item.distribution,
[sortBy.version]: (item: ClusterItem) => item.version,
[sortBy.online]: (item: ClusterItem) => item.connectionStatus,
}} }}
renderTableHeader={[ renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name }, { title: "Name", className: "name", sortBy: sortBy.name },
{ title: "Distribution", className: "distribution", sortBy: sortBy.distribution },
{ title: "Version", className: "version", sortBy: sortBy.version }, { title: "Version", className: "version", sortBy: sortBy.version },
{ title: "Status", className: "status" }, { title: "Status", className: "status", sortBy: sortBy.online },
]} ]}
renderTableContents={(item: ClusterItem) => [ renderTableContents={(item: ClusterItem) => [
item.name, item.name,
item.cluster.version, item.distribution,
{ title: item.cluster.online ? "online" : "offline", className: kebabCase(item.cluster.online ? "online" : "offline") } item.version,
{ title: item.connectionStatus, className: kebabCase(item.connectionStatus) }
]} ]}
onDetails={this.showCluster} onDetails={this.showCluster}
addRemoveButtons={{ addRemoveButtons={{