summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assets/styles/_alerts.scss59
-rw-r--r--src/assets/styles/_buttons.scss23
-rw-r--r--src/assets/styles/_obmc-custom.scss1
-rw-r--r--src/assets/styles/_toast.scss10
-rw-r--r--src/components/Global/Alert.vue33
-rw-r--r--src/components/Global/InputPasswordToggle.vue1
-rw-r--r--src/components/Global/StatusIcon.vue8
-rw-r--r--src/components/Mixins/BVToastMixin.js9
-rw-r--r--src/locales/en-US.json6
-rw-r--r--src/locales/es.json3
-rw-r--r--src/store/modules/Authentication/AuthenticanStore.js5
-rw-r--r--src/views/Login/Login.vue51
-rw-r--r--src/views/Overview/Overview.vue7
13 files changed, 167 insertions, 49 deletions
diff --git a/src/assets/styles/_alerts.scss b/src/assets/styles/_alerts.scss
new file mode 100644
index 00000000..3f103b19
--- /dev/null
+++ b/src/assets/styles/_alerts.scss
@@ -0,0 +1,59 @@
+.alert {
+ display: flex;
+ padding: $spacer;
+ border-width: 0 0 0 3px;
+ color: $gray-800;
+ margin-bottom: $spacer;
+
+ .close {
+ font-weight: 300;
+ opacity: 1;
+ }
+
+ .alert-icon {
+ display: inline-flex;
+ align-items: center;
+ margin-right: $spacer;
+ margin-bottom: $spacer;
+
+ @include media-breakpoint-up(sm) {
+ margin-bottom: 0;
+ }
+ }
+
+ .alert-content {
+ flex: 1 1 auto;
+ }
+
+ .alert-title {
+ margin-bottom: $spacer / 2;
+ }
+
+ .alert-msg {
+ p + p {
+ margin-bottom: $spacer;
+ }
+
+ p:last-of-type {
+ margin-bottom: 0;
+ }
+ }
+
+ &.alert-info {
+ border-left-color: $info;
+ background-color: $info-light;
+ fill: $info;
+ }
+
+ &.alert-danger {
+ border-left-color: $danger;
+ background-color: $danger-light;
+ fill: $danger;
+ }
+
+ &.alert-warning {
+ border-left-color: $warning;
+ background-color: $warning-light;
+ fill: $warning;
+ }
+ } \ No newline at end of file
diff --git a/src/assets/styles/_buttons.scss b/src/assets/styles/_buttons.scss
index 2f961e00..b9b8073b 100644
--- a/src/assets/styles/_buttons.scss
+++ b/src/assets/styles/_buttons.scss
@@ -1,8 +1,14 @@
.btn {
font-weight: $headings-font-weight;
- svg {
- vertical-align: sub;
- margin-left: $spacer / 2;
+ padding-top: $spacer / 2;
+ padding-right: $spacer;
+ padding-bottom: $spacer / 2;
+ padding-left: $spacer;
+
+ // Buttons with SVGs and text expect
+ // text to be wrapped in a span element
+ svg + span {
+ margin-left: $spacer / 4;
}
}
@@ -17,10 +23,21 @@
.btn-link {
fill: $primary;
text-decoration: none !important;
+
&:focus {
box-shadow: $btn-focus-box-shadow;
}
&:hover {
fill: darken($primary, 15%);
}
+}
+
+.btn:disabled {
+ color: $gray-600;
+ fill: currentColor;
+
+ &:not(.btn-link) {
+ border-color: $gray-400;
+ background-color: $gray-400;
+ }
} \ No newline at end of file
diff --git a/src/assets/styles/_obmc-custom.scss b/src/assets/styles/_obmc-custom.scss
index 66cebda2..2a8d896a 100644
--- a/src/assets/styles/_obmc-custom.scss
+++ b/src/assets/styles/_obmc-custom.scss
@@ -39,6 +39,7 @@
@import "~bootstrap-vue/src/index.scss";
+@import "./alerts";
@import "./buttons";
@import "./form-components";
@import "./modal";
diff --git a/src/assets/styles/_toast.scss b/src/assets/styles/_toast.scss
index 538f9968..9295b17e 100644
--- a/src/assets/styles/_toast.scss
+++ b/src/assets/styles/_toast.scss
@@ -4,7 +4,7 @@
.toast {
padding: $spacer/2 $spacer/2 $spacer/2 $spacer;
- border-width: 0 0 0 5px;
+ border-width: 0 0 0 3px;
.close {
font-weight: 300;
opacity: 1;
@@ -25,12 +25,20 @@
.b-toast-success .toast {
border-left-color: $success!important;
+ background-color: $success-light;
+}
+
+.b-toast-info .toast {
+ border-left-color: $info!important;
+ background-color: $info-light;
}
.b-toast-danger .toast {
border-left-color: $danger!important;
+ background-color: $danger-light;
}
.b-toast-warning .toast {
border-left-color: $warning!important;
+ background-color: $warning-light;
} \ No newline at end of file
diff --git a/src/components/Global/Alert.vue b/src/components/Global/Alert.vue
new file mode 100644
index 00000000..bc65b6e9
--- /dev/null
+++ b/src/components/Global/Alert.vue
@@ -0,0 +1,33 @@
+<template>
+ <b-alert :show="show" :variant="variant">
+ <div v-if="variant == 'warning' || variant == 'danger'" class="alert-icon">
+ <status-icon :status="variant" />
+ </div>
+ <div class="alert-content">
+ <div class="alert-msg"><slot /></div>
+ </div>
+ </b-alert>
+</template>
+
+<script>
+import StatusIcon from '../Global/StatusIcon';
+import { BAlert } from 'bootstrap-vue';
+
+export default {
+ name: 'Alert',
+ components: {
+ BAlert: BAlert,
+ StatusIcon: StatusIcon
+ },
+ props: {
+ show: {
+ type: Boolean,
+ default: true
+ },
+ variant: {
+ type: String,
+ default: ''
+ }
+ }
+};
+</script>
diff --git a/src/components/Global/InputPasswordToggle.vue b/src/components/Global/InputPasswordToggle.vue
index 3199cab3..40fb7443 100644
--- a/src/components/Global/InputPasswordToggle.vue
+++ b/src/components/Global/InputPasswordToggle.vue
@@ -52,6 +52,7 @@ export default {
svg {
margin-left: 0;
+ vertical-align: sub;
}
}
</style>
diff --git a/src/components/Global/StatusIcon.vue b/src/components/Global/StatusIcon.vue
index 96074ee6..11143212 100644
--- a/src/components/Global/StatusIcon.vue
+++ b/src/components/Global/StatusIcon.vue
@@ -33,20 +33,20 @@ export default {
.status-icon {
vertical-align: text-bottom;
&.success {
- fill: $success;
+ fill: theme-color('success');
}
&.danger {
- fill: $danger;
+ fill: theme-color('danger');
}
&.secondary {
- fill: $gray-600;
+ fill: gray('600');
svg {
transform: rotate(-45deg);
}
}
&.warning {
- fill: $warning;
+ fill: theme-color('warning');
}
}
</style>
diff --git a/src/components/Mixins/BVToastMixin.js b/src/components/Mixins/BVToastMixin.js
index 4fedc9a4..538bb93c 100644
--- a/src/components/Mixins/BVToastMixin.js
+++ b/src/components/Mixins/BVToastMixin.js
@@ -28,6 +28,15 @@ const BVToastMixin = {
isStatus: true,
solid: true
});
+ },
+ infoToast(message, title = i18n.t('global.status.informational')) {
+ this.$root.$bvToast.toast(message, {
+ title,
+ variant: 'info',
+ noAutoHide: true,
+ isStatus: true,
+ solid: true
+ });
}
}
};
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 0bf40513..63247da6 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -28,7 +28,8 @@
"off": "Off",
"on": "On",
"success": "Success",
- "warning": "Warning"
+ "warning": "Warning",
+ "informational": "Informational"
}
},
"appHeader": {
@@ -133,8 +134,7 @@
"password": "Password",
"username": "Username",
"alert": {
- "title": "Invalid username or password",
- "action": "Try again after verifying your username and password are correct."
+ "message": "Invalid username or password"
}
},
"pageOverview": {
diff --git a/src/locales/es.json b/src/locales/es.json
index 48ed7748..a3e3ee09 100644
--- a/src/locales/es.json
+++ b/src/locales/es.json
@@ -16,8 +16,7 @@
"password": "Contraseña",
"username": "Nombre de usuario",
"alert": {
- "title": "Usuario o contraseña invalido.",
- "action": "Inténtalo de nuevo."
+ "message": "Usuario o contraseña invalido"
},
"form": {
"english": "Inglés",
diff --git a/src/store/modules/Authentication/AuthenticanStore.js b/src/store/modules/Authentication/AuthenticanStore.js
index 975f258b..d64c7308 100644
--- a/src/store/modules/Authentication/AuthenticanStore.js
+++ b/src/store/modules/Authentication/AuthenticanStore.js
@@ -17,8 +17,8 @@ const AuthenticationStore = {
state.authError = false;
state.cookie = Cookies.get('XSRF-TOKEN');
},
- authError(state) {
- state.authError = true;
+ authError(state, authError = true) {
+ state.authError = authError;
},
logout() {
Cookies.remove('XSRF-TOKEN');
@@ -26,6 +26,7 @@ const AuthenticationStore = {
},
actions: {
login({ commit }, auth) {
+ commit('authError', false);
return api
.post('/login', { data: auth })
.then(() => commit('authSuccess'))
diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue
index 2018720c..c15e5f53 100644
--- a/src/views/Login/Login.vue
+++ b/src/views/Login/Login.vue
@@ -15,50 +15,53 @@
</b-col>
<b-col md="6">
<b-form class="login-form" novalidate @submit.prevent="login">
- <b-alert class="login-error" :show="authError" variant="danger">
+ <alert class="login-error" :show="authError" variant="danger">
<p id="login-error-alert">
- <strong>{{ $t('pageLogin.alert.title') }}</strong>
- <span>{{ $t('pageLogin.alert.action') }}</span>
+ {{ $t('pageLogin.alert.message') }}
</p>
- </b-alert>
- <div class="login-form__section">
- <label for="language">{{ $t('pageLogin.language') }}</label>
+ </alert>
+ <b-form-group
+ label-for="language"
+ :label="$t('pageLogin.language')"
+ >
<b-form-select
id="language"
v-model="$i18n.locale"
:options="languages"
></b-form-select>
- </div>
- <div class="login-form__section">
- <label for="username">{{ $t('pageLogin.username') }}</label>
+ </b-form-group>
+ <b-form-group
+ label-for="username"
+ :label="$t('pageLogin.username')"
+ >
<b-form-input
id="username"
v-model="userInfo.username"
- :aria-describedby="authError ? 'login-error-alert' : ''"
+ aria-describedby="login-error-alert username-required"
:state="getValidationState($v.userInfo.username)"
type="text"
autofocus="autofocus"
@input="$v.userInfo.username.$touch()"
>
</b-form-input>
- <b-form-invalid-feedback role="alert">
+ <b-form-invalid-feedback id="username-required" role="alert">
<template v-if="!$v.userInfo.username.required">
{{ $t('global.form.fieldRequired') }}
</template>
</b-form-invalid-feedback>
- </div>
+ </b-form-group>
<div class="login-form__section">
<label for="password">{{ $t('pageLogin.password') }}</label>
<b-form-input
id="password"
v-model="userInfo.password"
- :aria-describedby="authError ? 'login-error-alert' : ''"
+ aria-describedby="login-error-alert password-required"
:state="getValidationState($v.userInfo.password)"
type="password"
@input="$v.userInfo.password.$touch()"
>
</b-form-input>
- <b-form-invalid-feedback role="alert">
+ <b-form-invalid-feedback id="password-required" role="alert">
<template v-if="!$v.userInfo.password.required">
{{ $t('global.form.fieldRequired') }}
</template>
@@ -83,9 +86,11 @@
import { required } from 'vuelidate/lib/validators';
import VuelidateMixin from '../../components/Mixins/VuelidateMixin.js';
import i18n from '../../i18n';
+import Alert from '../../components/Global/Alert';
export default {
name: 'Login',
+ components: { Alert },
mixins: [VuelidateMixin],
data() {
return {
@@ -173,24 +178,8 @@ export default {
margin-bottom: $spacer;
}
-.login-error {
+.alert.login-error {
margin-bottom: $spacer * 2;
-
- p {
- margin-bottom: 0;
- }
-
- strong {
- display: block;
- font-size: 1rem;
- font-weight: 600;
- margin-bottom: 0;
- }
-
- strong + span {
- margin-top: $spacer / 2;
- margin-bottom: 0;
- }
}
.login-branding {
diff --git a/src/views/Overview/Overview.vue b/src/views/Overview/Overview.vue
index 962d9a37..156667bc 100644
--- a/src/views/Overview/Overview.vue
+++ b/src/views/Overview/Overview.vue
@@ -107,8 +107,8 @@ export default {
serverManufacturer: state => state.overview.serverManufacturer,
serverSerialNumber: state => state.overview.serverSerialNumber,
hostName: state => state.global.hostName,
- hostActiveVersion: state => state.firmware.hostActiveVersion,
- bmcActiveVersion: state => state.firmware.bmcActiveVersion,
+ hostFirmwareVersion: state => state.firmware.hostFirmwareVersion,
+ bmcFirmwareVersion: state => state.firmware.bmcFirmwareVersion,
powerCapValue: state => state.powerControl.powerCapValue,
powerConsumptionValue: state => state.powerControl.powerConsumptionValue
}),
@@ -119,7 +119,8 @@ export default {
getOverviewInfo() {
this.$store.dispatch('overview/getServerInfo');
this.$store.dispatch('global/getHostName');
- this.$store.dispatch('firmware/getFirmwareInfo');
+ this.$store.dispatch('firmware/getBmcFirmware');
+ this.$store.dispatch('firmware/getHostFirmware');
this.$store.dispatch('powerControl/getPowerControl');
}
}