@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.
- package/.afeefa/package/release/version.txt +1 -1
- package/package.json +1 -1
- package/src/components/form/EditForm.vue +1 -1
- package/src/components/form/EditModal.vue +4 -0
- package/src/components/index.js +3 -1
- package/src/components/list/filters/ListFilterSearchSelect.vue +138 -0
- package/src/components/search-select/SearchSelectList.vue +6 -1
- package/src-admin/components/FlyingContextContainer.vue +5 -5
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.162
|
package/package.json
CHANGED
@@ -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.
|
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
|
|
package/src/components/index.js
CHANGED
@@ -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 =>
|
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 +
|
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
|
-
|
83
|
+
this.lastScrollbarWidth = this.getScrollbarWidth()
|
84
84
|
setTimeout(() => {
|
85
85
|
el.style.overflowY = 'hidden'
|
86
|
-
el.style.marginRight =
|
86
|
+
el.style.marginRight = this.lastScrollbarWidth + 'px'
|
87
87
|
}, 100)
|
88
88
|
|
89
|
-
this.$el.style.left = (el.offsetWidth - this.$el.offsetWidth +
|
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
|