Skip to content

Commit

Permalink
Merge 05bc41d into bfce9f2
Browse files Browse the repository at this point in the history
  • Loading branch information
Ron-Lavi committed May 20, 2019
2 parents bfce9f2 + 05bc41d commit 46f7dc4
Show file tree
Hide file tree
Showing 17 changed files with 302 additions and 82 deletions.
33 changes: 0 additions & 33 deletions app/assets/stylesheets/login.scss

This file was deleted.

15 changes: 15 additions & 0 deletions app/helpers/login_helper.rb
@@ -0,0 +1,15 @@
module LoginHelper
def login_props
{
token: form_authenticity_token,
version: SETTINGS[:version].version,
caption: Setting[:login_text],
alerts: flash_inline,
logoSrc: image_path("login_logo.png")
}
end

def mount_login
render('common/login', props: login_props)
end
end
2 changes: 2 additions & 0 deletions app/views/common/_login.html.erb
@@ -0,0 +1,2 @@
<div id='login-page'></div>
<%= mount_react_component('LoginPage', '.login-page', props.to_json, flatten_data: true)%>
2 changes: 1 addition & 1 deletion app/views/layouts/base.html.erb
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="<%= I18n.locale %>" data-timezone="<%= iana_timezone %>" class="<%= User.current ? "layout-pf layout-pf-fixed" : "login-pf no-js"%>">
<html lang="<%= I18n.locale %>" data-timezone="<%= iana_timezone %>" class="<%= User.current ? "layout-pf layout-pf-fixed" : "no-js"%>">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
Expand Down
47 changes: 1 addition & 46 deletions app/views/users/login.html.erb
@@ -1,46 +1 @@
<% content_for :title, _('Login') %>
<span id="badge"></span>
<div id="login" class="container">
<div class="row">
<div class="col-sm-12">
<div id="brand">
<%= image_tag("login_logo.png") %>
</div><!--/#brand-->
</div>
<% if flash_inline.any? %>
<div class="col-sm-12">
<% flash_inline.each do |type, message| %>
<div class="alert <%= alert_class(type) %>">
<% header = _('Success!') if type == :success %>
<%= alert_header(header || "", alert_class(type)) %>
<%= message %>
</div>
<% end %>
</div>
<% end %>
<div class="col-sm-7 col-md-6 col-lg-5 login">
<%= form_tag login_users_path, :id => "login-form", :class=>"form-horizontal" do %>
<div class="form-group">
<%= label_tag "login[login]", _("Username"), :class=>"col-sm-2 control-label" %>
<div class="col-sm-10">
<%= text_field :login, :login, {:class=>"form-control", :focus_on_load => true} %>
</div>
</div>
<div class="form-group">
<%= label_tag "login[password]", _("Password"), :class=>"col-sm-2 control-label" %>
<div class="col-sm-10">
<%= password_field_tag 'login[password]', nil, :class => 'form-control' %>
<span class="glyphicon glyphicon-warning-sign input-addon"
title="<%= _('Caps lock ON') %>" style="display:none"></span>
</div>
</div>
<div class="form-group">
<div class="col-xs-offset-8 col-xs-4 submit">
<%= submit_tag(_("Log In").html_safe, :class => "btn btn-primary", :data => { :disable_with => _("Log In") }) %>
</div>
</div>
<% end %>
</div>
<%= render 'welcome_box' %>
</div>
</div>
<%= mount_login %>
9 changes: 9 additions & 0 deletions test/integration/middleware_js_test.rb
@@ -0,0 +1,9 @@
require 'integration_test_helper'

class MiddlewareJSTest < IntegrationTestWithJavascript
test 'login page appears after logout' do
logout_admin
visit '/environments'
assert page.has_selector? 'input[name="login[password]"]'
end
end
1 change: 0 additions & 1 deletion test/integration/middleware_test.rb
Expand Up @@ -39,7 +39,6 @@ class MiddlewareIntegrationTest < ActionDispatch::IntegrationTest
test 'it is added to the Content-Security-Policy as well' do
logout_admin
visit '/environments'
assert page.has_selector? 'input[name="login[password]"]'
assert page.response_headers['Content-Security-Policy'].include?(@webpack_url)
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/integration/user_test.rb
Expand Up @@ -19,8 +19,8 @@ class UserIntegrationTest < IntegrationTestWithJavascript
context "without automatic login" do
def login_admin
end

test "login" do
Capybara.current_driver = Capybara.javascript_driver
visit "/"
fill_in "login_login", :with => users(:admin).login
fill_in "login_password", :with => "secret"
Expand Down
@@ -0,0 +1,15 @@
export const alerts = { error: 'some-error' };
export const backgroundUrl = '/some-background';
export const caption = 'some caption';
export const logoSrc = '/some-logo';
export const token = 'some token';
export const version = 'some version';

export const props = {
alerts,
backgroundUrl,
caption,
logoSrc,
token,
version,
};
@@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { LoginPage as PFLoginPage } from 'patternfly-react';
import { translate as __ } from '../../common/I18n';
import LoginPageCaption from './components/LoginPageCaption';
import { adjustAlerts, defaultFormProps } from './helpers';
import './LoginPage.scss';

const LoginPage = ({
alerts,
backgroundUrl,
caption,
logoSrc,
token,
version,
}) => {
const { modifiedAlerts, submitErrors } = adjustAlerts(alerts);
return (
<PFLoginPage
container={{
backgroundUrl,
alert: modifiedAlerts,
}}
header={{
logoSrc,
caption: <LoginPageCaption version={version} caption={caption} />,
}}
card={{
title: __('Log Into Your Account'),
form: {
...defaultFormProps,
submitError: submitErrors,
additionalFields: (
<input name="authenticity_token" type="hidden" value={token} />
),
},
}}
/>
);
};

LoginPage.propTypes = {
alerts: PropTypes.shape({
success: PropTypes.string,
warning: PropTypes.string,
error: PropTypes.string,
}),
backgroundUrl: PropTypes.string,
caption: PropTypes.string,
logoSrc: PropTypes.string,
token: PropTypes.string.isRequired,
version: PropTypes.string,
};

LoginPage.defaultProps = {
alerts: null,
backgroundUrl: null,
caption: null,
logoSrc: null,
version: null,
};

export default LoginPage;
@@ -0,0 +1,47 @@
@import '~patternfly/dist/sass/patternfly/_color-variables.scss';
@import '~patternfly-react/dist/sass/_login-page.scss';

.login-page {
height: 100%;
overflow: hidden;

.login-pf-header {
margin-bottom: 0 !important; // conflicts with patternfly-sass gem.

h1 {
font-weight: 500;
}
}

.login-pf {
/* stylelint-disable-next-line */
background-image: linear-gradient(
to right,
#005e8c,
#084c75,
#0a3a5e,
#082948,
#041a33
);
}

.login-pf-caption {
color: white;

h1 {
font-weight: 600;
}
}

// patternfly_and_overrides.scss sets all spinners in the app to left.
.spinner {
float: none;
}

// patternfly_and_overrides.scss adjusts all inputs glyphicons.
.form-control + .glyphicon {
position: absolute;
padding: 0;
right: 0;
}
}
@@ -0,0 +1,12 @@
import LoginPage from '../LoginPage';
import { props } from '../LoginPage.fixtures';
import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers';

const fixtures = {
'renders LoginPage': props,
};
describe('AutoComplete', () => {
describe('rendering', () => {
testComponentSnapshotsWithFixtures(LoginPage, fixtures);
});
});
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AutoComplete rendering renders LoginPage 1`] = `
<LoginPage
card={
Object {
"form": Object {
"additionalFields": <input
name="authenticity_token"
type="hidden"
value="some token"
/>,
"attributes": Object {
"action": "/users/login",
"method": "post",
},
"passwordField": Object {
"attributes": Object {
"name": "login[password]",
},
"id": "login_password",
"placeholder": "Password",
"type": "password",
},
"submitError": Array [
"some-error",
],
"submitText": "Log In",
"topErrorOnly": true,
"usernameField": Object {
"attributes": Object {
"autoFocus": true,
"name": "login[login]",
},
"id": "login_login",
"placeholder": "Username",
"type": "text",
},
"validate": true,
},
"title": "Log Into Your Account",
}
}
container={
Object {
"alert": Array [],
"backgroundUrl": "/some-background",
}
}
footerLinks={Array []}
header={
Object {
"caption": <LoginPageCaption
caption="some caption"
version="some version"
/>,
"logoSrc": "/some-logo",
}
}
/>
`;
@@ -0,0 +1,22 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';

const LoginPageCaption = ({ version, caption }) => (
<Fragment>
<h1 id="title">{__('Welcome')}</h1>
{version && <p id="version">{`${__('Version')} ${version}`}</p>}
{caption && <p id="login_text">{caption}</p>}
</Fragment>
);

LoginPageCaption.propTypes = {
caption: PropTypes.string,
version: PropTypes.string,
};

LoginPageCaption.defaultProps = {
caption: null,
version: null,
};

export default LoginPageCaption;

0 comments on commit 46f7dc4

Please sign in to comment.