xref: /openbmc/webui-vue/src/layouts/AppLayout.vue (revision 06d53863)
1<template>
2  <div class="app-container">
3    <app-header ref="focusTarget" class="app-header" @refresh="refresh" />
4    <app-navigation class="app-navigation" />
5    <page-container class="app-content">
6      <router-view ref="routerView" :key="routerKey" />
7      <!-- Scroll to top button -->
8      <button-back-to-top />
9    </page-container>
10  </div>
11</template>
12
13<script>
14import AppHeader from '@/components/AppHeader';
15import AppNavigation from '@/components/AppNavigation';
16import PageContainer from '@/components/Global/PageContainer';
17import ButtonBackToTop from '@/components/Global/ButtonBackToTop';
18import JumpLinkMixin from '@/components/Mixins/JumpLinkMixin';
19
20export default {
21  name: 'App',
22  components: {
23    AppHeader,
24    AppNavigation,
25    PageContainer,
26    ButtonBackToTop,
27  },
28  mixins: [JumpLinkMixin],
29  data() {
30    return {
31      routerKey: 0,
32    };
33  },
34  watch: {
35    $route: function () {
36      this.$nextTick(function () {
37        this.setFocus(this.$refs.focusTarget.$el);
38      });
39    },
40  },
41  mounted() {
42    this.$root.$on('refresh-application', () => this.refresh());
43  },
44  methods: {
45    refresh() {
46      // Changing the component :key value will trigger
47      // a component re-rendering and 'refresh' the view
48      this.routerKey += 1;
49    },
50  },
51};
52</script>
53
54<style lang="scss" scoped>
55.app-container {
56  display: grid;
57  grid-template-columns: 100%;
58  grid-template-rows: auto;
59  grid-template-areas:
60    'header'
61    'content';
62
63  @include media-breakpoint-up($responsive-layout-bp) {
64    grid-template-columns: $navigation-width 1fr;
65    grid-template-areas:
66      'header header'
67      'navigation content';
68  }
69}
70
71.app-header {
72  grid-area: header;
73  position: sticky;
74  top: 0;
75  z-index: $zindex-fixed + 1;
76}
77
78.app-navigation {
79  grid-area: navigation;
80}
81
82.app-content {
83  grid-area: content;
84  background-color: $white;
85}
86</style>
87