@live-change/vue3-components 0.8.50 → 0.8.51
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/logic/data.js +10 -5
- package/logic/synchronized.js +12 -7
- package/package.json +3 -3
- package/view/RangeViewer.vue +8 -1
package/logic/data.js
CHANGED
|
@@ -18,7 +18,8 @@ export function defaultData(definition, otherSrc) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export function validateData(definition, data, validationType = 'validation',
|
|
21
|
-
context = undefined, propName = '', props = data
|
|
21
|
+
context = undefined, propName = '', props = data,
|
|
22
|
+
outputValidatorParams = false) {
|
|
22
23
|
context = context || getCurrentInstance().appContext
|
|
23
24
|
//console.log("VALIDATIE DATA", definition, data, validationType, context, propName, props)
|
|
24
25
|
if(!context) throw new Error("No context")
|
|
@@ -34,7 +35,11 @@ export function validateData(definition, data, validationType = 'validation',
|
|
|
34
35
|
: validators[validation.name](validation.params, validationContext)
|
|
35
36
|
if(!validator) throw new Error(`Validator ${validation.name || validation} not found`)
|
|
36
37
|
const error = validator(data, context)
|
|
37
|
-
if(error)
|
|
38
|
+
if(error) {
|
|
39
|
+
if(outputValidatorParams) {
|
|
40
|
+
return { error, validator: validation.params }
|
|
41
|
+
} else return error
|
|
42
|
+
}
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
45
|
if(!data) return undefined // No data, no errors, nonEmpty validator was already checked
|
|
@@ -42,7 +47,7 @@ export function validateData(definition, data, validationType = 'validation',
|
|
|
42
47
|
const propertyErrors = {}
|
|
43
48
|
for(let name in definition.properties) {
|
|
44
49
|
const error = validateData(definition.properties[name], data?.[name], validationType, context,
|
|
45
|
-
propName ? propName + '.' + name: name, props)
|
|
50
|
+
propName ? propName + '.' + name: name, props, outputValidatorParams)
|
|
46
51
|
if(error) {
|
|
47
52
|
if(error.propertyErrors) {
|
|
48
53
|
for(let internalName in error.propertyErrors) {
|
|
@@ -54,11 +59,11 @@ export function validateData(definition, data, validationType = 'validation',
|
|
|
54
59
|
}
|
|
55
60
|
}
|
|
56
61
|
if(Object.keys(propertyErrors).length > 0) return { propertyErrors }
|
|
57
|
-
} else if(definition.type
|
|
62
|
+
} else if(definition.type === 'Array') {
|
|
58
63
|
const propertyErrors = {}
|
|
59
64
|
for(let i = 0; i < data.length; i++) {
|
|
60
65
|
const error = validateData(definition.of, data[i], validationType, context,
|
|
61
|
-
propName ? propName + '.' + i : i, props)
|
|
66
|
+
propName ? propName + '.' + i : i, props, outputValidatorParams)
|
|
62
67
|
const name = '' + i
|
|
63
68
|
if(error) {
|
|
64
69
|
if(error.propertyErrors) {
|
package/logic/synchronized.js
CHANGED
|
@@ -36,16 +36,20 @@ function synchronized(options) {
|
|
|
36
36
|
|
|
37
37
|
let lastSavedUpdate = lastLocalUpdate.value
|
|
38
38
|
|
|
39
|
-
const changed = computed(() => (JSON.stringify(source.value)
|
|
39
|
+
const changed = computed(() => (JSON.stringify(source.value) !== synchronizedJSON.value)
|
|
40
40
|
&& (lastLocalUpdate.value > ((source.value && source.value[timeField]) ?? '')))
|
|
41
|
+
|
|
42
|
+
const saving = ref(false)
|
|
43
|
+
|
|
41
44
|
async function save() {
|
|
42
|
-
if((JSON.stringify(source.value)
|
|
45
|
+
if((JSON.stringify(source.value) === JSON.stringify(synchronizedValue.value))
|
|
43
46
|
|| (lastLocalUpdate.value <= ((source.value && source.value[timeField]) ?? ''))) {
|
|
44
47
|
return false // identical, no need to save
|
|
45
48
|
}
|
|
46
|
-
if(lastSavedUpdate
|
|
49
|
+
if(lastSavedUpdate === lastLocalUpdate.value) {
|
|
47
50
|
return false // duplicated save action
|
|
48
51
|
}
|
|
52
|
+
saving.value = true
|
|
49
53
|
lastSavedUpdate = lastLocalUpdate.value
|
|
50
54
|
const data = JSON.parse(synchronizedJSON.value)
|
|
51
55
|
// console.log("LAST LOCAL UPDATE", lastLocalUpdate.value)
|
|
@@ -60,10 +64,11 @@ function synchronized(options) {
|
|
|
60
64
|
console.error("SAVE ERROR", e)
|
|
61
65
|
onSaveError(e)
|
|
62
66
|
}
|
|
67
|
+
saving.value = false
|
|
63
68
|
return true
|
|
64
69
|
}
|
|
65
70
|
const throttledSave = debounce ? () => {} : (throttle ? useThrottleFn(save, throttle) : save)
|
|
66
|
-
const debouncedSave = debounce ? useDebounceFn(save,
|
|
71
|
+
const debouncedSave = debounce ? useDebounceFn(save, debounce)
|
|
67
72
|
: (throttle ? useDebounceFn(save, throttle) : () => {}) // debounce after throttle
|
|
68
73
|
watch(() => synchronizedJSON.value, json => {
|
|
69
74
|
lastLocalUpdate.value = timeSource()
|
|
@@ -89,11 +94,11 @@ function synchronized(options) {
|
|
|
89
94
|
return { value: synchronizedValue, save, changed }
|
|
90
95
|
} else {
|
|
91
96
|
const local = ref(source.value)
|
|
92
|
-
const changed = computed(() => (JSON.stringify(source.value)
|
|
97
|
+
const changed = computed(() => (JSON.stringify(source.value) !== JSON.stringify(local.value))
|
|
93
98
|
&& ( ((local.value && local.value[timeField]) ?? '')
|
|
94
99
|
> ((source.value && source.value[timeField]) ?? '')))
|
|
95
100
|
async function save() {
|
|
96
|
-
if((JSON.stringify(source.value)
|
|
101
|
+
if((JSON.stringify(source.value) === JSON.stringify(local.value))
|
|
97
102
|
|| ( ((local.value && local.value[timeField]) ?? '')
|
|
98
103
|
<= ((source.value && source.value[timeField]) ?? ''))) return false // identical, no need to save
|
|
99
104
|
const data = JSON.parse(JSON.stringify(local.value))
|
|
@@ -125,7 +130,7 @@ function synchronized(options) {
|
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
})
|
|
128
|
-
return { value: synchronizedComputed, save, changed }
|
|
133
|
+
return { value: synchronizedComputed, save, changed, saving }
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/vue3-components",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.51",
|
|
4
4
|
"description": "Live Change Framework - vue components",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
},
|
|
22
22
|
"homepage": "https://github.com/live-change/live-change-stack",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@live-change/vue3-ssr": "^0.8.
|
|
24
|
+
"@live-change/vue3-ssr": "^0.8.51",
|
|
25
25
|
"debug": "^4.3.4",
|
|
26
26
|
"mitt": "3.0.1",
|
|
27
27
|
"vue": "^3.4.29"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "ba8da813894eeb717223aa8d5e364649e4ac0347"
|
|
30
30
|
}
|
package/view/RangeViewer.vue
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
<slot v-if="frozen && buckets?.changed" name="changedTop"></slot>
|
|
19
19
|
|
|
20
|
+
<slot v-if="itemsCount === 0" name="empty"></slot>
|
|
21
|
+
|
|
20
22
|
<template v-for="(bucket, bucketIndex) in buckets.buckets" :key="bucket.id">
|
|
21
23
|
|
|
22
24
|
<slot v-for="(item, itemIndex) in bucket.data" v-bind="{ item, bucket, itemIndex, bucketIndex }">
|
|
@@ -48,7 +50,7 @@
|
|
|
48
50
|
<script setup>
|
|
49
51
|
|
|
50
52
|
import ScrollBorder from 'vue3-scroll-border'
|
|
51
|
-
import { ref, toRefs, defineProps, defineEmits, watch } from 'vue'
|
|
53
|
+
import { ref, toRefs, defineProps, defineEmits, watch, computed } from 'vue'
|
|
52
54
|
import { rangeBuckets } from '@live-change/vue3-ssr'
|
|
53
55
|
|
|
54
56
|
const props = defineProps({
|
|
@@ -154,6 +156,11 @@
|
|
|
154
156
|
|
|
155
157
|
const buckets = ref()
|
|
156
158
|
|
|
159
|
+
const itemsCount = computed(() => {
|
|
160
|
+
if(!buckets.value) return 0
|
|
161
|
+
return buckets.value.buckets.reduce((acc, b) => acc + b.data.length, 0)
|
|
162
|
+
})
|
|
163
|
+
|
|
157
164
|
if(props.buckets) {
|
|
158
165
|
buckets.value = props.buckets
|
|
159
166
|
} else if(props.pathFunction) {
|