From 46c1b4f77d336fb25ab04ac4edfb9a1b8b8f7a3b Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Thu, 24 May 2018 17:33:45 -0400 Subject: [PATCH 01/12] ui: declosurify event handlers on login page Release note: None --- pkg/ui/src/views/login/loginPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 5e335ed5bdfa..63be626fdf08 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -26,15 +26,15 @@ class LoginPage extends React.Component { + handleUpdateUsername = (evt: React.FormEvent) => { this.setState({ - username, + username: evt.target.value, }); } - handleUpdatePassword = (password: string) => { + handleUpdatePassword = (evt: React.FormEvent) => { this.setState({ - password, + password: evt.target.value, }); } @@ -66,12 +66,12 @@ class LoginPage extends React.Component this.handleUpdateUsername(evt.target.value)} + onChange={this.handleUpdateUsername} value={this.state.username} />
this.handleUpdatePassword(evt.target.value)} + onChange={this.handleUpdatePassword} value={this.state.password} />
From a9f74ae2dd085b45bb99b3ef82fd23a8724834d8 Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Thu, 24 May 2018 17:34:21 -0400 Subject: [PATCH 02/12] ui: style login page Add some initial styling to the login page. Contributes to #24939. Release note: None --- pkg/ui/src/views/login/loginPage.styl | 43 +++++++++++++++++++++++++++ pkg/ui/src/views/login/loginPage.tsx | 21 +++++++++++-- 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 pkg/ui/src/views/login/loginPage.styl diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl new file mode 100644 index 000000000000..8f9c2fccd3de --- /dev/null +++ b/pkg/ui/src/views/login/loginPage.styl @@ -0,0 +1,43 @@ +@require "~styl/base/palette.styl" + +.login-page + display flex + align-items center + justify-content center + height 100% + width 100% + position absolute + + .heading + text-transform none + letter-spacing default + + .aside + margin-top 12px + line-height 24px + letter-spacing 1px + color #666 + width 350px + + .input-text + letter-spacing 2px + line-height 17px + padding 12px 24px + vertical-align middle + border 1px solid $button-border-color + border-radius 4px + margin 12px 0 + color $body-color + + .submit-button + text-transform uppercase + font-size 14px + letter-spacing 2px + line-height 17px + padding 12px 24px + vertical-align middle + border 0px none + border-radius 4px + margin 24px 0 + color $background-color + background-color $link-color diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 63be626fdf08..2cdb077204e3 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -5,6 +5,9 @@ import { withRouter, WithRouterProps } from "react-router"; import { doLogin, LoginAPIState } from "src/redux/login"; import { AdminUIState } from "src/redux/state"; +import docsURL from "src/util/docs"; + +import "./loginPage.styl"; interface LoginPageProps { loginState: LoginAPIState; @@ -54,27 +57,39 @@ class LoginPage extends React.Component +
Login
-

Login

+

Sign in to the Console

+

+ Please contact your database administrator for + account access and password restoration. + For more information, see{" "} + the documentation. +

{this.props.loginState.error ?
Login error: {this.props.loginState.error}
: null}


- +
From b966f7c2bd95e388accbf1b78d1c90959f70565b Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Tue, 29 May 2018 13:22:02 -0400 Subject: [PATCH 03/12] ui: error state for login page Add some styling and clean up the error text on login page. Contributes to #24939. Release note: None --- pkg/ui/src/redux/login.ts | 4 ++-- pkg/ui/src/views/login/loginPage.styl | 9 +++++++- pkg/ui/src/views/login/loginPage.tsx | 32 ++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/pkg/ui/src/redux/login.ts b/pkg/ui/src/redux/login.ts index 13bf683b91a2..cabcddf97f5d 100644 --- a/pkg/ui/src/redux/login.ts +++ b/pkg/ui/src/redux/login.ts @@ -119,7 +119,7 @@ export function getLoginPage(location: Location) { export interface LoginAPIState { loggedInUser: string; - error: string; + error: Error; inProgress: boolean; } @@ -180,7 +180,7 @@ export function doLogin(username: string, password: string): ThunkAction { dispatch(loginSuccess(username)); }, - (err) => { dispatch(loginFailure(err.toString())); }, + (err) => { dispatch(loginFailure(err)); }, ); }; } diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl index 8f9c2fccd3de..f7cc80c623d5 100644 --- a/pkg/ui/src/views/login/loginPage.styl +++ b/pkg/ui/src/views/login/loginPage.styl @@ -16,7 +16,7 @@ margin-top 12px line-height 24px letter-spacing 1px - color #666 + color $body-color width 350px .input-text @@ -29,6 +29,9 @@ margin 12px 0 color $body-color + &--error + border-color $alert-color + .submit-button text-transform uppercase font-size 14px @@ -41,3 +44,7 @@ margin 24px 0 color $background-color background-color $link-color + + &__error + color $alert-color + margin 12px 0 diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 2cdb077204e3..98e2f1776c51 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -1,3 +1,4 @@ +import classNames from "classnames"; import React from "react"; import Helmet from "react-helmet"; import { connect } from "react-redux"; @@ -55,7 +56,27 @@ class LoginPage extends React.ComponentUnable to log in: { message } + ); + } + render() { + const inputClasses = classNames("input-text", { + "input-text--error": !!this.props.loginState.error, + }); + return (
@@ -66,22 +87,23 @@ class LoginPage extends React.Component Please contact your database administrator for account access and password restoration. + +

+

For more information, see{" "} the documentation.

- {this.props.loginState.error - ?
Login error: {this.props.loginState.error}
- : null} + {this.renderError()}


From 79b9dc4e7e87409a4d5575ded080efda13838183 Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Tue, 29 May 2018 13:39:13 -0400 Subject: [PATCH 04/12] ui: add cockroach icon to login page Release note: None --- pkg/ui/src/views/login/loginPage.styl | 6 ++++++ pkg/ui/src/views/login/loginPage.tsx | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl index f7cc80c623d5..4c9ab4b1ecb2 100644 --- a/pkg/ui/src/views/login/loginPage.styl +++ b/pkg/ui/src/views/login/loginPage.styl @@ -48,3 +48,9 @@ &__error color $alert-color margin 12px 0 + + .image-container + position fixed + height 38px + left 20px + bottom 20px diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 98e2f1776c51..7b1e6dbdd221 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -7,6 +7,8 @@ import { withRouter, WithRouterProps } from "react-router"; import { doLogin, LoginAPIState } from "src/redux/login"; import { AdminUIState } from "src/redux/state"; import docsURL from "src/util/docs"; +import { trustIcon } from "src/util/trust"; +import { cockroachIcon } from "src/views/shared/components/icons"; import "./loginPage.styl"; @@ -82,6 +84,8 @@ class LoginPage extends React.Component Login +

Sign in to the Console

@@ -111,6 +115,7 @@ class LoginPage extends React.Component

From 4eaa236a8f5f018a1c6ed5e42ac41b13940a473c Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Tue, 29 May 2018 13:59:20 -0400 Subject: [PATCH 05/12] ui: style navbar login indicator Adds some initial styling to the login indicator on the navigation sidebar. Release note: None --- .../app/components/layoutSidebar/index.tsx | 18 +++++++++------- pkg/ui/styl/layout/navigation-bar.styl | 21 ++++++++++++++++++- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx index d9be2c12724e..76909fc67de3 100644 --- a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx +++ b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx @@ -78,11 +78,15 @@ function LoginIndicator({ loginState, handleLogout }: LoginIndicatorProps) { } return ( -
- Logged in as {user} -
- -
+
  • +
    + { user[0] } +
    + Sign Out +
  • ); } @@ -113,10 +117,8 @@ export default class Sidebar extends React.Component { -
    - -
      +
    diff --git a/pkg/ui/styl/layout/navigation-bar.styl b/pkg/ui/styl/layout/navigation-bar.styl index 71d37f0e315d..aab97e02a6ed 100644 --- a/pkg/ui/styl/layout/navigation-bar.styl +++ b/pkg/ui/styl/layout/navigation-bar.styl @@ -67,8 +67,27 @@ $subnav-underline-height = 3px polyline, rect, path, ellipse stroke $link-color - &.cockroach + &.login-indicator padding-top 10px + text-align center + + .login-indicator__initial + border 2px solid $link-color + width 32px + height 32px + border-radius 5px + color $link-color + font-size 18px + line-height 32px + text-align center + margin 0 auto + + a + display inline + padding 0 + + &:hover + color $link-color &.active background-color $navbar-bg From 9f6f519116bdf4254084b3eb493c150b22a1b03c Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Tue, 29 May 2018 15:10:22 -0400 Subject: [PATCH 06/12] ui: add logout route An explicit logout route can be useful, so this adds one. Release note: None --- pkg/ui/src/index.tsx | 2 +- pkg/ui/src/redux/login.ts | 18 +++++++++++++--- pkg/ui/src/routes/login.tsx | 21 +++++++++++++++++-- .../app/components/layoutSidebar/index.tsx | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/pkg/ui/src/index.tsx b/pkg/ui/src/index.tsx index 591b33505220..5a86ca0730d2 100644 --- a/pkg/ui/src/index.tsx +++ b/pkg/ui/src/index.tsx @@ -66,7 +66,7 @@ ReactDOM.render( { /* login */} - { loginRoutes() } + { loginRoutes(store) } diff --git a/pkg/ui/src/redux/login.ts b/pkg/ui/src/redux/login.ts index cabcddf97f5d..2bdf7a0d027f 100644 --- a/pkg/ui/src/redux/login.ts +++ b/pkg/ui/src/redux/login.ts @@ -6,7 +6,7 @@ import { createSelector } from "reselect"; import { createPath } from "src/hacks/createPath"; import { userLogin, userLogout } from "src/util/api"; import { AdminUIState } from "src/redux/state"; -import { LOGIN_PAGE } from "src/routes/login"; +import { LOGIN_PAGE, LOGOUT_PAGE } from "src/routes/login"; import { cockroach } from "src/js/protos"; import { getDataFromServer } from "src/util/dataFromServer"; @@ -100,8 +100,20 @@ export const selectLoginState = createSelector( }, ); -export function getLoginPage(location: Location) { - const query = !location ? undefined : { +function shouldRedirect(location) { + if (!location) { + return false; + } + + if (location.pathname === LOGOUT_PAGE) { + return false; + } + + return true; +} + +export function getLoginPage(location) { + const query = !shouldRedirect(location) ? undefined : { redirectTo: createPath({ pathname: location.pathname, search: location.search, diff --git a/pkg/ui/src/routes/login.tsx b/pkg/ui/src/routes/login.tsx index 08bfeed7ed17..c06c59c5e0ae 100644 --- a/pkg/ui/src/routes/login.tsx +++ b/pkg/ui/src/routes/login.tsx @@ -1,12 +1,29 @@ import React from "react"; import { Route } from "react-router"; +import { Store } from "redux"; +import { doLogout, selectLoginState } from "src/redux/login"; +import { AdminUIState } from "src/redux/state"; import LoginPage from "src/views/login/loginPage"; export const LOGIN_PAGE = "/login"; +export const LOGOUT_PAGE = "/logout"; + +export default function(store: Store): JSX.Element { + function handleLogout(_nextState, replace) { + const loginState = selectLoginState(store.getState()); + + if (!loginState.loggedInUser()) { + return replace(LOGIN_PAGE); + } + + store.dispatch(doLogout()); + } -export default function(): JSX.Element { return ( - + + + + ); } diff --git a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx index 76909fc67de3..9b120c9beaf9 100644 --- a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx +++ b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx @@ -7,6 +7,7 @@ import { Link } from "react-router"; import { AdminUIState } from "src/redux/state"; import { selectLoginState, LoginState, doLogout } from "src/redux/login"; +import { LOGOUT_PAGE } from "src/routes/login"; import { cockroachIcon } from "src/views/shared/components/icons"; import { trustIcon } from "src/util/trust"; From f1ef28694ae64edc20dbd5daacbe5e405dd8674a Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Mon, 4 Jun 2018 15:08:49 -0400 Subject: [PATCH 07/12] ui: fix ts errors from previous changes Some TypeScript errors slipped through due to #26255. This fixes them. Release note: None --- pkg/ui/src/redux/login.ts | 8 +++---- pkg/ui/src/routes/login.tsx | 2 +- .../app/components/layoutSidebar/index.tsx | 2 +- pkg/ui/src/views/login/loginPage.styl | 22 ++++++++++++++++--- pkg/ui/src/views/login/loginPage.tsx | 18 +++++++-------- 5 files changed, 34 insertions(+), 18 deletions(-) diff --git a/pkg/ui/src/redux/login.ts b/pkg/ui/src/redux/login.ts index 2bdf7a0d027f..b7492f43a64c 100644 --- a/pkg/ui/src/redux/login.ts +++ b/pkg/ui/src/redux/login.ts @@ -100,7 +100,7 @@ export const selectLoginState = createSelector( }, ); -function shouldRedirect(location) { +function shouldRedirect(location: Location) { if (!location) { return false; } @@ -112,7 +112,7 @@ function shouldRedirect(location) { return true; } -export function getLoginPage(location) { +export function getLoginPage(location: Location) { const query = !shouldRedirect(location) ? undefined : { redirectTo: createPath({ pathname: location.pathname, @@ -165,10 +165,10 @@ function loginSuccess(loggedInUser: string): LoginSuccessAction { interface LoginFailureAction extends Action { type: typeof LOGIN_FAILURE; - error: string; + error: Error; } -function loginFailure(error: string): LoginFailureAction { +function loginFailure(error: Error): LoginFailureAction { return { type: LOGIN_FAILURE, error, diff --git a/pkg/ui/src/routes/login.tsx b/pkg/ui/src/routes/login.tsx index c06c59c5e0ae..18c9e1c7efeb 100644 --- a/pkg/ui/src/routes/login.tsx +++ b/pkg/ui/src/routes/login.tsx @@ -10,7 +10,7 @@ export const LOGIN_PAGE = "/login"; export const LOGOUT_PAGE = "/logout"; export default function(store: Store): JSX.Element { - function handleLogout(_nextState, replace) { + function handleLogout(_nextState: any, replace: (route: string) => {}) { const loginState = selectLoginState(store.getState()); if (!loginState.loggedInUser()) { diff --git a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx index 9b120c9beaf9..efc7388acb44 100644 --- a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx +++ b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx @@ -86,7 +86,7 @@ function LoginIndicator({ loginState, handleLogout }: LoginIndicatorProps) { > { user[0] }
    - Sign Out + Sign Out ); } diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl index 4c9ab4b1ecb2..f84c8d942114 100644 --- a/pkg/ui/src/views/login/loginPage.styl +++ b/pkg/ui/src/views/login/loginPage.styl @@ -7,6 +7,19 @@ height 100% width 100% position absolute + background-color white + border thin solid grey + + &__info + width 486px + display inline-block + padding 24px + + &__form + background-color grey + width 486px + display inline-block + padding 108px 53px 138px .heading text-transform none @@ -20,12 +33,13 @@ width 350px .input-text + width 100% letter-spacing 2px line-height 17px - padding 12px 24px + padding 12px 18px vertical-align middle border 1px solid $button-border-color - border-radius 4px + border-radius 3px margin 12px 0 color $body-color @@ -33,6 +47,7 @@ border-color $alert-color .submit-button + width 100% text-transform uppercase font-size 14px letter-spacing 2px @@ -40,10 +55,11 @@ padding 12px 24px vertical-align middle border 0px none - border-radius 4px + border-radius 3px margin 24px 0 color $background-color background-color $link-color + cursor pointer &__error color $alert-color diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 7b1e6dbdd221..4df2ef47e1c6 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -32,15 +32,15 @@ class LoginPage extends React.Component) => { + handleUpdateUsername = (evt: React.FormEvent<{ value: string }>) => { this.setState({ - username: evt.target.value, + username: evt.currentTarget.value, }); } - handleUpdatePassword = (evt: React.FormEvent) => { + handleUpdatePassword = (evt: React.FormEvent<{ value: string }>) => { this.setState({ - password: evt.target.value, + password: evt.currentTarget.value, }); } @@ -86,17 +86,17 @@ class LoginPage extends React.Component
    -
    -

    Sign in to the Console

    +

    Please contact your database administrator for account access and password restoration. -

    - For more information, see{" "} - the documentation. + Read the documentation.

    +
    +
    +

    Sign in to the Console

    {this.renderError()}
    Date: Mon, 4 Jun 2018 16:24:17 -0400 Subject: [PATCH 08/12] ui, server: pass build tag to ui This will get shown on the login page. Release note: None --- pkg/server/server.go | 1 + pkg/server/server_test.go | 9 ++++++--- pkg/ui/src/util/dataFromServer.ts | 1 + pkg/ui/ui.go | 1 + 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pkg/server/server.go b/pkg/server/server.go index 2970b52cc83c..19170f611324 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -1928,6 +1928,7 @@ func serveUIAssets(fileServer http.Handler, cfg Config) http.Handler { tmplArgs := ui.IndexHTMLArgs{ ExperimentalUseLogin: cfg.EnableWebSessionAuthentication, LoginEnabled: cfg.RequireWebSession(), + Tag: build.GetInfo().Tag, Version: build.VersionPrefix(), } loggedInUser, ok := request.Context().Value(webSessionUserKey{}).(string) diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index 0308a15b4742..874c555e1a9e 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -998,7 +998,8 @@ func TestServeIndexHTML(t *testing.T) { expected := fmt.Sprintf( htmlTemplate, fmt.Sprintf( - `{"ExperimentalUseLogin":false,"LoginEnabled":false,"LoggedInUser":null,"Version":"%s"}`, + `{"ExperimentalUseLogin":false,"LoginEnabled":false,"LoggedInUser":null,"Tag":"%s","Version":"%s"}`, + build.GetInfo().Tag, build.VersionPrefix(), ), ) @@ -1028,14 +1029,16 @@ func TestServeIndexHTML(t *testing.T) { { loggedInClient, fmt.Sprintf( - `{"ExperimentalUseLogin":true,"LoginEnabled":true,"LoggedInUser":"authentic_user","Version":"%s"}`, + `{"ExperimentalUseLogin":true,"LoginEnabled":true,"LoggedInUser":"authentic_user","Tag":"%s","Version":"%s"}`, + build.GetInfo().Tag, build.VersionPrefix(), ), }, { loggedOutClient, fmt.Sprintf( - `{"ExperimentalUseLogin":true,"LoginEnabled":true,"LoggedInUser":null,"Version":"%s"}`, + `{"ExperimentalUseLogin":true,"LoginEnabled":true,"LoggedInUser":null,"Tag":"%s","Version":"%s"}`, + build.GetInfo().Tag, build.VersionPrefix(), ), }, diff --git a/pkg/ui/src/util/dataFromServer.ts b/pkg/ui/src/util/dataFromServer.ts index 41d3ec560314..fa7642cc8c17 100644 --- a/pkg/ui/src/util/dataFromServer.ts +++ b/pkg/ui/src/util/dataFromServer.ts @@ -2,6 +2,7 @@ export interface DataFromServer { ExperimentalUseLogin: boolean; LoginEnabled: boolean; LoggedInUser: string; + Tag: string; Version: string; } diff --git a/pkg/ui/ui.go b/pkg/ui/ui.go index cf5f750431fb..15fa7913666f 100644 --- a/pkg/ui/ui.go +++ b/pkg/ui/ui.go @@ -79,6 +79,7 @@ type IndexHTMLArgs struct { ExperimentalUseLogin bool LoginEnabled bool LoggedInUser *string + Tag string Version string } From 31f60eb211728f54cbdbdf00dfad1f8ae809787c Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Mon, 4 Jun 2018 16:24:56 -0400 Subject: [PATCH 09/12] ui: update styling of login page This updates the login page styling to the latest designs. Release note: None --- pkg/ui/assets/crdb.png | Bin 0 -> 5280 bytes pkg/ui/assets/docs.svg | 3 + pkg/ui/src/views/login/loginPage.styl | 51 ++++++++++++---- pkg/ui/src/views/login/loginPage.tsx | 84 +++++++++++++++----------- 4 files changed, 90 insertions(+), 48 deletions(-) create mode 100644 pkg/ui/assets/crdb.png create mode 100644 pkg/ui/assets/docs.svg diff --git a/pkg/ui/assets/crdb.png b/pkg/ui/assets/crdb.png new file mode 100644 index 0000000000000000000000000000000000000000..af67498615b6bbea9bb7a1b78b927872c493b75d GIT binary patch literal 5280 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 m2SyPVk>T)RFc=Jm3iyAztotNfze~OV0000 + + diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl index f84c8d942114..0debed901d68 100644 --- a/pkg/ui/src/views/login/loginPage.styl +++ b/pkg/ui/src/views/login/loginPage.styl @@ -8,22 +8,26 @@ width 100% position absolute background-color white - border thin solid grey - &__info + .content + border thin solid $table-border-color + position relative + + &__info.section width 486px display inline-block padding 24px - &__form - background-color grey + &__form.section + background-color $table-border-color width 486px display inline-block padding 108px 53px 138px .heading text-transform none - letter-spacing default + letter-spacing 1px + margin-bottom 24px .aside margin-top 12px @@ -32,9 +36,36 @@ color $body-color width 350px + .version + color $body-color + position absolute + left 12px + top 12px + + .version-tag + color #54b30e + + .logo + height 32px + + .docs-link + display block + margin-top 32px + text-decoration none + color $link-color + + &__icon + position relative + top 6px + + &__text + font-size 17px + line-height 30px + margin-left 6px + .input-text width 100% - letter-spacing 2px + font-size 14px line-height 17px padding 12px 18px vertical-align middle @@ -42,6 +73,7 @@ border-radius 3px margin 12px 0 color $body-color + display block &--error border-color $alert-color @@ -60,13 +92,8 @@ color $background-color background-color $link-color cursor pointer + display block &__error color $alert-color margin 12px 0 - - .image-container - position fixed - height 38px - left 20px - bottom 20px diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 4df2ef47e1c6..99c182324212 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -6,9 +6,14 @@ import { withRouter, WithRouterProps } from "react-router"; import { doLogin, LoginAPIState } from "src/redux/login"; import { AdminUIState } from "src/redux/state"; +import { getDataFromServer } from "src/util/dataFromServer"; import docsURL from "src/util/docs"; import { trustIcon } from "src/util/trust"; -import { cockroachIcon } from "src/views/shared/components/icons"; + +import logo from "assets/crdb.png"; +import docsIcon from "!!raw-loader!assets/docs.svg"; + +const version = getDataFromServer().Tag || "UNKNOWN"; import "./loginPage.styl"; @@ -84,41 +89,48 @@ class LoginPage extends React.Component Login -
    -
    -

    - Please contact your database administrator for - account access and password restoration. -

    -

    - Read the documentation. -

    -
    -
    -

    Sign in to the Console

    - {this.renderError()} - -
    -
    - - -
    +
    +
    +

    + Version: { version } +

    + CockroachDB +

    + Please contact your database administrator for + account access and password restoration. +

    +

    + + + Read the documentation + +

    +
    +
    +

    Sign in to the Console

    + {this.renderError()} +
    + + + +
    +
    +
    ); } From 6d064e0fb1e8019bfd4b1032f9ce4cf940c67c34 Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Mon, 4 Jun 2018 17:11:38 -0400 Subject: [PATCH 10/12] ui: style insecure mode indicator This is temporary styling for the insecure mode indicator. A final design will be implemented later, but this will hold us over for now. Release note: None --- pkg/ui/assets/unlocked.svg | 38 +++++++++++++++++++ .../app/components/layoutSidebar/index.tsx | 9 ++++- pkg/ui/styl/layout/navigation-bar.styl | 10 +++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 pkg/ui/assets/unlocked.svg diff --git a/pkg/ui/assets/unlocked.svg b/pkg/ui/assets/unlocked.svg new file mode 100644 index 000000000000..16bb79c084e9 --- /dev/null +++ b/pkg/ui/assets/unlocked.svg @@ -0,0 +1,38 @@ + + + + +Created by potrace 1.10, written by Peter Selinger 2001-2011 + + + + + diff --git a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx index efc7388acb44..01cf3f8e1e4a 100644 --- a/pkg/ui/src/views/app/components/layoutSidebar/index.tsx +++ b/pkg/ui/src/views/app/components/layoutSidebar/index.tsx @@ -15,6 +15,7 @@ import homeIcon from "!!raw-loader!assets/home.svg"; import metricsIcon from "!!raw-loader!assets/metrics.svg"; import databasesIcon from "!!raw-loader!assets/databases.svg"; import jobsIcon from "!!raw-loader!assets/jobs.svg"; +import unlockedIcon from "!!raw-loader!assets/unlocked.svg"; interface IconLinkProps { icon: string; @@ -70,7 +71,13 @@ function LoginIndicator({ loginState, handleLogout }: LoginIndicatorProps) { } if (!loginState.loginEnabled()) { - return (
    Insecure mode
    ); + return ( +
  • +
    +
    Insecure mode
    +
  • + ); } const user = loginState.loggedInUser(); diff --git a/pkg/ui/styl/layout/navigation-bar.styl b/pkg/ui/styl/layout/navigation-bar.styl index aab97e02a6ed..d0ac4f3d700d 100644 --- a/pkg/ui/styl/layout/navigation-bar.styl +++ b/pkg/ui/styl/layout/navigation-bar.styl @@ -71,6 +71,16 @@ $subnav-underline-height = 3px padding-top 10px text-align center + &--insecure + font-family Lato-Heavy + font-size 8px + text-transform uppercase + text-align center + color $warning-color + + path + fill $warning-color + .login-indicator__initial border 2px solid $link-color width 32px From ee1a743112d2d9ddc55dfc8706adaa0ac394bcac Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Mon, 4 Jun 2018 17:19:29 -0400 Subject: [PATCH 11/12] ui: change copy on sign in button while waiting Release note: None --- pkg/ui/src/views/login/loginPage.styl | 3 +++ pkg/ui/src/views/login/loginPage.tsx | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/ui/src/views/login/loginPage.styl b/pkg/ui/src/views/login/loginPage.styl index 0debed901d68..9ada832546f7 100644 --- a/pkg/ui/src/views/login/loginPage.styl +++ b/pkg/ui/src/views/login/loginPage.styl @@ -94,6 +94,9 @@ cursor pointer display block + &:disabled + background-color #90b8ef + &__error color $alert-color margin 12px 0 diff --git a/pkg/ui/src/views/login/loginPage.tsx b/pkg/ui/src/views/login/loginPage.tsx index 99c182324212..bea1c9cade04 100644 --- a/pkg/ui/src/views/login/loginPage.tsx +++ b/pkg/ui/src/views/login/loginPage.tsx @@ -126,7 +126,7 @@ class LoginPage extends React.Component
    From de8d6f1d38c0b301428678caa1e513c1f7d59578 Mon Sep 17 00:00:00 2001 From: Andrew Couch Date: Thu, 7 Jun 2018 11:34:20 -0400 Subject: [PATCH 12/12] ui: name route creators A few files export functions used to configure routes. These were previously anonymous default exports, this change gives them names. Release note: None --- pkg/ui/ccl/src/routes/visualization.tsx | 2 +- pkg/ui/src/routes/login.tsx | 2 +- pkg/ui/src/routes/visualization.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/ui/ccl/src/routes/visualization.tsx b/pkg/ui/ccl/src/routes/visualization.tsx index 71275aa4a8e9..ee7b484d9b3a 100644 --- a/pkg/ui/ccl/src/routes/visualization.tsx +++ b/pkg/ui/ccl/src/routes/visualization.tsx @@ -13,7 +13,7 @@ import ClusterOverview from "src/views/cluster/containers/clusterOverview"; export const CLUSTERVIZ_ROOT = "/overview/map"; -export default function(): JSX.Element { +export default function createNodeMapRoutes(): JSX.Element { return ( diff --git a/pkg/ui/src/routes/login.tsx b/pkg/ui/src/routes/login.tsx index 18c9e1c7efeb..3771698ea29e 100644 --- a/pkg/ui/src/routes/login.tsx +++ b/pkg/ui/src/routes/login.tsx @@ -9,7 +9,7 @@ import LoginPage from "src/views/login/loginPage"; export const LOGIN_PAGE = "/login"; export const LOGOUT_PAGE = "/logout"; -export default function(store: Store): JSX.Element { +export default function createLoginRoutes(store: Store): JSX.Element { function handleLogout(_nextState: any, replace: (route: string) => {}) { const loginState = selectLoginState(store.getState()); diff --git a/pkg/ui/src/routes/visualization.tsx b/pkg/ui/src/routes/visualization.tsx index 8a1166287339..779a18f42429 100644 --- a/pkg/ui/src/routes/visualization.tsx +++ b/pkg/ui/src/routes/visualization.tsx @@ -19,7 +19,7 @@ class NodesWrapper extends React.Component<{}, {}> { } } -export default function(): JSX.Element { +export default function createClusterOverviewRoutes(): JSX.Element { return (