@kelpie/ui 0.1.0

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 (704) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +44 -0
  3. package/dist/ServiceStatus.d.ts +6 -0
  4. package/dist/ServiceStatus.d.ts.map +1 -0
  5. package/dist/ServiceStatus.js +35 -0
  6. package/dist/ServiceStatus.js.map +1 -0
  7. package/dist/api/ApiProvider.d.ts +19 -0
  8. package/dist/api/ApiProvider.d.ts.map +1 -0
  9. package/dist/api/ApiProvider.js +18 -0
  10. package/dist/api/ApiProvider.js.map +1 -0
  11. package/dist/api/client.d.ts +83 -0
  12. package/dist/api/client.d.ts.map +1 -0
  13. package/dist/api/client.js +162 -0
  14. package/dist/api/client.js.map +1 -0
  15. package/dist/api/context.d.ts +14 -0
  16. package/dist/api/context.d.ts.map +1 -0
  17. package/dist/api/context.js +20 -0
  18. package/dist/api/context.js.map +1 -0
  19. package/dist/api/errors.d.ts +9 -0
  20. package/dist/api/errors.d.ts.map +1 -0
  21. package/dist/api/errors.js +14 -0
  22. package/dist/api/errors.js.map +1 -0
  23. package/dist/api/health.d.ts +15 -0
  24. package/dist/api/health.d.ts.map +1 -0
  25. package/dist/api/health.js +22 -0
  26. package/dist/api/health.js.map +1 -0
  27. package/dist/api/json.d.ts +3 -0
  28. package/dist/api/json.d.ts.map +1 -0
  29. package/dist/api/json.js +5 -0
  30. package/dist/api/json.js.map +1 -0
  31. package/dist/api/queryClient.d.ts +17 -0
  32. package/dist/api/queryClient.d.ts.map +1 -0
  33. package/dist/api/queryClient.js +33 -0
  34. package/dist/api/queryClient.js.map +1 -0
  35. package/dist/api/resource.d.ts +110 -0
  36. package/dist/api/resource.d.ts.map +1 -0
  37. package/dist/api/resource.js +238 -0
  38. package/dist/api/resource.js.map +1 -0
  39. package/dist/api/resources/account.d.ts +49 -0
  40. package/dist/api/resources/account.d.ts.map +1 -0
  41. package/dist/api/resources/account.js +146 -0
  42. package/dist/api/resources/account.js.map +1 -0
  43. package/dist/api/resources/activities.d.ts +8 -0
  44. package/dist/api/resources/activities.d.ts.map +1 -0
  45. package/dist/api/resources/activities.js +21 -0
  46. package/dist/api/resources/activities.js.map +1 -0
  47. package/dist/api/resources/agentTasks.d.ts +31 -0
  48. package/dist/api/resources/agentTasks.d.ts.map +1 -0
  49. package/dist/api/resources/agentTasks.js +103 -0
  50. package/dist/api/resources/agentTasks.js.map +1 -0
  51. package/dist/api/resources/candidates.d.ts +17 -0
  52. package/dist/api/resources/candidates.d.ts.map +1 -0
  53. package/dist/api/resources/candidates.js +40 -0
  54. package/dist/api/resources/candidates.js.map +1 -0
  55. package/dist/api/resources/companies.d.ts +22 -0
  56. package/dist/api/resources/companies.d.ts.map +1 -0
  57. package/dist/api/resources/companies.js +36 -0
  58. package/dist/api/resources/companies.js.map +1 -0
  59. package/dist/api/resources/dashboard.d.ts +8 -0
  60. package/dist/api/resources/dashboard.d.ts.map +1 -0
  61. package/dist/api/resources/dashboard.js +27 -0
  62. package/dist/api/resources/dashboard.js.map +1 -0
  63. package/dist/api/resources/deals.d.ts +30 -0
  64. package/dist/api/resources/deals.d.ts.map +1 -0
  65. package/dist/api/resources/deals.js +38 -0
  66. package/dist/api/resources/deals.js.map +1 -0
  67. package/dist/api/resources/decisions.d.ts +13 -0
  68. package/dist/api/resources/decisions.d.ts.map +1 -0
  69. package/dist/api/resources/decisions.js +38 -0
  70. package/dist/api/resources/decisions.js.map +1 -0
  71. package/dist/api/resources/forms.d.ts +82 -0
  72. package/dist/api/resources/forms.d.ts.map +1 -0
  73. package/dist/api/resources/forms.js +129 -0
  74. package/dist/api/resources/forms.js.map +1 -0
  75. package/dist/api/resources/handbookPages.d.ts +33 -0
  76. package/dist/api/resources/handbookPages.d.ts.map +1 -0
  77. package/dist/api/resources/handbookPages.js +49 -0
  78. package/dist/api/resources/handbookPages.js.map +1 -0
  79. package/dist/api/resources/importJobs.d.ts +72 -0
  80. package/dist/api/resources/importJobs.d.ts.map +1 -0
  81. package/dist/api/resources/importJobs.js +145 -0
  82. package/dist/api/resources/importJobs.js.map +1 -0
  83. package/dist/api/resources/invites.d.ts +19 -0
  84. package/dist/api/resources/invites.d.ts.map +1 -0
  85. package/dist/api/resources/invites.js +78 -0
  86. package/dist/api/resources/invites.js.map +1 -0
  87. package/dist/api/resources/mcpTools.d.ts +8 -0
  88. package/dist/api/resources/mcpTools.d.ts.map +1 -0
  89. package/dist/api/resources/mcpTools.js +23 -0
  90. package/dist/api/resources/mcpTools.js.map +1 -0
  91. package/dist/api/resources/members.d.ts +40 -0
  92. package/dist/api/resources/members.d.ts.map +1 -0
  93. package/dist/api/resources/members.js +67 -0
  94. package/dist/api/resources/members.js.map +1 -0
  95. package/dist/api/resources/moduleSettings.d.ts +14 -0
  96. package/dist/api/resources/moduleSettings.d.ts.map +1 -0
  97. package/dist/api/resources/moduleSettings.js +43 -0
  98. package/dist/api/resources/moduleSettings.js.map +1 -0
  99. package/dist/api/resources/mutation.d.ts +18 -0
  100. package/dist/api/resources/mutation.d.ts.map +1 -0
  101. package/dist/api/resources/mutation.js +12 -0
  102. package/dist/api/resources/mutation.js.map +1 -0
  103. package/dist/api/resources/notes.d.ts +14 -0
  104. package/dist/api/resources/notes.d.ts.map +1 -0
  105. package/dist/api/resources/notes.js +39 -0
  106. package/dist/api/resources/notes.js.map +1 -0
  107. package/dist/api/resources/opportunities.d.ts +29 -0
  108. package/dist/api/resources/opportunities.d.ts.map +1 -0
  109. package/dist/api/resources/opportunities.js +38 -0
  110. package/dist/api/resources/opportunities.js.map +1 -0
  111. package/dist/api/resources/partnerships.d.ts +33 -0
  112. package/dist/api/resources/partnerships.d.ts.map +1 -0
  113. package/dist/api/resources/partnerships.js +39 -0
  114. package/dist/api/resources/partnerships.js.map +1 -0
  115. package/dist/api/resources/people.d.ts +22 -0
  116. package/dist/api/resources/people.d.ts.map +1 -0
  117. package/dist/api/resources/people.js +36 -0
  118. package/dist/api/resources/people.js.map +1 -0
  119. package/dist/api/resources/pipelineStages.d.ts +22 -0
  120. package/dist/api/resources/pipelineStages.d.ts.map +1 -0
  121. package/dist/api/resources/pipelineStages.js +61 -0
  122. package/dist/api/resources/pipelineStages.js.map +1 -0
  123. package/dist/api/resources/planItems.d.ts +31 -0
  124. package/dist/api/resources/planItems.d.ts.map +1 -0
  125. package/dist/api/resources/planItems.js +60 -0
  126. package/dist/api/resources/planItems.js.map +1 -0
  127. package/dist/api/resources/positions.d.ts +23 -0
  128. package/dist/api/resources/positions.d.ts.map +1 -0
  129. package/dist/api/resources/positions.js +31 -0
  130. package/dist/api/resources/positions.js.map +1 -0
  131. package/dist/api/resources/raises.d.ts +30 -0
  132. package/dist/api/resources/raises.d.ts.map +1 -0
  133. package/dist/api/resources/raises.js +38 -0
  134. package/dist/api/resources/raises.js.map +1 -0
  135. package/dist/api/resources/roles.d.ts +20 -0
  136. package/dist/api/resources/roles.d.ts.map +1 -0
  137. package/dist/api/resources/roles.js +31 -0
  138. package/dist/api/resources/roles.js.map +1 -0
  139. package/dist/api/resources/search.d.ts +12 -0
  140. package/dist/api/resources/search.d.ts.map +1 -0
  141. package/dist/api/resources/search.js +37 -0
  142. package/dist/api/resources/search.js.map +1 -0
  143. package/dist/api/resources/session.d.ts +58 -0
  144. package/dist/api/resources/session.d.ts.map +1 -0
  145. package/dist/api/resources/session.js +157 -0
  146. package/dist/api/resources/session.js.map +1 -0
  147. package/dist/api/resources/webhooks.d.ts +45 -0
  148. package/dist/api/resources/webhooks.d.ts.map +1 -0
  149. package/dist/api/resources/webhooks.js +106 -0
  150. package/dist/api/resources/webhooks.js.map +1 -0
  151. package/dist/api/resources/workspace.d.ts +20 -0
  152. package/dist/api/resources/workspace.d.ts.map +1 -0
  153. package/dist/api/resources/workspace.js +63 -0
  154. package/dist/api/resources/workspace.js.map +1 -0
  155. package/dist/app/KelpieApp.d.ts +18 -0
  156. package/dist/app/KelpieApp.d.ts.map +1 -0
  157. package/dist/app/KelpieApp.js +59 -0
  158. package/dist/app/KelpieApp.js.map +1 -0
  159. package/dist/app/SessionGate.d.ts +14 -0
  160. package/dist/app/SessionGate.d.ts.map +1 -0
  161. package/dist/app/SessionGate.js +33 -0
  162. package/dist/app/SessionGate.js.map +1 -0
  163. package/dist/components/ActivitiesPanel.d.ts +28 -0
  164. package/dist/components/ActivitiesPanel.d.ts.map +1 -0
  165. package/dist/components/ActivitiesPanel.js +75 -0
  166. package/dist/components/ActivitiesPanel.js.map +1 -0
  167. package/dist/components/AgentTasks.d.ts +16 -0
  168. package/dist/components/AgentTasks.d.ts.map +1 -0
  169. package/dist/components/AgentTasks.js +166 -0
  170. package/dist/components/AgentTasks.js.map +1 -0
  171. package/dist/components/Chip.d.ts +10 -0
  172. package/dist/components/Chip.d.ts.map +1 -0
  173. package/dist/components/Chip.js +21 -0
  174. package/dist/components/Chip.js.map +1 -0
  175. package/dist/components/CopyButton.d.ts +7 -0
  176. package/dist/components/CopyButton.d.ts.map +1 -0
  177. package/dist/components/CopyButton.js +30 -0
  178. package/dist/components/CopyButton.js.map +1 -0
  179. package/dist/components/DataTable.d.ts +36 -0
  180. package/dist/components/DataTable.d.ts.map +1 -0
  181. package/dist/components/DataTable.js +43 -0
  182. package/dist/components/DataTable.js.map +1 -0
  183. package/dist/components/DecisionsPanel.d.ts +14 -0
  184. package/dist/components/DecisionsPanel.d.ts.map +1 -0
  185. package/dist/components/DecisionsPanel.js +73 -0
  186. package/dist/components/DecisionsPanel.js.map +1 -0
  187. package/dist/components/DeleteRecord.d.ts +19 -0
  188. package/dist/components/DeleteRecord.d.ts.map +1 -0
  189. package/dist/components/DeleteRecord.js +22 -0
  190. package/dist/components/DeleteRecord.js.map +1 -0
  191. package/dist/components/EntitySearch.d.ts +33 -0
  192. package/dist/components/EntitySearch.d.ts.map +1 -0
  193. package/dist/components/EntitySearch.js +111 -0
  194. package/dist/components/EntitySearch.js.map +1 -0
  195. package/dist/components/ErrorBoundary.d.ts +21 -0
  196. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  197. package/dist/components/ErrorBoundary.js +26 -0
  198. package/dist/components/ErrorBoundary.js.map +1 -0
  199. package/dist/components/InlineEdit.d.ts +37 -0
  200. package/dist/components/InlineEdit.d.ts.map +1 -0
  201. package/dist/components/InlineEdit.js +77 -0
  202. package/dist/components/InlineEdit.js.map +1 -0
  203. package/dist/components/KanbanBoard.d.ts +24 -0
  204. package/dist/components/KanbanBoard.d.ts.map +1 -0
  205. package/dist/components/KanbanBoard.js +92 -0
  206. package/dist/components/KanbanBoard.js.map +1 -0
  207. package/dist/components/MarkdownView.d.ts +4 -0
  208. package/dist/components/MarkdownView.d.ts.map +1 -0
  209. package/dist/components/MarkdownView.js +45 -0
  210. package/dist/components/MarkdownView.js.map +1 -0
  211. package/dist/components/NotesPanel.d.ts +17 -0
  212. package/dist/components/NotesPanel.d.ts.map +1 -0
  213. package/dist/components/NotesPanel.js +53 -0
  214. package/dist/components/NotesPanel.js.map +1 -0
  215. package/dist/components/PageHeader.d.ts +20 -0
  216. package/dist/components/PageHeader.d.ts.map +1 -0
  217. package/dist/components/PageHeader.js +15 -0
  218. package/dist/components/PageHeader.js.map +1 -0
  219. package/dist/components/PhonesField.d.ts +7 -0
  220. package/dist/components/PhonesField.d.ts.map +1 -0
  221. package/dist/components/PhonesField.js +92 -0
  222. package/dist/components/PhonesField.js.map +1 -0
  223. package/dist/components/PlanAttention.d.ts +40 -0
  224. package/dist/components/PlanAttention.d.ts.map +1 -0
  225. package/dist/components/PlanAttention.js +86 -0
  226. package/dist/components/PlanAttention.js.map +1 -0
  227. package/dist/components/PlanPanel.d.ts +18 -0
  228. package/dist/components/PlanPanel.d.ts.map +1 -0
  229. package/dist/components/PlanPanel.js +102 -0
  230. package/dist/components/PlanPanel.js.map +1 -0
  231. package/dist/components/QueryState.d.ts +24 -0
  232. package/dist/components/QueryState.d.ts.map +1 -0
  233. package/dist/components/QueryState.js +34 -0
  234. package/dist/components/QueryState.js.map +1 -0
  235. package/dist/components/RecordTabs.d.ts +16 -0
  236. package/dist/components/RecordTabs.d.ts.map +1 -0
  237. package/dist/components/RecordTabs.js +15 -0
  238. package/dist/components/RecordTabs.js.map +1 -0
  239. package/dist/components/SectionHeader.d.ts +15 -0
  240. package/dist/components/SectionHeader.d.ts.map +1 -0
  241. package/dist/components/SectionHeader.js +14 -0
  242. package/dist/components/SectionHeader.js.map +1 -0
  243. package/dist/components/SegmentedControl.d.ts +13 -0
  244. package/dist/components/SegmentedControl.d.ts.map +1 -0
  245. package/dist/components/SegmentedControl.js +14 -0
  246. package/dist/components/SegmentedControl.js.map +1 -0
  247. package/dist/components/Shell.d.ts +2 -0
  248. package/dist/components/Shell.d.ts.map +1 -0
  249. package/dist/components/Shell.js +143 -0
  250. package/dist/components/Shell.js.map +1 -0
  251. package/dist/components/SidebarField.d.ts +8 -0
  252. package/dist/components/SidebarField.d.ts.map +1 -0
  253. package/dist/components/SidebarField.js +6 -0
  254. package/dist/components/SidebarField.js.map +1 -0
  255. package/dist/components/SocialProfilesField.d.ts +8 -0
  256. package/dist/components/SocialProfilesField.d.ts.map +1 -0
  257. package/dist/components/SocialProfilesField.js +176 -0
  258. package/dist/components/SocialProfilesField.js.map +1 -0
  259. package/dist/components/StageSettings.d.ts +16 -0
  260. package/dist/components/StageSettings.d.ts.map +1 -0
  261. package/dist/components/StageSettings.js +107 -0
  262. package/dist/components/StageSettings.js.map +1 -0
  263. package/dist/components/SummaryBlock.d.ts +12 -0
  264. package/dist/components/SummaryBlock.d.ts.map +1 -0
  265. package/dist/components/SummaryBlock.js +12 -0
  266. package/dist/components/SummaryBlock.js.map +1 -0
  267. package/dist/index.d.ts +90 -0
  268. package/dist/index.d.ts.map +1 -0
  269. package/dist/index.js +55 -0
  270. package/dist/index.js.map +1 -0
  271. package/dist/lib/dates.d.ts +26 -0
  272. package/dist/lib/dates.d.ts.map +1 -0
  273. package/dist/lib/dates.js +71 -0
  274. package/dist/lib/dates.js.map +1 -0
  275. package/dist/lib/money.d.ts +7 -0
  276. package/dist/lib/money.d.ts.map +1 -0
  277. package/dist/lib/money.js +13 -0
  278. package/dist/lib/money.js.map +1 -0
  279. package/dist/lib/names.d.ts +9 -0
  280. package/dist/lib/names.d.ts.map +1 -0
  281. package/dist/lib/names.js +13 -0
  282. package/dist/lib/names.js.map +1 -0
  283. package/dist/lib/plan.d.ts +67 -0
  284. package/dist/lib/plan.d.ts.map +1 -0
  285. package/dist/lib/plan.js +96 -0
  286. package/dist/lib/plan.js.map +1 -0
  287. package/dist/lib/theme.d.ts +19 -0
  288. package/dist/lib/theme.d.ts.map +1 -0
  289. package/dist/lib/theme.js +30 -0
  290. package/dist/lib/theme.js.map +1 -0
  291. package/dist/pages/CompaniesPage.d.ts +2 -0
  292. package/dist/pages/CompaniesPage.d.ts.map +1 -0
  293. package/dist/pages/CompaniesPage.js +77 -0
  294. package/dist/pages/CompaniesPage.js.map +1 -0
  295. package/dist/pages/CompanyDetail.d.ts +2 -0
  296. package/dist/pages/CompanyDetail.d.ts.map +1 -0
  297. package/dist/pages/CompanyDetail.js +177 -0
  298. package/dist/pages/CompanyDetail.js.map +1 -0
  299. package/dist/pages/DealDetail.d.ts +2 -0
  300. package/dist/pages/DealDetail.d.ts.map +1 -0
  301. package/dist/pages/DealDetail.js +192 -0
  302. package/dist/pages/DealDetail.js.map +1 -0
  303. package/dist/pages/DealStageSettingsPage.d.ts +7 -0
  304. package/dist/pages/DealStageSettingsPage.d.ts.map +1 -0
  305. package/dist/pages/DealStageSettingsPage.js +38 -0
  306. package/dist/pages/DealStageSettingsPage.js.map +1 -0
  307. package/dist/pages/DealsPage.d.ts +2 -0
  308. package/dist/pages/DealsPage.d.ts.map +1 -0
  309. package/dist/pages/DealsPage.js +177 -0
  310. package/dist/pages/DealsPage.js.map +1 -0
  311. package/dist/pages/DecisionsPage.d.ts +2 -0
  312. package/dist/pages/DecisionsPage.d.ts.map +1 -0
  313. package/dist/pages/DecisionsPage.js +121 -0
  314. package/dist/pages/DecisionsPage.js.map +1 -0
  315. package/dist/pages/FormDetail.d.ts +2 -0
  316. package/dist/pages/FormDetail.d.ts.map +1 -0
  317. package/dist/pages/FormDetail.js +56 -0
  318. package/dist/pages/FormDetail.js.map +1 -0
  319. package/dist/pages/FormsPage.d.ts +2 -0
  320. package/dist/pages/FormsPage.d.ts.map +1 -0
  321. package/dist/pages/FormsPage.js +67 -0
  322. package/dist/pages/FormsPage.js.map +1 -0
  323. package/dist/pages/FundraisingPage.d.ts +2 -0
  324. package/dist/pages/FundraisingPage.d.ts.map +1 -0
  325. package/dist/pages/FundraisingPage.js +187 -0
  326. package/dist/pages/FundraisingPage.js.map +1 -0
  327. package/dist/pages/HiringPage.d.ts +9 -0
  328. package/dist/pages/HiringPage.d.ts.map +1 -0
  329. package/dist/pages/HiringPage.js +73 -0
  330. package/dist/pages/HiringPage.js.map +1 -0
  331. package/dist/pages/NotFoundPage.d.ts +10 -0
  332. package/dist/pages/NotFoundPage.d.ts.map +1 -0
  333. package/dist/pages/NotFoundPage.js +14 -0
  334. package/dist/pages/NotFoundPage.js.map +1 -0
  335. package/dist/pages/OpportunitiesPage.d.ts +2 -0
  336. package/dist/pages/OpportunitiesPage.d.ts.map +1 -0
  337. package/dist/pages/OpportunitiesPage.js +184 -0
  338. package/dist/pages/OpportunitiesPage.js.map +1 -0
  339. package/dist/pages/OpportunityDetail.d.ts +2 -0
  340. package/dist/pages/OpportunityDetail.d.ts.map +1 -0
  341. package/dist/pages/OpportunityDetail.js +132 -0
  342. package/dist/pages/OpportunityDetail.js.map +1 -0
  343. package/dist/pages/OpportunityStageSettingsPage.d.ts +3 -0
  344. package/dist/pages/OpportunityStageSettingsPage.d.ts.map +1 -0
  345. package/dist/pages/OpportunityStageSettingsPage.js +34 -0
  346. package/dist/pages/OpportunityStageSettingsPage.js.map +1 -0
  347. package/dist/pages/PartnershipDetail.d.ts +2 -0
  348. package/dist/pages/PartnershipDetail.d.ts.map +1 -0
  349. package/dist/pages/PartnershipDetail.js +179 -0
  350. package/dist/pages/PartnershipDetail.js.map +1 -0
  351. package/dist/pages/PartnershipStageSettingsPage.d.ts +3 -0
  352. package/dist/pages/PartnershipStageSettingsPage.d.ts.map +1 -0
  353. package/dist/pages/PartnershipStageSettingsPage.js +34 -0
  354. package/dist/pages/PartnershipStageSettingsPage.js.map +1 -0
  355. package/dist/pages/PartnershipsPage.d.ts +2 -0
  356. package/dist/pages/PartnershipsPage.d.ts.map +1 -0
  357. package/dist/pages/PartnershipsPage.js +182 -0
  358. package/dist/pages/PartnershipsPage.js.map +1 -0
  359. package/dist/pages/PeoplePage.d.ts +10 -0
  360. package/dist/pages/PeoplePage.d.ts.map +1 -0
  361. package/dist/pages/PeoplePage.js +71 -0
  362. package/dist/pages/PeoplePage.js.map +1 -0
  363. package/dist/pages/PersonDetail.d.ts +2 -0
  364. package/dist/pages/PersonDetail.d.ts.map +1 -0
  365. package/dist/pages/PersonDetail.js +193 -0
  366. package/dist/pages/PersonDetail.js.map +1 -0
  367. package/dist/pages/PlanningPage.d.ts +2 -0
  368. package/dist/pages/PlanningPage.d.ts.map +1 -0
  369. package/dist/pages/PlanningPage.js +112 -0
  370. package/dist/pages/PlanningPage.js.map +1 -0
  371. package/dist/pages/RaiseDetail.d.ts +2 -0
  372. package/dist/pages/RaiseDetail.d.ts.map +1 -0
  373. package/dist/pages/RaiseDetail.js +198 -0
  374. package/dist/pages/RaiseDetail.js.map +1 -0
  375. package/dist/pages/RaiseStageSettingsPage.d.ts +3 -0
  376. package/dist/pages/RaiseStageSettingsPage.d.ts.map +1 -0
  377. package/dist/pages/RaiseStageSettingsPage.js +34 -0
  378. package/dist/pages/RaiseStageSettingsPage.js.map +1 -0
  379. package/dist/pages/RoleDetail.d.ts +2 -0
  380. package/dist/pages/RoleDetail.d.ts.map +1 -0
  381. package/dist/pages/RoleDetail.js +177 -0
  382. package/dist/pages/RoleDetail.js.map +1 -0
  383. package/dist/pages/SearchPage.d.ts +2 -0
  384. package/dist/pages/SearchPage.d.ts.map +1 -0
  385. package/dist/pages/SearchPage.js +51 -0
  386. package/dist/pages/SearchPage.js.map +1 -0
  387. package/dist/pages/account/AccountLayout.d.ts +2 -0
  388. package/dist/pages/account/AccountLayout.d.ts.map +1 -0
  389. package/dist/pages/account/AccountLayout.js +25 -0
  390. package/dist/pages/account/AccountLayout.js.map +1 -0
  391. package/dist/pages/account/Field.d.ts +8 -0
  392. package/dist/pages/account/Field.d.ts.map +1 -0
  393. package/dist/pages/account/Field.js +6 -0
  394. package/dist/pages/account/Field.js.map +1 -0
  395. package/dist/pages/account/PreferencesPage.d.ts +2 -0
  396. package/dist/pages/account/PreferencesPage.d.ts.map +1 -0
  397. package/dist/pages/account/PreferencesPage.js +92 -0
  398. package/dist/pages/account/PreferencesPage.js.map +1 -0
  399. package/dist/pages/account/ProfilePage.d.ts +14 -0
  400. package/dist/pages/account/ProfilePage.d.ts.map +1 -0
  401. package/dist/pages/account/ProfilePage.js +71 -0
  402. package/dist/pages/account/ProfilePage.js.map +1 -0
  403. package/dist/pages/account/SecurityPage.d.ts +11 -0
  404. package/dist/pages/account/SecurityPage.d.ts.map +1 -0
  405. package/dist/pages/account/SecurityPage.js +78 -0
  406. package/dist/pages/account/SecurityPage.js.map +1 -0
  407. package/dist/pages/admin/DataPage.d.ts +3 -0
  408. package/dist/pages/admin/DataPage.d.ts.map +1 -0
  409. package/dist/pages/admin/DataPage.js +210 -0
  410. package/dist/pages/admin/DataPage.js.map +1 -0
  411. package/dist/pages/admin/McpPage.d.ts +2 -0
  412. package/dist/pages/admin/McpPage.d.ts.map +1 -0
  413. package/dist/pages/admin/McpPage.js +128 -0
  414. package/dist/pages/admin/McpPage.js.map +1 -0
  415. package/dist/pages/admin/ModulesPage.d.ts +2 -0
  416. package/dist/pages/admin/ModulesPage.d.ts.map +1 -0
  417. package/dist/pages/admin/ModulesPage.js +53 -0
  418. package/dist/pages/admin/ModulesPage.js.map +1 -0
  419. package/dist/pages/admin/TeamPage.d.ts +2 -0
  420. package/dist/pages/admin/TeamPage.d.ts.map +1 -0
  421. package/dist/pages/admin/TeamPage.js +99 -0
  422. package/dist/pages/admin/TeamPage.js.map +1 -0
  423. package/dist/pages/admin/WebhookDeliveries.d.ts +4 -0
  424. package/dist/pages/admin/WebhookDeliveries.d.ts.map +1 -0
  425. package/dist/pages/admin/WebhookDeliveries.js +88 -0
  426. package/dist/pages/admin/WebhookDeliveries.js.map +1 -0
  427. package/dist/pages/admin/WebhooksPage.d.ts +2 -0
  428. package/dist/pages/admin/WebhooksPage.d.ts.map +1 -0
  429. package/dist/pages/admin/WebhooksPage.js +152 -0
  430. package/dist/pages/admin/WebhooksPage.js.map +1 -0
  431. package/dist/pages/admin/WorkspaceSettingsPage.d.ts +2 -0
  432. package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -0
  433. package/dist/pages/admin/WorkspaceSettingsPage.js +117 -0
  434. package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -0
  435. package/dist/pages/auth/AuthForm.d.ts +46 -0
  436. package/dist/pages/auth/AuthForm.d.ts.map +1 -0
  437. package/dist/pages/auth/AuthForm.js +32 -0
  438. package/dist/pages/auth/AuthForm.js.map +1 -0
  439. package/dist/pages/auth/AuthLayout.d.ts +24 -0
  440. package/dist/pages/auth/AuthLayout.d.ts.map +1 -0
  441. package/dist/pages/auth/AuthLayout.js +19 -0
  442. package/dist/pages/auth/AuthLayout.js.map +1 -0
  443. package/dist/pages/auth/ForgotPasswordPage.d.ts +13 -0
  444. package/dist/pages/auth/ForgotPasswordPage.d.ts.map +1 -0
  445. package/dist/pages/auth/ForgotPasswordPage.js +39 -0
  446. package/dist/pages/auth/ForgotPasswordPage.js.map +1 -0
  447. package/dist/pages/auth/JoinPage.d.ts +12 -0
  448. package/dist/pages/auth/JoinPage.d.ts.map +1 -0
  449. package/dist/pages/auth/JoinPage.js +43 -0
  450. package/dist/pages/auth/JoinPage.js.map +1 -0
  451. package/dist/pages/auth/ResetPasswordPage.d.ts +13 -0
  452. package/dist/pages/auth/ResetPasswordPage.d.ts.map +1 -0
  453. package/dist/pages/auth/ResetPasswordPage.js +58 -0
  454. package/dist/pages/auth/ResetPasswordPage.js.map +1 -0
  455. package/dist/pages/auth/SignInPage.d.ts +2 -0
  456. package/dist/pages/auth/SignInPage.d.ts.map +1 -0
  457. package/dist/pages/auth/SignInPage.js +38 -0
  458. package/dist/pages/auth/SignInPage.js.map +1 -0
  459. package/dist/pages/auth/SignUpPage.d.ts +13 -0
  460. package/dist/pages/auth/SignUpPage.d.ts.map +1 -0
  461. package/dist/pages/auth/SignUpPage.js +43 -0
  462. package/dist/pages/auth/SignUpPage.js.map +1 -0
  463. package/dist/pages/candidateFields.d.ts +22 -0
  464. package/dist/pages/candidateFields.d.ts.map +1 -0
  465. package/dist/pages/candidateFields.js +82 -0
  466. package/dist/pages/candidateFields.js.map +1 -0
  467. package/dist/pages/dashboard/DashboardPage.d.ts +2 -0
  468. package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -0
  469. package/dist/pages/dashboard/DashboardPage.js +40 -0
  470. package/dist/pages/dashboard/DashboardPage.js.map +1 -0
  471. package/dist/pages/dashboard/attention.d.ts +41 -0
  472. package/dist/pages/dashboard/attention.d.ts.map +1 -0
  473. package/dist/pages/dashboard/attention.js +146 -0
  474. package/dist/pages/dashboard/attention.js.map +1 -0
  475. package/dist/pages/dashboard/sections.d.ts +20 -0
  476. package/dist/pages/dashboard/sections.d.ts.map +1 -0
  477. package/dist/pages/dashboard/sections.js +60 -0
  478. package/dist/pages/dashboard/sections.js.map +1 -0
  479. package/dist/pages/fields.d.ts +11 -0
  480. package/dist/pages/fields.d.ts.map +1 -0
  481. package/dist/pages/fields.js +17 -0
  482. package/dist/pages/fields.js.map +1 -0
  483. package/dist/pages/forms/EmbedPanel.d.ts +14 -0
  484. package/dist/pages/forms/EmbedPanel.d.ts.map +1 -0
  485. package/dist/pages/forms/EmbedPanel.js +19 -0
  486. package/dist/pages/forms/EmbedPanel.js.map +1 -0
  487. package/dist/pages/forms/FieldsEditor.d.ts +6 -0
  488. package/dist/pages/forms/FieldsEditor.d.ts.map +1 -0
  489. package/dist/pages/forms/FieldsEditor.js +115 -0
  490. package/dist/pages/forms/FieldsEditor.js.map +1 -0
  491. package/dist/pages/forms/FormSettings.d.ts +6 -0
  492. package/dist/pages/forms/FormSettings.d.ts.map +1 -0
  493. package/dist/pages/forms/FormSettings.js +47 -0
  494. package/dist/pages/forms/FormSettings.js.map +1 -0
  495. package/dist/pages/forms/SubmissionsTable.d.ts +8 -0
  496. package/dist/pages/forms/SubmissionsTable.d.ts.map +1 -0
  497. package/dist/pages/forms/SubmissionsTable.js +91 -0
  498. package/dist/pages/forms/SubmissionsTable.js.map +1 -0
  499. package/dist/pages/forms/fieldList.d.ts +70 -0
  500. package/dist/pages/forms/fieldList.d.ts.map +1 -0
  501. package/dist/pages/forms/fieldList.js +126 -0
  502. package/dist/pages/forms/fieldList.js.map +1 -0
  503. package/dist/pages/forms/template.d.ts +18 -0
  504. package/dist/pages/forms/template.d.ts.map +1 -0
  505. package/dist/pages/forms/template.js +34 -0
  506. package/dist/pages/forms/template.js.map +1 -0
  507. package/dist/pages/handbook/HandbookPage.d.ts +2 -0
  508. package/dist/pages/handbook/HandbookPage.d.ts.map +1 -0
  509. package/dist/pages/handbook/HandbookPage.js +197 -0
  510. package/dist/pages/handbook/HandbookPage.js.map +1 -0
  511. package/dist/pages/handbook/tree.d.ts +62 -0
  512. package/dist/pages/handbook/tree.d.ts.map +1 -0
  513. package/dist/pages/handbook/tree.js +222 -0
  514. package/dist/pages/handbook/tree.js.map +1 -0
  515. package/dist/pages/hiringDirectory.d.ts +60 -0
  516. package/dist/pages/hiringDirectory.d.ts.map +1 -0
  517. package/dist/pages/hiringDirectory.js +81 -0
  518. package/dist/pages/hiringDirectory.js.map +1 -0
  519. package/dist/pages/onboarding/HandbookStepPage.d.ts +14 -0
  520. package/dist/pages/onboarding/HandbookStepPage.d.ts.map +1 -0
  521. package/dist/pages/onboarding/HandbookStepPage.js +29 -0
  522. package/dist/pages/onboarding/HandbookStepPage.js.map +1 -0
  523. package/dist/pages/onboarding/InvitesStepPage.d.ts +2 -0
  524. package/dist/pages/onboarding/InvitesStepPage.d.ts.map +1 -0
  525. package/dist/pages/onboarding/InvitesStepPage.js +77 -0
  526. package/dist/pages/onboarding/InvitesStepPage.js.map +1 -0
  527. package/dist/pages/onboarding/WorkspaceStepPage.d.ts +2 -0
  528. package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -0
  529. package/dist/pages/onboarding/WorkspaceStepPage.js +72 -0
  530. package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -0
  531. package/dist/pages/positionDirectory.d.ts +20 -0
  532. package/dist/pages/positionDirectory.d.ts.map +1 -0
  533. package/dist/pages/positionDirectory.js +58 -0
  534. package/dist/pages/positionDirectory.js.map +1 -0
  535. package/dist/registry/UiExtensionProvider.d.ts +12 -0
  536. package/dist/registry/UiExtensionProvider.d.ts.map +1 -0
  537. package/dist/registry/UiExtensionProvider.js +10 -0
  538. package/dist/registry/UiExtensionProvider.js.map +1 -0
  539. package/dist/registry/context.d.ts +31 -0
  540. package/dist/registry/context.d.ts.map +1 -0
  541. package/dist/registry/context.js +45 -0
  542. package/dist/registry/context.js.map +1 -0
  543. package/dist/registry/contributions.d.ts +71 -0
  544. package/dist/registry/contributions.d.ts.map +1 -0
  545. package/dist/registry/contributions.js +25 -0
  546. package/dist/registry/contributions.js.map +1 -0
  547. package/dist/registry/overridable.d.ts +27 -0
  548. package/dist/registry/overridable.d.ts.map +1 -0
  549. package/dist/registry/overridable.js +29 -0
  550. package/dist/registry/overridable.js.map +1 -0
  551. package/dist/registry/registry.d.ts +68 -0
  552. package/dist/registry/registry.d.ts.map +1 -0
  553. package/dist/registry/registry.js +112 -0
  554. package/dist/registry/registry.js.map +1 -0
  555. package/dist/testing/inputs.d.ts +13 -0
  556. package/dist/testing/inputs.d.ts.map +1 -0
  557. package/dist/testing/inputs.js +16 -0
  558. package/dist/testing/inputs.js.map +1 -0
  559. package/dist/testing/stubClient.d.ts +42 -0
  560. package/dist/testing/stubClient.d.ts.map +1 -0
  561. package/dist/testing/stubClient.js +29 -0
  562. package/dist/testing/stubClient.js.map +1 -0
  563. package/package.json +73 -0
  564. package/src/ServiceStatus.tsx +61 -0
  565. package/src/api/ApiProvider.tsx +40 -0
  566. package/src/api/client.ts +267 -0
  567. package/src/api/context.ts +25 -0
  568. package/src/api/errors.ts +14 -0
  569. package/src/api/health.ts +38 -0
  570. package/src/api/json.ts +4 -0
  571. package/src/api/queryClient.ts +35 -0
  572. package/src/api/resource.ts +412 -0
  573. package/src/api/resources/account.ts +220 -0
  574. package/src/api/resources/activities.ts +31 -0
  575. package/src/api/resources/agentTasks.ts +172 -0
  576. package/src/api/resources/candidates.ts +69 -0
  577. package/src/api/resources/companies.ts +72 -0
  578. package/src/api/resources/dashboard.ts +39 -0
  579. package/src/api/resources/deals.ts +82 -0
  580. package/src/api/resources/decisions.ts +60 -0
  581. package/src/api/resources/forms.ts +218 -0
  582. package/src/api/resources/handbookPages.ts +77 -0
  583. package/src/api/resources/importJobs.ts +229 -0
  584. package/src/api/resources/invites.ts +112 -0
  585. package/src/api/resources/mcpTools.ts +28 -0
  586. package/src/api/resources/members.ts +105 -0
  587. package/src/api/resources/moduleSettings.ts +67 -0
  588. package/src/api/resources/mutation.ts +31 -0
  589. package/src/api/resources/notes.ts +62 -0
  590. package/src/api/resources/opportunities.ts +84 -0
  591. package/src/api/resources/partnerships.ts +89 -0
  592. package/src/api/resources/people.ts +72 -0
  593. package/src/api/resources/pipelineStages.ts +93 -0
  594. package/src/api/resources/planItems.ts +103 -0
  595. package/src/api/resources/positions.ts +70 -0
  596. package/src/api/resources/raises.ts +82 -0
  597. package/src/api/resources/roles.ts +65 -0
  598. package/src/api/resources/search.ts +49 -0
  599. package/src/api/resources/session.ts +220 -0
  600. package/src/api/resources/webhooks.ts +157 -0
  601. package/src/api/resources/workspace.ts +81 -0
  602. package/src/app/KelpieApp.tsx +162 -0
  603. package/src/app/SessionGate.tsx +42 -0
  604. package/src/components/ActivitiesPanel.tsx +235 -0
  605. package/src/components/AgentTasks.tsx +473 -0
  606. package/src/components/Chip.tsx +36 -0
  607. package/src/components/CopyButton.tsx +48 -0
  608. package/src/components/DataTable.tsx +209 -0
  609. package/src/components/DecisionsPanel.tsx +233 -0
  610. package/src/components/DeleteRecord.tsx +73 -0
  611. package/src/components/EntitySearch.tsx +268 -0
  612. package/src/components/ErrorBoundary.tsx +58 -0
  613. package/src/components/InlineEdit.tsx +179 -0
  614. package/src/components/KanbanBoard.tsx +234 -0
  615. package/src/components/MarkdownView.tsx +73 -0
  616. package/src/components/NotesPanel.tsx +169 -0
  617. package/src/components/PageHeader.tsx +61 -0
  618. package/src/components/PhonesField.tsx +204 -0
  619. package/src/components/PlanAttention.tsx +249 -0
  620. package/src/components/PlanPanel.tsx +317 -0
  621. package/src/components/QueryState.tsx +83 -0
  622. package/src/components/RecordTabs.tsx +69 -0
  623. package/src/components/SectionHeader.tsx +63 -0
  624. package/src/components/SegmentedControl.tsx +48 -0
  625. package/src/components/Shell.tsx +300 -0
  626. package/src/components/SidebarField.tsx +18 -0
  627. package/src/components/SocialProfilesField.tsx +356 -0
  628. package/src/components/StageSettings.tsx +319 -0
  629. package/src/components/SummaryBlock.tsx +27 -0
  630. package/src/index.ts +190 -0
  631. package/src/lib/dates.ts +90 -0
  632. package/src/lib/money.ts +12 -0
  633. package/src/lib/names.ts +13 -0
  634. package/src/lib/plan.ts +147 -0
  635. package/src/lib/theme.ts +53 -0
  636. package/src/pages/CompaniesPage.tsx +143 -0
  637. package/src/pages/CompanyDetail.tsx +502 -0
  638. package/src/pages/DealDetail.tsx +512 -0
  639. package/src/pages/DealStageSettingsPage.tsx +67 -0
  640. package/src/pages/DealsPage.tsx +342 -0
  641. package/src/pages/DecisionsPage.tsx +211 -0
  642. package/src/pages/FormDetail.tsx +130 -0
  643. package/src/pages/FormsPage.tsx +151 -0
  644. package/src/pages/FundraisingPage.tsx +354 -0
  645. package/src/pages/HiringPage.tsx +169 -0
  646. package/src/pages/NotFoundPage.tsx +27 -0
  647. package/src/pages/OpportunitiesPage.tsx +349 -0
  648. package/src/pages/OpportunityDetail.tsx +337 -0
  649. package/src/pages/OpportunityStageSettingsPage.tsx +63 -0
  650. package/src/pages/PartnershipDetail.tsx +490 -0
  651. package/src/pages/PartnershipStageSettingsPage.tsx +63 -0
  652. package/src/pages/PartnershipsPage.tsx +353 -0
  653. package/src/pages/PeoplePage.tsx +145 -0
  654. package/src/pages/PersonDetail.tsx +526 -0
  655. package/src/pages/PlanningPage.tsx +318 -0
  656. package/src/pages/RaiseDetail.tsx +498 -0
  657. package/src/pages/RaiseStageSettingsPage.tsx +63 -0
  658. package/src/pages/RoleDetail.tsx +455 -0
  659. package/src/pages/SearchPage.tsx +135 -0
  660. package/src/pages/account/AccountLayout.tsx +38 -0
  661. package/src/pages/account/Field.tsx +20 -0
  662. package/src/pages/account/PreferencesPage.tsx +224 -0
  663. package/src/pages/account/ProfilePage.tsx +147 -0
  664. package/src/pages/account/SecurityPage.tsx +237 -0
  665. package/src/pages/admin/DataPage.tsx +772 -0
  666. package/src/pages/admin/McpPage.tsx +404 -0
  667. package/src/pages/admin/ModulesPage.tsx +113 -0
  668. package/src/pages/admin/TeamPage.tsx +386 -0
  669. package/src/pages/admin/WebhookDeliveries.tsx +184 -0
  670. package/src/pages/admin/WebhooksPage.tsx +443 -0
  671. package/src/pages/admin/WorkspaceSettingsPage.tsx +274 -0
  672. package/src/pages/auth/AuthForm.tsx +118 -0
  673. package/src/pages/auth/AuthLayout.tsx +74 -0
  674. package/src/pages/auth/ForgotPasswordPage.tsx +80 -0
  675. package/src/pages/auth/JoinPage.tsx +85 -0
  676. package/src/pages/auth/ResetPasswordPage.tsx +124 -0
  677. package/src/pages/auth/SignInPage.tsx +83 -0
  678. package/src/pages/auth/SignUpPage.tsx +93 -0
  679. package/src/pages/candidateFields.tsx +175 -0
  680. package/src/pages/dashboard/DashboardPage.tsx +108 -0
  681. package/src/pages/dashboard/attention.ts +206 -0
  682. package/src/pages/dashboard/sections.tsx +269 -0
  683. package/src/pages/fields.ts +21 -0
  684. package/src/pages/forms/EmbedPanel.tsx +95 -0
  685. package/src/pages/forms/FieldsEditor.tsx +412 -0
  686. package/src/pages/forms/FormSettings.tsx +159 -0
  687. package/src/pages/forms/SubmissionsTable.tsx +171 -0
  688. package/src/pages/forms/fieldList.ts +209 -0
  689. package/src/pages/forms/template.ts +37 -0
  690. package/src/pages/handbook/HandbookPage.tsx +500 -0
  691. package/src/pages/handbook/tree.ts +327 -0
  692. package/src/pages/hiringDirectory.ts +146 -0
  693. package/src/pages/onboarding/HandbookStepPage.tsx +75 -0
  694. package/src/pages/onboarding/InvitesStepPage.tsx +180 -0
  695. package/src/pages/onboarding/WorkspaceStepPage.tsx +122 -0
  696. package/src/pages/positionDirectory.ts +98 -0
  697. package/src/registry/UiExtensionProvider.tsx +20 -0
  698. package/src/registry/context.ts +67 -0
  699. package/src/registry/contributions.ts +89 -0
  700. package/src/registry/overridable.ts +62 -0
  701. package/src/registry/registry.ts +204 -0
  702. package/src/styles.css +175 -0
  703. package/src/testing/inputs.ts +18 -0
  704. package/src/testing/stubClient.ts +78 -0
@@ -0,0 +1,412 @@
1
+ import {
2
+ keepPreviousData,
3
+ useInfiniteQuery,
4
+ useMutation,
5
+ useQuery,
6
+ useQueryClient,
7
+ } from '@tanstack/react-query'
8
+ import type { InfiniteData, QueryClient } from '@tanstack/react-query'
9
+
10
+ import { ApiError } from './client.ts'
11
+ import type { Decoder, Page, QueryParameters } from './client.ts'
12
+ import { useApiClient } from './context.ts'
13
+ import { toError } from './errors.ts'
14
+
15
+ /**
16
+ * The read and write hooks for one `/v1` collection.
17
+ *
18
+ * Every CRM resource is the same five operations over the same list envelope,
19
+ * so they are built once here and configured per resource. A resource module
20
+ * supplies its path, its decoder, and its two body builders; it writes no cache
21
+ * handling of its own.
22
+ *
23
+ * Pages see the three result types below and never import from
24
+ * `@tanstack/react-query` directly. That is deliberate: it keeps page code short
25
+ * and leaves the cache library replaceable without touching a page.
26
+ */
27
+
28
+ /** A list, one page at a time. Nothing is truncated in silence: `hasMore` says so. */
29
+ export interface RecordListResult<TRecord> {
30
+ readonly records: readonly TRecord[]
31
+ readonly isLoading: boolean
32
+ readonly error: Error | null
33
+ readonly hasMore: boolean
34
+ readonly isLoadingMore: boolean
35
+ readonly loadMore: () => void
36
+ }
37
+
38
+ export interface RecordResult<TRecord> {
39
+ readonly record: TRecord | undefined
40
+ readonly isLoading: boolean
41
+ readonly error: Error | null
42
+ /** The record is not in this workspace, which `api.md` makes indistinguishable from not existing. */
43
+ readonly isNotFound: boolean
44
+ }
45
+
46
+ export interface MutationResult<TInput, TOutput> {
47
+ /** Fire and forget. A failure lands in `error` rather than in an unhandled rejection. */
48
+ readonly run: (input: TInput) => void
49
+ /** Await the result, for a caller that navigates or chains on success. Rejects on failure. */
50
+ readonly runAsync: (input: TInput) => Promise<TOutput>
51
+ readonly isPending: boolean
52
+ readonly error: Error | null
53
+ }
54
+
55
+ export interface UpdateArguments<TUpdateInput> {
56
+ readonly id: string
57
+ readonly changes: TUpdateInput
58
+ }
59
+
60
+ export interface PatchResult<TChanges> {
61
+ /** Fire and forget, bound to one record's id. A failure lands in `error`. */
62
+ readonly patch: (changes: TChanges) => void
63
+ readonly error: Error | null
64
+ }
65
+
66
+ export interface ListOptions {
67
+ /**
68
+ * Set false to hold the request back. A list filtered by a set of ids has
69
+ * nothing to ask until those ids are known, and asking with the filter omitted
70
+ * would answer with every record instead of none.
71
+ */
72
+ readonly enabled?: boolean
73
+ }
74
+
75
+ export interface ResourceHooks<TRecord, TCreateInput, TUpdateInput>
76
+ extends ReadOnlyResourceHooks<TRecord> {
77
+ useCreate(): MutationResult<TCreateInput, TRecord>
78
+ useUpdate(): MutationResult<UpdateArguments<TUpdateInput>, TRecord>
79
+ useRemove(): MutationResult<string, void>
80
+ }
81
+
82
+ /** What a collection with no write verbs offers. Activities are the case: the table is append-only. */
83
+ export interface ReadOnlyResourceHooks<TRecord> {
84
+ useList(query?: QueryParameters, options?: ListOptions): RecordListResult<TRecord>
85
+ useRecord(id: string | undefined): RecordResult<TRecord>
86
+ }
87
+
88
+ export interface ReadOnlyResourceDefinition<TRecord> {
89
+ /** Cache key root. The plural resource name, e.g. `activities`. */
90
+ readonly name: string
91
+ /** Path under the API base, e.g. `/activities`. */
92
+ readonly path: string
93
+ readonly decode: Decoder<TRecord>
94
+ }
95
+
96
+ export interface ResourceDefinition<TRecord, TCreateInput, TUpdateInput>
97
+ extends ReadOnlyResourceDefinition<TRecord> {
98
+ readonly createBody: (input: TCreateInput) => unknown
99
+ readonly updateBody: (input: TUpdateInput) => unknown
100
+ /**
101
+ * Other resources whose cached lists a write here can invalidate.
102
+ *
103
+ * A join record is the case that needs it. `GET /v1/people?company_id=` is a
104
+ * list of people, so creating a Position changes its contents without
105
+ * touching a single person, and a company page that only refetched positions
106
+ * would render the new row against a name it never fetched.
107
+ */
108
+ readonly alsoInvalidates?: readonly string[]
109
+ }
110
+
111
+ type ListData<TRecord> = InfiniteData<Page<TRecord>, string | null>
112
+
113
+ interface ResourceKeys {
114
+ readonly all: readonly unknown[]
115
+ readonly lists: readonly unknown[]
116
+ list(query: QueryParameters): readonly unknown[]
117
+ detail(id: string): readonly unknown[]
118
+ }
119
+
120
+ function keysFor(name: string): ResourceKeys {
121
+ return {
122
+ all: [name],
123
+ lists: [name, 'list'],
124
+ list: (query) => [name, 'list', query],
125
+ detail: (id) => [name, 'detail', id],
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Applies a partial update to a record.
131
+ *
132
+ * `undefined` means "not sent" and `null` means "clear this field", per
133
+ * `api.md`, so an undefined value must leave the existing one alone rather than
134
+ * overwrite it.
135
+ */
136
+ function mergeDefined<TRecord extends object>(record: TRecord, changes: Partial<TRecord>): TRecord {
137
+ const merged = { ...record }
138
+
139
+ for (const [key, value] of Object.entries(changes)) {
140
+ if (value !== undefined) {
141
+ Object.assign(merged, { [key]: value })
142
+ }
143
+ }
144
+
145
+ return merged
146
+ }
147
+
148
+ /** Rewrites one record everywhere it is cached: its own entry, and every list page holding it. */
149
+ function writeRecordEverywhere<TRecord extends { readonly id: string }>(
150
+ queryClient: QueryClient,
151
+ keys: ResourceKeys,
152
+ record: TRecord,
153
+ ): void {
154
+ queryClient.setQueryData(keys.detail(record.id), record)
155
+ queryClient.setQueriesData<ListData<TRecord>>({ queryKey: keys.lists }, (data) =>
156
+ data === undefined
157
+ ? data
158
+ : {
159
+ ...data,
160
+ pages: data.pages.map((page) => ({
161
+ ...page,
162
+ items: page.items.map((item) => (item.id === record.id ? record : item)),
163
+ })),
164
+ },
165
+ )
166
+ }
167
+
168
+ function removeRecordEverywhere<TRecord extends { readonly id: string }>(
169
+ queryClient: QueryClient,
170
+ keys: ResourceKeys,
171
+ id: string,
172
+ ): void {
173
+ queryClient.removeQueries({ queryKey: keys.detail(id) })
174
+ queryClient.setQueriesData<ListData<TRecord>>({ queryKey: keys.lists }, (data) =>
175
+ data === undefined
176
+ ? data
177
+ : {
178
+ ...data,
179
+ pages: data.pages.map((page) => ({
180
+ ...page,
181
+ items: page.items.filter((item) => item.id !== id),
182
+ })),
183
+ },
184
+ )
185
+ }
186
+
187
+ /**
188
+ * The read half: `useList` and `useRecord`, and nothing that writes.
189
+ *
190
+ * Split out because a collection can be read-only. `createResourceHooks` builds
191
+ * on this rather than repeating it, so both kinds of resource page, cache, and
192
+ * report a 404 identically.
193
+ */
194
+ export function createReadOnlyResourceHooks<TRecord>(
195
+ definition: ReadOnlyResourceDefinition<TRecord>,
196
+ ): ReadOnlyResourceHooks<TRecord> {
197
+ const keys = keysFor(definition.name)
198
+
199
+ function useList(query: QueryParameters = {}, options: ListOptions = {}): RecordListResult<TRecord> {
200
+ const client = useApiClient()
201
+ const enabled = options.enabled ?? true
202
+ const result = useInfiniteQuery({
203
+ queryKey: keys.list(query),
204
+ queryFn: ({ pageParam }) =>
205
+ client.list(definition.path, definition.decode, {
206
+ ...query,
207
+ ...(pageParam === null ? {} : { cursor: pageParam }),
208
+ }),
209
+ initialPageParam: null as string | null,
210
+ getNextPageParam: (lastPage) => lastPage.nextCursor,
211
+ // Without this a keystroke in the filter box blanks the table while the
212
+ // next query runs, which reads as "no results" for as long as it takes.
213
+ placeholderData: keepPreviousData,
214
+ enabled,
215
+ })
216
+
217
+ return {
218
+ records: result.data?.pages.flatMap((page) => page.items) ?? [],
219
+ // A disabled query stays pending forever, which is not the same as loading.
220
+ isLoading: result.isPending && enabled,
221
+ error: toError(result.error),
222
+ hasMore: result.hasNextPage,
223
+ isLoadingMore: result.isFetchingNextPage,
224
+ loadMore: () => {
225
+ void result.fetchNextPage()
226
+ },
227
+ }
228
+ }
229
+
230
+ function useRecord(id: string | undefined): RecordResult<TRecord> {
231
+ const client = useApiClient()
232
+ const result = useQuery({
233
+ queryKey: keys.detail(id ?? ''),
234
+ queryFn: () => client.get(`${definition.path}/${id ?? ''}`, definition.decode),
235
+ enabled: id !== undefined,
236
+ })
237
+
238
+ return {
239
+ record: result.data,
240
+ isLoading: result.isPending && id !== undefined,
241
+ error: toError(result.error),
242
+ isNotFound: result.error instanceof ApiError && result.error.status === 404,
243
+ }
244
+ }
245
+
246
+ return { useList, useRecord }
247
+ }
248
+
249
+ export function createResourceHooks<
250
+ TRecord extends { readonly id: string },
251
+ TCreateInput,
252
+ TUpdateInput extends Partial<TRecord>,
253
+ >(
254
+ definition: ResourceDefinition<TRecord, TCreateInput, TUpdateInput>,
255
+ ): ResourceHooks<TRecord, TCreateInput, TUpdateInput> {
256
+ const keys = keysFor(definition.name)
257
+ const related = (definition.alsoInvalidates ?? []).map(keysFor)
258
+ const { useList, useRecord } = createReadOnlyResourceHooks(definition)
259
+
260
+ /**
261
+ * Marks this resource's lists stale, and the related resources' with them.
262
+ * Applied to every write rather than only to create and delete: a resource
263
+ * that declares a relation has one, whichever verb reaches it.
264
+ */
265
+ function invalidateLists(queryClient: QueryClient): void {
266
+ for (const target of [keys, ...related]) {
267
+ void queryClient.invalidateQueries({ queryKey: target.lists })
268
+ }
269
+ }
270
+
271
+ function useCreate(): MutationResult<TCreateInput, TRecord> {
272
+ const client = useApiClient()
273
+ const queryClient = useQueryClient()
274
+ const mutation = useMutation({
275
+ mutationFn: (input: TCreateInput) =>
276
+ client.post(definition.path, definition.createBody(input), definition.decode),
277
+ // No optimistic insert: the id comes from the server, and the caller
278
+ // usually navigates straight to the new record. A placeholder id would be
279
+ // a route to a record that does not exist yet.
280
+ onSuccess: (record) => {
281
+ queryClient.setQueryData(keys.detail(record.id), record)
282
+ },
283
+ onSettled: () => {
284
+ invalidateLists(queryClient)
285
+ },
286
+ })
287
+
288
+ return {
289
+ run: (input) => {
290
+ mutation.mutate(input)
291
+ },
292
+ runAsync: (input) => mutation.mutateAsync(input),
293
+ isPending: mutation.isPending,
294
+ error: toError(mutation.error),
295
+ }
296
+ }
297
+
298
+ function useUpdate(): MutationResult<UpdateArguments<TUpdateInput>, TRecord> {
299
+ const client = useApiClient()
300
+ const queryClient = useQueryClient()
301
+ const mutation = useMutation({
302
+ mutationFn: ({ id, changes }: UpdateArguments<TUpdateInput>) =>
303
+ client.patch(`${definition.path}/${id}`, definition.updateBody(changes), definition.decode),
304
+
305
+ // Inline editing is the whole interaction on a detail page, so the field
306
+ // has to settle the moment it is committed. The snapshot is what makes
307
+ // that safe: a rejected PATCH puts the old value back.
308
+ onMutate: async ({ id, changes }) => {
309
+ await queryClient.cancelQueries({ queryKey: keys.detail(id) })
310
+ const previous = queryClient.getQueryData<TRecord>(keys.detail(id))
311
+
312
+ if (previous !== undefined) {
313
+ writeRecordEverywhere(queryClient, keys, mergeDefined(previous, changes))
314
+ }
315
+
316
+ return { previous }
317
+ },
318
+
319
+ onError: (_error, _arguments_, context) => {
320
+ if (context?.previous !== undefined) {
321
+ writeRecordEverywhere(queryClient, keys, context.previous)
322
+ }
323
+ },
324
+
325
+ onSuccess: (record) => {
326
+ writeRecordEverywhere(queryClient, keys, record)
327
+ },
328
+
329
+ onSettled: (_record, _error, { id }) => {
330
+ void queryClient.invalidateQueries({ queryKey: keys.detail(id) })
331
+ invalidateLists(queryClient)
332
+ },
333
+ })
334
+
335
+ return {
336
+ run: (input) => {
337
+ mutation.mutate(input)
338
+ },
339
+ runAsync: (input) => mutation.mutateAsync(input),
340
+ isPending: mutation.isPending,
341
+ error: toError(mutation.error),
342
+ }
343
+ }
344
+
345
+ function useRemove(): MutationResult<string, void> {
346
+ const client = useApiClient()
347
+ const queryClient = useQueryClient()
348
+ const mutation = useMutation({
349
+ mutationFn: (id: string) => client.delete(`${definition.path}/${id}`),
350
+
351
+ onMutate: async (id) => {
352
+ await queryClient.cancelQueries({ queryKey: keys.all })
353
+ const previous = queryClient.getQueryData<TRecord>(keys.detail(id))
354
+ const previousLists = queryClient.getQueriesData<ListData<TRecord>>({ queryKey: keys.lists })
355
+
356
+ removeRecordEverywhere<TRecord>(queryClient, keys, id)
357
+
358
+ return { previous, previousLists }
359
+ },
360
+
361
+ onError: (_error, id, context) => {
362
+ for (const [key, data] of context?.previousLists ?? []) {
363
+ queryClient.setQueryData(key, data)
364
+ }
365
+
366
+ if (context?.previous !== undefined) {
367
+ queryClient.setQueryData(keys.detail(id), context.previous)
368
+ }
369
+ },
370
+
371
+ onSettled: () => {
372
+ invalidateLists(queryClient)
373
+ },
374
+ })
375
+
376
+ return {
377
+ run: (id) => {
378
+ mutation.mutate(id)
379
+ },
380
+ runAsync: (id) => mutation.mutateAsync(id),
381
+ isPending: mutation.isPending,
382
+ error: toError(mutation.error),
383
+ }
384
+ }
385
+
386
+ return { useList, useRecord, useCreate, useUpdate, useRemove }
387
+ }
388
+
389
+ /**
390
+ * Binds a resource's `useUpdate` hook to one record's id, for a detail page's
391
+ * inline edits.
392
+ *
393
+ * Every detail page had its own three-line `use<X>Patch` doing exactly this,
394
+ * and every one of them discarded `update.error`. `InlineEdit`'s `onChange` has
395
+ * no return value to reject, so a failed `PATCH` — a duplicate email or domain,
396
+ * a dropped connection — had nowhere left to surface: the field just reverted
397
+ * to its old value with no explanation. Callers now get the error back and
398
+ * decide where to show it.
399
+ */
400
+ export function usePatch<TRecord extends { readonly id: string }, TChanges>(
401
+ useUpdate: () => MutationResult<UpdateArguments<TChanges>, TRecord>,
402
+ record: TRecord,
403
+ ): PatchResult<TChanges> {
404
+ const update = useUpdate()
405
+
406
+ return {
407
+ patch: (changes) => {
408
+ update.run({ id: record.id, changes })
409
+ },
410
+ error: update.error,
411
+ }
412
+ }
@@ -0,0 +1,220 @@
1
+ import {
2
+ accountPreferencesSchema,
3
+ accountSchema,
4
+ accountSessionSchema,
5
+ changePasswordBody,
6
+ updateAccountBody,
7
+ updateAccountPreferencesBody,
8
+ } from '@kelpie/schemas'
9
+ import type {
10
+ Account,
11
+ AccountPreferences,
12
+ AccountSession,
13
+ ChangePasswordInput,
14
+ ThemePreference,
15
+ UpdateAccountInput,
16
+ UpdateAccountPreferencesInput,
17
+ } from '@kelpie/schemas'
18
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
19
+ import { useEffect, useState } from 'react'
20
+
21
+ import { applyTheme, getStoredTheme, setStoredTheme, watchSystemTheme } from '../../lib/theme.ts'
22
+ import { useApiClient } from '../context.ts'
23
+ import { toError } from '../errors.ts'
24
+ import type { MutationResult } from '../resource.ts'
25
+ import { asMutationResult } from './mutation.ts'
26
+
27
+ /**
28
+ * The signed-in person, as the `/account/*` pages read and write them.
29
+ *
30
+ * Not CRM resources, so none of these go through `createResourceHooks`: there is
31
+ * no collection and no id in a path. They are also not workspace-scoped, which
32
+ * is why nothing here keys on the session's workspace: renaming an account
33
+ * renames it everywhere it is a member.
34
+ */
35
+
36
+ const ACCOUNT_KEY = ['account'] as const
37
+ const PREFERENCES_KEY = ['account', 'preferences'] as const
38
+ const SESSIONS_KEY = ['account', 'sessions'] as const
39
+
40
+ export interface AccountState {
41
+ readonly account: Account | undefined
42
+ readonly isLoading: boolean
43
+ readonly error: Error | null
44
+ }
45
+
46
+ export function useAccount(): AccountState {
47
+ const client = useApiClient()
48
+ const result = useQuery({
49
+ queryKey: ACCOUNT_KEY,
50
+ queryFn: () => client.get('/account', accountSchema.parse),
51
+ })
52
+
53
+ return { account: result.data, isLoading: result.isPending, error: toError(result.error) }
54
+ }
55
+
56
+ export function useUpdateAccount(): MutationResult<UpdateAccountInput, Account> {
57
+ const client = useApiClient()
58
+ const queryClient = useQueryClient()
59
+ const mutation = useMutation({
60
+ mutationFn: (input: UpdateAccountInput) =>
61
+ client.patch('/account', updateAccountBody(input), accountSchema.parse),
62
+ onSuccess: async (account) => {
63
+ queryClient.setQueryData(ACCOUNT_KEY, account)
64
+ // The team page lists this person by name and address out of the member
65
+ // list, which the account write knows nothing about.
66
+ await queryClient.invalidateQueries({ queryKey: ['members'] })
67
+ },
68
+ })
69
+
70
+ return asMutationResult(mutation)
71
+ }
72
+
73
+ export interface AccountPreferencesState {
74
+ readonly preferences: AccountPreferences | undefined
75
+ readonly isLoading: boolean
76
+ readonly error: Error | null
77
+ }
78
+
79
+ export function useAccountPreferences(): AccountPreferencesState {
80
+ const client = useApiClient()
81
+ const result = useQuery({
82
+ queryKey: PREFERENCES_KEY,
83
+ queryFn: () => client.get('/account/preferences', accountPreferencesSchema.parse),
84
+ })
85
+
86
+ return { preferences: result.data, isLoading: result.isPending, error: toError(result.error) }
87
+ }
88
+
89
+ export function useUpdateAccountPreferences(): MutationResult<
90
+ UpdateAccountPreferencesInput,
91
+ AccountPreferences
92
+ > {
93
+ const client = useApiClient()
94
+ const queryClient = useQueryClient()
95
+ const mutation = useMutation({
96
+ mutationFn: (input: UpdateAccountPreferencesInput) =>
97
+ client.patch(
98
+ '/account/preferences',
99
+ updateAccountPreferencesBody(input),
100
+ accountPreferencesSchema.parse,
101
+ ),
102
+ onSuccess: (preferences) => {
103
+ queryClient.setQueryData(PREFERENCES_KEY, preferences)
104
+ },
105
+ // A failed write leaves an optimistic theme on screen that the account does
106
+ // not hold. Ask the service what is true rather than guessing back.
107
+ onError: async () => {
108
+ await queryClient.invalidateQueries({ queryKey: PREFERENCES_KEY })
109
+ },
110
+ })
111
+
112
+ return asMutationResult(mutation)
113
+ }
114
+
115
+ export interface AccountSessionsState {
116
+ readonly sessions: readonly AccountSession[]
117
+ readonly isLoading: boolean
118
+ readonly error: Error | null
119
+ }
120
+
121
+ /** Where this account is signed in. The caller's own session is marked `current`. */
122
+ export function useAccountSessions(): AccountSessionsState {
123
+ const client = useApiClient()
124
+ const result = useQuery({
125
+ queryKey: SESSIONS_KEY,
126
+ queryFn: () => client.list('/auth/sessions', accountSessionSchema.parse),
127
+ })
128
+
129
+ return {
130
+ sessions: result.data?.items ?? [],
131
+ isLoading: result.isPending,
132
+ error: toError(result.error),
133
+ }
134
+ }
135
+
136
+ export function useRevokeAccountSession(): MutationResult<string, void> {
137
+ const client = useApiClient()
138
+ const queryClient = useQueryClient()
139
+ const mutation = useMutation({
140
+ mutationFn: (sessionId: string) => client.delete(`/auth/sessions/${sessionId}`),
141
+ onSuccess: async () => {
142
+ await queryClient.invalidateQueries({ queryKey: SESSIONS_KEY })
143
+ },
144
+ })
145
+
146
+ return asMutationResult(mutation)
147
+ }
148
+
149
+ /**
150
+ * Changes the password and ends every other session, which is what the service
151
+ * does, so the session list on the same page is refetched rather than left
152
+ * showing devices that are no longer signed in.
153
+ */
154
+ export function useChangePassword(): MutationResult<ChangePasswordInput, void> {
155
+ const client = useApiClient()
156
+ const queryClient = useQueryClient()
157
+ const mutation = useMutation({
158
+ mutationFn: (input: ChangePasswordInput) =>
159
+ client.patchEmpty('/auth/password', changePasswordBody(input)),
160
+ onSuccess: async () => {
161
+ await queryClient.invalidateQueries({ queryKey: SESSIONS_KEY })
162
+ },
163
+ })
164
+
165
+ return asMutationResult(mutation)
166
+ }
167
+
168
+ export interface ThemeControl {
169
+ readonly theme: ThemePreference
170
+ readonly setTheme: (theme: ThemePreference) => void
171
+ }
172
+
173
+ /**
174
+ * The theme, applied to the document and stored on the account.
175
+ *
176
+ * The account's preference is the source of truth, so the theme follows the
177
+ * person to a new browser. `localStorage` seeds the first paint only: waiting
178
+ * for the request would render the default theme and then correct itself on
179
+ * every cold load.
180
+ *
181
+ * The value comes from the query cache rather than component state, because
182
+ * more than one control changes it. The shell's toggle and the preferences page
183
+ * are separate components, and two `useState` copies of one preference disagree
184
+ * the moment either is clicked.
185
+ */
186
+ export function useTheme(): ThemeControl {
187
+ const queryClient = useQueryClient()
188
+ const { preferences } = useAccountPreferences()
189
+ const update = useUpdateAccountPreferences()
190
+ const [firstPaintTheme] = useState<ThemePreference>(() => getStoredTheme())
191
+ const theme = preferences?.theme ?? firstPaintTheme
192
+
193
+ useEffect(() => {
194
+ applyTheme(theme)
195
+ // Kept current so the next cold load in this browser paints the right theme
196
+ // before the request answers.
197
+ setStoredTheme(theme)
198
+ }, [theme])
199
+
200
+ useEffect(() => {
201
+ if (theme !== 'system') {
202
+ return
203
+ }
204
+
205
+ return watchSystemTheme(() => {
206
+ applyTheme('system')
207
+ })
208
+ }, [theme])
209
+
210
+ function setTheme(next: ThemePreference): void {
211
+ // Applied to the cache first: the click is about something visible, and the
212
+ // eye should not wait on a round trip. `onError` puts the truth back.
213
+ queryClient.setQueryData(PREFERENCES_KEY, (current: AccountPreferences | undefined) =>
214
+ current === undefined ? current : { ...current, theme: next },
215
+ )
216
+ update.run({ theme: next })
217
+ }
218
+
219
+ return { theme, setTheme }
220
+ }
@@ -0,0 +1,31 @@
1
+ import { activitySchema } from '@kelpie/schemas'
2
+ import type { Activity, RecordTargetType } from '@kelpie/schemas'
3
+
4
+ import { createReadOnlyResourceHooks } from '../resource.ts'
5
+ import type { RecordListResult } from '../resource.ts'
6
+
7
+ /**
8
+ * `/v1/activities`, read-only.
9
+ *
10
+ * No write hooks, because the API has no write routes: activity is emitted by
11
+ * the service that made the change, in the same transaction, and the table is
12
+ * append-only.
13
+ *
14
+ * The roll-up a person's or company's timeline shows is resolved server-side.
15
+ * Nothing here fetches related deals to merge them in.
16
+ */
17
+
18
+ const activities = createReadOnlyResourceHooks<Activity>({
19
+ name: 'activities',
20
+ path: '/activities',
21
+ decode: activitySchema.parse,
22
+ })
23
+
24
+ export interface ActivityTimeline {
25
+ readonly targetType: RecordTargetType
26
+ readonly targetId: string
27
+ }
28
+
29
+ export function useActivities(timeline: ActivityTimeline): RecordListResult<Activity> {
30
+ return activities.useList({ target_type: timeline.targetType, target_id: timeline.targetId })
31
+ }