@innertia-solutions/innertia-nuxt 0.1.31 → 0.1.33

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.
@@ -23,10 +23,14 @@ const props = defineProps({
23
23
 
24
24
  // Column visibility — map { [colKey]: boolean }. Si null, todas visibles.
25
25
  columnVisibility: { type: Object, default: null },
26
+
27
+ // Resalta la fila cuyo id coincide (selección externa via @row-click).
28
+ selectedId: { type: [String, Number], default: null },
26
29
  })
27
30
 
28
31
  const emit = defineEmits(['toggle', 'row-click', 'check'])
29
32
 
33
+ const isSelected = computed(() => props.selectedId != null && props.node.id === props.selectedId)
30
34
  const isExpanded = computed(() => props.expanded.has(props.node.id))
31
35
  const isLoading = computed(() => props.loadingSet.has(props.node.id))
32
36
  const hasChildren = computed(() => !!props.node.has_children)
@@ -79,7 +83,7 @@ const indentPx = computed(() => props.depth * 20)
79
83
  class="bg-card hover:bg-layer-hover transition-colors"
80
84
  :class="[
81
85
  clickableRows ? 'cursor-pointer' : '',
82
- isChecked ? 'bg-primary/5' : '',
86
+ isSelected ? 'bg-primary/10 hover:bg-primary/10' : (isChecked ? 'bg-primary/5' : ''),
83
87
  ]"
84
88
  @click="onRowClick"
85
89
  >
@@ -154,6 +158,7 @@ const indentPx = computed(() => props.depth * 20)
154
158
  :checked-set="checkedSet"
155
159
  :indeterminate-set="indeterminateSet"
156
160
  :column-visibility="columnVisibility"
161
+ :selected-id="selectedId"
157
162
  @toggle="(n) => emit('toggle', n)"
158
163
  @row-click="(n) => emit('row-click', n)"
159
164
  @check="(n) => emit('check', n)"
@@ -171,7 +176,7 @@ const indentPx = computed(() => props.depth * 20)
171
176
  class="group flex items-center gap-1.5 px-2 py-1 rounded-control hover:bg-muted-hover transition-colors"
172
177
  :class="[
173
178
  clickableRows ? 'cursor-pointer' : '',
174
- isChecked ? 'bg-primary/5' : '',
179
+ isSelected ? 'bg-primary/10 hover:bg-primary/10' : (isChecked ? 'bg-primary/5' : ''),
175
180
  ]"
176
181
  :style="{ paddingLeft: (indentPx + 8) + 'px' }"
177
182
  @click="onRowClick"
@@ -245,6 +250,7 @@ const indentPx = computed(() => props.depth * 20)
245
250
  :checked-set="checkedSet"
246
251
  :indeterminate-set="indeterminateSet"
247
252
  :column-visibility="columnVisibility"
253
+ :selected-id="selectedId"
248
254
  @toggle="(n) => emit('toggle', n)"
249
255
  @row-click="(n) => emit('row-click', n)"
250
256
  @check="(n) => emit('check', n)"
@@ -75,6 +75,9 @@ const props = defineProps({
75
75
  autoClosePreview: { type: Boolean, default: true },
76
76
  /** Porcentaje inicial de la tabla (0-100). El resto lo ocupa el preview. */
77
77
  splitRatio: { type: Number, default: 55 },
78
+
79
+ // Resalta la fila seleccionada (id del nodo). Para selección externa via @row-click.
80
+ selectedId: { type: [String, Number], default: null },
78
81
  })
79
82
 
80
83
  const sizeStyle = computed(() => {
@@ -211,6 +214,41 @@ const fetchInitial = async () => {
211
214
  }
212
215
  }
213
216
 
217
+ /**
218
+ * Refresca el árbol PRESERVANDO la expansión actual: re-fetchea los roots y los
219
+ * hijos de cada nodo expandido (datos frescos, sin colapsar ni resetear scroll).
220
+ * Útil tras mutar un nodo (ej. marcar revisado) sin remontar el componente.
221
+ */
222
+ const reload = async () => {
223
+ loading.value = true
224
+ isFetching.value = true
225
+ isDataFromCache.value = false
226
+ try {
227
+ const res = await api.post(props.endpoint, buildBody())
228
+ roots.value = res?.data ?? []
229
+ meta.value = res?.meta ?? null
230
+
231
+ const expanded = [...expandedSet.value]
232
+ const fresh = {}
233
+ await Promise.all(expanded.map(async (nodeId) => {
234
+ try {
235
+ const r = await api.post(props.endpoint, buildBody({ expand: nodeId }))
236
+ fresh[nodeId] = r?.data ?? []
237
+ } catch {
238
+ fresh[nodeId] = childrenById.value[nodeId] ?? []
239
+ }
240
+ }))
241
+ childrenById.value = fresh
242
+ if (props.cached) saveToCache()
243
+ emit('loaded', res)
244
+ } catch (e) {
245
+ console.error('[Tree.Standard] reload failed:', e)
246
+ } finally {
247
+ loading.value = false
248
+ isFetching.value = false
249
+ }
250
+ }
251
+
214
252
  // ─── Cache ────────────────────────────────────────────────────────────────────
215
253
  const cacheKey = computed(() => {
216
254
  if (!props.cached || !props.name) return null
@@ -527,6 +565,7 @@ onBeforeUnmount(() => {
527
565
 
528
566
  defineExpose({
529
567
  refresh: fetchInitial,
568
+ reload, // refresca preservando expansión (sin colapsar)
530
569
  clearChecked,
531
570
  getChecked: () => [...checkedSet.value],
532
571
  })
@@ -825,6 +864,7 @@ defineExpose({
825
864
  :checked-set="checkedSet"
826
865
  :indeterminate-set="indeterminateSet"
827
866
  :column-visibility="columnVisibility"
867
+ :selected-id="selectedId"
828
868
  @toggle="toggle"
829
869
  @check="toggleCheck"
830
870
  @row-click="handleRowClick"
@@ -868,6 +908,7 @@ defineExpose({
868
908
  :checked-set="checkedSet"
869
909
  :indeterminate-set="indeterminateSet"
870
910
  :column-visibility="columnVisibility"
911
+ :selected-id="selectedId"
871
912
  @toggle="toggle"
872
913
  @check="toggleCheck"
873
914
  @row-click="handleRowClick"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@innertia-solutions/innertia-nuxt",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Innertia Solutions — Nuxt layer unificada: core, auth, multitenancy, theme y app contexts",
5
5
  "keywords": [
6
6
  "nuxt",