@afeefa/vue-app 0.0.160 → 0.0.162

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- 0.0.160
1
+ 0.0.162
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afeefa/vue-app",
3
- "version": "0.0.160",
3
+ "version": "0.0.162",
4
4
  "description": "",
5
5
  "author": "Afeefa Kollektiv <kollektiv@afeefa.de>",
6
6
  "license": "MIT",
@@ -60,7 +60,7 @@ export default class EditForm extends Vue {
60
60
  if (this.createModelToEdit) {
61
61
  this.modelToEdit = this.createModelToEdit(this.model)
62
62
  } else if (this.model) {
63
- this.modelToEdit = this.model.cloneForEdit()
63
+ this.modelToEdit = this.model.clone()
64
64
  }
65
65
  this.lastJson = this.json
66
66
 
@@ -99,6 +99,10 @@ export default class EditModal extends Vue {
99
99
  this.$emit('open')
100
100
  } else {
101
101
  this.$emit('close')
102
+
103
+ setTimeout(() => { // allow client to conditionally remove <edit-modal> using v-if not before inner dialog has been removed from dom
104
+ this.$emit('destroyed')
105
+ }, 100)
102
106
  }
103
107
  }
104
108
 
@@ -4,7 +4,6 @@ import EditForm from './form/EditForm'
4
4
  import EditModal from './form/EditModal'
5
5
  import FormFieldCheckbox from './form/fields/FormFieldCheckbox'
6
6
  import FormFieldDate from './form/fields/FormFieldDate'
7
- import FormFieldTime from './form/fields/FormFieldTime'
8
7
  import FormFieldRadioGroup from './form/fields/FormFieldRadioGroup'
9
8
  import FormFieldRichTextArea from './form/fields/FormFieldRichTextArea'
10
9
  import FormFieldSearchSelect from './form/fields/FormFieldSearchSelect'
@@ -12,9 +11,11 @@ import FormFieldSelect from './form/fields/FormFieldSelect'
12
11
  import FormFieldSelect2 from './form/fields/FormFieldSelect2'
13
12
  import FormFieldText from './form/fields/FormFieldText'
14
13
  import FormFieldTextArea from './form/fields/FormFieldTextArea'
14
+ import FormFieldTime from './form/fields/FormFieldTime'
15
15
  import NestedEditForm from './form/NestedEditForm'
16
16
  import ListFilterPage from './list/filters/ListFilterPage'
17
17
  import ListFilterSearch from './list/filters/ListFilterSearch'
18
+ import ListFilterSearchSelect from './list/filters/ListFilterSearchSelect'
18
19
  import ListFilterSelect from './list/filters/ListFilterSelect'
19
20
 
20
21
  Vue.component('EditForm', EditForm)
@@ -33,3 +34,4 @@ Vue.component('FormFieldSelect2', FormFieldSelect2)
33
34
  Vue.component('ListFilterPage', ListFilterPage)
34
35
  Vue.component('ListFilterSearch', ListFilterSearch)
35
36
  Vue.component('ListFilterSelect', ListFilterSelect)
37
+ Vue.component('ListFilterSearchSelect', ListFilterSearchSelect)
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <a-search-select
3
+ ref="select"
4
+ :listAction="listAction"
5
+ :selectedItems="selectedItems"
6
+ :getSearchInput="() => $refs.searchInput"
7
+ diffXControls="-.5rem"
8
+ diffYControls="-.5rem"
9
+ v-bind="$attrs"
10
+ @select="itemSelected"
11
+ @close="focusInput"
12
+ @beforeOpen="calculateSelectorSize"
13
+ >
14
+ <template #activator="{open}">
15
+ <a-text-field
16
+ ref="input"
17
+ :value="inputModel"
18
+ readonly
19
+ :label="label"
20
+ placeholder="Mausklick oder Space/↓-Taste zum Auswählen"
21
+ :clearable="!!selectedItems.length"
22
+ hide-details
23
+ @keydown.space.prevent="open"
24
+ @keydown.down.prevent="open"
25
+ @keydown.enter.prevent="open"
26
+ @clear="clear"
27
+ />
28
+ </template>
29
+
30
+ <template #filters="{onSearchInputKey}">
31
+ <a-row gap="4">
32
+ <list-filter-search
33
+ ref="searchInput"
34
+ :focus="true"
35
+ tabindex="1"
36
+ maxWidth="100%"
37
+ :label="'Suche ' + label"
38
+ v-on="onSearchInputKey"
39
+ />
40
+
41
+ <list-filter-page
42
+ :has="{page_size: false, page_number: true}"
43
+ :totalVisible="0"
44
+ />
45
+ </a-row>
46
+ </template>
47
+
48
+ <template #row="{ model, on }">
49
+ <v-icon
50
+ v-if="$has.icon"
51
+ :color="model.getIcon().color"
52
+ size="1.5rem"
53
+ class="mr-2"
54
+ v-on="on"
55
+ v-text="model.getIcon().icon"
56
+ />
57
+
58
+ <div
59
+ style="width:100%;"
60
+ v-on="on"
61
+ >
62
+ {{ model.getTitle() }}
63
+ </div>
64
+ </template>
65
+ </a-search-select>
66
+ </template>
67
+
68
+
69
+ <script>
70
+ import { Component, Mixins } from '@a-vue'
71
+ import { ListFilterMixin } from '../ListFilterMixin'
72
+ import { ListAction } from '@a-vue/api-resources/ApiActions'
73
+
74
+ @Component({
75
+ props: ['itemTitle', 'itemValue']
76
+ })
77
+ export default class ListFilterSearchSelect extends Mixins(ListFilterMixin) {
78
+ $hasOptions = ['icon']
79
+
80
+ items = []
81
+ inputModel = 'Alle'
82
+
83
+ async created () {
84
+ if (this.filter.value) {
85
+ const {models} = await this.createListAction()
86
+ .params({
87
+ [this.filter.name]: this.filter.value
88
+ })
89
+ .load()
90
+ if (models.length) {
91
+ this.inputModel = models[0].getTitle()
92
+ }
93
+ }
94
+ }
95
+
96
+ calculateSelectorSize () {
97
+ const input = this.$refs.input.$el
98
+ const inputWidth = input.offsetWidth
99
+ this.$refs.select.setWidth(`calc(${inputWidth}px + 1rem)`)
100
+ }
101
+
102
+ get selectedItems () {
103
+ return [this.filter.value].filter(a => a)
104
+ }
105
+
106
+ get listAction () {
107
+ return this.createListAction()
108
+ }
109
+
110
+ createListAction () {
111
+ const request = this.filter
112
+ .createOptionsRequest()
113
+ return ListAction.fromRequest(request)
114
+ }
115
+
116
+ itemSelected (model) {
117
+ if (model) {
118
+ this.filter.value = model.id
119
+ this.inputModel = model.getTitle()
120
+ } else {
121
+ this.filter.value = null
122
+ }
123
+ this.$emit('select', model)
124
+ }
125
+
126
+ focusInput () {
127
+ this.$refs.input.setFocus(true)
128
+ }
129
+
130
+ clear () {
131
+ this.itemSelected(null)
132
+
133
+ setTimeout(() => { // input clear sets internal model to ''
134
+ this.inputModel = 'Alle'
135
+ }, 100)
136
+ }
137
+ }
138
+ </script>
@@ -73,7 +73,12 @@ export default class SearchSelectList extends Mixins(ListViewMixin) {
73
73
  }
74
74
 
75
75
  isSelected (model) {
76
- return !!this.selectedItems.find(i => i.equals(model))
76
+ return !!this.selectedItems.find(i => {
77
+ if (i.equals) {
78
+ return i.equals(model)
79
+ }
80
+ return i === model // if list item is a string not a model e.g. in filters
81
+ })
77
82
  }
78
83
 
79
84
  _filtersInitialized () {
@@ -34,6 +34,7 @@ export default class FlyingContextContainer extends Vue {
34
34
  visible = false
35
35
  oldOverflowY = null
36
36
  isClosing = false
37
+ lastScrollbarWidth = 0
37
38
 
38
39
  mounted () {
39
40
  const mutationWatcher = new MutationObserver(this.domChanged)
@@ -63,9 +64,8 @@ export default class FlyingContextContainer extends Vue {
63
64
  sizeChanged () {
64
65
  if (this.visible && !this.isClosing) { // do not set size if it is already closing
65
66
  this.$nextTick(() => {
66
- const scrollbarWidth = this.getScrollbarWidth()
67
67
  const el = document.documentElement
68
- const newSize = el.offsetWidth - this.$el.offsetWidth + scrollbarWidth
68
+ const newSize = el.offsetWidth - this.$el.offsetWidth + this.lastScrollbarWidth
69
69
  this.$el.style.left = newSize + 'px'
70
70
  })
71
71
  }
@@ -80,13 +80,13 @@ export default class FlyingContextContainer extends Vue {
80
80
  if (this.visible) {
81
81
  const style = getComputedStyle(el)
82
82
  this.oldOverflowY = style.overflowY
83
- const scrollbarWidth = this.getScrollbarWidth()
83
+ this.lastScrollbarWidth = this.getScrollbarWidth()
84
84
  setTimeout(() => {
85
85
  el.style.overflowY = 'hidden'
86
- el.style.marginRight = scrollbarWidth + 'px'
86
+ el.style.marginRight = this.lastScrollbarWidth + 'px'
87
87
  }, 100)
88
88
 
89
- this.$el.style.left = (el.offsetWidth - this.$el.offsetWidth + scrollbarWidth) + 'px'
89
+ this.$el.style.left = (el.offsetWidth - this.$el.offsetWidth + this.lastScrollbarWidth) + 'px'
90
90
  } else {
91
91
  el.style.overflowY = this.oldOverflowY
92
92
  el.style.marginRight = 0