Skip to content

Commit

Permalink
Update login page layout
Browse files Browse the repository at this point in the history
This update will:

- Change the positioning of the form to be on the left
- Add the built on OpenBMC logo to the bottom right corner of the
screen
- Add the ability to include a GUI custom name using a .env variable.
If the variable is not present, the login page will not include the <h1>
section heading element.
- Remove the word "logo" from the alt attribute for the company logo
image used in the application header and on the login page.

Github story: #63

Signed-off-by: Derick Montague <[email protected]>
Change-Id: I83ac5aecff0b3858c3ab5f38ab1aaa603d59acf1
  • Loading branch information
derick-montague committed Sep 2, 2021
1 parent 1908ac9 commit 932aff9
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 116 deletions.
1 change: 1 addition & 0 deletions .env.ibm
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
NODE_ENV=production
VUE_APP_ENV_NAME=ibm
VUE_APP_COMPANY_NAME="IBM"
VUE_APP_GUI_NAME="BMC System Management"
CUSTOM_STYLES=true
CUSTOM_APP_NAV=true
CUSTOM_ROUTER=true
Expand Down
13 changes: 13 additions & 0 deletions src/assets/images/built-on-openbmc-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
2 changes: 1 addition & 1 deletion src/components/AppHeader/AppHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export default {
data() {
return {
isNavigationOpen: false,
altLogo: `${process.env.VUE_APP_COMPANY_NAME} logo`,
altLogo: process.env.VUE_APP_COMPANY_NAME || 'Built on OpenBMC',
};
},
computed: {
Expand Down
108 changes: 81 additions & 27 deletions src/layouts/LoginLayout.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
<template>
<main>
<b-container class="login-container" fluid>
<b-row class="login-row" align-v="center">
<b-col class="login-branding mt-5 mb-5 text-center" md="6">
<div class="login-branding__container">
<div class="login-container">
<div class="login-main">
<div>
<div class="login-brand mb-5">
<img
class="logo"
width="200px"
src="@/assets/images/logo-login.svg"
width="90px"
src="@/assets/images/login-company-logo.svg"
:alt="altLogo"
/>
<h1>OpenBMC</h1>
</div>
</b-col>
<b-col md="6">
<router-view />
</b-col>
</b-row>
</b-container>
<h1 v-if="customizableGuiName" class="h3 mb-5">
{{ customizableGuiName }}
</h1>
<router-view class="login=form form-background" />
</div>
</div>
<div class="login-aside">
<div class="login-aside__logo-brand">
<!-- Add Secondary brand logo if needed -->
</div>
<div class="login-aside__logo-bmc">
<img
height="60px"
src="@/assets/images/built-on-openbmc-logo.svg"
alt="Built on OpenBMC"
/>
</div>
</div>
</div>
</main>
</template>

Expand All @@ -26,33 +37,76 @@ export default {
name: 'LoginLayout',
data() {
return {
altLogo: `${process.env.VUE_APP_COMPANY_NAME} logo`,
altLogo: process.env.VUE_APP_COMPANY_NAME || 'OpenBMC',
customizableGuiName: process.env.VUE_APP_GUI_NAME || '',
};
},
};
</script>

<style lang="scss" scoped>
.login-container {
@include media-breakpoint-up(md) {
background: linear-gradient(
to right,
theme-color('light') 50%,
gray('200') 50%
);
background: gray('100');
display: flex;
flex-direction: column;
gap: $spacer * 2;
max-width: 1400px;
min-width: 320px;
min-height: 100vh;
justify-content: space-around;
@include media-breakpoint-up('md') {
background: $white;
flex-direction: row;
}
}
.login-main {
min-height: 50vh;
padding: $spacer * 3;
@include media-breakpoint-up('md') {
background: gray('100');
display: flex;
flex-direction: column;
flex: 1 1 75%;
min-height: 100vh;
justify-content: center;
align-items: center;
}
}
.login-row {
@include media-breakpoint-up(md) {
.login-form {
@include media-breakpoint-up('md') {
max-width: 360px;
}
}
.login-aside {
display: flex;
align-items: flex-end;
justify-content: flex-end;
gap: $spacer * 1.5;
margin-right: $spacer * 3;
margin-bottom: $spacer;
@include media-breakpoint-up('md') {
min-height: 100vh;
padding-bottom: $spacer;
flex: 1 1 25%;
margin-bottom: 0;
}
}
.login-branding__container {
@include media-breakpoint-up(md) {
float: right;
margin-right: 4rem;
.login-aside__logo-brand:not(:empty) {
&::after {
content: '';
display: inline-block;
height: 2.5rem;
width: 2px;
background-color: gray('200');
margin-left: $spacer * 1.5;
vertical-align: middle;
}
}
</style>
130 changes: 67 additions & 63 deletions src/views/ChangePassword/ChangePassword.vue
Original file line number Diff line number Diff line change
@@ -1,71 +1,73 @@
<template>
<div class="change-password-container mx-auto ml-md-5 mb-3">
<div class="change-password-container">
<alert variant="danger" class="mb-4">
<p v-if="changePasswordError">
{{ $t('pageChangePassword.changePasswordError') }}
</p>
<p v-else>{{ $t('pageChangePassword.changePasswordAlertMessage') }}</p>
</alert>
<dl>
<dt>{{ $t('pageChangePassword.username') }}</dt>
<dd>{{ username }}</dd>
</dl>
<b-form novalidate @submit.prevent="changePassword">
<b-form-group
label-for="password"
:label="$t('pageChangePassword.newPassword')"
>
<input-password-toggle>
<b-form-input
id="password"
v-model="form.password"
autofocus="autofocus"
type="password"
:state="getValidationState($v.form.password)"
class="form-control-with-button"
@change="$v.form.password.$touch()"
>
</b-form-input>
<b-form-invalid-feedback role="alert">
<template v-if="!$v.form.password.required">
{{ $t('global.form.fieldRequired') }}
</template>
</b-form-invalid-feedback>
</input-password-toggle>
</b-form-group>
<b-form-group
label-for="password-confirm"
:label="$t('pageChangePassword.confirmNewPassword')"
>
<input-password-toggle>
<b-form-input
id="password-confirm"
v-model="form.passwordConfirm"
type="password"
:state="getValidationState($v.form.passwordConfirm)"
class="form-control-with-button"
@change="$v.form.passwordConfirm.$touch()"
>
</b-form-input>
<b-form-invalid-feedback role="alert">
<template v-if="!$v.form.passwordConfirm.required">
{{ $t('global.form.fieldRequired') }}
</template>
<template v-else-if="!$v.form.passwordConfirm.sameAsPassword">
{{ $t('global.form.passwordsDoNotMatch') }}
</template>
</b-form-invalid-feedback>
</input-password-toggle>
</b-form-group>
<div class="text-right">
<b-button type="button" variant="link" @click="goBack">
{{ $t('pageChangePassword.goBack') }}
</b-button>
<b-button type="submit" variant="primary">
{{ $t('pageChangePassword.changePassword') }}
</b-button>
</div>
</b-form>
<div class="change-password__form-container">
<dl>
<dt>{{ $t('pageChangePassword.username') }}</dt>
<dd>{{ username }}</dd>
</dl>
<b-form novalidate @submit.prevent="changePassword">
<b-form-group
label-for="password"
:label="$t('pageChangePassword.newPassword')"
>
<input-password-toggle>
<b-form-input
id="password"
v-model="form.password"
autofocus="autofocus"
type="password"
:state="getValidationState($v.form.password)"
class="form-control-with-button"
@change="$v.form.password.$touch()"
>
</b-form-input>
<b-form-invalid-feedback role="alert">
<template v-if="!$v.form.password.required">
{{ $t('global.form.fieldRequired') }}
</template>
</b-form-invalid-feedback>
</input-password-toggle>
</b-form-group>
<b-form-group
label-for="password-confirm"
:label="$t('pageChangePassword.confirmNewPassword')"
>
<input-password-toggle>
<b-form-input
id="password-confirm"
v-model="form.passwordConfirm"
type="password"
:state="getValidationState($v.form.passwordConfirm)"
class="form-control-with-button"
@change="$v.form.passwordConfirm.$touch()"
>
</b-form-input>
<b-form-invalid-feedback role="alert">
<template v-if="!$v.form.passwordConfirm.required">
{{ $t('global.form.fieldRequired') }}
</template>
<template v-else-if="!$v.form.passwordConfirm.sameAsPassword">
{{ $t('global.form.passwordsDoNotMatch') }}
</template>
</b-form-invalid-feedback>
</input-password-toggle>
</b-form-group>
<div class="text-right">
<b-button type="button" variant="link" @click="goBack">
{{ $t('pageChangePassword.goBack') }}
</b-button>
<b-button type="submit" variant="primary">
{{ $t('pageChangePassword.changePassword') }}
</b-button>
</div>
</b-form>
</div>
</div>
</template>

Expand Down Expand Up @@ -124,7 +126,9 @@ export default {
</script>

<style lang="scss" scoped>
.change-password-container {
max-width: 360px;
.change-password__form-container {
@include media-breakpoint-up('md') {
max-width: 360px;
}
}
</style>
41 changes: 17 additions & 24 deletions src/views/Login/Login.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<template>
<b-form
class="login-form mx-auto ml-md-5 mb-3"
novalidate
@submit.prevent="login"
>
<b-form class="login-form" novalidate @submit.prevent="login">
<alert class="login-error mb-4" :show="authError" variant="danger">
<p id="login-error-alert">
{{ $t('pageLogin.alert.message') }}
Expand Down Expand Up @@ -37,25 +33,27 @@
</b-form-group>
<div class="login-form__section mb-3">
<label for="password">{{ $t('pageLogin.password') }}</label>
<b-form-input
id="password"
v-model="userInfo.password"
aria-describedby="login-error-alert password-required"
:state="getValidationState($v.userInfo.password)"
type="password"
data-test-id="login-input-password"
@input="$v.userInfo.password.$touch()"
>
</b-form-input>
<input-password-toggle>
<b-form-input
id="password"
v-model="userInfo.password"
aria-describedby="login-error-alert password-required"
:state="getValidationState($v.userInfo.password)"
type="password"
data-test-id="login-input-password"
class="form-control-with-button"
@input="$v.userInfo.password.$touch()"
>
</b-form-input>
</input-password-toggle>
<b-form-invalid-feedback id="password-required" role="alert">
<template v-if="!$v.userInfo.password.required">
{{ $t('global.form.fieldRequired') }}
</template>
</b-form-invalid-feedback>
</div>
<b-button
block
class="mt-5"
class="mt-3"
type="submit"
variant="primary"
data-test-id="login-button-submit"
Expand All @@ -70,10 +68,11 @@ import { required } from 'vuelidate/lib/validators';
import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
import i18n from '@/i18n';
import Alert from '@/components/Global/Alert';
import InputPasswordToggle from '@/components/Global/InputPasswordToggle';
export default {
name: 'Login',
components: { Alert },
components: { Alert, InputPasswordToggle },
mixins: [VuelidateMixin],
data() {
return {
Expand Down Expand Up @@ -145,9 +144,3 @@ export default {
},
};
</script>

<style lang="scss" scoped>
.login-form {
max-width: 360px;
}
</style>
2 changes: 1 addition & 1 deletion tests/unit/__snapshots__/AppHeader.spec.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ exports[`AppHeader.vue should render correctly 1`] = `
to="/"
>
<img
alt="undefined logo"
alt="Built on OpenBMC"
class="header-logo"
src="@/assets/images/logo-header.svg"
/>
Expand Down

0 comments on commit 932aff9

Please sign in to comment.