@afeefa/vue-app 0.0.48 → 0.0.52

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.48
1
+ 0.0.52
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.48",
3
+ "version": "0.0.52",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -197,6 +197,7 @@ export class RemoveAction {
197
197
  .params({
198
198
  id: this.id
199
199
  })
200
+ .data(null)
200
201
  .send()
201
202
 
202
203
  if (this.afterRemoveHook) {
@@ -6,7 +6,7 @@
6
6
  >
7
7
  <slot name="activator">
8
8
  <a-icon class="contextButton">
9
- $dotsHorizontalIcon
9
+ {{ triggerIcon || '$dotsHorizontalIcon' }}
10
10
  </a-icon>
11
11
  </slot>
12
12
  </div>
@@ -31,7 +31,7 @@ import { Positions, PositionConfig } from '../services/PositionService'
31
31
  import { randomCssClass } from '../utils/random'
32
32
 
33
33
  @Component({
34
- props: ['contentHeight', 'repositionWatchKey']
34
+ props: ['contentHeight', 'repositionWatchKey', 'triggerIcon']
35
35
  })
36
36
  export default class AContextMenu extends Mixins(UsesPositionServiceMixin) {
37
37
  CONTEXT_MENU = true
@@ -10,7 +10,9 @@
10
10
  <script>
11
11
  import { Component, Vue } from 'vue-property-decorator'
12
12
 
13
- @Component
13
+ @Component({
14
+ props: ['to']
15
+ })
14
16
  export default class AContextMenuItem extends Vue {
15
17
  get contextMenu () {
16
18
  let parent = this.$parent
@@ -25,7 +27,12 @@ export default class AContextMenuItem extends Vue {
25
27
 
26
28
  click () {
27
29
  this.contextMenu.close()
28
- this.$emit('click')
30
+ if (this.to) {
31
+ this.$router.push(this.to)
32
+ .catch(() => null) // prevent duplicated navigation
33
+ } else {
34
+ this.$emit('click')
35
+ }
29
36
  }
30
37
  }
31
38
  </script>
@@ -46,8 +46,8 @@
46
46
  v-if="isOpen"
47
47
  v-bind="listConfig"
48
48
  :q="q"
49
- :noEvents="true"
50
- :noHistory="true"
49
+ :events="false"
50
+ :history="false"
51
51
  :filterSource="filterSource"
52
52
  :loadOnlyIfKeyword="_loadOnlyIfKeyword"
53
53
  :count.sync="count"
@@ -1,6 +1,6 @@
1
- import { BaseFilterSource } from '@afeefa/api-resources-client'
1
+ import { ListViewFilterSource } from '@afeefa/api-resources-client'
2
2
 
3
- export class RouteFilterSource extends BaseFilterSource {
3
+ export class CurrentRouteFilterSource extends ListViewFilterSource {
4
4
  router = null
5
5
 
6
6
  constructor (router) {
@@ -2,9 +2,6 @@ export class FilterSourceType {
2
2
  // filters are synchronized with url's query string
3
3
  static QUERY_STRING = 'query_string'
4
4
 
5
- // filters are initialized from given route params (no synchronisation allowed)
6
- static ROUTE_PARAMS = 'route_params'
7
-
8
5
  // filters are synchronized with plain history object
9
6
  static OBJECT = 'object'
10
7
  }
@@ -1,26 +1,31 @@
1
1
  import { ListAction } from '@a-vue/api-resources/ApiActions'
2
+ import { propsWithDefaults } from '@a-vue/utils/props-helper'
2
3
  import { ListViewModel } from '@afeefa/api-resources-client'
3
4
  import { Component, Vue, Watch } from 'vue-property-decorator'
4
5
 
6
+ import { CurrentRouteFilterSource } from './CurrentRouteFilterSource'
5
7
  import { FilterSourceType } from './FilterSourceType'
6
- import { RouteFilterSource } from './RouteFilterSource'
7
8
 
8
9
  @Component({
9
- props: [
10
- 'models', 'meta', // if already loaded
10
+ ...propsWithDefaults([
11
+ 'models', 'meta', // given, if already loaded
11
12
  'listViewConfig',
12
- 'noEvents', 'noHistory',
13
- 'filterHistoryKey', 'filterSource',
14
- 'loadOnlyIfKeyword'
15
- ]
13
+ 'filterHistoryKey',
14
+ 'loadOnlyIfKeyword',
15
+ {
16
+ filterSource: FilterSourceType.QUERY_STRING,
17
+ events: true,
18
+ history: true
19
+ }
20
+ ])
16
21
  })
17
22
  export class ListViewMixin extends Vue {
18
23
  LIST_VIEW = true
19
24
 
25
+ listViewModel = null
20
26
  models_ = []
21
27
  meta_ = {}
22
28
  isLoading = false
23
- listViewModel = null
24
29
 
25
30
  created () {
26
31
  this.init()
@@ -36,10 +41,12 @@ export class ListViewMixin extends Vue {
36
41
  this.listViewModel.off('change', this.filtersChanged)
37
42
  }
38
43
 
39
- const historyKey = this.noHistory
40
- ? undefined
41
- : [this.$route.path, this.filterHistoryKey].filter(i => i).join('.')
42
- const filterSource = this.filterSource === FilterSourceType.OBJECT ? undefined : new RouteFilterSource(this.$router)
44
+ const historyKey = this.history
45
+ ? [this.$route.path, this.filterHistoryKey].filter(i => i).join('.')
46
+ : undefined
47
+ const filterSource = this.filterSource === FilterSourceType.QUERY_STRING
48
+ ? new CurrentRouteFilterSource(this.$router)
49
+ : undefined
43
50
 
44
51
  if (this.models) {
45
52
  this.models_ = this.models
@@ -47,12 +54,12 @@ export class ListViewMixin extends Vue {
47
54
  }
48
55
 
49
56
  this.listViewModel = new ListViewModel(this.listViewConfig)
50
- .filterSource(filterSource, true)
51
- .historyKey(historyKey, true)
57
+ .filterSource(filterSource, !!filterSource)
58
+ .historyKey(historyKey, this.history)
52
59
  .usedFilters(this.meta_.used_filters || null, this.meta_.count_search || 0)
53
60
  .initFilters({
54
- source: true,
55
- history: true,
61
+ source: !!filterSource,
62
+ history: !!historyKey,
56
63
  used: !!this.models
57
64
  })
58
65
  .on('change', this.filtersChanged) // listen to change
@@ -68,7 +75,7 @@ export class ListViewMixin extends Vue {
68
75
 
69
76
  @Watch('$route.query')
70
77
  routeQueryChanged () {
71
- if (this.filterSource !== FilterSourceType.QUERY_STRING) {
78
+ if (this.filterSource === FilterSourceType.QUERY_STRING) {
72
79
  this.listViewModel.filterSourceChanged()
73
80
  }
74
81
  }
@@ -117,7 +124,7 @@ export class ListViewMixin extends Vue {
117
124
 
118
125
  const {models, meta} = await new ListAction()
119
126
  .setRequest(request)
120
- .noEvents(this.noEvents === true)
127
+ .noEvents(!this.events)
121
128
  .load()
122
129
 
123
130
  if (!models) { // error happened
@@ -0,0 +1,15 @@
1
+ import { ListViewFilterSource } from '@afeefa/api-resources-client'
2
+
3
+ export class NextRouteFilterSource extends ListViewFilterSource {
4
+ route = null
5
+
6
+ constructor (route) {
7
+ super()
8
+
9
+ this.route = route
10
+ }
11
+
12
+ getQuery () {
13
+ return this.route.query
14
+ }
15
+ }
@@ -22,7 +22,7 @@ export default class ListFilterSelect extends Mixins(ListFilterMixin) {
22
22
  items = null
23
23
 
24
24
  created () {
25
- if (this.filter.hasRequest()) {
25
+ if (this.filter.hasOptionsRequest()) {
26
26
  this.items = this.loadRequestOptions()
27
27
  } else if (this.filter.hasOptions()) {
28
28
  this.items = this.getOptions()
@@ -54,7 +54,7 @@ export default class ListFilterSelect extends Mixins(ListFilterMixin) {
54
54
 
55
55
  async loadRequestOptions () {
56
56
  const {models} = await new ListAction()
57
- .setRequest(this.filter.request)
57
+ .setRequest(this.filter.createOptionsRequest())
58
58
  .noEvents()
59
59
  .load()
60
60
 
@@ -0,0 +1,21 @@
1
+ export function propsWithDefaults (props) {
2
+ const normalizedProps = {}
3
+
4
+ for (const prop of props) {
5
+ if (typeof prop === 'object') {
6
+ Object.keys(prop).forEach(subProp => {
7
+ if (typeof prop[subProp] === 'object') {
8
+ normalizedProps[subProp] = prop[subProp]
9
+ } else {
10
+ normalizedProps[subProp] = { default: prop[subProp] }
11
+ }
12
+ })
13
+ } else {
14
+ normalizedProps[prop] = null
15
+ }
16
+ }
17
+
18
+ return {
19
+ props: normalizedProps
20
+ }
21
+ }
@@ -13,7 +13,7 @@
13
13
  >
14
14
  <router-link
15
15
  :to="{name: rootRouteName}"
16
- class="logoContainer d-flex flex-column pa-6"
16
+ class="logoContainer d-flex flex-column align-center pa-6"
17
17
  >
18
18
  <img
19
19
  v-if="logoUrl"
@@ -59,32 +59,14 @@
59
59
  </div>
60
60
  </div>
61
61
 
62
- <v-menu top>
63
- <template #activator="{ on, attrs }">
64
- <v-icon
65
- class="contextButton"
66
- v-bind="attrs"
67
- v-on="on"
68
- >
69
- $dotsVerticalIcon
70
- </v-icon>
71
- </template>
72
-
73
- <v-list
74
- class="pa-0"
62
+ <a-context-menu triggerIcon="$dotsVerticalIcon">
63
+ <a-context-menu-item
64
+ :to="{name: 'settings', params: {accountId: account.id}}"
75
65
  >
76
- <v-list-item :to="{name: 'accounts.edit', params: {accountId: account.id}}">
77
- <v-list-item-icon class="ma-0 mr-2 align-self-center">
78
- <v-icon class="ml-n1 mr-1">
79
- $pencilIcon
80
- </v-icon>
81
- </v-list-item-icon>
82
- <v-list-item-title>
83
- Einstellungen
84
- </v-list-item-title>
85
- </v-list-item>
86
- </v-list>
87
- </v-menu>
66
+ <v-icon>$pencilIcon</v-icon>
67
+ Einstellungen
68
+ </a-context-menu-item>
69
+ </a-context-menu>
88
70
  </div>
89
71
  </v-container>
90
72
  </v-container>
@@ -73,7 +73,7 @@ export default class ListView extends Mixins(ListViewMixin) {
73
73
 
74
74
  @Watch('isLoading')
75
75
  isLoadingChanged () {
76
- if (this.noEvents === undefined || !this.noEvents) {
76
+ if (this.events) {
77
77
  if (this.isLoading) {
78
78
  this.$events.dispatch(new LoadingEvent(LoadingEvent.START_LOADING))
79
79
  } else {
@@ -56,8 +56,8 @@ import { apiResources } from '@afeefa/api-resources-client'
56
56
  })
57
57
  export default class CreatePage extends Mixins(EditPageMixin) {
58
58
  created () {
59
- if (!this.$parent.constructor.getCreateConfig) {
60
- console.warn('<create-page> owner must provide a static getCreateConfig method.')
59
+ if (!this.$parent.constructor.createRouteConfig) {
60
+ console.warn('<create-page> owner must provide a static createRouteConfig method.')
61
61
  }
62
62
 
63
63
  this.reset()
@@ -65,11 +65,11 @@ export default class CreatePage extends Mixins(EditPageMixin) {
65
65
  }
66
66
 
67
67
  get editConfig () {
68
- return this.$parent.constructor.getCreateConfig(this.$route)
68
+ return this.$parent.constructor.createRouteConfig
69
69
  }
70
70
 
71
71
  get modelUpateAction () {
72
- return this.ModelClass.getAction('create')
72
+ return this.editConfig.createAction || this.ModelClass.getAction('save')
73
73
  }
74
74
 
75
75
  get _icon () {
@@ -55,7 +55,7 @@ import { Component, Vue, Watch } from 'vue-property-decorator'
55
55
  import { RemoveAction } from '@a-vue/api-resources/ApiActions'
56
56
 
57
57
  @Component({
58
- props: ['model', 'title', 'icon', 'removeAction', 'protectRemove', 'listLink']
58
+ props: ['model', 'title', 'icon', 'protectRemove', 'listLink']
59
59
  })
60
60
  export default class DetailPage extends Vue {
61
61
  $hasOptions = ['edit', 'remove', 'list']
@@ -64,7 +64,7 @@ export default class DetailPage extends Vue {
64
64
  removeConfirmed = null
65
65
 
66
66
  created () {
67
- if (!this.$parent.constructor.getDetailConfig) {
67
+ if (!this.$parent.constructor.detailRouteConfig) {
68
68
  console.warn('<detail-page> owner must provide a static getDetailConfig method.')
69
69
  }
70
70
  this.$emit('model', this.model)
@@ -80,7 +80,7 @@ export default class DetailPage extends Vue {
80
80
  }
81
81
 
82
82
  get detailConfig () {
83
- return this.$parent.constructor.getDetailConfig(this.$route)
83
+ return this.$parent.constructor.detailRouteConfig
84
84
  }
85
85
 
86
86
  get document () {
@@ -110,10 +110,7 @@ export default class DetailPage extends Vue {
110
110
  }
111
111
 
112
112
  get _deleteAction () {
113
- if (this.removeAction) {
114
- return this.removeAction
115
- }
116
- return this.ModelClass.getAction('delete')
113
+ return this.detailConfig.removeAction || this.ModelClass.getAction('save')
117
114
  }
118
115
 
119
116
  async remove () {
@@ -78,8 +78,8 @@ export default class EditPage extends Mixins(EditPageMixin) {
78
78
  model_ = null
79
79
 
80
80
  created () {
81
- if (!this.$parent.constructor.getEditConfig) {
82
- console.warn('<edit-page> owner must provide a static getEditConfig method.')
81
+ if (!this.$parent.constructor.editRouteConfig) {
82
+ console.warn('<edit-page> owner must provide a static editRouteConfig method.')
83
83
  }
84
84
 
85
85
  this.model_ = this.model
@@ -95,11 +95,11 @@ export default class EditPage extends Mixins(EditPageMixin) {
95
95
  }
96
96
 
97
97
  get editConfig () {
98
- return this.$parent.constructor.getEditConfig(this.$route)
98
+ return this.$parent.constructor.editRouteConfig
99
99
  }
100
100
 
101
101
  get modelUpateAction () {
102
- return this.ModelClass.getAction('update')
102
+ return this.editConfig.updateAction || this.ModelClass.getAction('save')
103
103
  }
104
104
 
105
105
  get _getAction () {
@@ -18,13 +18,18 @@ Component.registerHooks([
18
18
  function load (route) {
19
19
  const routeDefinition = route.meta.routeDefinition
20
20
  const Component = routeDefinition.config.detail
21
- const detailConfig = Component.getDetailConfig(route)
21
+
22
+ if (!Component.detailRouteConfig) {
23
+ console.warn('A detail route component must implement a static detailRouteConfig property.')
24
+ }
25
+
26
+ const detailConfig = Component.detailRouteConfig
22
27
  const action = detailConfig.action || detailConfig.ModelClass.getAction('get')
23
28
 
24
29
  return new GetAction()
25
30
  .setAction(action)
26
31
  .setFields(detailConfig.fields)
27
- .setId(route.params[routeDefinition.idKey])
32
+ .setId(detailConfig.id || route.params[routeDefinition.idKey])
28
33
  .load()
29
34
  }
30
35
 
@@ -19,13 +19,18 @@ Component.registerHooks([
19
19
  function load (route) {
20
20
  const routeDefinition = route.meta.routeDefinition
21
21
  const Component = routeDefinition.config.edit
22
- const editConfig = Component.getEditConfig(route)
22
+
23
+ if (!Component.editRouteConfig) {
24
+ console.warn('An edit route component must implement a static editRouteConfig property.')
25
+ }
26
+
27
+ const editConfig = Component.editRouteConfig
23
28
  const action = editConfig.getAction || editConfig.ModelClass.getAction('get')
24
29
 
25
30
  return new GetAction()
26
31
  .setAction(action)
27
32
  .setFields(editConfig.fields)
28
- .setId(route.params[routeDefinition.idKey])
33
+ .setId(editConfig.id || route.params[routeDefinition.idKey])
29
34
  .load()
30
35
  }
31
36
 
@@ -10,7 +10,7 @@
10
10
  <script>
11
11
  import { Component, Vue, Watch } from 'vue-property-decorator'
12
12
  import { ListAction } from '@a-vue/api-resources/ApiActions'
13
- import { RouteQueryFilterSource } from '@a-vue/components/list/RouteQueryFilterSource'
13
+ import { NextRouteFilterSource } from '@a-vue/components/list/NextRouteFilterSource'
14
14
  import { ListViewModel } from '@afeefa/api-resources-client'
15
15
 
16
16
  Component.registerHooks([
@@ -36,7 +36,11 @@ function load (route) {
36
36
  }
37
37
 
38
38
  const request = new ListViewModel(Component.listViewConfig)
39
- .filterSource(new RouteQueryFilterSource(route), false)
39
+ // read from next route query string, but do not push
40
+ // list component will be init with used_filters
41
+ .filterSource(new NextRouteFilterSource(route), false)
42
+ // read from history, but do not push
43
+ // list component will be init with used_filters
40
44
  .historyKey(route.path, false)
41
45
  .initFilters({
42
46
  source: true,
@@ -1,18 +0,0 @@
1
- import { BaseFilterSource } from '@afeefa/api-resources-client'
2
-
3
- export class RouteQueryFilterSource extends BaseFilterSource {
4
- route = null
5
-
6
- constructor (route) {
7
- super()
8
-
9
- this.route = route
10
- }
11
-
12
- getQuery () {
13
- return this.route.query
14
- }
15
-
16
- push (_query) {
17
- }
18
- }