Add ability to customize theme styles

Showcases how different themes/styles can be supported using
.env variables. If an environemnt name is specified during
the build process, an overrides file will be pulled in to
allow modifications to color and font definitions.

This commit includes possible style modifications with the openpower
env name as an example. To see the openpower changes, add the variable
definition VUE_APP_NAME="openpower" to your .env.development.local file
or build using 'npm run build -- --mode openpower'

- Moves helper imports into vue config to allow for
  specific import order
- Removed helper imports in SFCs

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Iaf7a59c24fda06a7b74e23f2f042fb3300cb2056
diff --git a/src/assets/styles/_obmc-custom.scss b/src/assets/styles/_obmc-custom.scss
index c063458..068364c 100644
--- a/src/assets/styles/_obmc-custom.scss
+++ b/src/assets/styles/_obmc-custom.scss
@@ -1,10 +1,3 @@
-// BMC Helpers must be imported before Bootstrap helpers to
-// take advantage of Bootstrap's use of the Sass !default
-// statement. Moving this helper after results in Bootstrap
-// variables taking precedence over BMC's
-@import "./bmc/helpers";
-@import "./bootstrap/helpers";
-
 // Vendor styles
 @import "./bootstrap";
 @import "~bootstrap-vue/src/index";
diff --git a/src/components/AppHeader/AppHeader.vue b/src/components/AppHeader/AppHeader.vue
index 4162add..b977b5f 100644
--- a/src/components/AppHeader/AppHeader.vue
+++ b/src/components/AppHeader/AppHeader.vue
@@ -160,8 +160,6 @@
 </script>
 
 <style lang="scss">
-@import 'src/assets/styles/helpers';
-
 .app-header {
   .link-skip-nav {
     position: absolute;
diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue
index e1c6fbf..be80171 100644
--- a/src/components/AppNavigation/AppNavigation.vue
+++ b/src/components/AppNavigation/AppNavigation.vue
@@ -213,8 +213,6 @@
 </script>
 
 <style scoped lang="scss">
-@import 'src/assets/styles/helpers';
-
 svg {
   fill: currentColor;
   height: 1.2rem;
diff --git a/src/components/Global/LoadingBar.vue b/src/components/Global/LoadingBar.vue
index d1736d6..8f7b785 100644
--- a/src/components/Global/LoadingBar.vue
+++ b/src/components/Global/LoadingBar.vue
@@ -72,8 +72,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .progress {
   position: absolute;
   left: 0;
diff --git a/src/components/Global/PageContainer.vue b/src/components/Global/PageContainer.vue
index 91bf346..8396bd5 100644
--- a/src/components/Global/PageContainer.vue
+++ b/src/components/Global/PageContainer.vue
@@ -11,8 +11,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 main {
   width: 100%;
   height: 100%;
diff --git a/src/components/Global/PageSection.vue b/src/components/Global/PageSection.vue
index 96f7134..ddf204d 100644
--- a/src/components/Global/PageSection.vue
+++ b/src/components/Global/PageSection.vue
@@ -18,8 +18,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .page-section {
   margin-bottom: $spacer * 2;
 }
diff --git a/src/components/Global/PageTitle.vue b/src/components/Global/PageTitle.vue
index dc0738e..a77e0a0 100644
--- a/src/components/Global/PageTitle.vue
+++ b/src/components/Global/PageTitle.vue
@@ -23,8 +23,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .page-title {
   margin-bottom: $spacer * 2;
 }
diff --git a/src/components/Global/Search.vue b/src/components/Global/Search.vue
index e370355..9ebf468 100644
--- a/src/components/Global/Search.vue
+++ b/src/components/Global/Search.vue
@@ -50,8 +50,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .search-input {
   padding-left: ($spacer * 2);
 }
diff --git a/src/components/Global/StatusIcon.vue b/src/components/Global/StatusIcon.vue
index 5608805..6de6d31 100644
--- a/src/components/Global/StatusIcon.vue
+++ b/src/components/Global/StatusIcon.vue
@@ -31,8 +31,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .status-icon {
   vertical-align: text-bottom;
   &.success {
diff --git a/src/components/Global/TableDateFilter.vue b/src/components/Global/TableDateFilter.vue
index e73d7d5..ab501ea 100644
--- a/src/components/Global/TableDateFilter.vue
+++ b/src/components/Global/TableDateFilter.vue
@@ -165,8 +165,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .b-form-datepicker {
   position: absolute;
   right: 0;
diff --git a/src/components/Global/TableFilter.vue b/src/components/Global/TableFilter.vue
index b514483..d6a954b 100644
--- a/src/components/Global/TableFilter.vue
+++ b/src/components/Global/TableFilter.vue
@@ -131,8 +131,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .badge {
   margin-right: $spacer / 2;
 }
diff --git a/src/components/Global/TableToolbar.vue b/src/components/Global/TableToolbar.vue
index bb18ceb..70389e8 100644
--- a/src/components/Global/TableToolbar.vue
+++ b/src/components/Global/TableToolbar.vue
@@ -68,8 +68,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 $toolbar-height: 46px;
 
 .toolbar-container {
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Italic.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Italic.woff
new file mode 100644
index 0000000..7e62ab4
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Italic.woff
Binary files differ
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Light.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Light.woff
new file mode 100644
index 0000000..8824a0d
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Light.woff
Binary files differ
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-LightItalic.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-LightItalic.woff
new file mode 100644
index 0000000..b079a5e
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-LightItalic.woff
Binary files differ
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Regular.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Regular.woff
new file mode 100644
index 0000000..79bdeab
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Regular.woff
Binary files differ
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBold.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBold.woff
new file mode 100644
index 0000000..ce9534c
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBold.woff
Binary files differ
diff --git a/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBoldItalic.woff b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBoldItalic.woff
new file mode 100644
index 0000000..f00b6ed
--- /dev/null
+++ b/src/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBoldItalic.woff
Binary files differ
diff --git a/src/env/assets/styles/_intel.scss b/src/env/assets/styles/_intel.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/env/assets/styles/_intel.scss
diff --git a/src/env/assets/styles/_openpower.scss b/src/env/assets/styles/_openpower.scss
new file mode 100644
index 0000000..f1bf432
--- /dev/null
+++ b/src/env/assets/styles/_openpower.scss
@@ -0,0 +1,57 @@
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Light.woff') format('woff');
+  font-weight: 200;
+}
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-LightItalic.woff') format('woff');
+  font-weight: 200;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Regular.woff') format('woff');
+  font-weight: 400;
+}
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-Italic.woff') format('woff');
+  font-weight: 400;
+  font-style: italic;
+}
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBold.woff') format('woff');
+  font-weight: 700;
+}
+@font-face {
+  font-family: 'Plex';
+  src: url('~@/env/assets/fonts/IBM_Plex_Sans/IBMPlexSans-SemiBoldItalic.woff') format('woff');
+  font-weight: 700;
+  font-style: italic;
+}
+
+// IBM Plex with Bootstrap default as fallbacks
+// https://getbootstrap.com/docs/4.4/content/reboot/#native-font-stack
+
+$font-family-base: 'Plex', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+
+// IBM gray palette
+$gray-100: #F4F4F4;
+// $gray-200: #E0E0E0; Use default OpenBMC $gray-200
+// $gray-300: #C6C6C6; Use default OpenBMC $gray-300
+$gray-400: #A8A8A8;
+$gray-500: #8D8D8D;
+$gray-600: #6F6F6F;
+$gray-700: #525252;
+$gray-800: #333333;
+$gray-900: #161616;
+
+// IBM theme colors
+$theme-colors: (
+  "primary": #0F62FE,
+  "danger": #DA1E28,
+  "success": #24A146,
+  "warning": #F1C21B
+);
\ No newline at end of file
diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue
index 6950e33..8edc338 100644
--- a/src/layouts/AppLayout.vue
+++ b/src/layouts/AppLayout.vue
@@ -54,8 +54,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .app-container {
   display: grid;
   grid-template-columns: 100%;
diff --git a/src/layouts/LoginLayout.vue b/src/layouts/LoginLayout.vue
index e92cf05..674f4eb 100644
--- a/src/layouts/LoginLayout.vue
+++ b/src/layouts/LoginLayout.vue
@@ -33,8 +33,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .login-container {
   @include media-breakpoint-up(md) {
     background: linear-gradient(
diff --git a/src/views/Control/Kvm/KvmConsole.vue b/src/views/Control/Kvm/KvmConsole.vue
index 080f72e..6881b69 100644
--- a/src/views/Control/Kvm/KvmConsole.vue
+++ b/src/views/Control/Kvm/KvmConsole.vue
@@ -57,7 +57,6 @@
 </script>
 
 <style scoped lang="scss">
-@import 'src/assets/styles/helpers';
 #terminal {
   height: calc(100vh - 42px);
 }
diff --git a/src/views/Control/ServerPowerOperations/BootSettings.vue b/src/views/Control/ServerPowerOperations/BootSettings.vue
index 16d567a..8f54cbb 100644
--- a/src/views/Control/ServerPowerOperations/BootSettings.vue
+++ b/src/views/Control/ServerPowerOperations/BootSettings.vue
@@ -147,8 +147,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 .boot-settings {
   background-color: gray('200');
 }
diff --git a/src/views/Overview/Overview.vue b/src/views/Overview/Overview.vue
index ba93413..46944cc 100644
--- a/src/views/Overview/Overview.vue
+++ b/src/views/Overview/Overview.vue
@@ -154,7 +154,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
 .quicklinks-section {
   margin-bottom: $spacer * 2;
   margin-left: $spacer * -1;
diff --git a/src/views/Overview/OverviewQuickLinks.vue b/src/views/Overview/OverviewQuickLinks.vue
index d3a1940..8dc1c8e 100644
--- a/src/views/Overview/OverviewQuickLinks.vue
+++ b/src/views/Overview/OverviewQuickLinks.vue
@@ -98,8 +98,6 @@
 </script>
 
 <style lang="scss" scoped>
-@import 'src/assets/styles/helpers';
-
 dd,
 dl {
   margin: 0;
diff --git a/vue.config.js b/vue.config.js
index c681f47..8176362 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,6 +1,39 @@
 const CompressionPlugin = require('compression-webpack-plugin');
 
 module.exports = {
+  css: {
+    loaderOptions: {
+      sass: {
+        prependData: () => {
+          const envName = process.env.VUE_APP_ENV_NAME;
+          if (envName !== undefined) {
+            // If there is an env name defined, import Sass
+            // overrides.
+            // It is important that these imports stay in this
+            // order to make sure enviroment overrides
+            // take precedence over the default BMC styles
+            return `
+              @import "@/assets/styles/bmc/helpers";
+              @import "@/env/assets/styles/_${process.env.VUE_APP_ENV_NAME}";
+              @import "@/assets/styles/bootstrap/_helpers";
+            `;
+          } else {
+            // Include helper imports so single file components
+            // do not need to include helper imports
+
+            // BMC Helpers must be imported before Bootstrap helpers to
+            // take advantage of Bootstrap's use of the Sass !default
+            // statement. Moving this helper after results in Bootstrap
+            // variables taking precedence over BMC's
+            return `
+              @import "@/assets/styles/bmc/helpers";
+              @import "@/assets/styles/bootstrap/_helpers";
+            `;
+          }
+        }
+      }
+    }
+  },
   devServer: {
     https: true,
     proxy: {