@contember/bindx-repeater 0.1.49 → 0.1.50

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.
@@ -1,6 +1,9 @@
1
- import type { EntityAccessor, HasManyAccessor, AnyBrand } from '@contember/bindx';
1
+ import { type AnyBrand, type EntityAccessor, type HasManyAccessor } from '@contember/bindx';
2
2
  /**
3
- * Hook that returns sorted items from a has-many ref and repairs order field values.
3
+ * Hook that returns sorted items from a has-many ref.
4
+ *
5
+ * Rendering never writes: an item that joins the list gets its order value from the
6
+ * connect event instead, so sparse values on existing rows are left as they are.
4
7
  *
5
8
  * @param hasMany - The has-many ref
6
9
  * @param orderField - Optional field name for sorting
@@ -1 +1 @@
1
- {"version":3,"file":"useSortedItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useSortedItems.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAIjF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAC5D,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CAiBtD"}
1
+ {"version":3,"file":"useSortedItems.d.ts","sourceRoot":"","sources":["../../src/hooks/useSortedItems.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,MAAM,kBAAkB,CAAA;AAIzB;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,CAAC,SAAS,MAAM,EAChB,CAAC,GAAG,CAAC,EACL,MAAM,SAAS,QAAQ,GAAG,QAAQ,EAClC,WAAW,SAAS,MAAM,GAAG,MAAM,EACnC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAE/D,OAAO,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAC5D,UAAU,EAAE,MAAM,GAAG,SAAS,GAC5B,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,CA4CtD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/bindx-repeater",
3
- "version": "0.1.49",
3
+ "version": "0.1.50",
4
4
  "description": "Repeater components for has-many list management",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -15,8 +15,8 @@
15
15
  "react": ">=18.0.0"
16
16
  },
17
17
  "dependencies": {
18
- "@contember/bindx": "0.1.49",
19
- "@contember/bindx-react": "0.1.49"
18
+ "@contember/bindx": "0.1.50",
19
+ "@contember/bindx-react": "0.1.50"
20
20
  },
21
21
  "files": [
22
22
  "dist",
@@ -1,10 +1,19 @@
1
- import { useEffect, useMemo } from 'react'
2
- import type { EntityAccessor, HasManyAccessor, AnyBrand } from '@contember/bindx'
1
+ import { useCallback, useMemo } from 'react'
2
+ import {
3
+ FIELD_REF_META,
4
+ type AnyBrand,
5
+ type EntityAccessor,
6
+ type HasManyAccessor,
7
+ type HasManyConnectedEvent,
8
+ } from '@contember/bindx'
9
+ import { useOnFieldEvent, useSnapshotStore } from '@contember/bindx-react'
3
10
  import { sortEntities } from '../utils/sortEntities.js'
4
- import { repairEntitiesOrder } from '../utils/repairEntitiesOrder.js'
5
11
 
6
12
  /**
7
- * Hook that returns sorted items from a has-many ref and repairs order field values.
13
+ * Hook that returns sorted items from a has-many ref.
14
+ *
15
+ * Rendering never writes: an item that joins the list gets its order value from the
16
+ * connect event instead, so sparse values on existing rows are left as they are.
8
17
  *
9
18
  * @param hasMany - The has-many ref
10
19
  * @param orderField - Optional field name for sorting
@@ -20,6 +29,7 @@ export function useSortedItems<
20
29
  hasMany: HasManyAccessor<T, S, TBrand, TEntityName, TSchema>,
21
30
  orderField: string | undefined,
22
31
  ): EntityAccessor<T, S, TBrand, TEntityName, TSchema>[] {
32
+ const store = useSnapshotStore()
23
33
  const rawItems = hasMany?.items
24
34
  const items = Array.isArray(rawItems) ? rawItems : []
25
35
 
@@ -28,12 +38,38 @@ export function useSortedItems<
28
38
  [items, orderField],
29
39
  )
30
40
 
31
- useEffect(() => {
32
- if (!orderField) {
33
- return
41
+ const meta = hasMany?.[FIELD_REF_META]
42
+ const itemType = meta?.targetType
43
+
44
+ const assignOrderToNewItem = useCallback((event: HasManyConnectedEvent): void => {
45
+ if (orderField === undefined || itemType === undefined) return
46
+
47
+ const added = store.getEntitySnapshot<Record<string, unknown>>(itemType, event.itemId)
48
+ // An item already carrying an order keeps it — this only fills the gap.
49
+ if (added === undefined) return
50
+ const currentOrder = added.data[orderField]
51
+ if (currentOrder !== undefined && currentOrder !== null) return
52
+
53
+ // Read through the accessor so the live list is used, not the render snapshot:
54
+ // several items added in one tick must not all land on the same order.
55
+ let maxOrder = -1
56
+ for (const item of hasMany.items) {
57
+ const value = store.getEntitySnapshot<Record<string, unknown>>(itemType, item.id)?.data[orderField]
58
+ if (typeof value === 'number' && value > maxOrder) {
59
+ maxOrder = value
60
+ }
34
61
  }
35
- repairEntitiesOrder(sortedItems, orderField)
36
- }, [orderField, sortedItems])
62
+
63
+ store.setFieldValue(itemType, event.itemId, [orderField], maxOrder + 1)
64
+ }, [store, hasMany, orderField, itemType])
65
+
66
+ useOnFieldEvent(
67
+ 'hasMany:connected',
68
+ meta?.entityType ?? '',
69
+ meta?.entityId ?? '',
70
+ meta?.fieldName ?? '',
71
+ assignOrderToNewItem,
72
+ )
37
73
 
38
74
  return sortedItems
39
75
  }