frappe-ui 0.0.12 → 0.0.13
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/package.json +1 -1
- package/src/components/Dropdown.vue +6 -6
- package/src/components/Input.vue +5 -3
- package/src/components/Popover.vue +45 -19
- package/src/utils/resources.js +55 -14
package/package.json
CHANGED
|
@@ -86,25 +86,25 @@ export default {
|
|
|
86
86
|
onClick,
|
|
87
87
|
}
|
|
88
88
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
dropdownItems() {
|
|
92
|
-
return (this.options || [])
|
|
89
|
+
filterOptions(options) {
|
|
90
|
+
return (options || [])
|
|
93
91
|
.filter(Boolean)
|
|
94
92
|
.filter((option) => (option.condition ? option.condition() : true))
|
|
95
93
|
.map((option) => this.normalizeDropdownItem(option))
|
|
96
94
|
},
|
|
95
|
+
},
|
|
96
|
+
computed: {
|
|
97
97
|
groups() {
|
|
98
98
|
let groups = this.options[0]?.group
|
|
99
99
|
? this.options
|
|
100
|
-
: [{ group: '', items: this.options }]
|
|
100
|
+
: [{ group: '', items: this.filterOptions(this.options) }]
|
|
101
101
|
|
|
102
102
|
return groups.map((group, i) => {
|
|
103
103
|
return {
|
|
104
104
|
key: i,
|
|
105
105
|
group: group.group,
|
|
106
106
|
hideLabel: group.hideLabel || false,
|
|
107
|
-
items: group.items
|
|
107
|
+
items: this.filterOptions(group.items),
|
|
108
108
|
}
|
|
109
109
|
})
|
|
110
110
|
},
|
package/src/components/Input.vue
CHANGED
|
@@ -68,6 +68,7 @@ import { debounce } from 'frappe-ui'
|
|
|
68
68
|
export default {
|
|
69
69
|
name: 'Input',
|
|
70
70
|
inheritAttrs: false,
|
|
71
|
+
expose: ['getInputValue'],
|
|
71
72
|
props: {
|
|
72
73
|
label: {
|
|
73
74
|
type: String,
|
|
@@ -122,9 +123,10 @@ export default {
|
|
|
122
123
|
this.$refs.input.blur()
|
|
123
124
|
},
|
|
124
125
|
getInputValue(e) {
|
|
125
|
-
let
|
|
126
|
+
let $input = e ? e.target : this.$refs.input
|
|
127
|
+
let value = $input.value
|
|
126
128
|
if (this.type == 'checkbox') {
|
|
127
|
-
value =
|
|
129
|
+
value = $input.checked
|
|
128
130
|
}
|
|
129
131
|
return value
|
|
130
132
|
},
|
|
@@ -134,7 +136,7 @@ export default {
|
|
|
134
136
|
if ('value' in this.$attrs) {
|
|
135
137
|
return this.$attrs.value
|
|
136
138
|
}
|
|
137
|
-
return this.modelValue
|
|
139
|
+
return this.modelValue || null
|
|
138
140
|
},
|
|
139
141
|
inputAttributes() {
|
|
140
142
|
let onInput = (e) => {
|
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="reference">
|
|
3
|
-
<div
|
|
4
|
-
|
|
3
|
+
<div
|
|
4
|
+
class="h-full"
|
|
5
|
+
ref="target"
|
|
6
|
+
@click="updatePosition"
|
|
7
|
+
@focusin="updatePosition"
|
|
8
|
+
@keydown="updatePosition"
|
|
9
|
+
>
|
|
10
|
+
<slot
|
|
11
|
+
name="target"
|
|
12
|
+
v-bind="{ togglePopover, updatePosition, open, close }"
|
|
13
|
+
></slot>
|
|
5
14
|
</div>
|
|
6
|
-
<teleport to="#
|
|
15
|
+
<teleport to="#frappeui-popper-root">
|
|
7
16
|
<div
|
|
8
17
|
ref="popover"
|
|
9
18
|
:class="popoverClass"
|
|
10
|
-
class="
|
|
11
|
-
|
|
19
|
+
class="relative z-[100] popover-container"
|
|
20
|
+
:style="{ minWidth: targetWidth ? targetWidth + 'px' : null }"
|
|
12
21
|
>
|
|
13
22
|
<div v-if="!hideArrow" class="popover-arrow" ref="popover-arrow"></div>
|
|
14
|
-
<slot
|
|
23
|
+
<slot
|
|
24
|
+
name="content"
|
|
25
|
+
v-bind="{ togglePopover, updatePosition, open, close }"
|
|
26
|
+
></slot>
|
|
15
27
|
</div>
|
|
16
28
|
</teleport>
|
|
17
29
|
</div>
|
|
@@ -25,9 +37,9 @@ export default {
|
|
|
25
37
|
props: {
|
|
26
38
|
hideArrow: {
|
|
27
39
|
type: Boolean,
|
|
28
|
-
default:
|
|
40
|
+
default: true,
|
|
29
41
|
},
|
|
30
|
-
|
|
42
|
+
show: {
|
|
31
43
|
default: null,
|
|
32
44
|
},
|
|
33
45
|
right: Boolean,
|
|
@@ -39,18 +51,28 @@ export default {
|
|
|
39
51
|
},
|
|
40
52
|
emits: ['init', 'open', 'close'],
|
|
41
53
|
watch: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
show: {
|
|
55
|
+
immediate: true,
|
|
56
|
+
handler(val) {
|
|
57
|
+
if (val) {
|
|
58
|
+
this.open()
|
|
59
|
+
} else {
|
|
60
|
+
this.close()
|
|
61
|
+
}
|
|
62
|
+
},
|
|
49
63
|
},
|
|
50
64
|
},
|
|
51
65
|
data() {
|
|
52
66
|
return {
|
|
53
67
|
isOpen: false,
|
|
68
|
+
targetWidth: null,
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
created() {
|
|
72
|
+
if (!document.getElementById('frappeui-popper-root')) {
|
|
73
|
+
const root = document.createElement('div')
|
|
74
|
+
root.id = 'frappeui-popper-root'
|
|
75
|
+
document.body.appendChild(root)
|
|
54
76
|
}
|
|
55
77
|
},
|
|
56
78
|
mounted() {
|
|
@@ -67,6 +89,9 @@ export default {
|
|
|
67
89
|
if (this.show == null) {
|
|
68
90
|
document.addEventListener('click', this.listener)
|
|
69
91
|
}
|
|
92
|
+
this.$nextTick(() => {
|
|
93
|
+
this.targetWidth = this.$refs['target'].clientWidth
|
|
94
|
+
})
|
|
70
95
|
},
|
|
71
96
|
beforeDestroy() {
|
|
72
97
|
this.popper && this.popper.destroy()
|
|
@@ -95,10 +120,13 @@ export default {
|
|
|
95
120
|
: [],
|
|
96
121
|
})
|
|
97
122
|
} else {
|
|
98
|
-
this.
|
|
123
|
+
this.updatePosition()
|
|
99
124
|
}
|
|
100
125
|
this.$emit('init')
|
|
101
126
|
},
|
|
127
|
+
updatePosition() {
|
|
128
|
+
this.popper && this.popper.update()
|
|
129
|
+
},
|
|
102
130
|
togglePopover(flag) {
|
|
103
131
|
if (flag == null) {
|
|
104
132
|
flag = !this.isOpen
|
|
@@ -115,9 +143,7 @@ export default {
|
|
|
115
143
|
return
|
|
116
144
|
}
|
|
117
145
|
this.isOpen = true
|
|
118
|
-
this.$nextTick(() =>
|
|
119
|
-
this.setupPopper()
|
|
120
|
-
})
|
|
146
|
+
this.$nextTick(() => this.setupPopper())
|
|
121
147
|
this.$emit('open')
|
|
122
148
|
},
|
|
123
149
|
close() {
|
package/src/utils/resources.js
CHANGED
|
@@ -41,7 +41,7 @@ export function createResource(options, vm, getResource) {
|
|
|
41
41
|
setData,
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
async function fetch(params) {
|
|
44
|
+
async function fetch(params, tempOptions = {}) {
|
|
45
45
|
if (params instanceof Event) {
|
|
46
46
|
params = null
|
|
47
47
|
}
|
|
@@ -57,18 +57,22 @@ export function createResource(options, vm, getResource) {
|
|
|
57
57
|
options.onFetch.call(vm, out.params)
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
let validateFunction = tempOptions.validate || options.validate
|
|
61
|
+
let errorFunction = tempOptions.onError || options.onError
|
|
62
|
+
let successFunction = tempOptions.onSuccess || options.onSuccess
|
|
63
|
+
|
|
64
|
+
if (validateFunction) {
|
|
61
65
|
let invalidMessage
|
|
62
66
|
try {
|
|
63
|
-
invalidMessage = await
|
|
67
|
+
invalidMessage = await validateFunction.call(vm, out.params)
|
|
64
68
|
if (invalidMessage && typeof invalidMessage == 'string') {
|
|
65
69
|
let error = new Error(invalidMessage)
|
|
66
|
-
handleError(error)
|
|
70
|
+
handleError(error, errorFunction)
|
|
67
71
|
out.loading = false
|
|
68
72
|
return
|
|
69
73
|
}
|
|
70
74
|
} catch (error) {
|
|
71
|
-
handleError(error)
|
|
75
|
+
handleError(error, errorFunction)
|
|
72
76
|
out.loading = false
|
|
73
77
|
return
|
|
74
78
|
}
|
|
@@ -78,11 +82,11 @@ export function createResource(options, vm, getResource) {
|
|
|
78
82
|
let data = await resourceFetcher(options.method, params || options.params)
|
|
79
83
|
out.data = data
|
|
80
84
|
out.fetched = true
|
|
81
|
-
if (
|
|
82
|
-
|
|
85
|
+
if (successFunction) {
|
|
86
|
+
successFunction.call(vm, data)
|
|
83
87
|
}
|
|
84
88
|
} catch (error) {
|
|
85
|
-
handleError(error)
|
|
89
|
+
handleError(error, errorFunction)
|
|
86
90
|
}
|
|
87
91
|
out.loading = false
|
|
88
92
|
}
|
|
@@ -109,14 +113,14 @@ export function createResource(options, vm, getResource) {
|
|
|
109
113
|
out.auto = options.auto
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
function handleError(error) {
|
|
116
|
+
function handleError(error, errorFunction) {
|
|
113
117
|
console.error(error)
|
|
114
118
|
if (out.previousData) {
|
|
115
119
|
out.data = out.previousData
|
|
116
120
|
}
|
|
117
121
|
out.error = error
|
|
118
|
-
if (
|
|
119
|
-
|
|
122
|
+
if (errorFunction) {
|
|
123
|
+
errorFunction.call(vm, error)
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
|
|
@@ -138,6 +142,8 @@ export function createResource(options, vm, getResource) {
|
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
export function createDocumentResource(options, vm) {
|
|
145
|
+
if (!(options.doctype && options.name)) return
|
|
146
|
+
|
|
141
147
|
let cacheKey = getCacheKey([options.doctype, options.name])
|
|
142
148
|
if (documentCache[cacheKey]) {
|
|
143
149
|
return documentCache[cacheKey]
|
|
@@ -153,7 +159,7 @@ export function createDocumentResource(options, vm) {
|
|
|
153
159
|
}
|
|
154
160
|
},
|
|
155
161
|
onSuccess(data) {
|
|
156
|
-
out.doc = data
|
|
162
|
+
out.doc = postprocess(data)
|
|
157
163
|
},
|
|
158
164
|
}
|
|
159
165
|
|
|
@@ -170,7 +176,7 @@ export function createDocumentResource(options, vm) {
|
|
|
170
176
|
}
|
|
171
177
|
},
|
|
172
178
|
onSuccess(data) {
|
|
173
|
-
out.doc = data
|
|
179
|
+
out.doc = postprocess(data)
|
|
174
180
|
},
|
|
175
181
|
}),
|
|
176
182
|
setValue: createResource(setValueOptions),
|
|
@@ -193,12 +199,47 @@ export function createDocumentResource(options, vm) {
|
|
|
193
199
|
update,
|
|
194
200
|
})
|
|
195
201
|
|
|
202
|
+
for (let method in options.whitelistedMethods) {
|
|
203
|
+
let methodName = options.whitelistedMethods[method]
|
|
204
|
+
out[method] = createResource({
|
|
205
|
+
method: 'run_doc_method',
|
|
206
|
+
makeParams(values) {
|
|
207
|
+
return {
|
|
208
|
+
dt: out.doctype,
|
|
209
|
+
dn: out.name,
|
|
210
|
+
method: methodName,
|
|
211
|
+
args: JSON.stringify(values),
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
onSuccess(data) {
|
|
215
|
+
if (data.docs) {
|
|
216
|
+
for (let doc of data.docs) {
|
|
217
|
+
if (doc.doctype === out.doctype && doc.name === out.name) {
|
|
218
|
+
out.doc = postprocess(doc)
|
|
219
|
+
break
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
196
227
|
function update(updatedOptions) {
|
|
197
228
|
out.doctype = updatedOptions.doctype
|
|
198
229
|
out.name = updatedOptions.name
|
|
199
230
|
out.get.fetch()
|
|
200
231
|
}
|
|
201
232
|
|
|
233
|
+
function postprocess(doc) {
|
|
234
|
+
if (options.postprocess) {
|
|
235
|
+
let returnValue = options.postprocess(doc)
|
|
236
|
+
if (typeof returnValue === 'object') {
|
|
237
|
+
return returnValue
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return doc
|
|
241
|
+
}
|
|
242
|
+
|
|
202
243
|
// fetch the doc
|
|
203
244
|
out.get.fetch()
|
|
204
245
|
// cache
|
|
@@ -248,7 +289,7 @@ let createMixin = (mixinOptions) => ({
|
|
|
248
289
|
} else {
|
|
249
290
|
resource.update(updatedOptions)
|
|
250
291
|
}
|
|
251
|
-
if (resource.auto) {
|
|
292
|
+
if (resource && resource.auto) {
|
|
252
293
|
resource.fetch()
|
|
253
294
|
}
|
|
254
295
|
},
|