diff options
author | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-02-10 23:28:37 +0300 |
---|---|---|
committer | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-02-19 22:17:46 +0300 |
commit | 74f8687d4ab358c071bd081b0b7709eba5a521c2 (patch) | |
tree | 0ff89ca0403a814c39dc73d422824939b2bc1770 /src/components | |
parent | eb154bbc9f71a923563479919578bd5053795980 (diff) | |
download | webui-vue-74f8687d4ab358c071bd081b0b7709eba5a521c2.tar.xz |
Add responsive layout
The main navigation will be collapsed until the viewport
minimum width reaches the Bootstrap defined 'lg' breakpoint
(defaults to 992px).
- Adding motion variables and updating some CSS values to
use existing Sass variables
Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: Id159b84da6adf55fdb15842b0e33b1ede4eeceb4
Diffstat (limited to 'src/components')
-rw-r--r-- | src/components/AppHeader/AppHeader.vue | 70 | ||||
-rw-r--r-- | src/components/AppNavigation/AppNavigation.vue | 202 | ||||
-rw-r--r-- | src/components/Global/PageContainer.vue | 12 |
3 files changed, 217 insertions, 67 deletions
diff --git a/src/components/AppHeader/AppHeader.vue b/src/components/AppHeader/AppHeader.vue index e155a651..39191766 100644 --- a/src/components/AppHeader/AppHeader.vue +++ b/src/components/AppHeader/AppHeader.vue @@ -4,8 +4,21 @@ Skip to content </a> <header id="page-header"> - <b-navbar toggleable="lg" variant="dark" type="dark"> + <b-navbar variant="dark" type="dark"> <!-- Left aligned nav items --> + <b-button + class="nav-trigger" + aria-hidden="true" + title="Open navigation" + type="button" + variant="link" + :aria-expanded="isNavigationOpen" + :class="{ 'nav-open': isNavigationOpen }" + @click="toggleNavigation" + > + <icon-close v-if="isNavigationOpen" /> + <icon-menu v-if="!isNavigationOpen" /> + </b-button> <b-navbar-nav> <b-nav-text>BMC System Management</b-nav-text> </b-navbar-nav> @@ -37,11 +50,19 @@ <script> import IconAvatar from '@carbon/icons-vue/es/user--avatar/20'; +import IconClose from '@carbon/icons-vue/es/close/20'; +import IconMenu from '@carbon/icons-vue/es/menu/20'; import IconRenew from '@carbon/icons-vue/es/renew/20'; import StatusIcon from '../Global/StatusIcon'; + export default { name: 'AppHeader', - components: { IconAvatar, IconRenew, StatusIcon }, + components: { IconAvatar, IconClose, IconMenu, IconRenew, StatusIcon }, + data() { + return { + isNavigationOpen: false + }; + }, computed: { hostStatus() { return this.$store.getters['global/hostStatus']; @@ -77,6 +98,12 @@ export default { this.getHostInfo(); this.getEvents(); }, + mounted() { + this.$root.$on( + 'change:isNavigationOpen', + isNavigationOpen => (this.isNavigationOpen = isNavigationOpen) + ); + }, methods: { getHostInfo() { this.$store.dispatch('global/getHostStatus'); @@ -89,6 +116,9 @@ export default { }, logout() { this.$store.dispatch('authentication/logout'); + }, + toggleNavigation() { + this.$root.$emit('toggle:navigation'); } } }; @@ -99,11 +129,11 @@ export default { position: absolute; top: -60px; left: 0.5rem; - z-index: 10; - transition: 150ms cubic-bezier(0.4, 0.14, 1, 1); + z-index: $zindex-popover; + transition: $duration--moderate-01 $exit-easing--expressive; &:focus { top: 0.5rem; - transition-timing-function: cubic-bezier(0, 0, 0.3, 1); + transition-timing-function: $entrance-easing--expressive; } } .navbar-dark { @@ -113,8 +143,36 @@ export default { } } .nav-item { + fill: $light; +} + +.navbar { + padding: 0; + height: $header-height; + overflow: hidden; +} + +.navbar-nav { + padding: 0 $spacer; +} + +.nav-trigger { + fill: $white; + width: $header-height; + height: $header-height; + transition: none; + svg { - fill: $light; + margin: 0; + } + + &:hover { + fill: $white; + background-color: $gray-900; + } + + @include media-breakpoint-up($responsive-layout-bp) { + display: none; } } </style> diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue index 28f4c715..2847e664 100644 --- a/src/components/AppNavigation/AppNavigation.vue +++ b/src/components/AppNavigation/AppNavigation.vue @@ -1,59 +1,78 @@ <template> - <b-nav vertical> - <b-nav-item to="/"><icon-overview />Overview</b-nav-item> - - <li class="nav-item"> - <b-button v-b-toggle.health-menu variant="link"> - <icon-health />Health - <icon-expand class="icon-expand" /> - </b-button> - <b-collapse id="health-menu" tag="ul" class="nav-item__nav"> - <b-nav-item href="javascript:void(0)">Event Log</b-nav-item> - <b-nav-item href="javascript:void(0)">Hardware Status</b-nav-item> - <b-nav-item href="javascript:void(0)">Sensors</b-nav-item> - </b-collapse> - </li> - - <li class="nav-item"> - <b-button v-b-toggle.control-menu variant="link"> - <icon-control />Control - <icon-expand class="icon-expand" /> - </b-button> - <b-collapse id="control-menu" tag="ul" class="nav-item__nav"> - <b-nav-item href="javascript:void(0)">Manage power usage</b-nav-item> - <b-nav-item href="javascript:void(0)">Server LED</b-nav-item> - <b-nav-item href="javascript:void(0)"> - Server power operations - </b-nav-item> - </b-collapse> - </li> - - <li class="nav-item"> - <b-button v-b-toggle.configuration-menu variant="link"> - <icon-configuration />Configuration - <icon-expand class="icon-expand" /> - </b-button> - <b-collapse id="configuration-menu" tag="ul" class="nav-item__nav"> - <b-nav-item href="javascript:void(0)">Firmware</b-nav-item> - <b-nav-item href="javascript:void(0)">Network settings</b-nav-item> - <b-nav-item href="javascript:void(0)">SNMP settings</b-nav-item> - </b-collapse> - </li> - - <li class="nav-item"> - <b-button v-b-toggle.access-control-menu variant="link"> - <icon-access-control />Access Control - <icon-expand class="icon-expand" /> - </b-button> - <b-collapse id="access-control-menu" tag="ul" class="nav-item__nav"> - <b-nav-item href="javascript:void(0)">LDAP</b-nav-item> - <b-nav-item to="/access-control/local-user-management"> - Local user management - </b-nav-item> - <b-nav-item href="javascript:void(0)">SSL Certificates</b-nav-item> - </b-collapse> - </li> - </b-nav> + <div> + <div class="nav-container" :class="{ open: isNavigationOpen }"> + <nav ref="nav"> + <b-nav vertical> + <b-nav-item to="/"><icon-overview />Overview</b-nav-item> + + <li class="nav-item"> + <b-button v-b-toggle.health-menu variant="link"> + <icon-health />Health + <icon-expand class="icon-expand" /> + </b-button> + <b-collapse id="health-menu" tag="ul" class="nav-item__nav"> + <b-nav-item href="javascript:void(0)">Event Log</b-nav-item> + <b-nav-item href="javascript:void(0)">Hardware Status</b-nav-item> + <b-nav-item href="javascript:void(0)">Sensors</b-nav-item> + </b-collapse> + </li> + + <li class="nav-item"> + <b-button v-b-toggle.control-menu variant="link"> + <icon-control />Control + <icon-expand class="icon-expand" /> + </b-button> + <b-collapse id="control-menu" tag="ul" class="nav-item__nav"> + <b-nav-item href="javascript:void(0)"> + Manage power usage + </b-nav-item> + <b-nav-item href="javascript:void(0)">Server LED</b-nav-item> + <b-nav-item href="javascript:void(0)"> + Server power operations + </b-nav-item> + </b-collapse> + </li> + + <li class="nav-item"> + <b-button v-b-toggle.configuration-menu variant="link"> + <icon-configuration />Configuration + <icon-expand class="icon-expand" /> + </b-button> + <b-collapse id="configuration-menu" tag="ul" class="nav-item__nav"> + <b-nav-item href="javascript:void(0)">Firmware</b-nav-item> + <b-nav-item href="javascript:void(0)"> + Network settings + </b-nav-item> + <b-nav-item href="javascript:void(0)">SNMP settings</b-nav-item> + </b-collapse> + </li> + + <li class="nav-item"> + <b-button v-b-toggle.access-control-menu variant="link"> + <icon-access-control />Access Control + <icon-expand class="icon-expand" /> + </b-button> + <b-collapse id="access-control-menu" tag="ul" class="nav-item__nav"> + <b-nav-item href="javascript:void(0)">LDAP</b-nav-item> + <b-nav-item to="/access-control/local-user-management"> + Local user management + </b-nav-item> + <b-nav-item href="javascript:void(0)"> + SSL Certificates + </b-nav-item> + </b-collapse> + </li> + </b-nav> + </nav> + </div> + <transition name="fade"> + <div + v-if="isNavigationOpen" + class="nav-overlay" + @click="toggleIsOpen" + ></div> + </transition> + </div> </template> <script> @@ -73,6 +92,27 @@ export default { iconConfiguration: IconSettings, iconAccessControl: IconPassword, iconExpand: IconChevronUp + }, + data() { + return { + isNavigationOpen: false + }; + }, + watch: { + $route: function() { + this.isNavigationOpen = false; + }, + isNavigationOpen: function(isNavigationOpen) { + this.$root.$emit('change:isNavigationOpen', isNavigationOpen); + } + }, + mounted() { + this.$root.$on('toggle:navigation', () => this.toggleIsOpen()); + }, + methods: { + toggleIsOpen() { + this.isNavigationOpen = !this.isNavigationOpen; + } } }; </script> @@ -88,7 +128,6 @@ svg { } .nav { - min-height: 100%; padding-top: $spacer; } @@ -155,4 +194,55 @@ svg { background-color: $primary; } } + +.nav-container { + position: fixed; + width: $navigation-width; + top: $header-height; + bottom: 0; + left: 0; + z-index: $zindex-fixed; + overflow-y: auto; + background-color: $gray-200; + transform: translateX(-$navigation-width); + transition: transform $exit-easing--productive $duration--moderate-02; + + &.open { + transform: translateX(0); + transition-timing-function: $entrance-easing--productive; + } + + @include media-breakpoint-up($responsive-layout-bp) { + transition-duration: $duration--fast-01; + transform: translateX(0); + } +} + +.nav-overlay { + position: fixed; + top: $header-height; + bottom: 0; + left: 0; + right: 0; + z-index: $zindex-fixed - 1; + background-color: $black; + opacity: 0.5; + + &.fade-enter-active { + transition: opacity $duration--moderate-02 $entrance-easing--productive; + } + + &.fade-leave-active { + transition: opacity $duration--fast-02 $exit-easing--productive; + } + + &.fade-enter, + &.fade-leave-to { + opacity: 0; + } + + @include media-breakpoint-up($responsive-layout-bp) { + display: none; + } +} </style> diff --git a/src/components/Global/PageContainer.vue b/src/components/Global/PageContainer.vue index 8efbf7b1..8396bd5b 100644 --- a/src/components/Global/PageContainer.vue +++ b/src/components/Global/PageContainer.vue @@ -1,5 +1,5 @@ <template> - <main id="main-content"> + <main id="main-content" class="page-container"> <slot /> </main> </template> @@ -12,12 +12,14 @@ export default { <style lang="scss" scoped> main { + width: 100%; + height: 100%; padding-top: $spacer * 1.5; padding-bottom: $spacer * 3; - padding-left: $spacer * 2; + padding-left: $spacer; padding-right: $spacer; - background-color: $gray-100; - height: 100%; - min-height: calc(100vh - 60px /*header height*/); + @include media-breakpoint-up($responsive-layout-bp) { + padding-left: $spacer * 2; + } } </style> |