@afeefa/vue-app 0.0.138 → 0.0.140

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.138
1
+ 0.0.140
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.138",
3
+ "version": "0.0.140",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -1,8 +1,9 @@
1
1
  <template>
2
2
  <div class="contextEditor">
3
+ <!-- click.stop prevents possible surrounding v-input to focus -->
3
4
  <div
4
5
  class="activator"
5
- @click="open"
6
+ @click.stop="open"
6
7
  >
7
8
  <slot name="activator">
8
9
  <a-icon class="contextButton">
@@ -11,7 +11,11 @@
11
11
  @click:clear="clear"
12
12
  @blur="sanitizeInternalValue"
13
13
  v-on="listeners"
14
- />
14
+ >
15
+ <template #append>
16
+ <slot name="append" />
17
+ </template>
18
+ </v-text-field>
15
19
  </template>
16
20
 
17
21
 
@@ -54,7 +54,7 @@ export class FormFieldMixin extends Vue {
54
54
 
55
55
  if (field.hasOptionsRequest()) {
56
56
  const request = field
57
- .getOptionsRequest()
57
+ .createOptionsRequest()
58
58
  .addParams(this.optionRequestParams || {})
59
59
  .addFilters(filters)
60
60
 
@@ -95,7 +95,7 @@ export default class FormFieldSearchSelect extends Mixins(FormFieldMixin) {
95
95
 
96
96
  get listAction () {
97
97
  const request = this.field
98
- .getOptionsRequest()
98
+ .createOptionsRequest()
99
99
  .addParams(this.optionRequestParams || {})
100
100
  return ListAction.fromRequest(request)
101
101
  }
@@ -11,7 +11,6 @@ import { FilterSourceType } from './FilterSourceType'
11
11
  'models', 'meta', // given, if already loaded
12
12
  'listAction',
13
13
  'filterHistoryKey',
14
- 'checkBeforeLoad',
15
14
  {
16
15
  filterSource: FilterSourceType.QUERY_STRING,
17
16
  loadOnlyIfKeyword: false,
@@ -123,16 +122,6 @@ export class ListViewMixin extends Vue {
123
122
  }
124
123
 
125
124
  async load () {
126
- if (this.checkBeforeLoad) {
127
- const canLoad = await this.checkBeforeLoad()
128
- if (!canLoad) {
129
- if (this.meta_.used_filters) {
130
- this.listViewModel.initFromUsedFilters(this.meta_.used_filters, this.meta_.count_search)
131
- }
132
- return
133
- }
134
- }
135
-
136
125
  if (this.loadOnlyIfKeyword && !this.filters.q.value) {
137
126
  this.models_ = []
138
127
  this.meta_ = {}
@@ -1,16 +1,47 @@
1
1
  <template>
2
- <a-text-field
3
- ref="input"
4
- v-model="filter.value"
5
- :maxWidth="$attrs.maxWidth || maxWidth_"
6
- :label="label || 'Suche'"
7
- :debounce="500"
8
- v-bind="$attrs"
9
- clearable
10
- hide-details
11
- @keyup.esc="clearValue"
12
- v-on="$listeners"
13
- />
2
+ <div>
3
+ <a-text-field
4
+ ref="input"
5
+ v-model="filter.value"
6
+ :maxWidth="$attrs.maxWidth || maxWidth_"
7
+ :label="label_"
8
+ :debounce="500"
9
+ v-bind="$attrs"
10
+ clearable
11
+ hide-details
12
+ @keyup.esc="clearValue"
13
+ v-on="$listeners"
14
+ >
15
+ <template
16
+ v-if="hasQFieldOptions()"
17
+ #append
18
+ >
19
+ <a-context-menu>
20
+ <template #activator>
21
+ <!-- click.prevent brings hand cursor -->
22
+ <!-- mousedown.stop will prevent the input focused -->
23
+ <a-icon
24
+ @click.prevent
25
+ @mousedown.stop
26
+ >
27
+ {{ appendIcon }}
28
+ </a-icon>
29
+ </template>
30
+
31
+ <a-context-menu-item
32
+ v-for="option in qFieldOptions"
33
+ :key="option.title"
34
+ @click="filters.qfield.value = option.value"
35
+ >
36
+ <a-icon :class="{selected: filters.qfield.value === option.value}">
37
+ $checkIcon
38
+ </a-icon>
39
+ {{ option.title }}
40
+ </a-context-menu-item>
41
+ </a-context-menu>
42
+ </template>
43
+ </a-text-field>
44
+ </div>
14
45
  </template>
15
46
 
16
47
 
@@ -33,5 +64,39 @@ export default class ListFilterSearch extends Mixins(ListFilterMixin) {
33
64
  setFocus (force) {
34
65
  this.$refs.input.setFocus(force)
35
66
  }
67
+
68
+ get appendIcon () {
69
+ if (this.hasQFieldOptions()) {
70
+ return '$filterIcon'
71
+ }
72
+ }
73
+
74
+ hasQFieldOptions () {
75
+ return this.filters.qfield && this.filters.qfield.hasOptions()
76
+ }
77
+
78
+ get qFieldOptions () {
79
+ return this.filters.qfield.options
80
+ }
81
+
82
+ get label_ () {
83
+ const label = this.label || 'Suche'
84
+
85
+ if (this.hasQFieldOptions() && !this.filters.qfield.hasDefaultValueSet()) {
86
+ const selected = this.qFieldOptions.filter(o => o.value === this.filters.qfield.value)[0]
87
+ if (selected) {
88
+ return `${label} (${selected.title})`
89
+ }
90
+ }
91
+
92
+ return label
93
+ }
36
94
  }
37
95
  </script>
96
+
97
+
98
+ <style lang="scss" scoped>
99
+ .contextMenuItem > *:not(.selected) {
100
+ opacity: 0;
101
+ }
102
+ </style>
@@ -5,7 +5,7 @@
5
5
  :items="_items"
6
6
  itemText="itemTitle"
7
7
  itemValue="itemValue"
8
- :clearable="filter.value !== filter.defaultValue"
8
+ :clearable="filter.hasDefaultValue() && !filter.hasDefaultValueSet()"
9
9
  :defaultValue="filter.defaultValue"
10
10
  hide-details
11
11
  v-bind="$attrs"
@@ -36,44 +36,13 @@ export default class ListFilterSelect extends Mixins(ListFilterMixin) {
36
36
  return this.$attrs.items || this.items || []
37
37
  }
38
38
 
39
- get showNullOption () {
40
- // either null is a selectable option, than it should be shown in the list
41
- // or the default is null, so the list should offer a 'null' option for the unselected state
42
- return this.filter.nullIsOption || this.filter.defaultValue === null
43
- }
44
-
45
- createOptions () {
46
- const options = []
47
-
48
- if (this.filter.allIsOption) {
49
- options.push({
50
- itemTitle: 'Alle',
51
- itemValue: 'all'
52
- })
53
- } else if (this.showNullOption) {
54
- options.push({
55
- itemTitle: 'Alle',
56
- itemValue: null
57
- })
58
- }
59
-
60
- if (this.filter.noneIsOption) {
61
- options.push({
62
- itemTitle: 'Keine',
63
- itemValue: 'none'
64
- })
65
- }
66
-
67
- return options
68
- }
69
-
70
39
  async loadRequestOptions () {
71
40
  const {models} = await ListAction
72
41
  .fromRequest(this.filter.createOptionsRequest())
73
42
  .load()
74
43
 
75
44
  return [
76
- ...this.createOptions(),
45
+ ...this.getOptions(),
77
46
  ...models.map(model => {
78
47
  let itemValue
79
48
  if (this.itemValue) {
@@ -93,13 +62,13 @@ export default class ListFilterSelect extends Mixins(ListFilterMixin) {
93
62
 
94
63
  getOptions () {
95
64
  return [
96
- ...this.createOptions(),
97
65
  ...this.filter.options
98
- .filter(o => o !== null) // null is already set in options (if any)
99
- .map(o => ({
100
- itemTitle: o ? 'Ja' : 'Nein',
101
- itemValue: o
102
- }))
66
+ .map(o => {
67
+ return {
68
+ itemTitle: o.title,
69
+ itemValue: o.value
70
+ }
71
+ })
103
72
  ]
104
73
  }
105
74
  }
@@ -104,7 +104,7 @@ export default class FlyingContextContainer extends Vue {
104
104
  background: white;
105
105
  transition: right .2s;
106
106
  padding: 2rem;
107
- overflow-y: scroll;
107
+ overflow-y: auto;
108
108
 
109
109
  &:not(.visible) {
110
110
  right: -80vw;
@@ -12,6 +12,7 @@ import {
12
12
  mdiDelete,
13
13
  mdiDotsHorizontal,
14
14
  mdiDotsVertical,
15
+ mdiFilter,
15
16
  mdiLock,
16
17
  mdiLogoutVariant,
17
18
  mdiMagnify,
@@ -58,7 +59,8 @@ export default new Vuetify({
58
59
  printerIcon: mdiPrinter,
59
60
  euroSymbol: mdiCurrencyEur,
60
61
  paletteIcon: mdiPalette,
61
- addIcon: mdiPlusCircle
62
+ addIcon: mdiPlusCircle,
63
+ filterIcon: mdiFilter
62
64
  }
63
65
  },
64
66
  breakpoint: {