mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
added what-s-new page, fixes
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
47f6a2b7e1
commit
693385a0a0
@ -22,7 +22,7 @@ export interface UserPreferences {
|
|||||||
export class UserStore extends BaseStore<UserStoreModel> {
|
export class UserStore extends BaseStore<UserStoreModel> {
|
||||||
private constructor() {
|
private constructor() {
|
||||||
super({
|
super({
|
||||||
configName: "lens-user-store",
|
// configName: "lens-user-store", // todo: migrate from default filename
|
||||||
migrations: migrations,
|
migrations: migrations,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
|
|||||||
downloadMirror: "default",
|
downloadMirror: "default",
|
||||||
};
|
};
|
||||||
|
|
||||||
get hasNewAppVersion() {
|
get isNewVersion() {
|
||||||
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
return semver.gt(getAppVersion(), this.lastSeenAppVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,8 @@ import type { ClusterId } from "../common/cluster-store";
|
|||||||
import { clusterStore } from "../common/cluster-store";
|
import { clusterStore } from "../common/cluster-store";
|
||||||
import logger from "./logger";
|
import logger from "./logger";
|
||||||
|
|
||||||
|
// fixme: remove switching view delay on first load
|
||||||
|
|
||||||
export class WindowManager {
|
export class WindowManager {
|
||||||
protected activeView: BrowserWindow;
|
protected activeView: BrowserWindow;
|
||||||
protected views = new Map<ClusterId, BrowserWindow>();
|
protected views = new Map<ClusterId, BrowserWindow>();
|
||||||
|
|||||||
@ -5,11 +5,4 @@
|
|||||||
background-size: 85%;
|
background-size: 85%;
|
||||||
background-clip: content-box;
|
background-clip: content-box;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: white;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 28px;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,3 +1,43 @@
|
|||||||
.WhatsNew {
|
.WhatsNew {
|
||||||
|
$spacing: $padding * 2;
|
||||||
|
|
||||||
|
background: $mainBackground url(../../components/icon/crane.svg) no-repeat;
|
||||||
|
background-position: 0 35%;
|
||||||
|
background-size: 85%;
|
||||||
|
background-clip: content-box;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 200px;
|
||||||
|
margin-bottom: $spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .content {
|
||||||
|
@include custom-scrollbar;
|
||||||
|
margin-top: $spacing;
|
||||||
|
padding: $spacing * 2;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $colorInfo;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: disc inside;
|
||||||
|
line-height: 120%;
|
||||||
|
padding-left: $spacing * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.25em .5em;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: $radius;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .bottom {
|
||||||
|
text-align: center;
|
||||||
|
padding: $spacing;
|
||||||
|
background: $contentColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,13 +1,43 @@
|
|||||||
import "./whats-new.scss"
|
import "./whats-new.scss"
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
import { userStore } from "../../../common/user-store"
|
||||||
|
import { navigate } from "../../navigation";
|
||||||
|
import { Button } from "../button";
|
||||||
|
import { Trans } from "@lingui/macro";
|
||||||
|
import { staticDir } from "../../../common/vars";
|
||||||
|
import marked from "marked"
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class WhatsNew extends React.Component {
|
export class WhatsNew extends React.Component {
|
||||||
|
releaseNotes = fs.readFileSync(path.join(staticDir, "RELEASE_NOTES.md")).toString();
|
||||||
|
|
||||||
|
ok = () => {
|
||||||
|
navigate("/");
|
||||||
|
userStore.saveLastSeenAppVersion();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const logo = require("../../components/icon/lens-logo.svg");
|
||||||
|
const releaseNotes = marked(this.releaseNotes);
|
||||||
return (
|
return (
|
||||||
<div className="WhatsNew">
|
<div className="WhatsNew flex column">
|
||||||
WhatsNew
|
<div className="content box grow">
|
||||||
|
<img className="logo" src={logo} alt="Lens"/>
|
||||||
|
<div
|
||||||
|
className="release-notes flex column gaps"
|
||||||
|
dangerouslySetInnerHTML={{ __html: releaseNotes }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="bottom">
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
label={<Trans>Ok, got it!</Trans>}
|
||||||
|
onClick={this.ok}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,10 @@ html, body {
|
|||||||
#app {
|
#app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
height: inherit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixme: doesn't work
|
// fixme: doesn't work
|
||||||
@ -75,37 +79,34 @@ hr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 11.2rem;
|
color: white;
|
||||||
font-weight: $font-weight-thin;
|
font-size: 28px;
|
||||||
|
font-weight: 300;
|
||||||
letter-spacing: -.010em;
|
letter-spacing: -.010em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@extend h1;
|
@extend h1;
|
||||||
font-size: 5.6 * $unit;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
@extend h2;
|
@extend h2;
|
||||||
font-size: 4.5 * $unit;
|
font-size: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
@extend h2;
|
@extend h2;
|
||||||
font-size: 3.4 * $unit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
@extend h2;
|
@extend h2;
|
||||||
font-size: 2.6 * $unit;
|
|
||||||
padding: $padding / 2 0;
|
padding: $padding / 2 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
@extend h2;
|
@extend h2;
|
||||||
font-size: 2 * $unit;
|
|
||||||
font-weight: $font-weight-bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
|
|||||||
@ -2,14 +2,16 @@ import "./cluster-manager.scss"
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { ClustersMenu } from "./clusters-menu";
|
import { ClustersMenu } from "./clusters-menu";
|
||||||
import { BottomBar } from "./bottom-bar";
|
import { BottomBar } from "./bottom-bar";
|
||||||
|
import { App } from "../app";
|
||||||
|
|
||||||
export class ClusterManager extends React.Component {
|
export class ClusterManager extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { children: lensView } = this.props;
|
|
||||||
return (
|
return (
|
||||||
<div className="ClusterManager">
|
<div className="ClusterManager">
|
||||||
<div id="draggable-top"/>
|
<div id="draggable-top"/>
|
||||||
<div id="lens-view">{lensView}</div>
|
<div id="lens-view">
|
||||||
|
<App/>
|
||||||
|
</div>
|
||||||
<ClustersMenu/>
|
<ClustersMenu/>
|
||||||
<BottomBar/>
|
<BottomBar/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { computed, observable, reaction } from "mobx";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { matchPath, NavLink } from "react-router-dom";
|
import { matchPath, NavLink } from "react-router-dom";
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { configStore } from "../../config.store";
|
|
||||||
import { createStorage, cssNames } from "../../utils";
|
import { createStorage, cssNames } from "../../utils";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { workloadsRoute, workloadsURL } from "../+workloads/workloads.route";
|
import { workloadsRoute, workloadsURL } from "../+workloads/workloads.route";
|
||||||
@ -29,6 +28,7 @@ import { CrdList, crdResourcesRoute, crdRoute, crdURL } from "../+custom-resourc
|
|||||||
import { CustomResources } from "../+custom-resources/custom-resources";
|
import { CustomResources } from "../+custom-resources/custom-resources";
|
||||||
import { navigation } from "../../navigation";
|
import { navigation } from "../../navigation";
|
||||||
import { isAllowedResource } from "../../api/rbac"
|
import { isAllowedResource } from "../../api/rbac"
|
||||||
|
import { TooltipContent } from "../tooltip";
|
||||||
|
|
||||||
const SidebarContext = React.createContext<SidebarContextValue>({ pinned: false });
|
const SidebarContext = React.createContext<SidebarContextValue>({ pinned: false });
|
||||||
type SidebarContextValue = {
|
type SidebarContextValue = {
|
||||||
@ -72,20 +72,28 @@ export class Sidebar extends React.Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { toggle, isPinned, className } = this.props;
|
const { toggle, isPinned, className } = this.props;
|
||||||
const { allowedResources } = configStore;
|
|
||||||
const query = namespaceStore.getContextParams();
|
const query = namespaceStore.getContextParams();
|
||||||
return (
|
return (
|
||||||
<SidebarContext.Provider value={{ pinned: isPinned }}>
|
<SidebarContext.Provider value={{ pinned: isPinned }}>
|
||||||
<div className={cssNames("Sidebar flex column", className, { pinned: isPinned })}>
|
<div className={cssNames("Sidebar flex column", className, { pinned: isPinned })}>
|
||||||
<div className="header flex align-center">
|
<div className="header flex align-center">
|
||||||
<NavLink exact to="/" className="box grow">
|
<NavLink exact to="/" className="box grow">
|
||||||
<Icon svg="logo-full" className="logo-icon"/> <div className="logo-text">Lens</div>
|
<Icon svg="logo-full" className="logo-icon"/>
|
||||||
|
<div className="logo-text">Lens</div>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<Icon
|
<Icon
|
||||||
className="pin-icon"
|
className="pin-icon"
|
||||||
material={isPinned ? "keyboard_arrow_left" : "keyboard_arrow_right"}
|
material={isPinned ? "keyboard_arrow_left" : "keyboard_arrow_right"}
|
||||||
onClick={toggle}
|
onClick={toggle}
|
||||||
tooltip={isPinned ? <Trans>Compact view</Trans> : <Trans>Extended view</Trans>}
|
tooltip={{
|
||||||
|
following: false,
|
||||||
|
position: { right: true },
|
||||||
|
children: (
|
||||||
|
<TooltipContent nowrap>
|
||||||
|
<Trans>Compact view</Trans>
|
||||||
|
</TooltipContent>
|
||||||
|
)
|
||||||
|
}}
|
||||||
focusable={false}
|
focusable={false}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import "../common/system-ca"
|
import "../common/system-ca"
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { render } from "react-dom";
|
import { render } from "react-dom";
|
||||||
import { Router } from "react-router";
|
import { Route, Router, Switch } from "react-router";
|
||||||
|
import { observer } from "mobx-react";
|
||||||
import { userStore } from "../common/user-store";
|
import { userStore } from "../common/user-store";
|
||||||
import { workspaceStore } from "../common/workspace-store";
|
import { workspaceStore } from "../common/workspace-store";
|
||||||
import { clusterStore } from "../common/cluster-store";
|
import { clusterStore } from "../common/cluster-store";
|
||||||
@ -11,7 +12,10 @@ import { _i18n } from "./i18n";
|
|||||||
import { App } from "./components/app";
|
import { App } from "./components/app";
|
||||||
import { ClusterManager } from "./components/cluster-manager";
|
import { ClusterManager } from "./components/cluster-manager";
|
||||||
import { ErrorBoundary } from "./components/error-boundary";
|
import { ErrorBoundary } from "./components/error-boundary";
|
||||||
|
import { WhatsNew, whatsNewRoute } from "./components/+whats-new";
|
||||||
|
import { Preferences, preferencesRoute } from "./components/+preferences";
|
||||||
|
|
||||||
|
@observer
|
||||||
class LensApp extends React.Component {
|
class LensApp extends React.Component {
|
||||||
static async init() {
|
static async init() {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -28,9 +32,12 @@ class LensApp extends React.Component {
|
|||||||
<I18nProvider i18n={_i18n}>
|
<I18nProvider i18n={_i18n}>
|
||||||
<Router history={browserHistory}>
|
<Router history={browserHistory}>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<ClusterManager>
|
<Switch>
|
||||||
<App/>
|
{userStore.isNewVersion && <Route component={WhatsNew}/>}
|
||||||
</ClusterManager>
|
<Route component={WhatsNew} {...whatsNewRoute}/>
|
||||||
|
<Route component={Preferences} {...preferencesRoute}/>
|
||||||
|
<Route component={ClusterManager}/>
|
||||||
|
</Switch>
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</Router>
|
</Router>
|
||||||
</I18nProvider>
|
</I18nProvider>
|
||||||
@ -38,4 +45,5 @@ class LensApp extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", LensApp.init);
|
// run
|
||||||
|
LensApp.init();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user