@live-change/vue3-components 0.8.49 → 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.
@@ -683,8 +683,11 @@
683
683
  unmounted() {
684
684
  },
685
685
  watch: {
686
- rootValue(newValue) {
687
- this.$emit('update', newValue)
686
+ data: {
687
+ deep: true,
688
+ handler(newValue) {
689
+ this.$emit('update', newValue)
690
+ }
688
691
  }
689
692
  }
690
693
  }
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) return 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 == 'Array') {
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) {
@@ -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) != synchronizedJSON.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) == JSON.stringify(synchronizedValue.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 == lastLocalUpdate.value) {
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, throttle)
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) != JSON.stringify(local.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) == JSON.stringify(local.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.49",
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.49",
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": "568f730f1c8a6ce0247d1d8e49fcea110604800c"
29
+ "gitHead": "ba8da813894eeb717223aa8d5e364649e4ac0347"
30
30
  }
@@ -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) {