frappe-ui 0.0.25 → 0.0.28
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/Input.vue +19 -10
- package/src/components/Popover.vue +19 -6
- package/src/index.js +1 -0
- package/src/utils/pageMeta.js +47 -0
- package/src/utils/resources.js +45 -4
package/package.json
CHANGED
package/src/components/Input.vue
CHANGED
|
@@ -30,12 +30,13 @@
|
|
|
30
30
|
<textarea
|
|
31
31
|
v-if="type === 'textarea'"
|
|
32
32
|
v-bind="inputAttributes"
|
|
33
|
+
:placeholder="placeholder"
|
|
34
|
+
class="placeholder-gray-500"
|
|
33
35
|
:class="['block w-full resize-none form-textarea', inputClass]"
|
|
34
36
|
ref="input"
|
|
35
37
|
:value="passedInputValue"
|
|
36
38
|
:disabled="disabled"
|
|
37
39
|
:rows="rows || 3"
|
|
38
|
-
@blur="$emit('blur', $event)"
|
|
39
40
|
></textarea>
|
|
40
41
|
<select
|
|
41
42
|
v-bind="inputAttributes"
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
v-for="option in selectOptions"
|
|
49
50
|
:key="option.value"
|
|
50
51
|
:value="option.value"
|
|
52
|
+
:disabled="option.disabled || false"
|
|
51
53
|
:selected="passedInputValue === option.value"
|
|
52
54
|
>
|
|
53
55
|
{{ option.label }}
|
|
@@ -114,7 +116,7 @@ export default {
|
|
|
114
116
|
type: String,
|
|
115
117
|
},
|
|
116
118
|
},
|
|
117
|
-
emits: ['
|
|
119
|
+
emits: ['input', 'change', 'update:modelValue'],
|
|
118
120
|
methods: {
|
|
119
121
|
focus() {
|
|
120
122
|
this.$refs.input.focus()
|
|
@@ -158,16 +160,23 @@ export default {
|
|
|
158
160
|
})
|
|
159
161
|
},
|
|
160
162
|
selectOptions() {
|
|
161
|
-
return this.options
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
return this.options
|
|
164
|
+
.map((option) => {
|
|
165
|
+
if (typeof option === 'string') {
|
|
166
|
+
return {
|
|
167
|
+
label: option,
|
|
168
|
+
value: option,
|
|
169
|
+
}
|
|
166
170
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
171
|
+
return option
|
|
172
|
+
})
|
|
173
|
+
.filter(Boolean)
|
|
170
174
|
},
|
|
171
175
|
},
|
|
172
176
|
}
|
|
173
177
|
</script>
|
|
178
|
+
<style>
|
|
179
|
+
.form-select {
|
|
180
|
+
background-image: url("data:image/svg+xml;utf8,<svg fill='none' width='8' xmlns='http://www.w3.org/2000/svg' viewBox='-4 -2 16 16'><path d='M4.5 3.636 6.136 2l1.637 1.636M4.5 8.364 6.136 10l1.637-1.636' stroke='%23333C44' stroke-linecap='round' stroke-linejoin='round'/></svg>");
|
|
181
|
+
}
|
|
182
|
+
</style>
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
>
|
|
10
10
|
<slot
|
|
11
11
|
name="target"
|
|
12
|
-
v-bind="{ togglePopover, updatePosition, open, close }"
|
|
12
|
+
v-bind="{ togglePopover, updatePosition, open, close, isOpen }"
|
|
13
13
|
></slot>
|
|
14
14
|
</div>
|
|
15
15
|
<teleport to="#frappeui-popper-root">
|
|
@@ -18,12 +18,21 @@
|
|
|
18
18
|
:class="popoverClass"
|
|
19
19
|
class="relative z-[100] popover-container"
|
|
20
20
|
:style="{ minWidth: targetWidth ? targetWidth + 'px' : null }"
|
|
21
|
+
v-show="isOpen"
|
|
21
22
|
>
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
<transition v-bind="transition">
|
|
24
|
+
<div v-show="isOpen">
|
|
25
|
+
<div
|
|
26
|
+
v-if="!hideArrow"
|
|
27
|
+
class="popover-arrow"
|
|
28
|
+
ref="popover-arrow"
|
|
29
|
+
></div>
|
|
30
|
+
<slot
|
|
31
|
+
name="content"
|
|
32
|
+
v-bind="{ togglePopover, updatePosition, open, close, isOpen }"
|
|
33
|
+
></slot>
|
|
34
|
+
</div>
|
|
35
|
+
</transition>
|
|
27
36
|
</div>
|
|
28
37
|
</teleport>
|
|
29
38
|
</div>
|
|
@@ -48,6 +57,10 @@ export default {
|
|
|
48
57
|
default: 'bottom-start',
|
|
49
58
|
},
|
|
50
59
|
popoverClass: [String, Object, Array],
|
|
60
|
+
transition: {
|
|
61
|
+
type: Object,
|
|
62
|
+
default: null,
|
|
63
|
+
},
|
|
51
64
|
},
|
|
52
65
|
emits: ['init', 'open', 'close'],
|
|
53
66
|
watch: {
|
package/src/index.js
CHANGED
|
@@ -29,6 +29,7 @@ export { default as onOutsideClickDirective } from './directives/onOutsideClick.
|
|
|
29
29
|
export { default as call, createCall } from './utils/call.js'
|
|
30
30
|
export { default as debounce } from './utils/debounce.js'
|
|
31
31
|
export { createResource } from './utils/resources.js'
|
|
32
|
+
export { default as pageMeta } from './utils/pageMeta.js'
|
|
32
33
|
|
|
33
34
|
// plugin
|
|
34
35
|
export { default as FrappeUI } from './utils/plugin.js'
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { watch } from 'vue'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
install(app) {
|
|
5
|
+
app.mixin(createMixin())
|
|
6
|
+
},
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function createMixin() {
|
|
10
|
+
let faviconRef = document.querySelector('link[rel="icon"]')
|
|
11
|
+
let defaultFavIcon = faviconRef.href
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
created() {
|
|
15
|
+
if (this.$options.pageMeta) {
|
|
16
|
+
watch(
|
|
17
|
+
() => {
|
|
18
|
+
try {
|
|
19
|
+
return this.$options.pageMeta.call(this)
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.warn('Failed to parse pageMeta\n\n', error)
|
|
22
|
+
return null
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
(pageMeta) => {
|
|
26
|
+
if (!pageMeta) return
|
|
27
|
+
if (pageMeta.title) {
|
|
28
|
+
document.title = pageMeta.title
|
|
29
|
+
}
|
|
30
|
+
if (pageMeta.emoji) {
|
|
31
|
+
let href = `data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>${pageMeta.emoji}</text></svg>`
|
|
32
|
+
faviconRef.href = href
|
|
33
|
+
} else if (pageMeta.icon) {
|
|
34
|
+
faviconRef.href = pageMeta.icon
|
|
35
|
+
} else {
|
|
36
|
+
faviconRef.href = defaultFavIcon
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
immediate: true,
|
|
41
|
+
deep: true,
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/utils/resources.js
CHANGED
|
@@ -196,6 +196,7 @@ export function createDocumentResource(options, vm) {
|
|
|
196
196
|
onSuccess(data) {
|
|
197
197
|
out.doc = transform(data)
|
|
198
198
|
},
|
|
199
|
+
onError: options.onError,
|
|
199
200
|
},
|
|
200
201
|
vm
|
|
201
202
|
),
|
|
@@ -287,8 +288,10 @@ function createListResource(options, vm, getResource) {
|
|
|
287
288
|
if (!options.doctype) return
|
|
288
289
|
|
|
289
290
|
let cacheKey = getCacheKey(options.cache)
|
|
290
|
-
if (
|
|
291
|
-
|
|
291
|
+
if (cacheKey) {
|
|
292
|
+
if (listCache[cacheKey]) {
|
|
293
|
+
return listCache[cacheKey]
|
|
294
|
+
}
|
|
292
295
|
}
|
|
293
296
|
|
|
294
297
|
let out = reactive({
|
|
@@ -298,6 +301,7 @@ function createListResource(options, vm, getResource) {
|
|
|
298
301
|
order_by: options.order_by,
|
|
299
302
|
start: options.start,
|
|
300
303
|
limit: options.limit,
|
|
304
|
+
originalData: null,
|
|
301
305
|
data: null,
|
|
302
306
|
list: createResource(
|
|
303
307
|
{
|
|
@@ -313,6 +317,7 @@ function createListResource(options, vm, getResource) {
|
|
|
313
317
|
}
|
|
314
318
|
},
|
|
315
319
|
onSuccess(data) {
|
|
320
|
+
out.originalData = data
|
|
316
321
|
out.data = transform(data)
|
|
317
322
|
options.onSuccess?.call(vm, out.data)
|
|
318
323
|
},
|
|
@@ -320,6 +325,37 @@ function createListResource(options, vm, getResource) {
|
|
|
320
325
|
},
|
|
321
326
|
vm
|
|
322
327
|
),
|
|
328
|
+
fetchOne: createResource(
|
|
329
|
+
{
|
|
330
|
+
method: 'frappe.client.get_list',
|
|
331
|
+
makeParams(name) {
|
|
332
|
+
return {
|
|
333
|
+
doctype: out.doctype,
|
|
334
|
+
fields: out.fields,
|
|
335
|
+
filters: { name },
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
onSuccess(data) {
|
|
339
|
+
if (data.length > 0 && out.originalData) {
|
|
340
|
+
let doc = data[0]
|
|
341
|
+
let index = out.originalData.findIndex((d) => d.name === doc.name)
|
|
342
|
+
out.originalData = out.originalData.filter(
|
|
343
|
+
(d) => d.name !== doc.name
|
|
344
|
+
)
|
|
345
|
+
out.originalData = [
|
|
346
|
+
out.originalData.slice(0, index),
|
|
347
|
+
data,
|
|
348
|
+
out.originalData.slice(index),
|
|
349
|
+
].flat()
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
out.data = transform(out.originalData)
|
|
353
|
+
options.fetchOne?.onSuccess?.call(vm, out.data)
|
|
354
|
+
},
|
|
355
|
+
onError: options.fetchOne?.onError,
|
|
356
|
+
},
|
|
357
|
+
vm
|
|
358
|
+
),
|
|
323
359
|
insert: createResource(
|
|
324
360
|
{
|
|
325
361
|
method: 'frappe.client.insert',
|
|
@@ -414,8 +450,10 @@ function createListResource(options, vm, getResource) {
|
|
|
414
450
|
// fetch list
|
|
415
451
|
out.list.fetch()
|
|
416
452
|
|
|
417
|
-
|
|
418
|
-
|
|
453
|
+
if (cacheKey) {
|
|
454
|
+
// cache
|
|
455
|
+
listCache[cacheKey] = out
|
|
456
|
+
}
|
|
419
457
|
|
|
420
458
|
return out
|
|
421
459
|
}
|
|
@@ -431,6 +469,9 @@ function createResourceForOptions(options, vm, getResource) {
|
|
|
431
469
|
}
|
|
432
470
|
|
|
433
471
|
function getCacheKey(cacheKey) {
|
|
472
|
+
if (!cacheKey) {
|
|
473
|
+
return null
|
|
474
|
+
}
|
|
434
475
|
if (typeof cacheKey === 'string') {
|
|
435
476
|
cacheKey = [cacheKey]
|
|
436
477
|
}
|