@anzusystems/common-admin 2.0.0-rc.5 → 2.0.0-rc.7

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.
Files changed (690) hide show
  1. package/README.md +4 -0
  2. package/dist/AnzuSystemsCommonAdmin.d.ts +42 -32
  3. package/dist/AnzuSystemsCommonAdmin.js.map +1 -1
  4. package/dist/common-admin.css +1 -1
  5. package/dist/common-admin.js +282 -282
  6. package/dist/domains/anzuUser/api/anzuUserApi.d.ts +9 -12
  7. package/dist/domains/anzuUser/api/anzuUserApi.js.map +1 -1
  8. package/dist/domains/anzuUser/components/AAnzuUserDatatable.js.map +1 -1
  9. package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue.d.ts +38 -44
  10. package/dist/domains/anzuUser/components/AAnzuUserDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  11. package/dist/domains/anzuUser/components/AAnzuUserFilter.js.map +1 -1
  12. package/dist/domains/anzuUser/components/AAnzuUserFilter.vue.d.ts +12 -13
  13. package/dist/domains/anzuUser/components/AAnzuUserFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  14. package/dist/domains/anzuUser/components/AAnzuUserForm.js.map +1 -1
  15. package/dist/domains/anzuUser/components/AAnzuUserForm.vue.d.ts +18 -20
  16. package/dist/domains/anzuUser/components/AAnzuUserForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  17. package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.js.map +1 -1
  18. package/dist/domains/anzuUser/components/AAnzuUserRoleAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/domains/anzuUser/components/AUserBulkActionDialog.js.map +1 -1
  20. package/dist/domains/anzuUser/components/AUserBulkActionDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.js.map +1 -1
  22. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue.d.ts +2 -3
  23. package/dist/domains/anzuUser/components/AUserCopyPermissionsDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  24. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.js.map +1 -1
  25. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue.d.ts +9 -15
  26. package/dist/domains/anzuUser/components/AUserCreateInSystemButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  27. package/dist/domains/anzuUser/components/AUserEnabledSwitch.js.map +1 -1
  28. package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue.d.ts +8 -7
  29. package/dist/domains/anzuUser/components/AUserEnabledSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  30. package/dist/domains/anzuUser/components/AUserManageButton.js.map +1 -1
  31. package/dist/domains/anzuUser/components/AUserManageButton.vue.d.ts +0 -1
  32. package/dist/domains/anzuUser/components/AUserManageButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  33. package/dist/domains/anzuUser/components/AUserMetadataForm.js.map +1 -1
  34. package/dist/domains/anzuUser/components/AUserMetadataForm.vue.d.ts +8 -9
  35. package/dist/domains/anzuUser/components/AUserMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  36. package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.js.map +1 -1
  37. package/dist/domains/anzuUser/components/AUserMetadataRepairDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  38. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.js.map +1 -1
  39. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue.d.ts +1 -2
  40. package/dist/domains/anzuUser/components/AUserOtherSystemsTable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  41. package/dist/domains/anzuUser/components/AUserSystemOverview.js.map +1 -1
  42. package/dist/domains/anzuUser/components/AUserSystemOverview.vue_vue_type_script_setup_true_lang.js.map +1 -1
  43. package/dist/domains/anzuUser/components/AUserSystemPanel.js.map +1 -1
  44. package/dist/domains/anzuUser/components/AUserSystemPanel.vue.d.ts +2 -2
  45. package/dist/domains/anzuUser/components/AUserSystemPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  46. package/dist/domains/anzuUser/components/AUserSystemStatusChip.js.map +1 -1
  47. package/dist/domains/anzuUser/components/AUserSystemStatusChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  48. package/dist/domains/anzuUser/components/AUserTabsShell.js.map +1 -1
  49. package/dist/domains/anzuUser/components/AUserTabsShell.vue.d.ts +17 -22
  50. package/dist/domains/anzuUser/components/AUserTabsShell.vue_vue_type_script_setup_true_lang.js.map +1 -1
  51. package/dist/domains/anzuUser/composables/anzuUserActions.d.ts +5 -9
  52. package/dist/domains/anzuUser/composables/anzuUserActions.js.map +1 -1
  53. package/dist/domains/anzuUser/composables/anzuUserValidations.d.ts +4 -6
  54. package/dist/domains/anzuUser/composables/anzuUserValidations.js.map +1 -1
  55. package/dist/domains/anzuUser/composables/cachedAnzuUsers.d.ts +3 -3
  56. package/dist/domains/anzuUser/composables/cachedAnzuUsers.js.map +1 -1
  57. package/dist/domains/anzuUser/composables/userCrossSystemSearch.d.ts +2 -4
  58. package/dist/domains/anzuUser/composables/userCrossSystemSearch.js.map +1 -1
  59. package/dist/domains/anzuUser/composables/userCrossSystemWrites.d.ts +5 -11
  60. package/dist/domains/anzuUser/composables/userCrossSystemWrites.js.map +1 -1
  61. package/dist/domains/anzuUser/composables/userSystemDescriptor.d.ts +33 -57
  62. package/dist/domains/anzuUser/composables/userSystemDescriptor.js.map +1 -1
  63. package/dist/domains/anzuUser/composables/userSystemProbe.d.ts +7 -27
  64. package/dist/domains/anzuUser/composables/userSystemProbe.js.map +1 -1
  65. package/dist/domains/anzuUser/filter/anzuUserFilter.d.ts +6 -16
  66. package/dist/domains/anzuUser/filter/anzuUserFilter.js.map +1 -1
  67. package/dist/domains/anzuUser/store/anzuUserStore.d.ts +1 -5
  68. package/dist/domains/anzuUser/store/anzuUserStore.js.map +1 -1
  69. package/dist/domains/anzuUser/store/userCrossSystemStore.d.ts +3 -14
  70. package/dist/domains/anzuUser/store/userCrossSystemStore.js.map +1 -1
  71. package/dist/domains/anzuUser/utils/userMetadataDiff.d.ts +7 -19
  72. package/dist/domains/anzuUser/utils/userMetadataDiff.js.map +1 -1
  73. package/dist/domains/anzuUser/utils/userSystemState.d.ts +12 -30
  74. package/dist/domains/anzuUser/utils/userSystemState.js.map +1 -1
  75. package/dist/domains/anzuUser/utils/userTabs.d.ts +1 -3
  76. package/dist/domains/anzuUser/utils/userTabs.js.map +1 -1
  77. package/dist/domains/api/composables/defineApiClient.d.ts +4 -8
  78. package/dist/domains/api/composables/defineApiClient.js.map +1 -1
  79. package/dist/domains/api/composables/request.d.ts +18 -48
  80. package/dist/domains/api/composables/request.js.map +1 -1
  81. package/dist/domains/api/composables/useApiFetchByIds.d.ts +7 -21
  82. package/dist/domains/api/composables/useApiFetchByIds.js.map +1 -1
  83. package/dist/domains/api/composables/useApiFetchItems.d.ts +18 -57
  84. package/dist/domains/api/composables/useApiFetchItems.js.map +1 -1
  85. package/dist/domains/api/composables/useApiFetchList.d.ts +7 -23
  86. package/dist/domains/api/composables/useApiFetchList.js.map +1 -1
  87. package/dist/domains/api/composables/useApiFetchListBatch.d.ts +5 -22
  88. package/dist/domains/api/composables/useApiFetchListBatch.js.map +1 -1
  89. package/dist/domains/api/composables/useApiQueryBuilder.js.map +1 -1
  90. package/dist/domains/api/composables/useApiRequest.d.ts +16 -39
  91. package/dist/domains/api/composables/useApiRequest.js.map +1 -1
  92. package/dist/domains/api/utils/apiErrors.d.ts +28 -55
  93. package/dist/domains/api/utils/apiErrors.js.map +1 -1
  94. package/dist/domains/api/utils/listBody.d.ts +22 -43
  95. package/dist/domains/api/utils/listBody.js.map +1 -1
  96. package/dist/domains/auth/components/Acl.js.map +1 -1
  97. package/dist/domains/auth/components/Acl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  98. package/dist/domains/auth/composables/aclAllowed.d.ts +2 -3
  99. package/dist/domains/auth/composables/aclAllowed.js.map +1 -1
  100. package/dist/domains/auth/composables/defineAuth.js.map +1 -1
  101. package/dist/domains/auth/composables/refreshSession.d.ts +10 -13
  102. package/dist/domains/auth/composables/refreshSession.js.map +1 -1
  103. package/dist/domains/cached/components/ACachedChip.js.map +1 -1
  104. package/dist/domains/cached/components/ACachedChip.vue.d.ts +13 -11
  105. package/dist/domains/cached/components/ACachedChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  106. package/dist/domains/cached/components/ACachedUserChip.js +1 -1
  107. package/dist/domains/cached/components/ACachedUserChip.js.map +1 -1
  108. package/dist/domains/cached/components/ACachedUserChip.vue.d.ts +3 -3
  109. package/dist/domains/cached/components/ACachedUserChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  110. package/dist/domains/cached/composables/createUserAndTimeTrackingFields.d.ts +9 -9
  111. package/dist/domains/cached/composables/createUserAndTimeTrackingFields.js.map +1 -1
  112. package/dist/domains/cached/composables/defineCached.d.ts +13 -11
  113. package/dist/domains/cached/composables/defineCached.js.map +1 -1
  114. package/dist/domains/cached/composables/useCachedItem.d.ts +7 -8
  115. package/dist/domains/cached/composables/useCachedItem.js.map +1 -1
  116. package/dist/domains/collab/components/ACollabLockedByUser.js.map +1 -1
  117. package/dist/domains/collab/components/ACollabLockedByUser.vue_vue_type_script_setup_true_lang.js.map +1 -1
  118. package/dist/domains/collab/composables/collabAnyDataChange.js.map +1 -1
  119. package/dist/domains/collab/composables/collabField.d.ts +5 -3
  120. package/dist/domains/collab/composables/collabField.js.map +1 -1
  121. package/dist/domains/collab/composables/collabInit.js +58 -54
  122. package/dist/domains/collab/composables/collabInit.js.map +1 -1
  123. package/dist/domains/collab/composables/collabRecovery.d.ts +49 -0
  124. package/dist/domains/collab/composables/collabRecovery.js +99 -0
  125. package/dist/domains/collab/composables/collabRecovery.js.map +1 -0
  126. package/dist/domains/collab/composables/collabRoom.js +106 -106
  127. package/dist/domains/collab/composables/collabRoom.js.map +1 -1
  128. package/dist/domains/collab/composables/collabState.d.ts +11 -4
  129. package/dist/domains/collab/composables/collabState.js +34 -25
  130. package/dist/domains/collab/composables/collabState.js.map +1 -1
  131. package/dist/domains/collab/composables/commonAdminCollabOptions.d.ts +4 -2
  132. package/dist/domains/collab/types/Collab.d.ts +31 -5
  133. package/dist/domains/collab/types/Collab.js +23 -11
  134. package/dist/domains/collab/types/Collab.js.map +1 -1
  135. package/dist/domains/customDataForm/components/ACustomDataForm.js.map +1 -1
  136. package/dist/domains/customDataForm/components/ACustomDataForm.vue.d.ts +7 -5
  137. package/dist/domains/customDataForm/components/ACustomDataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  138. package/dist/domains/customDataForm/components/ACustomDataFormElement.js.map +1 -1
  139. package/dist/domains/customDataForm/components/ACustomDataFormElement.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.js.map +1 -1
  141. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue.d.ts +5 -3
  142. package/dist/domains/customDataForm/components/ACustomDataFormHiddenPart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  143. package/dist/domains/customDataForm/composables/useCustomDataForm.js.map +1 -1
  144. package/dist/domains/customDataForm/types/CustomDataForm.d.ts +4 -1
  145. package/dist/domains/dam/api/damAssetApi.d.ts +7 -7
  146. package/dist/domains/dam/api/damAssetApi.js.map +1 -1
  147. package/dist/domains/dam/api/damAssetLicenceApi.d.ts +1 -1
  148. package/dist/domains/dam/api/damAssetLicenceApi.js.map +1 -1
  149. package/dist/domains/dam/api/damConstants.js.map +1 -1
  150. package/dist/domains/dam/api/damEndPoints.js.map +1 -1
  151. package/dist/domains/dam/api/damImageApi.js.map +1 -1
  152. package/dist/domains/dam/api/uploadApi.js.map +1 -1
  153. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.js.map +1 -1
  154. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue.d.ts +7 -5
  155. package/dist/domains/dam/assetDetail/components/AssetCustomMetadataForm.vue_vue_type_script_setup_true_lang.js.map +1 -1
  156. package/dist/domains/dam/assetDetail/components/AssetDetailDialog.js.map +1 -1
  157. package/dist/domains/dam/assetDetail/components/AssetDetailDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  158. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.js.map +1 -1
  159. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue.d.ts +1 -1
  160. package/dist/domains/dam/assetDetail/components/AssetDetailDialogFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  161. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarActionsWrapper.vue.d.ts +5 -3
  162. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.js.map +1 -1
  163. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarFrame.vue_vue_type_script_setup_true_lang.js.map +1 -1
  164. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.js.map +1 -1
  165. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  166. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.js.map +1 -1
  167. package/dist/domains/dam/assetDetail/components/AssetDetailSidebarROI.vue_vue_type_script_setup_true_lang.js.map +1 -1
  168. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.js.map +1 -1
  169. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue.d.ts +1 -1
  170. package/dist/domains/dam/assetDetail/components/AssetFileInfoPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  171. package/dist/domains/dam/assetDetail/components/AssetImage.js.map +1 -1
  172. package/dist/domains/dam/assetDetail/components/AssetImage.vue.d.ts +1 -1
  173. package/dist/domains/dam/assetDetail/components/AssetImage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  174. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.js.map +1 -1
  175. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue.d.ts +2 -2
  176. package/dist/domains/dam/assetDetail/components/AssetImageMetaIcons.vue_vue_type_script_setup_true_lang.js.map +1 -1
  177. package/dist/domains/dam/assetDetail/components/AssetInfobox.js.map +1 -1
  178. package/dist/domains/dam/assetDetail/components/AssetInfobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/domains/dam/assetDetail/components/AssetMetadata.js.map +1 -1
  180. package/dist/domains/dam/assetDetail/components/AssetMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  181. package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.d.ts +5 -6
  182. package/dist/domains/dam/assetDetail/composables/assetDetailExtSystem.js.map +1 -1
  183. package/dist/domains/dam/assetDetail/composables/assetDetailView.d.ts +10 -10
  184. package/dist/domains/dam/assetDetail/composables/assetDetailView.js.map +1 -1
  185. package/dist/domains/dam/assetDetail/store/assetDetailStore.js.map +1 -1
  186. package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.d.ts +4 -3
  187. package/dist/domains/dam/assetDetail/utils/assetMetadataMayStillChange.js.map +1 -1
  188. package/dist/domains/dam/assetSelect/api/damPodcastApi.js.map +1 -1
  189. package/dist/domains/dam/assetSelect/components/AAssetListInner.js.map +1 -1
  190. package/dist/domains/dam/assetSelect/components/AAssetListInner.vue.d.ts +789 -787
  191. package/dist/domains/dam/assetSelect/components/AAssetListInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  192. package/dist/domains/dam/assetSelect/components/AAssetSelect.js.map +1 -1
  193. package/dist/domains/dam/assetSelect/components/AAssetSelect.vue.d.ts +395 -393
  194. package/dist/domains/dam/assetSelect/components/AAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  195. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.js.map +1 -1
  196. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue.d.ts +14 -12
  197. package/dist/domains/dam/assetSelect/components/AAssetSelectMedia.vue_vue_type_script_setup_true_lang.js.map +1 -1
  198. package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.js.map +1 -1
  199. package/dist/domains/dam/assetSelect/components/AssetDistributionServiceNameFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  200. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.js.map +1 -1
  201. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue.d.ts +9 -7
  202. package/dist/domains/dam/assetSelect/components/AssetSelectListBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  203. package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.js.map +1 -1
  204. package/dist/domains/dam/assetSelect/components/AssetSelectTableRowItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  205. package/dist/domains/dam/assetSelect/composables/assetSelectListActions.js.map +1 -1
  206. package/dist/domains/dam/assetSelect/store/assetSelectStore.js.map +1 -1
  207. package/dist/domains/dam/author/api/authorApi.js.map +1 -1
  208. package/dist/domains/dam/author/components/AuthorCreateButton.js.map +1 -1
  209. package/dist/domains/dam/author/components/AuthorCreateButton.vue.d.ts +1 -1
  210. package/dist/domains/dam/author/components/AuthorCreateButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  211. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.js.map +1 -1
  212. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue.d.ts +9 -6
  213. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  214. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.js.map +1 -1
  215. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteCachedAuthorChipConflicts.vue_vue_type_script_setup_true_lang.js.map +1 -1
  216. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js +1 -1
  217. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.js.map +1 -1
  218. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue.d.ts +2 -2
  219. package/dist/domains/dam/author/components/AuthorRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
  220. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.js.map +1 -1
  221. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue.d.ts +1 -1
  222. package/dist/domains/dam/author/components/DamAuthorFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/domains/dam/author/composables/cachedAuthors.d.ts +5 -4
  224. package/dist/domains/dam/author/composables/cachedAuthors.js.map +1 -1
  225. package/dist/domains/dam/author/composables/cachedUsers.d.ts +5 -4
  226. package/dist/domains/dam/author/composables/cachedUsers.js.map +1 -1
  227. package/dist/domains/dam/author/composables/damAuthorConfig.d.ts +2 -2
  228. package/dist/domains/dam/author/composables/damAuthorConfig.js.map +1 -1
  229. package/dist/domains/dam/components/DamAdminAssetLink.js.map +1 -1
  230. package/dist/domains/dam/components/DamAdminAssetLink.vue_vue_type_script_setup_true_lang.js.map +1 -1
  231. package/dist/domains/dam/composables/commonAdminCoreDamOptions.d.ts +10 -8
  232. package/dist/domains/dam/composables/commonAdminCoreDamOptions.js.map +1 -1
  233. package/dist/domains/dam/composables/damConfigName.d.ts +8 -9
  234. package/dist/domains/dam/composables/damConfigName.js.map +1 -1
  235. package/dist/domains/dam/composables/damNotifications.d.ts +9 -9
  236. package/dist/domains/dam/composables/damNotifications.js.map +1 -1
  237. package/dist/domains/dam/composables/damNotificationsConnection.d.ts +4 -4
  238. package/dist/domains/dam/composables/damNotificationsConnection.js.map +1 -1
  239. package/dist/domains/dam/composables/damNotificationsEventBus.d.ts +2 -2
  240. package/dist/domains/dam/composables/damNotificationsEventBus.js.map +1 -1
  241. package/dist/domains/dam/composables/extSystemIdForCached.d.ts +5 -4
  242. package/dist/domains/dam/composables/extSystemIdForCached.js.map +1 -1
  243. package/dist/domains/dam/config/api/damAssetCustomFormApi.js.map +1 -1
  244. package/dist/domains/dam/config/api/damConfigApi.js.map +1 -1
  245. package/dist/domains/dam/config/composables/damConfigState.d.ts +5 -5
  246. package/dist/domains/dam/config/composables/damConfigState.js.map +1 -1
  247. package/dist/domains/dam/config/store/damConfigStore.d.ts +5 -4
  248. package/dist/domains/dam/config/store/damConfigStore.js.map +1 -1
  249. package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.d.ts +3 -1
  250. package/dist/domains/dam/config/utils/damFilterUserAllowedUploadConfigs.js.map +1 -1
  251. package/dist/domains/dam/cropper/components/ACropper.js.map +1 -1
  252. package/dist/domains/dam/cropper/components/ACropper.vue.d.ts +8 -16
  253. package/dist/domains/dam/cropper/components/ACropper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  254. package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.js.map +1 -1
  255. package/dist/domains/dam/cropper/components/DamAssetImageRoiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  256. package/dist/domains/dam/cropper/store/imageRoiStore.d.ts +9 -12
  257. package/dist/domains/dam/cropper/store/imageRoiStore.js.map +1 -1
  258. package/dist/domains/dam/cropper/utils/cropperGeometry.d.ts +24 -38
  259. package/dist/domains/dam/cropper/utils/cropperGeometry.js.map +1 -1
  260. package/dist/domains/dam/cropper/utils/cropperJsService.d.ts +3 -7
  261. package/dist/domains/dam/cropper/utils/cropperJsService.js +10 -3
  262. package/dist/domains/dam/cropper/utils/cropperJsService.js.map +1 -1
  263. package/dist/domains/dam/cropper/utils/cropperTypes.d.ts +3 -6
  264. package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.d.ts +5 -5
  265. package/dist/domains/dam/cropper/utils/damAssetImageRoiSelectLoader.js.map +1 -1
  266. package/dist/domains/dam/imageWidget/components/AImageMediaWidget.js.map +1 -1
  267. package/dist/domains/dam/imageWidget/components/AImageMediaWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
  268. package/dist/domains/dam/imageWidget/components/AImagePublicInput.js.map +1 -1
  269. package/dist/domains/dam/imageWidget/components/AImagePublicInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  270. package/dist/domains/dam/imageWidget/components/AImageWidget.js.map +1 -1
  271. package/dist/domains/dam/imageWidget/components/AImageWidget.vue_vue_type_script_setup_true_lang.js.map +1 -1
  272. package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.js.map +1 -1
  273. package/dist/domains/dam/imageWidget/components/AImageWidgetMultiple.vue_vue_type_script_setup_true_lang.js.map +1 -1
  274. package/dist/domains/dam/imageWidget/components/AImageWidgetSimple.vue.d.ts +43 -41
  275. package/dist/domains/dam/imageWidget/components/AMediaWidgetSimple.vue.d.ts +31 -29
  276. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.js.map +1 -1
  277. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue.d.ts +29 -27
  278. package/dist/domains/dam/imageWidget/components/ImageDetailDialogMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  279. package/dist/domains/dam/imageWidget/components/ImageMassOperations.js.map +1 -1
  280. package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue.d.ts +1 -1
  281. package/dist/domains/dam/imageWidget/components/ImageMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
  282. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.js.map +1 -1
  283. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue.d.ts +68 -66
  284. package/dist/domains/dam/imageWidget/components/ImageMediaWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  285. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.js.map +1 -1
  286. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue.d.ts +402 -400
  287. package/dist/domains/dam/imageWidget/components/ImageWidgetInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  288. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.js.map +1 -1
  289. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue.d.ts +384 -382
  290. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleInner.vue_vue_type_script_setup_true_lang.js.map +1 -1
  291. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.js.map +1 -1
  292. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  293. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.js.map +1 -1
  294. package/dist/domains/dam/imageWidget/components/ImageWidgetMultipleLimitDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  295. package/dist/domains/dam/imageWidget/components/MediaWidgetSimpleDialog.vue.d.ts +7 -5
  296. package/dist/domains/dam/imageWidget/composables/commonAdminImageOptions.js.map +1 -1
  297. package/dist/domains/dam/imageWidget/composables/imageApiCms.js.map +1 -1
  298. package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.d.ts +11 -13
  299. package/dist/domains/dam/imageWidget/composables/imageDialogDamAuthors.js.map +1 -1
  300. package/dist/domains/dam/imageWidget/composables/useImageMassOperations.js.map +1 -1
  301. package/dist/domains/dam/imageWidget/store/imageMediaWidgetStore.js.map +1 -1
  302. package/dist/domains/dam/imageWidget/store/imageStore.js.map +1 -1
  303. package/dist/domains/dam/imageWidget/utils/damImage.d.ts +5 -6
  304. package/dist/domains/dam/imageWidget/utils/damImage.js.map +1 -1
  305. package/dist/domains/dam/imageWidget/utils/fieldLockTurns.d.ts +1 -2
  306. package/dist/domains/dam/imageWidget/utils/fieldLockTurns.js.map +1 -1
  307. package/dist/domains/dam/imageWidget/utils/imageSaves.d.ts +10 -14
  308. package/dist/domains/dam/imageWidget/utils/imageSaves.js.map +1 -1
  309. package/dist/domains/dam/imageWidget/utils/metadataToImageMap.js.map +1 -1
  310. package/dist/domains/dam/imageWidget/utils/waitLimit.d.ts +4 -6
  311. package/dist/domains/dam/imageWidget/utils/waitLimit.js.map +1 -1
  312. package/dist/domains/dam/keyword/api/keywordApi.js.map +1 -1
  313. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.js.map +1 -1
  314. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue.d.ts +1 -1
  315. package/dist/domains/dam/keyword/components/DamKeywordFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  316. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.js.map +1 -1
  317. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue.d.ts +8 -5
  318. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteCachedKeywordChip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  319. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js +1 -1
  320. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.js.map +1 -1
  321. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue.d.ts +2 -2
  322. package/dist/domains/dam/keyword/components/KeywordRemoteAutocompleteWithCached.vue_vue_type_script_setup_true_lang.js.map +1 -1
  323. package/dist/domains/dam/keyword/composables/cachedKeywords.d.ts +5 -4
  324. package/dist/domains/dam/keyword/composables/cachedKeywords.js.map +1 -1
  325. package/dist/domains/dam/keyword/composables/damKeywordConfig.d.ts +2 -2
  326. package/dist/domains/dam/keyword/composables/damKeywordConfig.js.map +1 -1
  327. package/dist/domains/dam/types/Asset.d.ts +1 -1
  328. package/dist/domains/dam/types/Asset.js.map +1 -1
  329. package/dist/domains/dam/types/UploadQueue.d.ts +5 -4
  330. package/dist/domains/dam/types/UploadQueue.js.map +1 -1
  331. package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.js.map +1 -1
  332. package/dist/domains/dam/uploadQueue/components/AssetCustomMetadataFormMassOperations.vue_vue_type_script_setup_true_lang.js.map +1 -1
  333. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.js.map +1 -1
  334. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue.d.ts +2 -2
  335. package/dist/domains/dam/uploadQueue/components/AssetQueueSelectedSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  336. package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.js.map +1 -1
  337. package/dist/domains/dam/uploadQueue/components/UploadQueueDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  338. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.js.map +1 -1
  339. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingle.vue_vue_type_script_setup_true_lang.js.map +1 -1
  340. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.js.map +1 -1
  341. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue.d.ts +6 -4
  342. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  343. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.js.map +1 -1
  344. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue.d.ts +1 -1
  345. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadata.vue_vue_type_script_setup_true_lang.js.map +1 -1
  346. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.js.map +1 -1
  347. package/dist/domains/dam/uploadQueue/components/UploadQueueDialogSingleSidebarMetadataContent.vue_vue_type_script_setup_true_lang.js.map +1 -1
  348. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.js.map +1 -1
  349. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue.d.ts +6 -6
  350. package/dist/domains/dam/uploadQueue/components/UploadQueueEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  351. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.js.map +1 -1
  352. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue.d.ts +13 -13
  353. package/dist/domains/dam/uploadQueue/components/UploadQueueItemEditable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  354. package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.d.ts +13 -13
  355. package/dist/domains/dam/uploadQueue/components/uploadQueueBindings.js.map +1 -1
  356. package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.d.ts +2 -2
  357. package/dist/domains/dam/uploadQueue/composables/damUploadChunkSize.js.map +1 -1
  358. package/dist/domains/dam/uploadQueue/composables/uploadMeter.d.ts +12 -12
  359. package/dist/domains/dam/uploadQueue/composables/uploadMeter.js.map +1 -1
  360. package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.d.ts +5 -5
  361. package/dist/domains/dam/uploadQueue/composables/uploadQueueItemRefresh.js.map +1 -1
  362. package/dist/domains/dam/uploadQueue/composables/uploadService.d.ts +2 -3
  363. package/dist/domains/dam/uploadQueue/composables/uploadService.js.map +1 -1
  364. package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.d.ts +5 -4
  365. package/dist/domains/dam/uploadQueue/composables/useUploadQueueDialog.js.map +1 -1
  366. package/dist/domains/dam/uploadQueue/core/uploadQueueCore.d.ts +3 -2
  367. package/dist/domains/dam/uploadQueue/core/uploadQueueCore.js.map +1 -1
  368. package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.d.ts +8 -5
  369. package/dist/domains/dam/uploadQueue/core/uploadQueueCoreTypes.js.map +1 -1
  370. package/dist/domains/dam/uploadQueue/core/uploadQueueFill.d.ts +3 -3
  371. package/dist/domains/dam/uploadQueue/core/uploadQueueFill.js.map +1 -1
  372. package/dist/domains/dam/uploadQueue/presets/queuePresets.d.ts +8 -5
  373. package/dist/domains/dam/uploadQueue/presets/queuePresets.js.map +1 -1
  374. package/dist/domains/dam/uploadQueue/presets/uploadPresets.d.ts +15 -13
  375. package/dist/domains/dam/uploadQueue/presets/uploadPresets.js.map +1 -1
  376. package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.d.ts +7 -7
  377. package/dist/domains/dam/uploadQueue/settlement/uploadPollSchedule.js.map +1 -1
  378. package/dist/domains/dam/uploadQueue/settlement/uploadPoller.d.ts +4 -4
  379. package/dist/domains/dam/uploadQueue/settlement/uploadPoller.js.map +1 -1
  380. package/dist/domains/dam/uploadQueue/settlement/uploadSettle.d.ts +28 -30
  381. package/dist/domains/dam/uploadQueue/settlement/uploadSettle.js.map +1 -1
  382. package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.d.ts +2 -2
  383. package/dist/domains/dam/uploadQueue/settlement/uploadSettlement.js.map +1 -1
  384. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.d.ts +2 -2
  385. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementRuntime.js.map +1 -1
  386. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.d.ts +63 -73
  387. package/dist/domains/dam/uploadQueue/settlement/uploadSettlementTypes.js.map +1 -1
  388. package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.d.ts +8 -9
  389. package/dist/domains/dam/uploadQueue/store/uploadQueuesStore.js.map +1 -1
  390. package/dist/domains/dam/user/api/userApi.d.ts +2 -2
  391. package/dist/domains/dam/user/api/userApi.js.map +1 -1
  392. package/dist/domains/dam/user/components/DamDistributionServiceSelect.js.map +1 -1
  393. package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue.d.ts +1 -1
  394. package/dist/domains/dam/user/components/DamDistributionServiceSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  395. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.js.map +1 -1
  396. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue.d.ts +1 -1
  397. package/dist/domains/dam/user/components/DamExternalProviderAssetSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  398. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.js.map +1 -1
  399. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue.d.ts +1 -1
  400. package/dist/domains/dam/user/components/DamUserRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  401. package/dist/domains/dam/user/composables/damUserSelectActions.d.ts +1 -1
  402. package/dist/domains/dam/user/composables/damUserSelectActions.js.map +1 -1
  403. package/dist/domains/dam/user/types/DamDistributionServiceType.d.ts +2 -2
  404. package/dist/domains/dam/user/types/DamDistributionServiceType.js.map +1 -1
  405. package/dist/domains/dam/user/types/DamExternalProviderAssetType.d.ts +1 -1
  406. package/dist/domains/dam/user/types/DamExternalProviderAssetType.js.map +1 -1
  407. package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.js.map +1 -1
  408. package/dist/domains/filters/bookmarks/components/FilterBookmarkDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  409. package/dist/domains/filters/bookmarks/store/bookmarksStore.d.ts +3 -3
  410. package/dist/domains/filters/bookmarks/store/bookmarksStore.js.map +1 -1
  411. package/dist/domains/filters/components/AFilterDatetimePicker.js.map +1 -1
  412. package/dist/domains/filters/components/AFilterDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  413. package/dist/domains/filters/components/AFilterInteger.js.map +1 -1
  414. package/dist/domains/filters/components/AFilterInteger.vue_vue_type_script_setup_true_lang.js.map +1 -1
  415. package/dist/domains/filters/components/AFilterString.js.map +1 -1
  416. package/dist/domains/filters/components/AFilterString.vue_vue_type_script_setup_true_lang.js.map +1 -1
  417. package/dist/domains/filters/components/AFilterTimeInterval.js +1 -1
  418. package/dist/domains/filters/components/AFilterTimeInterval.js.map +1 -1
  419. package/dist/domains/filters/components/AFilterTimeInterval.vue.d.ts +5 -3
  420. package/dist/domains/filters/components/AFilterTimeInterval.vue_vue_type_script_setup_true_lang.js.map +1 -1
  421. package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.js.map +1 -1
  422. package/dist/domains/filters/components/AFilterValueObjectOptionsSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  423. package/dist/domains/filters/components/AFilterWrapper.js.map +1 -1
  424. package/dist/domains/filters/components/AFilterWrapper.vue.d.ts +17 -15
  425. package/dist/domains/filters/components/AFilterWrapper.vue_vue_type_script_setup_true_lang.js +63 -62
  426. package/dist/domains/filters/components/AFilterWrapper.vue_vue_type_script_setup_true_lang.js.map +1 -1
  427. package/dist/domains/filters/components/AFilterWrapperSidebar.vue.d.ts +5 -3
  428. package/dist/domains/filters/components/FiltersSelected.js.map +1 -1
  429. package/dist/domains/filters/components/FiltersSelected.vue_vue_type_script_setup_true_lang.js.map +1 -1
  430. package/dist/domains/filters/composables/filterFactory.d.ts +16 -26
  431. package/dist/domains/filters/composables/filterFactory.js +38 -31
  432. package/dist/domains/filters/composables/filterFactory.js.map +1 -1
  433. package/dist/domains/filters/datatable/components/ADatatableOrdering.js.map +1 -1
  434. package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js +3 -1
  435. package/dist/domains/filters/datatable/components/ADatatableOrdering.vue_vue_type_script_setup_true_lang.js.map +1 -1
  436. package/dist/domains/filters/datatable/components/ADatatablePagination.js.map +1 -1
  437. package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js +2 -4
  438. package/dist/domains/filters/datatable/components/ADatatablePagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  439. package/dist/domains/filters/utils/filterInjectionKeys.js.map +1 -1
  440. package/dist/domains/form/components/AFormDatetimePicker.js.map +1 -1
  441. package/dist/domains/form/components/AFormDatetimePicker.vue.d.ts +7 -5
  442. package/dist/domains/form/components/AFormDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  443. package/dist/domains/form/components/AFormFlagDatetimePicker.js.map +1 -1
  444. package/dist/domains/form/components/AFormFlagDatetimePicker.vue.d.ts +7 -5
  445. package/dist/domains/form/components/AFormFlagDatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  446. package/dist/domains/form/components/AFormSwitch.vue.d.ts +7 -5
  447. package/dist/domains/form/components/AFormTextField.js.map +1 -1
  448. package/dist/domains/form/components/AFormTextField.vue.d.ts +9 -7
  449. package/dist/domains/form/components/AFormTextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  450. package/dist/domains/form/components/AFormTextarea.vue.d.ts +13 -11
  451. package/dist/domains/form/components/AFormValueObjectOptionsSelect.vue.d.ts +7 -5
  452. package/dist/domains/form/components/ASystemEntityScope.vue.d.ts +5 -3
  453. package/dist/domains/job/api/jobApi.js.map +1 -1
  454. package/dist/domains/job/components/AJobDetailCommon.vue.d.ts +5 -3
  455. package/dist/domains/listEditor/components/AListEditor.js.map +1 -1
  456. package/dist/domains/listEditor/components/AListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  457. package/dist/domains/listEditor/components/ANestedSortableListEditor.js.map +1 -1
  458. package/dist/domains/listEditor/components/ANestedSortableListEditor.vue.d.ts +2 -3
  459. package/dist/domains/listEditor/components/ANestedSortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  460. package/dist/domains/listEditor/components/ASortableListEditor.js.map +1 -1
  461. package/dist/domains/listEditor/components/ASortableListEditor.vue.d.ts +2 -3
  462. package/dist/domains/listEditor/components/ASortableListEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  463. package/dist/domains/listEditor/composables/useListEditorController.d.ts +4 -5
  464. package/dist/domains/listEditor/composables/useListEditorController.js.map +1 -1
  465. package/dist/domains/listEditor/composables/useNestedListEditor.d.ts +3 -4
  466. package/dist/domains/listEditor/composables/useNestedListEditor.js.map +1 -1
  467. package/dist/domains/listEditor/composables/useNestedListEditorController.d.ts +5 -4
  468. package/dist/domains/listEditor/composables/useNestedListEditorController.js.map +1 -1
  469. package/dist/domains/listEditor/composables/useReorderMode.js.map +1 -1
  470. package/dist/domains/listEditor/types/listEditorTypes.d.ts +2 -2
  471. package/dist/domains/listEditor/utils/listEditorLoader.d.ts +5 -5
  472. package/dist/domains/listEditor/utils/listEditorLoader.js.map +1 -1
  473. package/dist/domains/listEditor/utils/resolveCompactText.js.map +1 -1
  474. package/dist/domains/log/api/logApi.d.ts +2 -3
  475. package/dist/domains/log/api/logApi.js.map +1 -1
  476. package/dist/domains/log/components/ALogDatatable.js.map +1 -1
  477. package/dist/domains/log/components/ALogDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  478. package/dist/domains/log/components/ALogDetailView.js.map +1 -1
  479. package/dist/domains/log/components/ALogDetailView.vue.d.ts +1 -1
  480. package/dist/domains/log/components/ALogDetailView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  481. package/dist/domains/log/components/ALogFilter.js.map +1 -1
  482. package/dist/domains/log/components/ALogFilter.vue_vue_type_script_setup_true_lang.js.map +1 -1
  483. package/dist/domains/log/components/ALogListView.js.map +1 -1
  484. package/dist/domains/log/components/ALogListView.vue.d.ts +1 -1
  485. package/dist/domains/log/components/ALogListView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  486. package/dist/domains/log/composables/logActions.d.ts +4 -5
  487. package/dist/domains/log/composables/logActions.js.map +1 -1
  488. package/dist/domains/log/composables/logType.d.ts +6 -7
  489. package/dist/domains/log/composables/logType.js.map +1 -1
  490. package/dist/domains/log/filter/logFilter.d.ts +8 -11
  491. package/dist/domains/log/filter/logFilter.js.map +1 -1
  492. package/dist/domains/permission/components/APermissionEditor.js.map +1 -1
  493. package/dist/domains/permission/components/APermissionEditor.vue.d.ts +4 -4
  494. package/dist/domains/permission/components/APermissionEditor.vue_vue_type_script_setup_true_lang.js.map +1 -1
  495. package/dist/domains/permission/composables/permissionActions.d.ts +3 -6
  496. package/dist/domains/permission/composables/permissionActions.js.map +1 -1
  497. package/dist/domains/permission/config/api/permissionConfigApi.d.ts +2 -2
  498. package/dist/domains/permission/config/api/permissionConfigApi.js.map +1 -1
  499. package/dist/domains/permission/config/composables/permissionConfigActions.d.ts +3 -7
  500. package/dist/domains/permission/config/composables/permissionConfigActions.js.map +1 -1
  501. package/dist/domains/permission/config/store/permissionConfigStore.d.ts +2 -4
  502. package/dist/domains/permission/config/store/permissionConfigStore.js.map +1 -1
  503. package/dist/domains/permission/group/api/permissionGroupApi.d.ts +8 -10
  504. package/dist/domains/permission/group/api/permissionGroupApi.js.map +1 -1
  505. package/dist/domains/permission/group/components/APermissionGroupDatatable.js.map +1 -1
  506. package/dist/domains/permission/group/components/APermissionGroupDatatable.vue.d.ts +12 -10
  507. package/dist/domains/permission/group/components/APermissionGroupDatatable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  508. package/dist/domains/permission/group/components/APermissionGroupDetail.js.map +1 -1
  509. package/dist/domains/permission/group/components/APermissionGroupDetail.vue.d.ts +21 -22
  510. package/dist/domains/permission/group/components/APermissionGroupDetail.vue_vue_type_script_setup_true_lang.js.map +1 -1
  511. package/dist/domains/permission/group/components/APermissionGroupManage.js.map +1 -1
  512. package/dist/domains/permission/group/components/APermissionGroupManage.vue.d.ts +21 -22
  513. package/dist/domains/permission/group/components/APermissionGroupManage.vue_vue_type_script_setup_true_lang.js.map +1 -1
  514. package/dist/domains/permission/group/composables/cachedPermissionGroups.js.map +1 -1
  515. package/dist/domains/permission/group/composables/permissionGroupActions.d.ts +6 -8
  516. package/dist/domains/permission/group/composables/permissionGroupActions.js.map +1 -1
  517. package/dist/domains/permission/group/composables/permissionGroupValidations.d.ts +2 -3
  518. package/dist/domains/permission/group/composables/permissionGroupValidations.js.map +1 -1
  519. package/dist/domains/permission/group/filter/permissionGroupFilter.d.ts +2 -3
  520. package/dist/domains/permission/group/filter/permissionGroupFilter.js.map +1 -1
  521. package/dist/domains/permission/group/store/permissionGroupStore.d.ts +3 -6
  522. package/dist/domains/permission/group/store/permissionGroupStore.js.map +1 -1
  523. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.js.map +1 -1
  524. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  525. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.js.map +1 -1
  526. package/dist/domains/remoteAutocomplete/components/AFilterRemoteAutocompleteWithMinimal.vue_vue_type_script_setup_true_lang.js.map +1 -1
  527. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.js.map +1 -1
  528. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocomplete.vue_vue_type_script_setup_true_lang.js.map +1 -1
  529. package/dist/domains/remoteAutocomplete/components/AFormRemoteAutocompleteWithCached.vue.d.ts +5 -3
  530. package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.d.ts +11 -13
  531. package/dist/domains/remoteAutocomplete/composables/createRemoteAutocomplete.js.map +1 -1
  532. package/dist/domains/subjectSelect/components/AFilterWrapperSubjectSelect.vue.d.ts +13 -11
  533. package/dist/domains/subjectSelect/components/ASubjectSelect.js.map +1 -1
  534. package/dist/domains/subjectSelect/components/ASubjectSelect.vue_vue_type_script_setup_true_lang.js.map +1 -1
  535. package/dist/domains/subjectSelect/composables/useSubjectSelect.js +53 -51
  536. package/dist/domains/subjectSelect/composables/useSubjectSelect.js.map +1 -1
  537. package/dist/domains/system/appShell/components/AActionbar.vue.d.ts +7 -5
  538. package/dist/domains/system/appShell/components/ALayoutSwitch.js.map +1 -1
  539. package/dist/domains/system/appShell/components/ALayoutSwitch.vue.d.ts +7 -5
  540. package/dist/domains/system/appShell/components/ALayoutSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  541. package/dist/domains/system/appShell/composables/teleportSlot.d.ts +0 -1
  542. package/dist/domains/system/appShell/composables/teleportSlot.js.map +1 -1
  543. package/dist/domains/system/components/AAlerts.js.map +1 -1
  544. package/dist/domains/system/components/AAlerts.vue_vue_type_script_setup_true_lang.js.map +1 -1
  545. package/dist/domains/system/composables/alerts.js.map +1 -1
  546. package/dist/domains/system/composables/breadcrumbs.d.ts +3 -3
  547. package/dist/domains/system/composables/breadcrumbs.js.map +1 -1
  548. package/dist/domains/system/composables/languageSettings.js.map +1 -1
  549. package/dist/domains/system/composables/loginStatus.js.map +1 -1
  550. package/dist/domains/system/composables/navigationError.d.ts +6 -8
  551. package/dist/domains/system/composables/navigationError.js.map +1 -1
  552. package/dist/domains/system/composables/pageNavigation.d.ts +9 -10
  553. package/dist/domains/system/composables/pageNavigation.js.map +1 -1
  554. package/dist/domains/system/composables/recordActions.d.ts +14 -22
  555. package/dist/domains/system/composables/recordActions.js.map +1 -1
  556. package/dist/domains/system/composables/recordPage.d.ts +23 -38
  557. package/dist/domains/system/composables/recordPage.js.map +1 -1
  558. package/dist/domains/system/composables/routeHistory.d.ts +4 -5
  559. package/dist/domains/system/composables/routeHistory.js.map +1 -1
  560. package/dist/domains/system/composables/sentry.js.map +1 -1
  561. package/dist/domains/system/composables/useDebugFeatures.d.ts +3 -6
  562. package/dist/domains/system/composables/useDebugFeatures.js.map +1 -1
  563. package/dist/domains/system/store/datatablePageStore.d.ts +8 -1
  564. package/dist/domains/system/store/datatablePageStore.js +10 -3
  565. package/dist/domains/system/store/datatablePageStore.js.map +1 -1
  566. package/dist/domains/system/systemBar/components/ASystemBar.js.map +1 -1
  567. package/dist/domains/system/systemBar/components/ASystemBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  568. package/dist/domains/system/systemBar/utils/appReload.d.ts +5 -5
  569. package/dist/domains/system/systemBar/utils/appReload.js.map +1 -1
  570. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.js.map +1 -1
  571. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue.d.ts +2 -3
  572. package/dist/domains/ui/buttons/action/components/AActionCloseButtonHistory.vue_vue_type_script_setup_true_lang.js.map +1 -1
  573. package/dist/domains/ui/buttons/action/components/AActionDeleteButton.js.map +1 -1
  574. package/dist/domains/ui/buttons/action/components/AActionDeleteButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  575. package/dist/domains/ui/buttons/components/ABtnSplit.vue.d.ts +9 -7
  576. package/dist/domains/ui/components/AAvatarColorPicker.js.map +1 -1
  577. package/dist/domains/ui/components/AAvatarColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  578. package/dist/domains/ui/components/ACard.js.map +1 -1
  579. package/dist/domains/ui/components/ACard.vue.d.ts +7 -3
  580. package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js +6 -2
  581. package/dist/domains/ui/components/ACard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  582. package/dist/domains/ui/components/ACardLoader.js.map +1 -1
  583. package/dist/domains/ui/components/ACardLoader.vue.d.ts +1 -0
  584. package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js +13 -7
  585. package/dist/domains/ui/components/ACardLoader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  586. package/dist/domains/ui/components/AChipNoLink.vue.d.ts +5 -3
  587. package/dist/domains/ui/components/ACopyText.vue.d.ts +9 -7
  588. package/dist/domains/ui/components/ACreateDialog.js.map +1 -1
  589. package/dist/domains/ui/components/ACreateDialog.vue.d.ts +11 -9
  590. package/dist/domains/ui/components/ACreateDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  591. package/dist/domains/ui/components/ADialogToolbar.vue.d.ts +5 -3
  592. package/dist/domains/ui/components/ARow.vue.d.ts +5 -3
  593. package/dist/domains/ui/components/ATimeTrackingFields.js.map +1 -1
  594. package/dist/domains/ui/components/ATimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
  595. package/dist/domains/ui/components/AUserAndTimeTrackingFields.js.map +1 -1
  596. package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue.d.ts +3 -5
  597. package/dist/domains/ui/components/AUserAndTimeTrackingFields.vue_vue_type_script_setup_true_lang.js.map +1 -1
  598. package/dist/domains/ui/datetime/components/ADatetimePicker.js +1 -1
  599. package/dist/domains/ui/datetime/components/ADatetimePicker.js.map +1 -1
  600. package/dist/domains/ui/datetime/components/ADatetimePicker.vue.d.ts +5 -3
  601. package/dist/domains/ui/datetime/components/ADatetimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  602. package/dist/domains/ui/file/components/AFileDropzone.js.map +1 -1
  603. package/dist/domains/ui/file/components/AFileDropzone.vue.d.ts +1 -1
  604. package/dist/domains/ui/file/components/AFileDropzone.vue_vue_type_script_setup_true_lang.js.map +1 -1
  605. package/dist/domains/ui/file/components/AFileInput.js.map +1 -1
  606. package/dist/domains/ui/file/components/AFileInput.vue.d.ts +9 -7
  607. package/dist/domains/ui/file/components/AFileInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  608. package/dist/domains/ui/file/components/AFileInputDialog.js.map +1 -1
  609. package/dist/domains/ui/file/components/AFileInputDialog.vue.d.ts +9 -7
  610. package/dist/domains/ui/file/components/AFileInputDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  611. package/dist/domains/ui/file/composables/dropzone.js.map +1 -1
  612. package/dist/domains/ui/file/composables/formatAndSizeCheck.js.map +1 -1
  613. package/dist/domains/ui/view/components/AGenericView.vue.d.ts +7 -5
  614. package/dist/domains/ui/view/components/ALoginView.js +1 -1
  615. package/dist/domains/ui/view/components/ALoginView.js.map +1 -1
  616. package/dist/domains/ui/view/components/ALoginView.vue.d.ts +5 -3
  617. package/dist/domains/ui/view/components/ALoginView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  618. package/dist/domains/ui/view/components/ALogoutView.js.map +1 -1
  619. package/dist/domains/ui/view/components/ALogoutView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  620. package/dist/domains/ui/view/components/ANotFoundView.js.map +1 -1
  621. package/dist/domains/ui/view/components/ANotFoundView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  622. package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.d.ts +6 -7
  623. package/dist/domains/unsavedGuard/composables/useUnsavedChangesGuard.js.map +1 -1
  624. package/dist/lib.d.ts +2 -2
  625. package/dist/plugins/commonVuetifyConfig.d.ts +3 -3
  626. package/dist/plugins/commonVuetifyConfig.js.map +1 -1
  627. package/dist/plugins/i18n.d.ts +4 -5
  628. package/dist/plugins/i18n.js.map +1 -1
  629. package/dist/plugins/pluginOptions.d.ts +4 -2
  630. package/dist/plugins/pluginOptions.js.map +1 -1
  631. package/dist/plugins/webfontloader.js.map +1 -1
  632. package/dist/shared/error/AnzuApiCancelledError.d.ts +5 -8
  633. package/dist/shared/error/AnzuApiCancelledError.js.map +1 -1
  634. package/dist/shared/error/AnzuError.d.ts +3 -5
  635. package/dist/shared/error/AnzuError.js.map +1 -1
  636. package/dist/shared/error/AuthUnavailableError.d.ts +3 -3
  637. package/dist/shared/error/AuthUnavailableError.js.map +1 -1
  638. package/dist/shared/error/isInCauseChain.d.ts +2 -2
  639. package/dist/shared/error/isInCauseChain.js.map +1 -1
  640. package/dist/shared/types/UserAndTimeTracking.d.ts +5 -5
  641. package/dist/shared/types/Validation.d.ts +4 -5
  642. package/dist/shared/types/common.d.ts +1 -3
  643. package/dist/shared/types/globalComponents.d.ts +5 -6
  644. package/dist/shared/utils/common.js.map +1 -1
  645. package/dist/shared/utils/datetime.d.ts +0 -1
  646. package/dist/shared/utils/datetime.js.map +1 -1
  647. package/dist/shared/utils/datetimePickerValue.d.ts +4 -7
  648. package/dist/shared/utils/datetimePickerValue.js.map +1 -1
  649. package/dist/shared/utils/development.d.ts +3 -3
  650. package/dist/shared/utils/development.js.map +1 -1
  651. package/dist/shared/utils/envConfig.d.ts +4 -4
  652. package/dist/shared/utils/envConfig.js.map +1 -1
  653. package/dist/shared/utils/json.d.ts +1 -1
  654. package/dist/shared/utils/json.js.map +1 -1
  655. package/dist/shared/utils/userAndTimeTracking.d.ts +5 -7
  656. package/dist/shared/utils/userAndTimeTracking.js.map +1 -1
  657. package/dist/shared/validators/vuelidate/common/useValidateHexColor.d.ts +3 -5
  658. package/dist/shared/validators/vuelidate/common/useValidateHexColor.js.map +1 -1
  659. package/dist/testing/appShell.d.ts +11 -11
  660. package/dist/testing/appShell.js.map +1 -1
  661. package/dist/testing/closeButtons.d.ts +9 -11
  662. package/dist/testing/closeButtons.js.map +1 -1
  663. package/dist/testing/declaredDependencies.d.ts +7 -7
  664. package/dist/testing/declaredDependencies.js.map +1 -1
  665. package/dist/testing/generatedRoutes.d.ts +6 -11
  666. package/dist/testing/generatedRoutes.js.map +1 -1
  667. package/dist/testing/routeHistory.d.ts +5 -12
  668. package/dist/testing/routeHistory.js.map +1 -1
  669. package/dist/testing/sortableLists.d.ts +16 -21
  670. package/dist/testing/sortableLists.js.map +1 -1
  671. package/dist/testing/typedRouter.d.ts +0 -1
  672. package/dist/testing/typedRouter.js.map +1 -1
  673. package/package.json +39 -29
  674. package/src/e2e/conventions.d.mts +4 -0
  675. package/src/e2e/conventions.mjs +15 -0
  676. package/src/e2e/index.d.mts +8 -0
  677. package/src/e2e/index.mjs +1 -0
  678. package/src/e2e/routeWalk.d.mts +43 -0
  679. package/src/e2e/routeWalk.mjs +606 -0
  680. package/src/e2e/types.d.mts +161 -0
  681. package/src/eslint/adminConfig.mjs +19 -27
  682. package/src/eslint/globalComponentNames.mjs +3 -4
  683. package/src/eslint/oxlint.mjs +7 -20
  684. package/src/eslint/plugin.d.mts +2 -4
  685. package/src/eslint/plugin.mjs +18 -34
  686. package/src/eslint/validRouteName.mjs +6 -7
  687. package/src/vite/devWatch.mjs +30 -43
  688. package/src/vite/index.d.mts +5 -5
  689. package/src/vite/sentry.mjs +7 -12
  690. package/src/vite/sourcemaps.mjs +4 -8
@@ -1 +1 @@
1
- {"version":3,"file":"useListEditorController.js","names":["useListEditorController","keyField","options","keyOf","item","positionOpt","managedPosition","positionField","positionMultiplier","positionStrategy","positionOverrides","items","computed","dirtyExclude","toValue","stripTempIds","_k","v","normalize","copy","f","baselineHashes","ref","baselineRows","captureBaseline","map","r","rows","cloneDeep","seeded","changed","nextListEditorTempId","movedKeys","deletedRows","submitted","registeredValidity","reactive","isItemDirty","saved","key","baseHash","addedBaseline","editedKeys","live","base","stale","isRowEdited","unsavedKeys","out","isUnsaved","hasUnsaved","unsavedCount","keys","resolveValidity","registered","invalidKeys","hasErrors","rowState","invalid","editing","warning","validateAll","renumber","action","preservePositionValues","arr","renumberPositions","write","getPayload","getChanges","added","updated","moved","commit","source","savedItems","next","reset","indexOfKey","x","row","at","hint","i","current","removed","opts","hashes","fromIndex","toIndex","el","isValid"],"sources":["../../../../src/domains/listEditor/composables/useListEditorController.ts"],"sourcesContent":["import {\n computed,\n reactive,\n ref,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n type ShallowUnwrapRef,\n} from 'vue'\nimport type { ListEditorKey, ListEditorValidationState, PositionHint } from '@/domains/listEditor/types/listEditorTypes'\nimport { preservePositionValues, renumberPositions } from '@/domains/listEditor/utils/positions'\nimport { nextListEditorTempId } from '@/domains/listEditor/utils/tempId'\nimport { cloneDeep } from '@/shared/utils/common'\n\n/** Per-row validity. `true` (or `{ valid: true }`) = VALID. Only `valid: false` blocks save. */\nexport type ListEditorValidationResult = boolean | { valid: boolean; state?: 'invalid' | 'warning'; message?: string }\n\nexport type GetKey<TItem> = keyof TItem | ((item: TItem) => ListEditorKey)\n/**\n * How the managed order field is maintained.\n * - `renumber` (default) — positions are opaque ordinals: every write rewrites them to a clean\n * `(index + 1) * multiplier` series.\n * - `preserve-values` — positions are meaningful ABSOLUTE numbers (e.g. a CMS page interleaves its\n * rows with another collection on the same numeric scale, so rewriting 10/310 to 100/200 would\n * move unrelated items). A REORDER then only swaps rows through the EXISTING slots: the set of\n * values is kept and reassigned, ascending, to the new row order. It is a reorder policy, not a\n * normalization policy — `add` keeps the position the factory/consumer supplied, `delete` leaves\n * holes rather than compacting.\n *\n * Per-action exceptions go through `strategyOverrides` (e.g. base `preserve-values` +\n * `{ remove: 'renumber' }` to keep absolute values on reorder/save but still close the gap on delete).\n */\nexport type PositionStrategy = 'renumber' | 'preserve-values'\n\n/** Which mutation is asking for positions to be (re)assigned. */\nexport type PositionAction = 'add' | 'update' | 'remove' | 'move' | 'payload'\n\nexport type PositionOption<TItem> =\n | false\n | keyof TItem\n | {\n field: keyof TItem\n multiplier?: number\n strategy?: PositionStrategy\n /**\n * Per-action override of `strategy`. Each entry replaces the base strategy for that one\n * action only; omitted actions inherit `strategy`. This is what lets a consumer mix policies\n * without a bespoke preset — the behaviour is visible at the call site, one action per key.\n */\n strategyOverrides?: Partial<Record<PositionAction, PositionStrategy>>\n }\n\nexport interface ListEditorChanges<TItem> {\n added: TItem[]\n updated: TItem[]\n moved: TItem[]\n deleted: TItem[]\n reparented: TItem[]\n}\n\nexport interface UseListEditorControllerOptions<TItem extends Record<string, any>> {\n /** Read the live list (the editor's v-model, or a consumer store getter). */\n get: () => TItem[]\n /** Write the list back. */\n set: (items: TItem[]) => void\n /** New-row factory. Optional for read-only / no-add lists. Should mint a stable temp id. */\n factory?: () => TItem\n /** Stable row identity. Default `'id'`. Never point this at the position field. */\n getKey?: GetKey<TItem>\n /** Managed order field. Default `'position'`. `false` opts out of position management. */\n position?: PositionOption<TItem>\n /**\n * Extra top-level fields to drop from the dirty content-hash (position is\n * always dropped). For a child collection a separate nested editor already\n * tracks, so editing a child doesn't flip the parent row amber. Still in the\n * payload — only the dirty comparison ignores it. Reactive (accepts a getter/ref).\n */\n dirtyExclude?: MaybeRefOrGetter<string[]>\n /** Per-row validity — `true` = valid. Drives the red rail + `hasErrors`. */\n validate?: (item: TItem) => ListEditorValidationResult\n /** Custom dirty predicate (override the default content-diff). */\n isDirty?: (current: TItem, saved: TItem | undefined) => boolean\n /** Custom save payload (overrides `getPayload`). */\n payload?: (items: TItem[]) => TItem[]\n /** Resolve a saved row's key on commit (default: existing key, else mint a temp id). */\n commitKey?: (saved: TItem, previous: TItem | undefined) => ListEditorKey\n /** Normalize server rows before they become the new baseline on commit. */\n normalizeSaved?: (savedItems: TItem[]) => TItem[]\n}\n\nexport interface ListEditorHandle<TItem extends Record<string, any>> {\n items: ComputedRef<TItem[]>\n hasUnsaved: ComputedRef<boolean>\n /** Count of distinct unconfirmed changes (added/edited/moved rows + deferred-deletion tombstones). */\n unsavedCount: ComputedRef<number>\n hasErrors: ComputedRef<boolean>\n invalidKeys: ComputedRef<Set<ListEditorKey>>\n /** Amber: is this row added / edited / moved since the last commit? */\n isUnsaved: (key: ListEditorKey) => boolean\n /** Red rail (gated): 'invalid' only once the row is unsaved or `validateAll()` ran. */\n rowState: (item: TItem, key: ListEditorKey, editing?: boolean) => ListEditorValidationState\n /** Force-show all invalid rows + return whether the list is valid. The save guard. */\n validateAll: () => boolean\n /** Normalized ordered array for a full-DTO save. */\n getPayload: () => TItem[]\n /** Change-set for partial-save endpoints. */\n getChanges: () => ListEditorChanges<TItem>\n /** Adopt saved rows as the new baseline; backfill keys; clear unsaved/submitted. */\n commit: (savedItems?: TItem[]) => void\n /** Discard unsaved edits back to the last committed baseline (or given items). */\n reset: (items?: TItem[]) => void\n addItem: (item?: TItem, hint?: PositionHint) => ListEditorKey | undefined\n updateItem: (key: ListEditorKey, next: TItem | Partial<TItem> | ((current: TItem) => TItem)) => void\n /** Remove a row. `trackDeleted: false` (immediate mode) skips the deferred-deletion tombstone. */\n deleteItem: (key: ListEditorKey, opts?: { trackDeleted?: boolean }) => void\n /** Clear a deferred-deletion tombstone (the caller re-inserts the row, e.g. reorder Cancel). */\n restoreDeleted: (key: ListEditorKey) => void\n moveItem: (fromIndex: number, toIndex: number) => void\n /** Drop the \"moved\" flag for the given keys (or all) without touching edits/adds — e.g. reorder Cancel. */\n clearMoved: (keys?: Iterable<ListEditorKey>) => void\n /** Escape hatch: a row form (e.g. vuelidate) reports its own validity instead of `validate`. */\n registerValidity: (key: ListEditorKey, isValid: () => boolean) => () => void\n}\n\n/**\n * The shape a CONSUMER sees when it reads a list-editor handle through a template/function ref.\n * Vue's `expose` proxy unwraps every exposed ref, so the reactive fields (`hasUnsaved`, `hasErrors`,\n * `unsavedCount`, …) arrive as plain VALUES here, not `Ref`s: read `handle.hasUnsaved` (a boolean),\n * never `handle.hasUnsaved.value` (that is `undefined`). Type your `useTemplateRef` / collected-ref\n * maps with this so a stray `.value` is a compile error instead of a silently-dead guard/save-gate.\n */\nexport type ExposedListEditorHandle<TItem extends Record<string, any>> = ShallowUnwrapRef<ListEditorHandle<TItem>>\n\n/**\n * Component-owned state controller for the list editors (v2). Owns row keys,\n * declared dirty tracking (no fragile whole-list JSON diff on volatile fields),\n * validation summary, position renumbering, and the save lifecycle — exposed as\n * a `ListEditorHandle`. Created internally by an editor (default) or by a consumer\n * that passes it in as `:editor`, so the state survives unmount/remount.\n */\nexport function useListEditorController<TItem extends Record<string, any>>(\n options: UseListEditorControllerOptions<TItem>\n): ListEditorHandle<TItem> {\n const keyField = (typeof options.getKey === 'function' ? null : (options.getKey ?? 'id')) as keyof TItem | null\n const keyOf = (item: TItem): ListEditorKey =>\n typeof options.getKey === 'function' ? options.getKey(item) : (item[keyField as keyof TItem] as ListEditorKey)\n\n const positionOpt = options.position ?? 'position'\n const managedPosition = positionOpt !== false\n const positionField = (\n typeof positionOpt === 'object' ? positionOpt.field : positionOpt === false ? 'position' : positionOpt\n ) as string\n const positionMultiplier = typeof positionOpt === 'object' && positionOpt.multiplier ? positionOpt.multiplier : 1\n const positionStrategy: PositionStrategy = (typeof positionOpt === 'object' && positionOpt.strategy) || 'renumber'\n const positionOverrides: Partial<Record<PositionAction, PositionStrategy>> =\n (typeof positionOpt === 'object' && positionOpt.strategyOverrides) || {}\n\n const items = computed<TItem[]>(() => options.get())\n\n // Baseline = last committed snapshot. `hashes` powers content-diff dirty\n // (position excluded so a reorder never marks a row dirty); `rows` powers `reset`.\n const dirtyExclude = computed<string[]>(() => toValue(options.dirtyExclude) ?? [])\n // Temp ids are client identity bookkeeping, never content. `ensureKeys` mints one INTO the model\n // for rows the server returns without a key — and for a NESTED editor that write happens on mount,\n // i.e. when a parent row is merely expanded to be read. The parent hashes the whole row, so without\n // this the seed would retroactively invalidate the parent's baseline and expanding a row to LOOK at\n // it would mark it unsaved (QA 85050 batch 10 BUG-02). Only negative NUMBERS are stripped —\n // persisted ids are positive (see `nextListEditorTempId`), so real ids still count as content, and\n // a genuinely added row still differs by its other fields.\n const stripTempIds = (_k: string, v: unknown): unknown =>\n _k === 'id' && typeof v === 'number' && v < 0 ? undefined : v\n const normalize = (item: TItem): string => {\n const copy = { ...item } as Record<string, unknown>\n if (managedPosition) delete copy[positionField]\n for (const f of dirtyExclude.value) delete copy[f]\n return JSON.stringify(copy, stripTempIds)\n }\n const baselineHashes = ref(new Map<ListEditorKey, string>()) as Ref<Map<ListEditorKey, string>>\n const baselineRows = ref<TItem[]>([]) as Ref<TItem[]>\n const captureBaseline = (rows: TItem[]) => {\n const map = new Map<ListEditorKey, string>()\n for (const r of rows) map.set(keyOf(r), normalize(r))\n baselineHashes.value = map\n // Deep clone: a shallow `{...r}` shares nested refs with the live row, so an\n // in-place mutation would drift the baseline (reset/re-hash read stale data).\n baselineRows.value = rows.map((r) => cloneDeep(r))\n }\n // Re-hash when the excluded-field set changes. `sync` so baseline + live\n // normalize() never disagree mid-flush (which would flash every row amber).\n watch(\n dirtyExclude,\n () => {\n const map = new Map<ListEditorKey, string>()\n for (const r of baselineRows.value) map.set(keyOf(r), normalize(r))\n baselineHashes.value = map\n },\n { flush: 'sync' }\n )\n // Ensure every row has a resolvable, UNIQUE key before the first baseline\n // capture. Server rows lacking the key field (e.g. no `id` and no custom\n // get-key → keyOf() is undefined for ALL of them) would collapse to a single\n // baseline entry and read as perpetually unsaved even on a clean load\n // (QA 85050 BUG-03). Mint a temp id for those rows — exactly what commit()\n // already does on save (line ~299). Rows that DO resolve a key (the common\n // case) are untouched, so id-backed editors are unaffected.\n const ensureKeys = (rows: TItem[]): { rows: TItem[]; changed: boolean } => {\n if (!keyField) return { rows, changed: false }\n let changed = false\n const next = rows.map((item) => {\n const k = keyOf(item)\n if (k === undefined || k === null) {\n changed = true\n return { ...item, [keyField]: nextListEditorTempId() } as TItem\n }\n return item\n })\n return { rows: next, changed }\n }\n const seeded = ensureKeys(options.get())\n if (seeded.changed) options.set(seeded.rows)\n // Capture from the seeded array directly (not a re-read of options.get()): when\n // set() emits through v-model the prop update is async, so options.get() would\n // still return the pre-mint colliding rows here. Mirrors commit()'s pattern.\n captureBaseline(seeded.rows)\n\n // Declared structural state the content-diff can't see.\n const movedKeys = ref(new Set<ListEditorKey>()) as Ref<Set<ListEditorKey>>\n const deletedRows = ref<TItem[]>([]) as Ref<TItem[]>\n const submitted = ref(false)\n // Reactive so a row form (re)registering its validity re-runs `invalidKeys`/`rowState`.\n const registeredValidity = reactive(new Map<ListEditorKey, () => boolean>())\n\n const isItemDirty = (item: TItem, key: ListEditorKey): boolean => {\n if (options.isDirty) {\n const saved = baselineRows.value.find((r) => keyOf(r) === key)\n return options.isDirty(item, saved)\n }\n const baseHash = baselineHashes.value.get(key)\n if (baseHash === undefined) return true // added\n if (baseHash !== normalize(item)) return true // edited\n return movedKeys.value.has(key) // moved (content-invisible)\n }\n\n // Gate the validation rail on \"has this row actually been edited\" rather than just \"is it\n // unsaved\", so a freshly added still-untouched row is amber but not yet red. `addedBaseline` =\n // first-seen content hash of each ADDED row; `editedKeys` = STICKY set of rows whose content has\n // since diverged from that first-seen / committed baseline. Sticky like vuelidate `$dirty`: once\n // edited a row stays dirty until commit/reset, so clearing a field back to empty keeps the rail\n // consistent with the field's own error state. Position / `dirtyExclude` are normalized out, so a\n // reorder never counts as an edit.\n const addedBaseline = ref(new Map<ListEditorKey, string>()) as Ref<Map<ListEditorKey, string>>\n const editedKeys = ref(new Set<ListEditorKey>()) as Ref<Set<ListEditorKey>>\n watch(\n items,\n (rows) => {\n const live = new Set<ListEditorKey>()\n for (const r of rows) {\n const key = keyOf(r)\n live.add(key)\n if (!baselineHashes.value.has(key) && !addedBaseline.value.has(key)) {\n addedBaseline.value.set(key, normalize(r))\n }\n if (!editedKeys.value.has(key)) {\n const base = baselineHashes.value.get(key) ?? addedBaseline.value.get(key)\n if (base !== undefined && base !== normalize(r)) editedKeys.value.add(key)\n }\n }\n const stale: ListEditorKey[] = []\n for (const key of addedBaseline.value.keys()) if (!live.has(key)) stale.push(key)\n for (const key of stale) addedBaseline.value.delete(key)\n // A deferred-deleted key that becomes live again (re-add before save) must drop its tombstone —\n // otherwise it would both render and still count/report as deleted.\n if (deletedRows.value.some((r) => live.has(keyOf(r)))) {\n deletedRows.value = deletedRows.value.filter((r) => !live.has(keyOf(r)))\n }\n },\n { immediate: true, deep: true }\n )\n\n const isRowEdited = (key: ListEditorKey): boolean => editedKeys.value.has(key)\n\n const unsavedKeys = computed<Set<ListEditorKey>>(() => {\n const out = new Set<ListEditorKey>()\n for (const item of options.get()) {\n const key = keyOf(item)\n if (isItemDirty(item, key)) out.add(key)\n }\n return out\n })\n\n const isUnsaved = (key: ListEditorKey): boolean => unsavedKeys.value.has(key)\n const hasUnsaved = computed<boolean>(() => unsavedKeys.value.size > 0 || deletedRows.value.length > 0)\n\n // Count of DISTINCT unconfirmed changes = union of live dirty keys (added / edited / moved) and\n // deferred-deletion tombstones. A key that is both live and tombstoned (delete-then-re-add) counts\n // once; a deleted row (no longer live) adds one. Drives the \"N unconfirmed changes\" indicator, so a\n // delete lights up as a change even though the row itself is gone.\n const unsavedCount = computed<number>(() => {\n const keys = new Set<ListEditorKey>(unsavedKeys.value)\n for (const r of deletedRows.value) keys.add(keyOf(r))\n return keys.size\n })\n\n const resolveValidity = (item: TItem, key: ListEditorKey): { invalid: boolean; warning: boolean } => {\n const registered = registeredValidity.get(key)\n if (registered) return { invalid: !registered(), warning: false }\n if (!options.validate) return { invalid: false, warning: false }\n const r = options.validate(item)\n if (typeof r === 'boolean') return { invalid: !r, warning: false }\n return { invalid: !r.valid, warning: r.valid && r.state === 'warning' }\n }\n\n const invalidKeys = computed<Set<ListEditorKey>>(() => {\n const out = new Set<ListEditorKey>()\n for (const item of options.get()) {\n const key = keyOf(item)\n if (resolveValidity(item, key).invalid) out.add(key)\n }\n return out\n })\n const hasErrors = computed<boolean>(() => invalidKeys.value.size > 0)\n\n // Red rail gated behind \"row has been edited\" (content changed since add/baseline — mirrors the\n // field's vuelidate `$dirty`) or an explicit validateAll() — so a freshly added still-untouched\n // row stays amber (not red) and a loaded-but-invalid row doesn't light up before interaction,\n // while a save attempt reveals every offender (mounted or collapsed).\n const rowState = (item: TItem, key: ListEditorKey, editing = false): ListEditorValidationState => {\n const { invalid, warning } = resolveValidity(item, key)\n // Red rail for an invalid row that is edited, unsaved (added), or after a save attempt. A row being\n // filled in reads amber (not red) and goes red once collapsed — but a save attempt (`submitted`,\n // which also reveals collapsed offenders) always reds it, even while open. (QA 85050 batch 7)\n if (invalid) {\n if (submitted.value) return 'invalid'\n if (editing) return null\n return isRowEdited(key) || isUnsaved(key) ? 'invalid' : null\n }\n if (warning) return 'warning'\n return null\n }\n\n const validateAll = (): boolean => {\n submitted.value = true\n return invalidKeys.value.size === 0\n }\n\n // Resolve the policy for THIS action: a per-action override wins, else the base strategy.\n // Under 'preserve-values' only a move reassigns (through the existing kept slots); every other\n // action leaves positions as-is (add keeps the handed value, delete leaves a hole, update/payload\n // never touch them). Under 'renumber' every action rewrites to a clean `(index+1)*multiplier`.\n const renumber = (arr: TItem[], action: PositionAction): TItem[] => {\n if (!managedPosition) return arr\n const strategy = positionOverrides[action] ?? positionStrategy\n if (strategy === 'preserve-values') {\n return action === 'move' ? preservePositionValues(arr, { positionField }) : arr\n }\n return renumberPositions(arr, { positionField, positionMultiplier })\n }\n\n const write = (arr: TItem[], action: PositionAction) => options.set(renumber(arr, action))\n\n const getPayload = (): TItem[] =>\n options.payload ? options.payload(options.get()) : renumber(options.get(), 'payload')\n\n const getChanges = (): ListEditorChanges<TItem> => {\n const added: TItem[] = []\n const updated: TItem[] = []\n const moved: TItem[] = []\n for (const item of options.get()) {\n const key = keyOf(item)\n const baseHash = baselineHashes.value.get(key)\n if (baseHash === undefined) added.push(item)\n else if (baseHash !== normalize(item)) updated.push(item)\n if (movedKeys.value.has(key)) moved.push(item)\n }\n return { added, updated, moved, deleted: [...deletedRows.value], reparented: [] }\n }\n\n const commit = (savedItems?: TItem[]): void => {\n const source = savedItems ?? options.get()\n const normalized = options.normalizeSaved ? options.normalizeSaved(source) : source\n const next = normalized.map((item) => {\n const key = options.commitKey\n ? options.commitKey(\n item,\n baselineRows.value.find((r) => keyOf(r) === keyOf(item))\n )\n : keyOf(item)\n if (key === undefined || key === null) {\n return keyField ? ({ ...item, [keyField]: nextListEditorTempId() } as TItem) : item\n }\n return item\n })\n options.set(next)\n captureBaseline(next)\n movedKeys.value = new Set()\n deletedRows.value = []\n addedBaseline.value = new Map()\n editedKeys.value = new Set()\n submitted.value = false\n }\n\n const reset = (rows?: TItem[]): void => {\n options.set(rows ?? baselineRows.value.map((r) => cloneDeep(r)))\n movedKeys.value = new Set()\n deletedRows.value = []\n addedBaseline.value = new Map()\n editedKeys.value = new Set()\n submitted.value = false\n }\n\n const indexOfKey = (arr: TItem[], key: ListEditorKey): number => arr.findIndex((x) => keyOf(x) === key)\n\n const addItem = (item?: TItem, hint?: PositionHint): ListEditorKey | undefined => {\n const row = item ?? options.factory?.()\n if (row === undefined) return undefined // no item + no factory (read-only list) → no-op\n const arr = [...options.get()]\n let at = arr.length\n if (hint?.afterId !== undefined) {\n const i = indexOfKey(arr, hint.afterId)\n at = i === -1 ? arr.length : i + 1\n } else if (hint?.index !== undefined) {\n at = Math.max(0, Math.min(hint.index, arr.length))\n }\n arr.splice(at, 0, row)\n write(arr, 'add')\n return keyOf(row)\n }\n\n const updateItem = (key: ListEditorKey, next: TItem | Partial<TItem> | ((current: TItem) => TItem)): void => {\n const arr = [...options.get()]\n const i = indexOfKey(arr, key)\n if (i === -1) return\n const current = arr[i]!\n const resolved =\n typeof next === 'function'\n ? (next as (c: TItem) => TItem)(current)\n : ({ ...current, ...(next as Partial<TItem>) } as TItem)\n arr[i] = resolved\n write(arr, 'update')\n }\n\n const deleteItem = (key: ListEditorKey, opts?: { trackDeleted?: boolean }): void => {\n const arr = [...options.get()]\n const i = indexOfKey(arr, key)\n if (i === -1) return\n const removed = arr.splice(i, 1)[0]!\n // A previously-saved row that's removed is a DEFERRED deletion: reported in the change-set and\n // counted as one unconfirmed change (`unsavedCount`) until save. `trackDeleted: false` (immediate\n // mode — the row is already deleted on the backend) skips the tombstone so it does NOT read as\n // unsaved. An unsaved temp row just vanishes either way.\n if (baselineHashes.value.has(key) && opts?.trackDeleted !== false) {\n deletedRows.value = [...deletedRows.value, removed]\n } else if (baselineHashes.value.has(key)) {\n // Deleted on the backend: no longer part of the saved rows `reset()` returns to.\n const hashes = new Map(baselineHashes.value)\n hashes.delete(key)\n baselineHashes.value = hashes\n baselineRows.value = baselineRows.value.filter((r) => keyOf(r) !== key)\n }\n movedKeys.value.delete(key)\n write(arr, 'remove')\n }\n\n // Un-tombstone a deferred-deleted row. Re-inserting the row into the model is the caller's job\n // (e.g. reorder Cancel restoring the pre-session snapshot); this only clears the deletion record so\n // `deletedRows` / `unsavedCount` / `getChanges().deleted` stay consistent.\n const restoreDeleted = (key: ListEditorKey): void => {\n deletedRows.value = deletedRows.value.filter((r) => keyOf(r) !== key)\n }\n\n const moveItem = (fromIndex: number, toIndex: number): void => {\n const arr = [...options.get()]\n if (fromIndex < 0 || fromIndex >= arr.length || toIndex < 0 || toIndex >= arr.length) return\n if (fromIndex === toIndex) return\n const el = arr.splice(fromIndex, 1)[0]!\n arr.splice(toIndex, 0, el)\n movedKeys.value.add(keyOf(el))\n write(arr, 'move')\n }\n\n // Reorder Cancel restores the pre-session order, so the moves are undone — drop\n // just those keys' \"moved\" flag (edits/adds stay dirty). No arg = clear all.\n const clearMoved = (keys?: Iterable<ListEditorKey>): void => {\n if (keys === undefined) {\n movedKeys.value = new Set()\n return\n }\n const next = new Set(movedKeys.value)\n for (const key of keys) next.delete(key)\n movedKeys.value = next\n }\n\n const registerValidity = (key: ListEditorKey, isValid: () => boolean): (() => void) => {\n registeredValidity.set(key, isValid)\n return () => registeredValidity.delete(key)\n }\n\n return {\n items,\n hasUnsaved,\n unsavedCount,\n hasErrors,\n invalidKeys,\n isUnsaved,\n rowState,\n validateAll,\n getPayload,\n getChanges,\n commit,\n reset,\n addItem,\n updateItem,\n deleteItem,\n restoreDeleted,\n moveItem,\n clearMoved,\n registerValidity,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useListEditorController.js","names":["useListEditorController","keyField","options","keyOf","item","positionOpt","managedPosition","positionField","positionMultiplier","positionStrategy","positionOverrides","items","computed","dirtyExclude","toValue","stripTempIds","_k","v","normalize","copy","f","baselineHashes","ref","baselineRows","captureBaseline","map","r","rows","cloneDeep","seeded","changed","nextListEditorTempId","movedKeys","deletedRows","submitted","registeredValidity","reactive","isItemDirty","saved","key","baseHash","addedBaseline","editedKeys","live","base","stale","isRowEdited","unsavedKeys","out","isUnsaved","hasUnsaved","unsavedCount","keys","resolveValidity","registered","invalidKeys","hasErrors","rowState","invalid","editing","warning","validateAll","renumber","action","preservePositionValues","arr","renumberPositions","write","getPayload","getChanges","added","updated","moved","commit","source","savedItems","next","reset","indexOfKey","x","row","at","hint","i","current","removed","opts","hashes","fromIndex","toIndex","el","isValid"],"sources":["../../../../src/domains/listEditor/composables/useListEditorController.ts"],"sourcesContent":["import {\n computed,\n reactive,\n ref,\n toValue,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type Ref,\n type ShallowUnwrapRef,\n} from 'vue'\nimport type { ListEditorKey, ListEditorValidationState, PositionHint } from '@/domains/listEditor/types/listEditorTypes'\nimport { preservePositionValues, renumberPositions } from '@/domains/listEditor/utils/positions'\nimport { nextListEditorTempId } from '@/domains/listEditor/utils/tempId'\nimport { cloneDeep } from '@/shared/utils/common'\n\n/** Per-row validity. `true` (or `{ valid: true }`) = VALID. Only `valid: false` blocks save. */\nexport type ListEditorValidationResult = boolean | { valid: boolean; state?: 'invalid' | 'warning'; message?: string }\n\nexport type GetKey<TItem> = keyof TItem | ((item: TItem) => ListEditorKey)\n/**\n * How the managed order field is maintained.\n * - `renumber` (default) — positions are opaque ordinals: every write rewrites them to a clean\n * `(index + 1) * multiplier` series.\n * - `preserve-values` — positions are meaningful ABSOLUTE numbers (e.g. a CMS page interleaves its\n * rows with another collection on the same numeric scale, so rewriting 10/310 to 100/200 would\n * move unrelated items). A REORDER then only swaps rows through the EXISTING slots: the set of\n * values is kept and reassigned, ascending, to the new row order. It is a reorder policy, not a\n * normalization policy — `add` keeps the position the factory/consumer supplied, `delete` leaves\n * holes rather than compacting.\n *\n * Per-action exceptions go through `strategyOverrides` (e.g. base `preserve-values` +\n * `{ remove: 'renumber' }` to keep absolute values on reorder/save but still close the gap on delete).\n */\nexport type PositionStrategy = 'renumber' | 'preserve-values'\n\n/** Which mutation is asking for positions to be (re)assigned. */\nexport type PositionAction = 'add' | 'update' | 'remove' | 'move' | 'payload'\n\nexport type PositionOption<TItem> =\n | false\n | keyof TItem\n | {\n field: keyof TItem\n multiplier?: number\n strategy?: PositionStrategy\n /**\n * Per-action override of `strategy`. Each entry replaces the base strategy for that one\n * action only; omitted actions inherit `strategy`. This is what lets a consumer mix policies\n * without a bespoke preset — the behaviour is visible at the call site, one action per key.\n */\n strategyOverrides?: Partial<Record<PositionAction, PositionStrategy>>\n }\n\nexport interface ListEditorChanges<TItem> {\n added: TItem[]\n updated: TItem[]\n moved: TItem[]\n deleted: TItem[]\n reparented: TItem[]\n}\n\nexport interface UseListEditorControllerOptions<TItem extends Record<string, any>> {\n /** Read the live list (the editor's v-model, or a consumer store getter). */\n get: () => TItem[]\n /** Write the list back. */\n set: (items: TItem[]) => void\n /** New-row factory. Optional for read-only / no-add lists. Should mint a stable temp id. */\n factory?: () => TItem\n /** Stable row identity. Default `'id'`. Never point this at the position field. */\n getKey?: GetKey<TItem>\n /** Managed order field. Default `'position'`. `false` opts out of position management. */\n position?: PositionOption<TItem>\n /**\n * Extra top-level fields to drop from the dirty content-hash (position is\n * always dropped). For a child collection a separate nested editor already\n * tracks, so editing a child doesn't flip the parent row amber. Still in the\n * payload — only the dirty comparison ignores it. Reactive (accepts a getter/ref).\n */\n dirtyExclude?: MaybeRefOrGetter<string[]>\n /** Per-row validity — `true` = valid. Drives the red rail + `hasErrors`. */\n validate?: (item: TItem) => ListEditorValidationResult\n /** Custom dirty predicate (override the default content-diff). */\n isDirty?: (current: TItem, saved: TItem | undefined) => boolean\n /** Custom save payload (overrides `getPayload`). */\n payload?: (items: TItem[]) => TItem[]\n /** Resolve a saved row's key on commit (default: existing key, else mint a temp id). */\n commitKey?: (saved: TItem, previous: TItem | undefined) => ListEditorKey\n /** Normalize server rows before they become the new baseline on commit. */\n normalizeSaved?: (savedItems: TItem[]) => TItem[]\n}\n\nexport interface ListEditorHandle<TItem extends Record<string, any>> {\n items: ComputedRef<TItem[]>\n hasUnsaved: ComputedRef<boolean>\n /** Count of distinct unconfirmed changes (added/edited/moved rows + deferred-deletion tombstones). */\n unsavedCount: ComputedRef<number>\n hasErrors: ComputedRef<boolean>\n invalidKeys: ComputedRef<Set<ListEditorKey>>\n /** Amber: is this row added / edited / moved since the last commit? */\n isUnsaved: (key: ListEditorKey) => boolean\n /** Red rail (gated): 'invalid' only once the row is unsaved or `validateAll()` ran. */\n rowState: (item: TItem, key: ListEditorKey, editing?: boolean) => ListEditorValidationState\n /** Force-show all invalid rows + return whether the list is valid. The save guard. */\n validateAll: () => boolean\n /** Normalized ordered array for a full-DTO save. */\n getPayload: () => TItem[]\n /** Change-set for partial-save endpoints. */\n getChanges: () => ListEditorChanges<TItem>\n /** Adopt saved rows as the new baseline; backfill keys; clear unsaved/submitted. */\n commit: (savedItems?: TItem[]) => void\n /** Discard unsaved edits back to the last committed baseline (or given items). */\n reset: (items?: TItem[]) => void\n addItem: (item?: TItem, hint?: PositionHint) => ListEditorKey | undefined\n updateItem: (key: ListEditorKey, next: TItem | Partial<TItem> | ((current: TItem) => TItem)) => void\n /** Remove a row. `trackDeleted: false` (immediate mode) skips the deferred-deletion tombstone. */\n deleteItem: (key: ListEditorKey, opts?: { trackDeleted?: boolean }) => void\n /** Clear a deferred-deletion tombstone (the caller re-inserts the row, e.g. reorder Cancel). */\n restoreDeleted: (key: ListEditorKey) => void\n moveItem: (fromIndex: number, toIndex: number) => void\n /** Drop the \"moved\" flag for the given keys (or all) without touching edits/adds — e.g. reorder Cancel. */\n clearMoved: (keys?: Iterable<ListEditorKey>) => void\n /** Escape hatch: a row form (e.g. vuelidate) reports its own validity instead of `validate`. */\n registerValidity: (key: ListEditorKey, isValid: () => boolean) => () => void\n}\n\n/**\n * The shape a CONSUMER sees when it reads a list-editor handle through a template/function ref.\n * Vue's `expose` proxy unwraps every exposed ref, so the reactive fields (`hasUnsaved`, `hasErrors`,\n * `unsavedCount`, …) arrive as plain VALUES here, not `Ref`s: read `handle.hasUnsaved` (a boolean),\n * never `handle.hasUnsaved.value` (that is `undefined`). Type your `useTemplateRef` / collected-ref\n * maps with this so a stray `.value` is a compile error instead of a silently-dead guard/save-gate.\n */\nexport type ExposedListEditorHandle<TItem extends Record<string, any>> = ShallowUnwrapRef<ListEditorHandle<TItem>>\n\n/**\n * State controller for the list editors, exposed as a `ListEditorHandle`. Owns row keys, declared dirty\n * tracking (no whole-list JSON diff), validation summary, position renumbering and the save lifecycle.\n * An editor creates it by default. A consumer can create it and\n * pass it as `:editor` so state survives unmount and remount.\n */\nexport function useListEditorController<TItem extends Record<string, any>>(\n options: UseListEditorControllerOptions<TItem>\n): ListEditorHandle<TItem> {\n const keyField = (typeof options.getKey === 'function' ? null : (options.getKey ?? 'id')) as keyof TItem | null\n const keyOf = (item: TItem): ListEditorKey =>\n typeof options.getKey === 'function' ? options.getKey(item) : (item[keyField as keyof TItem] as ListEditorKey)\n\n const positionOpt = options.position ?? 'position'\n const managedPosition = positionOpt !== false\n const positionField = (\n typeof positionOpt === 'object' ? positionOpt.field : positionOpt === false ? 'position' : positionOpt\n ) as string\n const positionMultiplier = typeof positionOpt === 'object' && positionOpt.multiplier ? positionOpt.multiplier : 1\n const positionStrategy: PositionStrategy = (typeof positionOpt === 'object' && positionOpt.strategy) || 'renumber'\n const positionOverrides: Partial<Record<PositionAction, PositionStrategy>> =\n (typeof positionOpt === 'object' && positionOpt.strategyOverrides) || {}\n\n const items = computed<TItem[]>(() => options.get())\n\n // Baseline = last committed snapshot. `hashes` powers content-diff dirty\n // (position excluded so a reorder never marks a row dirty); `rows` powers `reset`.\n const dirtyExclude = computed<string[]>(() => toValue(options.dirtyExclude) ?? [])\n // Temp ids are client identity bookkeeping, never content. `ensureKeys` mints one INTO the model\n // for rows the server returns without a key — and for a NESTED editor that write happens on mount,\n // i.e. when a parent row is merely expanded to be read. The parent hashes the whole row, so without\n // this the seed would retroactively invalidate the parent's baseline and expanding a row to LOOK at\n // it would mark it unsaved (QA 85050 batch 10 BUG-02). Only negative NUMBERS are stripped —\n // persisted ids are positive (see `nextListEditorTempId`), so real ids still count as content, and\n // a genuinely added row still differs by its other fields.\n const stripTempIds = (_k: string, v: unknown): unknown =>\n _k === 'id' && typeof v === 'number' && v < 0 ? undefined : v\n const normalize = (item: TItem): string => {\n const copy = { ...item } as Record<string, unknown>\n if (managedPosition) delete copy[positionField]\n for (const f of dirtyExclude.value) delete copy[f]\n return JSON.stringify(copy, stripTempIds)\n }\n const baselineHashes = ref(new Map<ListEditorKey, string>()) as Ref<Map<ListEditorKey, string>>\n const baselineRows = ref<TItem[]>([]) as Ref<TItem[]>\n const captureBaseline = (rows: TItem[]) => {\n const map = new Map<ListEditorKey, string>()\n for (const r of rows) map.set(keyOf(r), normalize(r))\n baselineHashes.value = map\n // Deep clone: a shallow `{...r}` shares nested refs with the live row, so an\n // in-place mutation would drift the baseline (reset/re-hash read stale data).\n baselineRows.value = rows.map((r) => cloneDeep(r))\n }\n // Re-hash when the excluded-field set changes. `sync` so baseline + live\n // normalize() never disagree mid-flush (which would flash every row amber).\n watch(\n dirtyExclude,\n () => {\n const map = new Map<ListEditorKey, string>()\n for (const r of baselineRows.value) map.set(keyOf(r), normalize(r))\n baselineHashes.value = map\n },\n { flush: 'sync' }\n )\n // Ensure every row has a resolvable, UNIQUE key before the first baseline\n // capture. Server rows lacking the key field (e.g. no `id` and no custom\n // get-key → keyOf() is undefined for ALL of them) would collapse to a single\n // baseline entry and read as perpetually unsaved even on a clean load\n // (QA 85050 BUG-03). Mint a temp id for those rows — exactly what commit()\n // already does on save (line ~299). Rows that DO resolve a key (the common\n // case) are untouched, so id-backed editors are unaffected.\n const ensureKeys = (rows: TItem[]): { rows: TItem[]; changed: boolean } => {\n if (!keyField) return { rows, changed: false }\n let changed = false\n const next = rows.map((item) => {\n const k = keyOf(item)\n if (k === undefined || k === null) {\n changed = true\n return { ...item, [keyField]: nextListEditorTempId() } as TItem\n }\n return item\n })\n return { rows: next, changed }\n }\n const seeded = ensureKeys(options.get())\n if (seeded.changed) options.set(seeded.rows)\n // Capture from the seeded array directly (not a re-read of options.get()): when\n // set() emits through v-model the prop update is async, so options.get() would\n // still return the pre-mint colliding rows here. Mirrors commit()'s pattern.\n captureBaseline(seeded.rows)\n\n // Declared structural state the content-diff can't see.\n const movedKeys = ref(new Set<ListEditorKey>()) as Ref<Set<ListEditorKey>>\n const deletedRows = ref<TItem[]>([]) as Ref<TItem[]>\n const submitted = ref(false)\n // Reactive so a row form (re)registering its validity re-runs `invalidKeys`/`rowState`.\n const registeredValidity = reactive(new Map<ListEditorKey, () => boolean>())\n\n const isItemDirty = (item: TItem, key: ListEditorKey): boolean => {\n if (options.isDirty) {\n const saved = baselineRows.value.find((r) => keyOf(r) === key)\n return options.isDirty(item, saved)\n }\n const baseHash = baselineHashes.value.get(key)\n if (baseHash === undefined) return true // added\n if (baseHash !== normalize(item)) return true // edited\n return movedKeys.value.has(key) // moved (content-invisible)\n }\n\n // Gate the validation rail on \"has this row actually been edited\" rather than just \"is it\n // unsaved\", so a freshly added still-untouched row is amber but not yet red. `addedBaseline` =\n // first-seen content hash of each ADDED row; `editedKeys` = STICKY set of rows whose content has\n // since diverged from that first-seen / committed baseline. Sticky like vuelidate `$dirty`: once\n // edited a row stays dirty until commit/reset, so clearing a field back to empty keeps the rail\n // consistent with the field's own error state. Position / `dirtyExclude` are normalized out, so a\n // reorder never counts as an edit.\n const addedBaseline = ref(new Map<ListEditorKey, string>()) as Ref<Map<ListEditorKey, string>>\n const editedKeys = ref(new Set<ListEditorKey>()) as Ref<Set<ListEditorKey>>\n watch(\n items,\n (rows) => {\n const live = new Set<ListEditorKey>()\n for (const r of rows) {\n const key = keyOf(r)\n live.add(key)\n if (!baselineHashes.value.has(key) && !addedBaseline.value.has(key)) {\n addedBaseline.value.set(key, normalize(r))\n }\n if (!editedKeys.value.has(key)) {\n const base = baselineHashes.value.get(key) ?? addedBaseline.value.get(key)\n if (base !== undefined && base !== normalize(r)) editedKeys.value.add(key)\n }\n }\n const stale: ListEditorKey[] = []\n for (const key of addedBaseline.value.keys()) if (!live.has(key)) stale.push(key)\n for (const key of stale) addedBaseline.value.delete(key)\n // A deferred-deleted key that becomes live again (re-add before save) must drop its tombstone —\n // otherwise it would both render and still count/report as deleted.\n if (deletedRows.value.some((r) => live.has(keyOf(r)))) {\n deletedRows.value = deletedRows.value.filter((r) => !live.has(keyOf(r)))\n }\n },\n { immediate: true, deep: true }\n )\n\n const isRowEdited = (key: ListEditorKey): boolean => editedKeys.value.has(key)\n\n const unsavedKeys = computed<Set<ListEditorKey>>(() => {\n const out = new Set<ListEditorKey>()\n for (const item of options.get()) {\n const key = keyOf(item)\n if (isItemDirty(item, key)) out.add(key)\n }\n return out\n })\n\n const isUnsaved = (key: ListEditorKey): boolean => unsavedKeys.value.has(key)\n const hasUnsaved = computed<boolean>(() => unsavedKeys.value.size > 0 || deletedRows.value.length > 0)\n\n // Count of DISTINCT unconfirmed changes = union of live dirty keys (added / edited / moved) and\n // deferred-deletion tombstones. A key that is both live and tombstoned (delete-then-re-add) counts\n // once; a deleted row (no longer live) adds one. Drives the \"N unconfirmed changes\" indicator, so a\n // delete lights up as a change even though the row itself is gone.\n const unsavedCount = computed<number>(() => {\n const keys = new Set<ListEditorKey>(unsavedKeys.value)\n for (const r of deletedRows.value) keys.add(keyOf(r))\n return keys.size\n })\n\n const resolveValidity = (item: TItem, key: ListEditorKey): { invalid: boolean; warning: boolean } => {\n const registered = registeredValidity.get(key)\n if (registered) return { invalid: !registered(), warning: false }\n if (!options.validate) return { invalid: false, warning: false }\n const r = options.validate(item)\n if (typeof r === 'boolean') return { invalid: !r, warning: false }\n return { invalid: !r.valid, warning: r.valid && r.state === 'warning' }\n }\n\n const invalidKeys = computed<Set<ListEditorKey>>(() => {\n const out = new Set<ListEditorKey>()\n for (const item of options.get()) {\n const key = keyOf(item)\n if (resolveValidity(item, key).invalid) out.add(key)\n }\n return out\n })\n const hasErrors = computed<boolean>(() => invalidKeys.value.size > 0)\n\n // Red rail gated behind \"row has been edited\" (content changed since add/baseline — mirrors the\n // field's vuelidate `$dirty`) or an explicit validateAll() — so a freshly added still-untouched\n // row stays amber (not red) and a loaded-but-invalid row doesn't light up before interaction,\n // while a save attempt reveals every offender (mounted or collapsed).\n const rowState = (item: TItem, key: ListEditorKey, editing = false): ListEditorValidationState => {\n const { invalid, warning } = resolveValidity(item, key)\n // Red rail for an invalid row that is edited, unsaved (added), or after a save attempt. A row being\n // filled in reads amber (not red) and goes red once collapsed — but a save attempt (`submitted`,\n // which also reveals collapsed offenders) always reds it, even while open. (QA 85050 batch 7)\n if (invalid) {\n if (submitted.value) return 'invalid'\n if (editing) return null\n return isRowEdited(key) || isUnsaved(key) ? 'invalid' : null\n }\n if (warning) return 'warning'\n return null\n }\n\n const validateAll = (): boolean => {\n submitted.value = true\n return invalidKeys.value.size === 0\n }\n\n // Resolve the policy for THIS action: a per-action override wins, else the base strategy.\n // Under 'preserve-values' only a move reassigns (through the existing kept slots); every other\n // action leaves positions as-is (add keeps the handed value, delete leaves a hole, update/payload\n // never touch them). Under 'renumber' every action rewrites to a clean `(index+1)*multiplier`.\n const renumber = (arr: TItem[], action: PositionAction): TItem[] => {\n if (!managedPosition) return arr\n const strategy = positionOverrides[action] ?? positionStrategy\n if (strategy === 'preserve-values') {\n return action === 'move' ? preservePositionValues(arr, { positionField }) : arr\n }\n return renumberPositions(arr, { positionField, positionMultiplier })\n }\n\n const write = (arr: TItem[], action: PositionAction) => options.set(renumber(arr, action))\n\n const getPayload = (): TItem[] =>\n options.payload ? options.payload(options.get()) : renumber(options.get(), 'payload')\n\n const getChanges = (): ListEditorChanges<TItem> => {\n const added: TItem[] = []\n const updated: TItem[] = []\n const moved: TItem[] = []\n for (const item of options.get()) {\n const key = keyOf(item)\n const baseHash = baselineHashes.value.get(key)\n if (baseHash === undefined) added.push(item)\n else if (baseHash !== normalize(item)) updated.push(item)\n if (movedKeys.value.has(key)) moved.push(item)\n }\n return { added, updated, moved, deleted: [...deletedRows.value], reparented: [] }\n }\n\n const commit = (savedItems?: TItem[]): void => {\n const source = savedItems ?? options.get()\n const normalized = options.normalizeSaved ? options.normalizeSaved(source) : source\n const next = normalized.map((item) => {\n const key = options.commitKey\n ? options.commitKey(\n item,\n baselineRows.value.find((r) => keyOf(r) === keyOf(item))\n )\n : keyOf(item)\n if (key === undefined || key === null) {\n return keyField ? ({ ...item, [keyField]: nextListEditorTempId() } as TItem) : item\n }\n return item\n })\n options.set(next)\n captureBaseline(next)\n movedKeys.value = new Set()\n deletedRows.value = []\n addedBaseline.value = new Map()\n editedKeys.value = new Set()\n submitted.value = false\n }\n\n const reset = (rows?: TItem[]): void => {\n options.set(rows ?? baselineRows.value.map((r) => cloneDeep(r)))\n movedKeys.value = new Set()\n deletedRows.value = []\n addedBaseline.value = new Map()\n editedKeys.value = new Set()\n submitted.value = false\n }\n\n const indexOfKey = (arr: TItem[], key: ListEditorKey): number => arr.findIndex((x) => keyOf(x) === key)\n\n const addItem = (item?: TItem, hint?: PositionHint): ListEditorKey | undefined => {\n const row = item ?? options.factory?.()\n if (row === undefined) return undefined // no item + no factory (read-only list) → no-op\n const arr = [...options.get()]\n let at = arr.length\n if (hint?.afterId !== undefined) {\n const i = indexOfKey(arr, hint.afterId)\n at = i === -1 ? arr.length : i + 1\n } else if (hint?.index !== undefined) {\n at = Math.max(0, Math.min(hint.index, arr.length))\n }\n arr.splice(at, 0, row)\n write(arr, 'add')\n return keyOf(row)\n }\n\n const updateItem = (key: ListEditorKey, next: TItem | Partial<TItem> | ((current: TItem) => TItem)): void => {\n const arr = [...options.get()]\n const i = indexOfKey(arr, key)\n if (i === -1) return\n const current = arr[i]!\n const resolved =\n typeof next === 'function'\n ? (next as (c: TItem) => TItem)(current)\n : ({ ...current, ...(next as Partial<TItem>) } as TItem)\n arr[i] = resolved\n write(arr, 'update')\n }\n\n const deleteItem = (key: ListEditorKey, opts?: { trackDeleted?: boolean }): void => {\n const arr = [...options.get()]\n const i = indexOfKey(arr, key)\n if (i === -1) return\n const removed = arr.splice(i, 1)[0]!\n // A previously-saved row that's removed is a DEFERRED deletion: reported in the change-set and\n // counted as one unconfirmed change (`unsavedCount`) until save. `trackDeleted: false` (immediate\n // mode — the row is already deleted on the backend) skips the tombstone so it does NOT read as\n // unsaved. An unsaved temp row just vanishes either way.\n if (baselineHashes.value.has(key) && opts?.trackDeleted !== false) {\n deletedRows.value = [...deletedRows.value, removed]\n } else if (baselineHashes.value.has(key)) {\n // Deleted on the backend: no longer part of the saved rows `reset()` returns to.\n const hashes = new Map(baselineHashes.value)\n hashes.delete(key)\n baselineHashes.value = hashes\n baselineRows.value = baselineRows.value.filter((r) => keyOf(r) !== key)\n }\n movedKeys.value.delete(key)\n write(arr, 'remove')\n }\n\n // Un-tombstone a deferred-deleted row. Re-inserting the row into the model is the caller's job\n // (e.g. reorder Cancel restoring the pre-session snapshot); this only clears the deletion record so\n // `deletedRows` / `unsavedCount` / `getChanges().deleted` stay consistent.\n const restoreDeleted = (key: ListEditorKey): void => {\n deletedRows.value = deletedRows.value.filter((r) => keyOf(r) !== key)\n }\n\n const moveItem = (fromIndex: number, toIndex: number): void => {\n const arr = [...options.get()]\n if (fromIndex < 0 || fromIndex >= arr.length || toIndex < 0 || toIndex >= arr.length) return\n if (fromIndex === toIndex) return\n const el = arr.splice(fromIndex, 1)[0]!\n arr.splice(toIndex, 0, el)\n movedKeys.value.add(keyOf(el))\n write(arr, 'move')\n }\n\n // Reorder Cancel restores the pre-session order, so the moves are undone — drop\n // just those keys' \"moved\" flag (edits/adds stay dirty). No arg = clear all.\n const clearMoved = (keys?: Iterable<ListEditorKey>): void => {\n if (keys === undefined) {\n movedKeys.value = new Set()\n return\n }\n const next = new Set(movedKeys.value)\n for (const key of keys) next.delete(key)\n movedKeys.value = next\n }\n\n const registerValidity = (key: ListEditorKey, isValid: () => boolean): (() => void) => {\n registeredValidity.set(key, isValid)\n return () => registeredValidity.delete(key)\n }\n\n return {\n items,\n hasUnsaved,\n unsavedCount,\n hasErrors,\n invalidKeys,\n isUnsaved,\n rowState,\n validateAll,\n getPayload,\n getChanges,\n commit,\n reset,\n addItem,\n updateItem,\n deleteItem,\n restoreDeleted,\n moveItem,\n clearMoved,\n registerValidity,\n }\n}\n"],"mappings":"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"}
@@ -29,7 +29,7 @@ export interface UseNestedListEditorOptions {
29
29
  positionMultiplier?: number;
30
30
  /** `false` = the position field is not managed: tree ops never write it. */
31
31
  managedPosition?: boolean;
32
- /** Per-action policy (mirrors the flat controller); default 'renumber'. */
32
+ /** Per-action policy, as in the flat controller. Default 'renumber'. */
33
33
  positionStrategyFor?: (action: 'add' | 'remove' | 'move') => 'renumber' | 'preserve-values';
34
34
  maxDepth: number;
35
35
  expandedKeys?: Ref<Set<ListEditorKey>>;
@@ -60,8 +60,7 @@ export interface NestedListEditorApi<TItem extends Record<string, any>> {
60
60
  calculateSubtreeDepth: (node: NestedTreeNode<TItem>) => number;
61
61
  }
62
62
  /**
63
- * Nested list editor core. Pure data behavior shared by ANestedSortableListEditor.
64
- * Works on a tree of `{ data, children, meta }` nodes. Mutators return a cloned tree and also
65
- * assign it to `model.value`.
63
+ * Nested list editor core for `ANestedSortableListEditor`. Works on a tree of `{ data, children, meta }` nodes.
64
+ * Mutators return a cloned tree and also assign it to `model.value`.
66
65
  */
67
66
  export declare function useNestedListEditor<TItem extends Record<string, any>>(model: Ref<NestedTree<TItem>>, options: UseNestedListEditorOptions): NestedListEditorApi<TItem>;
@@ -1 +1 @@
1
- {"version":3,"file":"useNestedListEditor.js","names":["DEFAULT_KEY_FIELD","DEFAULT_POSITION_FIELD","DEFAULT_PARENT_FIELD","useNestedListEditor","keyField","options","resolveKey","positionField","parentField","positionMultiplier","maxDepth","getKey","data","calculateSubtreeDepth","node","max","child","d","findNode","model","item","arr","id","found","recalculateSiblings","action","values","siblings","s","v","slots","a","b","sibling","i","pos","recalculateAll","walk","tree","recalculatePositions","cloned","cloneDeep","buildViewItems","flat","expandedKeys","flatIndex","nodes","key","childrenAllowed","isUndefined","hasChildren","childrenCount","isExpanded","remainingDepth","depth","canAddChild","canOutdent","canIndent","parentNode","viewItems","computed","insertAfter","afterIdx","newNode","resolveInsertIndex","hint","idx","addItem","targetSiblings","afterNode","afterParent","insertIdx","deleteItem","parent","opts","updateItem","markDirty","swapSiblings","target","getTargetIndex","removed","moveUp","res","moveDown","moveTop","moveBottom","indent","prev","subtreeDepth","calculateParentDepth","outdent","grandParent","grandSiblings","parentIdx","currentSiblings","targetParentId","isDescendant","n","c","newParentNode","newParentDepth","targetParent","sourceSiblings","sourceIdx","samelist","insertAt","targetIndex"],"sources":["../../../../src/domains/listEditor/composables/useNestedListEditor.ts"],"sourcesContent":["import { computed, type ComputedRef, type Ref } from 'vue'\nimport { cloneDeep, isUndefined } from '@/shared/utils/common'\nimport type {\n ListEditorKey,\n ListViewItem,\n NestedTree,\n NestedTreeNode,\n PositionHint,\n} from '@/domains/listEditor/types/listEditorTypes'\n\nexport interface NestedViewItem<TItem> extends ListViewItem<TItem> {\n node: NestedTreeNode<TItem>\n depth: number\n parent: TItem | null\n parentKey: ListEditorKey | null\n childrenCount: number\n hasChildren: boolean\n childrenAllowed: boolean\n siblingIndex: number\n siblingCount: number\n firstInParent: boolean\n lastInParent: boolean\n canAddChild: boolean\n canIndent: boolean\n canOutdent: boolean\n}\n\nexport interface UseNestedListEditorOptions {\n keyField?: string\n /**\n * Resolve a row's key; takes precedence over `keyField`. Pass the controller's\n * `keyOf` so tree ops key rows the same way as dirty/validity tracking — incl.\n * a FUNCTION get-key, which `keyField` lookup would miss.\n */\n getKey?: (data: any) => ListEditorKey\n positionField?: string\n parentField?: string\n positionMultiplier?: number\n /** `false` = the position field is not managed: tree ops never write it. */\n managedPosition?: boolean\n /** Per-action policy (mirrors the flat controller); default 'renumber'. */\n positionStrategyFor?: (action: 'add' | 'remove' | 'move') => 'renumber' | 'preserve-values'\n maxDepth: number\n expandedKeys?: Ref<Set<ListEditorKey>>\n}\n\nexport interface NestedListEditorApi<TItem extends Record<string, any>> {\n viewItems: ComputedRef<NestedViewItem<TItem>[]>\n findNode: (id: ListEditorKey) => {\n node: NestedTreeNode<TItem> | null\n parent: NestedTreeNode<TItem> | null\n }\n addItem: (\n data: TItem,\n hint?: PositionHint & {\n parentId?: ListEditorKey | null\n asFirstChild?: boolean\n childrenAllowed?: boolean\n }\n ) => NestedTree<TItem>\n deleteItem: (id: ListEditorKey, opts?: { renumber?: boolean }) => NestedTree<TItem>\n updateItem: (id: ListEditorKey, data: TItem, markDirty?: boolean) => NestedTree<TItem>\n moveUp: (id: ListEditorKey) => NestedTree<TItem> | null\n moveDown: (id: ListEditorKey) => NestedTree<TItem> | null\n moveTop: (id: ListEditorKey) => NestedTree<TItem> | null\n moveBottom: (id: ListEditorKey) => NestedTree<TItem> | null\n indent: (id: ListEditorKey) => NestedTree<TItem> | null\n outdent: (id: ListEditorKey) => NestedTree<TItem> | null\n moveTo: (id: ListEditorKey, targetParentId: ListEditorKey | null, targetIndex: number) => NestedTree<TItem> | null\n recalculatePositions: (model: NestedTree<TItem>) => NestedTree<TItem>\n calculateSubtreeDepth: (node: NestedTreeNode<TItem>) => number\n}\n\nconst DEFAULT_KEY_FIELD = 'id'\nconst DEFAULT_POSITION_FIELD = 'position'\nconst DEFAULT_PARENT_FIELD = 'parent'\n\n/**\n * Nested list editor core. Pure data behavior shared by ANestedSortableListEditor.\n * Works on a tree of `{ data, children, meta }` nodes. Mutators return a cloned tree and also\n * assign it to `model.value`.\n */\nexport function useNestedListEditor<TItem extends Record<string, any>>(\n model: Ref<NestedTree<TItem>>,\n options: UseNestedListEditorOptions\n): NestedListEditorApi<TItem> {\n const keyField = options.keyField ?? DEFAULT_KEY_FIELD\n const resolveKey = options.getKey\n const positionField = options.positionField ?? DEFAULT_POSITION_FIELD\n const parentField = options.parentField ?? DEFAULT_PARENT_FIELD\n const positionMultiplier = options.positionMultiplier ?? 1\n const maxDepth = options.maxDepth\n\n const getKey = (data: TItem): ListEditorKey => (resolveKey ? resolveKey(data) : (data[keyField] as ListEditorKey))\n\n const calculateSubtreeDepth = (node: NestedTreeNode<TItem>): number => {\n if (!node.children || node.children.length === 0) return 1\n let max = 0\n for (const child of node.children) {\n const d = calculateSubtreeDepth(child)\n if (d > max) max = d\n }\n return max + 1\n }\n\n const findNode = (\n id: ListEditorKey,\n arr: NestedTreeNode<TItem>[] = model.value.children,\n parent: NestedTreeNode<TItem> | null = null\n ): { node: NestedTreeNode<TItem> | null; parent: NestedTreeNode<TItem> | null } => {\n for (const item of arr) {\n if (getKey(item.data) === id) return { node: item, parent }\n if (item.children && item.children.length > 0) {\n const found = findNode(id, item.children, item)\n if (found.node) return found\n }\n }\n return { node: null, parent: null }\n }\n\n const recalculateSiblings = (siblings: NestedTreeNode<TItem>[], action: 'add' | 'remove' | 'move' = 'move') => {\n if (options.managedPosition === false) return\n const strategy = options.positionStrategyFor?.(action) ?? 'renumber'\n if (strategy === 'preserve-values') {\n if (action !== 'move') return\n const values = siblings.map((s) => s.data[positionField])\n // As in the flat editor: without a finite number on every row there is no slot set to move\n // through, and inventing one would write a wrong payload.\n if (!values.every((v) => typeof v === 'number' && Number.isFinite(v))) {\n console.warn(\n `[listEditor] position strategy \"preserve-values\" needs a finite numeric \\`${positionField}\\` ` +\n 'on every row; found ' +\n JSON.stringify(values) +\n ' — leaving positions untouched.'\n )\n return\n }\n const slots = (values as number[]).slice().sort((a, b) => a - b)\n siblings.forEach((sibling, i) => {\n if (sibling.data[positionField] !== slots[i]) {\n ;(sibling.data as any)[positionField] = slots[i]\n sibling.meta.dirty = true\n }\n })\n return\n }\n let pos = 1 * positionMultiplier\n for (const sibling of siblings) {\n if (sibling.data[positionField] !== pos) {\n ;(sibling.data as any)[positionField] = pos\n // Flag dirty so a partial-subset save persists the new position;\n // otherwise reorders are lost on reload and rows collide on old positions.\n sibling.meta.dirty = true\n }\n pos += positionMultiplier\n }\n }\n\n const recalculateAll = (tree: NestedTree<TItem>) => {\n const walk = (arr: NestedTreeNode<TItem>[]) => {\n recalculateSiblings(arr)\n for (const item of arr) if (item.children && item.children.length) walk(item.children)\n }\n walk(tree.children)\n }\n\n const recalculatePositions = (tree: NestedTree<TItem>): NestedTree<TItem> => {\n const cloned = cloneDeep(tree) as NestedTree<TItem>\n recalculateAll(cloned)\n return cloned\n }\n\n const buildViewItems = (tree: NestedTree<TItem>): NestedViewItem<TItem>[] => {\n const flat: NestedViewItem<TItem>[] = []\n const expandedKeys = options.expandedKeys?.value\n let flatIndex = 0\n const walk = (nodes: NestedTreeNode<TItem>[], depth: number, parentNode: NestedTreeNode<TItem> | null) => {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]!\n const key = getKey(node.data)\n const childrenAllowed = !isUndefined(node.children)\n const hasChildren = childrenAllowed && (node.children?.length ?? 0) > 0\n const childrenCount = node.children?.length ?? 0\n const isExpanded = expandedKeys ? expandedKeys.has(key) : true\n const remainingDepth = maxDepth - (depth + 1)\n const canAddChild = childrenAllowed && remainingDepth > 0\n const canOutdent = depth > 0\n const canIndent = i > 0\n flat.push({\n key,\n index: flatIndex++,\n raw: node.data,\n position: node.data[positionField] as number | undefined,\n node,\n depth,\n parent: parentNode?.data ?? null,\n parentKey: parentNode ? getKey(parentNode.data) : null,\n childrenCount,\n hasChildren,\n childrenAllowed,\n siblingIndex: i,\n siblingCount: nodes.length,\n firstInParent: i === 0,\n lastInParent: i === nodes.length - 1,\n canAddChild,\n canIndent,\n canOutdent,\n })\n if (hasChildren && isExpanded) {\n walk(node.children as NestedTreeNode<TItem>[], depth + 1, node)\n }\n }\n }\n walk(tree.children, 0, null)\n return flat\n }\n\n const viewItems = computed<NestedViewItem<TItem>[]>(() => buildViewItems(model.value))\n\n const insertAfter = (siblings: NestedTreeNode<TItem>[], afterIdx: number, newNode: NestedTreeNode<TItem>) => {\n siblings.splice(afterIdx + 1, 0, newNode)\n }\n\n const resolveInsertIndex = (siblings: NestedTreeNode<TItem>[], hint?: PositionHint): number => {\n if (!hint) return siblings.length\n if (hint.afterId !== undefined) {\n const idx = siblings.findIndex((s) => getKey(s.data) === hint.afterId)\n return idx === -1 ? siblings.length : idx + 1\n }\n if (hint.afterIndex !== undefined) {\n if (hint.afterIndex < 0) return siblings.length\n return Math.min(hint.afterIndex + 1, siblings.length)\n }\n if (hint.index !== undefined) {\n return Math.max(0, Math.min(hint.index, siblings.length))\n }\n return siblings.length\n }\n\n const addItem = (\n data: TItem,\n hint?: PositionHint & {\n parentId?: ListEditorKey | null\n asFirstChild?: boolean\n childrenAllowed?: boolean\n }\n ): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const childrenAllowed = hint?.childrenAllowed ?? true\n const newNode: NestedTreeNode<TItem> = {\n data: cloneDeep(data) as TItem,\n children: childrenAllowed ? [] : undefined,\n meta: { dirty: false },\n }\n\n let targetSiblings: NestedTreeNode<TItem>[] = cloned.children\n let parentNode: NestedTreeNode<TItem> | null = null\n\n if (hint?.parentId !== undefined && hint.parentId !== null) {\n const { node } = findNode(hint.parentId, cloned.children)\n if (node && node.children) {\n targetSiblings = node.children\n parentNode = node\n }\n }\n\n if (hint?.afterId !== undefined) {\n const { node: afterNode, parent: afterParent } = findNode(hint.afterId, cloned.children)\n if (afterNode) {\n const siblings = afterParent ? (afterParent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(afterNode)\n if (idx !== -1) {\n insertAfter(siblings, idx, newNode)\n ;(newNode.data as any)[parentField] = afterParent ? getKey(afterParent.data) : null\n recalculateSiblings(siblings, 'add')\n model.value = cloned\n return cloned\n }\n }\n }\n\n const insertIdx = hint?.asFirstChild ? 0 : resolveInsertIndex(targetSiblings, hint)\n targetSiblings.splice(insertIdx, 0, newNode)\n ;(newNode.data as any)[parentField] = parentNode ? getKey(parentNode.data) : null\n recalculateSiblings(targetSiblings, 'add')\n model.value = cloned\n return cloned\n }\n\n // `renumber: false` leaves the siblings' positions as they are: a row already deleted on the backend,\n // which does not renumber either, so the gap the server has stays in the editor too.\n const deleteItem = (id: ListEditorKey, opts?: { renumber?: boolean }): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return cloned\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx === -1) return cloned\n siblings.splice(idx, 1)\n if (opts?.renumber !== false) recalculateSiblings(siblings, 'remove')\n model.value = cloned\n return cloned\n }\n\n const updateItem = (id: ListEditorKey, data: TItem, markDirty = true): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node } = findNode(id, cloned.children)\n if (!node) return cloned\n node.data = cloneDeep(data) as TItem\n // An edit must be persisted by partial-subset saves. `markDirty=false` is for\n // snapshot restore on edit-cancel, which must NOT flag the node dirty.\n if (markDirty) node.meta.dirty = true\n model.value = cloned\n return cloned\n }\n\n const swapSiblings = (\n cloned: NestedTree<TItem>,\n id: ListEditorKey,\n getTargetIndex: (siblings: NestedTreeNode<TItem>[], currentIdx: number) => number | null\n ): NestedTree<TItem> | null => {\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx === -1) return null\n const target = getTargetIndex(siblings, idx)\n if (target === null || target === idx) return null\n const removed = siblings.splice(idx, 1)[0]!\n siblings.splice(target, 0, removed)\n if (options.managedPosition === false) removed.meta.dirty = true\n recalculateSiblings(siblings)\n return cloned\n }\n\n const moveUp = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (_s, idx) => (idx > 0 ? idx - 1 : null))\n if (res) model.value = res\n return res\n }\n\n const moveDown = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (s, idx) => (idx < s.length - 1 ? idx + 1 : null))\n if (res) model.value = res\n return res\n }\n\n const moveTop = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (_s, idx) => (idx > 0 ? 0 : null))\n if (res) model.value = res\n return res\n }\n\n const moveBottom = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (s, idx) => (idx < s.length - 1 ? s.length - 1 : null))\n if (res) model.value = res\n return res\n }\n\n /**\n * Indent: move the item under its previous sibling as its last child.\n * Fails if: no previous sibling, previous sibling doesn't allow children,\n * or the resulting depth would exceed maxDepth.\n */\n const indent = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx <= 0) return null\n const prev = siblings[idx - 1]!\n if (isUndefined(prev.children)) return null\n const subtreeDepth = calculateSubtreeDepth(node)\n const prevDepth = calculateParentDepth(cloned, getKey(prev.data))\n if (prevDepth + 1 + subtreeDepth > maxDepth) return null\n\n siblings.splice(idx, 1)\n prev.children!.push(node)\n ;(node.data as any)[parentField] = getKey(prev.data)\n // Persist the reparent even when the position number is unchanged (QA 85050 BUG-13).\n node.meta.dirty = true\n recalculateSiblings(siblings)\n recalculateSiblings(prev.children!)\n model.value = cloned\n return cloned\n }\n\n /**\n * Outdent: move the item up one level — it becomes the next sibling of its current parent.\n * Fails if the item is already at root.\n */\n const outdent = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node || !parent) return null\n\n const { parent: grandParent } = findNode(getKey(parent.data), cloned.children)\n const grandSiblings = grandParent ? (grandParent.children as NestedTreeNode<TItem>[]) : cloned.children\n const parentIdx = grandSiblings.indexOf(parent)\n if (parentIdx === -1) return null\n\n const currentSiblings = parent.children as NestedTreeNode<TItem>[]\n const idx = currentSiblings.indexOf(node)\n if (idx === -1) return null\n currentSiblings.splice(idx, 1)\n grandSiblings.splice(parentIdx + 1, 0, node)\n ;(node.data as any)[parentField] = grandParent ? getKey(grandParent.data) : null\n // Persist the reparent even when the position number is unchanged (QA 85050 BUG-13).\n node.meta.dirty = true\n\n recalculateSiblings(currentSiblings)\n recalculateSiblings(grandSiblings)\n model.value = cloned\n return cloned\n }\n\n const calculateParentDepth = (tree: NestedTree<TItem>, id: ListEditorKey): number => {\n const walk = (arr: NestedTreeNode<TItem>[], depth: number): number | null => {\n for (const item of arr) {\n if (getKey(item.data) === id) return depth\n if (item.children && item.children.length) {\n const d = walk(item.children, depth + 1)\n if (d !== null) return d\n }\n }\n return null\n }\n return walk(tree.children, 0) ?? 0\n }\n\n /**\n * Move a node to a specific parent at a specific index. Used by drag/drop.\n * Respects maxDepth — returns null if the move would exceed it.\n */\n const moveTo = (\n id: ListEditorKey,\n targetParentId: ListEditorKey | null,\n targetIndex: number\n ): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n\n if (targetParentId !== null) {\n const isDescendant = (n: NestedTreeNode<TItem>): boolean => {\n if (!n.children) return false\n for (const c of n.children) {\n if (getKey(c.data) === targetParentId) return true\n if (isDescendant(c)) return true\n }\n return false\n }\n if (getKey(node.data) === targetParentId || isDescendant(node)) return null\n }\n\n let targetSiblings: NestedTreeNode<TItem>[]\n let newParentNode: NestedTreeNode<TItem> | null = null\n let newParentDepth = 0\n if (targetParentId === null) {\n targetSiblings = cloned.children\n newParentDepth = 0\n } else {\n const { node: targetParent } = findNode(targetParentId, cloned.children)\n if (!targetParent || isUndefined(targetParent.children)) return null\n targetSiblings = targetParent.children\n newParentNode = targetParent\n newParentDepth = calculateParentDepth(cloned, targetParentId) + 1\n }\n\n const subtreeDepth = calculateSubtreeDepth(node)\n if (newParentDepth + subtreeDepth > maxDepth) return null\n\n const sourceSiblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const sourceIdx = sourceSiblings.indexOf(node)\n if (sourceIdx === -1) return null\n\n const samelist = sourceSiblings === targetSiblings\n const removed = sourceSiblings.splice(sourceIdx, 1)[0]!\n let insertAt = targetIndex\n if (samelist && sourceIdx < targetIndex) insertAt = targetIndex - 1\n insertAt = Math.max(0, Math.min(insertAt, targetSiblings.length))\n targetSiblings.splice(insertAt, 0, removed)\n ;(removed.data as any)[parentField] = newParentNode ? getKey(newParentNode.data) : null\n // Flag explicitly: a reparent at an unchanged position number (root pos 2 →\n // a group's 2nd child, also pos 2) isn't caught by recalculateSiblings, so the\n // partial save would omit it and the child reverts to root on reload (BUG-13).\n removed.meta.dirty = true\n\n if (!samelist) recalculateSiblings(sourceSiblings)\n recalculateSiblings(targetSiblings)\n model.value = cloned\n return cloned\n }\n\n return {\n viewItems,\n findNode,\n addItem,\n deleteItem,\n updateItem,\n moveUp,\n moveDown,\n moveTop,\n moveBottom,\n indent,\n outdent,\n moveTo,\n recalculatePositions,\n calculateSubtreeDepth,\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useNestedListEditor.js","names":["DEFAULT_KEY_FIELD","DEFAULT_POSITION_FIELD","DEFAULT_PARENT_FIELD","useNestedListEditor","keyField","options","resolveKey","positionField","parentField","positionMultiplier","maxDepth","getKey","data","calculateSubtreeDepth","node","max","child","d","findNode","model","item","arr","id","found","recalculateSiblings","action","values","siblings","s","v","slots","a","b","sibling","i","pos","recalculateAll","walk","tree","recalculatePositions","cloned","cloneDeep","buildViewItems","flat","expandedKeys","flatIndex","nodes","key","childrenAllowed","isUndefined","hasChildren","childrenCount","isExpanded","remainingDepth","depth","canAddChild","canOutdent","canIndent","parentNode","viewItems","computed","insertAfter","afterIdx","newNode","resolveInsertIndex","hint","idx","addItem","targetSiblings","afterNode","afterParent","insertIdx","deleteItem","parent","opts","updateItem","markDirty","swapSiblings","target","getTargetIndex","removed","moveUp","res","moveDown","moveTop","moveBottom","indent","prev","subtreeDepth","calculateParentDepth","outdent","grandParent","grandSiblings","parentIdx","currentSiblings","targetParentId","isDescendant","n","c","newParentNode","newParentDepth","targetParent","sourceSiblings","sourceIdx","samelist","insertAt","targetIndex"],"sources":["../../../../src/domains/listEditor/composables/useNestedListEditor.ts"],"sourcesContent":["import { computed, type ComputedRef, type Ref } from 'vue'\nimport { cloneDeep, isUndefined } from '@/shared/utils/common'\nimport type {\n ListEditorKey,\n ListViewItem,\n NestedTree,\n NestedTreeNode,\n PositionHint,\n} from '@/domains/listEditor/types/listEditorTypes'\n\nexport interface NestedViewItem<TItem> extends ListViewItem<TItem> {\n node: NestedTreeNode<TItem>\n depth: number\n parent: TItem | null\n parentKey: ListEditorKey | null\n childrenCount: number\n hasChildren: boolean\n childrenAllowed: boolean\n siblingIndex: number\n siblingCount: number\n firstInParent: boolean\n lastInParent: boolean\n canAddChild: boolean\n canIndent: boolean\n canOutdent: boolean\n}\n\nexport interface UseNestedListEditorOptions {\n keyField?: string\n /**\n * Resolve a row's key; takes precedence over `keyField`. Pass the controller's\n * `keyOf` so tree ops key rows the same way as dirty/validity tracking — incl.\n * a FUNCTION get-key, which `keyField` lookup would miss.\n */\n getKey?: (data: any) => ListEditorKey\n positionField?: string\n parentField?: string\n positionMultiplier?: number\n /** `false` = the position field is not managed: tree ops never write it. */\n managedPosition?: boolean\n /** Per-action policy, as in the flat controller. Default 'renumber'. */\n positionStrategyFor?: (action: 'add' | 'remove' | 'move') => 'renumber' | 'preserve-values'\n maxDepth: number\n expandedKeys?: Ref<Set<ListEditorKey>>\n}\n\nexport interface NestedListEditorApi<TItem extends Record<string, any>> {\n viewItems: ComputedRef<NestedViewItem<TItem>[]>\n findNode: (id: ListEditorKey) => {\n node: NestedTreeNode<TItem> | null\n parent: NestedTreeNode<TItem> | null\n }\n addItem: (\n data: TItem,\n hint?: PositionHint & {\n parentId?: ListEditorKey | null\n asFirstChild?: boolean\n childrenAllowed?: boolean\n }\n ) => NestedTree<TItem>\n deleteItem: (id: ListEditorKey, opts?: { renumber?: boolean }) => NestedTree<TItem>\n updateItem: (id: ListEditorKey, data: TItem, markDirty?: boolean) => NestedTree<TItem>\n moveUp: (id: ListEditorKey) => NestedTree<TItem> | null\n moveDown: (id: ListEditorKey) => NestedTree<TItem> | null\n moveTop: (id: ListEditorKey) => NestedTree<TItem> | null\n moveBottom: (id: ListEditorKey) => NestedTree<TItem> | null\n indent: (id: ListEditorKey) => NestedTree<TItem> | null\n outdent: (id: ListEditorKey) => NestedTree<TItem> | null\n moveTo: (id: ListEditorKey, targetParentId: ListEditorKey | null, targetIndex: number) => NestedTree<TItem> | null\n recalculatePositions: (model: NestedTree<TItem>) => NestedTree<TItem>\n calculateSubtreeDepth: (node: NestedTreeNode<TItem>) => number\n}\n\nconst DEFAULT_KEY_FIELD = 'id'\nconst DEFAULT_POSITION_FIELD = 'position'\nconst DEFAULT_PARENT_FIELD = 'parent'\n\n/**\n * Nested list editor core for `ANestedSortableListEditor`. Works on a tree of `{ data, children, meta }` nodes.\n * Mutators return a cloned tree and also assign it to `model.value`.\n */\nexport function useNestedListEditor<TItem extends Record<string, any>>(\n model: Ref<NestedTree<TItem>>,\n options: UseNestedListEditorOptions\n): NestedListEditorApi<TItem> {\n const keyField = options.keyField ?? DEFAULT_KEY_FIELD\n const resolveKey = options.getKey\n const positionField = options.positionField ?? DEFAULT_POSITION_FIELD\n const parentField = options.parentField ?? DEFAULT_PARENT_FIELD\n const positionMultiplier = options.positionMultiplier ?? 1\n const maxDepth = options.maxDepth\n\n const getKey = (data: TItem): ListEditorKey => (resolveKey ? resolveKey(data) : (data[keyField] as ListEditorKey))\n\n const calculateSubtreeDepth = (node: NestedTreeNode<TItem>): number => {\n if (!node.children || node.children.length === 0) return 1\n let max = 0\n for (const child of node.children) {\n const d = calculateSubtreeDepth(child)\n if (d > max) max = d\n }\n return max + 1\n }\n\n const findNode = (\n id: ListEditorKey,\n arr: NestedTreeNode<TItem>[] = model.value.children,\n parent: NestedTreeNode<TItem> | null = null\n ): { node: NestedTreeNode<TItem> | null; parent: NestedTreeNode<TItem> | null } => {\n for (const item of arr) {\n if (getKey(item.data) === id) return { node: item, parent }\n if (item.children && item.children.length > 0) {\n const found = findNode(id, item.children, item)\n if (found.node) return found\n }\n }\n return { node: null, parent: null }\n }\n\n const recalculateSiblings = (siblings: NestedTreeNode<TItem>[], action: 'add' | 'remove' | 'move' = 'move') => {\n if (options.managedPosition === false) return\n const strategy = options.positionStrategyFor?.(action) ?? 'renumber'\n if (strategy === 'preserve-values') {\n if (action !== 'move') return\n const values = siblings.map((s) => s.data[positionField])\n // Same as the flat editor: without a finite number on every row there is no slot set to move through.\n // Inventing one would write a wrong payload.\n if (!values.every((v) => typeof v === 'number' && Number.isFinite(v))) {\n console.warn(\n `[listEditor] position strategy \"preserve-values\" needs a finite numeric \\`${positionField}\\` ` +\n 'on every row; found ' +\n JSON.stringify(values) +\n ' — leaving positions untouched.'\n )\n return\n }\n const slots = (values as number[]).slice().sort((a, b) => a - b)\n siblings.forEach((sibling, i) => {\n if (sibling.data[positionField] !== slots[i]) {\n ;(sibling.data as any)[positionField] = slots[i]\n sibling.meta.dirty = true\n }\n })\n return\n }\n let pos = 1 * positionMultiplier\n for (const sibling of siblings) {\n if (sibling.data[positionField] !== pos) {\n ;(sibling.data as any)[positionField] = pos\n // Flag dirty so a partial-subset save persists the new position;\n // otherwise reorders are lost on reload and rows collide on old positions.\n sibling.meta.dirty = true\n }\n pos += positionMultiplier\n }\n }\n\n const recalculateAll = (tree: NestedTree<TItem>) => {\n const walk = (arr: NestedTreeNode<TItem>[]) => {\n recalculateSiblings(arr)\n for (const item of arr) if (item.children && item.children.length) walk(item.children)\n }\n walk(tree.children)\n }\n\n const recalculatePositions = (tree: NestedTree<TItem>): NestedTree<TItem> => {\n const cloned = cloneDeep(tree) as NestedTree<TItem>\n recalculateAll(cloned)\n return cloned\n }\n\n const buildViewItems = (tree: NestedTree<TItem>): NestedViewItem<TItem>[] => {\n const flat: NestedViewItem<TItem>[] = []\n const expandedKeys = options.expandedKeys?.value\n let flatIndex = 0\n const walk = (nodes: NestedTreeNode<TItem>[], depth: number, parentNode: NestedTreeNode<TItem> | null) => {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i]!\n const key = getKey(node.data)\n const childrenAllowed = !isUndefined(node.children)\n const hasChildren = childrenAllowed && (node.children?.length ?? 0) > 0\n const childrenCount = node.children?.length ?? 0\n const isExpanded = expandedKeys ? expandedKeys.has(key) : true\n const remainingDepth = maxDepth - (depth + 1)\n const canAddChild = childrenAllowed && remainingDepth > 0\n const canOutdent = depth > 0\n const canIndent = i > 0\n flat.push({\n key,\n index: flatIndex++,\n raw: node.data,\n position: node.data[positionField] as number | undefined,\n node,\n depth,\n parent: parentNode?.data ?? null,\n parentKey: parentNode ? getKey(parentNode.data) : null,\n childrenCount,\n hasChildren,\n childrenAllowed,\n siblingIndex: i,\n siblingCount: nodes.length,\n firstInParent: i === 0,\n lastInParent: i === nodes.length - 1,\n canAddChild,\n canIndent,\n canOutdent,\n })\n if (hasChildren && isExpanded) {\n walk(node.children as NestedTreeNode<TItem>[], depth + 1, node)\n }\n }\n }\n walk(tree.children, 0, null)\n return flat\n }\n\n const viewItems = computed<NestedViewItem<TItem>[]>(() => buildViewItems(model.value))\n\n const insertAfter = (siblings: NestedTreeNode<TItem>[], afterIdx: number, newNode: NestedTreeNode<TItem>) => {\n siblings.splice(afterIdx + 1, 0, newNode)\n }\n\n const resolveInsertIndex = (siblings: NestedTreeNode<TItem>[], hint?: PositionHint): number => {\n if (!hint) return siblings.length\n if (hint.afterId !== undefined) {\n const idx = siblings.findIndex((s) => getKey(s.data) === hint.afterId)\n return idx === -1 ? siblings.length : idx + 1\n }\n if (hint.afterIndex !== undefined) {\n if (hint.afterIndex < 0) return siblings.length\n return Math.min(hint.afterIndex + 1, siblings.length)\n }\n if (hint.index !== undefined) {\n return Math.max(0, Math.min(hint.index, siblings.length))\n }\n return siblings.length\n }\n\n const addItem = (\n data: TItem,\n hint?: PositionHint & {\n parentId?: ListEditorKey | null\n asFirstChild?: boolean\n childrenAllowed?: boolean\n }\n ): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const childrenAllowed = hint?.childrenAllowed ?? true\n const newNode: NestedTreeNode<TItem> = {\n data: cloneDeep(data) as TItem,\n children: childrenAllowed ? [] : undefined,\n meta: { dirty: false },\n }\n\n let targetSiblings: NestedTreeNode<TItem>[] = cloned.children\n let parentNode: NestedTreeNode<TItem> | null = null\n\n if (hint?.parentId !== undefined && hint.parentId !== null) {\n const { node } = findNode(hint.parentId, cloned.children)\n if (node && node.children) {\n targetSiblings = node.children\n parentNode = node\n }\n }\n\n if (hint?.afterId !== undefined) {\n const { node: afterNode, parent: afterParent } = findNode(hint.afterId, cloned.children)\n if (afterNode) {\n const siblings = afterParent ? (afterParent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(afterNode)\n if (idx !== -1) {\n insertAfter(siblings, idx, newNode)\n ;(newNode.data as any)[parentField] = afterParent ? getKey(afterParent.data) : null\n recalculateSiblings(siblings, 'add')\n model.value = cloned\n return cloned\n }\n }\n }\n\n const insertIdx = hint?.asFirstChild ? 0 : resolveInsertIndex(targetSiblings, hint)\n targetSiblings.splice(insertIdx, 0, newNode)\n ;(newNode.data as any)[parentField] = parentNode ? getKey(parentNode.data) : null\n recalculateSiblings(targetSiblings, 'add')\n model.value = cloned\n return cloned\n }\n\n // `renumber: false` keeps sibling positions. The row is already\n // deleted on the backend, which does not renumber either.\n // So the editor keeps the same gap the server has.\n const deleteItem = (id: ListEditorKey, opts?: { renumber?: boolean }): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return cloned\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx === -1) return cloned\n siblings.splice(idx, 1)\n if (opts?.renumber !== false) recalculateSiblings(siblings, 'remove')\n model.value = cloned\n return cloned\n }\n\n const updateItem = (id: ListEditorKey, data: TItem, markDirty = true): NestedTree<TItem> => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node } = findNode(id, cloned.children)\n if (!node) return cloned\n node.data = cloneDeep(data) as TItem\n // An edit must be persisted by partial-subset saves. `markDirty=false` is for\n // snapshot restore on edit-cancel, which must NOT flag the node dirty.\n if (markDirty) node.meta.dirty = true\n model.value = cloned\n return cloned\n }\n\n const swapSiblings = (\n cloned: NestedTree<TItem>,\n id: ListEditorKey,\n getTargetIndex: (siblings: NestedTreeNode<TItem>[], currentIdx: number) => number | null\n ): NestedTree<TItem> | null => {\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx === -1) return null\n const target = getTargetIndex(siblings, idx)\n if (target === null || target === idx) return null\n const removed = siblings.splice(idx, 1)[0]!\n siblings.splice(target, 0, removed)\n if (options.managedPosition === false) removed.meta.dirty = true\n recalculateSiblings(siblings)\n return cloned\n }\n\n const moveUp = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (_s, idx) => (idx > 0 ? idx - 1 : null))\n if (res) model.value = res\n return res\n }\n\n const moveDown = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (s, idx) => (idx < s.length - 1 ? idx + 1 : null))\n if (res) model.value = res\n return res\n }\n\n const moveTop = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (_s, idx) => (idx > 0 ? 0 : null))\n if (res) model.value = res\n return res\n }\n\n const moveBottom = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const res = swapSiblings(cloned, id, (s, idx) => (idx < s.length - 1 ? s.length - 1 : null))\n if (res) model.value = res\n return res\n }\n\n /**\n * Indent: move the item under its previous sibling as its last child.\n * Fails if: no previous sibling, previous sibling doesn't allow children,\n * or the resulting depth would exceed maxDepth.\n */\n const indent = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n const siblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const idx = siblings.indexOf(node)\n if (idx <= 0) return null\n const prev = siblings[idx - 1]!\n if (isUndefined(prev.children)) return null\n const subtreeDepth = calculateSubtreeDepth(node)\n const prevDepth = calculateParentDepth(cloned, getKey(prev.data))\n if (prevDepth + 1 + subtreeDepth > maxDepth) return null\n\n siblings.splice(idx, 1)\n prev.children!.push(node)\n ;(node.data as any)[parentField] = getKey(prev.data)\n // Persist the reparent even when the position number is unchanged (QA 85050 BUG-13).\n node.meta.dirty = true\n recalculateSiblings(siblings)\n recalculateSiblings(prev.children!)\n model.value = cloned\n return cloned\n }\n\n /**\n * Outdent: move the item up one level — it becomes the next sibling of its current parent.\n * Fails if the item is already at root.\n */\n const outdent = (id: ListEditorKey): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node || !parent) return null\n\n const { parent: grandParent } = findNode(getKey(parent.data), cloned.children)\n const grandSiblings = grandParent ? (grandParent.children as NestedTreeNode<TItem>[]) : cloned.children\n const parentIdx = grandSiblings.indexOf(parent)\n if (parentIdx === -1) return null\n\n const currentSiblings = parent.children as NestedTreeNode<TItem>[]\n const idx = currentSiblings.indexOf(node)\n if (idx === -1) return null\n currentSiblings.splice(idx, 1)\n grandSiblings.splice(parentIdx + 1, 0, node)\n ;(node.data as any)[parentField] = grandParent ? getKey(grandParent.data) : null\n // Persist the reparent even when the position number is unchanged (QA 85050 BUG-13).\n node.meta.dirty = true\n\n recalculateSiblings(currentSiblings)\n recalculateSiblings(grandSiblings)\n model.value = cloned\n return cloned\n }\n\n const calculateParentDepth = (tree: NestedTree<TItem>, id: ListEditorKey): number => {\n const walk = (arr: NestedTreeNode<TItem>[], depth: number): number | null => {\n for (const item of arr) {\n if (getKey(item.data) === id) return depth\n if (item.children && item.children.length) {\n const d = walk(item.children, depth + 1)\n if (d !== null) return d\n }\n }\n return null\n }\n return walk(tree.children, 0) ?? 0\n }\n\n /**\n * Move a node to a specific parent at a specific index. Used by drag/drop.\n * Respects maxDepth — returns null if the move would exceed it.\n */\n const moveTo = (\n id: ListEditorKey,\n targetParentId: ListEditorKey | null,\n targetIndex: number\n ): NestedTree<TItem> | null => {\n const cloned = cloneDeep(model.value) as NestedTree<TItem>\n const { node, parent } = findNode(id, cloned.children)\n if (!node) return null\n\n if (targetParentId !== null) {\n const isDescendant = (n: NestedTreeNode<TItem>): boolean => {\n if (!n.children) return false\n for (const c of n.children) {\n if (getKey(c.data) === targetParentId) return true\n if (isDescendant(c)) return true\n }\n return false\n }\n if (getKey(node.data) === targetParentId || isDescendant(node)) return null\n }\n\n let targetSiblings: NestedTreeNode<TItem>[]\n let newParentNode: NestedTreeNode<TItem> | null = null\n let newParentDepth = 0\n if (targetParentId === null) {\n targetSiblings = cloned.children\n newParentDepth = 0\n } else {\n const { node: targetParent } = findNode(targetParentId, cloned.children)\n if (!targetParent || isUndefined(targetParent.children)) return null\n targetSiblings = targetParent.children\n newParentNode = targetParent\n newParentDepth = calculateParentDepth(cloned, targetParentId) + 1\n }\n\n const subtreeDepth = calculateSubtreeDepth(node)\n if (newParentDepth + subtreeDepth > maxDepth) return null\n\n const sourceSiblings = parent ? (parent.children as NestedTreeNode<TItem>[]) : cloned.children\n const sourceIdx = sourceSiblings.indexOf(node)\n if (sourceIdx === -1) return null\n\n const samelist = sourceSiblings === targetSiblings\n const removed = sourceSiblings.splice(sourceIdx, 1)[0]!\n let insertAt = targetIndex\n if (samelist && sourceIdx < targetIndex) insertAt = targetIndex - 1\n insertAt = Math.max(0, Math.min(insertAt, targetSiblings.length))\n targetSiblings.splice(insertAt, 0, removed)\n ;(removed.data as any)[parentField] = newParentNode ? getKey(newParentNode.data) : null\n // Flag explicitly: a reparent at an unchanged position number (root pos 2 →\n // a group's 2nd child, also pos 2) isn't caught by recalculateSiblings, so the\n // partial save would omit it and the child reverts to root on reload (BUG-13).\n removed.meta.dirty = true\n\n if (!samelist) recalculateSiblings(sourceSiblings)\n recalculateSiblings(targetSiblings)\n model.value = cloned\n return cloned\n }\n\n return {\n viewItems,\n findNode,\n addItem,\n deleteItem,\n updateItem,\n moveUp,\n moveDown,\n moveTop,\n moveBottom,\n indent,\n outdent,\n moveTo,\n recalculatePositions,\n calculateSubtreeDepth,\n }\n}\n"],"mappings":"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"}
@@ -116,10 +116,11 @@ export type ExposedNestedListEditorHandle<TItem extends Record<string, any>> = S
116
116
  /** What `ANestedSortableListEditor` exposes on top of the controller handle. */
117
117
  export interface NestedSortableListEditorExtras {
118
118
  /**
119
- * Runs a tree mutation the server has already made (a row created through a dialog) and adopts as
120
- * saved only the rows it added or edited, plus `keys`. Siblings it only renumbered and other pending
121
- * work stay unsaved (the server may not have renumbered them), and so does the position of a created
122
- * row the op renumbered. `commit()` would adopt the whole tree instead.
119
+ * Runs a tree mutation the server already made (e.g. a row created through a dialog).
120
+ * Adopts as saved only the rows it added or edited, plus `keys`.
121
+ * Siblings it only renumbered, other pending work and a renumbered position of
122
+ * a created row stay unsaved, because the server may not have renumbered them.
123
+ * `commit()` would adopt the whole tree instead.
123
124
  */
124
125
  acceptChanges: (op: () => void, keys?: ListEditorKey[]) => void;
125
126
  enterReorderMode: () => void;