@afeefa/vue-app 0.0.173 → 0.0.174

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,176 @@
1
+ <template>
2
+ <div
3
+ v-show="visible"
4
+ id="information-bar"
5
+ :class="{mobile, rail}"
6
+ >
7
+ <div :class="['toggleButton', {rail}]">
8
+ <v-app-bar-nav-icon
9
+ :title="'Menü ' + (rail ? 'ausklappen' : 'einklappen')"
10
+ @click="toggleRail"
11
+ >
12
+ <v-icon>
13
+ {{ rail ? openMenuIcon : closeMenuIcon }}
14
+ </v-icon>
15
+ </v-app-bar-nav-icon>
16
+ </div>
17
+
18
+ <div
19
+ id="information-bar__children"
20
+ :class="{rail}"
21
+ >
22
+ <div class="top" />
23
+
24
+ <div class="bottom" />
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script>
30
+ import { Component, Vue, Watch } from '@a-vue'
31
+ import { mdiBackburger, mdiForwardburger } from '@mdi/js'
32
+ import { SidebarEvent } from '@a-admin/events'
33
+ import { sidebarService, SidebarState } from './sidebar/SidebarService'
34
+
35
+ @Component
36
+ export default class InformationBar extends Vue {
37
+ openMenuIcon = mdiBackburger
38
+ closeMenuIcon = mdiForwardburger
39
+
40
+ visible = false
41
+ mobile = false
42
+ rail = false
43
+
44
+ created () {
45
+ this.$events.on(SidebarEvent.STATUS, ({payload: {information, informationRailed, mobile}}) => {
46
+ this.visible = information
47
+ this.rail = informationRailed
48
+ this.mobile = mobile
49
+ })
50
+ }
51
+
52
+ mounted () {
53
+ this.mutationWatcher = new MutationObserver(this.domChanged)
54
+ this.mutationWatcher.observe(this.$el.querySelector('#information-bar__children > .top'), { childList: true })
55
+ this.mutationWatcher.observe(this.$el.querySelector('#information-bar__children > .bottom'), { childList: true })
56
+ this.domChanged()
57
+ }
58
+
59
+ /**
60
+ * park sidebar children and attach - only for use with HMR which would remove all children on destroy 234567890
61
+ *
62
+ * s
63
+ */
64
+ destroyed () {
65
+ function moveChildren (from, to) {
66
+ for (const child of from.children) {
67
+ to.appendChild(child)
68
+ }
69
+ }
70
+
71
+ const elTop = document.createElement('div')
72
+ document.body.appendChild(elTop)
73
+ moveChildren(this.$el.querySelector('#information-bar__children .top'), elTop)
74
+
75
+ const elBottom = document.createElement('div')
76
+ document.body.appendChild(elBottom)
77
+ moveChildren(this.$el.querySelector('#information-bar__children .bottom'), elBottom)
78
+
79
+ this.$nextTick(() => {
80
+ moveChildren(elTop, document.querySelector('#information-bar__children .top'))
81
+ moveChildren(elBottom, document.querySelector('#information-bar__children .bottom'))
82
+ this.$nextTick(() => {
83
+ this.$events.dispatch(new SidebarEvent(SidebarEvent.STATUS, new SidebarState(sidebarService)))
84
+ })
85
+ })
86
+ }
87
+
88
+ @Watch('rail')
89
+ railChanged () {
90
+ this.$el.style.marginRight = this.rail ? '-240px' : 0
91
+ }
92
+
93
+ toggleRail () {
94
+ sidebarService.setRailInformation(!this.rail)
95
+ }
96
+
97
+ domChanged () {
98
+ const old = this.visible
99
+ const visible = this.hasSidebarItems()
100
+
101
+ if (visible && !old) {
102
+ sidebarService.setInformation(true)
103
+ }
104
+
105
+ if (!visible && old) {
106
+ sidebarService.setInformation(false)
107
+ }
108
+ }
109
+
110
+ getChildrenContainer () {
111
+ return this.$el.querySelector('#information-bar__children')
112
+ }
113
+
114
+ hasSidebarItems () {
115
+ return !!(this.$el.querySelector('#information-bar__children .top').children.length +
116
+ this.$el.querySelector('#information-bar__children .bottom').children.length)
117
+ }
118
+
119
+ hideSidebar () {
120
+ sidebarService.setInformation(false)
121
+ }
122
+ }
123
+ </script>
124
+
125
+
126
+ <style lang="scss" scoped>
127
+ #information-bar {
128
+ position: relative;
129
+
130
+ flex: 0 0 300px;
131
+ width: 300px;
132
+ height: 100vh;
133
+ overflow-y: auto;
134
+
135
+ border-left: 1px solid rgba(0, 0, 0, .12);
136
+ transition: all .2s;
137
+
138
+ background: white;
139
+ padding: 4rem 1.5rem 1.5rem;
140
+
141
+ &.rail {
142
+ padding: 4rem .8rem .8rem;
143
+ }
144
+
145
+ &.mobile {
146
+ position: fixed;
147
+ z-index: 299;
148
+ right: 0;
149
+
150
+ &:not(.rail) {
151
+ border-left: none;
152
+ box-shadow: 0 0 7px #00000066;
153
+ }
154
+ }
155
+ }
156
+
157
+ .toggleButton {
158
+ position: absolute;
159
+ top: 0;
160
+ left: .3rem;
161
+ }
162
+
163
+ #information-bar__children {
164
+ display: flex;
165
+ flex-direction: column;
166
+ justify-content: space-between;
167
+ height: 100%;
168
+ }
169
+
170
+ .top, .bottom {
171
+ display: flex;
172
+ flex-direction: column;
173
+ align-items: flex-start;
174
+ gap: .75rem;
175
+ }
176
+ </style>
@@ -0,0 +1,187 @@
1
+ <template>
2
+ <div
3
+ id="navigation-bar"
4
+ :class="{mobile}"
5
+ >
6
+ <div class="toggleButton">
7
+ <v-app-bar-nav-icon
8
+ title="Menü schließen"
9
+ @click="hideSidebar"
10
+ >
11
+ <v-icon>{{ closeMenuIcon }}</v-icon>
12
+ </v-app-bar-nav-icon>
13
+ </div>
14
+
15
+ <router-link
16
+ :to="{name: rootRouteName}"
17
+ class="logoContainer d-flex flex-column align-center pa-6"
18
+ >
19
+ <img
20
+ v-if="logoUrl"
21
+ class="logo"
22
+ :src="logoUrl"
23
+ >
24
+ <div class="text-button">
25
+ {{ title }}
26
+ </div>
27
+ </router-link>
28
+
29
+ <component
30
+ :is="SidebarMenu"
31
+ class="px-0 mt-0 flex-grow-1"
32
+ />
33
+
34
+ <v-container
35
+ v-if="hasAuthService"
36
+ d-flex
37
+ align-center
38
+ gap-4
39
+ pa-6
40
+ pb-8
41
+ >
42
+ <div class="d-flex align-center gap-3">
43
+ <v-avatar
44
+ color="primary white--text"
45
+ size="40"
46
+ >
47
+ {{ account.first_name.charAt(0).toUpperCase() }}{{ account.last_name.charAt(0).toUpperCase() }}
48
+ </v-avatar>
49
+
50
+ <div>
51
+ <div class="accountName">
52
+ {{ account.first_name }}
53
+ <template v-if="$auth.roles[0]">
54
+ ({{ $auth.roles[0].title }})
55
+ </template>
56
+ </div>
57
+
58
+ <div class="body-2 d-flex align-center">
59
+ <v-icon class="ml-n1 mr-1">
60
+ $logoutIcon
61
+ </v-icon>
62
+ <a @click="logout()">Logout</a>
63
+ </div>
64
+ </div>
65
+
66
+ <a-context-menu v-if="$has.settings">
67
+ <a-context-menu-item
68
+ :to="{name: 'settings', params: {accountId: account.id}}"
69
+ >
70
+ <v-icon>$pencilIcon</v-icon>
71
+ Einstellungen
72
+ </a-context-menu-item>
73
+ </a-context-menu>
74
+ </div>
75
+ </v-container>
76
+ </div>
77
+ </template>
78
+
79
+ <script>
80
+ import { Component, Vue, Watch } from '@a-vue'
81
+ import { mdiBackburger } from '@mdi/js'
82
+ import { adminConfig } from '@a-admin/config/AdminConfig'
83
+ import { SidebarEvent } from '@a-admin/events'
84
+ import { sidebarService } from './sidebar/SidebarService'
85
+
86
+ @Component
87
+ export default class NavigationBar extends Vue {
88
+ $hasOptions = ['settings']
89
+
90
+ closeMenuIcon = mdiBackburger
91
+
92
+ visible = true
93
+ mobile = false
94
+
95
+ created () {
96
+ this.$events.on(SidebarEvent.STATUS, ({payload: {navigation, mobile}}) => {
97
+ this.visible = navigation
98
+ this.mobile = mobile
99
+ })
100
+
101
+ this.mobile = sidebarService.mobile
102
+ }
103
+
104
+ @Watch('visible')
105
+ visibleChanged () {
106
+ this.$el.style.marginLeft = this.visible ? 0 : '-300px'
107
+ }
108
+
109
+ hideSidebar () {
110
+ sidebarService.setNavigation(false)
111
+ }
112
+
113
+ get rootRouteName () {
114
+ return adminConfig.app.rootRouteName || 'root'
115
+ }
116
+
117
+ get logoUrl () {
118
+ return adminConfig.app.logo
119
+ }
120
+
121
+ get title () {
122
+ return adminConfig.app.title
123
+ }
124
+
125
+ get SidebarMenu () {
126
+ return adminConfig.app.components.SidebarMenu
127
+ }
128
+
129
+ get hasAuthService () {
130
+ return !!this.$auth
131
+ }
132
+
133
+ get account () {
134
+ if (this.hasAuthService) {
135
+ return this.$auth.account
136
+ }
137
+ return null
138
+ }
139
+ }
140
+ </script>
141
+
142
+ <style lang="scss" scoped>
143
+ #navigation-bar {
144
+ position: relative;
145
+
146
+ flex: 0 0 300px;
147
+ width: 300px;
148
+ height: 100vh;
149
+ overflow: hidden;
150
+
151
+ border-right: 1px solid rgba(0, 0, 0, .12);
152
+ transition: all .2s;
153
+
154
+ background: white;
155
+ padding-top: 2rem;
156
+
157
+ display: flex;
158
+ flex-direction: column;
159
+ justify-content: space-between;
160
+
161
+ &.mobile {
162
+ position: fixed;
163
+ box-shadow: 0 0 7px #00000066;
164
+ z-index: 299;
165
+ }
166
+ }
167
+
168
+ .toggleButton {
169
+ position: absolute;
170
+ top: 0;
171
+ right: .3rem;
172
+ }
173
+
174
+ .accountName {
175
+ line-height: 1.2;
176
+ word-break: break-all;
177
+ }
178
+
179
+ .logoContainer {
180
+ text-decoration: none;
181
+ }
182
+
183
+ .logo {
184
+ max-height: 80px;
185
+ max-width: 90%;
186
+ }
187
+ </style>
@@ -1,10 +1,23 @@
1
1
  <template>
2
2
  <div
3
3
  id="stickyHeader"
4
- :class="['d-flex align-center gap-8', {visible}]"
4
+ :class="{visible}"
5
5
  >
6
- <app-bar-title-container class="appBarTitle flex-grow-1" />
7
- <app-bar-buttons class="appBarButtons mr-2" />
6
+ <a-row class="topbar">
7
+ <v-app-bar-nav-icon
8
+ v-if="sidebarIconVisible"
9
+ class="mr-2 ml-3"
10
+ title="Menu öffnen"
11
+ @click="openSidebar"
12
+ />
13
+
14
+ <a-breadcrumbs />
15
+ </a-row>
16
+
17
+ <div :class="['d-flex align-center gap-8 mt-2']">
18
+ <app-bar-title-container class="appBarTitle flex-grow-1" />
19
+ <app-bar-buttons class="appBarButtons mr-2" />
20
+ </div>
8
21
  </div>
9
22
  </template>
10
23
 
@@ -12,6 +25,8 @@
12
25
  import { Component, Vue } from '@a-vue'
13
26
  import AppBarButtons from './app/AppBarButtons'
14
27
  import AppBarTitleContainer from './app/AppBarTitleContainer'
28
+ import { SidebarEvent } from '@a-admin/events'
29
+ import { sidebarService } from './sidebar/SidebarService'
15
30
 
16
31
  @Component({
17
32
  components: {
@@ -22,6 +37,12 @@ import AppBarTitleContainer from './app/AppBarTitleContainer'
22
37
  export default class StickyHeader extends Vue {
23
38
  visible = false
24
39
 
40
+ sidebarIconVisible = false
41
+
42
+ created () {
43
+ this.$events.on(SidebarEvent.STATUS, ({payload: {navigation, mobile}}) => (this.sidebarIconVisible = !navigation || mobile))
44
+ }
45
+
25
46
  mounted () {
26
47
  // watch mutation
27
48
  this.mutationWatcher = new MutationObserver(this.domChanged)
@@ -34,7 +55,7 @@ export default class StickyHeader extends Vue {
34
55
  ([e]) => {
35
56
  e.target.classList.toggle('is-pinned', e.intersectionRatio < 1)
36
57
  },
37
- { threshold: [1] }
58
+ { threshold: 1 }
38
59
  )
39
60
  observer.observe(el)
40
61
 
@@ -49,6 +70,10 @@ export default class StickyHeader extends Vue {
49
70
  return !!(this.$el.querySelector('.appBarTitle').children.length +
50
71
  this.$el.querySelector('.appBarButtons').children.length)
51
72
  }
73
+
74
+ openSidebar () {
75
+ sidebarService.setNavigation(true)
76
+ }
52
77
  }
53
78
  </script>
54
79
 
@@ -56,9 +81,9 @@ export default class StickyHeader extends Vue {
56
81
  <style lang="scss" scoped>
57
82
  #stickyHeader {
58
83
  position: sticky;
59
- top: -1px;
60
- margin: 0 -2rem 2rem;
61
- padding: 1rem 2rem;
84
+ left: 0;
85
+ top: -32px;
86
+ padding: .75rem 2rem;
62
87
  background-color: white;
63
88
 
64
89
  &:not(.visible) {
@@ -68,7 +93,13 @@ export default class StickyHeader extends Vue {
68
93
  &.is-pinned {
69
94
  background: white;
70
95
  z-index: 2;
71
- box-shadow: 0 4px 7px -4px #00000033;
96
+ box-shadow: 0 0 7px #00000033;
97
+ }
98
+
99
+ .topbar {
100
+ margin-left: -18px;
101
+ margin-top: -18px;
102
+ height:40px;
72
103
  }
73
104
  }
74
105
  </style>
@@ -14,18 +14,13 @@
14
14
  </v-icon>
15
15
  </v-btn>
16
16
 
17
- <v-avatar
18
- color="#F4F4F4"
19
- size="3rem"
20
- >
21
- <v-icon
22
- :color="icon.color"
23
- size="2.2rem"
24
- v-text="icon.icon"
25
- />
26
- </v-avatar>
17
+ <v-icon
18
+ :color="icon.color"
19
+ size="3.5rem"
20
+ v-text="icon.icon"
21
+ />
27
22
 
28
- <div class="titleContainer">
23
+ <div class="titleContainer ml-n2">
29
24
  <h3 v-if="subtitle">
30
25
  {{ subtitle }}
31
26
  </h3>
@@ -1,18 +1,13 @@
1
1
  <template>
2
2
  <div class="detailProperty">
3
3
  <div class="header">
4
- <v-avatar
4
+ <v-icon
5
5
  v-if="_icon"
6
- color="#F4F4F4"
7
- size="2.5rem"
6
+ :color="_icon.color"
7
+ size="3rem"
8
8
  >
9
- <v-icon
10
- :color="_icon.color"
11
- size="1.5rem"
12
- >
13
- {{ _icon.icon }}
14
- </v-icon>
15
- </v-avatar>
9
+ {{ _icon.icon }}
10
+ </v-icon>
16
11
 
17
12
  <div
18
13
  v-else
@@ -70,26 +65,26 @@ export default class DetailProperty extends Vue {
70
65
  height: 40px;
71
66
  margin-bottom: .5rem;
72
67
 
73
- .v-avatar {
74
- flex: 0 0 40px;
75
- margin-right: 15px;
68
+ > .v-icon {
69
+ flex: 0 0 3rem;
70
+ margin-right: 1.5rem;
76
71
  }
77
72
 
78
73
  .iconPlaceholder {
79
- width: 55px;
74
+ width: 4.5rem;
80
75
  }
81
76
 
82
77
  .label {
83
78
  display: block;
84
79
  text-transform: uppercase;
85
80
  letter-spacing: 3px;
86
- border-bottom: 5px solid #CCCCCC;
81
+ border-bottom: 5px solid #DDDDDD;
87
82
  color: #666666;
88
83
  }
89
84
  }
90
85
 
91
86
  .content {
92
- padding-left: 55px;
87
+ padding-left: 4.5rem;
93
88
  }
94
89
  }
95
90
  </style>
@@ -2,6 +2,7 @@ import Vue from 'vue'
2
2
 
3
3
  import AppBarButton from './app/AppBarButton'
4
4
  import AppBarTitle from './app/AppBarTitle'
5
+ import CollapsibleSection from './CollapsibleSection.vue'
5
6
  import DetailColumn from './detail/DetailColumn'
6
7
  import DetailContent from './detail/DetailContent'
7
8
  import DetailMeta from './detail/DetailMeta'
@@ -11,6 +12,7 @@ import FlyingContext from './FlyingContext.vue'
11
12
  import EditFormButtons from './form/EditFormButtons'
12
13
  import RemoveButton from './form/RemoveButton'
13
14
  import RemoveDialog from './form/RemoveDialog'
15
+ import HSeparator from './HSeparator.vue'
14
16
  import ListCard from './list/ListCard'
15
17
  import ListColumnHeader from './list/ListColumnHeader'
16
18
  import ListContent from './list/ListContent'
@@ -20,9 +22,10 @@ import ListView from './list/ListView'
20
22
  import ModelCount from './model/ModelCount'
21
23
  import ModelIcon from './model/ModelIcon'
22
24
  import EditPage from './pages/EditPage'
23
- import SidebarItem from './SidebarItem.vue'
25
+ import InformationBarItem from './sidebar/InformationBarItem.vue'
24
26
  import Start from './Start.vue'
25
27
  import StickyFooter from './StickyFooter.vue'
28
+ import CollapseTransition from './transitions/CollapseTransition.vue'
26
29
 
27
30
  Vue.component('ListCard', ListCard)
28
31
  Vue.component('ListColumnHeader', ListColumnHeader)
@@ -48,7 +51,11 @@ Vue.component('DetailColumn', DetailColumn)
48
51
  Vue.component('AppBarButton', AppBarButton)
49
52
  Vue.component('AppBarTitle', AppBarTitle)
50
53
 
54
+ Vue.component('HSeparator', HSeparator)
55
+ Vue.component('CollapsibleSection', CollapsibleSection)
56
+ Vue.component('CollapseTransition', CollapseTransition)
57
+
51
58
  Vue.component('Start', Start)
52
59
  Vue.component('FlyingContext', FlyingContext)
53
60
  Vue.component('StickyFooter', StickyFooter)
54
- Vue.component('SidebarItem', SidebarItem)
61
+ Vue.component('InformationBarItem', InformationBarItem)