@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.
@@ -1 +1 @@
1
- 0.0.58
1
+ 0.0.61
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.58",
3
+ "version": "0.0.61",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -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_ = new Date()
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
- created () {
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>
@@ -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)
@@ -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.createRouteConfig) {
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.createRouteConfig
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
- const type = this.$apiResources.getType(this.ModelClass.type)
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: ['model', 'icon', 'title', 'listLink', 'getAction']
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
- const type = this.$apiResources.getType(this.ModelClass.type)
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
- this.modelToEdit = this.createModelToEdit()
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
- const type = this.$apiResources.getType(this.Model.type)
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
- const type = this.$apiResources.getType(this.Model.type)
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()