@qoretechnologies/reqraft 0.10.25 → 0.10.26

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 (310) hide show
  1. package/.claude/CLAUDE.md +52 -23
  2. package/design/COMPACT_ENGINE_REDESIGN.md +156 -0
  3. package/design/FORM_ENGINE_COMPACT_UX_PLAN.md +353 -0
  4. package/dist/components/FocusedEditing/index.d.ts +9 -1
  5. package/dist/components/FocusedEditing/index.d.ts.map +1 -1
  6. package/dist/components/FocusedEditing/index.js +2 -2
  7. package/dist/components/FocusedEditing/index.js.map +1 -1
  8. package/dist/components/composer/Composer.d.ts +108 -0
  9. package/dist/components/composer/Composer.d.ts.map +1 -0
  10. package/dist/components/composer/Composer.js +238 -0
  11. package/dist/components/composer/Composer.js.map +1 -0
  12. package/dist/components/composer/helpers.d.ts +21 -0
  13. package/dist/components/composer/helpers.d.ts.map +1 -0
  14. package/dist/components/composer/helpers.js +75 -0
  15. package/dist/components/composer/helpers.js.map +1 -0
  16. package/dist/components/composer/index.d.ts +3 -0
  17. package/dist/components/composer/index.d.ts.map +1 -0
  18. package/dist/components/composer/index.js +19 -0
  19. package/dist/components/composer/index.js.map +1 -0
  20. package/dist/components/form/engine/CompactRow.d.ts.map +1 -1
  21. package/dist/components/form/engine/CompactRow.js +307 -110
  22. package/dist/components/form/engine/CompactRow.js.map +1 -1
  23. package/dist/components/form/engine/CompactToolbar.d.ts.map +1 -1
  24. package/dist/components/form/engine/CompactToolbar.js +123 -106
  25. package/dist/components/form/engine/CompactToolbar.js.map +1 -1
  26. package/dist/components/form/engine/FormEngine.d.ts +107 -11
  27. package/dist/components/form/engine/FormEngine.d.ts.map +1 -1
  28. package/dist/components/form/engine/FormEngine.js +618 -179
  29. package/dist/components/form/engine/FormEngine.js.map +1 -1
  30. package/dist/components/form/engine/compactRowContext.d.ts +9 -0
  31. package/dist/components/form/engine/compactRowContext.d.ts.map +1 -1
  32. package/dist/components/form/engine/compactRowContext.js.map +1 -1
  33. package/dist/components/form/engine/compactRowStyles.d.ts +7 -3
  34. package/dist/components/form/engine/compactRowStyles.d.ts.map +1 -1
  35. package/dist/components/form/engine/compactRowStyles.js +88 -51
  36. package/dist/components/form/engine/compactRowStyles.js.map +1 -1
  37. package/dist/components/form/engine/compactToolbarContext.d.ts +1 -0
  38. package/dist/components/form/engine/compactToolbarContext.d.ts.map +1 -1
  39. package/dist/components/form/engine/compactToolbarContext.js.map +1 -1
  40. package/dist/components/form/engine/optionActions.d.ts +28 -0
  41. package/dist/components/form/engine/optionActions.d.ts.map +1 -0
  42. package/dist/components/form/engine/optionActions.js +18 -0
  43. package/dist/components/form/engine/optionActions.js.map +1 -0
  44. package/dist/components/form/engine/readFirst.d.ts +63 -2
  45. package/dist/components/form/engine/readFirst.d.ts.map +1 -1
  46. package/dist/components/form/engine/readFirst.js +121 -6
  47. package/dist/components/form/engine/readFirst.js.map +1 -1
  48. package/dist/components/form/engine/rendererTypes.d.ts +35 -0
  49. package/dist/components/form/engine/rendererTypes.d.ts.map +1 -0
  50. package/dist/components/form/engine/rendererTypes.js +63 -0
  51. package/dist/components/form/engine/rendererTypes.js.map +1 -0
  52. package/dist/components/form/engine/variants/VariantCalmTable.d.ts +6 -0
  53. package/dist/components/form/engine/variants/VariantCalmTable.d.ts.map +1 -0
  54. package/dist/components/form/engine/variants/VariantCalmTable.js +94 -0
  55. package/dist/components/form/engine/variants/VariantCalmTable.js.map +1 -0
  56. package/dist/components/form/engine/variants/VariantCards.d.ts +6 -0
  57. package/dist/components/form/engine/variants/VariantCards.d.ts.map +1 -0
  58. package/dist/components/form/engine/variants/VariantCards.js +80 -0
  59. package/dist/components/form/engine/variants/VariantCards.js.map +1 -0
  60. package/dist/components/form/engine/variants/VariantFocus.d.ts +7 -0
  61. package/dist/components/form/engine/variants/VariantFocus.d.ts.map +1 -0
  62. package/dist/components/form/engine/variants/VariantFocus.js +138 -0
  63. package/dist/components/form/engine/variants/VariantFocus.js.map +1 -0
  64. package/dist/components/form/engine/variants/VariantMinimal.d.ts +6 -0
  65. package/dist/components/form/engine/variants/VariantMinimal.d.ts.map +1 -0
  66. package/dist/components/form/engine/variants/VariantMinimal.js +73 -0
  67. package/dist/components/form/engine/variants/VariantMinimal.js.map +1 -0
  68. package/dist/components/form/engine/variants/focusDemo.d.ts +13 -0
  69. package/dist/components/form/engine/variants/focusDemo.d.ts.map +1 -0
  70. package/dist/components/form/engine/variants/focusDemo.js +139 -0
  71. package/dist/components/form/engine/variants/focusDemo.js.map +1 -0
  72. package/dist/components/form/engine/variants/variantModel.d.ts +70 -0
  73. package/dist/components/form/engine/variants/variantModel.d.ts.map +1 -0
  74. package/dist/components/form/engine/variants/variantModel.js +133 -0
  75. package/dist/components/form/engine/variants/variantModel.js.map +1 -0
  76. package/dist/components/form/engine/variants/variantParts.d.ts +79 -0
  77. package/dist/components/form/engine/variants/variantParts.d.ts.map +1 -0
  78. package/dist/components/form/engine/variants/variantParts.js +191 -0
  79. package/dist/components/form/engine/variants/variantParts.js.map +1 -0
  80. package/dist/components/form/expressions/builder/index.d.ts.map +1 -1
  81. package/dist/components/form/expressions/builder/index.js +13 -2
  82. package/dist/components/form/expressions/builder/index.js.map +1 -1
  83. package/dist/components/form/expressions/useExpressions.d.ts.map +1 -1
  84. package/dist/components/form/expressions/useExpressions.js +4 -1
  85. package/dist/components/form/expressions/useExpressions.js.map +1 -1
  86. package/dist/components/form/fields/Field.d.ts.map +1 -1
  87. package/dist/components/form/fields/Field.js +5 -3
  88. package/dist/components/form/fields/Field.js.map +1 -1
  89. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts +2 -1
  90. package/dist/components/form/fields/allowed-values/AllowedValues.d.ts.map +1 -1
  91. package/dist/components/form/fields/allowed-values/AllowedValues.js +8 -26
  92. package/dist/components/form/fields/allowed-values/AllowedValues.js.map +1 -1
  93. package/dist/components/form/fields/auto/AutoFormField.d.ts +3 -0
  94. package/dist/components/form/fields/auto/AutoFormField.d.ts.map +1 -1
  95. package/dist/components/form/fields/auto/AutoFormField.js +42 -8
  96. package/dist/components/form/fields/auto/AutoFormField.js.map +1 -1
  97. package/dist/components/form/fields/binary/Binary.d.ts +15 -0
  98. package/dist/components/form/fields/binary/Binary.d.ts.map +1 -0
  99. package/dist/components/form/fields/binary/Binary.js +74 -0
  100. package/dist/components/form/fields/binary/Binary.js.map +1 -0
  101. package/dist/components/form/fields/boolean/Boolean.js +1 -1
  102. package/dist/components/form/fields/boolean/Boolean.js.map +1 -1
  103. package/dist/components/form/fields/multi-select/MultiSelectFormField.d.ts.map +1 -1
  104. package/dist/components/form/fields/multi-select/MultiSelectFormField.js +5 -4
  105. package/dist/components/form/fields/multi-select/MultiSelectFormField.js.map +1 -1
  106. package/dist/components/form/fields/select/Select.d.ts.map +1 -1
  107. package/dist/components/form/fields/select/Select.js +29 -12
  108. package/dist/components/form/fields/select/Select.js.map +1 -1
  109. package/dist/components/form/fields/select/SelectCollection.d.ts +8 -2
  110. package/dist/components/form/fields/select/SelectCollection.d.ts.map +1 -1
  111. package/dist/components/form/fields/select/SelectCollection.js +52 -16
  112. package/dist/components/form/fields/select/SelectCollection.js.map +1 -1
  113. package/dist/components/form/index.d.ts +2 -0
  114. package/dist/components/form/index.d.ts.map +1 -1
  115. package/dist/components/form/index.js +2 -0
  116. package/dist/components/form/index.js.map +1 -1
  117. package/dist/components/imageLightbox/ImageLightbox.d.ts +21 -0
  118. package/dist/components/imageLightbox/ImageLightbox.d.ts.map +1 -0
  119. package/dist/components/imageLightbox/ImageLightbox.js +169 -0
  120. package/dist/components/imageLightbox/ImageLightbox.js.map +1 -0
  121. package/dist/components/imageLightbox/index.d.ts +2 -0
  122. package/dist/components/imageLightbox/index.d.ts.map +1 -0
  123. package/dist/components/imageLightbox/index.js +18 -0
  124. package/dist/components/imageLightbox/index.js.map +1 -0
  125. package/dist/components/searchFilterBar/SearchFilterBar.d.ts +33 -0
  126. package/dist/components/searchFilterBar/SearchFilterBar.d.ts.map +1 -0
  127. package/dist/components/searchFilterBar/SearchFilterBar.js +76 -0
  128. package/dist/components/searchFilterBar/SearchFilterBar.js.map +1 -0
  129. package/dist/components/searchFilterBar/index.d.ts +2 -0
  130. package/dist/components/searchFilterBar/index.d.ts.map +1 -0
  131. package/dist/components/searchFilterBar/index.js +18 -0
  132. package/dist/components/searchFilterBar/index.js.map +1 -0
  133. package/dist/components/supportTicket/AttachmentChips.d.ts +10 -0
  134. package/dist/components/supportTicket/AttachmentChips.d.ts.map +1 -0
  135. package/dist/components/supportTicket/AttachmentChips.js +122 -0
  136. package/dist/components/supportTicket/AttachmentChips.js.map +1 -0
  137. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts +43 -0
  138. package/dist/components/supportTicket/InterfaceReferenceTags.d.ts.map +1 -0
  139. package/dist/components/supportTicket/InterfaceReferenceTags.js +31 -0
  140. package/dist/components/supportTicket/InterfaceReferenceTags.js.map +1 -0
  141. package/dist/components/supportTicket/ReferencePicker.d.ts +87 -0
  142. package/dist/components/supportTicket/ReferencePicker.d.ts.map +1 -0
  143. package/dist/components/supportTicket/ReferencePicker.js +295 -0
  144. package/dist/components/supportTicket/ReferencePicker.js.map +1 -0
  145. package/dist/components/supportTicket/TicketHeader.d.ts +86 -0
  146. package/dist/components/supportTicket/TicketHeader.d.ts.map +1 -0
  147. package/dist/components/supportTicket/TicketHeader.js +149 -0
  148. package/dist/components/supportTicket/TicketHeader.js.map +1 -0
  149. package/dist/components/supportTicket/TicketMetaTags.d.ts +32 -0
  150. package/dist/components/supportTicket/TicketMetaTags.d.ts.map +1 -0
  151. package/dist/components/supportTicket/TicketMetaTags.js +21 -0
  152. package/dist/components/supportTicket/TicketMetaTags.js.map +1 -0
  153. package/dist/components/supportTicket/TicketReplyBox.d.ts +63 -0
  154. package/dist/components/supportTicket/TicketReplyBox.d.ts.map +1 -0
  155. package/dist/components/supportTicket/TicketReplyBox.js +115 -0
  156. package/dist/components/supportTicket/TicketReplyBox.js.map +1 -0
  157. package/dist/components/supportTicket/attachmentAccess.d.ts +37 -0
  158. package/dist/components/supportTicket/attachmentAccess.d.ts.map +1 -0
  159. package/dist/components/supportTicket/attachmentAccess.js +132 -0
  160. package/dist/components/supportTicket/attachmentAccess.js.map +1 -0
  161. package/dist/components/supportTicket/fileToAttachment.d.ts +9 -0
  162. package/dist/components/supportTicket/fileToAttachment.d.ts.map +1 -0
  163. package/dist/components/supportTicket/fileToAttachment.js +28 -0
  164. package/dist/components/supportTicket/fileToAttachment.js.map +1 -0
  165. package/dist/components/supportTicket/index.d.ts +11 -0
  166. package/dist/components/supportTicket/index.d.ts.map +1 -0
  167. package/dist/components/supportTicket/index.js +27 -0
  168. package/dist/components/supportTicket/index.js.map +1 -0
  169. package/dist/components/supportTicket/meta.d.ts +71 -0
  170. package/dist/components/supportTicket/meta.d.ts.map +1 -0
  171. package/dist/components/supportTicket/meta.js +115 -0
  172. package/dist/components/supportTicket/meta.js.map +1 -0
  173. package/dist/components/supportTicket/ticketModel.d.ts +102 -0
  174. package/dist/components/supportTicket/ticketModel.d.ts.map +1 -0
  175. package/dist/components/supportTicket/ticketModel.js +3 -0
  176. package/dist/components/supportTicket/ticketModel.js.map +1 -0
  177. package/dist/components/ticketReferences/TicketReferences.d.ts +52 -0
  178. package/dist/components/ticketReferences/TicketReferences.d.ts.map +1 -0
  179. package/dist/components/ticketReferences/TicketReferences.js +492 -0
  180. package/dist/components/ticketReferences/TicketReferences.js.map +1 -0
  181. package/dist/components/ticketReferences/index.d.ts +3 -0
  182. package/dist/components/ticketReferences/index.d.ts.map +1 -0
  183. package/dist/components/ticketReferences/index.js +6 -0
  184. package/dist/components/ticketReferences/index.js.map +1 -0
  185. package/dist/components/ticketThread/TicketThread.d.ts +57 -0
  186. package/dist/components/ticketThread/TicketThread.d.ts.map +1 -0
  187. package/dist/components/ticketThread/TicketThread.js +299 -0
  188. package/dist/components/ticketThread/TicketThread.js.map +1 -0
  189. package/dist/components/ticketThread/index.d.ts +3 -0
  190. package/dist/components/ticketThread/index.d.ts.map +1 -0
  191. package/dist/components/ticketThread/index.js +7 -0
  192. package/dist/components/ticketThread/index.js.map +1 -0
  193. package/dist/helpers/common.d.ts +5 -0
  194. package/dist/helpers/common.d.ts.map +1 -1
  195. package/dist/helpers/common.js +20 -1
  196. package/dist/helpers/common.js.map +1 -1
  197. package/dist/helpers/scrollbar.d.ts +2 -0
  198. package/dist/helpers/scrollbar.d.ts.map +1 -0
  199. package/dist/helpers/scrollbar.js +25 -0
  200. package/dist/helpers/scrollbar.js.map +1 -0
  201. package/dist/index.d.ts +8 -1
  202. package/dist/index.d.ts.map +1 -1
  203. package/dist/index.js +10 -1
  204. package/dist/index.js.map +1 -1
  205. package/dist/providers/StorageProvider.d.ts +13 -0
  206. package/dist/providers/StorageProvider.d.ts.map +1 -1
  207. package/dist/providers/StorageProvider.js +29 -5
  208. package/dist/providers/StorageProvider.js.map +1 -1
  209. package/package.json +6 -5
  210. package/src/components/FocusedEditing/index.tsx +17 -2
  211. package/src/components/composer/Composer.stories.tsx +238 -0
  212. package/src/components/composer/Composer.tsx +545 -0
  213. package/src/components/composer/helpers.ts +74 -0
  214. package/src/components/composer/index.ts +2 -0
  215. package/src/components/dpqlEditor/DpqlEditor.stories.tsx +74 -2
  216. package/src/components/form/engine/CompactRow.tsx +561 -283
  217. package/src/components/form/engine/CompactToolbar.tsx +216 -182
  218. package/src/components/form/engine/FormEngine.stories.tsx +1736 -162
  219. package/src/components/form/engine/FormEngine.tsx +886 -170
  220. package/src/components/form/engine/FormEngineRemote.stories.tsx +377 -0
  221. package/src/components/form/engine/_structuredData/StructuredDataView.stories.tsx +8 -0
  222. package/src/components/form/engine/compactRowContext.ts +14 -0
  223. package/src/components/form/engine/compactRowStyles.ts +273 -146
  224. package/src/components/form/engine/compactToolbarContext.ts +1 -0
  225. package/src/components/form/engine/optionActions.ts +40 -0
  226. package/src/components/form/engine/readFirst.ts +169 -10
  227. package/src/components/form/engine/rendererTypes.ts +55 -0
  228. package/src/components/form/engine/variants/FormEngineVariants.stories.tsx +159 -0
  229. package/src/components/form/engine/variants/VariantCalmTable.tsx +242 -0
  230. package/src/components/form/engine/variants/VariantCards.tsx +212 -0
  231. package/src/components/form/engine/variants/VariantFocus.tsx +382 -0
  232. package/src/components/form/engine/variants/VariantMinimal.tsx +170 -0
  233. package/src/components/form/engine/variants/focusDemo.ts +145 -0
  234. package/src/components/form/engine/variants/variantModel.ts +216 -0
  235. package/src/components/form/engine/variants/variantParts.tsx +313 -0
  236. package/src/components/form/expressions/ExpressionField.stories.tsx +84 -2
  237. package/src/components/form/expressions/builder/ExpressionBuilder.stories.tsx +213 -19
  238. package/src/components/form/expressions/builder/index.tsx +12 -1
  239. package/src/components/form/expressions/useExpressions.ts +4 -1
  240. package/src/components/form/fields/Field.stories.tsx +40 -0
  241. package/src/components/form/fields/Field.tsx +10 -1
  242. package/src/components/form/fields/allowed-values/AllowedValues.tsx +13 -36
  243. package/src/components/form/fields/array/ArrayAutoField.stories.tsx +64 -0
  244. package/src/components/form/fields/auto/AutoFormField.stories.tsx +146 -2
  245. package/src/components/form/fields/auto/AutoFormField.tsx +42 -1
  246. package/src/components/form/fields/binary/Binary.stories.tsx +122 -0
  247. package/src/components/form/fields/binary/Binary.tsx +81 -0
  248. package/src/components/form/fields/boolean/Boolean.stories.tsx +58 -0
  249. package/src/components/form/fields/boolean/Boolean.tsx +1 -1
  250. package/src/components/form/fields/byte-size/ByteSize.stories.tsx +24 -0
  251. package/src/components/form/fields/color/Color.stories.tsx +30 -0
  252. package/src/components/form/fields/cron/Cron.stories.tsx +8 -0
  253. package/src/components/form/fields/date/Date.stories.tsx +22 -0
  254. package/src/components/form/fields/file/File.stories.tsx +48 -0
  255. package/src/components/form/fields/long-string/LongString.stories.tsx +24 -0
  256. package/src/components/form/fields/markdown/Markdown.stories.tsx +8 -0
  257. package/src/components/form/fields/multi-select/MultiSelectFormField.tsx +14 -10
  258. package/src/components/form/fields/number/Number.stories.tsx +31 -0
  259. package/src/components/form/fields/object/Object.stories.tsx +88 -0
  260. package/src/components/form/fields/radio-group/RadioGroup.stories.tsx +24 -0
  261. package/src/components/form/fields/rich-text/RichText.stories.tsx +23 -0
  262. package/src/components/form/fields/schema-definition/SchemaDefinitionField.stories.tsx +72 -0
  263. package/src/components/form/fields/select/Select.stories.tsx +108 -0
  264. package/src/components/form/fields/select/Select.tsx +38 -12
  265. package/src/components/form/fields/select/SelectCollection.tsx +78 -17
  266. package/src/components/form/fields/string/String.stories.tsx +16 -0
  267. package/src/components/form/fields/template/TemplateField.stories.tsx +160 -0
  268. package/src/components/form/fields/url/Url.stories.tsx +24 -0
  269. package/src/components/form/index.tsx +2 -0
  270. package/src/components/imageLightbox/ImageLightbox.stories.tsx +238 -0
  271. package/src/components/imageLightbox/ImageLightbox.tsx +236 -0
  272. package/src/components/imageLightbox/index.ts +1 -0
  273. package/src/components/log/Log.stories.tsx +96 -0
  274. package/src/components/menu/Menu.stories.tsx +54 -0
  275. package/src/components/qonsoleSmartInput/QonsoleSmartInput.stories.tsx +83 -37
  276. package/src/components/searchFilterBar/SearchFilterBar.tsx +131 -0
  277. package/src/components/searchFilterBar/index.ts +1 -0
  278. package/src/components/smartEditor/SmartEditor.stories.tsx +32 -0
  279. package/src/components/supportTicket/AttachmentChips.stories.tsx +171 -0
  280. package/src/components/supportTicket/AttachmentChips.tsx +147 -0
  281. package/src/components/supportTicket/InterfaceReferenceTags.stories.tsx +171 -0
  282. package/src/components/supportTicket/InterfaceReferenceTags.tsx +96 -0
  283. package/src/components/supportTicket/ReferencePicker.stories.tsx +519 -0
  284. package/src/components/supportTicket/ReferencePicker.tsx +563 -0
  285. package/src/components/supportTicket/TicketConversation.stories.tsx +121 -0
  286. package/src/components/supportTicket/TicketHeader.stories.tsx +183 -0
  287. package/src/components/supportTicket/TicketHeader.tsx +247 -0
  288. package/src/components/supportTicket/TicketMetaTags.stories.tsx +103 -0
  289. package/src/components/supportTicket/TicketMetaTags.tsx +85 -0
  290. package/src/components/supportTicket/TicketReplyBox.stories.tsx +351 -0
  291. package/src/components/supportTicket/TicketReplyBox.tsx +146 -0
  292. package/src/components/supportTicket/attachmentAccess.ts +97 -0
  293. package/src/components/supportTicket/fileToAttachment.ts +24 -0
  294. package/src/components/supportTicket/index.ts +10 -0
  295. package/src/components/supportTicket/meta.ts +185 -0
  296. package/src/components/supportTicket/ticketModel.ts +131 -0
  297. package/src/components/ticketReferences/TicketReferences.stories.tsx +315 -0
  298. package/src/components/ticketReferences/TicketReferences.tsx +886 -0
  299. package/src/components/ticketReferences/index.ts +2 -0
  300. package/src/components/ticketThread/TicketThread.stories.tsx +828 -0
  301. package/src/components/ticketThread/TicketThread.tsx +704 -0
  302. package/src/components/ticketThread/index.ts +6 -0
  303. package/src/helpers/common.ts +19 -0
  304. package/src/helpers/scrollbar.ts +32 -0
  305. package/src/hooks/useFetch/useFetch.stories.tsx +30 -0
  306. package/src/hooks/useStorage/useStorage.stories.tsx +82 -0
  307. package/src/hooks/useWebSocket/useWebsocket.stories.tsx +127 -1
  308. package/src/index.tsx +8 -1
  309. package/src/providers/StorageProvider.tsx +30 -4
  310. package/src/stores/currentUser/currentUser.stories.tsx +49 -0
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ReqraftUserProvider = void 0;
3
+ exports.ReqraftUserProvider = exports.applyStorageWrite = void 0;
4
4
  var jsx_runtime_1 = require("react/jsx-runtime");
5
5
  var lodash_1 = require("lodash");
6
6
  var react_1 = require("react");
@@ -9,6 +9,19 @@ var StorageContext_1 = require("../contexts/StorageContext");
9
9
  var useFetch_1 = require("../hooks/useFetch/useFetch");
10
10
  var useReqraftProperty_1 = require("../hooks/useReqraftProperty");
11
11
  var currentUser_1 = require("../stores/currentUser/currentUser");
12
+ /**
13
+ * Apply a single path write onto the current storage blob, seeding a fresh object
14
+ * when the user has no storage yet.
15
+ *
16
+ * `?? {}` is load-bearing: a user who has never written storage has
17
+ * `storage === undefined | null`, and `set(cloneDeep(undefined), …)` returns
18
+ * `undefined` (lodash won't set on a nullish target). Without the seed the FIRST
19
+ * write for such a user — e.g. accepting the cookie-consent banner — persists an
20
+ * empty body and silently drops the value, so the flag stays unset forever and
21
+ * the banner never closes. Exported for testing.
22
+ */
23
+ var applyStorageWrite = function (storage, path, value) { var _a; return (0, lodash_1.set)((_a = (0, lodash_1.cloneDeep)(storage)) !== null && _a !== void 0 ? _a : {}, path, value); };
24
+ exports.applyStorageWrite = applyStorageWrite;
12
25
  var ReqraftUserProvider = function (_a) {
13
26
  var children = _a.children, waitForStorage = _a.waitForStorage;
14
27
  var appName = (0, useReqraftProperty_1.useReqraftProperty)('appName');
@@ -28,19 +41,30 @@ var ReqraftUserProvider = function (_a) {
28
41
  return (_a = (0, lodash_1.get)(currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage, _path)) !== null && _a !== void 0 ? _a : defaultValue;
29
42
  }, [appName, currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage]);
30
43
  var updateStorage = (0, react_1.useCallback)(function (path, value, includeAppPrefix) {
44
+ var _a;
31
45
  if (includeAppPrefix === void 0) { includeAppPrefix = true; }
32
46
  var _path = includeAppPrefix ? "".concat(appName, ".").concat(path) : path;
33
- var updatedStorage = (0, lodash_1.set)((0, lodash_1.cloneDeep)(currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage), _path, value);
47
+ // Base the write on the LATEST storage read straight from the store, not
48
+ // the blob captured in this callback's closure. A caller holding a stale
49
+ // updater — e.g. an imperative store subscription created on mount, before
50
+ // other keys had loaded — would otherwise persist an out-of-date blob and
51
+ // wipe every key written to storage since its closure was captured.
52
+ var latestStorage = (_a = currentUser_1.currentUserStore.getState().currentUser) === null || _a === void 0 ? void 0 : _a.storage;
53
+ var updatedStorage = (0, exports.applyStorageWrite)(latestStorage, _path, value);
34
54
  updateCurrentUserStorage(updatedStorage);
35
55
  load({ body: { storage: updatedStorage } });
36
- }, [appName, currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage, load, updateCurrentUserStorage]);
56
+ }, [appName, load, updateCurrentUserStorage]);
37
57
  var removeStorageValue = (0, react_1.useCallback)(function (path, includeAppPrefix) {
58
+ var _a;
38
59
  if (includeAppPrefix === void 0) { includeAppPrefix = true; }
39
60
  var _path = includeAppPrefix ? "".concat(appName, ".").concat(path) : path;
40
- var updatedStorage = (0, lodash_1.set)((0, lodash_1.cloneDeep)(currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage), _path, null);
61
+ // Same as `updateStorage`: mutate the LATEST blob (never a stale closure
62
+ // copy), seeding a fresh object when there's no storage yet.
63
+ var latestStorage = (_a = currentUser_1.currentUserStore.getState().currentUser) === null || _a === void 0 ? void 0 : _a.storage;
64
+ var updatedStorage = (0, exports.applyStorageWrite)(latestStorage, _path, null);
41
65
  updateCurrentUserStorage(updatedStorage);
42
66
  load({ body: { storage_path: _path } });
43
- }, [appName, currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage, load, updateCurrentUserStorage]);
67
+ }, [appName, load, updateCurrentUserStorage]);
44
68
  var contextValue = (0, react_1.useMemo)(function () { return ({ storage: currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage, getStorage: getStorage, updateStorage: updateStorage, removeStorageValue: removeStorageValue }); }, [currentUser === null || currentUser === void 0 ? void 0 : currentUser.storage, getStorage, updateStorage, removeStorageValue]);
45
69
  if (loading && waitForStorage) {
46
70
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"StorageProvider.js","sourceRoot":"","sources":["../../src/providers/StorageProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StorageProvider.js","sourceRoot":"","sources":["../../src/providers/StorageProvider.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qoretechnologies/reqraft",
3
- "version": "0.10.25",
3
+ "version": "0.10.26",
4
4
  "description": "ReQraft is a collection of React components and hooks that are used across Qore Technologies' products made using the ReQore component library from Qore.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,6 +20,7 @@
20
20
  "storybook": "storybook dev -p 6008",
21
21
  "update-reqore": "yarn add -D @qoretechnologies/reqore@beta",
22
22
  "update-qlip": "yarn add @qoretechnologies/qlip@beta --dev",
23
+ "update-toolkit": "yarn add @qoretechnologies/ts-toolkit@beta",
23
24
  "install-playwright": "npx playwright@latest install --with-deps",
24
25
  "build-storybook": "storybook build",
25
26
  "chromatic": "npx chromatic",
@@ -54,8 +55,8 @@
54
55
  "devDependencies": {
55
56
  "@chromatic-com/storybook": "^5.2.1",
56
57
  "@netsells/storybook-mockdate": "^0.3.3",
57
- "@qoretechnologies/qlip": "^0.1.3-beta.20260622084321",
58
- "@qoretechnologies/reqore": "^0.69.4",
58
+ "@qoretechnologies/qlip": "^0.1.3-beta.20260724071501",
59
+ "@qoretechnologies/reqore": "^0.71.16",
59
60
  "@storybook/addon-docs": "^10.4.6",
60
61
  "@storybook/addon-links": "^10.4.6",
61
62
  "@storybook/addon-vitest": "^10.4.6",
@@ -98,12 +99,12 @@
98
99
  "vitest": "^4.1.8"
99
100
  },
100
101
  "peerDependencies": {
101
- "@qoretechnologies/reqore": ">=0.68.5",
102
+ "@qoretechnologies/reqore": ">=0.71.16",
102
103
  "react": "^18.3.1",
103
104
  "react-dom": "^18.3.1"
104
105
  },
105
106
  "dependencies": {
106
- "@qoretechnologies/ts-toolkit": "^0.5.78",
107
+ "@qoretechnologies/ts-toolkit": "^0.5.80",
107
108
  "@tanstack/react-query": "4",
108
109
  "classnames": "^2.2.6",
109
110
  "cron-validator": "^1.4.0",
@@ -2,7 +2,22 @@ import { IReqoreModalProps, ReqoreModal } from '@qoretechnologies/reqore/dist/co
2
2
  import { memo, useCallback, useEffect, useState } from 'react';
3
3
 
4
4
  export const FocusedEditing = memo(
5
- ({ children, isFullscreen, ...rest }: IReqoreModalProps & { isFullscreen?: boolean }) => {
5
+ ({
6
+ children,
7
+ isFullscreen,
8
+ modalOnly,
9
+ ...rest
10
+ }: IReqoreModalProps & {
11
+ isFullscreen?: boolean;
12
+ /**
13
+ * Render ONLY the modal, not the in-place copy of `children`. For call
14
+ * sites that already render the field themselves and just need the focused
15
+ * overlay on top — e.g. the compact row's inline editor, which lives in the
16
+ * row grid and must stay there. Default (`false`) renders children in place
17
+ * as well, which is what the classic and card layouts wrap themselves in.
18
+ */
19
+ modalOnly?: boolean;
20
+ }) => {
6
21
  const [_isFullscreen, setIsFullscreen] = useState(isFullscreen);
7
22
 
8
23
  const handleFullscreenToggle = useCallback(() => {
@@ -28,7 +43,7 @@ export const FocusedEditing = memo(
28
43
  {children}
29
44
  </ReqoreModal>
30
45
  )}
31
- {children}
46
+ {modalOnly ? null : children}
32
47
  </>
33
48
  );
34
49
  }
@@ -0,0 +1,238 @@
1
+ import { ReqoreButton, ReqoreTag, ReqoreUIProvider } from '@qoretechnologies/reqore';
2
+ import { StoryObj } from '@storybook/react-vite';
3
+ import { expect, fn, userEvent, waitFor, within } from 'storybook/test';
4
+ import { StoryMeta } from '../../types';
5
+ import { Composer } from './Composer';
6
+
7
+ const meta = {
8
+ component: Composer,
9
+ title: 'Components/Composer',
10
+ args: {
11
+ onSend: fn(),
12
+ },
13
+ } as StoryMeta<typeof Composer>;
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof meta>;
17
+
18
+ /**
19
+ * The default: the rich, Qonsole-style editor (`ReqoreRichTextEditor`). It renders
20
+ * a Slate contenteditable (not a `<textarea>`), an attach button, and Send.
21
+ */
22
+ export const Rich: Story = {
23
+ parameters: {
24
+ docs: {
25
+ description: {
26
+ story:
27
+ 'Renders the default rich editor — a Slate contenteditable (not a textarea) with an attach button and Send, seeded with a multi-line draft.',
28
+ },
29
+ },
30
+ },
31
+ args: {
32
+ placeholder: 'Write a message…',
33
+ defaultText: 'A rich, multi-line draft.\nSecond paragraph survives as a newline.',
34
+ },
35
+ async play({ canvasElement }) {
36
+ await expect(canvasElement.querySelector('[contenteditable="true"]')).not.toBeNull();
37
+ await expect(canvasElement.querySelector('textarea')).toBeNull();
38
+ await expect(within(canvasElement).getByText('Send')).toBeInTheDocument();
39
+ },
40
+ };
41
+
42
+ /**
43
+ * The `plain` variant — a `ReqoreTextarea`, used where a simple text field is
44
+ * enough (and for deterministic tests). Typing enables Send; clicking it calls
45
+ * `onSend` with the plain body and the staged files.
46
+ */
47
+ export const Plain: Story = {
48
+ parameters: {
49
+ docs: {
50
+ description: {
51
+ story:
52
+ 'Renders the plain textarea variant, where typing enables Send and clicking it calls onSend with the plain body and the staged files.',
53
+ },
54
+ },
55
+ },
56
+ args: { editor: 'plain' },
57
+ async play({ canvasElement, args }) {
58
+ const canvas = within(canvasElement);
59
+ const textarea = canvasElement.querySelector('textarea');
60
+ await expect(textarea).not.toBeNull();
61
+
62
+ await userEvent.type(textarea!, 'hello there');
63
+ await userEvent.click(canvas.getByText('Send'));
64
+ await waitFor(() =>
65
+ expect(args.onSend).toHaveBeenCalledWith(
66
+ 'hello there',
67
+ expect.objectContaining({ files: [] })
68
+ )
69
+ );
70
+ },
71
+ };
72
+
73
+ /**
74
+ * Multiple `sendActions` split the send button — a primary button plus a caret
75
+ * dropdown. The primary is the first action; its `id` is echoed back to `onSend`.
76
+ */
77
+ export const SplitSend: Story = {
78
+ parameters: {
79
+ docs: {
80
+ description: {
81
+ story:
82
+ "Renders the composer with multiple sendActions, splitting Send into a primary Publish button plus a caret dropdown — sending echoes the chosen action's id back to onSend.",
83
+ },
84
+ },
85
+ },
86
+ args: {
87
+ editor: 'plain',
88
+ sendActions: [
89
+ { id: 'publish', label: 'Publish', icon: 'SendPlane2Line' },
90
+ { id: 'draft', label: 'Save draft', icon: 'FileLine' },
91
+ ],
92
+ },
93
+ async play({ canvasElement, args }) {
94
+ const canvas = within(canvasElement);
95
+ const textarea = canvasElement.querySelector('textarea');
96
+ await userEvent.type(textarea!, 'ship it');
97
+ await userEvent.click(canvas.getByText('Publish'));
98
+ await waitFor(() =>
99
+ expect(args.onSend).toHaveBeenCalledWith(
100
+ 'ship it',
101
+ expect.objectContaining({ action: 'publish' })
102
+ )
103
+ );
104
+ },
105
+ };
106
+
107
+ /**
108
+ * A map of the composer's injection slots. The same Composer becomes the Qonsole
109
+ * input or the helpdesk reply box by filling these — so here every slot renders a
110
+ * tag naming itself, to show exactly where each one lands:
111
+ *
112
+ * - `attachMenuItems` — turns the `+` into a dropdown (open it for the entry)
113
+ * - `toolbarStart` — after `+` on the left
114
+ * - `footerActions` — after `toolbarStart`
115
+ * - `rightActions` — just left of Send
116
+ * - `aboveInput` — on top of the editor, inside the bar (Qonsole's reference chips)
117
+ * - `belowInput` — under the whole bar
118
+ */
119
+ const slotTag = (name: string) => <ReqoreTag label={name} size='small' intent='info' />;
120
+
121
+ export const WithSlots: Story = {
122
+ parameters: {
123
+ docs: {
124
+ description: {
125
+ story:
126
+ 'Renders every composer injection slot — attachMenuItems, toolbarStart, footerActions, rightActions, aboveInput, and belowInput — each filled with a self-naming tag, so the story reads as a legible map of where each slot lands.',
127
+ },
128
+ },
129
+ },
130
+ args: {
131
+ editor: 'plain',
132
+ attachMenuItems: () => [
133
+ { label: 'attachMenuItems entry', icon: 'CameraAiLine', onClick: fn() },
134
+ ],
135
+ toolbarStart: slotTag('toolbarStart'),
136
+ footerActions: slotTag('footerActions'),
137
+ rightActions: slotTag('rightActions'),
138
+ aboveInput: slotTag('aboveInput'),
139
+ belowInput: slotTag('belowInput'),
140
+ },
141
+ async play({ canvasElement }) {
142
+ const canvas = within(canvasElement);
143
+ // every slot renders its own marker, so the story is a legible slot map
144
+ for (const slot of [
145
+ 'toolbarStart',
146
+ 'footerActions',
147
+ 'rightActions',
148
+ 'aboveInput',
149
+ 'belowInput',
150
+ ]) {
151
+ await expect(canvas.getByText(slot)).toBeInTheDocument();
152
+ }
153
+ },
154
+ };
155
+
156
+ /**
157
+ * Proof that the composer is configurable enough to *be* the qorus-ide Qonsole
158
+ * input — no fork. Wrapped in qorus-ide's Reqore theme (`main #121212`,
159
+ * `custom1 #762f7e`) and given the same effect + controls the real QonsoleInput
160
+ * uses: the `custom1:darken` gradient bar, an icon-only `custom1` send, and the
161
+ * `+` / `/` / compass controls in the slots. Compare against
162
+ * :6006 story `qonsole-ui-components--business-impact`.
163
+ */
164
+ export const QonsoleReplica: Story = {
165
+ parameters: {
166
+ docs: {
167
+ description: {
168
+ story:
169
+ "Renders the composer configured to replicate qorus-ide's QonsoleInput — a dark custom1 theme, gradient bar, icon-only send, and the slash-commands and design-session compass controls in its slots.",
170
+ },
171
+ },
172
+ },
173
+ decorators: [
174
+ (Story) => (
175
+ <ReqoreUIProvider theme={{ main: '#121212', intents: { custom1: '#762f7e' } }}>
176
+ <div style={{ padding: 20, background: '#121212' }}>
177
+ <Story />
178
+ </div>
179
+ </ReqoreUIProvider>
180
+ ),
181
+ ],
182
+ args: {
183
+ placeholder: "Tell Qorus what you're trying to do…",
184
+ // the exact QonsoleInput bar effect (a custom1 gradient border + fill)
185
+ effect: { gradient: { direction: 'to bottom right', colors: 'custom1:darken:1:0.9' } },
186
+ // icon-only, custom1-themed, minimal — the Qonsole send
187
+ sendActions: [{ id: 'send', icon: 'SendPlane2Line', customTheme: { main: 'custom1' }, minimal: true }],
188
+ // `+` becomes a dropdown once it has extra items (screenshot / capture), like Qonsole
189
+ attachMenuItems: () => [
190
+ { label: 'Take screenshot', icon: 'CameraAiLine', onClick: fn() },
191
+ { label: 'Capture area', icon: 'CropLine', onClick: fn() },
192
+ ],
193
+ // the `/` slash-commands control (a stand-in for the Qonsole completions dropdown)
194
+ toolbarStart: (
195
+ <ReqoreButton
196
+ icon='SlashCommands2'
197
+ minimal
198
+ flat
199
+ size='small'
200
+ customTheme={{ main: 'custom1' }}
201
+ tooltip='Slash commands'
202
+ />
203
+ ),
204
+ // the design-session compass, left of send — exactly where QonsoleInput puts it
205
+ rightActions: (
206
+ <ReqoreButton
207
+ icon='Compass3Line'
208
+ minimal
209
+ flat
210
+ size='small'
211
+ customTheme={{ main: 'custom1' }}
212
+ tooltip='Start a design session'
213
+ />
214
+ ),
215
+ },
216
+ async play({ canvasElement }) {
217
+ // rich editor + the icon-only send (no "Send" label) render
218
+ await expect(canvasElement.querySelector('[contenteditable="true"]')).not.toBeNull();
219
+ await expect(within(canvasElement).queryByText('Send')).not.toBeInTheDocument();
220
+ },
221
+ };
222
+
223
+ /** `disabled` replaces the whole composer with a muted notice. */
224
+ export const Disabled: Story = {
225
+ parameters: {
226
+ docs: {
227
+ description: {
228
+ story:
229
+ 'Renders the disabled state, where the whole composer is replaced by a muted notice showing the disabledReason.',
230
+ },
231
+ },
232
+ },
233
+ args: { disabled: true, disabledReason: 'This channel is read-only.' },
234
+ async play({ canvasElement }) {
235
+ await expect(within(canvasElement).getByText('This channel is read-only.')).toBeInTheDocument();
236
+ await expect(canvasElement.querySelector('textarea')).toBeNull();
237
+ },
238
+ };