@afeefa/vue-app 0.0.110 → 0.0.112
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.
- package/.afeefa/package/release/version.txt +1 -1
- package/README.md +4 -0
- package/docs/components/amodal.md +19 -0
- package/package.json +1 -1
- package/src/api-resources/ApiAction.js +6 -0
- package/src/api-resources/DeleteAction.js +7 -5
- package/src/api-resources/GetAction.js +7 -5
- package/src/api-resources/SaveAction.js +7 -5
- package/src/components/AAutocomplete.vue +2 -2
- package/src/components/ADatePicker.vue +7 -2
- package/src/components/AGrid.vue +11 -4
- package/src/components/ASelect.vue +9 -2
- package/src/components/ATextArea.vue +2 -2
- package/src/components/ATextField.vue +139 -41
- package/src/components/form/EditModal.vue +5 -1
- package/src/components/form/fields/FormFieldText.vue +2 -68
- package/src/components/index.js +0 -2
- package/src/components/list/filters/ListFilterPage.vue +3 -4
- package/src/components/list/filters/ListFilterSearch.vue +1 -0
- package/src/components/list/filters/ListFilterSelect.vue +1 -0
- package/src/index.js +1 -1
- package/src-admin/components/controls/SearchSelectFormField.vue +2 -2
- package/src/components/list/ListFilterRow.vue +0 -26
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.112
|
package/README.md
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
# AModal
|
2
|
+
|
3
|
+
It's a Modal capsule for vuetifys Modals. Whats the magic about it?
|
4
|
+
|
5
|
+
The Modal is by default relatively positioned near its activator.
|
6
|
+
|
7
|
+
## Properties
|
8
|
+
|
9
|
+
* show
|
10
|
+
* icon
|
11
|
+
* title
|
12
|
+
* beforeClose
|
13
|
+
* anchorPosition
|
14
|
+
* screenCentered
|
15
|
+
|
16
|
+
|
17
|
+
### screenCentered
|
18
|
+
|
19
|
+
if set to true the Modal is positioned in the middle of the Viewport, like in vuetify's default beavior.
|
package/package.json
CHANGED
@@ -10,6 +10,7 @@ export class ApiAction extends ApiResourcesApiAction {
|
|
10
10
|
_dispatchGlobalSaveEvents = false
|
11
11
|
_minDuration = 100
|
12
12
|
_startTime = 0
|
13
|
+
_showError = true
|
13
14
|
|
14
15
|
id (id) {
|
15
16
|
this.param('id', id)
|
@@ -21,6 +22,11 @@ export class ApiAction extends ApiResourcesApiAction {
|
|
21
22
|
return this
|
22
23
|
}
|
23
24
|
|
25
|
+
hideError () {
|
26
|
+
this._showError = false
|
27
|
+
return this
|
28
|
+
}
|
29
|
+
|
24
30
|
dispatchGlobalLoadingEvents (dispatch = true) {
|
25
31
|
this._dispatchGlobalLoadingEvents = dispatch
|
26
32
|
return this
|
@@ -27,10 +27,12 @@ export class DeleteAction extends ApiAction {
|
|
27
27
|
}
|
28
28
|
|
29
29
|
processError (result) {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
if (this._showError) {
|
31
|
+
eventBus.dispatch(new AlertEvent(AlertEvent.ERROR, {
|
32
|
+
headline: 'Die Daten konnten nicht gelöscht werden.',
|
33
|
+
message: result.message,
|
34
|
+
detail: result.detail
|
35
|
+
}))
|
36
|
+
}
|
35
37
|
}
|
36
38
|
}
|
@@ -9,10 +9,12 @@ export class GetAction extends ApiAction {
|
|
9
9
|
}
|
10
10
|
|
11
11
|
processError (result) {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
if (this._showError) {
|
13
|
+
eventBus.dispatch(new AlertEvent(AlertEvent.ERROR, {
|
14
|
+
headline: 'Die Daten konntent nicht geladen werden.',
|
15
|
+
message: result.message,
|
16
|
+
detail: result.detail
|
17
|
+
}))
|
18
|
+
}
|
17
19
|
}
|
18
20
|
}
|
@@ -17,10 +17,12 @@ export class SaveAction extends ApiAction {
|
|
17
17
|
}
|
18
18
|
|
19
19
|
processError (result) {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
if (this._showError) {
|
21
|
+
eventBus.dispatch(new AlertEvent(AlertEvent.ERROR, {
|
22
|
+
headline: 'Die Daten konnten nicht gespeichert werden.',
|
23
|
+
message: result.message,
|
24
|
+
detail: result.detail
|
25
|
+
}))
|
26
|
+
}
|
25
27
|
}
|
26
28
|
}
|
@@ -11,7 +11,7 @@
|
|
11
11
|
no-filter
|
12
12
|
|
13
13
|
:rules="validationRules"
|
14
|
-
v-bind="
|
14
|
+
v-bind="{...$attrs, dense, outlined}"
|
15
15
|
v-on="$listeners"
|
16
16
|
/>
|
17
17
|
</template>
|
@@ -23,7 +23,7 @@ import { Model } from '@afeefa/api-resources-client'
|
|
23
23
|
import { debounce } from '@a-vue/utils/debounce'
|
24
24
|
|
25
25
|
@Component({
|
26
|
-
props: ['items', 'validator', 'defaultValue', 'selectedItemText', 'debounce']
|
26
|
+
props: ['items', 'validator', 'defaultValue', 'selectedItemText', 'debounce', {dense: true, outlined: true}]
|
27
27
|
})
|
28
28
|
export default class AAutocomplete extends Vue {
|
29
29
|
isLoading = false
|
@@ -12,7 +12,7 @@
|
|
12
12
|
:value="formattedDate"
|
13
13
|
:label="label"
|
14
14
|
:style="cwm_widthStyle"
|
15
|
-
v-bind="{...$attrs, ...attrs}"
|
15
|
+
v-bind="{...$attrs, ...attrs, dense, outlined}"
|
16
16
|
:rules="validationRules"
|
17
17
|
:error-messages="errorMessages"
|
18
18
|
:readonly="type === 'month'"
|
@@ -41,7 +41,7 @@ import { formatDate } from '@a-vue/utils/format-date'
|
|
41
41
|
import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
42
42
|
|
43
43
|
@Component({
|
44
|
-
props: ['value', 'validator', 'type']
|
44
|
+
props: ['value', 'validator', 'type', {dense: true, outlined: true}]
|
45
45
|
})
|
46
46
|
export default class ADatePicker extends Mixins(ComponentWidthMixin) {
|
47
47
|
value_ = null
|
@@ -153,8 +153,13 @@ export default class ADatePicker extends Mixins(ComponentWidthMixin) {
|
|
153
153
|
<style lang="scss" scoped>
|
154
154
|
:deep(.v-select__slot) {
|
155
155
|
cursor: pointer;
|
156
|
+
|
156
157
|
input {
|
157
158
|
cursor: pointer;
|
158
159
|
}
|
159
160
|
}
|
161
|
+
|
162
|
+
.v-text-field :deep(.v-input__icon--clear) { // always show clear icon, https://github.com/vuetifyjs/vuetify/pull/15876
|
163
|
+
opacity: 1;
|
164
|
+
}
|
160
165
|
</style>
|
package/src/components/AGrid.vue
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
<template>
|
2
|
-
<div
|
2
|
+
<div
|
3
|
+
:style="{display: displayStyle}"
|
4
|
+
:class="['a-grid', colsClass, gapClass, evenClass, breakMobileClass]"
|
5
|
+
>
|
3
6
|
<slot />
|
4
7
|
</div>
|
5
8
|
</template>
|
@@ -10,7 +13,7 @@ import { Component, Mixins } from '@a-vue'
|
|
10
13
|
import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
11
14
|
|
12
15
|
@Component({
|
13
|
-
props: ['gap', 'hGap', 'vGap', 'cols', {even: false}, 'breakMobile']
|
16
|
+
props: ['gap', 'hGap', 'vGap', 'cols', {inline: false, even: false}, 'breakMobile']
|
14
17
|
})
|
15
18
|
export default class AGrid extends Mixins(ComponentWidthMixin) {
|
16
19
|
get breakMobileClass () {
|
@@ -19,6 +22,10 @@ export default class AGrid extends Mixins(ComponentWidthMixin) {
|
|
19
22
|
}
|
20
23
|
}
|
21
24
|
|
25
|
+
get displayStyle () {
|
26
|
+
return this.inline ? 'inline-grid' : 'grid'
|
27
|
+
}
|
28
|
+
|
22
29
|
get colsClass () {
|
23
30
|
const cols = this.cols || 2
|
24
31
|
return 'cols-' + cols
|
@@ -53,11 +60,10 @@ export default class AGrid extends Mixins(ComponentWidthMixin) {
|
|
53
60
|
|
54
61
|
<style scoped lang="scss">
|
55
62
|
.a-grid {
|
56
|
-
display: grid;
|
57
|
-
|
58
63
|
@for $i from 1 through 8 {
|
59
64
|
&.cols-#{$i} {
|
60
65
|
grid-template-columns: repeat(#{$i}, auto);
|
66
|
+
|
61
67
|
&.even {
|
62
68
|
grid-template-columns: repeat(#{$i}, 1fr);
|
63
69
|
}
|
@@ -67,6 +73,7 @@ export default class AGrid extends Mixins(ComponentWidthMixin) {
|
|
67
73
|
&.breakMobile {
|
68
74
|
@media (max-width: 900px), (orientation : portrait) {
|
69
75
|
grid-template-columns: 1fr;
|
76
|
+
|
70
77
|
&.even {
|
71
78
|
grid-template-columns: 1fr;
|
72
79
|
}
|
@@ -5,7 +5,7 @@
|
|
5
5
|
:items="items_"
|
6
6
|
:valueComparator="compareValues"
|
7
7
|
:style="cwm_widthStyle"
|
8
|
-
v-bind="
|
8
|
+
v-bind="{...$attrs, dense, outlined}"
|
9
9
|
v-on="$listeners"
|
10
10
|
/>
|
11
11
|
</template>
|
@@ -17,7 +17,7 @@ import { Model } from '@afeefa/api-resources-client'
|
|
17
17
|
import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
18
18
|
|
19
19
|
@Component({
|
20
|
-
props: ['validator', 'defaultValue', 'items']
|
20
|
+
props: ['validator', 'defaultValue', 'items', {dense: true, outlined: true}]
|
21
21
|
})
|
22
22
|
export default class ASelect extends Mixins(ComponentWidthMixin) {
|
23
23
|
items_ = []
|
@@ -96,3 +96,10 @@ export default class ASelect extends Mixins(ComponentWidthMixin) {
|
|
96
96
|
}
|
97
97
|
}
|
98
98
|
</script>
|
99
|
+
|
100
|
+
|
101
|
+
<style lang="scss" scoped>
|
102
|
+
.v-text-field :deep(.v-input__icon--clear) { // always show clear icon, https://github.com/vuetifyjs/vuetify/pull/15876
|
103
|
+
opacity: 1;
|
104
|
+
}
|
105
|
+
</style>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
ref="input"
|
4
4
|
:rules="validationRules"
|
5
5
|
:counter="counter"
|
6
|
-
v-bind="
|
6
|
+
v-bind="{...$attrs, dense, outlined}"
|
7
7
|
v-on="$listeners"
|
8
8
|
/>
|
9
9
|
</template>
|
@@ -13,7 +13,7 @@
|
|
13
13
|
import { Component, Vue } from '@a-vue'
|
14
14
|
|
15
15
|
@Component({
|
16
|
-
props: ['validator']
|
16
|
+
props: ['validator', {dense: true, outlined: true}]
|
17
17
|
})
|
18
18
|
export default class ATextArea extends Vue {
|
19
19
|
mounted () {
|
@@ -1,45 +1,150 @@
|
|
1
1
|
<template>
|
2
2
|
<v-text-field
|
3
3
|
ref="input"
|
4
|
-
|
5
|
-
:autocomplete="autocomplete"
|
6
|
-
:rules="validationRules"
|
4
|
+
v-model="internalValue"
|
7
5
|
:counter="counter"
|
8
6
|
:style="cwm_widthStyle"
|
9
|
-
|
10
|
-
v-
|
11
|
-
@
|
7
|
+
:error-messages="errorMessages"
|
8
|
+
v-bind="attrs"
|
9
|
+
@input="inputChanged"
|
10
|
+
@keyup.esc="clear"
|
11
|
+
@click:clear="clear"
|
12
|
+
v-on="listeners"
|
12
13
|
/>
|
13
14
|
</template>
|
14
15
|
|
15
16
|
|
16
17
|
<script>
|
17
|
-
import { Component, Watch, Mixins } from '@a-vue'
|
18
|
+
import { Component, Watch, Mixins, Inject } from '@a-vue'
|
18
19
|
import { debounce } from '@a-vue/utils/debounce'
|
19
20
|
import { ComponentWidthMixin } from './mixins/ComponentWidthMixin'
|
20
21
|
|
21
22
|
@Component({
|
22
|
-
props: ['debounce', 'validator', {
|
23
|
+
props: ['value', 'debounce', 'validator', 'rules', {dense: true, outlined: true, clearable: false, focus: false, number: false}]
|
23
24
|
})
|
24
25
|
export default class ATextField extends Mixins(ComponentWidthMixin) {
|
25
26
|
$hasOptions = ['counter']
|
26
27
|
|
27
|
-
|
28
|
+
@Inject({ from: 'form', default: null }) form
|
29
|
+
|
30
|
+
internalValue = null
|
31
|
+
errorMessages = []
|
32
|
+
debounceInputFunction = null
|
28
33
|
|
29
34
|
created () {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}, this.debounce, value => value)
|
34
|
-
}
|
35
|
+
this.form && this.form.register(this)
|
36
|
+
|
37
|
+
this.setInternalValue(this.value)
|
35
38
|
}
|
36
39
|
|
37
40
|
mounted () {
|
38
41
|
this.setFocus()
|
39
42
|
|
40
|
-
|
41
|
-
|
43
|
+
this.$emit('input:internal', this.internalValue)
|
44
|
+
this.validate()
|
45
|
+
}
|
46
|
+
|
47
|
+
setInternalValue (value) {
|
48
|
+
if (typeof value === 'number') {
|
49
|
+
value = value.toString()
|
50
|
+
}
|
51
|
+
this.internalValue = value || ''
|
52
|
+
}
|
53
|
+
|
54
|
+
@Watch('value')
|
55
|
+
valueChanged () {
|
56
|
+
this.setInternalValue(this.value)
|
57
|
+
}
|
58
|
+
|
59
|
+
get listeners () {
|
60
|
+
// remove input from nested listening
|
61
|
+
// let clients listend to only THIS component
|
62
|
+
const listeners = {...this.$listeners}
|
63
|
+
delete listeners.input
|
64
|
+
return listeners
|
65
|
+
}
|
66
|
+
|
67
|
+
get attrs () {
|
68
|
+
// remove 'rules' from being passed to v-text-field
|
69
|
+
const attrs = {...this.$attrs}
|
70
|
+
delete attrs.rules
|
71
|
+
|
72
|
+
attrs.dense = this.dense
|
73
|
+
attrs.outlined = this.outlined
|
74
|
+
attrs.clearable = this.clearable
|
75
|
+
return attrs
|
76
|
+
}
|
77
|
+
|
78
|
+
clear () {
|
79
|
+
if (this.clearable) {
|
80
|
+
this.setInternalValue('')
|
81
|
+
this.$emit('input', this.emptyValue)
|
82
|
+
this.validate()
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
inputChanged () {
|
87
|
+
this.$emit('input:internal', this.internalValue)
|
88
|
+
|
89
|
+
const valid = this.validate()
|
90
|
+
|
91
|
+
if (!valid) {
|
92
|
+
return
|
93
|
+
}
|
94
|
+
|
95
|
+
const value = this.stringToNumber(this.internalValue)
|
96
|
+
|
97
|
+
// NaN means: wrong numerical value AND no validator present
|
98
|
+
// otherwise validator would return validate() -> false
|
99
|
+
if (Number.isNaN(value)) {
|
100
|
+
return
|
101
|
+
}
|
102
|
+
|
103
|
+
if (this.debounce) {
|
104
|
+
if (!this.debounceInputFunction) {
|
105
|
+
this.debounceInputFunction = debounce(value => {
|
106
|
+
this.$emit('input', value)
|
107
|
+
}, this.debounce, value => value) // fire immediately if !value (click clearable-x)
|
108
|
+
}
|
109
|
+
this.debounceInputFunction(value)
|
110
|
+
} else {
|
111
|
+
this.$emit('input', value)
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
stringToNumber (value) {
|
116
|
+
if (this.treatAsNumericValue) {
|
117
|
+
if (!value) {
|
118
|
+
value = null
|
119
|
+
} else {
|
120
|
+
value = this.internalValue.match(/^\d*(.\d+)?$/) ? parseFloat(this.internalValue) : NaN
|
121
|
+
}
|
42
122
|
}
|
123
|
+
return value
|
124
|
+
}
|
125
|
+
|
126
|
+
get type () {
|
127
|
+
return this.$attrs.type || 'text'
|
128
|
+
}
|
129
|
+
|
130
|
+
get treatAsNumericValue () {
|
131
|
+
return this.type === 'number' || this.number
|
132
|
+
}
|
133
|
+
|
134
|
+
validate () {
|
135
|
+
const rules = this.validationRules
|
136
|
+
let errorMessage = null
|
137
|
+
for (const rule of rules) {
|
138
|
+
const value = this.stringToNumber(this.internalValue)
|
139
|
+
const result = rule(value)
|
140
|
+
if (result !== true) {
|
141
|
+
errorMessage = result
|
142
|
+
break
|
143
|
+
}
|
144
|
+
}
|
145
|
+
|
146
|
+
this.errorMessages = [errorMessage].filter(e => e)
|
147
|
+
return !this.errorMessages.length
|
43
148
|
}
|
44
149
|
|
45
150
|
@Watch('focus')
|
@@ -58,49 +163,42 @@ export default class ATextField extends Mixins(ComponentWidthMixin) {
|
|
58
163
|
}
|
59
164
|
}
|
60
165
|
|
61
|
-
get type () {
|
62
|
-
if (this.password && !this.showPassword) {
|
63
|
-
return 'password'
|
64
|
-
}
|
65
|
-
return 'text'
|
66
|
-
}
|
67
|
-
|
68
|
-
get appendIcon () {
|
69
|
-
if (this.password) {
|
70
|
-
return this.showPassword ? '$eyeIcon' : '$eyeOffIcon'
|
71
|
-
}
|
72
|
-
return null
|
73
|
-
}
|
74
|
-
|
75
|
-
get autocomplete () {
|
76
|
-
if (this.password) {
|
77
|
-
return 'new-password'
|
78
|
-
}
|
79
|
-
return null
|
80
|
-
}
|
81
|
-
|
82
166
|
get validationRules () {
|
167
|
+
if (this.$attrs.rules) {
|
168
|
+
return this.$attrs.rules
|
169
|
+
}
|
83
170
|
const label = this.$attrs.label
|
84
171
|
return (this.validator && this.validator.getRules(label)) || []
|
85
172
|
}
|
86
173
|
|
87
174
|
get counter () {
|
88
175
|
if (!this.$has.counter) {
|
89
|
-
return
|
176
|
+
return null
|
90
177
|
}
|
91
178
|
|
92
179
|
if (!this.validator) {
|
93
|
-
return
|
180
|
+
return null
|
94
181
|
}
|
95
182
|
|
96
|
-
return
|
183
|
+
return this.validator.getMaxValueLength()
|
184
|
+
}
|
185
|
+
|
186
|
+
get emptyValue () {
|
187
|
+
if (this.validator) {
|
188
|
+
return this.validator.getEmptyValue()
|
189
|
+
}
|
190
|
+
return null
|
97
191
|
}
|
98
192
|
}
|
99
193
|
</script>
|
100
194
|
|
101
195
|
|
102
196
|
<style lang="scss" scoped>
|
103
|
-
.v-input:not(.v-input--is-focused) :deep(.v-counter) {
|
197
|
+
.v-input:not(.v-input--is-focused) :deep(.v-counter) { // hide counter when not focused
|
104
198
|
display: none;
|
105
199
|
}
|
200
|
+
|
201
|
+
.v-text-field :deep(.v-input__icon--clear) { // always show clear icon, https://github.com/vuetifyjs/vuetify/pull/15876
|
202
|
+
opacity: 1;
|
203
|
+
}
|
106
204
|
</style>
|
@@ -44,7 +44,7 @@
|
|
44
44
|
small
|
45
45
|
angular
|
46
46
|
:has="{reset: !!modelToEdit.id}"
|
47
|
-
@save="$emit('save', modelToEdit, ignoreChangesOnClose)"
|
47
|
+
@save="$emit('save', modelToEdit, ignoreChangesOnClose, close)"
|
48
48
|
@reset="$refs.form.reset()"
|
49
49
|
/>
|
50
50
|
</a-row>
|
@@ -68,6 +68,10 @@ export default class EditModal extends Vue {
|
|
68
68
|
ignoreChangesOnClose_ = false
|
69
69
|
|
70
70
|
created () {
|
71
|
+
if (!this.model && !this.createModelToEdit) {
|
72
|
+
console.warn('You need to pass either a model or a model factory to <edit-modal>.')
|
73
|
+
}
|
74
|
+
|
71
75
|
if (this.show) { // open on create with v-show
|
72
76
|
this.open()
|
73
77
|
}
|
@@ -1,12 +1,10 @@
|
|
1
1
|
<template>
|
2
2
|
<a-text-field
|
3
|
-
|
3
|
+
v-model="model[name]"
|
4
4
|
:label="label || name"
|
5
5
|
:validator="validator"
|
6
6
|
v-bind="$attrs"
|
7
7
|
v-on="$listeners"
|
8
|
-
@input="textFieldValueChanged"
|
9
|
-
@blur="onBlur"
|
10
8
|
/>
|
11
9
|
</template>
|
12
10
|
|
@@ -14,71 +12,7 @@
|
|
14
12
|
import { Component, Mixins } from '@a-vue'
|
15
13
|
import { FormFieldMixin } from '../FormFieldMixin'
|
16
14
|
|
17
|
-
@Component
|
18
|
-
props: [{emptyNull: false}]
|
19
|
-
})
|
15
|
+
@Component
|
20
16
|
export default class FormFieldText extends Mixins(FormFieldMixin) {
|
21
|
-
internalValue = ''
|
22
|
-
|
23
|
-
created () {
|
24
|
-
this.setInternalValue(this.model[this.name])
|
25
|
-
this.$watch(() => this.model[this.name], value => {
|
26
|
-
this.setInternalValue(value)
|
27
|
-
})
|
28
|
-
}
|
29
|
-
|
30
|
-
onBlur () {
|
31
|
-
this.setInternalValue(this.model[this.name], true)
|
32
|
-
}
|
33
|
-
|
34
|
-
textFieldValueChanged (value) {
|
35
|
-
this.internalValue = value
|
36
|
-
|
37
|
-
// cast to number
|
38
|
-
if (this.isNumber) {
|
39
|
-
value = Number(value)
|
40
|
-
if (isNaN(value)) {
|
41
|
-
return // do not set anything to the model
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
// set model value to null if empty
|
46
|
-
if (this.emptyNull) {
|
47
|
-
if (this.isNumber) {
|
48
|
-
if (value === 0) {
|
49
|
-
value = null
|
50
|
-
}
|
51
|
-
} else {
|
52
|
-
if (!value) {
|
53
|
-
value = null
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
this.model[this.name] = value
|
59
|
-
this.$emit('input', value)
|
60
|
-
}
|
61
|
-
|
62
|
-
setInternalValue (value, reset = false) {
|
63
|
-
if (this.isNumber) {
|
64
|
-
// reset text field if value is null but keep leading 0 (allows for copy and paste)
|
65
|
-
if (value === null) {
|
66
|
-
if (!reset && this.internalValue === '0') {
|
67
|
-
value = '0'
|
68
|
-
} else {
|
69
|
-
value = ''
|
70
|
-
}
|
71
|
-
}
|
72
|
-
} else { // null string should be ''
|
73
|
-
if (!value) {
|
74
|
-
value = ''
|
75
|
-
}
|
76
|
-
}
|
77
|
-
this.internalValue = value
|
78
|
-
}
|
79
|
-
|
80
|
-
get isNumber () {
|
81
|
-
return this.$attrs.number === ''
|
82
|
-
}
|
83
17
|
}
|
84
18
|
</script>
|
package/src/components/index.js
CHANGED
@@ -15,7 +15,6 @@ import NestedEditForm from './form/NestedEditForm'
|
|
15
15
|
import ListFilterPage from './list/filters/ListFilterPage'
|
16
16
|
import ListFilterSearch from './list/filters/ListFilterSearch'
|
17
17
|
import ListFilterSelect from './list/filters/ListFilterSelect'
|
18
|
-
import ListFilterRow from './list/ListFilterRow'
|
19
18
|
|
20
19
|
Vue.component('EditForm', EditForm)
|
21
20
|
Vue.component('NestedEditForm', NestedEditForm)
|
@@ -31,5 +30,4 @@ Vue.component('FormFieldSelect', FormFieldSelect)
|
|
31
30
|
Vue.component('FormFieldSelect2', FormFieldSelect2)
|
32
31
|
Vue.component('ListFilterPage', ListFilterPage)
|
33
32
|
Vue.component('ListFilterSearch', ListFilterSearch)
|
34
|
-
Vue.component('ListFilterRow', ListFilterRow)
|
35
33
|
Vue.component('ListFilterSelect', ListFilterSelect)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<a-row
|
3
|
-
gap="8"
|
4
|
-
>
|
2
|
+
<a-row gap="8">
|
5
3
|
<a-pagination
|
6
4
|
v-if="count && numPages > 1"
|
7
5
|
v-model="filter.value"
|
@@ -20,6 +18,7 @@
|
|
20
18
|
:items="pageSizeFilter.options"
|
21
19
|
:defaultValue="pageSizeFilter.defaultValue"
|
22
20
|
:clearable="!pageSizeFilter.hasDefaultValueSet()"
|
21
|
+
hide-details
|
23
22
|
/>
|
24
23
|
</a-row>
|
25
24
|
</template>
|
@@ -54,7 +53,7 @@ export default class ListFilterPage extends Mixins(ListFilterMixin) {
|
|
54
53
|
|
55
54
|
<style lang="scss" scoped>
|
56
55
|
.v-select {
|
57
|
-
max-width:
|
56
|
+
max-width: 150px;
|
58
57
|
}
|
59
58
|
|
60
59
|
.pageNumber {
|
package/src/index.js
CHANGED
@@ -76,7 +76,7 @@
|
|
76
76
|
</template>
|
77
77
|
|
78
78
|
<template #filters>
|
79
|
-
<
|
79
|
+
<a-row gap="4">
|
80
80
|
<list-filter-search
|
81
81
|
:focus="true"
|
82
82
|
maxWidth="100%"
|
@@ -87,7 +87,7 @@
|
|
87
87
|
:has="{page_size: false, page_number: true}"
|
88
88
|
:totalVisible="0"
|
89
89
|
/>
|
90
|
-
</
|
90
|
+
</a-row>
|
91
91
|
</template>
|
92
92
|
|
93
93
|
<template #row="{ model, on }">
|
@@ -1,26 +0,0 @@
|
|
1
|
-
<template>
|
2
|
-
<a-row
|
3
|
-
:gap="gap || 4"
|
4
|
-
class="mb-0"
|
5
|
-
>
|
6
|
-
<slot />
|
7
|
-
</a-row>
|
8
|
-
</template>
|
9
|
-
|
10
|
-
|
11
|
-
<script>
|
12
|
-
import { Component, Vue } from '@a-vue'
|
13
|
-
|
14
|
-
@Component({
|
15
|
-
props: ['gap']
|
16
|
-
})
|
17
|
-
export default class ListFilterRow extends Vue {
|
18
|
-
}
|
19
|
-
</script>
|
20
|
-
|
21
|
-
|
22
|
-
<style scoped lang="scss">
|
23
|
-
:deep(.v-text-field__details) {
|
24
|
-
display: none;
|
25
|
-
}
|
26
|
-
</style>
|