@afeefa/vue-app 0.0.174 → 0.0.176
Sign up to get free protection for your applications and to get access to all the features.
- package/.afeefa/package/release/version.txt +1 -1
- package/package.json +1 -1
- package/src/components/AInfo.vue +4 -0
- package/src/components/ATimePicker.vue +1 -1
- package/src-admin/AfeefaAdmin.js +2 -0
- package/src-admin/components/DetailOrInfo.vue +33 -0
- package/src-admin/components/FlyingContextContainer.vue +21 -1
- package/src-admin/components/InformationBar.vue +2 -2
- package/src-admin/components/StickyHeader.vue +1 -0
- package/src-admin/components/detail/DetailProperty.vue +5 -15
- package/src-admin/components/index.js +9 -7
- package/src-admin/components/list/ListView.vue +1 -1
- package/src-admin/components/sidebar/InformationBarItem.vue +43 -24
- package/src-admin/components/sidebar/SidebarService.js +2 -2
- package/src-admin/config/AdminConfig.js +3 -1
- package/src-admin/models/Model.js +1 -17
- package/src-admin/plugins/IconsPlugin.js +13 -0
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.176
|
package/package.json
CHANGED
package/src/components/AInfo.vue
CHANGED
@@ -67,7 +67,7 @@
|
|
67
67
|
</template>
|
68
68
|
|
69
69
|
<script>
|
70
|
-
import { Component, Watch, Vue } from 'vue
|
70
|
+
import { Component, Watch, Vue } from '@a-vue'
|
71
71
|
import moment from 'moment'
|
72
72
|
import formatHour from '@a-vue/utils/format-hour'
|
73
73
|
import formatMinutes from '@a-vue/utils/format-minutes'
|
package/src-admin/AfeefaAdmin.js
CHANGED
@@ -12,6 +12,7 @@ import routeConfigPlugin from './config/routing'
|
|
12
12
|
import vuetify from './config/vuetify'
|
13
13
|
import { authPlugin } from './plugins/AuthPlugin'
|
14
14
|
import { configPlugin } from './plugins/ConfigPlugin'
|
15
|
+
import { iconsPlugin } from './plugins/IconsPlugin'
|
15
16
|
|
16
17
|
Vue.config.productionTip = false
|
17
18
|
|
@@ -58,6 +59,7 @@ export class AfeefaAdmin {
|
|
58
59
|
adminConfig.app = this._appConfig
|
59
60
|
|
60
61
|
Vue.use(configPlugin)
|
62
|
+
Vue.use(iconsPlugin)
|
61
63
|
|
62
64
|
// authenticate current user before doing any gui-voodo
|
63
65
|
if (this._authService) {
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<template>
|
2
|
+
<information-bar-item
|
3
|
+
v-if="sidebar"
|
4
|
+
v-bind="$attrs"
|
5
|
+
>
|
6
|
+
<template #actionButton>
|
7
|
+
<slot name="actionButton" />
|
8
|
+
</template>
|
9
|
+
|
10
|
+
<slot />
|
11
|
+
</information-bar-item>
|
12
|
+
|
13
|
+
<detail-property
|
14
|
+
v-else
|
15
|
+
v-bind="$attrs"
|
16
|
+
>
|
17
|
+
<template #actionButton>
|
18
|
+
<slot name="actionButton" />
|
19
|
+
</template>
|
20
|
+
|
21
|
+
<slot />
|
22
|
+
</detail-property>
|
23
|
+
</template>
|
24
|
+
|
25
|
+
<script>
|
26
|
+
import { Component, Vue } from '@a-vue'
|
27
|
+
|
28
|
+
@Component({
|
29
|
+
props: [{sidebar: false}]
|
30
|
+
})
|
31
|
+
export default class DetailOrInfo extends Vue {
|
32
|
+
}
|
33
|
+
</script>
|
@@ -46,6 +46,25 @@ export default class FlyingContextContainer extends Vue {
|
|
46
46
|
sizeWatcher.observe(this.getChildrenContainer())
|
47
47
|
}
|
48
48
|
|
49
|
+
/**
|
50
|
+
* park sidebar children and attach - only for use with HMR which would remove all children on destroy 234567890
|
51
|
+
*/
|
52
|
+
destroyed () {
|
53
|
+
function moveChildren (from, to) {
|
54
|
+
for (const child of from.children) {
|
55
|
+
to.appendChild(child)
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
const elTmp = document.createElement('div')
|
60
|
+
document.body.appendChild(elTmp)
|
61
|
+
moveChildren(this.getChildrenContainer(), elTmp)
|
62
|
+
|
63
|
+
this.$nextTick(() => {
|
64
|
+
moveChildren(elTmp, document.querySelector('#flyingContextContainer__children'))
|
65
|
+
})
|
66
|
+
}
|
67
|
+
|
49
68
|
getScrollbarWidth () {
|
50
69
|
const el = document.documentElement
|
51
70
|
const overflowY = getComputedStyle(el)['overflow-y']
|
@@ -157,7 +176,8 @@ export default class FlyingContextContainer extends Vue {
|
|
157
176
|
transition: left .2s;
|
158
177
|
padding: 2rem;
|
159
178
|
overflow-y: auto;
|
160
|
-
box-shadow: 0 0
|
179
|
+
box-shadow: 0 0 17px #00000033;
|
180
|
+
border-left: 1px solid #DDDDDD;
|
161
181
|
|
162
182
|
&:not(.visible) {
|
163
183
|
left: 101vw;
|
@@ -53,13 +53,12 @@ export default class InformationBar extends Vue {
|
|
53
53
|
this.mutationWatcher = new MutationObserver(this.domChanged)
|
54
54
|
this.mutationWatcher.observe(this.$el.querySelector('#information-bar__children > .top'), { childList: true })
|
55
55
|
this.mutationWatcher.observe(this.$el.querySelector('#information-bar__children > .bottom'), { childList: true })
|
56
|
+
|
56
57
|
this.domChanged()
|
57
58
|
}
|
58
59
|
|
59
60
|
/**
|
60
61
|
* park sidebar children and attach - only for use with HMR which would remove all children on destroy 234567890
|
61
|
-
*
|
62
|
-
* s
|
63
62
|
*/
|
64
63
|
destroyed () {
|
65
64
|
function moveChildren (from, to) {
|
@@ -130,6 +129,7 @@ export default class InformationBar extends Vue {
|
|
130
129
|
flex: 0 0 300px;
|
131
130
|
width: 300px;
|
132
131
|
height: 100vh;
|
132
|
+
overflow-x: hidden;
|
133
133
|
overflow-y: auto;
|
134
134
|
|
135
135
|
border-left: 1px solid rgba(0, 0, 0, .12);
|
@@ -2,11 +2,11 @@
|
|
2
2
|
<div class="detailProperty">
|
3
3
|
<div class="header">
|
4
4
|
<v-icon
|
5
|
-
v-if="
|
6
|
-
:color="
|
5
|
+
v-if="icon"
|
6
|
+
:color="icon.color"
|
7
7
|
size="3rem"
|
8
8
|
>
|
9
|
-
{{
|
9
|
+
{{ icon.icon }}
|
10
10
|
</v-icon>
|
11
11
|
|
12
12
|
<div
|
@@ -37,19 +37,9 @@
|
|
37
37
|
import { Component, Vue } from '@a-vue'
|
38
38
|
|
39
39
|
@Component({
|
40
|
-
props: ['icon', '
|
40
|
+
props: ['icon', 'label']
|
41
41
|
})
|
42
42
|
export default class DetailProperty extends Vue {
|
43
|
-
get _icon () {
|
44
|
-
if (this.icon) {
|
45
|
-
return this.icon
|
46
|
-
}
|
47
|
-
|
48
|
-
if (this.iconModelType) {
|
49
|
-
const ModelClass = this.$apiResources.getModelClass(this.iconModelType)
|
50
|
-
return ModelClass.icon
|
51
|
-
}
|
52
|
-
}
|
53
43
|
}
|
54
44
|
</script>
|
55
45
|
|
@@ -63,7 +53,6 @@ export default class DetailProperty extends Vue {
|
|
63
53
|
flex-wrap: nowrap;
|
64
54
|
align-items: center;
|
65
55
|
height: 40px;
|
66
|
-
margin-bottom: .5rem;
|
67
56
|
|
68
57
|
> .v-icon {
|
69
58
|
flex: 0 0 3rem;
|
@@ -84,6 +73,7 @@ export default class DetailProperty extends Vue {
|
|
84
73
|
}
|
85
74
|
|
86
75
|
.content {
|
76
|
+
margin-top: .5rem;
|
87
77
|
padding-left: 4.5rem;
|
88
78
|
}
|
89
79
|
}
|
@@ -2,17 +2,18 @@ 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
|
5
|
+
import CollapsibleSection from './CollapsibleSection'
|
6
6
|
import DetailColumn from './detail/DetailColumn'
|
7
7
|
import DetailContent from './detail/DetailContent'
|
8
8
|
import DetailMeta from './detail/DetailMeta'
|
9
9
|
import DetailProperty from './detail/DetailProperty'
|
10
10
|
import DetailTitle from './detail/DetailTitle'
|
11
|
-
import
|
11
|
+
import DetailOrInfo from './DetailOrInfo'
|
12
|
+
import FlyingContext from './FlyingContext'
|
12
13
|
import EditFormButtons from './form/EditFormButtons'
|
13
14
|
import RemoveButton from './form/RemoveButton'
|
14
15
|
import RemoveDialog from './form/RemoveDialog'
|
15
|
-
import HSeparator from './HSeparator
|
16
|
+
import HSeparator from './HSeparator'
|
16
17
|
import ListCard from './list/ListCard'
|
17
18
|
import ListColumnHeader from './list/ListColumnHeader'
|
18
19
|
import ListContent from './list/ListContent'
|
@@ -22,10 +23,10 @@ import ListView from './list/ListView'
|
|
22
23
|
import ModelCount from './model/ModelCount'
|
23
24
|
import ModelIcon from './model/ModelIcon'
|
24
25
|
import EditPage from './pages/EditPage'
|
25
|
-
import InformationBarItem from './sidebar/InformationBarItem
|
26
|
-
import Start from './Start
|
27
|
-
import StickyFooter from './StickyFooter
|
28
|
-
import CollapseTransition from './transitions/CollapseTransition
|
26
|
+
import InformationBarItem from './sidebar/InformationBarItem'
|
27
|
+
import Start from './Start'
|
28
|
+
import StickyFooter from './StickyFooter'
|
29
|
+
import CollapseTransition from './transitions/CollapseTransition'
|
29
30
|
|
30
31
|
Vue.component('ListCard', ListCard)
|
31
32
|
Vue.component('ListColumnHeader', ListColumnHeader)
|
@@ -59,3 +60,4 @@ Vue.component('Start', Start)
|
|
59
60
|
Vue.component('FlyingContext', FlyingContext)
|
60
61
|
Vue.component('StickyFooter', StickyFooter)
|
61
62
|
Vue.component('InformationBarItem', InformationBarItem)
|
63
|
+
Vue.component('DetailOrInfo', DetailOrInfo)
|
@@ -4,25 +4,37 @@
|
|
4
4
|
:class="['item', infoItemId, {expanded, rail}]"
|
5
5
|
:style="{width}"
|
6
6
|
>
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<v-icon
|
12
|
-
:color="icon.color"
|
13
|
-
size="2rem"
|
7
|
+
<a-row justify-space-between>
|
8
|
+
<div
|
9
|
+
class="header"
|
10
|
+
@click="derail"
|
14
11
|
>
|
15
|
-
|
16
|
-
|
12
|
+
<v-icon
|
13
|
+
v-if="icon"
|
14
|
+
:color="icon.color"
|
15
|
+
size="2rem"
|
16
|
+
>
|
17
|
+
{{ icon.icon }}
|
18
|
+
</v-icon>
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
<div
|
21
|
+
v-else
|
22
|
+
class="iconPlaceholder"
|
23
|
+
/>
|
20
24
|
|
21
|
-
<v-
|
22
|
-
{{
|
23
|
-
|
24
|
-
|
25
|
-
|
25
|
+
<template v-if="!rail">
|
26
|
+
<label class="label">{{ label }}</label>
|
27
|
+
|
28
|
+
<v-icon class="contextButton mt-n1">
|
29
|
+
{{ expanded ? '$caretDownIcon' : '$caretRightIcon' }}
|
30
|
+
</v-icon>
|
31
|
+
</template>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<div v-if="expanded">
|
35
|
+
<slot name="actionButton" />
|
36
|
+
</div>
|
37
|
+
</a-row>
|
26
38
|
|
27
39
|
<collapse-transition>
|
28
40
|
<div
|
@@ -63,9 +75,10 @@ export default class InformationBarItem extends Vue {
|
|
63
75
|
infoItemId = randomCssClass(10)
|
64
76
|
rail = sidebarService.informationRailed
|
65
77
|
expanded = !this.rail && this.open
|
78
|
+
isCreated = false
|
66
79
|
|
67
80
|
created () {
|
68
|
-
this.$events.on(SidebarEvent.STATUS,
|
81
|
+
this.$events.on(SidebarEvent.STATUS, this.railChanged)
|
69
82
|
}
|
70
83
|
|
71
84
|
mounted () {
|
@@ -79,18 +92,24 @@ export default class InformationBarItem extends Vue {
|
|
79
92
|
if (container.contains(el)) {
|
80
93
|
container.removeChild(el)
|
81
94
|
}
|
95
|
+
|
96
|
+
this.$events.off(SidebarEvent.STATUS, this.railChanged)
|
82
97
|
}
|
83
98
|
|
84
|
-
railChanged (
|
85
|
-
if (this.rail ===
|
99
|
+
railChanged ({payload: {informationRailed}}) {
|
100
|
+
if (this.rail === informationRailed) {
|
86
101
|
return
|
87
102
|
}
|
88
103
|
|
89
|
-
this.rail =
|
104
|
+
this.rail = informationRailed
|
90
105
|
|
91
|
-
if (!this.rail) {
|
92
|
-
this.
|
106
|
+
if (!this.rail) { // derailed
|
107
|
+
if (!this.isCreated) { // open only the first time not after subsequent derailing
|
108
|
+
this.expanded = this.open
|
109
|
+
}
|
93
110
|
}
|
111
|
+
|
112
|
+
this.isCreated = true
|
94
113
|
}
|
95
114
|
|
96
115
|
derail () {
|
@@ -172,7 +191,7 @@ export default class InformationBarItem extends Vue {
|
|
172
191
|
border-top: 2px solid #EEEEEE;
|
173
192
|
font-size: .9rem;
|
174
193
|
|
175
|
-
margin: .
|
176
|
-
padding:
|
194
|
+
margin: .25rem -1.5rem;
|
195
|
+
padding: 1rem 1.5rem;
|
177
196
|
}
|
178
197
|
</style>
|
@@ -65,8 +65,8 @@ class SidebarService {
|
|
65
65
|
|
66
66
|
this.information = information
|
67
67
|
|
68
|
-
if (information
|
69
|
-
this.informationRailed =
|
68
|
+
if (information) { // rail if mobile, derail if desktop
|
69
|
+
this.informationRailed = this.mobile
|
70
70
|
}
|
71
71
|
|
72
72
|
eventBus.dispatch(new SidebarEvent(SidebarEvent.STATUS, new SidebarState(this)))
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { translationService } from '@a-admin/services/TranslationService'
|
2
|
-
import { Model as ApiResourcesModel
|
2
|
+
import { Model as ApiResourcesModel } from '@afeefa/api-resources-client'
|
3
3
|
import { mdiAlphaMCircle } from '@mdi/js'
|
4
4
|
|
5
5
|
import { ModelAdminConfig } from './ModelAdminConfig'
|
@@ -7,7 +7,6 @@ import { ModelAdminConfig } from './ModelAdminConfig'
|
|
7
7
|
export { ModelAdminConfig }
|
8
8
|
|
9
9
|
export class Model extends ApiResourcesModel {
|
10
|
-
static resourceType = null
|
11
10
|
static routeName = null
|
12
11
|
static routeIdKey = 'id'
|
13
12
|
|
@@ -17,17 +16,6 @@ export class Model extends ApiResourcesModel {
|
|
17
16
|
return (new this()).getLink(action)
|
18
17
|
}
|
19
18
|
|
20
|
-
static getAction (actionName) {
|
21
|
-
if (this.resourceType) {
|
22
|
-
return apiResources.getAction({
|
23
|
-
resourceType: this.resourceType,
|
24
|
-
actionName
|
25
|
-
})
|
26
|
-
}
|
27
|
-
console.warn('You can\'t get an action out of a model without resourceType:', this.type)
|
28
|
-
return null
|
29
|
-
}
|
30
|
-
|
31
19
|
static get adminConfig () {
|
32
20
|
return new ModelAdminConfig()
|
33
21
|
.setIcon({
|
@@ -53,10 +41,6 @@ export class Model extends ApiResourcesModel {
|
|
53
41
|
}
|
54
42
|
}
|
55
43
|
|
56
|
-
getAction (action) {
|
57
|
-
return this.constructor.getAction(action)
|
58
|
-
}
|
59
|
-
|
60
44
|
getIcon () {
|
61
45
|
return this.constructor.icon
|
62
46
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { adminConfig } from '../config/AdminConfig'
|
2
|
+
|
3
|
+
class IconsPlugin {
|
4
|
+
install (Vue) {
|
5
|
+
Object.defineProperty(Vue.prototype, '$icons', {
|
6
|
+
get () {
|
7
|
+
return adminConfig.app.icons
|
8
|
+
}
|
9
|
+
})
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
export const iconsPlugin = new IconsPlugin()
|