@innertia-solutions/nuxt-theme-spark 0.1.78 → 0.1.80

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.
@@ -48,6 +48,9 @@ const previewRow = ref(null)
48
48
  const currentRatio = ref(props.splitRatio)
49
49
  const containerRef = ref(null)
50
50
  const previewEnabled = ref(false)
51
+ const paginationHeight = ref(0)
52
+
53
+ const previewCacheKey = computed(() => `table-preview-${props.name}`)
51
54
 
52
55
  const closePreview = () => { previewRow.value = null }
53
56
 
@@ -59,6 +62,35 @@ const handleRowClick = (row) => {
59
62
  }
60
63
  }
61
64
 
65
+ // Persist preview row in session cache when table cache is enabled
66
+ watch(previewRow, (row) => {
67
+ if (!props.cached) return
68
+ if (row) sessionStorage.setItem(previewCacheKey.value, JSON.stringify(row))
69
+ else sessionStorage.removeItem(previewCacheKey.value)
70
+ })
71
+
72
+ // When data reloads, update previewRow with fresh data from response
73
+ const handleLoaded = (res) => {
74
+ emit('loaded', res)
75
+ if (previewRow.value && Array.isArray(res?.data)) {
76
+ const fresh = res.data.find(r => r.id === previewRow.value.id)
77
+ if (fresh) previewRow.value = fresh
78
+ }
79
+ }
80
+
81
+ // Track pagination bar height so the overlay never covers it
82
+ let paginationObserver = null
83
+ watch(() => tableRef.value?.paginationBarRef, (el) => {
84
+ paginationObserver?.disconnect()
85
+ paginationObserver = null
86
+ if (!el) return
87
+ paginationHeight.value = el.offsetHeight
88
+ paginationObserver = new ResizeObserver(() => {
89
+ paginationHeight.value = el.offsetHeight
90
+ })
91
+ paginationObserver.observe(el)
92
+ }, { flush: 'post' })
93
+
62
94
  const startResize = (e) => {
63
95
  e.preventDefault()
64
96
  const onMove = (ev) => {
@@ -79,8 +111,18 @@ const onEsc = (e) => { if (e.key === 'Escape' && previewRow.value) closePreview(
79
111
  onMounted(() => {
80
112
  previewEnabled.value = !!slots.preview
81
113
  window.addEventListener('keydown', onEsc)
114
+ // Restore preview from session cache
115
+ if (props.cached && previewEnabled.value) {
116
+ try {
117
+ const raw = sessionStorage.getItem(previewCacheKey.value)
118
+ if (raw) previewRow.value = JSON.parse(raw)
119
+ } catch {}
120
+ }
121
+ })
122
+ onBeforeUnmount(() => {
123
+ window.removeEventListener('keydown', onEsc)
124
+ paginationObserver?.disconnect()
82
125
  })
83
- onBeforeUnmount(() => window.removeEventListener('keydown', onEsc))
84
126
 
85
127
  // ─── Column panel ─────────────────────────────────────────────────────────────
86
128
  const showColumnPanel = ref(false)
@@ -209,7 +251,7 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
209
251
  </div>
210
252
 
211
253
  <!-- Contenido: tabla siempre full width + preview overlay -->
212
- <div class="relative">
254
+ <div class="relative overflow-hidden">
213
255
 
214
256
  <!-- Tabla -->
215
257
  <Table
@@ -226,7 +268,9 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
226
268
  :preview-row-id="previewRow?.id ?? null"
227
269
  :preview-mode="!!previewEnabled"
228
270
  @row-click="handleRowClick"
229
- @loaded="emit('loaded', $event)"
271
+ @loaded="handleLoaded"
272
+ @page-change="closePreview"
273
+ @per-page-change="closePreview"
230
274
  >
231
275
  <template v-for="(_, name) in $slots" #[name]="slotProps">
232
276
  <slot :name="name" v-bind="slotProps ?? {}" />
@@ -244,8 +288,8 @@ defineExpose({ getSelectedRows, reload, clearCache, exportTable, tableRef })
244
288
  >
245
289
  <div
246
290
  v-if="previewRow && previewEnabled"
247
- class="absolute inset-y-0 right-0 z-10 flex bg-white dark:bg-slate-800 border-l border-slate-200 dark:border-slate-700 shadow-xl"
248
- :style="{ width: (100 - currentRatio) + '%' }"
291
+ class="absolute top-0 right-0 z-30 flex bg-white dark:bg-slate-800 border-l border-slate-200 dark:border-slate-700 shadow-[-4px_0_16px_rgba(0,0,0,0.06)]"
292
+ :style="{ width: (100 - currentRatio) + '%', bottom: paginationHeight + 'px' }"
249
293
  >
250
294
  <!-- Resize handle -->
251
295
  <div
@@ -24,7 +24,7 @@ const props = defineProps({
24
24
  previewMode: { type: Boolean, default: false },
25
25
  })
26
26
 
27
- const emit = defineEmits(['update:search', 'row-click', 'loaded'])
27
+ const emit = defineEmits(['update:search', 'row-click', 'loaded', 'page-change', 'per-page-change'])
28
28
  const instance = getCurrentInstance()
29
29
 
30
30
  // ─── API / toast ─────────────────────────────────────────────────────────────
@@ -39,6 +39,7 @@ const isDataFromCache = ref(false)
39
39
  const lastDataLength = ref(-1)
40
40
  const lastRowHeight = ref(48)
41
41
  const tableBodyRef = ref(null)
42
+ const paginationBarRef = ref(null)
42
43
  const skeletonRows = computed(() => {
43
44
  const count = lastDataLength.value < 0 ? pagination.value.pageSize : lastDataLength.value
44
45
  return Array.from({ length: count })
@@ -261,6 +262,13 @@ watch(tableData, (newData) => {
261
262
  }, { flush: 'post' })
262
263
 
263
264
  watch(pagination, () => { if (!isRestoring.value) scheduleFetch(0) }, { deep: true })
265
+
266
+ watch(() => pagination.value.pageIndex, (val, old) => {
267
+ if (!isRestoring.value && val !== old) emit('page-change', val)
268
+ })
269
+ watch(() => pagination.value.pageSize, (val, old) => {
270
+ if (!isRestoring.value && val !== old) emit('per-page-change', val)
271
+ })
264
272
  watch(sorting, () => { if (!isRestoring.value) scheduleFetch(0) }, { deep: true })
265
273
  watch(columnFilters, () => { if (!isRestoring.value) scheduleFetch(300) }, { deep: true })
266
274
 
@@ -463,6 +471,7 @@ defineExpose({
463
471
  setColumnOrder,
464
472
  isDataFromCache,
465
473
  cached: computed(() => props.cached),
474
+ paginationBarRef,
466
475
  })
467
476
  </script>
468
477
 
@@ -757,7 +766,7 @@ defineExpose({
757
766
  </div>
758
767
 
759
768
  <!-- Pagination & controls bar -->
760
- <div class="flex flex-col sm:flex-row items-center justify-between gap-y-4 sm:gap-y-0 px-4 py-3 border-t border-slate-200 dark:border-slate-700">
769
+ <div ref="paginationBarRef" class="flex flex-col sm:flex-row items-center justify-between gap-y-4 sm:gap-y-0 px-4 py-3 border-t border-slate-200 dark:border-slate-700">
761
770
  <!-- Left: reload, total, cache, columns button -->
762
771
  <div class="flex items-center gap-x-4 flex-wrap gap-y-2">
763
772
  <!-- Reload button -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innertia-solutions/nuxt-theme-spark",
3
- "version": "0.1.78",
3
+ "version": "0.1.80",
4
4
  "description": "Innertia Solutions — Spark theme: backoffice, landing and mobile components and layouts",
5
5
  "keywords": [
6
6
  "nuxt",