@afeefa/vue-app 0.0.61 → 0.0.64
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.
- package/.afeefa/package/release/version.txt +1 -1
- package/README.md +3 -1
- package/package.json +1 -1
- package/src/api-resources/ApiAction.js +87 -0
- package/src/api-resources/ApiActions2.js +13 -0
- package/src/api-resources/DeleteAction.js +21 -0
- package/src/api-resources/GetAction.js +18 -0
- package/src/api-resources/ListAction.js +27 -0
- package/src/api-resources/SaveAction.js +15 -0
- package/src/components/AModal.vue +21 -3
- package/src/components/ASearchSelect.vue +2 -2
- package/src/components/ATableRow.vue +4 -0
- package/src/components/flying-context/FlyingContextEvent.js +5 -0
- package/src/components/form/EditForm.vue +30 -8
- package/src/components/form/EditModal.vue +50 -35
- package/src/components/form/FormFieldMixin.js +1 -1
- package/src/components/form/NestedEditForm.vue +4 -0
- package/src/components/list/ListViewMixin.js +2 -2
- package/src/events.js +1 -0
- package/src-admin/bootstrap.js +1 -0
- package/src-admin/components/App.vue +5 -1
- package/src-admin/components/FlyingContext.vue +77 -0
- package/src-admin/components/FlyingContextContainer.vue +85 -0
- package/src-admin/components/app/AppBarButton.vue +10 -2
- package/src-admin/components/controls/SearchSelectFormField.vue +1 -1
- package/src-admin/components/form/EditFormButtons.vue +40 -0
- package/src-admin/components/form/RemoveButton.vue +71 -0
- package/src-admin/components/index.js +7 -8
- package/src-admin/components/list/ListView.vue +19 -5
- package/src-admin/components/pages/EditPage.vue +48 -134
- package/src-admin/components/routes/DataRouteMixin.js +84 -0
- package/src-admin/config/routing.js +0 -11
- package/src-admin/directives/index.js +26 -0
- package/src-admin/models/Model.js +3 -3
- package/src-admin/components/pages/CreatePage.vue +0 -114
- package/src-admin/components/pages/DetailPage.vue +0 -143
- package/src-admin/components/pages/EditPageMixin.js +0 -96
- package/src-admin/components/pages/ListPage.vue +0 -55
- package/src-admin/components/routes/CreateRoute.vue +0 -15
- package/src-admin/components/routes/DetailRoute.vue +0 -85
- package/src-admin/components/routes/EditRoute.vue +0 -78
- package/src-admin/components/routes/ListRoute.vue +0 -110
@@ -0,0 +1,85 @@
|
|
1
|
+
<template>
|
2
|
+
<div
|
3
|
+
id="flyingContextContainer"
|
4
|
+
:class="{visible}"
|
5
|
+
>
|
6
|
+
<a
|
7
|
+
href=""
|
8
|
+
@click.prevent="hide"
|
9
|
+
>close</a>
|
10
|
+
|
11
|
+
<br>
|
12
|
+
<br>
|
13
|
+
|
14
|
+
<div id="flyingContextContainer__children" />
|
15
|
+
</div>
|
16
|
+
</template>
|
17
|
+
|
18
|
+
<script>
|
19
|
+
import { Component, Vue } from '@a-vue'
|
20
|
+
import { FlyingContextEvent } from '@a-vue/events'
|
21
|
+
|
22
|
+
@Component({
|
23
|
+
props: []
|
24
|
+
})
|
25
|
+
export default class FlyingContextContainer extends Vue {
|
26
|
+
visible = false
|
27
|
+
|
28
|
+
mounted () {
|
29
|
+
this.mutationWatcher = new MutationObserver(this.domChanged)
|
30
|
+
this.mutationWatcher.observe(this.getChildrenContainer(), { childList: true })
|
31
|
+
|
32
|
+
window.addEventListener('mousedown', this.onClickOutside)
|
33
|
+
}
|
34
|
+
|
35
|
+
domChanged () {
|
36
|
+
const container = this.getChildrenContainer()
|
37
|
+
this.visible = !!container.children.length
|
38
|
+
}
|
39
|
+
|
40
|
+
hide () {
|
41
|
+
if (this.visible) {
|
42
|
+
this.$events.dispatch(new FlyingContextEvent(FlyingContextEvent.HIDE_ALL))
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
getChildrenContainer () {
|
47
|
+
return this.$el.querySelector('#flyingContextContainer__children')
|
48
|
+
}
|
49
|
+
|
50
|
+
onClickOutside (e) {
|
51
|
+
// check if trigger is clicked
|
52
|
+
let parent = e.target
|
53
|
+
while (parent) {
|
54
|
+
if (parent.classList.contains('flyingContextTrigger')) {
|
55
|
+
return
|
56
|
+
}
|
57
|
+
parent = parent.parentElement
|
58
|
+
}
|
59
|
+
|
60
|
+
// check if flying context ist clicked
|
61
|
+
if (!this.$el.contains(e.target)) {
|
62
|
+
this.hide()
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
</script>
|
67
|
+
|
68
|
+
|
69
|
+
<style lang="scss" scoped>
|
70
|
+
#flyingContextContainer {
|
71
|
+
position: fixed;
|
72
|
+
z-index: 200;
|
73
|
+
right: 0;
|
74
|
+
width: 60vw;
|
75
|
+
height: 80vh;
|
76
|
+
top: 10vh;
|
77
|
+
background: rgba($color: white, $alpha: .6);
|
78
|
+
border: 1px solid black;
|
79
|
+
transition: right .2s;
|
80
|
+
|
81
|
+
&:not(.visible) {
|
82
|
+
right: -80vw;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
</style>
|
@@ -8,12 +8,20 @@
|
|
8
8
|
import { Component, Vue } from '@a-vue'
|
9
9
|
|
10
10
|
@Component({
|
11
|
-
props:
|
11
|
+
props: {
|
12
|
+
prepend: {
|
13
|
+
type: Boolean
|
14
|
+
}
|
15
|
+
}
|
12
16
|
})
|
13
17
|
export default class AppBarButton extends Vue {
|
14
18
|
mounted () {
|
15
19
|
const section = this.getButtonBar()
|
16
|
-
|
20
|
+
if (this.prepend) {
|
21
|
+
section.prepend(this.$el)
|
22
|
+
} else {
|
23
|
+
section.append(this.$el)
|
24
|
+
}
|
17
25
|
}
|
18
26
|
|
19
27
|
destroyed () {
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<template>
|
2
|
+
<a-row gap="2">
|
3
|
+
<v-btn
|
4
|
+
:small="small"
|
5
|
+
:disabled="($has.reset && !changed) || !valid"
|
6
|
+
color="green white--text"
|
7
|
+
@click="$emit('save')"
|
8
|
+
>
|
9
|
+
Speichern
|
10
|
+
</v-btn>
|
11
|
+
|
12
|
+
<v-icon
|
13
|
+
v-if="$has.reset && changed"
|
14
|
+
:small="small"
|
15
|
+
text
|
16
|
+
title="Formular zurücksetzen"
|
17
|
+
@click="$emit('reset')"
|
18
|
+
>
|
19
|
+
{{ undoIcon }}
|
20
|
+
</v-icon>
|
21
|
+
</a-row>
|
22
|
+
</template>
|
23
|
+
|
24
|
+
<script>
|
25
|
+
import { Component, Vue } from '@a-vue'
|
26
|
+
import { mdiRotateLeft} from '@mdi/js'
|
27
|
+
|
28
|
+
@Component({
|
29
|
+
props: [
|
30
|
+
'changed',
|
31
|
+
'valid',
|
32
|
+
'small'
|
33
|
+
]
|
34
|
+
})
|
35
|
+
export default class EditFormButtons extends Vue {
|
36
|
+
$hasOptions = ['reset']
|
37
|
+
|
38
|
+
undoIcon = mdiRotateLeft
|
39
|
+
}
|
40
|
+
</script>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<a-icon-button
|
4
|
+
small
|
5
|
+
color="red white--text"
|
6
|
+
:class="'removeButton-' + dialogId"
|
7
|
+
icon="$trashCanIcon"
|
8
|
+
text="Löschen"
|
9
|
+
@click="remove"
|
10
|
+
/>
|
11
|
+
|
12
|
+
<a-dialog
|
13
|
+
:id="dialogId"
|
14
|
+
:anchor="[document, '.removeButton-' + dialogId]"
|
15
|
+
:active="protect ? removeKey === removeConfirmed : true"
|
16
|
+
>
|
17
|
+
<template v-if="protect">
|
18
|
+
<div>Bitte folgenden Key eingeben: <strong class="removeKey">{{ removeKey }}</strong></div>
|
19
|
+
|
20
|
+
<a-text-field
|
21
|
+
v-model="removeConfirmed"
|
22
|
+
label="Key"
|
23
|
+
:focus="true"
|
24
|
+
width="100"
|
25
|
+
/>
|
26
|
+
</template>
|
27
|
+
</a-dialog>
|
28
|
+
</div>
|
29
|
+
</template>
|
30
|
+
|
31
|
+
|
32
|
+
<script>
|
33
|
+
import { Component, Vue } from '@a-vue'
|
34
|
+
import { DialogEvent } from '@a-vue/events'
|
35
|
+
import { randomCssClass } from '@a-vue/utils/random'
|
36
|
+
|
37
|
+
@Component({
|
38
|
+
props: ['itemTitle', 'protect']
|
39
|
+
})
|
40
|
+
export default class EditPage extends Vue {
|
41
|
+
dialogId = randomCssClass(10)
|
42
|
+
document = document
|
43
|
+
removeKey = null
|
44
|
+
removeConfirmed = null
|
45
|
+
|
46
|
+
async remove () {
|
47
|
+
if (this.protect) {
|
48
|
+
this.removeKey = [...Array(6)].map(() => Math.floor(Math.random() * 16).toString(16)).join('')
|
49
|
+
}
|
50
|
+
|
51
|
+
const result = await this.$events.dispatch(new DialogEvent(DialogEvent.SHOW, {
|
52
|
+
id: this.dialogId,
|
53
|
+
title: this.itemTitle + ' löschen?',
|
54
|
+
message: 'Soll ' + this.itemTitle + ' gelöscht werden?',
|
55
|
+
yesButton: 'Löschen',
|
56
|
+
yesColor: 'red white--text'
|
57
|
+
}))
|
58
|
+
|
59
|
+
if (result === DialogEvent.RESULT_YES) {
|
60
|
+
this.$emit('remove')
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
</script>
|
65
|
+
|
66
|
+
|
67
|
+
<style lang="scss" scoped>
|
68
|
+
.removeKey {
|
69
|
+
user-select: none;
|
70
|
+
}
|
71
|
+
</style>
|
@@ -7,7 +7,9 @@ import DetailContent from './detail/DetailContent'
|
|
7
7
|
import DetailMeta from './detail/DetailMeta'
|
8
8
|
import DetailProperty from './detail/DetailProperty'
|
9
9
|
import DetailTitle from './detail/DetailTitle'
|
10
|
-
import
|
10
|
+
import FlyingContext from './FlyingContext.vue'
|
11
|
+
import EditFormButtons from './form/EditFormButtons'
|
12
|
+
import RemoveButton from './form/RemoveButton'
|
11
13
|
import ListCard from './list/ListCard'
|
12
14
|
import ListColumnHeader from './list/ListColumnHeader'
|
13
15
|
import ListContent from './list/ListContent'
|
@@ -16,10 +18,8 @@ import ListTitle from './list/ListTitle'
|
|
16
18
|
import ListView from './list/ListView'
|
17
19
|
import ModelCount from './model/ModelCount'
|
18
20
|
import ModelIcon from './model/ModelIcon'
|
19
|
-
import CreatePage from './pages/CreatePage'
|
20
|
-
import DetailPage from './pages/DetailPage'
|
21
21
|
import EditPage from './pages/EditPage'
|
22
|
-
import
|
22
|
+
import Start from './Start.vue'
|
23
23
|
|
24
24
|
Vue.component('ListCard', ListCard)
|
25
25
|
Vue.component('ListColumnHeader', ListColumnHeader)
|
@@ -27,11 +27,10 @@ Vue.component('ListContent', ListContent)
|
|
27
27
|
Vue.component('ListMeta', ListMeta)
|
28
28
|
Vue.component('ListTitle', ListTitle)
|
29
29
|
Vue.component('ListView', ListView)
|
30
|
-
Vue.component('ListPage', ListPage)
|
31
|
-
|
32
|
-
Vue.component('CreatePage', CreatePage)
|
33
30
|
|
34
31
|
Vue.component('EditPage', EditPage)
|
32
|
+
Vue.component('EditFormButtons', EditFormButtons)
|
33
|
+
Vue.component('RemoveButton', RemoveButton)
|
35
34
|
|
36
35
|
Vue.component('ModelCount', ModelCount)
|
37
36
|
Vue.component('ModelIcon', ModelIcon)
|
@@ -39,7 +38,6 @@ Vue.component('ModelIcon', ModelIcon)
|
|
39
38
|
Vue.component('DetailContent', DetailContent)
|
40
39
|
Vue.component('DetailMeta', DetailMeta)
|
41
40
|
Vue.component('DetailTitle', DetailTitle)
|
42
|
-
Vue.component('DetailPage', DetailPage)
|
43
41
|
Vue.component('DetailProperty', DetailProperty)
|
44
42
|
Vue.component('DetailColumn', DetailColumn)
|
45
43
|
|
@@ -47,3 +45,4 @@ Vue.component('AppBarButton', AppBarButton)
|
|
47
45
|
Vue.component('AppBarTitle', AppBarTitle)
|
48
46
|
|
49
47
|
Vue.component('Start', Start)
|
48
|
+
Vue.component('FlyingContext', FlyingContext)
|
@@ -28,7 +28,11 @@
|
|
28
28
|
<a-table-row
|
29
29
|
v-for="model in models_"
|
30
30
|
:key="model.id"
|
31
|
-
|
31
|
+
v-flying-context-trigger="hasFlyingContext"
|
32
|
+
:class="{selectable: hasFlyingContext}"
|
33
|
+
v-bind="getRowAttributes(model)"
|
34
|
+
v-on="getRowListeners(model)"
|
35
|
+
@click="$emit('flyingContext', model)"
|
32
36
|
>
|
33
37
|
<v-icon
|
34
38
|
v-if="$has.icon"
|
@@ -50,7 +54,6 @@
|
|
50
54
|
<div
|
51
55
|
v-for="model in models_"
|
52
56
|
:key="model.id"
|
53
|
-
:class="getModelClass(model)"
|
54
57
|
>
|
55
58
|
<slot
|
56
59
|
name="model"
|
@@ -76,7 +79,7 @@ import { ListViewMixin } from '@a-vue/components/list/ListViewMixin'
|
|
76
79
|
import { LoadingEvent } from '@a-vue/events'
|
77
80
|
|
78
81
|
@Component({
|
79
|
-
props: ['
|
82
|
+
props: ['rowAttributes', 'rowListeners']
|
80
83
|
})
|
81
84
|
export default class ListView extends Mixins(ListViewMixin) {
|
82
85
|
$hasOptions = ['icon']
|
@@ -93,8 +96,19 @@ export default class ListView extends Mixins(ListViewMixin) {
|
|
93
96
|
this.$emit('update:isLoading', this.isLoading)
|
94
97
|
}
|
95
98
|
|
96
|
-
|
97
|
-
|
99
|
+
getRowAttributes (model) {
|
100
|
+
if (typeof this.rowAttributes === 'function') {
|
101
|
+
return this.rowAttributes(model)
|
102
|
+
}
|
103
|
+
return this.rowAttributes
|
104
|
+
}
|
105
|
+
|
106
|
+
getRowListeners (model) {
|
107
|
+
return (this.rowListeners && this.rowListeners(model)) || {}
|
108
|
+
}
|
109
|
+
|
110
|
+
get hasFlyingContext () {
|
111
|
+
return !!this.$listeners.flyingContext
|
98
112
|
}
|
99
113
|
|
100
114
|
setFilter (name, value) {
|
@@ -1,151 +1,65 @@
|
|
1
1
|
<template>
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
</app-bar-button>
|
25
|
-
|
26
|
-
<edit-form
|
27
|
-
:model="modelToEdit"
|
28
|
-
:valid.sync="valid"
|
29
|
-
:changed.sync="changed"
|
30
|
-
>
|
31
|
-
<template #fields>
|
32
|
-
<slot
|
33
|
-
name="fields"
|
34
|
-
:model="modelToEdit"
|
35
|
-
/>
|
36
|
-
</template>
|
37
|
-
</edit-form>
|
38
|
-
|
39
|
-
<a-row class="mt-8">
|
40
|
-
<v-btn
|
41
|
-
:disabled="!changed || !valid"
|
42
|
-
color="green white--text"
|
43
|
-
@click="save"
|
44
|
-
>
|
45
|
-
Speichern
|
46
|
-
</v-btn>
|
47
|
-
|
48
|
-
<v-btn
|
49
|
-
v-if="changed"
|
50
|
-
text
|
51
|
-
@click="reset"
|
52
|
-
>
|
53
|
-
Zurücksetzen
|
54
|
-
</v-btn>
|
55
|
-
</a-row>
|
56
|
-
</div>
|
2
|
+
<edit-form
|
3
|
+
ref="form"
|
4
|
+
:model="model"
|
5
|
+
:createModelToEdit="createModelToEdit"
|
6
|
+
>
|
7
|
+
<template #form="{modelToEdit, changed, valid}">
|
8
|
+
<slot
|
9
|
+
name="form"
|
10
|
+
:modelToEdit="modelToEdit"
|
11
|
+
:changed="changed"
|
12
|
+
:valid="valid"
|
13
|
+
/>
|
14
|
+
|
15
|
+
<edit-form-buttons
|
16
|
+
:changed="changed"
|
17
|
+
:valid="valid"
|
18
|
+
:has="{reset: !!modelToEdit.id}"
|
19
|
+
@save="$emit('save', modelToEdit, ignoreChangesOnRouteChange)"
|
20
|
+
@reset="$refs.form.reset()"
|
21
|
+
/>
|
22
|
+
</template>
|
23
|
+
</edit-form>
|
57
24
|
</template>
|
58
25
|
|
59
26
|
<script>
|
60
|
-
import { Component,
|
61
|
-
import {
|
27
|
+
import { Component, Vue } from '@a-vue'
|
28
|
+
import { DialogEvent } from '@a-vue/events'
|
62
29
|
|
63
30
|
@Component({
|
64
|
-
props: [
|
65
|
-
'model',
|
66
|
-
'icon',
|
67
|
-
'title',
|
68
|
-
'listLink',
|
69
|
-
'getAction'
|
70
|
-
]
|
31
|
+
props: ['model', 'createModelToEdit']
|
71
32
|
})
|
72
|
-
export default class EditPage extends
|
73
|
-
|
74
|
-
|
75
|
-
model_ = null
|
33
|
+
export default class EditPage extends Vue {
|
34
|
+
unregisterRouterHook = null
|
35
|
+
ignoreChangesOnRouteChange_ = false
|
76
36
|
|
77
37
|
created () {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
this.reset()
|
90
|
-
}
|
91
|
-
|
92
|
-
get editConfig () {
|
93
|
-
return this.$parent.constructor.getEditRouteConfig(this.$route)
|
94
|
-
}
|
95
|
-
|
96
|
-
get modelUpateAction () {
|
97
|
-
return this.editConfig.updateAction || this.ModelClass.getAction('save')
|
98
|
-
}
|
99
|
-
|
100
|
-
get _getAction () {
|
101
|
-
if (this.getAction) {
|
102
|
-
return this.getAction
|
103
|
-
}
|
104
|
-
return this.ModelClass.getAction('get')
|
105
|
-
}
|
106
|
-
|
107
|
-
get _icon () {
|
108
|
-
return this.icon || this.model.getIcon()
|
109
|
-
}
|
110
|
-
|
111
|
-
get _title () {
|
112
|
-
const title = this.modelToEdit.getTitle()
|
113
|
-
if (title) {
|
114
|
-
return title
|
115
|
-
}
|
116
|
-
|
117
|
-
if (this.title) {
|
118
|
-
return this.title
|
119
|
-
}
|
120
|
-
|
121
|
-
return this.$t('Admin.Types', this.ModelClass.type, null, 'TITLE_EMPTY', 'de')
|
122
|
-
}
|
123
|
-
|
124
|
-
get _listLink () {
|
125
|
-
if (this.listLink) {
|
126
|
-
if (typeof this.listLink === 'function') {
|
127
|
-
return this.listLink()
|
128
|
-
} else {
|
129
|
-
return this.listLink
|
38
|
+
this.unregisterRouterHook = this.$router.beforeEach(async (to, from, next) => {
|
39
|
+
if (this.$refs.form.changed && !this.ignoreChangesOnRouteChange_) {
|
40
|
+
const result = await this.$events.dispatch(new DialogEvent(DialogEvent.SHOW, {
|
41
|
+
title: 'Änderungen verwerfen?',
|
42
|
+
message: 'Im Formular sind nicht gespeicherte Änderungen. Sollen diese verworfen werden?',
|
43
|
+
yesButton: 'Verwerfen'
|
44
|
+
}))
|
45
|
+
if (result === DialogEvent.RESULT_YES) {
|
46
|
+
next()
|
47
|
+
}
|
48
|
+
return
|
130
49
|
}
|
131
|
-
|
132
|
-
|
133
|
-
}
|
134
|
-
|
135
|
-
createModelToEdit () {
|
136
|
-
return this.model_.cloneForEdit(this.fields)
|
50
|
+
next()
|
51
|
+
})
|
137
52
|
}
|
138
53
|
|
139
|
-
|
140
|
-
|
141
|
-
id: this.model.id
|
142
|
-
}
|
54
|
+
destroyed () {
|
55
|
+
this.unregisterRouterHook()
|
143
56
|
}
|
144
57
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
58
|
+
/**
|
59
|
+
* hook to allow to leave a just created (saved) model
|
60
|
+
*/
|
61
|
+
ignoreChangesOnRouteChange () {
|
62
|
+
this.ignoreChangesOnRouteChange_ = true
|
149
63
|
}
|
150
64
|
}
|
151
65
|
</script>
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import { Component, Vue, Watch } from '@a-vue'
|
2
|
+
|
3
|
+
Component.registerHooks([
|
4
|
+
'beforeRouteEnter',
|
5
|
+
'beforeRouteUpdate'
|
6
|
+
])
|
7
|
+
|
8
|
+
let onLoadCallback = () => {}
|
9
|
+
let routerHookCalled = false
|
10
|
+
let lastResult = null // cache last result because of hmr reload
|
11
|
+
|
12
|
+
function onLoad (callback) {
|
13
|
+
onLoadCallback = callback
|
14
|
+
}
|
15
|
+
|
16
|
+
function load (route) {
|
17
|
+
const Component = [...route.matched].pop().components.default
|
18
|
+
|
19
|
+
if (!Component.drm_getActions) {
|
20
|
+
console.warn('A data route component must implement a static drm_getActions() method.')
|
21
|
+
}
|
22
|
+
|
23
|
+
const request = Component.drm_getActions(route, onLoad)
|
24
|
+
if (Array.isArray(request)) {
|
25
|
+
return Promise.all(request.map(request => {
|
26
|
+
return request
|
27
|
+
.dispatchGlobalLoadingEvents()
|
28
|
+
.execute()
|
29
|
+
}))
|
30
|
+
} else {
|
31
|
+
return request
|
32
|
+
.dispatchGlobalLoadingEvents()
|
33
|
+
.execute()
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
@Component
|
38
|
+
export class DataRouteMixin extends Vue {
|
39
|
+
drm_isLoaded = false
|
40
|
+
|
41
|
+
async beforeRouteEnter (to, from, next) {
|
42
|
+
routerHookCalled = true
|
43
|
+
const result = await load(to)
|
44
|
+
|
45
|
+
next(vm => {
|
46
|
+
if (result !== false) {
|
47
|
+
vm.drm_onLoad(result)
|
48
|
+
vm.drm_isLoaded = true
|
49
|
+
}
|
50
|
+
routerHookCalled = false
|
51
|
+
})
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* triggered both, if route name or route params change
|
56
|
+
@Watch('$route.params')
|
57
|
+
async routeParamsChanged () {
|
58
|
+
if (routerHookCalled) {
|
59
|
+
return
|
60
|
+
}
|
61
|
+
|
62
|
+
if (!this.drm_isLoaded) {
|
63
|
+
const result = await load(this.$route)
|
64
|
+
|
65
|
+
if (result !== false) {
|
66
|
+
this.drm_onLoad(result)
|
67
|
+
this.drm_isLoaded = true
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
*/
|
72
|
+
|
73
|
+
drm_onLoad (result) {
|
74
|
+
onLoadCallback(this, result)
|
75
|
+
lastResult = result
|
76
|
+
}
|
77
|
+
|
78
|
+
created () {
|
79
|
+
// hmr reload creates vm but not triggers route enter
|
80
|
+
if (!routerHookCalled) {
|
81
|
+
onLoadCallback(this, lastResult)
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
@@ -1,7 +1,3 @@
|
|
1
|
-
import CreateRoute from '@a-admin/components/routes/CreateRoute'
|
2
|
-
import DetailRoute from '@a-admin/components/routes/DetailRoute'
|
3
|
-
import EditRoute from '@a-admin/components/routes/EditRoute'
|
4
|
-
import ListRoute from '@a-admin/components/routes/ListRoute'
|
5
1
|
import { routeConfigPlugin } from '@a-vue/plugins/route-config/RouteConfigPlugin'
|
6
2
|
|
7
3
|
export default routeConfigPlugin
|
@@ -9,13 +5,6 @@ export default routeConfigPlugin
|
|
9
5
|
linkActiveClass: 'active'
|
10
6
|
})
|
11
7
|
|
12
|
-
.defaultComponents({
|
13
|
-
list: ListRoute,
|
14
|
-
new: CreateRoute,
|
15
|
-
detail: DetailRoute,
|
16
|
-
edit: EditRoute
|
17
|
-
})
|
18
|
-
|
19
8
|
.defaultBreadcrumbTitles({
|
20
9
|
edit: 'Bearbeiten',
|
21
10
|
new: 'Neu'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { Vue } from '@a-vue'
|
2
|
+
|
3
|
+
Vue.directive('flying-context-trigger', {
|
4
|
+
bind: function (el, bindings) {
|
5
|
+
if (bindings.value) {
|
6
|
+
el.$flyingContextObserver = new MutationObserver(() => {
|
7
|
+
if (!el.classList.contains('flyingContextTrigger')) {
|
8
|
+
el.classList.add('flyingContextTrigger')
|
9
|
+
}
|
10
|
+
})
|
11
|
+
|
12
|
+
el.$flyingContextObserver.observe(el, {
|
13
|
+
attributes: true,
|
14
|
+
attributeFilter: ['class']
|
15
|
+
})
|
16
|
+
|
17
|
+
el.classList.add('flyingContextTrigger')
|
18
|
+
}
|
19
|
+
},
|
20
|
+
|
21
|
+
unbind: function (el) {
|
22
|
+
if (el.$flyingContextObserver) {
|
23
|
+
el.$flyingContextObserver.disconnect()
|
24
|
+
}
|
25
|
+
}
|
26
|
+
})
|
@@ -17,11 +17,11 @@ export class Model extends ApiResourcesModel {
|
|
17
17
|
return (new this()).getLink(action)
|
18
18
|
}
|
19
19
|
|
20
|
-
static getAction (
|
20
|
+
static getAction (actionName) {
|
21
21
|
if (this.resourceType) {
|
22
22
|
return apiResources.getAction({
|
23
|
-
|
24
|
-
|
23
|
+
resourceType: this.resourceType,
|
24
|
+
actionName
|
25
25
|
})
|
26
26
|
}
|
27
27
|
console.warn('You can\'t get an action out of a model without resourceType:', this.type)
|