@afeefa/vue-app 0.0.58 → 0.0.61
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/ADatePicker.vue +3 -1
- package/src/components/ARichTextArea.vue +2 -0
- package/src/components/form/EditForm.vue +12 -6
- package/src/components/form/NestedEditForm.vue +25 -0
- package/src/components/index.js +2 -0
- package/src-admin/bootstrap.js +8 -1
- package/src-admin/components/pages/CreatePage.vue +4 -5
- package/src-admin/components/pages/EditPage.vue +8 -13
- package/src-admin/components/pages/EditPageMixin.js +7 -2
- package/src-admin/components/pages/ListPage.vue +2 -4
- package/src-admin/models/Model.js +5 -0
- package/src-admin/plugins/translation/TranslationPlugin.js +20 -0
- package/src-admin/services/TranslationService.js +35 -0
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.61
|
package/package.json
CHANGED
@@ -8,11 +8,13 @@
|
|
8
8
|
>
|
9
9
|
<template #activator="{ on, attrs }">
|
10
10
|
<v-combobox
|
11
|
+
ref="input"
|
11
12
|
:value="formattedDate"
|
12
13
|
:label="label"
|
13
14
|
:style="cwm_widthStyle"
|
14
15
|
readonly
|
15
16
|
v-bind="attrs"
|
17
|
+
:rules="validationRules"
|
16
18
|
v-on="on"
|
17
19
|
@click.native="on.click"
|
18
20
|
/>
|
@@ -37,7 +39,7 @@ import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
|
37
39
|
props: ['value', 'validator']
|
38
40
|
})
|
39
41
|
export default class ADatePicker extends Mixins(ComponentWidthMixin) {
|
40
|
-
value_ =
|
42
|
+
value_ = null
|
41
43
|
menu = false
|
42
44
|
|
43
45
|
created () {
|
@@ -151,9 +151,11 @@ export default class ARichTextArea extends Vue {
|
|
151
151
|
},
|
152
152
|
onFocus: ({ editor, event }) => {
|
153
153
|
this.focus = true
|
154
|
+
this.$emit('focus')
|
154
155
|
},
|
155
156
|
onBlur: ({ editor, event }) => {
|
156
157
|
this.focus = false
|
158
|
+
this.$emit('blur')
|
157
159
|
}
|
158
160
|
})
|
159
161
|
|
@@ -26,8 +26,17 @@ export default class EditForm extends Vue {
|
|
26
26
|
valid = false
|
27
27
|
lastJson = null
|
28
28
|
|
29
|
-
|
29
|
+
/**
|
30
|
+
* This will be triggered after the this.model has been set
|
31
|
+
* but before sub components may have changed model values
|
32
|
+
* as a date field, which could turn a null to a default date.
|
33
|
+
* Using the created() method would result in already having set
|
34
|
+
* the default date, hence not detecting a valid "change" anymore.
|
35
|
+
*/
|
36
|
+
@Watch('model', {immediate: true})
|
37
|
+
modelChanged () {
|
30
38
|
this.lastJson = this.json
|
39
|
+
this.$emit('update:changed', this.changed)
|
31
40
|
}
|
32
41
|
|
33
42
|
get json () {
|
@@ -35,14 +44,11 @@ export default class EditForm extends Vue {
|
|
35
44
|
}
|
36
45
|
|
37
46
|
get changed () {
|
47
|
+
// console.log(this.json)
|
48
|
+
// console.log(this.lastJson)
|
38
49
|
return this.json !== this.lastJson
|
39
50
|
}
|
40
51
|
|
41
|
-
@Watch('model')
|
42
|
-
modelChanged () {
|
43
|
-
this.lastJson = this.json
|
44
|
-
}
|
45
|
-
|
46
52
|
@Watch('valid')
|
47
53
|
validChanged () {
|
48
54
|
this.$emit('update:valid', this.valid)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<template>
|
2
|
+
<div>
|
3
|
+
<slot name="fields" />
|
4
|
+
|
5
|
+
<slot :model="model" />
|
6
|
+
</div>
|
7
|
+
</template>
|
8
|
+
|
9
|
+
|
10
|
+
<script>
|
11
|
+
import { Component, Vue } from '@a-vue'
|
12
|
+
|
13
|
+
@Component({
|
14
|
+
props: ['model']
|
15
|
+
})
|
16
|
+
export default class NestedEditForm extends Vue {
|
17
|
+
EDIT_FORM = true
|
18
|
+
|
19
|
+
created () {
|
20
|
+
if (!this.model) {
|
21
|
+
console.warn('Nested edit form does not have a model.')
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
</script>
|
package/src/components/index.js
CHANGED
@@ -11,12 +11,14 @@ import FormFieldSelect from './form/fields/FormFieldSelect'
|
|
11
11
|
import FormFieldSelect2 from './form/fields/FormFieldSelect2'
|
12
12
|
import FormFieldText from './form/fields/FormFieldText'
|
13
13
|
import FormFieldTextArea from './form/fields/FormFieldTextArea'
|
14
|
+
import NestedEditForm from './form/NestedEditForm'
|
14
15
|
import ListFilterPage from './list/filters/ListFilterPage'
|
15
16
|
import ListFilterSearch from './list/filters/ListFilterSearch'
|
16
17
|
import ListFilterSelect from './list/filters/ListFilterSelect'
|
17
18
|
import ListFilterRow from './list/ListFilterRow'
|
18
19
|
|
19
20
|
Vue.component('EditForm', EditForm)
|
21
|
+
Vue.component('NestedEditForm', NestedEditForm)
|
20
22
|
Vue.component('EditModal', EditModal)
|
21
23
|
Vue.component('FormFieldText', FormFieldText)
|
22
24
|
Vue.component('FormFieldTextArea', FormFieldTextArea)
|
package/src-admin/bootstrap.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import './config/event-bus'
|
2
2
|
import './config/components'
|
3
3
|
|
4
|
+
import { translationPlugin } from '@a-admin/plugins/translation/TranslationPlugin'
|
4
5
|
import { apiResourcesPlugin } from '@a-vue/plugins/api-resources/ApiResourcesPlugin'
|
5
6
|
import { hasOptionsPlugin } from '@a-vue/plugins/has-options/HasOptionsPlugin'
|
6
7
|
import { timeout } from '@a-vue/utils/timeout'
|
@@ -12,10 +13,11 @@ import vuetify from './config/vuetify'
|
|
12
13
|
|
13
14
|
Vue.use(apiResourcesPlugin)
|
14
15
|
Vue.use(hasOptionsPlugin)
|
16
|
+
Vue.use(translationPlugin)
|
15
17
|
|
16
18
|
Vue.config.productionTip = false
|
17
19
|
|
18
|
-
export async function bootstrap ({ apis, models, routing, authService, app, components }) {
|
20
|
+
export async function bootstrap ({ apis, models, routing, authService, getTranslations, app, components }) {
|
19
21
|
apiResourcesPlugin.register(models, apis)
|
20
22
|
|
21
23
|
appConfig.authService = authService
|
@@ -35,6 +37,11 @@ export async function bootstrap ({ apis, models, routing, authService, app, comp
|
|
35
37
|
const router = await routeConfigPlugin.getRouter()
|
36
38
|
await apiResourcesPlugin.schemasLoaded()
|
37
39
|
|
40
|
+
if (getTranslations) {
|
41
|
+
const translations = await getTranslations(apiResourcesPlugin.apiResources)
|
42
|
+
translationPlugin.setTranslations(translations.models)
|
43
|
+
}
|
44
|
+
|
38
45
|
if (authService) {
|
39
46
|
authService.initApp(router)
|
40
47
|
}
|
@@ -30,6 +30,7 @@
|
|
30
30
|
<a-row class="mt-6">
|
31
31
|
<v-btn
|
32
32
|
:disabled="!changed || !valid"
|
33
|
+
color="green white--text"
|
33
34
|
@click="save"
|
34
35
|
>
|
35
36
|
Anlegen
|
@@ -55,16 +56,15 @@ import { EditPageMixin } from './EditPageMixin'
|
|
55
56
|
})
|
56
57
|
export default class CreatePage extends Mixins(EditPageMixin) {
|
57
58
|
created () {
|
58
|
-
if (!this.$parent.constructor.
|
59
|
+
if (!this.$parent.constructor.getCreateRouteConfig) {
|
59
60
|
console.warn('<create-page> owner must provide a static createRouteConfig method.')
|
60
61
|
}
|
61
62
|
|
62
63
|
this.reset()
|
63
|
-
this.$emit('model', this.modelToEdit)
|
64
64
|
}
|
65
65
|
|
66
66
|
get editConfig () {
|
67
|
-
return this.$parent.constructor.
|
67
|
+
return this.$parent.constructor.getCreateRouteConfig(this.$route)
|
68
68
|
}
|
69
69
|
|
70
70
|
get modelUpateAction () {
|
@@ -85,8 +85,7 @@ export default class CreatePage extends Mixins(EditPageMixin) {
|
|
85
85
|
return this.title
|
86
86
|
}
|
87
87
|
|
88
|
-
|
89
|
-
return type.t('TITLE_NEW')
|
88
|
+
return this.$t('Admin.Types', this.ModelClass.type, null, 'TITLE_NEW', 'de')
|
90
89
|
}
|
91
90
|
|
92
91
|
get _listLink () {
|
@@ -23,14 +23,6 @@
|
|
23
23
|
</v-btn>
|
24
24
|
</app-bar-button>
|
25
25
|
|
26
|
-
<component
|
27
|
-
:is="Component"
|
28
|
-
v-if="false"
|
29
|
-
:model="modelToEdit"
|
30
|
-
:valid.sync="valid"
|
31
|
-
:changed.sync="changed"
|
32
|
-
/>
|
33
|
-
|
34
26
|
<edit-form
|
35
27
|
:model="modelToEdit"
|
36
28
|
:valid.sync="valid"
|
@@ -69,7 +61,13 @@ import { Component, Mixins, Watch } from '@a-vue'
|
|
69
61
|
import { EditPageMixin } from './EditPageMixin'
|
70
62
|
|
71
63
|
@Component({
|
72
|
-
props: [
|
64
|
+
props: [
|
65
|
+
'model',
|
66
|
+
'icon',
|
67
|
+
'title',
|
68
|
+
'listLink',
|
69
|
+
'getAction'
|
70
|
+
]
|
73
71
|
})
|
74
72
|
export default class EditPage extends Mixins(EditPageMixin) {
|
75
73
|
$hasOptions = ['detail', {list: false}]
|
@@ -83,14 +81,12 @@ export default class EditPage extends Mixins(EditPageMixin) {
|
|
83
81
|
|
84
82
|
this.model_ = this.model
|
85
83
|
this.reset()
|
86
|
-
this.$emit('model', this.modelToEdit)
|
87
84
|
}
|
88
85
|
|
89
86
|
@Watch('model')
|
90
87
|
modelChanged () {
|
91
88
|
this.model_ = this.model
|
92
89
|
this.reset()
|
93
|
-
this.$emit('model', this.modelToEdit)
|
94
90
|
}
|
95
91
|
|
96
92
|
get editConfig () {
|
@@ -122,8 +118,7 @@ export default class EditPage extends Mixins(EditPageMixin) {
|
|
122
118
|
return this.title
|
123
119
|
}
|
124
120
|
|
125
|
-
|
126
|
-
return type.t('TITLE_EMPTY')
|
121
|
+
return this.$t('Admin.Types', this.ModelClass.type, null, 'TITLE_EMPTY', 'de')
|
127
122
|
}
|
128
123
|
|
129
124
|
get _listLink () {
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { Component, Vue } from '@a-vue'
|
1
2
|
import { SaveAction } from '@a-vue/api-resources/ApiActions'
|
2
3
|
import { DialogEvent } from '@a-vue/events'
|
3
|
-
import { Component, Vue } from '@a-vue'
|
4
4
|
|
5
5
|
@Component({
|
6
6
|
props: ['saveAction']
|
@@ -78,7 +78,12 @@ export class EditPageMixin extends Vue {
|
|
78
78
|
}
|
79
79
|
|
80
80
|
reset () {
|
81
|
-
|
81
|
+
const modelToEdit = this.createModelToEdit()
|
82
|
+
if (this.editConfig.createModelToEdit) {
|
83
|
+
this.editConfig.createModelToEdit(modelToEdit)
|
84
|
+
}
|
85
|
+
this.modelToEdit = modelToEdit // this assignment makes modelToEdit recursively reactive
|
86
|
+
this.$emit('model', this.modelToEdit)
|
82
87
|
}
|
83
88
|
|
84
89
|
afterSave (_model) {
|
@@ -37,8 +37,7 @@ export default class ListPage extends Vue {
|
|
37
37
|
return this.title
|
38
38
|
}
|
39
39
|
|
40
|
-
|
41
|
-
return type.t('TITLE_PLURAL')
|
40
|
+
return this.$t('Admin.Types', this.Model.type, null, 'TITLE_PLURAL', 'de')
|
42
41
|
}
|
43
42
|
|
44
43
|
get _newTitle () {
|
@@ -46,8 +45,7 @@ export default class ListPage extends Vue {
|
|
46
45
|
return this.newTitle
|
47
46
|
}
|
48
47
|
|
49
|
-
|
50
|
-
return type.t('TITLE_SINGULAR')
|
48
|
+
return this.$t('Admin.Types', this.Model.type, null, 'TITLE_SINGULAR', 'de')
|
51
49
|
}
|
52
50
|
|
53
51
|
get _newLink () {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { translationService } from '@a-admin/services/TranslationService'
|
1
2
|
import { Model as ApiResourcesModel, apiResources } from '@afeefa/api-resources-client'
|
2
3
|
import { mdiAlphaMCircle } from '@mdi/js'
|
3
4
|
|
@@ -39,6 +40,10 @@ export class Model extends ApiResourcesModel {
|
|
39
40
|
color: 'blue lighten-2'
|
40
41
|
}
|
41
42
|
|
43
|
+
static translate (realm, objectType, objectId, key, lang) {
|
44
|
+
return translationService.translate(realm, objectType, objectId, key, lang)
|
45
|
+
}
|
46
|
+
|
42
47
|
getLink (action = 'detail') {
|
43
48
|
return {
|
44
49
|
name: `${this.constructor.routeName}.${action}`,
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { translationService } from '../../services/TranslationService'
|
2
|
+
|
3
|
+
class TranslationPlugin {
|
4
|
+
setTranslations (translations) {
|
5
|
+
translationService
|
6
|
+
.setTranslations(translations)
|
7
|
+
}
|
8
|
+
|
9
|
+
install (Vue) {
|
10
|
+
Vue.mixin({
|
11
|
+
created () {
|
12
|
+
this.$t = (realm, objectId, objectType, key, lang) => {
|
13
|
+
return translationService.translate(realm, objectId, objectType, key, lang)
|
14
|
+
}
|
15
|
+
}
|
16
|
+
})
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
export const translationPlugin = new TranslationPlugin()
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class TranslationService {
|
2
|
+
translations = {}
|
3
|
+
|
4
|
+
setTranslations (translations) {
|
5
|
+
translations.forEach(t => {
|
6
|
+
const key = JSON.stringify([
|
7
|
+
t.realm,
|
8
|
+
t.object_type,
|
9
|
+
t.object_id,
|
10
|
+
t.key,
|
11
|
+
t.lang
|
12
|
+
])
|
13
|
+
this.translations[key] = t.value
|
14
|
+
})
|
15
|
+
}
|
16
|
+
|
17
|
+
translate (realm, objectType, objectId, key, lang) {
|
18
|
+
const tKey = JSON.stringify([
|
19
|
+
realm,
|
20
|
+
objectType,
|
21
|
+
objectId,
|
22
|
+
key,
|
23
|
+
lang
|
24
|
+
])
|
25
|
+
|
26
|
+
if (!this.translations[tKey]) {
|
27
|
+
console.warn(`No translation found for ${tKey}`)
|
28
|
+
return `${key}:${lang}`
|
29
|
+
}
|
30
|
+
|
31
|
+
return this.translations[tKey]
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
export const translationService = new TranslationService()
|