@afeefa/vue-app 0.0.58 → 0.0.61

Sign up to get free protection for your applications and to get access to all the features.
@@ -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()