@afeefa/vue-app 0.0.63 → 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/package.json +1 -1
- package/src/components/AModal.vue +21 -3
- package/src/components/ATableRow.vue +4 -0
- package/src/components/flying-context/FlyingContextEvent.js +5 -0
- package/src/components/form/EditForm.vue +4 -3
- package/src/components/form/EditModal.vue +50 -35
- 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/form/EditFormButtons.vue +4 -2
- package/src-admin/components/index.js +2 -7
- package/src-admin/components/list/ListView.vue +19 -5
- package/src-admin/components/pages/EditPage.vue +8 -3
- package/src-admin/components/routes/DataRouteMixin.js +23 -14
- package/src-admin/config/routing.js +0 -11
- package/src-admin/directives/index.js +26 -0
- 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
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.64
|
package/package.json
CHANGED
@@ -7,6 +7,8 @@
|
|
7
7
|
v-bind="$attrs"
|
8
8
|
:contentClass="modalId"
|
9
9
|
transition="v-fade-transition"
|
10
|
+
:persistent="true"
|
11
|
+
:no-click-animation="true"
|
10
12
|
@click:outside="cancel"
|
11
13
|
@keydown.esc="cancel"
|
12
14
|
>
|
@@ -41,7 +43,7 @@ import { getZIndex } from 'vuetify/lib/util/helpers'
|
|
41
43
|
import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
42
44
|
|
43
45
|
@Component({
|
44
|
-
props: ['show', 'title', 'triggerClass', 'anchorPosition']
|
46
|
+
props: ['show', 'title', 'beforeClose', 'triggerClass', 'anchorPosition']
|
45
47
|
})
|
46
48
|
export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentWidthMixin) {
|
47
49
|
modalId = randomCssClass(10)
|
@@ -83,7 +85,15 @@ export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentW
|
|
83
85
|
* and emit a visibility event
|
84
86
|
*/
|
85
87
|
@Watch('show')
|
86
|
-
showChanged () {
|
88
|
+
async showChanged () {
|
89
|
+
// check if a modal is allowed to be closed
|
90
|
+
if (this.modal && !this.show && this.beforeClose) {
|
91
|
+
const result = await this.beforeClose()
|
92
|
+
if (!result) {
|
93
|
+
return
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
87
97
|
this.modal = this.show
|
88
98
|
}
|
89
99
|
|
@@ -121,7 +131,15 @@ export default class ADialog extends Mixins(UsesPositionServiceMixin, ComponentW
|
|
121
131
|
this.urp_registerPositionWatcher(this.position)
|
122
132
|
}
|
123
133
|
|
124
|
-
cancel () {
|
134
|
+
async cancel () {
|
135
|
+
// check if a modal is allowed to be closed
|
136
|
+
if (this.modal && this.beforeClose) {
|
137
|
+
const result = await this.beforeClose()
|
138
|
+
if (!result) {
|
139
|
+
return
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
125
143
|
this.modal = false
|
126
144
|
}
|
127
145
|
|
@@ -4,9 +4,10 @@
|
|
4
4
|
autocomplete="off"
|
5
5
|
>
|
6
6
|
<slot
|
7
|
+
name="form"
|
7
8
|
:changed="changed"
|
8
9
|
:valid="valid"
|
9
|
-
:
|
10
|
+
:modelToEdit="modelToEdit"
|
10
11
|
/>
|
11
12
|
</v-form>
|
12
13
|
</template>
|
@@ -35,8 +36,8 @@ export default class EditForm extends Vue {
|
|
35
36
|
reset () {
|
36
37
|
if (this.createModelToEdit) {
|
37
38
|
this.modelToEdit = this.createModelToEdit(this.model)
|
38
|
-
} else {
|
39
|
-
this.modelToEdit = this.model
|
39
|
+
} else if (this.model) {
|
40
|
+
this.modelToEdit = this.model.cloneForEdit()
|
40
41
|
}
|
41
42
|
this.lastJson = this.json
|
42
43
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
<template>
|
2
2
|
<a-modal
|
3
3
|
:title="title"
|
4
|
+
:beforeClose="beforeClose"
|
4
5
|
:show.sync="show_"
|
5
6
|
v-bind="$attrs"
|
6
7
|
>
|
@@ -10,16 +11,18 @@
|
|
10
11
|
|
11
12
|
<edit-form
|
12
13
|
v-if="show_"
|
14
|
+
ref="form"
|
13
15
|
:model="model"
|
16
|
+
:createModelToEdit="createModelToEdit"
|
14
17
|
>
|
15
|
-
<template #
|
18
|
+
<template #form="{modelToEdit, changed, valid}">
|
16
19
|
<slot
|
17
|
-
name="
|
18
|
-
:
|
20
|
+
name="form"
|
21
|
+
:modelToEdit="modelToEdit"
|
22
|
+
:changed="changed"
|
23
|
+
:valid="valid"
|
19
24
|
/>
|
20
|
-
</template>
|
21
25
|
|
22
|
-
<template #default="{changed, valid}">
|
23
26
|
<a-row
|
24
27
|
class="mt-8 mb-1 pb-1 gap-4"
|
25
28
|
right
|
@@ -31,25 +34,14 @@
|
|
31
34
|
Schließen
|
32
35
|
</v-btn>
|
33
36
|
|
34
|
-
<
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
</v-btn>
|
43
|
-
|
44
|
-
<v-icon
|
45
|
-
v-if="changed"
|
46
|
-
small
|
47
|
-
text
|
48
|
-
@click="reset"
|
49
|
-
>
|
50
|
-
{{ undoIcon }}
|
51
|
-
</v-icon>
|
52
|
-
</a-row>
|
37
|
+
<edit-form-buttons
|
38
|
+
:changed="changed"
|
39
|
+
:valid="valid"
|
40
|
+
small
|
41
|
+
:has="{reset: !!modelToEdit.id}"
|
42
|
+
@save="$emit('save', modelToEdit, ignoreChangesOnClose)"
|
43
|
+
@reset="$refs.form.reset()"
|
44
|
+
/>
|
53
45
|
</a-row>
|
54
46
|
</template>
|
55
47
|
</edit-form>
|
@@ -59,21 +51,26 @@
|
|
59
51
|
|
60
52
|
<script>
|
61
53
|
import { Component, Vue, Watch } from '@a-vue'
|
62
|
-
import {
|
54
|
+
import { DialogEvent } from '@a-vue/events'
|
63
55
|
|
64
56
|
@Component({
|
65
|
-
props: ['model', 'title', 'show']
|
57
|
+
props: ['model', 'createModelToEdit', 'title', 'show']
|
66
58
|
})
|
67
59
|
export default class EditModal extends Vue {
|
68
60
|
show_ = false
|
61
|
+
ignoreChangesOnClose_ = false
|
69
62
|
|
70
|
-
|
63
|
+
created () {
|
64
|
+
if (this.show) { // open on create with v-show
|
65
|
+
this.open()
|
66
|
+
}
|
67
|
+
}
|
71
68
|
|
72
69
|
/**
|
73
70
|
* visiblility changes from outside
|
74
71
|
* this will trigger the show_ watcher,
|
75
72
|
* forward the change to the modal and
|
76
|
-
* later emit
|
73
|
+
* later emit an open/close event
|
77
74
|
*/
|
78
75
|
@Watch('show')
|
79
76
|
showChanged () {
|
@@ -90,7 +87,6 @@ export default class EditModal extends Vue {
|
|
90
87
|
@Watch('show_')
|
91
88
|
show_Changed () {
|
92
89
|
if (this.show_) {
|
93
|
-
this.reset()
|
94
90
|
this.$emit('open')
|
95
91
|
} else {
|
96
92
|
this.$emit('close')
|
@@ -101,16 +97,35 @@ export default class EditModal extends Vue {
|
|
101
97
|
this.show_ = true
|
102
98
|
}
|
103
99
|
|
104
|
-
|
105
|
-
|
100
|
+
async beforeClose () {
|
101
|
+
// run only if show_ is true to prevent double checks with a-modal
|
102
|
+
if (this.show_ && this.$refs.form.changed && !this.ignoreChangesOnClose_) {
|
103
|
+
const result = await this.$events.dispatch(new DialogEvent(DialogEvent.SHOW, {
|
104
|
+
title: 'Änderungen verwerfen?',
|
105
|
+
message: 'Im Formular sind nicht gespeicherte Änderungen. Sollen diese verworfen werden?',
|
106
|
+
yesButton: 'Verwerfen'
|
107
|
+
}))
|
108
|
+
if (result !== DialogEvent.RESULT_YES) {
|
109
|
+
return false
|
110
|
+
}
|
111
|
+
}
|
112
|
+
return true
|
106
113
|
}
|
107
114
|
|
108
|
-
|
109
|
-
this
|
115
|
+
async close () {
|
116
|
+
const result = await this.beforeClose()
|
117
|
+
if (!result) {
|
118
|
+
return
|
119
|
+
}
|
120
|
+
|
121
|
+
this.show_ = false
|
110
122
|
}
|
111
123
|
|
112
|
-
|
113
|
-
|
124
|
+
/**
|
125
|
+
* hook to allow to leave a just created (saved) model
|
126
|
+
*/
|
127
|
+
ignoreChangesOnClose () {
|
128
|
+
this.ignoreChangesOnClose_ = true
|
114
129
|
}
|
115
130
|
}
|
116
131
|
</script>
|
package/src/events.js
CHANGED
@@ -2,3 +2,4 @@ export { LoadingEvent } from './components/loading-indicator/LoadingEvent'
|
|
2
2
|
export { SaveEvent } from './components/save-indicator/SaveEvent'
|
3
3
|
export { AlertEvent } from './components/alert/AlertEvent'
|
4
4
|
export { DialogEvent } from './components/dialog/DialogEvent'
|
5
|
+
export { FlyingContextEvent } from './components/flying-context/FlyingContextEvent'
|
package/src-admin/bootstrap.js
CHANGED
@@ -91,6 +91,8 @@
|
|
91
91
|
</v-list>
|
92
92
|
</v-navigation-drawer>
|
93
93
|
|
94
|
+
<flying-context-container />
|
95
|
+
|
94
96
|
<v-app-bar
|
95
97
|
app
|
96
98
|
flat
|
@@ -142,12 +144,14 @@ import { appConfig } from '@a-admin/config/AppConfig'
|
|
142
144
|
import { sleep } from '@a-vue/utils/timeout'
|
143
145
|
import AppBarButtons from './app/AppBarButtons'
|
144
146
|
import AppBarTitleContainer from './app/AppBarTitleContainer'
|
147
|
+
import FlyingContextContainer from './FlyingContextContainer'
|
145
148
|
import '../styles.scss'
|
146
149
|
|
147
150
|
@Component({
|
148
151
|
components: {
|
149
152
|
AppBarButtons,
|
150
|
-
AppBarTitleContainer
|
153
|
+
AppBarTitleContainer,
|
154
|
+
FlyingContextContainer
|
151
155
|
}
|
152
156
|
})
|
153
157
|
export default class App extends Vue {
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="flyingContext">
|
3
|
+
<div :class="contextId">
|
4
|
+
<slot v-if="isVisible" />
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
</template>
|
8
|
+
|
9
|
+
<script>
|
10
|
+
import { Component, Watch, Vue } from '@a-vue'
|
11
|
+
import { FlyingContextEvent } from '@a-vue/events'
|
12
|
+
import { randomCssClass } from '@a-vue/utils/random'
|
13
|
+
|
14
|
+
@Component({
|
15
|
+
props: [{show: false}]
|
16
|
+
})
|
17
|
+
export default class FlyingContext extends Vue {
|
18
|
+
isVisible = false
|
19
|
+
contextId = randomCssClass(10)
|
20
|
+
|
21
|
+
created () {
|
22
|
+
this.$events.on(FlyingContextEvent.HIDE_ALL, this.onHide)
|
23
|
+
}
|
24
|
+
|
25
|
+
mounted () {
|
26
|
+
if (this.show) {
|
27
|
+
this.showChanged()
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
@Watch('show')
|
32
|
+
showChanged () {
|
33
|
+
if (this.isVisible === this.show) {
|
34
|
+
return
|
35
|
+
}
|
36
|
+
|
37
|
+
this.isVisible = this.show
|
38
|
+
|
39
|
+
if (this.isVisible) {
|
40
|
+
const container = this.getSidebarContainer()
|
41
|
+
container.appendChild(this.getContent())
|
42
|
+
} else {
|
43
|
+
this.$el.appendChild(this.getContent())
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
destroyed () {
|
48
|
+
const container = this.getSidebarContainer()
|
49
|
+
const el = this.getContent()
|
50
|
+
if (container.contains(el)) {
|
51
|
+
container.removeChild(el)
|
52
|
+
}
|
53
|
+
|
54
|
+
this.$events.off(FlyingContextEvent.HIDE_ALL, this.onHide)
|
55
|
+
}
|
56
|
+
|
57
|
+
onHide () {
|
58
|
+
if (this.isVisible) {
|
59
|
+
this.$el.appendChild(this.getContent())
|
60
|
+
this.isVisible = false
|
61
|
+
this.$emit('hide')
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
getContent () {
|
66
|
+
return document.querySelector('.' + this.contextId)
|
67
|
+
}
|
68
|
+
|
69
|
+
getSidebarContainer () {
|
70
|
+
return document.getElementById('flyingContextContainer__children')
|
71
|
+
}
|
72
|
+
}
|
73
|
+
</script>
|
74
|
+
|
75
|
+
|
76
|
+
<style lang="scss" scoped>
|
77
|
+
</style>
|
@@ -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>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<a-row gap="2">
|
3
3
|
<v-btn
|
4
4
|
:small="small"
|
5
|
-
:disabled="!changed || !valid"
|
5
|
+
:disabled="($has.reset && !changed) || !valid"
|
6
6
|
color="green white--text"
|
7
7
|
@click="$emit('save')"
|
8
8
|
>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
</v-btn>
|
11
11
|
|
12
12
|
<v-icon
|
13
|
-
v-if="changed"
|
13
|
+
v-if="$has.reset && changed"
|
14
14
|
:small="small"
|
15
15
|
text
|
16
16
|
title="Formular zurücksetzen"
|
@@ -33,6 +33,8 @@ import { mdiRotateLeft} from '@mdi/js'
|
|
33
33
|
]
|
34
34
|
})
|
35
35
|
export default class EditFormButtons extends Vue {
|
36
|
+
$hasOptions = ['reset']
|
37
|
+
|
36
38
|
undoIcon = mdiRotateLeft
|
37
39
|
}
|
38
40
|
</script>
|
@@ -7,6 +7,7 @@ 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 FlyingContext from './FlyingContext.vue'
|
10
11
|
import EditFormButtons from './form/EditFormButtons'
|
11
12
|
import RemoveButton from './form/RemoveButton'
|
12
13
|
import ListCard from './list/ListCard'
|
@@ -17,10 +18,7 @@ import ListTitle from './list/ListTitle'
|
|
17
18
|
import ListView from './list/ListView'
|
18
19
|
import ModelCount from './model/ModelCount'
|
19
20
|
import ModelIcon from './model/ModelIcon'
|
20
|
-
import CreatePage from './pages/CreatePage'
|
21
|
-
import DetailPage from './pages/DetailPage'
|
22
21
|
import EditPage from './pages/EditPage'
|
23
|
-
import ListPage from './pages/ListPage'
|
24
22
|
import Start from './Start.vue'
|
25
23
|
|
26
24
|
Vue.component('ListCard', ListCard)
|
@@ -29,9 +27,6 @@ Vue.component('ListContent', ListContent)
|
|
29
27
|
Vue.component('ListMeta', ListMeta)
|
30
28
|
Vue.component('ListTitle', ListTitle)
|
31
29
|
Vue.component('ListView', ListView)
|
32
|
-
Vue.component('ListPage', ListPage)
|
33
|
-
|
34
|
-
Vue.component('CreatePage', CreatePage)
|
35
30
|
|
36
31
|
Vue.component('EditPage', EditPage)
|
37
32
|
Vue.component('EditFormButtons', EditFormButtons)
|
@@ -43,7 +38,6 @@ Vue.component('ModelIcon', ModelIcon)
|
|
43
38
|
Vue.component('DetailContent', DetailContent)
|
44
39
|
Vue.component('DetailMeta', DetailMeta)
|
45
40
|
Vue.component('DetailTitle', DetailTitle)
|
46
|
-
Vue.component('DetailPage', DetailPage)
|
47
41
|
Vue.component('DetailProperty', DetailProperty)
|
48
42
|
Vue.component('DetailColumn', DetailColumn)
|
49
43
|
|
@@ -51,3 +45,4 @@ Vue.component('AppBarButton', AppBarButton)
|
|
51
45
|
Vue.component('AppBarTitle', AppBarTitle)
|
52
46
|
|
53
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) {
|
@@ -4,9 +4,10 @@
|
|
4
4
|
:model="model"
|
5
5
|
:createModelToEdit="createModelToEdit"
|
6
6
|
>
|
7
|
-
<template #
|
7
|
+
<template #form="{modelToEdit, changed, valid}">
|
8
8
|
<slot
|
9
|
-
|
9
|
+
name="form"
|
10
|
+
:modelToEdit="modelToEdit"
|
10
11
|
:changed="changed"
|
11
12
|
:valid="valid"
|
12
13
|
/>
|
@@ -14,7 +15,8 @@
|
|
14
15
|
<edit-form-buttons
|
15
16
|
:changed="changed"
|
16
17
|
:valid="valid"
|
17
|
-
|
18
|
+
:has="{reset: !!modelToEdit.id}"
|
19
|
+
@save="$emit('save', modelToEdit, ignoreChangesOnRouteChange)"
|
18
20
|
@reset="$refs.form.reset()"
|
19
21
|
/>
|
20
22
|
</template>
|
@@ -53,6 +55,9 @@ export default class EditPage extends Vue {
|
|
53
55
|
this.unregisterRouterHook()
|
54
56
|
}
|
55
57
|
|
58
|
+
/**
|
59
|
+
* hook to allow to leave a just created (saved) model
|
60
|
+
*/
|
56
61
|
ignoreChangesOnRouteChange () {
|
57
62
|
this.ignoreChangesOnRouteChange_ = true
|
58
63
|
}
|
@@ -7,6 +7,7 @@ Component.registerHooks([
|
|
7
7
|
|
8
8
|
let onLoadCallback = () => {}
|
9
9
|
let routerHookCalled = false
|
10
|
+
let lastResult = null // cache last result because of hmr reload
|
10
11
|
|
11
12
|
function onLoad (callback) {
|
12
13
|
onLoadCallback = callback
|
@@ -52,24 +53,32 @@ export class DataRouteMixin extends Vue {
|
|
52
53
|
|
53
54
|
/**
|
54
55
|
* triggered both, if route name or route params change
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
56
|
+
@Watch('$route.params')
|
57
|
+
async routeParamsChanged () {
|
58
|
+
if (routerHookCalled) {
|
59
|
+
return
|
60
|
+
}
|
61
61
|
|
62
|
-
|
63
|
-
|
62
|
+
if (!this.drm_isLoaded) {
|
63
|
+
const result = await load(this.$route)
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
if (result !== false) {
|
66
|
+
this.drm_onLoad(result)
|
67
|
+
this.drm_isLoaded = true
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
*/
|
71
72
|
|
72
73
|
drm_onLoad (result) {
|
73
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
|
+
}
|
74
83
|
}
|
75
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'
|