agim-cli 1.2.131 → 1.2.133

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 (188) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/core/llm/agent-loop.d.ts.map +1 -1
  3. package/dist/core/llm/agent-loop.js +16 -5
  4. package/dist/core/llm/agent-loop.js.map +1 -1
  5. package/dist/web/public/assets/{a2a-Rq5d7Xk5.js → a2a-TmaKRhXV.js} +2 -2
  6. package/dist/web/public/assets/{a2a-Rq5d7Xk5.js.map → a2a-TmaKRhXV.js.map} +1 -1
  7. package/dist/web/public/assets/{activity-FCJjBNRM.js → activity-Cckc7fGG.js} +2 -2
  8. package/dist/web/public/assets/{activity-FCJjBNRM.js.map → activity-Cckc7fGG.js.map} +1 -1
  9. package/dist/web/public/assets/{admins-9fFdLRCv.js → admins-1hMCDolP.js} +2 -2
  10. package/dist/web/public/assets/{admins-9fFdLRCv.js.map → admins-1hMCDolP.js.map} +1 -1
  11. package/dist/web/public/assets/{agents-CiWiDAvY.js → agents-3sUHlKzx.js} +2 -2
  12. package/dist/web/public/assets/{agents-CiWiDAvY.js.map → agents-3sUHlKzx.js.map} +1 -1
  13. package/dist/web/public/assets/{approvals-4gNB4E5r.js → approvals-CY-_Lg4Y.js} +2 -2
  14. package/dist/web/public/assets/{approvals-4gNB4E5r.js.map → approvals-CY-_Lg4Y.js.map} +1 -1
  15. package/dist/web/public/assets/{arrow-down-CL6JRd2c.js → arrow-down-BkZ50IzL.js} +2 -2
  16. package/dist/web/public/assets/{arrow-down-CL6JRd2c.js.map → arrow-down-BkZ50IzL.js.map} +1 -1
  17. package/dist/web/public/assets/{arrow-up-B47-Pj-X.js → arrow-up-NWC5K6Jw.js} +2 -2
  18. package/dist/web/public/assets/{arrow-up-B47-Pj-X.js.map → arrow-up-NWC5K6Jw.js.map} +1 -1
  19. package/dist/web/public/assets/{asks-DPTxh_Os.js → asks-VzAmpsEh.js} +2 -2
  20. package/dist/web/public/assets/{asks-DPTxh_Os.js.map → asks-VzAmpsEh.js.map} +1 -1
  21. package/dist/web/public/assets/{audit-Dw3mL-g7.js → audit-fOn2LH4D.js} +2 -2
  22. package/dist/web/public/assets/{audit-Dw3mL-g7.js.map → audit-fOn2LH4D.js.map} +1 -1
  23. package/dist/web/public/assets/{bell-ojwGPpS7.js → bell-FF7PJo1N.js} +2 -2
  24. package/dist/web/public/assets/{bell-ojwGPpS7.js.map → bell-FF7PJo1N.js.map} +1 -1
  25. package/dist/web/public/assets/{bgjobs-DDTjejCS.js → bgjobs-L0v-UwPW.js} +2 -2
  26. package/dist/web/public/assets/{bgjobs-DDTjejCS.js.map → bgjobs-L0v-UwPW.js.map} +1 -1
  27. package/dist/web/public/assets/{brain-wzaKeCbt.js → brain-CdkDpFr1.js} +2 -2
  28. package/dist/web/public/assets/{brain-wzaKeCbt.js.map → brain-CdkDpFr1.js.map} +1 -1
  29. package/dist/web/public/assets/{briefcase-CCAq-ik6.js → briefcase-BXbOdl7E.js} +2 -2
  30. package/dist/web/public/assets/{briefcase-CCAq-ik6.js.map → briefcase-BXbOdl7E.js.map} +1 -1
  31. package/dist/web/public/assets/{chat-CbSvPFpG.js → chat-BazMi-ik.js} +3 -3
  32. package/dist/web/public/assets/{chat-CbSvPFpG.js.map → chat-BazMi-ik.js.map} +1 -1
  33. package/dist/web/public/assets/{chevron-left-bpKHh9Bu.js → chevron-left-Di1Tz64J.js} +2 -2
  34. package/dist/web/public/assets/{chevron-left-bpKHh9Bu.js.map → chevron-left-Di1Tz64J.js.map} +1 -1
  35. package/dist/web/public/assets/{chevron-right-CUlLpETY.js → chevron-right-BLjhBkqs.js} +2 -2
  36. package/dist/web/public/assets/{chevron-right-CUlLpETY.js.map → chevron-right-BLjhBkqs.js.map} +1 -1
  37. package/dist/web/public/assets/{circle-check-D98QQwz0.js → circle-check-BaxzYLlE.js} +2 -2
  38. package/dist/web/public/assets/{circle-check-D98QQwz0.js.map → circle-check-BaxzYLlE.js.map} +1 -1
  39. package/dist/web/public/assets/{circle-check-big-BP-0K1le.js → circle-check-big-C4BGLUvw.js} +2 -2
  40. package/dist/web/public/assets/{circle-check-big-BP-0K1le.js.map → circle-check-big-C4BGLUvw.js.map} +1 -1
  41. package/dist/web/public/assets/{circle-x-Et3rwVPd.js → circle-x-THl-PO3_.js} +2 -2
  42. package/dist/web/public/assets/{circle-x-Et3rwVPd.js.map → circle-x-THl-PO3_.js.map} +1 -1
  43. package/dist/web/public/assets/clock-iitpdQjZ.js +7 -0
  44. package/dist/web/public/assets/clock-iitpdQjZ.js.map +1 -0
  45. package/dist/web/public/assets/{confirm-dialog-6dKowsEt.js → confirm-dialog-r9HgkIYf.js} +2 -2
  46. package/dist/web/public/assets/{confirm-dialog-6dKowsEt.js.map → confirm-dialog-r9HgkIYf.js.map} +1 -1
  47. package/dist/web/public/assets/{copy-kCWCP9Wu.js → copy-DwyF4MOL.js} +2 -2
  48. package/dist/web/public/assets/{copy-kCWCP9Wu.js.map → copy-DwyF4MOL.js.map} +1 -1
  49. package/dist/web/public/assets/{data-table-BbNkr6tW.js → data-table-B80M8zdu.js} +2 -2
  50. package/dist/web/public/assets/{data-table-BbNkr6tW.js.map → data-table-B80M8zdu.js.map} +1 -1
  51. package/dist/web/public/assets/dialog-fGS0IXOo.js +6 -0
  52. package/dist/web/public/assets/{dialog-Cv87qelJ.js.map → dialog-fGS0IXOo.js.map} +1 -1
  53. package/dist/web/public/assets/{download-Cv8u9PxC.js → download-5ihiF2Gj.js} +2 -2
  54. package/dist/web/public/assets/{download-Cv8u9PxC.js.map → download-5ihiF2Gj.js.map} +1 -1
  55. package/dist/web/public/assets/{email-BS3f2y7i.js → email-LmRMqLRU.js} +3 -3
  56. package/dist/web/public/assets/{email-BS3f2y7i.js.map → email-LmRMqLRU.js.map} +1 -1
  57. package/dist/web/public/assets/{empty-state-CRnid5FY.js → empty-state-CrPnUC6d.js} +2 -2
  58. package/dist/web/public/assets/{empty-state-CRnid5FY.js.map → empty-state-CrPnUC6d.js.map} +1 -1
  59. package/dist/web/public/assets/{external-link-CzQc-c_P.js → external-link-DIJK1MAH.js} +2 -2
  60. package/dist/web/public/assets/{external-link-CzQc-c_P.js.map → external-link-DIJK1MAH.js.map} +1 -1
  61. package/dist/web/public/assets/{eye-DEBkfJiC.js → eye-DJJw0Ald.js} +2 -2
  62. package/dist/web/public/assets/{eye-DEBkfJiC.js.map → eye-DJJw0Ald.js.map} +1 -1
  63. package/dist/web/public/assets/{facts-O3FFqdD1.js → facts-BzImxpJD.js} +2 -2
  64. package/dist/web/public/assets/{facts-O3FFqdD1.js.map → facts-BzImxpJD.js.map} +1 -1
  65. package/dist/web/public/assets/{goals-pr5ky9rG.js → goals-C6p21B9N.js} +2 -2
  66. package/dist/web/public/assets/{goals-pr5ky9rG.js.map → goals-C6p21B9N.js.map} +1 -1
  67. package/dist/web/public/assets/{health-D_rfBsgq.js → health-D-ugz2Gp.js} +2 -2
  68. package/dist/web/public/assets/{health-D_rfBsgq.js.map → health-D-ugz2Gp.js.map} +1 -1
  69. package/dist/web/public/assets/{heart-pulse-203oH09r.js → heart-pulse-DlZXcdL0.js} +2 -2
  70. package/dist/web/public/assets/{heart-pulse-203oH09r.js.map → heart-pulse-DlZXcdL0.js.map} +1 -1
  71. package/dist/web/public/assets/{heartbeat-B5yJoH-X.js → heartbeat-DSasg-3y.js} +2 -2
  72. package/dist/web/public/assets/{heartbeat-B5yJoH-X.js.map → heartbeat-DSasg-3y.js.map} +1 -1
  73. package/dist/web/public/assets/{hot-CXGeh4Oo.js → hot-D67pYtaV.js} +2 -2
  74. package/dist/web/public/assets/{hot-CXGeh4Oo.js.map → hot-D67pYtaV.js.map} +1 -1
  75. package/dist/web/public/assets/{index-CuNnG-5O.js → index-CqwhfPlr.js} +9 -9
  76. package/dist/web/public/assets/index-CqwhfPlr.js.map +1 -0
  77. package/dist/web/public/assets/{installed-CQKXZNEU.js → installed-CrIsSoQE.js} +2 -2
  78. package/dist/web/public/assets/{installed-CQKXZNEU.js.map → installed-CrIsSoQE.js.map} +1 -1
  79. package/dist/web/public/assets/{jobs-DPxN8Ko0.js → jobs-yAwphb1W.js} +2 -2
  80. package/dist/web/public/assets/{jobs-DPxN8Ko0.js.map → jobs-yAwphb1W.js.map} +1 -1
  81. package/dist/web/public/assets/{layout-CxQy-DtV.js → layout-BXZKGQAk.js} +2 -2
  82. package/dist/web/public/assets/{layout-CxQy-DtV.js.map → layout-BXZKGQAk.js.map} +1 -1
  83. package/dist/web/public/assets/layout-CL5HFvHN.js +2 -0
  84. package/dist/web/public/assets/layout-CL5HFvHN.js.map +1 -0
  85. package/dist/web/public/assets/{layout-CQXWA5Ak.js → layout-CrtmlC8G.js} +2 -2
  86. package/dist/web/public/assets/{layout-CQXWA5Ak.js.map → layout-CrtmlC8G.js.map} +1 -1
  87. package/dist/web/public/assets/{layout-4C_GhacH.js → layout-awbFImGg.js} +2 -2
  88. package/dist/web/public/assets/{layout-4C_GhacH.js.map → layout-awbFImGg.js.map} +1 -1
  89. package/dist/web/public/assets/{layout-VOwsqNph.js → layout-cacmfseo.js} +2 -2
  90. package/dist/web/public/assets/{layout-VOwsqNph.js.map → layout-cacmfseo.js.map} +1 -1
  91. package/dist/web/public/assets/{llm-i15cVS6k.js → llm-C19AX6q2.js} +2 -2
  92. package/dist/web/public/assets/{llm-i15cVS6k.js.map → llm-C19AX6q2.js.map} +1 -1
  93. package/dist/web/public/assets/{loader-circle-CVEo3Hwx.js → loader-circle-U-jPjmeD.js} +2 -2
  94. package/dist/web/public/assets/{loader-circle-CVEo3Hwx.js.map → loader-circle-U-jPjmeD.js.map} +1 -1
  95. package/dist/web/public/assets/{map-pin-BlmDrPGJ.js → map-pin-4rE1NK87.js} +2 -2
  96. package/dist/web/public/assets/{map-pin-BlmDrPGJ.js.map → map-pin-4rE1NK87.js.map} +1 -1
  97. package/dist/web/public/assets/{mcp-9MlUdHAS.js → mcp-B94wc6Vi.js} +2 -2
  98. package/dist/web/public/assets/{mcp-9MlUdHAS.js.map → mcp-B94wc6Vi.js.map} +1 -1
  99. package/dist/web/public/assets/{memos-MDYe436b.js → memos-CrG4zgfI.js} +3 -3
  100. package/dist/web/public/assets/{memos-MDYe436b.js.map → memos-CrG4zgfI.js.map} +1 -1
  101. package/dist/web/public/assets/{messengers-D0F-cgJ0.js → messengers-UWarJd_C.js} +2 -2
  102. package/dist/web/public/assets/{messengers-D0F-cgJ0.js.map → messengers-UWarJd_C.js.map} +1 -1
  103. package/dist/web/public/assets/{mobile-Bezz5MnW.js → mobile-QhAUKqcJ.js} +2 -2
  104. package/dist/web/public/assets/{mobile-Bezz5MnW.js.map → mobile-QhAUKqcJ.js.map} +1 -1
  105. package/dist/web/public/assets/{native-agent-bRS7DRfj.js → native-agent-DMf0u4dm.js} +2 -2
  106. package/dist/web/public/assets/{native-agent-bRS7DRfj.js.map → native-agent-DMf0u4dm.js.map} +1 -1
  107. package/dist/web/public/assets/{network-3O1O1jsk.js → network-l6l5gLHO.js} +2 -2
  108. package/dist/web/public/assets/{network-3O1O1jsk.js.map → network-l6l5gLHO.js.map} +1 -1
  109. package/dist/web/public/assets/{outbox-D2iX9mcs.js → outbox-BenX_yUQ.js} +2 -2
  110. package/dist/web/public/assets/{outbox-D2iX9mcs.js.map → outbox-BenX_yUQ.js.map} +1 -1
  111. package/dist/web/public/assets/{pagination-79ms7QFI.js → pagination-B4g1CBsi.js} +2 -2
  112. package/dist/web/public/assets/{pagination-79ms7QFI.js.map → pagination-B4g1CBsi.js.map} +1 -1
  113. package/dist/web/public/assets/{persona-D37NzRbz.js → persona--3cjtl9q.js} +2 -2
  114. package/dist/web/public/assets/{persona-D37NzRbz.js.map → persona--3cjtl9q.js.map} +1 -1
  115. package/dist/web/public/assets/plans-DsHtDRlS.js +12 -0
  116. package/dist/web/public/assets/plans-DsHtDRlS.js.map +1 -0
  117. package/dist/web/public/assets/{play-BedplEoY.js → play-BG0hyTnO.js} +2 -2
  118. package/dist/web/public/assets/{play-BedplEoY.js.map → play-BG0hyTnO.js.map} +1 -1
  119. package/dist/web/public/assets/{plus-4GdEpvTV.js → plus-Dof9AQvU.js} +2 -2
  120. package/dist/web/public/assets/{plus-4GdEpvTV.js.map → plus-Dof9AQvU.js.map} +1 -1
  121. package/dist/web/public/assets/{policy-Gmd4rmzp.js → policy-BzHy4WbV.js} +2 -2
  122. package/dist/web/public/assets/{policy-Gmd4rmzp.js.map → policy-BzHy4WbV.js.map} +1 -1
  123. package/dist/web/public/assets/{qr-code-DVgHWDky.js → qr-code-yD_ztCf6.js} +2 -2
  124. package/dist/web/public/assets/{qr-code-DVgHWDky.js.map → qr-code-yD_ztCf6.js.map} +1 -1
  125. package/dist/web/public/assets/{refresh-ccw-DZHRYuFA.js → refresh-ccw-CBiHL1tY.js} +2 -2
  126. package/dist/web/public/assets/{refresh-ccw-DZHRYuFA.js.map → refresh-ccw-CBiHL1tY.js.map} +1 -1
  127. package/dist/web/public/assets/reminders-CDJlFR2Y.js +7 -0
  128. package/dist/web/public/assets/reminders-CDJlFR2Y.js.map +1 -0
  129. package/dist/web/public/assets/{save-DQlBAXAl.js → save-DVHI3V6o.js} +2 -2
  130. package/dist/web/public/assets/{save-DQlBAXAl.js.map → save-DVHI3V6o.js.map} +1 -1
  131. package/dist/web/public/assets/{schedules-BtuWAAd7.js → schedules-DYf64Fpr.js} +2 -2
  132. package/dist/web/public/assets/{schedules-BtuWAAd7.js.map → schedules-DYf64Fpr.js.map} +1 -1
  133. package/dist/web/public/assets/{search-dBGBHpnH.js → search-BYPDbBkC.js} +2 -2
  134. package/dist/web/public/assets/{search-dBGBHpnH.js.map → search-BYPDbBkC.js.map} +1 -1
  135. package/dist/web/public/assets/{search-DJXxphzz.js → search-aw0y39Qs.js} +2 -2
  136. package/dist/web/public/assets/{search-DJXxphzz.js.map → search-aw0y39Qs.js.map} +1 -1
  137. package/dist/web/public/assets/{security-CP0MP_Gx.js → security-DhN1kRac.js} +2 -2
  138. package/dist/web/public/assets/{security-CP0MP_Gx.js.map → security-DhN1kRac.js.map} +1 -1
  139. package/dist/web/public/assets/{service-BJFnNe7Y.js → service-BhvI7Mb5.js} +2 -2
  140. package/dist/web/public/assets/{service-BJFnNe7Y.js.map → service-BhvI7Mb5.js.map} +1 -1
  141. package/dist/web/public/assets/{shield-alert-DRh8fC8Z.js → shield-alert-DjqqnTMk.js} +2 -2
  142. package/dist/web/public/assets/{shield-alert-DRh8fC8Z.js.map → shield-alert-DjqqnTMk.js.map} +1 -1
  143. package/dist/web/public/assets/{status-badge-CTRG6Pb2.js → status-badge-nSFUUEfy.js} +2 -2
  144. package/dist/web/public/assets/{status-badge-CTRG6Pb2.js.map → status-badge-nSFUUEfy.js.map} +1 -1
  145. package/dist/web/public/assets/{subtasks-BiZ2mCPs.js → subtasks-C_x1RLJA.js} +2 -2
  146. package/dist/web/public/assets/{subtasks-BiZ2mCPs.js.map → subtasks-C_x1RLJA.js.map} +1 -1
  147. package/dist/web/public/assets/{table-Dbriy3Jz.js → table-BNqo2xb8.js} +2 -2
  148. package/dist/web/public/assets/{table-Dbriy3Jz.js.map → table-BNqo2xb8.js.map} +1 -1
  149. package/dist/web/public/assets/{topn-BEi7Uvlg.js → topn-NGtwNz38.js} +2 -2
  150. package/dist/web/public/assets/{topn-BEi7Uvlg.js.map → topn-NGtwNz38.js.map} +1 -1
  151. package/dist/web/public/assets/{trash-2-BgltvQpz.js → trash-2-BoFq2ZOF.js} +2 -2
  152. package/dist/web/public/assets/{trash-2-BgltvQpz.js.map → trash-2-BoFq2ZOF.js.map} +1 -1
  153. package/dist/web/public/assets/use-background-tasks-CY2gWPBZ.js +2 -0
  154. package/dist/web/public/assets/{use-background-tasks-DHo3Hnu9.js.map → use-background-tasks-CY2gWPBZ.js.map} +1 -1
  155. package/dist/web/public/assets/{use-llm-admin-EU1V1WQ5.js → use-llm-admin-CA5tUbEU.js} +2 -2
  156. package/dist/web/public/assets/{use-llm-admin-EU1V1WQ5.js.map → use-llm-admin-CA5tUbEU.js.map} +1 -1
  157. package/dist/web/public/assets/{use-memory-D0FD5n0A.js → use-memory-CxasvYqR.js} +2 -2
  158. package/dist/web/public/assets/{use-memory-D0FD5n0A.js.map → use-memory-CxasvYqR.js.map} +1 -1
  159. package/dist/web/public/assets/{use-observability-CZg_sS2t.js → use-observability-BOepIjX5.js} +2 -2
  160. package/dist/web/public/assets/{use-observability-CZg_sS2t.js.map → use-observability-BOepIjX5.js.map} +1 -1
  161. package/dist/web/public/assets/{use-settings-D3vI1Dwg.js → use-settings-DBXvAYm9.js} +2 -2
  162. package/dist/web/public/assets/{use-settings-D3vI1Dwg.js.map → use-settings-DBXvAYm9.js.map} +1 -1
  163. package/dist/web/public/assets/{use-workspace-DWm4dRVD.js → use-workspace-dw_69jpb.js} +2 -2
  164. package/dist/web/public/assets/{use-workspace-DWm4dRVD.js.map → use-workspace-dw_69jpb.js.map} +1 -1
  165. package/dist/web/public/assets/{useQuery-DIlm0vJ-.js → useQuery-Ds6-WURB.js} +2 -2
  166. package/dist/web/public/assets/{useQuery-DIlm0vJ-.js.map → useQuery-Ds6-WURB.js.map} +1 -1
  167. package/dist/web/public/assets/{vector-CaijGbpn.js → vector-C5WBAtlL.js} +2 -2
  168. package/dist/web/public/assets/{vector-CaijGbpn.js.map → vector-C5WBAtlL.js.map} +1 -1
  169. package/dist/web/public/assets/{viewer-nU6uZJWq.js → viewer-DQG9P7-t.js} +2 -2
  170. package/dist/web/public/assets/{viewer-nU6uZJWq.js.map → viewer-DQG9P7-t.js.map} +1 -1
  171. package/dist/web/public/assets/{workspace-BluXJmIg.js → workspace-Dku83Qqr.js} +3 -3
  172. package/dist/web/public/assets/{workspace-BluXJmIg.js.map → workspace-Dku83Qqr.js.map} +1 -1
  173. package/dist/web/public/assets/{workspaces-B2nSpx9t.js → workspaces-ClLQ253x.js} +2 -2
  174. package/dist/web/public/assets/{workspaces-B2nSpx9t.js.map → workspaces-ClLQ253x.js.map} +1 -1
  175. package/dist/web/public/assets/{x-D_eFtxsK.js → x-ClXUlQDe.js} +2 -2
  176. package/dist/web/public/assets/{x-D_eFtxsK.js.map → x-ClXUlQDe.js.map} +1 -1
  177. package/dist/web/public/index.html +1 -1
  178. package/dist/web/server.d.ts.map +1 -1
  179. package/dist/web/server.js +28 -0
  180. package/dist/web/server.js.map +1 -1
  181. package/package.json +1 -1
  182. package/dist/web/public/assets/dialog-Cv87qelJ.js +0 -6
  183. package/dist/web/public/assets/index-CuNnG-5O.js.map +0 -1
  184. package/dist/web/public/assets/layout-tAyuz3-F.js +0 -2
  185. package/dist/web/public/assets/layout-tAyuz3-F.js.map +0 -1
  186. package/dist/web/public/assets/reminders-C00V-Fs9.js +0 -12
  187. package/dist/web/public/assets/reminders-C00V-Fs9.js.map +0 -1
  188. package/dist/web/public/assets/use-background-tasks-DHo3Hnu9.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"external-link-CzQc-c_P.js","sources":["../../node_modules/lucide-react/dist/esm/icons/external-link.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ExternalLink = createLucideIcon(\"ExternalLink\", [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n]);\n\nexport { ExternalLink as default };\n//# sourceMappingURL=external-link.js.map\n"],"names":["ExternalLink","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,cAAe,IAAK,QAAQ,CAAE,EAC5C,CAAC,OAAQ,CAAE,EAAG,2DAA4D,IAAK,QAAQ,CAAE,CAC3F,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"external-link-DIJK1MAH.js","sources":["../../node_modules/lucide-react/dist/esm/icons/external-link.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst ExternalLink = createLucideIcon(\"ExternalLink\", [\n [\"path\", { d: \"M15 3h6v6\", key: \"1q9fwt\" }],\n [\"path\", { d: \"M10 14 21 3\", key: \"gplh6r\" }],\n [\"path\", { d: \"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\", key: \"a6xqqp\" }]\n]);\n\nexport { ExternalLink as default };\n//# sourceMappingURL=external-link.js.map\n"],"names":["ExternalLink","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAQ,CAAE,EAC1C,CAAC,OAAQ,CAAE,EAAG,cAAe,IAAK,QAAQ,CAAE,EAC5C,CAAC,OAAQ,CAAE,EAAG,2DAA4D,IAAK,QAAQ,CAAE,CAC3F,CAAC","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import{n as e}from"./index-CuNnG-5O.js";/**
1
+ import{n as e}from"./index-CqwhfPlr.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -9,4 +9,4 @@ import{n as e}from"./index-CuNnG-5O.js";/**
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
11
  */const y=e("Eye",[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);export{c as E,y as a};
12
- //# sourceMappingURL=eye-DEBkfJiC.js.map
12
+ //# sourceMappingURL=eye-DJJw0Ald.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"eye-DEBkfJiC.js","sources":["../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../node_modules/lucide-react/dist/esm/icons/eye.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n"],"names":["EyeOff","createLucideIcon","Eye"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CACE,OACA,CACE,EAAG,iGACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,EACrE,CACE,OACA,CACE,EAAG,+FACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACC,EAAMD,EAAiB,MAAO,CAClC,CACE,OACA,CACE,EAAG,wGACH,IAAK,QACX,CACA,EACE,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC","x_google_ignoreList":[0,1]}
1
+ {"version":3,"file":"eye-DJJw0Ald.js","sources":["../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../node_modules/lucide-react/dist/esm/icons/eye.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n"],"names":["EyeOff","createLucideIcon","Eye"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAASC,EAAiB,SAAU,CACxC,CACE,OACA,CACE,EAAG,iGACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,uCAAwC,IAAK,QAAQ,CAAE,EACrE,CACE,OACA,CACE,EAAG,+FACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAQ,CAAE,CAC7C,CAAC,EC1BD;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACC,EAAMD,EAAiB,MAAO,CAClC,CACE,OACA,CACE,EAAG,wGACH,IAAK,QACX,CACA,EACE,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC","x_google_ignoreList":[0,1]}
@@ -1,2 +1,2 @@
1
- import{u as Q,e as Y,j as e,k as D,B as b,L as E,I as J,S as W,f as X,g as Z,h as ee,i as k,l as p,m as T}from"./index-CuNnG-5O.js";import{r}from"./react-Cb2sDjhD.js";import{D as te}from"./data-table-BbNkr6tW.js";import{E as B}from"./empty-state-CRnid5FY.js";import{P as se}from"./pagination-79ms7QFI.js";import{C as M}from"./confirm-dialog-6dKowsEt.js";import{a as ae,b as ne,c as ce}from"./use-memory-D0FD5n0A.js";import{T as A}from"./trash-2-BgltvQpz.js";import{B as R}from"./brain-wzaKeCbt.js";import{L as re}from"./loader-circle-CVEo3Hwx.js";import{R as ie}from"./refresh-ccw-DZHRYuFA.js";import{S as le}from"./search-DJXxphzz.js";import"./table-Dbriy3Jz.js";import"./arrow-up-B47-Pj-X.js";import"./arrow-down-CL6JRd2c.js";import"./chevron-left-bpKHh9Bu.js";import"./chevron-right-CUlLpETY.js";import"./dialog-Cv87qelJ.js";import"./x-D_eFtxsK.js";import"./useQuery-DIlm0vJ-.js";const oe=["fact","preference","goal","history","profile"],me=[25,50,100],F=50,de=300;function Be(){const{t:s}=Q(["memory","common"]),[n,L]=Y(),c=n.get("user")??"",i=n.get("q")??"",m=n.get("cat")??null,d=Math.max(1,Number(n.get("page"))||1),l=Number(n.get("per_page"))||F,[f,I]=r.useState(i);r.useEffect(()=>{if(f===i)return;const t=window.setTimeout(()=>h({q:f||null}),de);return()=>window.clearTimeout(t)},[f]);const q=r.useMemo(()=>({user_key:c,...i?{query:i}:{},...m?{category:m}:{},limit:l,offset:(d-1)*l}),[c,i,m,d,l]),{data:S,isLoading:z,isFetching:C,refetch:U}=ae(q,{enabled:!!c}),_=S?.facts??[],P=S?.total??0,G=Math.max(1,Math.ceil(P/l)),[u,g]=r.useState(new Set);r.useEffect(()=>{g(new Set)},[c,i,m,d,l]);const j=ne(),x=ce(),[y,v]=r.useState(null),[V,O]=r.useState(!1);function h(t){const a=new URLSearchParams(n);for(const[o,w]of Object.entries(t))w==null||w===""?a.delete(o):a.set(o,w);Object.keys(t).some(o=>o!=="page")&&a.delete("page"),L(a,{replace:!1})}async function $(){if(!(y==null||!c))try{await j.mutateAsync({id:y,user_key:c}),p.success(s("facts.toast.deletedOne"))}catch(t){const{message:a}=T(t,s);throw p.error(a),t}}async function H(){if(!c||u.size===0)return;const t=Array.from(u).map(Number).filter(Number.isFinite);try{const a=await x.mutateAsync({user_key:c,body:{ids:t}});p.success(s("facts.toast.deletedMany",{count:a.deleted})),g(new Set)}catch(a){const{message:o}=T(a,s);throw p.error(o),a}}const K=r.useMemo(()=>[{id:"id",header:s("facts.col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"what",header:s("facts.col.what"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text",children:t.what}),asCardTitle:!0},{id:"category",header:s("facts.col.category"),cell:t=>e.jsx(D,{variant:"outline",children:s(`facts.category.${t.category}`,{defaultValue:t.category})}),headClassName:"w-28"},{id:"confidence",header:s("facts.col.confidence"),cell:t=>e.jsx("span",{className:"tabular-nums text-text-dim",children:t.confidence.toFixed(2)}),headClassName:"w-24",hideOnMobile:!0},{id:"source",header:s("facts.col.source"),cell:t=>e.jsx("span",{className:"text-text-dim text-xs",children:t.source}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:s("facts.col.createdAt"),cell:t=>e.jsx("span",{className:"text-text-dim",children:fe(t.created_at)}),headClassName:"w-32",hideOnMobile:!0},{id:"actions",header:"",cell:t=>e.jsx("div",{className:"flex justify-end",children:e.jsxs(b,{variant:"ghost",size:"sm",onClick:a=>{a.stopPropagation(),v(t.id)},disabled:j.isPending||x.isPending,"aria-label":s("facts.action.delete"),children:[e.jsx(A,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:s("facts.action.delete")})]})}),headClassName:"w-24"}],[s,j.isPending,x.isPending]);if(!c)return e.jsx("div",{className:"mx-auto max-w-3xl",children:e.jsx(B,{icon:e.jsx(R,{}),title:s("noUserSelected.title"),description:s("noUserSelected.description")})});const N=u.size;return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("facts.title")}),e.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>U(),disabled:C,"aria-label":s("actions.refresh",{ns:"common"}),children:[C?e.jsx(re,{className:"h-4 w-4 animate-spin"}):e.jsx(ie,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[200px] max-w-md",children:[e.jsx(E,{htmlFor:"search",className:"text-xs text-text-dim",children:s("facts.filter.search")}),e.jsx(le,{className:"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted"}),e.jsx(J,{id:"search",value:f,onChange:t=>I(t.target.value),className:"pl-7 mt-1"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(E,{htmlFor:"category",className:"text-xs text-text-dim",children:s("facts.filter.category")}),e.jsxs(W,{value:m??"__any__",onValueChange:t=>h({cat:t==="__any__"?null:t}),children:[e.jsx(X,{id:"category",className:"w-[140px]",children:e.jsx(Z,{})}),e.jsxs(ee,{children:[e.jsx(k,{value:"__any__",children:s("facts.filter.categoryAny")}),oe.map(t=>e.jsx(k,{value:t,children:s(`facts.category.${t}`)},t))]})]})]}),N>0&&e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(D,{variant:"secondary",children:s("facts.batch.selected",{count:N})}),e.jsxs(b,{variant:"destructive",size:"sm",onClick:()=>O(!0),disabled:x.isPending,children:[e.jsx(A,{className:"h-4 w-4"}),s("facts.batch.deleteSelected")]})]})]}),e.jsx(te,{columns:K,rows:_,getRowId:t=>String(t.id),loading:z,selection:u,onSelectionChange:g,emptyState:e.jsx(B,{icon:e.jsx(R,{}),title:s("facts.empty.title"),description:s("facts.empty.description")})}),(_.length>0||d>1)&&e.jsx(se,{page:d,totalPages:G,totalRows:P,perPage:l,perPageOptions:me,onPageChange:t=>h({page:t===1?null:String(t)}),onPerPageChange:t=>h({per_page:t===F?null:String(t)})}),e.jsx(M,{open:y!=null,onOpenChange:t=>{t||v(null)},title:s("facts.action.confirmDelete"),description:s("facts.action.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.action.delete"),onConfirm:$}),e.jsx(M,{open:V,onOpenChange:O,title:s("facts.batch.confirmDelete",{count:N}),description:s("facts.batch.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.batch.deleteSelected"),onConfirm:H})]})}function fe(s){try{const n=new Date(s);return Number.isNaN(n.getTime())?String(s):n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{Be as default};
2
- //# sourceMappingURL=facts-O3FFqdD1.js.map
1
+ import{u as Q,e as Y,j as e,k as D,B as b,L as E,I as J,S as W,f as X,g as Z,h as ee,i as k,l as p,m as T}from"./index-CqwhfPlr.js";import{r}from"./react-Cb2sDjhD.js";import{D as te}from"./data-table-B80M8zdu.js";import{E as B}from"./empty-state-CrPnUC6d.js";import{P as se}from"./pagination-B4g1CBsi.js";import{C as M}from"./confirm-dialog-r9HgkIYf.js";import{a as ae,b as ne,c as ce}from"./use-memory-CxasvYqR.js";import{T as A}from"./trash-2-BoFq2ZOF.js";import{B as R}from"./brain-CdkDpFr1.js";import{L as re}from"./loader-circle-U-jPjmeD.js";import{R as ie}from"./refresh-ccw-CBiHL1tY.js";import{S as le}from"./search-aw0y39Qs.js";import"./table-BNqo2xb8.js";import"./arrow-up-NWC5K6Jw.js";import"./arrow-down-BkZ50IzL.js";import"./chevron-left-Di1Tz64J.js";import"./chevron-right-BLjhBkqs.js";import"./dialog-fGS0IXOo.js";import"./x-ClXUlQDe.js";import"./useQuery-Ds6-WURB.js";const oe=["fact","preference","goal","history","profile"],me=[25,50,100],F=50,de=300;function Be(){const{t:s}=Q(["memory","common"]),[n,L]=Y(),c=n.get("user")??"",i=n.get("q")??"",m=n.get("cat")??null,d=Math.max(1,Number(n.get("page"))||1),l=Number(n.get("per_page"))||F,[f,I]=r.useState(i);r.useEffect(()=>{if(f===i)return;const t=window.setTimeout(()=>h({q:f||null}),de);return()=>window.clearTimeout(t)},[f]);const q=r.useMemo(()=>({user_key:c,...i?{query:i}:{},...m?{category:m}:{},limit:l,offset:(d-1)*l}),[c,i,m,d,l]),{data:S,isLoading:z,isFetching:C,refetch:U}=ae(q,{enabled:!!c}),_=S?.facts??[],P=S?.total??0,G=Math.max(1,Math.ceil(P/l)),[u,g]=r.useState(new Set);r.useEffect(()=>{g(new Set)},[c,i,m,d,l]);const j=ne(),x=ce(),[y,v]=r.useState(null),[V,O]=r.useState(!1);function h(t){const a=new URLSearchParams(n);for(const[o,w]of Object.entries(t))w==null||w===""?a.delete(o):a.set(o,w);Object.keys(t).some(o=>o!=="page")&&a.delete("page"),L(a,{replace:!1})}async function $(){if(!(y==null||!c))try{await j.mutateAsync({id:y,user_key:c}),p.success(s("facts.toast.deletedOne"))}catch(t){const{message:a}=T(t,s);throw p.error(a),t}}async function H(){if(!c||u.size===0)return;const t=Array.from(u).map(Number).filter(Number.isFinite);try{const a=await x.mutateAsync({user_key:c,body:{ids:t}});p.success(s("facts.toast.deletedMany",{count:a.deleted})),g(new Set)}catch(a){const{message:o}=T(a,s);throw p.error(o),a}}const K=r.useMemo(()=>[{id:"id",header:s("facts.col.id"),cell:t=>e.jsxs("span",{className:"tabular-nums text-text-dim",children:["#",t.id]}),headClassName:"w-16"},{id:"what",header:s("facts.col.what"),cell:t=>e.jsx("span",{className:"line-clamp-2 text-text",children:t.what}),asCardTitle:!0},{id:"category",header:s("facts.col.category"),cell:t=>e.jsx(D,{variant:"outline",children:s(`facts.category.${t.category}`,{defaultValue:t.category})}),headClassName:"w-28"},{id:"confidence",header:s("facts.col.confidence"),cell:t=>e.jsx("span",{className:"tabular-nums text-text-dim",children:t.confidence.toFixed(2)}),headClassName:"w-24",hideOnMobile:!0},{id:"source",header:s("facts.col.source"),cell:t=>e.jsx("span",{className:"text-text-dim text-xs",children:t.source}),headClassName:"w-28",hideOnMobile:!0},{id:"createdAt",header:s("facts.col.createdAt"),cell:t=>e.jsx("span",{className:"text-text-dim",children:fe(t.created_at)}),headClassName:"w-32",hideOnMobile:!0},{id:"actions",header:"",cell:t=>e.jsx("div",{className:"flex justify-end",children:e.jsxs(b,{variant:"ghost",size:"sm",onClick:a=>{a.stopPropagation(),v(t.id)},disabled:j.isPending||x.isPending,"aria-label":s("facts.action.delete"),children:[e.jsx(A,{className:"h-3 w-3"}),e.jsx("span",{className:"sr-only sm:not-sr-only sm:ml-1",children:s("facts.action.delete")})]})}),headClassName:"w-24"}],[s,j.isPending,x.isPending]);if(!c)return e.jsx("div",{className:"mx-auto max-w-3xl",children:e.jsx(B,{icon:e.jsx(R,{}),title:s("noUserSelected.title"),description:s("noUserSelected.description")})});const N=u.size;return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("facts.title")}),e.jsxs(b,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>U(),disabled:C,"aria-label":s("actions.refresh",{ns:"common"}),children:[C?e.jsx(re,{className:"h-4 w-4 animate-spin"}):e.jsx(ie,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("subtitle")})]}),e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[200px] max-w-md",children:[e.jsx(E,{htmlFor:"search",className:"text-xs text-text-dim",children:s("facts.filter.search")}),e.jsx(le,{className:"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted"}),e.jsx(J,{id:"search",value:f,onChange:t=>I(t.target.value),className:"pl-7 mt-1"})]}),e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(E,{htmlFor:"category",className:"text-xs text-text-dim",children:s("facts.filter.category")}),e.jsxs(W,{value:m??"__any__",onValueChange:t=>h({cat:t==="__any__"?null:t}),children:[e.jsx(X,{id:"category",className:"w-[140px]",children:e.jsx(Z,{})}),e.jsxs(ee,{children:[e.jsx(k,{value:"__any__",children:s("facts.filter.categoryAny")}),oe.map(t=>e.jsx(k,{value:t,children:s(`facts.category.${t}`)},t))]})]})]}),N>0&&e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(D,{variant:"secondary",children:s("facts.batch.selected",{count:N})}),e.jsxs(b,{variant:"destructive",size:"sm",onClick:()=>O(!0),disabled:x.isPending,children:[e.jsx(A,{className:"h-4 w-4"}),s("facts.batch.deleteSelected")]})]})]}),e.jsx(te,{columns:K,rows:_,getRowId:t=>String(t.id),loading:z,selection:u,onSelectionChange:g,emptyState:e.jsx(B,{icon:e.jsx(R,{}),title:s("facts.empty.title"),description:s("facts.empty.description")})}),(_.length>0||d>1)&&e.jsx(se,{page:d,totalPages:G,totalRows:P,perPage:l,perPageOptions:me,onPageChange:t=>h({page:t===1?null:String(t)}),onPerPageChange:t=>h({per_page:t===F?null:String(t)})}),e.jsx(M,{open:y!=null,onOpenChange:t=>{t||v(null)},title:s("facts.action.confirmDelete"),description:s("facts.action.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.action.delete"),onConfirm:$}),e.jsx(M,{open:V,onOpenChange:O,title:s("facts.batch.confirmDelete",{count:N}),description:s("facts.batch.confirmDeleteDesc"),intent:"danger",confirmLabel:s("facts.batch.deleteSelected"),onConfirm:H})]})}function fe(s){try{const n=new Date(s);return Number.isNaN(n.getTime())?String(s):n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return String(s)}}export{Be as default};
2
+ //# sourceMappingURL=facts-BzImxpJD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"facts-O3FFqdD1.js","sources":["../../src/routes/memory/facts.tsx"],"sourcesContent":["/**\n * /memory/facts — list / search / delete the user's facts.\n *\n * Reads `?user=` from the URL (the layout writes it). Without a\n * user_key the route shows a friendly empty state pointing at the\n * picker — no query fires until a user is chosen.\n *\n * Search + category filter live in URL params so deep-link sharing\n * works (\"show me john's goals matching tax\"). The free-text input\n * is local-only with a 300ms debounce, same pattern as /memos, so\n * the FTS5 layer isn't hit on every keystroke.\n *\n * Single-row delete via the per-row Delete button; batch delete via\n * checkbox selection + the bulk-delete action bar. Both route\n * through ConfirmDialog.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, Loader2, RefreshCcw, Search, Trash2 } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Pagination } from '@/components/common/pagination'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useMemoryFacts,\n useDeleteFactById,\n useBulkDeleteFacts,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport type { Fact, FactCategory, ListMemoryFactsQuery } from '@/types/api'\n\nconst CATEGORY_OPTIONS: FactCategory[] = ['fact', 'preference', 'goal', 'history', 'profile']\nconst PER_PAGE_OPTIONS = [25, 50, 100]\nconst DEFAULT_PER_PAGE = 50\nconst SEARCH_DEBOUNCE_MS = 300\n\nexport default function MemoryFactsRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params, setParams] = useSearchParams()\n\n const userKey = params.get('user') ?? ''\n const q = params.get('q') ?? ''\n const cat = (params.get('cat') as FactCategory | null) ?? null\n const page = Math.max(1, Number(params.get('page')) || 1)\n const perPage = Number(params.get('per_page')) || DEFAULT_PER_PAGE\n\n const [qDraft, setQDraft] = useState(q)\n useEffect(() => {\n if (qDraft === q) return\n const timer = window.setTimeout(() => patchParams({ q: qDraft || null }), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [qDraft])\n\n const query: ListMemoryFactsQuery = useMemo(\n () => ({\n user_key: userKey,\n ...(q ? { query: q } : {}),\n ...(cat ? { category: cat } : {}),\n limit: perPage,\n offset: (page - 1) * perPage,\n }),\n [userKey, q, cat, page, perPage],\n )\n\n const { data, isLoading, isFetching, refetch } = useMemoryFacts(query, { enabled: Boolean(userKey) })\n const facts = data?.facts ?? []\n const total = data?.total ?? 0\n const totalPages = Math.max(1, Math.ceil(total / perPage))\n\n // Selection state for the bulk delete bar.\n const [selection, setSelection] = useState<Set<string>>(new Set())\n useEffect(() => { setSelection(new Set()) }, [userKey, q, cat, page, perPage])\n\n const deleteOne = useDeleteFactById()\n const bulkDelete = useBulkDeleteFacts()\n\n const [confirmOneId, setConfirmOneId] = useState<number | null>(null)\n const [confirmBulk, setConfirmBulk] = useState(false)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n // Reset to page 1 on any filter mutation.\n if (Object.keys(patch).some((k) => k !== 'page')) next.delete('page')\n setParams(next, { replace: false })\n }\n\n async function onConfirmDeleteOne(): Promise<void> {\n if (confirmOneId == null || !userKey) return\n try {\n await deleteOne.mutateAsync({ id: confirmOneId, user_key: userKey })\n toast.success(t('facts.toast.deletedOne'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmBulk(): Promise<void> {\n if (!userKey || selection.size === 0) return\n const ids = Array.from(selection).map(Number).filter(Number.isFinite)\n try {\n const r = await bulkDelete.mutateAsync({ user_key: userKey, body: { ids } })\n toast.success(t('facts.toast.deletedMany', { count: r.deleted }))\n setSelection(new Set())\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n const columns: DataTableColumn<Fact>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('facts.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'what',\n header: t('facts.col.what'),\n cell: (r) => <span className=\"line-clamp-2 text-text\">{r.what}</span>,\n asCardTitle: true,\n },\n {\n id: 'category',\n header: t('facts.col.category'),\n cell: (r) => (\n <Badge variant=\"outline\">\n {t(`facts.category.${r.category}`, { defaultValue: r.category })}\n </Badge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'confidence',\n header: t('facts.col.confidence'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">{r.confidence.toFixed(2)}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('facts.col.source'),\n cell: (r) => <span className=\"text-text-dim text-xs\">{r.source}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('facts.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatEpoch(r.created_at)}</span>,\n headClassName: 'w-32',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) => (\n <div className=\"flex justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmOneId(r.id)\n }}\n disabled={deleteOne.isPending || bulkDelete.isPending}\n aria-label={t('facts.action.delete')}\n >\n <Trash2 className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('facts.action.delete')}</span>\n </Button>\n </div>\n ),\n headClassName: 'w-24',\n },\n ],\n [t, deleteOne.isPending, bulkDelete.isPending],\n )\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n const selectedCount = selection.size\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('facts.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\n <Label htmlFor=\"search\" className=\"text-xs text-text-dim\">\n {t('facts.filter.search')}\n </Label>\n <Search className=\"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted\" />\n <Input\n id=\"search\"\n value={qDraft}\n onChange={(e) => setQDraft(e.target.value)}\n className=\"pl-7 mt-1\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"category\" className=\"text-xs text-text-dim\">\n {t('facts.filter.category')}\n </Label>\n <Select\n value={cat ?? '__any__'}\n onValueChange={(v) => patchParams({ cat: v === '__any__' ? null : v })}\n >\n <SelectTrigger id=\"category\" className=\"w-[140px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__any__\">{t('facts.filter.categoryAny')}</SelectItem>\n {CATEGORY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`facts.category.${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {selectedCount > 0 && (\n <div className=\"ml-auto flex items-center gap-2\">\n <Badge variant=\"secondary\">\n {t('facts.batch.selected', { count: selectedCount })}\n </Badge>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmBulk(true)}\n disabled={bulkDelete.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('facts.batch.deleteSelected')}\n </Button>\n </div>\n )}\n </div>\n\n <DataTable\n columns={columns}\n rows={facts}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n selection={selection}\n onSelectionChange={setSelection}\n emptyState={\n <EmptyState\n icon={<Brain />}\n title={t('facts.empty.title')}\n description={t('facts.empty.description')}\n />\n }\n />\n\n {(facts.length > 0 || page > 1) && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalRows={total}\n perPage={perPage}\n perPageOptions={PER_PAGE_OPTIONS}\n onPageChange={(p) => patchParams({ page: p === 1 ? null : String(p) })}\n onPerPageChange={(pp) => patchParams({ per_page: pp === DEFAULT_PER_PAGE ? null : String(pp) })}\n />\n )}\n\n <ConfirmDialog\n open={confirmOneId != null}\n onOpenChange={(open) => { if (!open) setConfirmOneId(null) }}\n title={t('facts.action.confirmDelete')}\n description={t('facts.action.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.action.delete')}\n onConfirm={onConfirmDeleteOne}\n />\n\n <ConfirmDialog\n open={confirmBulk}\n onOpenChange={setConfirmBulk}\n title={t('facts.batch.confirmDelete', { count: selectedCount })}\n description={t('facts.batch.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.batch.deleteSelected')}\n onConfirm={onConfirmBulk}\n />\n </div>\n )\n}\n\n/** Format an epoch-ms number as a short locale string. */\nfunction formatEpoch(ms: number): string {\n try {\n const d = new Date(ms)\n if (Number.isNaN(d.getTime())) return String(ms)\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return String(ms)\n }\n}\n"],"names":["CATEGORY_OPTIONS","PER_PAGE_OPTIONS","DEFAULT_PER_PAGE","SEARCH_DEBOUNCE_MS","MemoryFactsRoute","t","useTranslation","params","setParams","useSearchParams","userKey","q","cat","page","perPage","qDraft","setQDraft","useState","useEffect","timer","patchParams","query","useMemo","data","isLoading","isFetching","refetch","useMemoryFacts","facts","total","totalPages","selection","setSelection","deleteOne","useDeleteFactById","bulkDelete","useBulkDeleteFacts","confirmOneId","setConfirmOneId","confirmBulk","setConfirmBulk","patch","next","k","v","onConfirmDeleteOne","toast","err","message","describeError","onConfirmBulk","ids","r","columns","jsxs","jsx","Badge","formatEpoch","Button","e","Trash2","EmptyState","Brain","selectedCount","Loader2","RefreshCcw","Label","Search","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","c","DataTable","Pagination","p","pp","ConfirmDialog","open","ms","d"],"mappings":"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"}
1
+ {"version":3,"file":"facts-BzImxpJD.js","sources":["../../src/routes/memory/facts.tsx"],"sourcesContent":["/**\n * /memory/facts — list / search / delete the user's facts.\n *\n * Reads `?user=` from the URL (the layout writes it). Without a\n * user_key the route shows a friendly empty state pointing at the\n * picker — no query fires until a user is chosen.\n *\n * Search + category filter live in URL params so deep-link sharing\n * works (\"show me john's goals matching tax\"). The free-text input\n * is local-only with a 300ms debounce, same pattern as /memos, so\n * the FTS5 layer isn't hit on every keystroke.\n *\n * Single-row delete via the per-row Delete button; batch delete via\n * checkbox selection + the bulk-delete action bar. Both route\n * through ConfirmDialog.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { Brain, Loader2, RefreshCcw, Search, Trash2 } from 'lucide-react'\n\nimport { DataTable, type DataTableColumn } from '@/components/common/data-table'\nimport { EmptyState } from '@/components/common/empty-state'\nimport { Pagination } from '@/components/common/pagination'\nimport { ConfirmDialog } from '@/components/common/confirm-dialog'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Label } from '@/components/ui/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select'\nimport {\n useMemoryFacts,\n useDeleteFactById,\n useBulkDeleteFacts,\n} from '@/hooks/use-memory'\nimport { describeError } from '@/lib/api/errors'\nimport type { Fact, FactCategory, ListMemoryFactsQuery } from '@/types/api'\n\nconst CATEGORY_OPTIONS: FactCategory[] = ['fact', 'preference', 'goal', 'history', 'profile']\nconst PER_PAGE_OPTIONS = [25, 50, 100]\nconst DEFAULT_PER_PAGE = 50\nconst SEARCH_DEBOUNCE_MS = 300\n\nexport default function MemoryFactsRoute(): JSX.Element {\n const { t } = useTranslation(['memory', 'common'])\n const [params, setParams] = useSearchParams()\n\n const userKey = params.get('user') ?? ''\n const q = params.get('q') ?? ''\n const cat = (params.get('cat') as FactCategory | null) ?? null\n const page = Math.max(1, Number(params.get('page')) || 1)\n const perPage = Number(params.get('per_page')) || DEFAULT_PER_PAGE\n\n const [qDraft, setQDraft] = useState(q)\n useEffect(() => {\n if (qDraft === q) return\n const timer = window.setTimeout(() => patchParams({ q: qDraft || null }), SEARCH_DEBOUNCE_MS)\n return () => window.clearTimeout(timer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [qDraft])\n\n const query: ListMemoryFactsQuery = useMemo(\n () => ({\n user_key: userKey,\n ...(q ? { query: q } : {}),\n ...(cat ? { category: cat } : {}),\n limit: perPage,\n offset: (page - 1) * perPage,\n }),\n [userKey, q, cat, page, perPage],\n )\n\n const { data, isLoading, isFetching, refetch } = useMemoryFacts(query, { enabled: Boolean(userKey) })\n const facts = data?.facts ?? []\n const total = data?.total ?? 0\n const totalPages = Math.max(1, Math.ceil(total / perPage))\n\n // Selection state for the bulk delete bar.\n const [selection, setSelection] = useState<Set<string>>(new Set())\n useEffect(() => { setSelection(new Set()) }, [userKey, q, cat, page, perPage])\n\n const deleteOne = useDeleteFactById()\n const bulkDelete = useBulkDeleteFacts()\n\n const [confirmOneId, setConfirmOneId] = useState<number | null>(null)\n const [confirmBulk, setConfirmBulk] = useState(false)\n\n function patchParams(patch: Record<string, string | null>): void {\n const next = new URLSearchParams(params)\n for (const [k, v] of Object.entries(patch)) {\n if (v == null || v === '') next.delete(k)\n else next.set(k, v)\n }\n // Reset to page 1 on any filter mutation.\n if (Object.keys(patch).some((k) => k !== 'page')) next.delete('page')\n setParams(next, { replace: false })\n }\n\n async function onConfirmDeleteOne(): Promise<void> {\n if (confirmOneId == null || !userKey) return\n try {\n await deleteOne.mutateAsync({ id: confirmOneId, user_key: userKey })\n toast.success(t('facts.toast.deletedOne'))\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n async function onConfirmBulk(): Promise<void> {\n if (!userKey || selection.size === 0) return\n const ids = Array.from(selection).map(Number).filter(Number.isFinite)\n try {\n const r = await bulkDelete.mutateAsync({ user_key: userKey, body: { ids } })\n toast.success(t('facts.toast.deletedMany', { count: r.deleted }))\n setSelection(new Set())\n } catch (err) {\n const { message } = describeError(err, t)\n toast.error(message)\n throw err\n }\n }\n\n const columns: DataTableColumn<Fact>[] = useMemo(\n () => [\n {\n id: 'id',\n header: t('facts.col.id'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">#{r.id}</span>,\n headClassName: 'w-16',\n },\n {\n id: 'what',\n header: t('facts.col.what'),\n cell: (r) => <span className=\"line-clamp-2 text-text\">{r.what}</span>,\n asCardTitle: true,\n },\n {\n id: 'category',\n header: t('facts.col.category'),\n cell: (r) => (\n <Badge variant=\"outline\">\n {t(`facts.category.${r.category}`, { defaultValue: r.category })}\n </Badge>\n ),\n headClassName: 'w-28',\n },\n {\n id: 'confidence',\n header: t('facts.col.confidence'),\n cell: (r) => <span className=\"tabular-nums text-text-dim\">{r.confidence.toFixed(2)}</span>,\n headClassName: 'w-24',\n hideOnMobile: true,\n },\n {\n id: 'source',\n header: t('facts.col.source'),\n cell: (r) => <span className=\"text-text-dim text-xs\">{r.source}</span>,\n headClassName: 'w-28',\n hideOnMobile: true,\n },\n {\n id: 'createdAt',\n header: t('facts.col.createdAt'),\n cell: (r) => <span className=\"text-text-dim\">{formatEpoch(r.created_at)}</span>,\n headClassName: 'w-32',\n hideOnMobile: true,\n },\n {\n id: 'actions',\n header: '',\n cell: (r) => (\n <div className=\"flex justify-end\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation()\n setConfirmOneId(r.id)\n }}\n disabled={deleteOne.isPending || bulkDelete.isPending}\n aria-label={t('facts.action.delete')}\n >\n <Trash2 className=\"h-3 w-3\" />\n <span className=\"sr-only sm:not-sr-only sm:ml-1\">{t('facts.action.delete')}</span>\n </Button>\n </div>\n ),\n headClassName: 'w-24',\n },\n ],\n [t, deleteOne.isPending, bulkDelete.isPending],\n )\n\n if (!userKey) {\n return (\n <div className=\"mx-auto max-w-3xl\">\n <EmptyState\n icon={<Brain />}\n title={t('noUserSelected.title')}\n description={t('noUserSelected.description')}\n />\n </div>\n )\n }\n\n const selectedCount = selection.size\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('facts.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n <p className=\"text-sm text-text-dim\">{t('subtitle')}</p>\n </header>\n\n {/* Filter row */}\n <div className=\"flex flex-wrap items-end gap-2\">\n <div className=\"relative flex-1 min-w-[200px] max-w-md\">\n <Label htmlFor=\"search\" className=\"text-xs text-text-dim\">\n {t('facts.filter.search')}\n </Label>\n <Search className=\"pointer-events-none absolute left-2 bottom-2 h-4 w-4 text-text-muted\" />\n <Input\n id=\"search\"\n value={qDraft}\n onChange={(e) => setQDraft(e.target.value)}\n className=\"pl-7 mt-1\"\n />\n </div>\n <div className=\"flex flex-col gap-1\">\n <Label htmlFor=\"category\" className=\"text-xs text-text-dim\">\n {t('facts.filter.category')}\n </Label>\n <Select\n value={cat ?? '__any__'}\n onValueChange={(v) => patchParams({ cat: v === '__any__' ? null : v })}\n >\n <SelectTrigger id=\"category\" className=\"w-[140px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__any__\">{t('facts.filter.categoryAny')}</SelectItem>\n {CATEGORY_OPTIONS.map((c) => (\n <SelectItem key={c} value={c}>\n {t(`facts.category.${c}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {selectedCount > 0 && (\n <div className=\"ml-auto flex items-center gap-2\">\n <Badge variant=\"secondary\">\n {t('facts.batch.selected', { count: selectedCount })}\n </Badge>\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => setConfirmBulk(true)}\n disabled={bulkDelete.isPending}\n >\n <Trash2 className=\"h-4 w-4\" />\n {t('facts.batch.deleteSelected')}\n </Button>\n </div>\n )}\n </div>\n\n <DataTable\n columns={columns}\n rows={facts}\n getRowId={(r) => String(r.id)}\n loading={isLoading}\n selection={selection}\n onSelectionChange={setSelection}\n emptyState={\n <EmptyState\n icon={<Brain />}\n title={t('facts.empty.title')}\n description={t('facts.empty.description')}\n />\n }\n />\n\n {(facts.length > 0 || page > 1) && (\n <Pagination\n page={page}\n totalPages={totalPages}\n totalRows={total}\n perPage={perPage}\n perPageOptions={PER_PAGE_OPTIONS}\n onPageChange={(p) => patchParams({ page: p === 1 ? null : String(p) })}\n onPerPageChange={(pp) => patchParams({ per_page: pp === DEFAULT_PER_PAGE ? null : String(pp) })}\n />\n )}\n\n <ConfirmDialog\n open={confirmOneId != null}\n onOpenChange={(open) => { if (!open) setConfirmOneId(null) }}\n title={t('facts.action.confirmDelete')}\n description={t('facts.action.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.action.delete')}\n onConfirm={onConfirmDeleteOne}\n />\n\n <ConfirmDialog\n open={confirmBulk}\n onOpenChange={setConfirmBulk}\n title={t('facts.batch.confirmDelete', { count: selectedCount })}\n description={t('facts.batch.confirmDeleteDesc')}\n intent=\"danger\"\n confirmLabel={t('facts.batch.deleteSelected')}\n onConfirm={onConfirmBulk}\n />\n </div>\n )\n}\n\n/** Format an epoch-ms number as a short locale string. */\nfunction formatEpoch(ms: number): string {\n try {\n const d = new Date(ms)\n if (Number.isNaN(d.getTime())) return String(ms)\n return d.toLocaleString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n } catch {\n return String(ms)\n }\n}\n"],"names":["CATEGORY_OPTIONS","PER_PAGE_OPTIONS","DEFAULT_PER_PAGE","SEARCH_DEBOUNCE_MS","MemoryFactsRoute","t","useTranslation","params","setParams","useSearchParams","userKey","q","cat","page","perPage","qDraft","setQDraft","useState","useEffect","timer","patchParams","query","useMemo","data","isLoading","isFetching","refetch","useMemoryFacts","facts","total","totalPages","selection","setSelection","deleteOne","useDeleteFactById","bulkDelete","useBulkDeleteFacts","confirmOneId","setConfirmOneId","confirmBulk","setConfirmBulk","patch","next","k","v","onConfirmDeleteOne","toast","err","message","describeError","onConfirmBulk","ids","r","columns","jsxs","jsx","Badge","formatEpoch","Button","e","Trash2","EmptyState","Brain","selectedCount","Loader2","RefreshCcw","Label","Search","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","c","DataTable","Pagination","p","pp","ConfirmDialog","open","ms","d"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import{n as h,u as g,j as e,k as p,B as d,l as j}from"./index-CuNnG-5O.js";import{r as u}from"./react-Cb2sDjhD.js";import{T as N,a as k,b as m,c as i,d as v,e as t}from"./table-Dbriy3Jz.js";import{b as w,c as C}from"./use-background-tasks-DHo3Hnu9.js";import{L as T}from"./loader-circle-CVEo3Hwx.js";import{R as L}from"./refresh-ccw-DZHRYuFA.js";import{C as M}from"./circle-check-D98QQwz0.js";import{C as S}from"./circle-x-Et3rwVPd.js";import"./useQuery-DIlm0vJ-.js";/**
1
+ import{n as h,u as g,j as e,k as p,B as d,l as j}from"./index-CqwhfPlr.js";import{r as u}from"./react-Cb2sDjhD.js";import{T as N,a as k,b as m,c as i,d as v,e as t}from"./table-BNqo2xb8.js";import{b as w,c as C}from"./use-background-tasks-CY2gWPBZ.js";import{L as T}from"./loader-circle-U-jPjmeD.js";import{R as L}from"./refresh-ccw-CBiHL1tY.js";import{C as M}from"./circle-check-BaxzYLlE.js";import{C as S}from"./circle-x-THl-PO3_.js";import"./useQuery-Ds6-WURB.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -14,4 +14,4 @@ import{n as h,u as g,j as e,k as p,B as d,l as j}from"./index-CuNnG-5O.js";impor
14
14
  * This source code is licensed under the ISC license.
15
15
  * See the LICENSE file in the root directory of this source tree.
16
16
  */const P=h("Target",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["circle",{cx:"12",cy:"12",r:"6",key:"1vlfrh"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}]]);function Q(){const{t:s}=g(["tasks","common"]),r=w(),o=C(),[y,f]=u.useState(null);async function n(a,l){try{await o.mutateAsync({id:a.id,status:l}),j.success(s("goals.statusUpdated",{status:l}))}catch(c){j.error(c?.message??String(c))}}const x=r.data?.goals??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(P,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:s("goals.title")}),e.jsx(p,{variant:"info",children:x.length}),e.jsxs(d,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void r.refetch(),disabled:r.isFetching,"aria-label":s("actions.refresh",{ns:"common"}),children:[r.isFetching?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(L,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("goals.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("goals.subtitle")}),r.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):x.length===0?e.jsx(A,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(N,{children:[e.jsx(k,{children:e.jsxs(m,{children:[e.jsx(i,{className:"w-12",children:s("goals.col.id")}),e.jsx(i,{children:s("goals.col.thread")}),e.jsx(i,{children:s("goals.col.title")}),e.jsx(i,{children:s("goals.col.progress")}),e.jsx(i,{children:s("goals.col.updated")}),e.jsx(i,{children:s("goals.col.actions")})]})}),e.jsx(v,{children:x.map(a=>{const l=y===a.id;return e.jsxs(u.Fragment,{children:[e.jsxs(m,{children:[e.jsx(t,{className:"font-mono text-xs",children:a.id}),e.jsxs(t,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(t,{children:e.jsx(d,{variant:"ghost",size:"sm",className:"-ml-2 text-left",onClick:()=>f(l?null:a.id),title:s(l?"goals.hideBody":"goals.showBody"),children:a.title})}),e.jsx(t,{children:e.jsx(p,{variant:"outline",children:a.progressCount})}),e.jsx(t,{className:"text-[11px] text-text-dim",children:a.updatedAt}),e.jsxs(t,{className:"flex flex-wrap gap-1",children:[e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.pause"),onClick:()=>void n(a,"paused"),disabled:o.isPending,children:e.jsx(B,{className:"h-4 w-4"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.complete"),onClick:()=>void n(a,"completed"),disabled:o.isPending,children:e.jsx(M,{className:"h-4 w-4 text-success"})}),e.jsx(d,{variant:"ghost",size:"sm",title:s("goals.cancel"),onClick:()=>void n(a,"cancelled"),disabled:o.isPending,className:"text-danger hover:text-danger",children:e.jsx(S,{className:"h-4 w-4"})})]})]}),l&&e.jsxs(m,{children:[e.jsx(t,{}),e.jsx(t,{colSpan:5,children:e.jsxs("div",{className:"space-y-2 rounded bg-surface-2 p-3 text-xs",children:[a.body&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.body")}),e.jsx("pre",{className:"mt-1 whitespace-pre-wrap break-words",children:a.body})]}),a.progressLog.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"text-text-dim",children:s("goals.recentProgress",{count:a.progressLog.length})}),e.jsx("ul",{className:"mt-1 space-y-1",children:a.progressLog.slice().reverse().map((c,b)=>e.jsxs("li",{className:"font-mono text-[11px]",children:[e.jsxs("span",{className:"text-text-dim",children:[c.ts.slice(0,19)," (",c.by,")"]})," ",c.text]},b))})]}),e.jsxs("div",{className:"text-[11px] text-text-dim",children:[s("goals.created",{at:a.createdAt}),a.closedAt?` · ${s("goals.closed",{at:a.closedAt})}`:""]})]})})]})]},a.id)})})]})})]})}function A(){const{t:s}=g("tasks");return e.jsxs("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:[s("goals.empty"),e.jsx("div",{className:"mt-2",children:e.jsx(z,{className:"mx-auto h-8 w-8 opacity-30"})})]})}export{Q as default};
17
- //# sourceMappingURL=goals-pr5ky9rG.js.map
17
+ //# sourceMappingURL=goals-C6p21B9N.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"goals-pr5ky9rG.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', { status }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n, i) => (\n <li key={i} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n","i"],"mappings":"mdAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAeC,EAAiB,eAAgB,CACpD,CAAC,OAAQ,CAAE,EAAG,gCAAiC,IAAK,QAAQ,CAAE,EAC9D,CAAC,OAAQ,CAAE,EAAG,iCAAkC,IAAK,QAAQ,CAAE,EAC/D,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAQ,CAAE,EACnE,CAAC,OAAQ,CAAE,EAAG,gCAAiC,IAAK,QAAQ,CAAE,EAC9D,CAAC,OAAQ,CAAE,EAAG,sCAAuC,IAAK,QAAQ,CAAE,EACpE,CAAC,OAAQ,CAAE,EAAG,iCAAkC,IAAK,QAAQ,CAAE,EAC/D,CAAC,OAAQ,CAAE,EAAG,oCAAqC,IAAK,QAAQ,CAAE,EAClE,CAAC,OAAQ,CAAE,EAAG,qCAAsC,IAAK,QAAQ,CAAE,CACrE,CAAC,EClBD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMC,EAAcD,EAAiB,cAAe,CAClD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,SAAU,EACzD,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,EACjE,CAAC,OAAQ,CAAE,GAAI,KAAM,GAAI,KAAM,GAAI,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,CACnE,CAAC,ECbD;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAME,EAASF,EAAiB,SAAU,CACxC,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,KAAM,IAAK,SAAU,EACzD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,SAAU,EACxD,CAAC,SAAU,CAAE,GAAI,KAAM,GAAI,KAAM,EAAG,IAAK,IAAK,QAAQ,CAAE,CAC1D,CAAC,ECKD,SAAwBG,GAA+B,CACrD,KAAM,CAAE,EAAAC,CAAA,EAAMC,EAAe,CAAC,QAAS,QAAQ,CAAC,EAC1CC,EAAYC,EAAA,EACZC,EAAeC,EAAA,EACf,CAACC,EAAYC,CAAa,EAAIC,EAAAA,SAAwB,IAAI,EAEhE,eAAeC,EAAeC,EAAYC,EAA0C,CAClF,GAAI,CACF,MAAMP,EAAa,YAAY,CAAE,GAAIM,EAAE,GAAI,OAAAC,EAAQ,EACnDC,EAAM,QAAQZ,EAAE,sBAAuB,CAAE,OAAAW,CAAA,CAAQ,CAAC,CACpD,OAASE,EAAK,CACZD,EAAM,MAAQC,GAAe,SAAW,OAAOA,CAAG,CAAE,CACtD,CACF,CAEA,MAAMC,EAAOZ,EAAU,MAAM,OAAS,CAAA,EACtC,OACEa,EAAAA,KAAC,MAAA,CAAI,UAAU,4CACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,0BAChB,SAAA,CAAAC,EAAAA,IAAClB,EAAA,CAAO,UAAU,uBAAA,CAAwB,QACzC,KAAA,CAAG,UAAU,wBAAyB,SAAAE,EAAE,aAAa,EAAE,EACxDgB,EAAAA,IAACC,EAAA,CAAM,QAAQ,OAAQ,WAAK,OAAO,EACnCF,EAAAA,KAACG,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,UACpC,QAAS,IAAM,KAAKhB,EAAU,QAAA,EAC9B,SAAUA,EAAU,WACpB,aAAYF,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAE,EAAU,iBACNiB,EAAA,CAAQ,UAAU,uBAAuB,EAC1CH,EAAAA,IAACI,EAAA,CAAW,UAAU,SAAA,CAAU,QACnC,OAAA,CAAK,UAAU,mBAAoB,SAAApB,EAAE,eAAe,CAAA,CAAE,CAAA,CAAA,CAAA,CACzD,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAAA,EAAE,gBAAgB,EAAE,EAEzDE,EAAU,UACTc,MAAC,OAAI,UAAU,4CAAA,CAA6C,EAC1DF,EAAK,SAAW,EAClBE,EAAAA,IAACK,IAAa,EAEdL,MAAC,WAAQ,UAAU,6CACjB,gBAACM,EAAA,CACC,SAAA,CAAAN,EAAAA,IAACO,EAAA,CACC,gBAACC,EAAA,CACC,SAAA,CAAAR,MAACS,EAAA,CAAU,UAAU,OAAQ,SAAAzB,EAAE,cAAc,EAAE,EAC/CgB,EAAAA,IAACS,EAAA,CAAW,SAAAzB,EAAE,kBAAkB,CAAA,CAAE,EAClCgB,EAAAA,IAACS,EAAA,CAAW,SAAAzB,EAAE,iBAAiB,CAAA,CAAE,EACjCgB,EAAAA,IAACS,EAAA,CAAW,SAAAzB,EAAE,oBAAoB,CAAA,CAAE,EACpCgB,EAAAA,IAACS,EAAA,CAAW,SAAAzB,EAAE,mBAAmB,CAAA,CAAE,EACnCgB,EAAAA,IAACS,EAAA,CAAW,SAAAzB,EAAE,mBAAmB,CAAA,CAAE,CAAA,CAAA,CACrC,CAAA,CACF,EACAgB,EAAAA,IAACU,EAAA,CACE,SAAAZ,EAAK,IAAKJ,GAAM,CACf,MAAMiB,EAAarB,IAAeI,EAAE,GACpC,cACGkB,WAAA,CACC,SAAA,CAAAb,OAACS,EAAA,CACC,SAAA,CAAAR,EAAAA,IAACa,EAAA,CAAU,UAAU,oBAAqB,SAAAnB,EAAE,GAAG,EAC/CK,EAAAA,KAACc,EAAA,CAAU,UAAU,wBAAyB,SAAA,CAAAnB,EAAE,SAAS,IAAEA,EAAE,QAAA,EAAS,QACrEmB,EAAA,CACC,SAAAb,EAAAA,IAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,kBACpC,QAAS,IAAMX,EAAcoB,EAAa,KAAOjB,EAAE,EAAE,EACrD,MAAoBV,EAAb2B,EAAe,iBAAsB,gBAAN,EAErC,SAAAjB,EAAE,KAAA,CAAA,EAEP,EACAM,EAAAA,IAACa,GAAU,SAAAb,EAAAA,IAACC,EAAA,CAAM,QAAQ,UAAW,SAAAP,EAAE,cAAc,CAAA,CAAQ,EAC7DM,EAAAA,IAACa,EAAA,CAAU,UAAU,4BAA6B,WAAE,UAAU,EAC9Dd,EAAAA,KAACc,EAAA,CAAU,UAAU,uBACnB,SAAA,CAAAb,EAAAA,IAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,MAAOlB,EAAE,aAAa,EAChD,QAAS,IAAM,KAAKS,EAAeC,EAAG,QAAQ,EAC9C,SAAUN,EAAa,UAEvB,SAAAY,EAAAA,IAACc,EAAA,CAAY,UAAU,SAAA,CAAU,CAAA,CAAA,EAEnCd,EAAAA,IAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,MAAOlB,EAAE,gBAAgB,EACnD,QAAS,IAAM,KAAKS,EAAeC,EAAG,WAAW,EACjD,SAAUN,EAAa,UAEvB,SAAAY,EAAAA,IAACe,EAAA,CAAa,UAAU,sBAAA,CAAuB,CAAA,CAAA,EAEjDf,EAAAA,IAACE,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,MAAOlB,EAAE,cAAc,EACjD,QAAS,IAAM,KAAKS,EAAeC,EAAG,WAAW,EACjD,SAAUN,EAAa,UACvB,UAAU,gCAEV,SAAAY,EAAAA,IAACgB,EAAA,CAAQ,UAAU,SAAA,CAAU,CAAA,CAAA,CAC/B,CAAA,CACF,CAAA,EACF,EACCL,UACEH,EAAA,CACC,SAAA,CAAAR,EAAAA,IAACa,EAAA,EAAU,QACVA,EAAA,CAAU,QAAS,EAClB,SAAAd,EAAAA,KAAC,MAAA,CAAI,UAAU,6CACZ,SAAA,CAAAL,EAAE,aACA,MAAA,CACC,SAAA,CAAAM,MAAC,MAAA,CAAI,UAAU,gBAAiB,SAAAhB,EAAE,YAAY,EAAE,EAChDgB,EAAAA,IAAC,MAAA,CAAI,UAAU,uCAAwC,WAAE,IAAA,CAAK,CAAA,EAChE,EAEDN,EAAE,YAAY,OAAS,UACrB,MAAA,CACC,SAAA,CAAAM,EAAAA,IAAC,MAAA,CAAI,UAAU,gBACZ,SAAAhB,EAAE,uBAAwB,CAAE,MAAOU,EAAE,YAAY,MAAA,CAAQ,CAAA,CAC5D,QACC,KAAA,CAAG,UAAU,iBACX,SAAAA,EAAE,YAAY,QAAQ,QAAA,EAAU,IAAI,CAACuB,EAAGC,IACvCnB,EAAAA,KAAC,KAAA,CAAW,UAAU,wBACpB,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,gBAAiB,SAAA,CAAAkB,EAAE,GAAG,MAAM,EAAG,EAAE,EAAE,KAAGA,EAAE,GAAG,GAAA,EAAC,EAAO,IAAEA,EAAE,IAAA,CAAA,EADhEC,CAET,CACD,CAAA,CACH,CAAA,EACF,EAEFnB,EAAAA,KAAC,MAAA,CAAI,UAAU,4BACZ,SAAA,CAAAf,EAAE,gBAAiB,CAAE,GAAIU,EAAE,UAAW,EACtCA,EAAE,SAAW,MAAMV,EAAE,eAAgB,CAAE,GAAIU,EAAE,QAAA,CAAU,CAAC,GAAK,EAAA,CAAA,CAChE,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CAAA,CACF,CAAA,CAAA,EAvEWA,EAAE,EAyEjB,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EAEJ,CAEJ,CAEA,SAASW,GAA4B,CACnC,KAAM,CAAE,EAAArB,CAAA,EAAMC,EAAe,OAAO,EACpC,OACEc,EAAAA,KAAC,UAAA,CAAQ,UAAU,mFAChB,SAAA,CAAAf,EAAE,aAAa,EAChBgB,EAAAA,IAAC,OAAI,UAAU,OACb,eAACrB,EAAA,CAAa,UAAU,6BAA6B,CAAA,CACvD,CAAA,EACF,CAEJ","x_google_ignoreList":[0,1,2]}
1
+ {"version":3,"file":"goals-C6p21B9N.js","sources":["../../node_modules/lucide-react/dist/esm/icons/circle-dashed.js","../../node_modules/lucide-react/dist/esm/icons/circle-pause.js","../../node_modules/lucide-react/dist/esm/icons/target.js","../../src/routes/tasks/goals.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CircleDashed = createLucideIcon(\"CircleDashed\", [\n [\"path\", { d: \"M10.1 2.182a10 10 0 0 1 3.8 0\", key: \"5ilxe3\" }],\n [\"path\", { d: \"M13.9 21.818a10 10 0 0 1-3.8 0\", key: \"11zvb9\" }],\n [\"path\", { d: \"M17.609 3.721a10 10 0 0 1 2.69 2.7\", key: \"1iw5b2\" }],\n [\"path\", { d: \"M2.182 13.9a10 10 0 0 1 0-3.8\", key: \"c0bmvh\" }],\n [\"path\", { d: \"M20.279 17.609a10 10 0 0 1-2.7 2.69\", key: \"1ruxm7\" }],\n [\"path\", { d: \"M21.818 10.1a10 10 0 0 1 0 3.8\", key: \"qkgqxc\" }],\n [\"path\", { d: \"M3.721 6.391a10 10 0 0 1 2.7-2.69\", key: \"1mcia2\" }],\n [\"path\", { d: \"M6.391 20.279a10 10 0 0 1-2.69-2.7\", key: \"1fvljs\" }]\n]);\n\nexport { CircleDashed as default };\n//# sourceMappingURL=circle-dashed.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst CirclePause = createLucideIcon(\"CirclePause\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"10\", x2: \"10\", y1: \"15\", y2: \"9\", key: \"c1nkhi\" }],\n [\"line\", { x1: \"14\", x2: \"14\", y1: \"15\", y2: \"9\", key: \"h65svq\" }]\n]);\n\nexport { CirclePause as default };\n//# sourceMappingURL=circle-pause.js.map\n","/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Target = createLucideIcon(\"Target\", [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"6\", key: \"1vlfrh\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }]\n]);\n\nexport { Target as default };\n//# sourceMappingURL=target.js.map\n","/**\n * /tasks/goals — admin overview of every ACTIVE goal (P1).\n */\n\nimport { Fragment, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { CheckCircle2, CircleDashed, Loader2, PauseCircle, RefreshCcw, Target, XCircle } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useGoalsList, useGoalUpdateStatus, type GoalRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksGoalsRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useGoalsList()\n const updateStatus = useGoalUpdateStatus()\n const [expandedId, setExpandedId] = useState<number | null>(null)\n\n async function onChangeStatus(g: GoalRow, status: GoalRow['status']): Promise<void> {\n try {\n await updateStatus.mutateAsync({ id: g.id, status })\n toast.success(t('goals.statusUpdated', { status }))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.goals ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <Target className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('goals.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('goals.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('goals.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-12\">{t('goals.col.id')}</TableHead>\n <TableHead>{t('goals.col.thread')}</TableHead>\n <TableHead>{t('goals.col.title')}</TableHead>\n <TableHead>{t('goals.col.progress')}</TableHead>\n <TableHead>{t('goals.col.updated')}</TableHead>\n <TableHead>{t('goals.col.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((g) => {\n const isExpanded = expandedId === g.id\n return (\n <Fragment key={g.id}>\n <TableRow>\n <TableCell className=\"font-mono text-xs\">{g.id}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{g.platform}:{g.threadId}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"-ml-2 text-left\"\n onClick={() => setExpandedId(isExpanded ? null : g.id)}\n title={isExpanded ? t('goals.hideBody') : t('goals.showBody')}\n >\n {g.title}\n </Button>\n </TableCell>\n <TableCell><Badge variant=\"outline\">{g.progressCount}</Badge></TableCell>\n <TableCell className=\"text-[11px] text-text-dim\">{g.updatedAt}</TableCell>\n <TableCell className=\"flex flex-wrap gap-1\">\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.pause')}\n onClick={() => void onChangeStatus(g, 'paused')}\n disabled={updateStatus.isPending}\n >\n <PauseCircle className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.complete')}\n onClick={() => void onChangeStatus(g, 'completed')}\n disabled={updateStatus.isPending}\n >\n <CheckCircle2 className=\"h-4 w-4 text-success\" />\n </Button>\n <Button\n variant=\"ghost\" size=\"sm\" title={t('goals.cancel')}\n onClick={() => void onChangeStatus(g, 'cancelled')}\n disabled={updateStatus.isPending}\n className=\"text-danger hover:text-danger\"\n >\n <XCircle className=\"h-4 w-4\" />\n </Button>\n </TableCell>\n </TableRow>\n {isExpanded && (\n <TableRow>\n <TableCell />\n <TableCell colSpan={5}>\n <div className=\"space-y-2 rounded bg-surface-2 p-3 text-xs\">\n {g.body && (\n <div>\n <div className=\"text-text-dim\">{t('goals.body')}</div>\n <pre className=\"mt-1 whitespace-pre-wrap break-words\">{g.body}</pre>\n </div>\n )}\n {g.progressLog.length > 0 && (\n <div>\n <div className=\"text-text-dim\">\n {t('goals.recentProgress', { count: g.progressLog.length })}\n </div>\n <ul className=\"mt-1 space-y-1\">\n {g.progressLog.slice().reverse().map((n, i) => (\n <li key={i} className=\"font-mono text-[11px]\">\n <span className=\"text-text-dim\">{n.ts.slice(0, 19)} ({n.by})</span> {n.text}\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"text-[11px] text-text-dim\">\n {t('goals.created', { at: g.createdAt })}\n {g.closedAt ? ` · ${t('goals.closed', { at: g.closedAt })}` : ''}\n </div>\n </div>\n </TableCell>\n </TableRow>\n )}\n </Fragment>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('goals.empty')}\n <div className=\"mt-2\">\n <CircleDashed className=\"mx-auto h-8 w-8 opacity-30\" />\n </div>\n </section>\n )\n}\n"],"names":["CircleDashed","createLucideIcon","CirclePause","Target","TasksGoalsRoute","t","useTranslation","listQuery","useGoalsList","updateStatus","useGoalUpdateStatus","expandedId","setExpandedId","useState","onChangeStatus","g","status","toast","err","rows","jsxs","jsx","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","isExpanded","Fragment","TableCell","PauseCircle","CheckCircle2","XCircle","n","i"],"mappings":"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","x_google_ignoreList":[0,1,2]}
@@ -1,2 +1,2 @@
1
- import{u as p,e as f,j as e,B as g,c as y}from"./index-CuNnG-5O.js";import{r as N}from"./react-Cb2sDjhD.js";import{E as v}from"./empty-state-CRnid5FY.js";import{T as w,a as C,b as h,c as i,d as M,e as o}from"./table-Dbriy3Jz.js";import{u as L}from"./use-observability-CZg_sS2t.js";import{L as T}from"./loader-circle-CVEo3Hwx.js";import{R as k}from"./refresh-ccw-DZHRYuFA.js";import{A as D}from"./activity-FCJjBNRM.js";import"./useQuery-DIlm0vJ-.js";function P(){const{t:s}=p(["observability","common"]),[l]=f(),n=Math.max(1,Number(l.get("days"))||7),{data:c,isLoading:u,isFetching:m,refetch:j}=L(n),a=c?.totals,d=c?.byDay??[],b=N.useMemo(()=>d.reduce((t,x)=>x.calls>t?x.calls:t,0),[d]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("health.title")}),e.jsxs(g,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>j(),disabled:m,"aria-label":s("actions.refresh",{ns:"common"}),children:[m?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),c&&e.jsxs("p",{className:"text-xs text-text-dim tabular-nums",children:[c.since," → ",c.until]})]}),u?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):!a||a.calls===0&&d.length===0?e.jsx(v,{icon:e.jsx(D,{}),title:s("health.empty.title"),description:s("health.empty.description")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6",children:[e.jsx(r,{label:s("health.kpi.calls"),value:String(a.calls),tone:"info"}),e.jsx(r,{label:s("health.kpi.cost"),value:`$${a.cost.toFixed(4)}`,tone:"info"}),e.jsx(r,{label:s("health.kpi.errors"),value:String(a.errors),tone:a.errors>0?"danger":"success"}),e.jsx(r,{label:s("health.kpi.errorRate"),value:`${(a.errorRate*100).toFixed(1)}%`,tone:a.errorRate>.05?"warning":"success"}),e.jsx(r,{label:s("health.kpi.avgLatencyMs"),value:`${Math.round(a.avgLatencyMs)}ms`,tone:"info"}),e.jsx(r,{label:s("health.kpi.p95LatencyMs"),value:`${Math.round(a.p95LatencyMs)}ms`,tone:"info"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim",children:s("health.byDay")}),e.jsxs(w,{children:[e.jsx(C,{children:e.jsxs(h,{children:[e.jsx(i,{className:"w-28",children:s("health.byDayCol.date")}),e.jsx(i,{children:s("health.byDayCol.calls")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.cost")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.errors")}),e.jsx(i,{className:"w-32",children:s("health.byDayCol.avgLatencyMs")})]})}),e.jsx(M,{children:d.map(t=>e.jsxs(h,{children:[e.jsx(o,{className:"font-mono text-xs",children:t.date}),e.jsx(o,{children:e.jsx(S,{value:t.calls,max:b})}),e.jsxs(o,{className:"tabular-nums",children:["$",t.cost.toFixed(4)]}),e.jsx(o,{className:"tabular-nums",children:e.jsx("span",{className:t.errors>0?"text-danger":"text-text-dim",children:t.errors})}),e.jsxs(o,{className:"tabular-nums",children:[Math.round(t.avgLatencyMs),"ms"]})]},t.date))})]})]})]})]})}const R={info:"border-info/30 text-info",success:"border-success/30 text-success",warning:"border-warning/30 text-warning",danger:"border-danger/30 text-danger"};function r({label:s,value:l,tone:n}){return e.jsxs("div",{className:y("rounded-md border bg-surface px-3 py-2",R[n]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:l})]})}function S({value:s,max:l}){const n=l>0?s/l*100:0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2",children:e.jsx("div",{className:"absolute inset-y-0 left-0 bg-accent/60",style:{width:`${n}%`}})}),e.jsx("span",{className:"tabular-nums text-sm text-text-dim",children:s})]})}export{P as default};
2
- //# sourceMappingURL=health-D_rfBsgq.js.map
1
+ import{u as p,e as f,j as e,B as g,c as y}from"./index-CqwhfPlr.js";import{r as N}from"./react-Cb2sDjhD.js";import{E as v}from"./empty-state-CrPnUC6d.js";import{T as w,a as C,b as h,c as i,d as M,e as o}from"./table-BNqo2xb8.js";import{u as L}from"./use-observability-BOepIjX5.js";import{L as T}from"./loader-circle-U-jPjmeD.js";import{R as k}from"./refresh-ccw-CBiHL1tY.js";import{A as D}from"./activity-Cckc7fGG.js";import"./useQuery-Ds6-WURB.js";function P(){const{t:s}=p(["observability","common"]),[l]=f(),n=Math.max(1,Number(l.get("days"))||7),{data:c,isLoading:u,isFetching:m,refetch:j}=L(n),a=c?.totals,d=c?.byDay??[],b=N.useMemo(()=>d.reduce((t,x)=>x.calls>t?x.calls:t,0),[d]);return e.jsxs("div",{className:"mx-auto flex max-w-7xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsx("h1",{className:"text-xl font-semibold",children:s("health.title")}),e.jsxs(g,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>j(),disabled:m,"aria-label":s("actions.refresh",{ns:"common"}),children:[m?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(k,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]}),c&&e.jsxs("p",{className:"text-xs text-text-dim tabular-nums",children:[c.since," → ",c.until]})]}),u?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):!a||a.calls===0&&d.length===0?e.jsx(v,{icon:e.jsx(D,{}),title:s("health.empty.title"),description:s("health.empty.description")}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6",children:[e.jsx(r,{label:s("health.kpi.calls"),value:String(a.calls),tone:"info"}),e.jsx(r,{label:s("health.kpi.cost"),value:`$${a.cost.toFixed(4)}`,tone:"info"}),e.jsx(r,{label:s("health.kpi.errors"),value:String(a.errors),tone:a.errors>0?"danger":"success"}),e.jsx(r,{label:s("health.kpi.errorRate"),value:`${(a.errorRate*100).toFixed(1)}%`,tone:a.errorRate>.05?"warning":"success"}),e.jsx(r,{label:s("health.kpi.avgLatencyMs"),value:`${Math.round(a.avgLatencyMs)}ms`,tone:"info"}),e.jsx(r,{label:s("health.kpi.p95LatencyMs"),value:`${Math.round(a.p95LatencyMs)}ms`,tone:"info"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim",children:s("health.byDay")}),e.jsxs(w,{children:[e.jsx(C,{children:e.jsxs(h,{children:[e.jsx(i,{className:"w-28",children:s("health.byDayCol.date")}),e.jsx(i,{children:s("health.byDayCol.calls")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.cost")}),e.jsx(i,{className:"w-24",children:s("health.byDayCol.errors")}),e.jsx(i,{className:"w-32",children:s("health.byDayCol.avgLatencyMs")})]})}),e.jsx(M,{children:d.map(t=>e.jsxs(h,{children:[e.jsx(o,{className:"font-mono text-xs",children:t.date}),e.jsx(o,{children:e.jsx(S,{value:t.calls,max:b})}),e.jsxs(o,{className:"tabular-nums",children:["$",t.cost.toFixed(4)]}),e.jsx(o,{className:"tabular-nums",children:e.jsx("span",{className:t.errors>0?"text-danger":"text-text-dim",children:t.errors})}),e.jsxs(o,{className:"tabular-nums",children:[Math.round(t.avgLatencyMs),"ms"]})]},t.date))})]})]})]})]})}const R={info:"border-info/30 text-info",success:"border-success/30 text-success",warning:"border-warning/30 text-warning",danger:"border-danger/30 text-danger"};function r({label:s,value:l,tone:n}){return e.jsxs("div",{className:y("rounded-md border bg-surface px-3 py-2",R[n]),children:[e.jsx("div",{className:"text-xs uppercase tracking-wide text-text-dim",children:s}),e.jsx("div",{className:"text-xl font-semibold tabular-nums",children:l})]})}function S({value:s,max:l}){const n=l>0?s/l*100:0;return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2",children:e.jsx("div",{className:"absolute inset-y-0 left-0 bg-accent/60",style:{width:`${n}%`}})}),e.jsx("span",{className:"tabular-nums text-sm text-text-dim",children:s})]})}export{P as default};
2
+ //# sourceMappingURL=health-D-ugz2Gp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"health-D_rfBsgq.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('health.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
1
+ {"version":3,"file":"health-D-ugz2Gp.js","sources":["../../src/routes/observability/health.tsx"],"sourcesContent":["/**\n * /observability/health — invocation totals + per-day breakdown.\n *\n * No chart library yet (would push bundle past budget). Instead we\n * render a CSS bar chart inline: each byDay row gets a horizontal\n * bar proportional to the max calls across the window. Cheap,\n * readable, no JS dependency.\n */\n\nimport { useMemo } from 'react'\nimport { useSearchParams } from 'react-router-dom'\nimport { useTranslation } from 'react-i18next'\nimport { Activity, Loader2, RefreshCcw } from 'lucide-react'\n\nimport { EmptyState } from '@/components/common/empty-state'\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from '@/components/ui/table'\nimport { Button } from '@/components/ui/button'\nimport { useHealthSummary } from '@/hooks/use-observability'\nimport { cn } from '@/lib/utils'\n\nexport default function ObservabilityHealthRoute(): JSX.Element {\n const { t } = useTranslation(['observability', 'common'])\n const [params] = useSearchParams()\n const days = Math.max(1, Number(params.get('days')) || 7)\n\n const { data, isLoading, isFetching, refetch } = useHealthSummary(days)\n const totals = data?.totals\n const byDay = data?.byDay ?? []\n\n const maxCalls = useMemo(\n () => byDay.reduce((m, r) => (r.calls > m ? r.calls : m), 0),\n [byDay],\n )\n\n return (\n <div className=\"mx-auto flex max-w-7xl flex-col gap-4\">\n <header className=\"flex flex-col gap-1\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <h1 className=\"text-xl font-semibold\">{t('health.title')}</h1>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-auto\"\n onClick={() => refetch()}\n disabled={isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {isFetching ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('actions.refresh', { ns: 'common' })}</span>\n </Button>\n </div>\n {data && (\n <p className=\"text-xs text-text-dim tabular-nums\">{data.since} → {data.until}</p>\n )}\n </header>\n\n {isLoading ? (\n <div className=\"h-48 w-full rounded-md bg-surface-2 animate-pulse\" />\n ) : !totals || (totals.calls === 0 && byDay.length === 0) ? (\n <EmptyState\n icon={<Activity />}\n title={t('health.empty.title')}\n description={t('health.empty.description')}\n />\n ) : (\n <>\n {/* KPI strip */}\n <div className=\"grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-6\">\n <Kpi label={t('health.kpi.calls')} value={String(totals.calls)} tone=\"info\" />\n <Kpi label={t('health.kpi.cost')} value={`$${totals.cost.toFixed(4)}`} tone=\"info\" />\n <Kpi label={t('health.kpi.errors')} value={String(totals.errors)} tone={totals.errors > 0 ? 'danger' : 'success'} />\n <Kpi label={t('health.kpi.errorRate')} value={`${(totals.errorRate * 100).toFixed(1)}%`} tone={totals.errorRate > 0.05 ? 'warning' : 'success'} />\n <Kpi label={t('health.kpi.avgLatencyMs')} value={`${Math.round(totals.avgLatencyMs)}ms`} tone=\"info\" />\n <Kpi label={t('health.kpi.p95LatencyMs')} value={`${Math.round(totals.p95LatencyMs)}ms`} tone=\"info\" />\n </div>\n\n {/* By-day table with inline CSS bars */}\n <div>\n <h2 className=\"mb-2 text-sm font-medium uppercase tracking-wide text-text-dim\">\n {t('health.byDay')}\n </h2>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-28\">{t('health.byDayCol.date')}</TableHead>\n <TableHead>{t('health.byDayCol.calls')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.cost')}</TableHead>\n <TableHead className=\"w-24\">{t('health.byDayCol.errors')}</TableHead>\n <TableHead className=\"w-32\">{t('health.byDayCol.avgLatencyMs')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {byDay.map((r) => (\n <TableRow key={r.date}>\n <TableCell className=\"font-mono text-xs\">{r.date}</TableCell>\n <TableCell>\n <CallsBar value={r.calls} max={maxCalls} />\n </TableCell>\n <TableCell className=\"tabular-nums\">${r.cost.toFixed(4)}</TableCell>\n <TableCell className=\"tabular-nums\">\n <span className={r.errors > 0 ? 'text-danger' : 'text-text-dim'}>{r.errors}</span>\n </TableCell>\n <TableCell className=\"tabular-nums\">{Math.round(r.avgLatencyMs)}ms</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n </>\n )}\n </div>\n )\n}\n\ninterface KpiProps {\n label: string\n value: string\n tone: 'info' | 'success' | 'warning' | 'danger'\n}\n\nconst TONE_STYLES: Record<KpiProps['tone'], string> = {\n info: 'border-info/30 text-info',\n success: 'border-success/30 text-success',\n warning: 'border-warning/30 text-warning',\n danger: 'border-danger/30 text-danger',\n}\n\nfunction Kpi({ label, value, tone }: KpiProps): JSX.Element {\n return (\n <div className={cn('rounded-md border bg-surface px-3 py-2', TONE_STYLES[tone])}>\n <div className=\"text-xs uppercase tracking-wide text-text-dim\">{label}</div>\n <div className=\"text-xl font-semibold tabular-nums\">{value}</div>\n </div>\n )\n}\n\ninterface CallsBarProps {\n value: number\n max: number\n}\n\n/** Inline CSS bar — width proportional to max across the window. */\nfunction CallsBar({ value, max }: CallsBarProps): JSX.Element {\n const pct = max > 0 ? (value / max) * 100 : 0\n return (\n <div className=\"flex items-center gap-2\">\n <div className=\"relative h-3 w-full max-w-xs overflow-hidden rounded bg-surface-2\">\n <div\n className=\"absolute inset-y-0 left-0 bg-accent/60\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <span className=\"tabular-nums text-sm text-text-dim\">{value}</span>\n </div>\n )\n}\n"],"names":["ObservabilityHealthRoute","t","useTranslation","params","useSearchParams","days","data","isLoading","isFetching","refetch","useHealthSummary","totals","byDay","maxCalls","useMemo","m","r","jsxs","jsx","Button","Loader2","RefreshCcw","EmptyState","Activity","Fragment","Kpi","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","CallsBar","TONE_STYLES","label","value","tone","cn","max","pct"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import{n as e}from"./index-CuNnG-5O.js";/**
1
+ import{n as e}from"./index-CqwhfPlr.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const t=e("HeartPulse",[["path",{d:"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z",key:"c3ymky"}],["path",{d:"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27",key:"1uw2ng"}]]);export{t as H};
7
- //# sourceMappingURL=heart-pulse-203oH09r.js.map
7
+ //# sourceMappingURL=heart-pulse-DlZXcdL0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heart-pulse-203oH09r.js","sources":["../../node_modules/lucide-react/dist/esm/icons/heart-pulse.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst HeartPulse = createLucideIcon(\"HeartPulse\", [\n [\n \"path\",\n {\n d: \"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\",\n key: \"c3ymky\"\n }\n ],\n [\"path\", { d: \"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\", key: \"1uw2ng\" }]\n]);\n\nexport { HeartPulse as default };\n//# sourceMappingURL=heart-pulse.js.map\n"],"names":["HeartPulse","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,2IACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAQ,CAAE,CAC3E,CAAC","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"heart-pulse-DlZXcdL0.js","sources":["../../node_modules/lucide-react/dist/esm/icons/heart-pulse.js"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst HeartPulse = createLucideIcon(\"HeartPulse\", [\n [\n \"path\",\n {\n d: \"M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z\",\n key: \"c3ymky\"\n }\n ],\n [\"path\", { d: \"M3.22 12H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27\", key: \"1uw2ng\" }]\n]);\n\nexport { HeartPulse as default };\n//# sourceMappingURL=heart-pulse.js.map\n"],"names":["HeartPulse","createLucideIcon"],"mappings":"wCAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASK,MAACA,EAAaC,EAAiB,aAAc,CAChD,CACE,OACA,CACE,EAAG,2IACH,IAAK,QACX,CACA,EACE,CAAC,OAAQ,CAAE,EAAG,2CAA4C,IAAK,QAAQ,CAAE,CAC3E,CAAC","x_google_ignoreList":[0]}
@@ -1,7 +1,7 @@
1
- import{n as w,u as b,j as e,k as o,B as h,l as m}from"./index-CuNnG-5O.js";import{r as N}from"./react-Cb2sDjhD.js";import{T as v,a as T,b as u,c as l,d as k,e as c}from"./table-Dbriy3Jz.js";import{u as y,a as A}from"./use-background-tasks-DHo3Hnu9.js";import{H}from"./heart-pulse-203oH09r.js";import{L as R}from"./loader-circle-CVEo3Hwx.js";import{R as S}from"./refresh-ccw-DZHRYuFA.js";import{P as C}from"./play-BedplEoY.js";import"./useQuery-DIlm0vJ-.js";/**
1
+ import{n as w,u as b,j as e,k as o,B as h,l as m}from"./index-CqwhfPlr.js";import{r as N}from"./react-Cb2sDjhD.js";import{T as v,a as T,b as u,c as l,d as k,e as c}from"./table-BNqo2xb8.js";import{u as y,a as A}from"./use-background-tasks-CY2gWPBZ.js";import{H}from"./heart-pulse-DlZXcdL0.js";import{L as R}from"./loader-circle-U-jPjmeD.js";import{R as S}from"./refresh-ccw-CBiHL1tY.js";import{P as C}from"./play-BG0hyTnO.js";import"./useQuery-Ds6-WURB.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
6
  */const P=w("Pause",[["rect",{x:"14",y:"4",width:"4",height:"16",rx:"1",key:"zuxfzm"}],["rect",{x:"6",y:"4",width:"4",height:"16",rx:"1",key:"1okwgv"}]]);function Q(){const{t}=b(["tasks","common"]),s=y(),r=A(),[j,f]=N.useState(null);async function p(a,n){try{await r.mutateAsync({row:a,op:n}),m.success(t(n==="enable"?"heartbeat.enabledToast":"heartbeat.disabledToast"))}catch(i){m.error(i?.message??String(i))}}const d=s.data?.bindings??[];return e.jsxs("div",{className:"mx-auto flex max-w-6xl flex-col gap-4 p-4",children:[e.jsxs("header",{className:"flex items-center gap-3",children:[e.jsx(H,{className:"h-5 w-5 text-text-dim"}),e.jsx("h1",{className:"text-xl font-semibold",children:t("heartbeat.title")}),e.jsx(o,{variant:"info",children:d.length}),e.jsxs(h,{variant:"ghost",size:"sm",className:"ml-auto",onClick:()=>void s.refetch(),disabled:s.isFetching,"aria-label":t("actions.refresh",{ns:"common"}),children:[s.isFetching?e.jsx(R,{className:"h-4 w-4 animate-spin"}):e.jsx(S,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:t("heartbeat.refresh")})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:t("heartbeat.subtitle")}),s.isLoading?e.jsx("div",{className:"h-48 rounded-md bg-surface-2 animate-pulse"}):d.length===0?e.jsx(z,{}):e.jsx("section",{className:"rounded-md border border-border bg-surface",children:e.jsxs(v,{children:[e.jsx(T,{children:e.jsxs(u,{children:[e.jsx(l,{children:t("heartbeat.col.thread")}),e.jsx(l,{children:t("heartbeat.col.owner")}),e.jsx(l,{children:t("heartbeat.col.interval")}),e.jsx(l,{children:t("heartbeat.col.lastTick")}),e.jsx(l,{children:t("heartbeat.col.enabled")}),e.jsx(l,{children:t("heartbeat.col.body")})]})}),e.jsx(k,{children:d.map(a=>{const n=`${a.platform}:${a.channelId}:${a.threadId}`,i=j===n,g=a.lastTickAt?a.lastStatus==="delivered"?e.jsx(o,{variant:"success",children:x(a.lastTickAt,t)}):a.lastStatus==="error"?e.jsxs(o,{variant:"danger",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsxs(o,{variant:"outline",title:a.lastReason,children:[a.lastStatus," · ",x(a.lastTickAt,t)]}):e.jsx(o,{variant:"outline",children:t("heartbeat.never")});return e.jsxs(u,{children:[e.jsxs(c,{className:"font-mono text-[11px]",children:[a.platform,":",a.threadId]}),e.jsx(c,{className:"font-mono text-[11px]",children:a.userId||"—"}),e.jsx(c,{className:"text-xs",children:t("heartbeat.intervalMin",{count:a.intervalMinutes})}),e.jsx(c,{children:g}),e.jsx(c,{children:e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>void p(a,a.enabled?"disable":"enable"),disabled:r.isPending,children:a.enabled?e.jsxs(e.Fragment,{children:[e.jsx(P,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.pause")})]}):e.jsxs(e.Fragment,{children:[e.jsx(C,{className:"h-4 w-4"}),e.jsx("span",{children:t("heartbeat.enable")})]})})}),e.jsxs(c,{className:"max-w-md",children:[e.jsx(h,{variant:"ghost",size:"sm",onClick:()=>f(i?null:n),className:"-ml-2",children:t(i?"heartbeat.hide":"heartbeat.show")}),i&&e.jsx("pre",{className:"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim",children:a.body})]})]},n)})})]})})]})}function z(){const{t}=b("tasks");return e.jsx("section",{className:"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim",children:t("heartbeat.empty")})}function x(t,s){if(!t)return s("heartbeat.never");const r=Date.now()-new Date(t).getTime();return!Number.isFinite(r)||r<0||r<6e4?s("heartbeat.justNow"):r<36e5?s("heartbeat.minutesAgo",{count:Math.floor(r/6e4)}):r<864e5?s("heartbeat.hoursAgo",{count:Math.floor(r/36e5)}):s("heartbeat.daysAgo",{count:Math.floor(r/864e5)})}export{Q as default};
7
- //# sourceMappingURL=heartbeat-B5yJoH-X.js.map
7
+ //# sourceMappingURL=heartbeat-DSasg-3y.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat-B5yJoH-X.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"ycAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASA,MAAMA,EAAQC,EAAiB,QAAS,CACtC,CAAC,OAAQ,CAAE,EAAG,KAAM,EAAG,IAAK,MAAO,IAAK,OAAQ,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC9E,CAAC,OAAQ,CAAE,EAAG,IAAK,EAAG,IAAK,MAAO,IAAK,OAAQ,KAAM,GAAI,IAAK,IAAK,QAAQ,CAAE,CAC/E,CAAC,ECMD,SAAwBC,GAAmC,CACzD,KAAM,CAAE,CAAA,EAAMC,EAAe,CAAC,QAAS,QAAQ,CAAC,EAC1CC,EAAYC,EAAA,EACZC,EAASC,EAAA,EACT,CAACC,EAAaC,CAAc,EAAIC,EAAAA,SAAwB,IAAI,EAElE,eAAeC,EAASC,EAAmBC,EAAyC,CAClF,GAAI,CACF,MAAMP,EAAO,YAAY,CAAE,IAAAM,EAAK,GAAAC,EAAI,EACpCC,EAAM,QAA0B,EAAlBD,IAAO,SAAa,yBAA8B,yBAAN,CAAgC,CAC5F,OAASE,EAAK,CACZD,EAAM,MAAQC,GAAe,SAAW,OAAOA,CAAG,CAAE,CACtD,CACF,CAEA,MAAMC,EAAOZ,EAAU,MAAM,UAAY,CAAA,EACzC,OACEa,EAAAA,KAAC,MAAA,CAAI,UAAU,4CACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CAAO,UAAU,0BAChB,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAW,UAAU,uBAAA,CAAwB,QAC7C,KAAA,CAAG,UAAU,wBAAyB,SAAA,EAAE,iBAAiB,EAAE,EAC5DD,EAAAA,IAACE,EAAA,CAAM,QAAQ,OAAQ,WAAK,OAAO,EACnCH,EAAAA,KAACI,EAAA,CACC,QAAQ,QAAQ,KAAK,KAAK,UAAU,UACpC,QAAS,IAAM,KAAKjB,EAAU,QAAA,EAC9B,SAAUA,EAAU,WACpB,aAAY,EAAE,kBAAmB,CAAE,GAAI,SAAU,EAEhD,SAAA,CAAAA,EAAU,iBACNkB,EAAA,CAAQ,UAAU,uBAAuB,EAC1CJ,EAAAA,IAACK,EAAA,CAAW,UAAU,SAAA,CAAU,QACnC,OAAA,CAAK,UAAU,mBAAoB,SAAA,EAAE,mBAAmB,CAAA,CAAE,CAAA,CAAA,CAAA,CAC7D,EACF,QACC,IAAA,CAAE,UAAU,wBAAyB,SAAA,EAAE,oBAAoB,EAAE,EAE7DnB,EAAU,UACTc,MAAC,OAAI,UAAU,4CAAA,CAA6C,EAC1DF,EAAK,SAAW,EAClBE,EAAAA,IAACM,IAAa,EAEdN,MAAC,WAAQ,UAAU,6CACjB,gBAACO,EAAA,CACC,SAAA,CAAAP,EAAAA,IAACQ,EAAA,CACC,gBAACC,EAAA,CACC,SAAA,CAAAT,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,sBAAsB,CAAA,CAAE,EACtCV,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,qBAAqB,CAAA,CAAE,EACrCV,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,wBAAwB,CAAA,CAAE,EACxCV,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,wBAAwB,CAAA,CAAE,EACxCV,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,uBAAuB,CAAA,CAAE,EACvCV,EAAAA,IAACU,EAAA,CAAW,SAAA,EAAE,oBAAoB,CAAA,CAAE,CAAA,CAAA,CACtC,CAAA,CACF,EACAV,EAAAA,IAACW,EAAA,CACE,SAAAb,EAAK,IAAKc,GAAM,CACf,MAAMC,EAAM,GAAGD,EAAE,QAAQ,IAAIA,EAAE,SAAS,IAAIA,EAAE,QAAQ,GAChDE,EAAaxB,IAAgBuB,EAC7BE,EAAaH,EAAE,WAEjBA,EAAE,aAAe,YACfZ,EAAAA,IAACE,EAAA,CAAM,QAAQ,UAAW,SAAAc,EAASJ,EAAE,WAAY,CAAC,EAAE,EACpDA,EAAE,aAAe,eACdV,EAAA,CAAM,QAAQ,SAAS,MAAOU,EAAE,WAAa,SAAA,CAAAA,EAAE,WAAW,MAAII,EAASJ,EAAE,WAAY,CAAC,CAAA,EAAE,EACzFb,OAACG,EAAA,CAAM,QAAQ,UAAU,MAAOU,EAAE,WAAa,SAAA,CAAAA,EAAE,WAAW,MAAII,EAASJ,EAAE,WAAY,CAAC,CAAA,EAAE,QAL7FV,EAAA,CAAM,QAAQ,UAAW,SAAA,EAAE,iBAAiB,CAAA,CAAE,EAMnD,cACGO,EAAA,CACC,SAAA,CAAAV,EAAAA,KAACkB,EAAA,CAAU,UAAU,wBAAyB,SAAA,CAAAL,EAAE,SAAS,IAAEA,EAAE,QAAA,EAAS,QACrEK,EAAA,CAAU,UAAU,wBAAyB,SAAAL,EAAE,QAAU,IAAI,EAC9DZ,EAAAA,IAACiB,EAAA,CAAU,UAAU,UAAW,SAAA,EAAE,wBAAyB,CAAE,MAAOL,EAAE,eAAA,CAAiB,CAAA,CAAE,EACzFZ,EAAAA,IAACiB,GAAW,SAAAF,CAAA,CAAU,QACrBE,EAAA,CACC,SAAAjB,EAAAA,IAACG,EAAA,CACC,QAAQ,QAAQ,KAAK,KACrB,QAAS,IAAM,KAAKV,EAASmB,EAAGA,EAAE,QAAU,UAAY,QAAQ,EAChE,SAAUxB,EAAO,UAEhB,SAAAwB,EAAE,QACCb,EAAAA,KAAAmB,EAAAA,SAAA,CAAE,SAAA,CAAAlB,EAAAA,IAAClB,EAAA,CAAM,UAAU,SAAA,CAAU,EAAEkB,EAAAA,IAAC,OAAA,CAAM,SAAA,EAAE,iBAAiB,CAAA,CAAE,CAAA,CAAA,CAAO,EAClED,EAAAA,KAAAmB,EAAAA,SAAA,CAAE,SAAA,CAAAlB,EAAAA,IAACmB,EAAA,CAAK,UAAU,SAAA,CAAU,EAAEnB,EAAAA,IAAC,OAAA,CAAM,SAAA,EAAE,kBAAkB,CAAA,CAAE,CAAA,CAAA,CAAO,CAAA,CAAA,EAE1E,EACAD,EAAAA,KAACkB,EAAA,CAAU,UAAU,WACnB,SAAA,CAAAjB,EAAAA,IAACG,EAAA,CACC,QAAQ,QAAQ,KAAK,KACrB,QAAS,IAAMZ,EAAeuB,EAAa,KAAOD,CAAG,EACrD,UAAU,QAET,SAAa,EAAbC,EAAe,iBAAsB,gBAAN,CAAsB,CAAA,EAEvDA,GACCd,EAAAA,IAAC,MAAA,CAAI,UAAU,0FACZ,WAAE,IAAA,CACL,CAAA,CAAA,CAEJ,CAAA,CAAA,EA7Baa,CA8Bf,CAEJ,CAAC,CAAA,CACH,CAAA,CAAA,CACF,CAAA,CACF,CAAA,EAEJ,CAEJ,CAEA,SAASP,GAA4B,CACnC,KAAM,CAAE,CAAA,EAAMrB,EAAe,OAAO,EACpC,aACG,UAAA,CAAQ,UAAU,mFAChB,SAAA,EAAE,iBAAiB,EACtB,CAEJ,CAEA,SAAS+B,EAASI,EAAoBC,EAAoE,CACxG,GAAI,CAACD,EAAK,OAAOC,EAAE,iBAAiB,EACpC,MAAMC,EAAK,KAAK,IAAA,EAAQ,IAAI,KAAKF,CAAG,EAAE,QAAA,EAEtC,MADI,CAAC,OAAO,SAASE,CAAE,GAAKA,EAAK,GAC7BA,EAAK,IAAeD,EAAE,mBAAmB,EACzCC,EAAK,KAAkBD,EAAE,uBAAwB,CAAE,MAAO,KAAK,MAAMC,EAAK,GAAM,CAAA,CAAG,EACnFA,EAAK,MAAmBD,EAAE,qBAAsB,CAAE,MAAO,KAAK,MAAMC,EAAK,IAAS,CAAA,CAAG,EAClFD,EAAE,oBAAqB,CAAE,MAAO,KAAK,MAAMC,EAAK,KAAU,EAAG,CACtE","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"heartbeat-DSasg-3y.js","sources":["../../node_modules/lucide-react/dist/esm/icons/pause.js","../../src/routes/tasks/heartbeat.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.469.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Pause = createLucideIcon(\"Pause\", [\n [\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"zuxfzm\" }],\n [\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\", rx: \"1\", key: \"1okwgv\" }]\n]);\n\nexport { Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * /tasks/heartbeat — admin overview of every heartbeat binding (P1).\n */\n\nimport { useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { toast } from 'sonner'\nimport { HeartPulse, Loader2, Pause, Play, RefreshCcw } from 'lucide-react'\n\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport {\n Table, TableBody, TableCell, TableHead, TableHeader, TableRow,\n} from '@/components/ui/table'\nimport {\n useHeartbeatList, useHeartbeatToggle, type HeartbeatRow,\n} from '@/hooks/use-background-tasks'\n\nexport default function TasksHeartbeatRoute(): JSX.Element {\n const { t } = useTranslation(['tasks', 'common'])\n const listQuery = useHeartbeatList()\n const toggle = useHeartbeatToggle()\n const [expandedKey, setExpandedKey] = useState<string | null>(null)\n\n async function onToggle(row: HeartbeatRow, op: 'enable' | 'disable'): Promise<void> {\n try {\n await toggle.mutateAsync({ row, op })\n toast.success(op === 'enable' ? t('heartbeat.enabledToast') : t('heartbeat.disabledToast'))\n } catch (err) {\n toast.error(((err as Error)?.message ?? String(err)))\n }\n }\n\n const rows = listQuery.data?.bindings ?? []\n return (\n <div className=\"mx-auto flex max-w-6xl flex-col gap-4 p-4\">\n <header className=\"flex items-center gap-3\">\n <HeartPulse className=\"h-5 w-5 text-text-dim\" />\n <h1 className=\"text-xl font-semibold\">{t('heartbeat.title')}</h1>\n <Badge variant=\"info\">{rows.length}</Badge>\n <Button\n variant=\"ghost\" size=\"sm\" className=\"ml-auto\"\n onClick={() => void listQuery.refetch()}\n disabled={listQuery.isFetching}\n aria-label={t('actions.refresh', { ns: 'common' })}\n >\n {listQuery.isFetching\n ? <Loader2 className=\"h-4 w-4 animate-spin\" />\n : <RefreshCcw className=\"h-4 w-4\" />}\n <span className=\"hidden sm:inline\">{t('heartbeat.refresh')}</span>\n </Button>\n </header>\n <p className=\"text-sm text-text-dim\">{t('heartbeat.subtitle')}</p>\n\n {listQuery.isLoading ? (\n <div className=\"h-48 rounded-md bg-surface-2 animate-pulse\" />\n ) : rows.length === 0 ? (\n <EmptySection />\n ) : (\n <section className=\"rounded-md border border-border bg-surface\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('heartbeat.col.thread')}</TableHead>\n <TableHead>{t('heartbeat.col.owner')}</TableHead>\n <TableHead>{t('heartbeat.col.interval')}</TableHead>\n <TableHead>{t('heartbeat.col.lastTick')}</TableHead>\n <TableHead>{t('heartbeat.col.enabled')}</TableHead>\n <TableHead>{t('heartbeat.col.body')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {rows.map((r) => {\n const key = `${r.platform}:${r.channelId}:${r.threadId}`\n const isExpanded = expandedKey === key\n const tickBadge = !r.lastTickAt\n ? <Badge variant=\"outline\">{t('heartbeat.never')}</Badge>\n : r.lastStatus === 'delivered'\n ? <Badge variant=\"success\">{shortAge(r.lastTickAt, t)}</Badge>\n : r.lastStatus === 'error'\n ? <Badge variant=\"danger\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n : <Badge variant=\"outline\" title={r.lastReason}>{r.lastStatus} · {shortAge(r.lastTickAt, t)}</Badge>\n return (\n <TableRow key={key}>\n <TableCell className=\"font-mono text-[11px]\">{r.platform}:{r.threadId}</TableCell>\n <TableCell className=\"font-mono text-[11px]\">{r.userId || '—'}</TableCell>\n <TableCell className=\"text-xs\">{t('heartbeat.intervalMin', { count: r.intervalMinutes })}</TableCell>\n <TableCell>{tickBadge}</TableCell>\n <TableCell>\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => void onToggle(r, r.enabled ? 'disable' : 'enable')}\n disabled={toggle.isPending}\n >\n {r.enabled\n ? <><Pause className=\"h-4 w-4\" /><span>{t('heartbeat.pause')}</span></>\n : <><Play className=\"h-4 w-4\" /><span>{t('heartbeat.enable')}</span></>}\n </Button>\n </TableCell>\n <TableCell className=\"max-w-md\">\n <Button\n variant=\"ghost\" size=\"sm\"\n onClick={() => setExpandedKey(isExpanded ? null : key)}\n className=\"-ml-2\"\n >\n {isExpanded ? t('heartbeat.hide') : t('heartbeat.show')}\n </Button>\n {isExpanded && (\n <pre className=\"mt-2 whitespace-pre-wrap break-words rounded bg-surface-2 p-2 text-[11px] text-text-dim\">\n {r.body}\n </pre>\n )}\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </section>\n )}\n </div>\n )\n}\n\nfunction EmptySection(): JSX.Element {\n const { t } = useTranslation('tasks')\n return (\n <section className=\"rounded-md border border-border bg-surface p-6 text-center text-sm text-text-dim\">\n {t('heartbeat.empty')}\n </section>\n )\n}\n\nfunction shortAge(iso: string | null, t: (key: string, opts?: Record<string, unknown>) => string): string {\n if (!iso) return t('heartbeat.never')\n const ms = Date.now() - new Date(iso).getTime()\n if (!Number.isFinite(ms) || ms < 0) return t('heartbeat.justNow')\n if (ms < 60_000) return t('heartbeat.justNow')\n if (ms < 3_600_000) return t('heartbeat.minutesAgo', { count: Math.floor(ms / 60_000) })\n if (ms < 86_400_000) return t('heartbeat.hoursAgo', { count: Math.floor(ms / 3_600_000) })\n return t('heartbeat.daysAgo', { count: Math.floor(ms / 86_400_000) })\n}\n"],"names":["Pause","createLucideIcon","TasksHeartbeatRoute","useTranslation","listQuery","useHeartbeatList","toggle","useHeartbeatToggle","expandedKey","setExpandedKey","useState","onToggle","row","op","toast","err","rows","jsxs","jsx","HeartPulse","Badge","Button","Loader2","RefreshCcw","EmptySection","Table","TableHeader","TableRow","TableHead","TableBody","r","key","isExpanded","tickBadge","shortAge","TableCell","Fragment","Play","iso","t","ms"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,4 +1,4 @@
1
- import{n as w,d as v,u as x,j as e,B as u,I as C,k as m,c as S,l as j}from"./index-CuNnG-5O.js";import{r as o}from"./react-Cb2sDjhD.js";import{E as k}from"./empty-state-CRnid5FY.js";import{D as L,a as D,b as F,c as H,d as R}from"./dialog-Cv87qelJ.js";import{u as E}from"./useQuery-DIlm0vJ-.js";import{E as M}from"./external-link-CzQc-c_P.js";import{L as T}from"./loader-circle-CVEo3Hwx.js";import{R as z}from"./refresh-ccw-DZHRYuFA.js";import{S as I}from"./search-DJXxphzz.js";import{D as A}from"./download-Cv8u9PxC.js";import{C as B}from"./copy-kCWCP9Wu.js";import"./x-D_eFtxsK.js";/**
1
+ import{n as w,d as v,u as x,j as e,B as u,I as C,k as m,c as S,l as j}from"./index-CqwhfPlr.js";import{r as o}from"./react-Cb2sDjhD.js";import{E as k}from"./empty-state-CrPnUC6d.js";import{D as L,a as D,b as F,c as H,d as R}from"./dialog-fGS0IXOo.js";import{u as E}from"./useQuery-Ds6-WURB.js";import{E as M}from"./external-link-DIJK1MAH.js";import{L as T}from"./loader-circle-U-jPjmeD.js";import{R as z}from"./refresh-ccw-CBiHL1tY.js";import{S as I}from"./search-aw0y39Qs.js";import{D as A}from"./download-5ihiF2Gj.js";import{C as B}from"./copy-DwyF4MOL.js";import"./x-ClXUlQDe.js";/**
2
2
  * @license lucide-react v0.469.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
@@ -9,4 +9,4 @@ import{n as w,d as v,u as x,j as e,B as u,I as C,k as m,c as S,l as j}from"./ind
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
11
  */const $=w("Star",[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]]),q={remoteHot:["skills","remote","hot"]};function K(){return E({queryKey:q.remoteHot,queryFn:()=>v.getSkillsRemoteHot(),staleTime:6e4})}function ae(){const{t:s}=x(["skills","common"]),{data:l,isLoading:a,isFetching:r,refetch:i}=K(),n=l?.skills??[],[h,b]=o.useState(""),[p,f]=o.useState(null),g=o.useMemo(()=>{const t=h.trim().toLowerCase();return t?n.filter(d=>d.slug.toLowerCase().includes(t)||(d.name||"").toLowerCase().includes(t)||(d.description||"").toLowerCase().includes(t)||(d.category||"").toLowerCase().includes(t)):n},[n,h]),y=p?n.find(t=>t.slug===p)??null:null;return e.jsxs("div",{className:"mx-auto flex max-w-5xl flex-col gap-4",children:[e.jsxs("header",{className:"flex flex-col gap-1",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3",children:[e.jsxs("h1",{className:"text-xl font-semibold inline-flex items-center gap-2",children:[e.jsx(N,{className:"h-5 w-5 text-warning"}),s("hot.title")]}),e.jsxs("div",{className:"ml-auto flex items-center gap-2",children:[e.jsx(u,{asChild:!0,variant:"ghost",size:"sm",children:e.jsxs("a",{href:"https://skillhub.cn",target:"_blank",rel:"noopener noreferrer",children:[e.jsx(M,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("hot.openHub")})]})}),e.jsxs(u,{variant:"ghost",size:"sm",onClick:()=>i(),disabled:r,"aria-label":s("actions.refresh",{ns:"common"}),children:[r?e.jsx(T,{className:"h-4 w-4 animate-spin"}):e.jsx(z,{className:"h-4 w-4"}),e.jsx("span",{className:"hidden sm:inline",children:s("actions.refresh",{ns:"common"})})]})]})]}),e.jsx("p",{className:"text-sm text-text-dim",children:s("hot.subtitle")}),l&&e.jsx(O,{cached:!!l.cached,stale:!!l.stale,fetchedAt:l.fetchedAt})]}),n.length>0&&e.jsxs("div",{className:"flex flex-wrap items-end gap-2",children:[e.jsxs("div",{className:"relative flex-1 min-w-[180px] max-w-md",children:[e.jsx(I,{className:"pointer-events-none absolute left-2 top-1/2 -translate-y-1/2 h-4 w-4 text-text-muted"}),e.jsx(C,{value:h,onChange:t=>b(t.target.value),placeholder:s("actions.search",{ns:"common"}),className:"pl-7"})]}),e.jsxs(m,{variant:"secondary",className:"ml-auto",children:[g.length," / ",n.length]})]}),a?e.jsx("div",{className:"h-48 w-full rounded-md bg-surface-2 animate-pulse"}):n.length===0?e.jsx(k,{icon:e.jsx(N,{}),title:s("hot.empty")}):e.jsx("ul",{className:"flex flex-col gap-2",children:g.map(t=>e.jsx("li",{children:e.jsxs("button",{type:"button",onClick:()=>f(t.slug),className:S("flex w-full flex-col gap-1 rounded-md border border-border bg-surface px-3 py-2 text-left","transition-colors hover:border-border-strong hover:bg-surface-hover"),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("span",{className:"font-medium text-text",children:t.name||t.slug}),t.version&&e.jsxs("span",{className:"text-text-muted text-xs font-mono",children:["v",t.version]}),t.category&&e.jsx(m,{variant:"outline",children:t.category}),e.jsxs("div",{className:"ml-auto flex items-center gap-3 text-xs text-text-dim tabular-nums",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx($,{className:"h-3 w-3"}),c(t.stars)]}),e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(A,{className:"h-3 w-3"}),c(t.installs)]})]})]}),e.jsx("code",{className:"text-text-muted text-xs font-mono",children:t.slug}),t.description&&e.jsx("p",{className:"line-clamp-2 text-sm text-text-dim",children:t.description})]})},t.slug))}),e.jsx(Q,{skill:y,onOpenChange:t=>{t||f(null)}})]})}function O({cached:s,stale:l,fetchedAt:a}){const{t:r}=x("skills"),i=o.useMemo(()=>{try{const n=new Date(a);return Number.isNaN(n.getTime())?"":n.toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}catch{return""}},[a]);return e.jsxs("div",{className:"flex flex-wrap items-center gap-2 text-xs text-text-muted",children:[e.jsx("span",{children:r("hot.updatedAt",{at:i})}),s&&e.jsx(m,{variant:"outline",children:r("hot.cached")}),l&&e.jsx(m,{variant:"warning",children:r("hot.stale")})]})}function Q({skill:s,onOpenChange:l}){const{t:a}=x("skills"),r=o.useMemo(()=>s?[{key:"cliInstall",cmd:`skillhub install ${s.slug}`},{key:"cliSearch",cmd:`skillhub search ${s.slug}`},{key:"imAsk",cmd:`请用 skillhub 安装 ${s.slug} 技能`}]:[],[s]);return e.jsx(L,{open:s!=null,onOpenChange:l,children:e.jsxs(D,{className:"sm:max-w-2xl",children:[e.jsxs(F,{children:[e.jsx(H,{children:s?.name||s?.slug||""}),s?.description&&e.jsx(R,{children:s.description})]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("dl",{className:"grid grid-cols-[max-content_1fr] gap-x-3 gap-y-1 text-xs",children:[e.jsx("dt",{className:"text-text-dim",children:"slug"}),e.jsx("dd",{className:"font-mono",children:s.slug}),s.version&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.version")}),e.jsxs("dd",{className:"font-mono",children:["v",s.version]})]}),s.category&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.category")}),e.jsx("dd",{children:s.category})]}),e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.stars")}),e.jsx("dd",{className:"tabular-nums",children:c(s.stars)}),e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.installs")}),e.jsx("dd",{className:"tabular-nums",children:c(s.installs)}),s.downloads!=null&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{className:"text-text-dim",children:a("hot.detail.downloads")}),e.jsx("dd",{className:"tabular-nums",children:c(s.downloads)})]})]}),e.jsxs("div",{className:"mt-4 border-t border-border pt-3",children:[e.jsx("h3",{className:"text-sm font-medium",children:a("hot.detail.howInstall")}),e.jsx("ul",{className:"mt-2 flex flex-col gap-2",children:r.map(i=>e.jsxs("li",{className:"flex flex-col gap-1 sm:flex-row sm:items-center sm:gap-2",children:[e.jsx("span",{className:"text-xs text-text-dim sm:w-40 sm:shrink-0",children:a(`hot.detail.label.${i.key}`)}),e.jsx("code",{className:"flex-1 rounded bg-surface-2 px-2 py-1 font-mono text-xs break-all",children:i.cmd}),e.jsx(_,{text:i.cmd})]},i.key))}),e.jsx("p",{className:"mt-3 text-[11px] text-text-muted",children:a("hot.detail.hint")})]})]})]})})}function _({text:s}){const{t:l}=x("skills"),[a,r]=o.useState(!1);async function i(){try{await navigator.clipboard.writeText(s),r(!0),j.success(l("hot.detail.copied")),setTimeout(()=>r(!1),1500)}catch(n){j.error(String(n?.message??n))}}return e.jsxs(u,{type:"button",variant:"secondary",size:"sm",onClick:()=>void i(),className:"shrink-0",children:[e.jsx(B,{className:"h-3 w-3"}),l(a?"hot.detail.copied":"hot.detail.copy")]})}function c(s){return s==null||!Number.isFinite(s)?"—":s.toLocaleString()}export{ae as default};
12
- //# sourceMappingURL=hot-CXGeh4Oo.js.map
12
+ //# sourceMappingURL=hot-D67pYtaV.js.map