prefect 3.6.12__py3-none-any.whl → 3.6.13__py3-none-any.whl
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.
- prefect/_build_info.py +3 -3
- prefect/_internal/compatibility/blocks.py +18 -0
- prefect/_internal/urls.py +29 -0
- prefect/_states.py +4 -1
- prefect/client/orchestration/_concurrency_limits/client.py +16 -16
- prefect/client/schemas/filters.py +24 -0
- prefect/client/subscriptions.py +1 -1
- prefect/events/clients.py +52 -13
- prefect/flow_engine.py +192 -10
- prefect/flows.py +61 -2
- prefect/results.py +262 -21
- prefect/runner/runner.py +29 -82
- prefect/runner/storage.py +6 -25
- prefect/server/schemas/filters.py +45 -0
- prefect/server/ui-v2/assets/{artifact-card-Ds2tntMW.js → artifact-card-CUEaRDGw.js} +2 -2
- prefect/server/ui-v2/assets/{artifact-card-Ds2tntMW.js.map → artifact-card-CUEaRDGw.js.map} +1 -1
- prefect/server/ui-v2/assets/{artifact._id-erPNL0a8.js → artifact._id-Ca6VCUS0.js} +2 -2
- prefect/server/ui-v2/assets/{artifact._id-erPNL0a8.js.map → artifact._id-Ca6VCUS0.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation-wizard-Bx9AQxRV.js → automation-wizard-z26pICBl.js} +2 -2
- prefect/server/ui-v2/assets/{automation-wizard-Bx9AQxRV.js.map → automation-wizard-z26pICBl.js.map} +1 -1
- prefect/server/ui-v2/assets/automation._id-DuodjY5t.js +2 -0
- prefect/server/ui-v2/assets/{automation._id-IHh5QJwE.js.map → automation._id-DuodjY5t.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation_._id.edit-Ds8vO0c5.js → automation_._id.edit-CcuJhc-y.js} +2 -2
- prefect/server/ui-v2/assets/{automation_._id.edit-Ds8vO0c5.js.map → automation_._id.edit-CcuJhc-y.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-header-C6aUe5Tw.js → automations-header-CgOWwuc6.js} +2 -2
- prefect/server/ui-v2/assets/{automations-header-C6aUe5Tw.js.map → automations-header-CgOWwuc6.js.map} +1 -1
- prefect/server/ui-v2/assets/{base-job-template-form-section-a-9TFMcW.js → base-job-template-form-section-DN9HyjM5.js} +2 -2
- prefect/server/ui-v2/assets/{base-job-template-form-section-a-9TFMcW.js.map → base-job-template-form-section-DN9HyjM5.js.map} +1 -1
- prefect/server/ui-v2/assets/{block-type-details-eq3Wg2ht.js → block-type-details-rrToxL5r.js} +2 -2
- prefect/server/ui-v2/assets/{block-type-details-eq3Wg2ht.js.map → block-type-details-rrToxL5r.js.map} +1 -1
- prefect/server/ui-v2/assets/block-type-logo-DURScH8H.js +2 -0
- prefect/server/ui-v2/assets/{block-type-logo-B31LJm5H.js.map → block-type-logo-DURScH8H.js.map} +1 -1
- prefect/server/ui-v2/assets/{block._id-OVdz3htC.js → block._id-Bue6lnrN.js} +2 -2
- prefect/server/ui-v2/assets/{block._id-OVdz3htC.js.map → block._id-Bue6lnrN.js.map} +1 -1
- prefect/server/ui-v2/assets/block_._id.edit-QY0OzN_b.js +2 -0
- prefect/server/ui-v2/assets/{block_._id.edit-CIhIBJrm.js.map → block_._id.edit-QY0OzN_b.js.map} +1 -1
- prefect/server/ui-v2/assets/catalog-CGjRGWv6.js +2 -0
- prefect/server/ui-v2/assets/{catalog-CfniU0UV.js.map → catalog-CGjRGWv6.js.map} +1 -1
- prefect/server/ui-v2/assets/catalog_._slug-BMFNZhEb.js +2 -0
- prefect/server/ui-v2/assets/{catalog_._slug-C9p86T4s.js.map → catalog_._slug-BMFNZhEb.js.map} +1 -1
- prefect/server/ui-v2/assets/catalog_._slug_.create-CuFA3kUC.js +2 -0
- prefect/server/ui-v2/assets/{catalog_._slug_.create-BhSunL__.js.map → catalog_._slug_.create-CuFA3kUC.js.map} +1 -1
- prefect/server/ui-v2/assets/{collapsible-DBD7wjpi.js → collapsible-Ell2FjrX.js} +2 -2
- prefect/server/ui-v2/assets/{collapsible-DBD7wjpi.js.map → collapsible-Ell2FjrX.js.map} +1 -1
- prefect/server/ui-v2/assets/{concurrency-limit._id-C-XWq7Tf.js → concurrency-limit._id-Rr1ysUct.js} +2 -2
- prefect/server/ui-v2/assets/{concurrency-limit._id-C-XWq7Tf.js.map → concurrency-limit._id-Rr1ysUct.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-noFojqGL.js → create-CQK8-uO1.js} +2 -2
- prefect/server/ui-v2/assets/{create-noFojqGL.js.map → create-CQK8-uO1.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-Bj2t5YQq.js → create-ewA3uq_h.js} +2 -2
- prefect/server/ui-v2/assets/{create-Bj2t5YQq.js.map → create-ewA3uq_h.js.map} +1 -1
- prefect/server/ui-v2/assets/{data-table-BjFlVIyC.js → data-table-Bx1uYX_M.js} +2 -2
- prefect/server/ui-v2/assets/{data-table-BjFlVIyC.js.map → data-table-Bx1uYX_M.js.map} +1 -1
- prefect/server/ui-v2/assets/delete-confirmation-dialog-CqKsUEj_.js +2 -0
- prefect/server/ui-v2/assets/{delete-confirmation-dialog-COdZmNfa.js.map → delete-confirmation-dialog-CqKsUEj_.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-action-header-C6v2kZ6V.js → deployment-action-header-Bz5COdER.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-action-header-C6v2kZ6V.js.map → deployment-action-header-Bz5COdER.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-form-D9d5sZM2.js → deployment-form-CrlZlNoj.js} +3 -3
- prefect/server/ui-v2/assets/{deployment-form-D9d5sZM2.js.map → deployment-form-CrlZlNoj.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-links-Dy-M1Que.js → deployment-links-D9ZR_vmp.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-links-Dy-M1Que.js.map → deployment-links-D9ZR_vmp.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment._id-BV0rSqba.js +2 -0
- prefect/server/ui-v2/assets/{deployment._id-DVmqclRz.js.map → deployment._id-BV0rSqba.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment._id-CZlY9261.js → deployment._id-DvHhx-qN.js} +2 -2
- prefect/server/ui-v2/assets/{deployment._id-CZlY9261.js.map → deployment._id-DvHhx-qN.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.duplicate-BrEOenqP.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.duplicate-DVMjpk5m.js.map → deployment_._id.duplicate-BrEOenqP.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.edit-BbYKPK42.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.edit-Ck_P6KDn.js.map → deployment_._id.edit-BbYKPK42.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.run-Cht7AHDG.js → deployment_._id.run-Dv7S_MJR.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.run-Cht7AHDG.js.map → deployment_._id.run-Dv7S_MJR.js.map} +1 -1
- prefect/server/ui-v2/assets/{dropdown-menu-xZ_3w9OP.js → dropdown-menu-e0Fqb6aw.js} +2 -2
- prefect/server/ui-v2/assets/{dropdown-menu-xZ_3w9OP.js.map → dropdown-menu-e0Fqb6aw.js.map} +1 -1
- prefect/server/ui-v2/assets/{event._eventDate._eventId-CpexuXd6.js → event._eventDate._eventId-Cp4UmGqq.js} +2 -2
- prefect/server/ui-v2/assets/{event._eventDate._eventId-CpexuXd6.js.map → event._eventDate._eventId-Cp4UmGqq.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run-graph-BrqoR3E2.js +2 -0
- prefect/server/ui-v2/assets/flow-run-graph-BrqoR3E2.js.map +1 -0
- prefect/server/ui-v2/assets/{flow-run._id-ZBlKBwPO.js → flow-run._id-BOp38Pbq.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-ZBlKBwPO.js.map → flow-run._id-BOp38Pbq.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run._id-DJnTDEN_.js +2 -0
- prefect/server/ui-v2/assets/{flow-run._id-OL0YhyLW.js.map → flow-run._id-DJnTDEN_.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run._id-D_wY_rBe.js +4 -0
- prefect/server/ui-v2/assets/flow-run._id-D_wY_rBe.js.map +1 -0
- prefect/server/ui-v2/assets/flow-runs-pagination-Bq2ZUzM6.js +2 -0
- prefect/server/ui-v2/assets/flow-runs-pagination-Bq2ZUzM6.js.map +1 -0
- prefect/server/ui-v2/assets/flow._id-eCBL95rg.js +2 -0
- prefect/server/ui-v2/assets/{flow._id-DhrCicwR.js.map → flow._id-eCBL95rg.js.map} +1 -1
- prefect/server/ui-v2/assets/{form-BTub_PhK.js → form-DNerk3LS.js} +2 -2
- prefect/server/ui-v2/assets/{form-BTub_PhK.js.map → form-DNerk3LS.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-6wmrKLU3.js → header-B0ejRncu.js} +2 -2
- prefect/server/ui-v2/assets/{header-6wmrKLU3.js.map → header-B0ejRncu.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-Dp9qi8fq.js → header-DwagHBlF.js} +2 -2
- prefect/server/ui-v2/assets/{header-Dp9qi8fq.js.map → header-DwagHBlF.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-B75eb688.js → header-huSvwxKI.js} +2 -2
- prefect/server/ui-v2/assets/{header-B75eb688.js.map → header-huSvwxKI.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-DSaSov8V.js → index-BO3SOwdV.js} +2 -2
- prefect/server/ui-v2/assets/{index-DSaSov8V.js.map → index-BO3SOwdV.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-DOkFJdYY.js → index-BTPE3vs7.js} +2 -2
- prefect/server/ui-v2/assets/{index-DOkFJdYY.js.map → index-BTPE3vs7.js.map} +1 -1
- prefect/server/ui-v2/assets/index-BU4yZRd3.js +2 -0
- prefect/server/ui-v2/assets/{index-Cs8eFQKw.js.map → index-BU4yZRd3.js.map} +1 -1
- prefect/server/ui-v2/assets/index-BhALpenO.js +2 -0
- prefect/server/ui-v2/assets/{index-qPlIYf3i.js.map → index-BhALpenO.js.map} +1 -1
- prefect/server/ui-v2/assets/index-BzN9bQeM.js +2 -0
- prefect/server/ui-v2/assets/{index-CT_nG86y.js.map → index-BzN9bQeM.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-zpb5iSCL.js → index-CBhi1P9g.js} +2 -2
- prefect/server/ui-v2/assets/{index-zpb5iSCL.js.map → index-CBhi1P9g.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-UN2Tx4jH.js → index-CRDz4nhM.js} +2 -2
- prefect/server/ui-v2/assets/{index-UN2Tx4jH.js.map → index-CRDz4nhM.js.map} +1 -1
- prefect/server/ui-v2/assets/index-CTnoa3Ho.js +2 -0
- prefect/server/ui-v2/assets/index-CTnoa3Ho.js.map +1 -0
- prefect/server/ui-v2/assets/{index-DzMGV8GV.js → index-CWkbSdxY.js} +2 -2
- prefect/server/ui-v2/assets/{index-DzMGV8GV.js.map → index-CWkbSdxY.js.map} +1 -1
- prefect/server/ui-v2/assets/index-CgOsOj5t.js +2 -0
- prefect/server/ui-v2/assets/{index-7ThYp9SY.js.map → index-CgOsOj5t.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CGWoVV2s.js → index-CnIJUujl.js} +2 -2
- prefect/server/ui-v2/assets/{index-CGWoVV2s.js.map → index-CnIJUujl.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-D08xgmV0.js → index-Cutg_A1j.js} +2 -2
- prefect/server/ui-v2/assets/{index-D08xgmV0.js.map → index-Cutg_A1j.js.map} +1 -1
- prefect/server/ui-v2/assets/index-D5RdrxkU.js +17 -0
- prefect/server/ui-v2/assets/index-D5RdrxkU.js.map +1 -0
- prefect/server/ui-v2/assets/{index-DfiNsXba.js → index-DDiyFpIV.js} +2 -2
- prefect/server/ui-v2/assets/{index-DfiNsXba.js.map → index-DDiyFpIV.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-BA7ACCoL.js → index-DI2DC5gd.js} +2 -2
- prefect/server/ui-v2/assets/{index-BA7ACCoL.js.map → index-DI2DC5gd.js.map} +1 -1
- prefect/server/ui-v2/assets/index-Dg_duvDx.js +2 -0
- prefect/server/ui-v2/assets/{index-B_3f8Hcb.js.map → index-Dg_duvDx.js.map} +1 -1
- prefect/server/ui-v2/assets/index-Dspw5HFj.js +2 -0
- prefect/server/ui-v2/assets/{index-7-r4ia_S.js.map → index-Dspw5HFj.js.map} +1 -1
- prefect/server/ui-v2/assets/index-NY089eTx.css +1 -0
- prefect/server/ui-v2/assets/{index-DYOACRXY.js → index-VOOLxiSE.js} +2 -2
- prefect/server/ui-v2/assets/{index-DYOACRXY.js.map → index-VOOLxiSE.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-HGoNWFfP.js → index-Wfs7Cjew.js} +2 -2
- prefect/server/ui-v2/assets/{index-HGoNWFfP.js.map → index-Wfs7Cjew.js.map} +1 -1
- prefect/server/ui-v2/assets/index-dSUEBAqg.js +2 -0
- prefect/server/ui-v2/assets/{index-H6bwm6L6.js.map → index-dSUEBAqg.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-D3ILnEzm.js → index-uvH5a3zO.js} +2 -2
- prefect/server/ui-v2/assets/{index-D3ILnEzm.js.map → index-uvH5a3zO.js.map} +1 -1
- prefect/server/ui-v2/assets/{json-input-9UPGqxTw.js → json-input-gXz7BuJj.js} +2 -2
- prefect/server/ui-v2/assets/{json-input-9UPGqxTw.js.map → json-input-gXz7BuJj.js.map} +1 -1
- prefect/server/ui-v2/assets/{key._key-CTFfXO_k.js → key._key-CJPbLXwU.js} +2 -2
- prefect/server/ui-v2/assets/{key._key-CTFfXO_k.js.map → key._key-CJPbLXwU.js.map} +1 -1
- prefect/server/ui-v2/assets/{lazy-markdown-BHwIrC8E.js → lazy-markdown-wPid80zf.js} +2 -2
- prefect/server/ui-v2/assets/{lazy-markdown-BHwIrC8E.js.map → lazy-markdown-wPid80zf.js.map} +1 -1
- prefect/server/ui-v2/assets/{login-kqmT29n7.js → login-DC63bGXK.js} +2 -2
- prefect/server/ui-v2/assets/{login-kqmT29n7.js.map → login-DC63bGXK.js.map} +1 -1
- prefect/server/ui-v2/assets/{markdown-input-BesmAbLS.js → markdown-input-BhqrU6Eo.js} +2 -2
- prefect/server/ui-v2/assets/{markdown-input-BesmAbLS.js.map → markdown-input-BhqrU6Eo.js.map} +1 -1
- prefect/server/ui-v2/assets/{python-example-snippet-COTWYn1Y.js → python-example-snippet-3jtXWQZN.js} +3 -3
- prefect/server/ui-v2/assets/{python-example-snippet-COTWYn1Y.js.map → python-example-snippet-3jtXWQZN.js.map} +1 -1
- prefect/server/ui-v2/assets/{python-input-Bjccebi0.js → python-input-ZVi-v324.js} +2 -2
- prefect/server/ui-v2/assets/{python-input-Bjccebi0.js.map → python-input-ZVi-v324.js.map} +1 -1
- prefect/server/ui-v2/assets/{radio-group-DkAK0M2h.js → radio-group-BBMLpHGc.js} +2 -2
- prefect/server/ui-v2/assets/{radio-group-DkAK0M2h.js.map → radio-group-BBMLpHGc.js.map} +1 -1
- prefect/server/ui-v2/assets/route-error-state-BJXl8qkX.js +2 -0
- prefect/server/ui-v2/assets/{route-error-state-ALftyvGl.js.map → route-error-state-BJXl8qkX.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-BR4E-WXE.js → schema-form-BEqYjsM-.js} +2 -2
- prefect/server/ui-v2/assets/{schema-form-BR4E-WXE.js.map → schema-form-BEqYjsM-.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BhL8C5NS.js → schema-form-input-string-format-datetime-l3xt3PWf.js} +4 -4
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BhL8C5NS.js.map → schema-form-input-string-format-datetime-l3xt3PWf.js.map} +1 -1
- prefect/server/ui-v2/assets/settings-txD0dR5Q.js +2 -0
- prefect/server/ui-v2/assets/settings-txD0dR5Q.js.map +1 -0
- prefect/server/ui-v2/assets/{sort-filter-BD4vwJXt.js → sort-filter-DHPFdKZ2.js} +2 -2
- prefect/server/ui-v2/assets/{sort-filter-BD4vwJXt.js.map → sort-filter-DHPFdKZ2.js.map} +1 -1
- prefect/server/ui-v2/assets/state-colors-CAAf0Eg3.js +2 -0
- prefect/server/ui-v2/assets/state-colors-CAAf0Eg3.js.map +1 -0
- prefect/server/ui-v2/assets/table-ULfpXJXB.js +2 -0
- prefect/server/ui-v2/assets/table-ULfpXJXB.js.map +1 -0
- prefect/server/ui-v2/assets/tags-input-BLzMOTDb.js +2 -0
- prefect/server/ui-v2/assets/tags-input-BLzMOTDb.js.map +1 -0
- prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-BpeKHk7g.js +2 -0
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-CG3den1B.js.map → task-run-concurrency-limits-reset-dialog-BpeKHk7g.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-DOcIzVi0.js → task-run._id-CkOl9MJs.js} +3 -3
- prefect/server/ui-v2/assets/{task-run._id-DOcIzVi0.js.map → task-run._id-CkOl9MJs.js.map} +1 -1
- prefect/server/ui-v2/assets/task-run._id-udkz1lhh.js +2 -0
- prefect/server/ui-v2/assets/{task-run._id-CnIVqU6v.js.map → task-run._id-udkz1lhh.js.map} +1 -1
- prefect/server/ui-v2/assets/task-runs-pagination-B7D5K_FM.js +2 -0
- prefect/server/ui-v2/assets/{task-runs-pagination-DLSAz-Ur.js.map → task-runs-pagination-B7D5K_FM.js.map} +1 -1
- prefect/server/ui-v2/assets/{textarea-D8LjlIx7.js → textarea-C4bdj7Jk.js} +2 -2
- prefect/server/ui-v2/assets/{textarea-D8LjlIx7.js.map → textarea-C4bdj7Jk.js.map} +1 -1
- prefect/server/ui-v2/assets/{timezone-select-BG3cL3-U.js → timezone-select-AdlSRQxZ.js} +2 -2
- prefect/server/ui-v2/assets/{timezone-select-BG3cL3-U.js.map → timezone-select-AdlSRQxZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{toggle-group-D3zeurIL.js → toggle-group-C-vxYz4l.js} +2 -2
- prefect/server/ui-v2/assets/{toggle-group-D3zeurIL.js.map → toggle-group-C-vxYz4l.js.map} +1 -1
- prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-Cqhaqtqe.js +2 -0
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-Bzy2ML2T.js.map → use-delete-automation-confirmation-dialog-Cqhaqtqe.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-DRAP-Tnu.js → use-delete-block-document-confirmation-dialog-GjNhFxZe.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-DRAP-Tnu.js.map → use-delete-block-document-confirmation-dialog-GjNhFxZe.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-D4yWonR8.js → use-flow-runs-selected-rows-DfwmswyR.js} +2 -2
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-D4yWonR8.js.map → use-flow-runs-selected-rows-DfwmswyR.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-DZeBiVd9.js → use-get-artifacts-flow-task-runs-BEBpG_5J.js} +2 -2
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-DZeBiVd9.js.map → use-get-artifacts-flow-task-runs-BEBpG_5J.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-quick-run-BxAMqZDM.js → use-quick-run-BYBRcDwC.js} +2 -2
- prefect/server/ui-v2/assets/{use-quick-run-BxAMqZDM.js.map → use-quick-run-BYBRcDwC.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-stepper-T3wAKNvM.js → use-stepper-Bk97vOTm.js} +2 -2
- prefect/server/ui-v2/assets/{use-stepper-T3wAKNvM.js.map → use-stepper-Bk97vOTm.js.map} +1 -1
- prefect/server/ui-v2/assets/{utilities-B2JMf8iI.js → utilities-BQwGFLk5.js} +2 -2
- prefect/server/ui-v2/assets/{utilities-B2JMf8iI.js.map → utilities-BQwGFLk5.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool-filter-CZz0AJlt.js → work-pool-filter-Ddhp_M-L.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-filter-CZz0AJlt.js.map → work-pool-filter-Ddhp_M-L.js.map} +1 -1
- prefect/server/ui-v2/assets/work-pool-queue-toggle-DX3eV3R_.js +2 -0
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-D4eeo-hi.js.map → work-pool-queue-toggle-DX3eV3R_.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool._workPoolName-DrWddu9K.js → work-pool._workPoolName-BaRIsXBX.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool._workPoolName-DrWddu9K.js.map → work-pool._workPoolName-BaRIsXBX.js.map} +1 -1
- prefect/server/ui-v2/assets/work-pool_._workPoolName.edit-dhS_Xz32.js +2 -0
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-CA0ePjCk.js.map → work-pool_._workPoolName.edit-dhS_Xz32.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DpUnE86v.js → work-pool_._workPoolName.queue._workQueueName-BlstL9Se.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-DpUnE86v.js.map → work-pool_._workPoolName.queue._workQueueName-BlstL9Se.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-queue-icon-text-BjiA7vAW.js → work-queue-icon-text-_Ez8e2dw.js} +2 -2
- prefect/server/ui-v2/assets/{work-queue-icon-text-BjiA7vAW.js.map → work-queue-icon-text-_Ez8e2dw.js.map} +1 -1
- prefect/server/ui-v2/index.html +2 -2
- prefect/settings/models/flows.py +14 -1
- prefect/settings/models/runner.py +16 -6
- prefect/task_engine.py +17 -3
- prefect/task_worker.py +99 -17
- prefect/tasks.py +2 -2
- prefect/testing/fixtures.py +41 -6
- {prefect-3.6.12.dist-info → prefect-3.6.13.dist-info}/METADATA +1 -1
- {prefect-3.6.12.dist-info → prefect-3.6.13.dist-info}/RECORD +221 -220
- prefect/server/ui-v2/assets/automation._id-IHh5QJwE.js +0 -2
- prefect/server/ui-v2/assets/block-type-logo-B31LJm5H.js +0 -2
- prefect/server/ui-v2/assets/block_._id.edit-CIhIBJrm.js +0 -2
- prefect/server/ui-v2/assets/catalog-CfniU0UV.js +0 -2
- prefect/server/ui-v2/assets/catalog_._slug-C9p86T4s.js +0 -2
- prefect/server/ui-v2/assets/catalog_._slug_.create-BhSunL__.js +0 -2
- prefect/server/ui-v2/assets/delete-confirmation-dialog-COdZmNfa.js +0 -2
- prefect/server/ui-v2/assets/deployment._id-DVmqclRz.js +0 -2
- prefect/server/ui-v2/assets/deployment_._id.duplicate-DVMjpk5m.js +0 -2
- prefect/server/ui-v2/assets/deployment_._id.edit-Ck_P6KDn.js +0 -2
- prefect/server/ui-v2/assets/flow-run-graph-CfoPEAgQ.js +0 -2
- prefect/server/ui-v2/assets/flow-run-graph-CfoPEAgQ.js.map +0 -1
- prefect/server/ui-v2/assets/flow-run._id-C-qxwEBp.js +0 -4
- prefect/server/ui-v2/assets/flow-run._id-C-qxwEBp.js.map +0 -1
- prefect/server/ui-v2/assets/flow-run._id-OL0YhyLW.js +0 -2
- prefect/server/ui-v2/assets/flow-runs-pagination-DnwkJapB.js +0 -2
- prefect/server/ui-v2/assets/flow-runs-pagination-DnwkJapB.js.map +0 -1
- prefect/server/ui-v2/assets/flow._id-DhrCicwR.js +0 -2
- prefect/server/ui-v2/assets/index-7-r4ia_S.js +0 -2
- prefect/server/ui-v2/assets/index-7ThYp9SY.js +0 -2
- prefect/server/ui-v2/assets/index-B7zHzWQW.css +0 -1
- prefect/server/ui-v2/assets/index-B_3f8Hcb.js +0 -2
- prefect/server/ui-v2/assets/index-BiCd-Iuz.js +0 -2
- prefect/server/ui-v2/assets/index-BiCd-Iuz.js.map +0 -1
- prefect/server/ui-v2/assets/index-CT_nG86y.js +0 -2
- prefect/server/ui-v2/assets/index-Cs8eFQKw.js +0 -2
- prefect/server/ui-v2/assets/index-H6bwm6L6.js +0 -2
- prefect/server/ui-v2/assets/index-WYPZo52S.js +0 -17
- prefect/server/ui-v2/assets/index-WYPZo52S.js.map +0 -1
- prefect/server/ui-v2/assets/index-qPlIYf3i.js +0 -2
- prefect/server/ui-v2/assets/route-error-state-ALftyvGl.js +0 -2
- prefect/server/ui-v2/assets/settings-BL0X8cDU.js +0 -2
- prefect/server/ui-v2/assets/settings-BL0X8cDU.js.map +0 -1
- prefect/server/ui-v2/assets/table-CEAx-qHs.js +0 -2
- prefect/server/ui-v2/assets/table-CEAx-qHs.js.map +0 -1
- prefect/server/ui-v2/assets/tags-input-D1RJZEUA.js +0 -2
- prefect/server/ui-v2/assets/tags-input-D1RJZEUA.js.map +0 -1
- prefect/server/ui-v2/assets/task-run-concurrency-limits-reset-dialog-CG3den1B.js +0 -2
- prefect/server/ui-v2/assets/task-run._id-CnIVqU6v.js +0 -2
- prefect/server/ui-v2/assets/task-runs-pagination-DLSAz-Ur.js +0 -2
- prefect/server/ui-v2/assets/use-delete-automation-confirmation-dialog-Bzy2ML2T.js +0 -2
- prefect/server/ui-v2/assets/use-local-storage-CpxMp5wR.js +0 -2
- prefect/server/ui-v2/assets/use-local-storage-CpxMp5wR.js.map +0 -1
- prefect/server/ui-v2/assets/work-pool-queue-toggle-D4eeo-hi.js +0 -2
- prefect/server/ui-v2/assets/work-pool_._workPoolName.edit-CA0ePjCk.js +0 -2
- {prefect-3.6.12.dist-info → prefect-3.6.13.dist-info}/WHEEL +0 -0
- {prefect-3.6.12.dist-info → prefect-3.6.13.dist-info}/entry_points.txt +0 -0
- {prefect-3.6.12.dist-info → prefect-3.6.13.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as s,L as
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{j as s,L as r,p as n}from"./vendor-tanstack-BK8oseNA.js";import{E as l,t as m,v as c,w as d,x,q as p,I as u,D as j,br as g,al as h,C as f,B as A,g as y,h as b,bs as D}from"./index-D5RdrxkU.js";import{D as N}from"./delete-confirmation-dialog-CqKsUEj_.js";import{u as v,A as S,a as E,b as B,c as C,d as L}from"./use-delete-automation-confirmation-dialog-Cqhaqtqe.js";import{A as k}from"./automations-header-CgOWwuc6.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-forms-DxqqmhL5.js";import"./vendor-date-7GxEwcQM.js";import"./work-queue-icon-text-_Ez8e2dw.js";import"./index-Cutg_A1j.js";import"./dropdown-menu-e0Fqb6aw.js";import"./use-delete-confirmation-dialog-CvQEyyhU.js";const I=()=>s.jsxs(l,{children:[s.jsx(m,{id:"Bot"}),s.jsx(c,{children:"Create an automation to get started"}),s.jsx(d,{children:"Automations bring reactivity to your data stack and let you configure triggers and actions based on events."}),s.jsxs(x,{children:[s.jsx(r,{to:"/automations/create",children:s.jsxs(p,{children:["Add Automation ",s.jsx(u,{id:"Plus",className:"size-4 ml-2"})]})}),s.jsx(j,{id:"automations-guide"})]})]}),T=()=>{const[e,i]=v(),{data:a}=n(g()),o=t=>i(t);return s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsx(k,{}),a.length===0?s.jsx(I,{}):s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsxs(h,{variant:"bodySmall",className:"text-muted-foreground",children:[a.length," ",`${a.length===1?"automation":"automations"}`]}),s.jsx("ul",{className:"flex flex-col gap-2",children:a.map(t=>s.jsx("li",{"aria-label":`automation item ${t.name}`,children:s.jsx($,{automation:t,onDelete:()=>o(t)})},t.id))})]})]}),s.jsx(N,{...e})]})},$=({automation:e,onDelete:i})=>s.jsxs(f,{className:"p-4 pt-5 flex flex-col gap-6",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx(w,{automation:e}),s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(S,{automation:e}),s.jsx(E,{id:e.id,onDelete:i})]})]}),s.jsxs("div",{className:"flex flex-col gap-4",children:[e.description&&s.jsx(B,{automation:e}),s.jsx(C,{automation:e}),s.jsx(L,{automation:e})]})]}),w=({automation:e})=>s.jsx(A,{children:s.jsx(y,{children:s.jsx(b,{className:"text-xl",children:s.jsx(D,{to:"/automations/automation/$id",params:{id:e.id},className:"text-lg",children:e.name})})})}),W=T;export{W as component};
|
|
2
|
+
//# sourceMappingURL=index-BTPE3vs7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-BTPE3vs7.js","sources":["../../src/components/automations/automations-empty-state/automations-empty-state.tsx","../../src/components/automations/automations-page.tsx","../../src/routes/automations/index.tsx?tsr-split=component"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { Button } from \"@/components/ui/button\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport {\n\tEmptyState,\n\tEmptyStateActions,\n\tEmptyStateDescription,\n\tEmptyStateIcon,\n\tEmptyStateTitle,\n} from \"@/components/ui/empty-state\";\nimport { Icon } from \"@/components/ui/icons\";\n\nexport const AutomationsEmptyState = () => {\n\treturn (\n\t\t<EmptyState>\n\t\t\t<EmptyStateIcon id=\"Bot\" />\n\t\t\t<EmptyStateTitle>Create an automation to get started</EmptyStateTitle>\n\t\t\t<EmptyStateDescription>\n\t\t\t\tAutomations bring reactivity to your data stack and let you configure\n\t\t\t\ttriggers and actions based on events.\n\t\t\t</EmptyStateDescription>\n\t\t\t<EmptyStateActions>\n\t\t\t\t<Link to=\"/automations/create\">\n\t\t\t\t\t<Button>\n\t\t\t\t\t\tAdd Automation <Icon id=\"Plus\" className=\"size-4 ml-2\" />\n\t\t\t\t\t</Button>\n\t\t\t\t</Link>\n\t\t\t\t<DocsLink id=\"automations-guide\" />\n\t\t\t</EmptyStateActions>\n\t\t</EmptyState>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { type Automation, buildListAutomationsQuery } from \"@/api/automations\";\nimport {\n\tBreadcrumb,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbList,\n} from \"@/components/ui/breadcrumb\";\nimport { Card } from \"@/components/ui/card\";\nimport { DeleteConfirmationDialog } from \"@/components/ui/delete-confirmation-dialog\";\nimport { Typography } from \"../ui/typography\";\nimport {\n\tAutomationActions,\n\tAutomationDescription,\n\tAutomationTrigger,\n} from \"./automation-details\";\nimport { AutomationEnableToggle } from \"./automation-enable-toggle\";\nimport { AutomationsActionsMenu } from \"./automations-actions-menu\";\nimport { AutomationsEmptyState } from \"./automations-empty-state\";\nimport { AutomationsHeader } from \"./automations-header\";\nimport { useDeleteAutomationConfirmationDialog } from \"./use-delete-automation-confirmation-dialog\";\n\nexport const AutomationsPage = () => {\n\tconst [dialogState, confirmDelete] = useDeleteAutomationConfirmationDialog();\n\tconst { data } = useSuspenseQuery(buildListAutomationsQuery());\n\n\tconst handleDelete = (automation: Automation) => confirmDelete(automation);\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t<AutomationsHeader />\n\t\t\t\t{data.length === 0 ? (\n\t\t\t\t\t<AutomationsEmptyState />\n\t\t\t\t) : (\n\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t<Typography variant=\"bodySmall\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t{data.length}{\" \"}\n\t\t\t\t\t\t\t{`${data.length === 1 ? \"automation\" : \"automations\"}`}\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t<ul className=\"flex flex-col gap-2\">\n\t\t\t\t\t\t\t{data.map((automation) => (\n\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\tkey={automation.id}\n\t\t\t\t\t\t\t\t\taria-label={`automation item ${automation.name}`}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<AutomationCardDetails\n\t\t\t\t\t\t\t\t\t\tautomation={automation}\n\t\t\t\t\t\t\t\t\t\tonDelete={() => handleDelete(automation)}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t\t<DeleteConfirmationDialog {...dialogState} />\n\t\t</>\n\t);\n};\n\ntype AutomationCardDetailsProps = {\n\tautomation: Automation;\n\tonDelete: () => void;\n};\nconst AutomationCardDetails = ({\n\tautomation,\n\tonDelete,\n}: AutomationCardDetailsProps) => {\n\treturn (\n\t\t<Card className=\"p-4 pt-5 flex flex-col gap-6\">\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t<NavHeader automation={automation} />\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<AutomationEnableToggle automation={automation} />\n\t\t\t\t\t<AutomationsActionsMenu id={automation.id} onDelete={onDelete} />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t{automation.description && (\n\t\t\t\t\t<AutomationDescription automation={automation} />\n\t\t\t\t)}\n\t\t\t\t<AutomationTrigger automation={automation} />\n\t\t\t\t<AutomationActions automation={automation} />\n\t\t\t</div>\n\t\t</Card>\n\t);\n};\n\ntype NavHeaderProps = {\n\tautomation: Automation;\n};\n\nconst NavHeader = ({ automation }: NavHeaderProps) => {\n\treturn (\n\t\t<Breadcrumb>\n\t\t\t<BreadcrumbList>\n\t\t\t\t<BreadcrumbItem className=\"text-xl\">\n\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\tto=\"/automations/automation/$id\"\n\t\t\t\t\t\tparams={{ id: automation.id }}\n\t\t\t\t\t\tclassName=\"text-lg\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{automation.name}\n\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t</BreadcrumbItem>\n\t\t\t</BreadcrumbList>\n\t\t</Breadcrumb>\n\t);\n};\n","import type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { buildListAutomationsQuery } from \"@/api/automations\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport { AutomationsHeader } from \"@/components/automations/automations-header\";\nimport { AutomationsPage } from \"@/components/automations/automations-page\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\n\nfunction AutomationsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load automations\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<AutomationsHeader />\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\n// nb: Currently there is no filtering or search params used on this page\nexport const Route = createFileRoute(\"/automations/\")({\n\tcomponent: AutomationsPage,\n\terrorComponent: AutomationsErrorComponent,\n\tloader: ({ context }) =>\n\t\tcontext.queryClient.ensureQueryData(buildListAutomationsQuery()),\n\twrapInSuspense: true,\n});\n"],"names":["AutomationsEmptyState","EmptyState","jsx","EmptyStateIcon","EmptyStateTitle","EmptyStateDescription","EmptyStateActions","Link","jsxs","Button","Icon","DocsLink","AutomationsPage","dialogState","confirmDelete","useDeleteAutomationConfirmationDialog","data","useSuspenseQuery","buildListAutomationsQuery","handleDelete","automation","Fragment","AutomationsHeader","Typography","AutomationCardDetails","DeleteConfirmationDialog","onDelete","Card","NavHeader","AutomationEnableToggle","AutomationsActionsMenu","AutomationDescription","AutomationTrigger","AutomationActions","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","SplitComponent"],"mappings":"0vBAYO,MAAMA,EAAwB,WAElCC,EAAA,CACA,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAe,GAAG,KAAA,CAAM,EACzBD,EAAAA,IAACE,GAAgB,SAAA,qCAAA,CAAmC,EACpDF,EAAAA,IAACG,GAAsB,SAAA,6GAAA,CAGvB,SACCC,EAAA,CACA,SAAA,CAAAJ,MAACK,EAAA,CAAK,GAAG,sBACR,SAAAC,EAAAA,KAACC,EAAA,CAAO,SAAA,CAAA,kBACQP,EAAAA,IAACQ,EAAA,CAAK,GAAG,OAAO,UAAU,aAAA,CAAc,CAAA,CAAA,CACxD,CAAA,CACD,EACAR,EAAAA,IAACS,EAAA,CAAS,GAAG,mBAAA,CAAoB,CAAA,CAAA,CAClC,CAAA,EACD,ECPWC,EAAkB,IAAM,CACpC,KAAM,CAACC,EAAaC,CAAa,EAAIC,EAAA,EAC/B,CAAE,KAAAC,CAAA,EAASC,EAAiBC,GAA2B,EAEvDC,EAAgBC,GAA2BN,EAAcM,CAAU,EAEzE,OACCZ,EAAAA,KAAAa,WAAA,CACC,SAAA,CAAAb,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAN,EAAAA,IAACoB,EAAA,EAAkB,EAClBN,EAAK,SAAW,EAChBd,EAAAA,IAACF,IAAsB,EAEvBQ,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAA,EAAAA,KAACe,EAAA,CAAW,QAAQ,YAAY,UAAU,wBACxC,SAAA,CAAAP,EAAK,OAAQ,IACb,GAAGA,EAAK,SAAW,EAAI,aAAe,aAAa,EAAA,EACrD,QACC,KAAA,CAAG,UAAU,sBACZ,SAAAA,EAAK,IAAKI,GACVlB,EAAAA,IAAC,KAAA,CAEA,aAAY,mBAAmBkB,EAAW,IAAI,GAE9C,SAAAlB,EAAAA,IAACsB,EAAA,CACA,WAAAJ,EACA,SAAU,IAAMD,EAAaC,CAAU,CAAA,CAAA,CACxC,EANKA,EAAW,EAAA,CAQjB,CAAA,CACF,CAAA,CAAA,CACD,CAAA,EAEF,EACAlB,MAACuB,EAAA,CAA0B,GAAGZ,CAAA,CAAa,CAAA,EAC5C,CAEF,EAMMW,EAAwB,CAAC,CAC9B,WAAAJ,EACA,SAAAM,CACD,IAEElB,EAAAA,KAACmB,EAAA,CAAK,UAAU,+BACf,SAAA,CAAAnB,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACd,SAAA,CAAAN,MAAC0B,GAAU,WAAAR,EAAwB,EACnCZ,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACd,SAAA,CAAAN,MAAC2B,GAAuB,WAAAT,EAAwB,EAChDlB,EAAAA,IAAC4B,EAAA,CAAuB,GAAIV,EAAW,GAAI,SAAAM,CAAA,CAAoB,CAAA,CAAA,CAChE,CAAA,EACD,EACAlB,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACb,SAAA,CAAAY,EAAW,aACXlB,EAAAA,IAAC6B,EAAA,CAAsB,WAAAX,CAAA,CAAwB,EAEhDlB,MAAC8B,GAAkB,WAAAZ,EAAwB,EAC3ClB,MAAC+B,GAAkB,WAAAb,CAAA,CAAwB,CAAA,CAAA,CAC5C,CAAA,EACD,EAQIQ,EAAY,CAAC,CAAE,WAAAR,WAElBc,EAAA,CACA,SAAAhC,EAAAA,IAACiC,GACA,SAAAjC,EAAAA,IAACkC,EAAA,CAAe,UAAU,UACzB,SAAAlC,EAAAA,IAACmC,EAAA,CACA,GAAG,8BACH,OAAQ,CAAE,GAAIjB,EAAW,EAAA,EACzB,UAAU,UAET,SAAAA,EAAW,IAAA,CAAA,CACb,CACD,EACD,EACD,EC/EFkB,EAvBS1B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as o}from"./vendor-tanstack-BK8oseNA.js";import{s}from"./index-D5RdrxkU.js";import{R as p}from"./route-error-state-BJXl8qkX.js";import{o as n,e as l,a as m,n as e,s as a}from"./vendor-forms-DxqqmhL5.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-date-7GxEwcQM.js";n({name:a().optional(),page:e().int().positive().optional().default(1).catch(1),limit:e().int().positive().max(100).optional().default(10).catch(10),tags:m(a()).optional(),sort:l(["CREATED_DESC","UPDATED_DESC","NAME_ASC","NAME_DESC"]).optional().default("NAME_ASC")}).optional().default({});function h({error:t,reset:i}){const r=s(t,"Failed to load flows");if(r.type!=="server-error"&&r.type!=="client-error")throw t;return o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsx("div",{children:o.jsx("h1",{className:"text-2xl font-semibold",children:"Flows"})}),o.jsx(p,{error:r,onRetry:i})]})}export{h as errorComponent};
|
|
2
|
+
//# sourceMappingURL=index-BU4yZRd3.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-Cs8eFQKw.js","sources":["../../src/routes/flows/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import {\n\tuseQuery,\n\tuseQueryClient,\n\tuseSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport type {\n\tColumnFiltersState,\n\tPaginationState,\n} from \"@tanstack/react-table\";\nimport { zodValidator } from \"@tanstack/zod-adapter\";\nimport { useCallback, useMemo } from \"react\";\nimport { z } from \"zod\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport { buildFilterFlowRunsQuery } from \"@/api/flow-runs\";\nimport {\n\tbuildCountFlowsFilteredQuery,\n\tbuildDeploymentsCountByFlowQuery,\n\tbuildNextRunsByFlowQuery,\n\tbuildPaginateFlowsQuery,\n\ttype FlowsPaginateFilter,\n} from \"@/api/flows\";\nimport FlowsPage from \"@/components/flows/flows-page\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\n\n// Route for /flows/\n\nconst searchParams = z\n\t.object({\n\t\tname: z.string().optional(),\n\t\tpage: z.number().int().positive().optional().default(1).catch(1),\n\t\tlimit: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(100)\n\t\t\t.optional()\n\t\t\t.default(10)\n\t\t\t.catch(10),\n\t\ttags: z.array(z.string()).optional(),\n\t\tsort: z\n\t\t\t.enum([\"CREATED_DESC\", \"UPDATED_DESC\", \"NAME_ASC\", \"NAME_DESC\"])\n\t\t\t.optional()\n\t\t\t.default(\"NAME_ASC\"),\n\t})\n\t.optional()\n\t.default({});\n\ntype SearchParams = z.infer<typeof searchParams>;\n\nconst buildPaginationBody = (search?: SearchParams): FlowsPaginateFilter => {\n\tconst hasNameFilter = Boolean(search?.name);\n\tconst hasTagsFilter = Boolean(search?.tags?.length);\n\n\tif (!hasNameFilter && !hasTagsFilter) {\n\t\treturn {\n\t\t\tpage: search?.page ?? 1,\n\t\t\tlimit: search?.limit ?? 10,\n\t\t\tsort: search?.sort ?? \"NAME_ASC\",\n\t\t};\n\t}\n\n\treturn {\n\t\tpage: search?.page ?? 1,\n\t\tlimit: search?.limit ?? 10,\n\t\tsort: search?.sort ?? \"NAME_ASC\",\n\t\tflows: {\n\t\t\toperator: \"and_\",\n\t\t\t...(hasNameFilter && { name: { like_: search?.name } }),\n\t\t\t...(hasTagsFilter && {\n\t\t\t\ttags: { operator: \"and_\", all_: search?.tags },\n\t\t\t}),\n\t\t},\n\t};\n};\n\nconst NUMBER_OF_ACTIVITY_BARS = 16;\n\nfunction FlowsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load flows\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<div>\n\t\t\t\t<h1 className=\"text-2xl font-semibold\">Flows</h1>\n\t\t\t</div>\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/flows/\")({\n\tvalidateSearch: zodValidator(searchParams),\n\tcomponent: FlowsRoute,\n\terrorComponent: FlowsErrorComponent,\n\tloaderDeps: ({ search }) => buildPaginationBody(search),\n\tloader: ({ deps, context }) => {\n\t\t// Prefetch current page queries without blocking the loader\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildPaginateFlowsQuery(deps, 30_000),\n\t\t);\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildCountFlowsFilteredQuery({\n\t\t\t\toffset: 0,\n\t\t\t\tsort: deps.sort,\n\t\t\t\tflows: deps.flows ?? undefined,\n\t\t\t}),\n\t\t);\n\t\t// Prefetch total count for empty state check\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildCountFlowsFilteredQuery({\n\t\t\t\toffset: 0,\n\t\t\t\tsort: \"NAME_ASC\",\n\t\t\t}),\n\t\t);\n\t},\n\twrapInSuspense: true,\n});\n\nconst usePagination = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\t// Convert URL params (1-based page) to TanStack Table's PaginationState (0-based pageIndex)\n\tconst pagination: PaginationState = useMemo(\n\t\t() => ({\n\t\t\tpageIndex: (search.page ?? 1) - 1,\n\t\t\tpageSize: search.limit ?? 10,\n\t\t}),\n\t\t[search.page, search.limit],\n\t);\n\n\tconst onPaginationChange = useCallback(\n\t\t(newPagination: PaginationState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\t// Convert TanStack Table's 0-based pageIndex back to 1-based page for URL\n\t\t\t\t\tpage: newPagination.pageIndex + 1,\n\t\t\t\t\tlimit: newPagination.pageSize,\n\t\t\t\t}),\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [pagination, onPaginationChange] as const;\n};\n\ntype FlowSort = \"CREATED_DESC\" | \"UPDATED_DESC\" | \"NAME_ASC\" | \"NAME_DESC\";\n\nconst useSort = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\tconst onSortChange = useCallback(\n\t\t(sort: FlowSort) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => ({ ...prev, sort }),\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [search.sort, onSortChange] as const;\n};\n\nconst useFlowsColumnFilters = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\tconst columnFilters: ColumnFiltersState = useMemo(\n\t\t() => [\n\t\t\t{ id: \"name\", value: search.name },\n\t\t\t{ id: \"tags\", value: search.tags },\n\t\t],\n\t\t[search.name, search.tags],\n\t);\n\n\tconst onColumnFiltersChange = useCallback(\n\t\t(newColumnFilters: ColumnFiltersState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => {\n\t\t\t\t\tconst name = newColumnFilters.find((filter) => filter.id === \"name\")\n\t\t\t\t\t\t?.value as string | undefined;\n\t\t\t\t\tconst tags = newColumnFilters.find((filter) => filter.id === \"tags\")\n\t\t\t\t\t\t?.value as string[] | undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tpage: 1,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttags,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [columnFilters, onColumnFiltersChange] as const;\n};\n\nfunction FlowsRoute() {\n\tconst search = Route.useSearch();\n\tconst queryClient = useQueryClient();\n\tconst [pagination, onPaginationChange] = usePagination();\n\tconst [sort, onSortChange] = useSort();\n\tconst [columnFilters, onColumnFiltersChange] = useFlowsColumnFilters();\n\n\tconst paginationBody = buildPaginationBody(search);\n\n\t// Use useSuspenseQuery for count (stable key, won't cause suspense on search change)\n\tconst { data: count } = useSuspenseQuery(\n\t\tbuildCountFlowsFilteredQuery({\n\t\t\toffset: 0,\n\t\t\tsort: search.sort,\n\t\t\tflows: paginationBody.flows ?? undefined,\n\t\t}),\n\t);\n\n\t// Get total count of all flows (without filters) to determine if empty state should be shown\n\tconst { data: totalCount } = useSuspenseQuery(\n\t\tbuildCountFlowsFilteredQuery({\n\t\t\toffset: 0,\n\t\t\tsort: \"NAME_ASC\",\n\t\t}),\n\t);\n\n\t// Use useQuery for paginated flows to leverage placeholderData: keepPreviousData\n\t// This prevents the page from suspending when search/filter changes\n\tconst { data: flowsPage } = useQuery(\n\t\tbuildPaginateFlowsQuery(paginationBody, 30_000),\n\t);\n\n\tconst flows = flowsPage?.results ?? [];\n\n\t// Prefetch a page and its child component data when user hovers over pagination buttons\n\tconst onPrefetchPage = useCallback(\n\t\t(page: number) => {\n\t\t\tconst pageDeps = { ...paginationBody, page };\n\t\t\tvoid queryClient\n\t\t\t\t.prefetchQuery(buildPaginateFlowsQuery(pageDeps, 30_000))\n\t\t\t\t.then(() => {\n\t\t\t\t\t// Get the prefetched page data from cache\n\t\t\t\t\tconst pageData = queryClient.getQueryData<{\n\t\t\t\t\t\tresults?: Array<{ id?: string }>;\n\t\t\t\t\t}>(buildPaginateFlowsQuery(pageDeps, 30_000).queryKey);\n\n\t\t\t\t\tconst flowIds =\n\t\t\t\t\t\tpageData?.results\n\t\t\t\t\t\t\t?.map((flow) => flow.id)\n\t\t\t\t\t\t\t.filter((id): id is string => Boolean(id)) ?? [];\n\n\t\t\t\t\tif (flowIds.length === 0) return;\n\n\t\t\t\t\t// Prefetch child component queries for each flow individually\n\t\t\t\t\t// Using individual flow IDs ensures query keys match what components use\n\t\t\t\t\tfor (const flowId of flowIds) {\n\t\t\t\t\t\t// FlowNextRun query - uses single flow ID array for query key matching\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(buildNextRunsByFlowQuery([flowId]));\n\n\t\t\t\t\t\t// FlowDeploymentCount query - uses single flow ID array for query key matching\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildDeploymentsCountByFlowQuery([flowId]),\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// FlowLastRun query - last completed run\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildFilterFlowRunsQuery({\n\t\t\t\t\t\t\t\tflows: { operator: \"and_\", id: { any_: [flowId] } },\n\t\t\t\t\t\t\t\tflow_runs: {\n\t\t\t\t\t\t\t\t\toperator: \"and_\",\n\t\t\t\t\t\t\t\t\tstart_time: { is_null_: false },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\tlimit: 1,\n\t\t\t\t\t\t\t\tsort: \"START_TIME_DESC\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// FlowActivity query - recent runs for activity chart\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildFilterFlowRunsQuery({\n\t\t\t\t\t\t\t\tflows: { operator: \"and_\", id: { any_: [flowId] } },\n\t\t\t\t\t\t\t\tflow_runs: {\n\t\t\t\t\t\t\t\t\toperator: \"and_\",\n\t\t\t\t\t\t\t\t\tstart_time: { is_null_: false },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\tlimit: NUMBER_OF_ACTIVITY_BARS,\n\t\t\t\t\t\t\t\tsort: \"START_TIME_DESC\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t},\n\t\t[queryClient, paginationBody],\n\t);\n\n\treturn (\n\t\t<FlowsPage\n\t\t\tflows={flows}\n\t\t\tcount={count ?? 0}\n\t\t\ttotalCount={totalCount ?? 0}\n\t\t\tpageCount={flowsPage?.pages ?? 0}\n\t\t\tsort={sort as \"NAME_ASC\" | \"NAME_DESC\" | \"CREATED_DESC\"}\n\t\t\tpagination={pagination}\n\t\t\tonPaginationChange={onPaginationChange}\n\t\t\tonSortChange={onSortChange}\n\t\t\tcolumnFilters={columnFilters}\n\t\t\tonColumnFiltersChange={onColumnFiltersChange}\n\t\t\tonPrefetchPage={onPrefetchPage}\n\t\t/>\n\t);\n}\n"],"names":["z","name","string","optional","page","number","int","positive","default","catch","limit","max","tags","sort","FlowsErrorComponent","error","reset","serverError","categorizeError","type","jsxs","jsx","RouteErrorState"],"mappings":"uWA4BqBA,EACZ,CACPC,KAAMD,EAAEE,EAASC,SAAAA,EACjBC,KAAMJ,EAAEK,EAASC,MAAMC,SAAAA,EAAWJ,SAAAA,EAAWK,QAAQ,CAAC,EAAEC,MAAM,CAAC,EAC/DC,MAAOV,EACLK,EACAC,IAAAA,EACAC,SAAAA,EACAI,IAAI,GAAG,EACPR,SAAAA,EACAK,QAAQ,EAAE,EACVC,MAAM,EAAE,EACVG,KAAMZ,EAAQA,EAAEE,CAAQ,EAAEC,SAAAA,EAC1BU,KAAMb,EACC,CAAC,eAAgB,eAAgB,WAAY,WAAW,CAAC,EAC9DG,WACAK,QAAQ,UAAU,CACrB,CAAC,EACAL,WACAK,QAAQ,CAAA,CAAE,EAgCZ,SAASM,EAAoB,CAAEC,MAAAA,EAAOC,MAAAA,CAA2B,EAAG,CACnE,MAAMC,EAAcC,EAAgBH,EAAO,sBAAsB,EAIjE,GACCE,EAAYE,OAAS,gBACrBF,EAAYE,OAAS,eAErB,MAAMJ,EAGP,OACCK,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAC,EAAAA,IAAC,OACA,SAAAA,EAAAA,IAAC,KAAA,CAAG,UAAU,yBAAyB,iBAAK,CAAA,CAC7C,EACAA,EAAAA,IAACC,EAAA,CAAgB,MAAOL,EAAa,QAASD,CAAAA,CAAM,CAAA,EACrD,CAEF"}
|
|
1
|
+
{"version":3,"file":"index-BU4yZRd3.js","sources":["../../src/routes/flows/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import {\n\tuseQuery,\n\tuseQueryClient,\n\tuseSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport type {\n\tColumnFiltersState,\n\tPaginationState,\n} from \"@tanstack/react-table\";\nimport { zodValidator } from \"@tanstack/zod-adapter\";\nimport { useCallback, useMemo } from \"react\";\nimport { z } from \"zod\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport { buildFilterFlowRunsQuery } from \"@/api/flow-runs\";\nimport {\n\tbuildCountFlowsFilteredQuery,\n\tbuildDeploymentsCountByFlowQuery,\n\tbuildNextRunsByFlowQuery,\n\tbuildPaginateFlowsQuery,\n\ttype FlowsPaginateFilter,\n} from \"@/api/flows\";\nimport FlowsPage from \"@/components/flows/flows-page\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\n\n// Route for /flows/\n\nconst searchParams = z\n\t.object({\n\t\tname: z.string().optional(),\n\t\tpage: z.number().int().positive().optional().default(1).catch(1),\n\t\tlimit: z\n\t\t\t.number()\n\t\t\t.int()\n\t\t\t.positive()\n\t\t\t.max(100)\n\t\t\t.optional()\n\t\t\t.default(10)\n\t\t\t.catch(10),\n\t\ttags: z.array(z.string()).optional(),\n\t\tsort: z\n\t\t\t.enum([\"CREATED_DESC\", \"UPDATED_DESC\", \"NAME_ASC\", \"NAME_DESC\"])\n\t\t\t.optional()\n\t\t\t.default(\"NAME_ASC\"),\n\t})\n\t.optional()\n\t.default({});\n\ntype SearchParams = z.infer<typeof searchParams>;\n\nconst buildPaginationBody = (search?: SearchParams): FlowsPaginateFilter => {\n\tconst hasNameFilter = Boolean(search?.name);\n\tconst hasTagsFilter = Boolean(search?.tags?.length);\n\n\tif (!hasNameFilter && !hasTagsFilter) {\n\t\treturn {\n\t\t\tpage: search?.page ?? 1,\n\t\t\tlimit: search?.limit ?? 10,\n\t\t\tsort: search?.sort ?? \"NAME_ASC\",\n\t\t};\n\t}\n\n\treturn {\n\t\tpage: search?.page ?? 1,\n\t\tlimit: search?.limit ?? 10,\n\t\tsort: search?.sort ?? \"NAME_ASC\",\n\t\tflows: {\n\t\t\toperator: \"and_\",\n\t\t\t...(hasNameFilter && { name: { like_: search?.name } }),\n\t\t\t...(hasTagsFilter && {\n\t\t\t\ttags: { operator: \"and_\", all_: search?.tags },\n\t\t\t}),\n\t\t},\n\t};\n};\n\nconst NUMBER_OF_ACTIVITY_BARS = 16;\n\nfunction FlowsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load flows\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<div>\n\t\t\t\t<h1 className=\"text-2xl font-semibold\">Flows</h1>\n\t\t\t</div>\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/flows/\")({\n\tvalidateSearch: zodValidator(searchParams),\n\tcomponent: FlowsRoute,\n\terrorComponent: FlowsErrorComponent,\n\tloaderDeps: ({ search }) => buildPaginationBody(search),\n\tloader: ({ deps, context }) => {\n\t\t// Prefetch current page queries without blocking the loader\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildPaginateFlowsQuery(deps, 30_000),\n\t\t);\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildCountFlowsFilteredQuery({\n\t\t\t\toffset: 0,\n\t\t\t\tsort: deps.sort,\n\t\t\t\tflows: deps.flows ?? undefined,\n\t\t\t}),\n\t\t);\n\t\t// Prefetch total count for empty state check\n\t\tvoid context.queryClient.prefetchQuery(\n\t\t\tbuildCountFlowsFilteredQuery({\n\t\t\t\toffset: 0,\n\t\t\t\tsort: \"NAME_ASC\",\n\t\t\t}),\n\t\t);\n\t},\n\twrapInSuspense: true,\n});\n\nconst usePagination = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\t// Convert URL params (1-based page) to TanStack Table's PaginationState (0-based pageIndex)\n\tconst pagination: PaginationState = useMemo(\n\t\t() => ({\n\t\t\tpageIndex: (search.page ?? 1) - 1,\n\t\t\tpageSize: search.limit ?? 10,\n\t\t}),\n\t\t[search.page, search.limit],\n\t);\n\n\tconst onPaginationChange = useCallback(\n\t\t(newPagination: PaginationState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\t// Convert TanStack Table's 0-based pageIndex back to 1-based page for URL\n\t\t\t\t\tpage: newPagination.pageIndex + 1,\n\t\t\t\t\tlimit: newPagination.pageSize,\n\t\t\t\t}),\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [pagination, onPaginationChange] as const;\n};\n\ntype FlowSort = \"CREATED_DESC\" | \"UPDATED_DESC\" | \"NAME_ASC\" | \"NAME_DESC\";\n\nconst useSort = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\tconst onSortChange = useCallback(\n\t\t(sort: FlowSort) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => ({ ...prev, sort }),\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [search.sort, onSortChange] as const;\n};\n\nconst useFlowsColumnFilters = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\tconst columnFilters: ColumnFiltersState = useMemo(\n\t\t() => [\n\t\t\t{ id: \"name\", value: search.name },\n\t\t\t{ id: \"tags\", value: search.tags },\n\t\t],\n\t\t[search.name, search.tags],\n\t);\n\n\tconst onColumnFiltersChange = useCallback(\n\t\t(newColumnFilters: ColumnFiltersState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => {\n\t\t\t\t\tconst name = newColumnFilters.find((filter) => filter.id === \"name\")\n\t\t\t\t\t\t?.value as string | undefined;\n\t\t\t\t\tconst tags = newColumnFilters.find((filter) => filter.id === \"tags\")\n\t\t\t\t\t\t?.value as string[] | undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tpage: 1,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttags,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [columnFilters, onColumnFiltersChange] as const;\n};\n\nfunction FlowsRoute() {\n\tconst search = Route.useSearch();\n\tconst queryClient = useQueryClient();\n\tconst [pagination, onPaginationChange] = usePagination();\n\tconst [sort, onSortChange] = useSort();\n\tconst [columnFilters, onColumnFiltersChange] = useFlowsColumnFilters();\n\n\tconst paginationBody = buildPaginationBody(search);\n\n\t// Use useSuspenseQuery for count (stable key, won't cause suspense on search change)\n\tconst { data: count } = useSuspenseQuery(\n\t\tbuildCountFlowsFilteredQuery({\n\t\t\toffset: 0,\n\t\t\tsort: search.sort,\n\t\t\tflows: paginationBody.flows ?? undefined,\n\t\t}),\n\t);\n\n\t// Get total count of all flows (without filters) to determine if empty state should be shown\n\tconst { data: totalCount } = useSuspenseQuery(\n\t\tbuildCountFlowsFilteredQuery({\n\t\t\toffset: 0,\n\t\t\tsort: \"NAME_ASC\",\n\t\t}),\n\t);\n\n\t// Use useQuery for paginated flows to leverage placeholderData: keepPreviousData\n\t// This prevents the page from suspending when search/filter changes\n\tconst { data: flowsPage } = useQuery(\n\t\tbuildPaginateFlowsQuery(paginationBody, 30_000),\n\t);\n\n\tconst flows = flowsPage?.results ?? [];\n\n\t// Prefetch a page and its child component data when user hovers over pagination buttons\n\tconst onPrefetchPage = useCallback(\n\t\t(page: number) => {\n\t\t\tconst pageDeps = { ...paginationBody, page };\n\t\t\tvoid queryClient\n\t\t\t\t.prefetchQuery(buildPaginateFlowsQuery(pageDeps, 30_000))\n\t\t\t\t.then(() => {\n\t\t\t\t\t// Get the prefetched page data from cache\n\t\t\t\t\tconst pageData = queryClient.getQueryData<{\n\t\t\t\t\t\tresults?: Array<{ id?: string }>;\n\t\t\t\t\t}>(buildPaginateFlowsQuery(pageDeps, 30_000).queryKey);\n\n\t\t\t\t\tconst flowIds =\n\t\t\t\t\t\tpageData?.results\n\t\t\t\t\t\t\t?.map((flow) => flow.id)\n\t\t\t\t\t\t\t.filter((id): id is string => Boolean(id)) ?? [];\n\n\t\t\t\t\tif (flowIds.length === 0) return;\n\n\t\t\t\t\t// Prefetch child component queries for each flow individually\n\t\t\t\t\t// Using individual flow IDs ensures query keys match what components use\n\t\t\t\t\tfor (const flowId of flowIds) {\n\t\t\t\t\t\t// FlowNextRun query - uses single flow ID array for query key matching\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(buildNextRunsByFlowQuery([flowId]));\n\n\t\t\t\t\t\t// FlowDeploymentCount query - uses single flow ID array for query key matching\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildDeploymentsCountByFlowQuery([flowId]),\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// FlowLastRun query - last completed run\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildFilterFlowRunsQuery({\n\t\t\t\t\t\t\t\tflows: { operator: \"and_\", id: { any_: [flowId] } },\n\t\t\t\t\t\t\t\tflow_runs: {\n\t\t\t\t\t\t\t\t\toperator: \"and_\",\n\t\t\t\t\t\t\t\t\tstart_time: { is_null_: false },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\tlimit: 1,\n\t\t\t\t\t\t\t\tsort: \"START_TIME_DESC\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// FlowActivity query - recent runs for activity chart\n\t\t\t\t\t\tvoid queryClient.prefetchQuery(\n\t\t\t\t\t\t\tbuildFilterFlowRunsQuery({\n\t\t\t\t\t\t\t\tflows: { operator: \"and_\", id: { any_: [flowId] } },\n\t\t\t\t\t\t\t\tflow_runs: {\n\t\t\t\t\t\t\t\t\toperator: \"and_\",\n\t\t\t\t\t\t\t\t\tstart_time: { is_null_: false },\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\t\t\tlimit: NUMBER_OF_ACTIVITY_BARS,\n\t\t\t\t\t\t\t\tsort: \"START_TIME_DESC\",\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t},\n\t\t[queryClient, paginationBody],\n\t);\n\n\treturn (\n\t\t<FlowsPage\n\t\t\tflows={flows}\n\t\t\tcount={count ?? 0}\n\t\t\ttotalCount={totalCount ?? 0}\n\t\t\tpageCount={flowsPage?.pages ?? 0}\n\t\t\tsort={sort as \"NAME_ASC\" | \"NAME_DESC\" | \"CREATED_DESC\"}\n\t\t\tpagination={pagination}\n\t\t\tonPaginationChange={onPaginationChange}\n\t\t\tonSortChange={onSortChange}\n\t\t\tcolumnFilters={columnFilters}\n\t\t\tonColumnFiltersChange={onColumnFiltersChange}\n\t\t\tonPrefetchPage={onPrefetchPage}\n\t\t/>\n\t);\n}\n"],"names":["z","name","string","optional","page","number","int","positive","default","catch","limit","max","tags","sort","FlowsErrorComponent","error","reset","serverError","categorizeError","type","jsxs","jsx","RouteErrorState"],"mappings":"kWA4BqBA,EACZ,CACPC,KAAMD,EAAEE,EAASC,SAAAA,EACjBC,KAAMJ,EAAEK,EAASC,MAAMC,SAAAA,EAAWJ,SAAAA,EAAWK,QAAQ,CAAC,EAAEC,MAAM,CAAC,EAC/DC,MAAOV,EACLK,EACAC,IAAAA,EACAC,SAAAA,EACAI,IAAI,GAAG,EACPR,SAAAA,EACAK,QAAQ,EAAE,EACVC,MAAM,EAAE,EACVG,KAAMZ,EAAQA,EAAEE,CAAQ,EAAEC,SAAAA,EAC1BU,KAAMb,EACC,CAAC,eAAgB,eAAgB,WAAY,WAAW,CAAC,EAC9DG,WACAK,QAAQ,UAAU,CACrB,CAAC,EACAL,WACAK,QAAQ,CAAA,CAAE,EAgCZ,SAASM,EAAoB,CAAEC,MAAAA,EAAOC,MAAAA,CAA2B,EAAG,CACnE,MAAMC,EAAcC,EAAgBH,EAAO,sBAAsB,EAIjE,GACCE,EAAYE,OAAS,gBACrBF,EAAYE,OAAS,eAErB,MAAMJ,EAGP,OACCK,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAC,EAAAA,IAAC,OACA,SAAAA,EAAAA,IAAC,KAAA,CAAG,UAAU,yBAAyB,iBAAK,CAAA,CAC7C,EACAA,EAAAA,IAACC,EAAA,CAAgB,MAAOL,EAAa,QAASD,CAAAA,CAAM,CAAA,EACrD,CAEF"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{bH as y,aW as N,H as C,cr as S,_ as k,$ as D,a0 as R,a1 as w,i as v,aq as I,p as E,a3 as L,q as b}from"./index-D5RdrxkU.js";import{r,J as O,j as e}from"./vendor-tanstack-BK8oseNA.js";import{I as M,Z as j}from"./vendor-date-7GxEwcQM.js";import{S as B}from"./index-BO3SOwdV.js";const T=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M21 9H3",key:"1338ky"}],["path",{d:"M21 15H3",key:"9uk58r"}]],$=y("rows-3",T),q=({logs:s,taskRun:t,onBottomReached:n,virtualize:d=!0,className:h})=>{const c=r.useRef(null),i=r.useRef(s);i.current=s;const m=r.useCallback(a=>i.current[a]?.id??a,[]),o=O({count:s.length,getScrollElement:()=>c.current,estimateSize:()=>75,overscan:5,getItemKey:m}),g=r.useCallback(a=>{a&&o.measureElement(a)},[o]),x=d?o.getVirtualItems():Array.from({length:s.length},(a,l)=>({index:l,size:75,start:l*75})),u=x.at(-1)?.index;r.useEffect(()=>{u!==void 0&&u>=s.length-1&&n()},[s.length,u,n]);const p=a=>{if(a===0)return!0;const l=s[a-1],f=s[a];return!M(l.timestamp,f.timestamp)};return s.length===0?e.jsx("div",{className:"flex flex-col gap-2 bg-muted p-2 rounded-md font-mono",children:e.jsx("span",{className:"text-muted-foreground",children:"No logs found"})}):e.jsx("div",{ref:c,className:N("bg-muted rounded-md font-mono p-4 overflow-y-auto",h),role:"log",children:e.jsx("ol",{className:"relative",style:{height:`${o.getTotalSize()}px`},children:x.map(a=>{const l=s[a.index],f=p(a.index);return e.jsxs("li",{"data-index":a.index,ref:g,style:{position:"absolute",top:0,left:0,width:"100%",transform:`translateY(${a.start}px)`},children:[f&&e.jsx(H,{date:new Date(l.timestamp)}),e.jsx(_,{log:l,taskRunName:t?.name})]},l.id)})})})},_=({log:s,taskRunName:t})=>e.jsxs("div",{className:"grid grid-cols-[84px_minmax(0,1fr)_150px] gap-2 text-sm",children:[e.jsx("div",{children:e.jsx(A,{level:s.level})}),e.jsx("div",{className:"select-auto whitespace-pre-wrap break-words",children:s.message}),e.jsxs("div",{className:"text-xs grid grid-cols-1 gap-1 justify-items-end text-muted-foreground truncate",children:[e.jsx("span",{children:j(s.timestamp,"pp")}),t&&e.jsx("span",{children:t}),e.jsx("span",{className:"font-bold break-all whitespace-normal",children:s.name})]})]}),z=S("gap-1",{variants:{level:{CRITICAL:"bg-red-600 text-red-50 hover:bg-red-600",ERROR:"bg-red-600 text-red-50 hover:bg-red-600",WARNING:"bg-orange-600 text-orange-50 hover:bg-orange-600",INFO:"bg-sky-600 text-blue-50 hover:bg-sky-600",DEBUG:"bg-gray-700 text-gray-50 hover:bg-gray-700",CUSTOM:"bg-gray-700 text-gray-50 hover:bg-gray-700"}}}),A=({level:s})=>{const t=F(s);return e.jsx(C,{className:z({level:t}),children:t})};function F(s){const[t]=s.toString();switch(t){case"5":return"CRITICAL";case"4":return"ERROR";case"3":return"WARNING";case"2":return"INFO";case"1":return"DEBUG";default:return"CUSTOM"}}const H=({date:s})=>e.jsxs("div",{className:"flex flex-row justify-center items-center gap-2",children:[e.jsx("div",{className:"h-[1px] w-full bg-muted-foreground/30"}),e.jsx("span",{className:"text-xs text-muted-foreground whitespace-nowrap",children:j(s,"MMM d, yyyy")}),e.jsx("div",{className:"h-[1px] w-full bg-muted-foreground/30"})]}),J=({open:s,onOpenChange:t,currentState:n,label:d,onConfirm:h,isLoading:c=!1})=>{const[i,m]=r.useState(void 0),[o,g]=r.useState("");r.useEffect(()=>{s||(m(void 0),g(""))},[s]);const x=()=>{i&&h({type:i,message:o||void 0})},u=!i||c;return e.jsx(k,{open:s,onOpenChange:t,children:e.jsxs(D,{"aria-describedby":void 0,children:[e.jsx(R,{children:e.jsxs(w,{children:["Change ",d," State"]})}),e.jsxs("div",{className:"space-y-4",children:[n&&e.jsxs("div",{children:[e.jsx(v,{className:"mb-2 block",children:"Current State"}),e.jsx(I,{type:n.type,name:n.name})]}),e.jsxs("div",{children:[e.jsx(v,{htmlFor:"desired-state",className:"mb-2 block",children:"Desired State"}),e.jsx(B,{value:i,onValueChange:m,terminalOnly:!0})]}),e.jsxs("div",{children:[e.jsx(v,{htmlFor:"message",className:"mb-2 block",children:"Reason (Optional)"}),e.jsx(E,{id:"message",value:o,onChange:p=>g(p.target.value),placeholder:"State changed manually via UI"})]})]}),e.jsxs(L,{children:[e.jsx(b,{type:"button",variant:"outline",onClick:()=>t(!1),disabled:c,children:"Close"}),e.jsx(b,{type:"button",onClick:x,disabled:u,loading:c,children:"Change"})]})]})})},K=()=>{const[s,t]=r.useState(!1),n=r.useCallback(()=>t(!0),[]),d=r.useCallback(()=>t(!1),[]);return{open:s,onOpenChange:t,openDialog:n,closeDialog:d}};export{J as C,$ as R,q as a,K as u};
|
|
2
|
+
//# sourceMappingURL=index-BhALpenO.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-qPlIYf3i.js","sources":["../../node_modules/lucide-react/dist/esm/icons/rows-3.js","../../src/components/ui/run-logs/index.tsx","../../src/components/ui/change-state-dialog/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.562.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 __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M21 9H3\", key: \"1338ky\" }],\n [\"path\", { d: \"M21 15H3\", key: \"9uk58r\" }]\n];\nconst Rows3 = createLucideIcon(\"rows-3\", __iconNode);\n\nexport { __iconNode, Rows3 as default };\n//# sourceMappingURL=rows-3.js.map\n","import { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { cva } from \"class-variance-authority\";\nimport { isSameDay } from \"date-fns\";\nimport { format } from \"date-fns-tz\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { components } from \"@/api/prefect\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/utils\";\n\ntype RunLogsProps = {\n\tlogs: components[\"schemas\"][\"Log\"][];\n\ttaskRun?: components[\"schemas\"][\"TaskRun\"];\n\tonBottomReached: () => void;\n\tvirtualize?: boolean;\n\tclassName?: string;\n};\n\n/**\n * Displays logs from a run in a virtualized list.\n *\n * @param logs - Array of log entries to display\n * @param taskRun - Optional task run information to display with logs\n * @param onBottomReached - Callback function triggered when the user scrolls to the bottom of the logs\n *\n */\nexport const RunLogs = ({\n\tlogs,\n\ttaskRun,\n\tonBottomReached,\n\tvirtualize = true,\n\tclassName,\n}: RunLogsProps) => {\n\tconst parentRef = useRef<HTMLDivElement>(null);\n\n\t// Use a ref to store logs for stable getItemKey callback\n\tconst logsRef = useRef(logs);\n\tlogsRef.current = logs;\n\n\tconst getItemKey = useCallback(\n\t\t(index: number) => logsRef.current[index]?.id ?? index,\n\t\t[],\n\t);\n\n\tconst virtualizer = useVirtualizer({\n\t\tcount: logs.length,\n\t\tgetScrollElement: () => parentRef.current,\n\t\testimateSize: () => 75,\n\t\toverscan: 5,\n\t\tgetItemKey,\n\t});\n\n\t// Wrap measureElement in a stable callback to prevent infinite re-renders\n\tconst measureElement = useCallback(\n\t\t(el: HTMLElement | null) => {\n\t\t\tif (el) {\n\t\t\t\tvirtualizer.measureElement(el);\n\t\t\t}\n\t\t},\n\t\t[virtualizer],\n\t);\n\n\tconst virtualItems = virtualize\n\t\t? virtualizer.getVirtualItems()\n\t\t: Array.from({ length: logs.length }, (_, i) => ({\n\t\t\t\tindex: i,\n\t\t\t\tsize: 75,\n\t\t\t\tstart: i * 75,\n\t\t\t}));\n\n\t// Get the last visible item index for stable effect dependency\n\tconst lastVisibleIndex = virtualItems.at(-1)?.index;\n\n\t/**\n\t * This effect detects when the user has scrolled to the bottom of the logs.\n\t * It works by checking if the last visible virtual item is also the last item in the logs array.\n\t * When this condition is met, it calls the bottomReached callback to potentially load more logs.\n\t */\n\tuseEffect(() => {\n\t\tif (lastVisibleIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (lastVisibleIndex >= logs.length - 1) {\n\t\t\tonBottomReached();\n\t\t}\n\t}, [logs.length, lastVisibleIndex, onBottomReached]);\n\n\tconst showDivider = (index: number): boolean => {\n\t\tif (index === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst previous = logs[index - 1];\n\t\tconst current = logs[index];\n\n\t\treturn !isSameDay(previous.timestamp, current.timestamp);\n\t};\n\n\tif (logs.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"flex flex-col gap-2 bg-muted p-2 rounded-md font-mono\">\n\t\t\t\t<span className=\"text-muted-foreground\">No logs found</span>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={parentRef}\n\t\t\tclassName={cn(\n\t\t\t\t\"bg-muted rounded-md font-mono p-4 overflow-y-auto\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\trole=\"log\"\n\t\t>\n\t\t\t<ol\n\t\t\t\tclassName=\"relative\"\n\t\t\t\tstyle={{\n\t\t\t\t\theight: `${virtualizer.getTotalSize()}px`,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{virtualItems.map((virtualRow) => {\n\t\t\t\t\tconst log = logs[virtualRow.index];\n\t\t\t\t\tconst shouldShowDivider = showDivider(virtualRow.index);\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tkey={log.id}\n\t\t\t\t\t\t\tdata-index={virtualRow.index}\n\t\t\t\t\t\t\tref={measureElement}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\ttransform: `translateY(${virtualRow.start}px)`,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{shouldShowDivider && (\n\t\t\t\t\t\t\t\t<LogDivider date={new Date(log.timestamp)} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<RunLogRow log={log} taskRunName={taskRun?.name} />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ol>\n\t\t</div>\n\t);\n};\n\ntype RunLogRowProps = {\n\tlog: components[\"schemas\"][\"Log\"];\n\ttaskRunName?: string;\n};\n\nconst RunLogRow = ({ log, taskRunName }: RunLogRowProps) => {\n\treturn (\n\t\t<div className=\"grid grid-cols-[84px_minmax(0,1fr)_150px] gap-2 text-sm\">\n\t\t\t<div>\n\t\t\t\t<LogLevelBadge level={log.level} />\n\t\t\t</div>\n\t\t\t<div className=\"select-auto whitespace-pre-wrap break-words\">\n\t\t\t\t{log.message}\n\t\t\t</div>\n\t\t\t<div className=\"text-xs grid grid-cols-1 gap-1 justify-items-end text-muted-foreground truncate\">\n\t\t\t\t<span>{format(log.timestamp, \"pp\")}</span>\n\t\t\t\t{taskRunName && <span>{taskRunName}</span>}\n\t\t\t\t<span className=\"font-bold break-all whitespace-normal\">\n\t\t\t\t\t{log.name}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst logLevelBadgeVariants = cva(\"gap-1\", {\n\tvariants: {\n\t\tlevel: {\n\t\t\tCRITICAL: \"bg-red-600 text-red-50 hover:bg-red-600\",\n\t\t\tERROR: \"bg-red-600 text-red-50 hover:bg-red-600\",\n\t\t\tWARNING: \"bg-orange-600 text-orange-50 hover:bg-orange-600\",\n\t\t\tINFO: \"bg-sky-600 text-blue-50 hover:bg-sky-600\",\n\t\t\tDEBUG: \"bg-gray-700 text-gray-50 hover:bg-gray-700\",\n\t\t\tCUSTOM: \"bg-gray-700 text-gray-50 hover:bg-gray-700\",\n\t\t} satisfies Record<LogLevel, string>,\n\t},\n});\n\nexport const LogLevelBadge = ({ level }: { level: number }) => {\n\tconst levelLabel = logLevelLabel(level);\n\treturn (\n\t\t<Badge className={logLevelBadgeVariants({ level: levelLabel })}>\n\t\t\t{levelLabel}\n\t\t</Badge>\n\t);\n};\n\ntype LogLevel = \"CRITICAL\" | \"ERROR\" | \"WARNING\" | \"INFO\" | \"DEBUG\" | \"CUSTOM\";\n\nfunction logLevelLabel(level: number): LogLevel {\n\tconst [first] = level.toString();\n\n\tswitch (first) {\n\t\tcase \"5\":\n\t\t\treturn \"CRITICAL\";\n\t\tcase \"4\":\n\t\t\treturn \"ERROR\";\n\t\tcase \"3\":\n\t\t\treturn \"WARNING\";\n\t\tcase \"2\":\n\t\t\treturn \"INFO\";\n\t\tcase \"1\":\n\t\t\treturn \"DEBUG\";\n\t\tdefault:\n\t\t\treturn \"CUSTOM\";\n\t}\n}\n\nconst LogDivider = ({ date }: { date: Date }) => {\n\treturn (\n\t\t<div className=\"flex flex-row justify-center items-center gap-2\">\n\t\t\t<div className=\"h-[1px] w-full bg-muted-foreground/30\" />\n\t\t\t<span className=\"text-xs text-muted-foreground whitespace-nowrap\">\n\t\t\t\t{format(date, \"MMM d, yyyy\")}\n\t\t\t</span>\n\t\t\t<div className=\"h-[1px] w-full bg-muted-foreground/30\" />\n\t\t</div>\n\t);\n};\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { components } from \"@/api/prefect\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { StateBadge } from \"@/components/ui/state-badge\";\nimport { StateSelect } from \"@/components/ui/state-select\";\n\ntype StateType = components[\"schemas\"][\"StateType\"];\n\nexport type ChangeStateDialogProps = {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tcurrentState: { type: string; name: string } | null;\n\tlabel: string;\n\tonConfirm: (newState: { type: string; message?: string }) => void;\n\tisLoading?: boolean;\n};\n\nexport const ChangeStateDialog = ({\n\topen,\n\tonOpenChange,\n\tcurrentState,\n\tlabel,\n\tonConfirm,\n\tisLoading = false,\n}: ChangeStateDialogProps) => {\n\tconst [selectedState, setSelectedState] = useState<StateType | undefined>(\n\t\tundefined,\n\t);\n\tconst [message, setMessage] = useState(\"\");\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\tsetSelectedState(undefined);\n\t\t\tsetMessage(\"\");\n\t\t}\n\t}, [open]);\n\n\tconst handleConfirm = () => {\n\t\tif (selectedState) {\n\t\t\tonConfirm({\n\t\t\t\ttype: selectedState,\n\t\t\t\tmessage: message || undefined,\n\t\t\t});\n\t\t}\n\t};\n\n\tconst isConfirmDisabled = !selectedState || isLoading;\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Change {label} State</DialogTitle>\n\t\t\t\t</DialogHeader>\n\n\t\t\t\t<div className=\"space-y-4\">\n\t\t\t\t\t{currentState && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<Label className=\"mb-2 block\">Current State</Label>\n\t\t\t\t\t\t\t<StateBadge\n\t\t\t\t\t\t\t\ttype={currentState.type as StateType}\n\t\t\t\t\t\t\t\tname={currentState.name}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<Label htmlFor=\"desired-state\" className=\"mb-2 block\">\n\t\t\t\t\t\t\tDesired State\n\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t<StateSelect\n\t\t\t\t\t\t\tvalue={selectedState}\n\t\t\t\t\t\t\tonValueChange={setSelectedState}\n\t\t\t\t\t\t\tterminalOnly\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<Label htmlFor=\"message\" className=\"mb-2 block\">\n\t\t\t\t\t\t\tReason (Optional)\n\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tid=\"message\"\n\t\t\t\t\t\t\tvalue={message}\n\t\t\t\t\t\t\tonChange={(e) => setMessage(e.target.value)}\n\t\t\t\t\t\t\tplaceholder=\"State changed manually via UI\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tonClick={() => onOpenChange(false)}\n\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t>\n\t\t\t\t\t\tClose\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t\t\tdisabled={isConfirmDisabled}\n\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t>\n\t\t\t\t\t\tChange\n\t\t\t\t\t</Button>\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n\nexport type UseChangeStateDialogResult = {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\topenDialog: () => void;\n\tcloseDialog: () => void;\n};\n\nexport const useChangeStateDialog = (): UseChangeStateDialogResult => {\n\tconst [open, setOpen] = useState(false);\n\n\tconst openDialog = useCallback(() => setOpen(true), []);\n\tconst closeDialog = useCallback(() => setOpen(false), []);\n\n\treturn {\n\t\topen,\n\t\tonOpenChange: setOpen,\n\t\topenDialog,\n\t\tcloseDialog,\n\t};\n};\n"],"names":["__iconNode","Rows3","createLucideIcon","RunLogs","logs","taskRun","onBottomReached","virtualize","className","parentRef","useRef","logsRef","getItemKey","useCallback","index","virtualizer","useVirtualizer","measureElement","el","virtualItems","_","i","lastVisibleIndex","useEffect","showDivider","previous","current","isSameDay","jsx","cn","virtualRow","log","shouldShowDivider","jsxs","LogDivider","RunLogRow","taskRunName","LogLevelBadge","format","logLevelBadgeVariants","cva","level","levelLabel","logLevelLabel","Badge","first","date","ChangeStateDialog","open","onOpenChange","currentState","label","onConfirm","isLoading","selectedState","setSelectedState","useState","message","setMessage","handleConfirm","isConfirmDisabled","Dialog","DialogContent","DialogHeader","DialogTitle","Label","StateBadge","StateSelect","Input","e","DialogFooter","Button","useChangeStateDialog","setOpen","openDialog","closeDialog"],"mappings":"0RASA,MAAMA,EAAa,CACjB,CAAC,OAAQ,CAAE,MAAO,KAAM,OAAQ,KAAM,EAAG,IAAK,EAAG,IAAK,GAAI,IAAK,IAAK,QAAQ,CAAE,EAC9E,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAQ,CAAE,EACxC,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAQ,CAAE,CAC3C,EACMC,EAAQC,EAAiB,SAAUF,CAAU,ECWtCG,EAAU,CAAC,CACvB,KAAAC,EACA,QAAAC,EACA,gBAAAC,EACA,WAAAC,EAAa,GACb,UAAAC,CACD,IAAoB,CACnB,MAAMC,EAAYC,EAAAA,OAAuB,IAAI,EAGvCC,EAAUD,EAAAA,OAAON,CAAI,EAC3BO,EAAQ,QAAUP,EAElB,MAAMQ,EAAaC,EAAAA,YACjBC,GAAkBH,EAAQ,QAAQG,CAAK,GAAG,IAAMA,EACjD,CAAA,CAAC,EAGIC,EAAcC,EAAe,CAClC,MAAOZ,EAAK,OACZ,iBAAkB,IAAMK,EAAU,QAClC,aAAc,IAAM,GACpB,SAAU,EACV,WAAAG,CAAA,CACA,EAGKK,EAAiBJ,EAAAA,YACrBK,GAA2B,CACvBA,GACHH,EAAY,eAAeG,CAAE,CAE/B,EACA,CAACH,CAAW,CAAA,EAGPI,EAAeZ,EAClBQ,EAAY,gBAAA,EACZ,MAAM,KAAK,CAAE,OAAQX,EAAK,MAAA,EAAU,CAACgB,EAAGC,KAAO,CAC/C,MAAOA,EACP,KAAM,GACN,MAAOA,EAAI,EAAA,EACV,EAGEC,EAAmBH,EAAa,GAAG,EAAE,GAAG,MAO9CI,EAAAA,UAAU,IAAM,CACXD,IAAqB,QAIrBA,GAAoBlB,EAAK,OAAS,GACrCE,EAAA,CAEF,EAAG,CAACF,EAAK,OAAQkB,EAAkBhB,CAAe,CAAC,EAEnD,MAAMkB,EAAeV,GAA2B,CAC/C,GAAIA,IAAU,EACb,MAAO,GAGR,MAAMW,EAAWrB,EAAKU,EAAQ,CAAC,EACzBY,EAAUtB,EAAKU,CAAK,EAE1B,MAAO,CAACa,EAAUF,EAAS,UAAWC,EAAQ,SAAS,CACxD,EAEA,OAAItB,EAAK,SAAW,EAElBwB,EAAAA,IAAC,OAAI,UAAU,wDACd,eAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,eAAA,CAAa,CAAA,CACtD,EAKDA,EAAAA,IAAC,MAAA,CACA,IAAKnB,EACL,UAAWoB,EACV,oDACArB,CAAA,EAED,KAAK,MAEL,SAAAoB,EAAAA,IAAC,KAAA,CACA,UAAU,WACV,MAAO,CACN,OAAQ,GAAGb,EAAY,aAAA,CAAc,IAAA,EAGrC,SAAAI,EAAa,IAAKW,GAAe,CACjC,MAAMC,EAAM3B,EAAK0B,EAAW,KAAK,EAC3BE,EAAoBR,EAAYM,EAAW,KAAK,EAEtD,OACCG,EAAAA,KAAC,KAAA,CAEA,aAAYH,EAAW,MACvB,IAAKb,EACL,MAAO,CACN,SAAU,WACV,IAAK,EACL,KAAM,EACN,MAAO,OACP,UAAW,cAAca,EAAW,KAAK,KAAA,EAGzC,SAAA,CAAAE,SACCE,EAAA,CAAW,KAAM,IAAI,KAAKH,EAAI,SAAS,EAAG,EAE5CH,EAAAA,IAACO,EAAA,CAAU,IAAAJ,EAAU,YAAa1B,GAAS,IAAA,CAAM,CAAA,CAAA,EAd5C0B,EAAI,EAAA,CAiBZ,CAAC,CAAA,CAAA,CACF,CAAA,CAGH,EAOMI,EAAY,CAAC,CAAE,IAAAJ,EAAK,YAAAK,KAExBH,EAAAA,KAAC,MAAA,CAAI,UAAU,0DACd,SAAA,CAAAL,EAAAA,IAAC,OACA,SAAAA,MAACS,EAAA,CAAc,MAAON,EAAI,MAAO,EAClC,EACAH,EAAAA,IAAC,MAAA,CAAI,UAAU,8CACb,WAAI,QACN,EACAK,EAAAA,KAAC,MAAA,CAAI,UAAU,kFACd,SAAA,CAAAL,MAAC,OAAA,CAAM,SAAAU,EAAOP,EAAI,UAAW,IAAI,EAAE,EAClCK,GAAeR,EAAAA,IAAC,OAAA,CAAM,SAAAQ,CAAA,CAAY,EACnCR,EAAAA,IAAC,OAAA,CAAK,UAAU,wCACd,WAAI,IAAA,CACN,CAAA,CAAA,CACD,CAAA,EACD,EAIIW,EAAwBC,EAAI,QAAS,CAC1C,SAAU,CACT,MAAO,CACN,SAAU,0CACV,MAAO,0CACP,QAAS,mDACT,KAAM,2CACN,MAAO,6CACP,OAAQ,4CAAA,CACT,CAEF,CAAC,EAEYH,EAAgB,CAAC,CAAE,MAAAI,KAA+B,CAC9D,MAAMC,EAAaC,EAAcF,CAAK,EACtC,OACCb,MAACgB,GAAM,UAAWL,EAAsB,CAAE,MAAOG,CAAA,CAAY,EAC3D,SAAAA,CAAA,CACF,CAEF,EAIA,SAASC,EAAcF,EAAyB,CAC/C,KAAM,CAACI,CAAK,EAAIJ,EAAM,SAAA,EAEtB,OAAQI,EAAA,CACP,IAAK,IACJ,MAAO,WACR,IAAK,IACJ,MAAO,QACR,IAAK,IACJ,MAAO,UACR,IAAK,IACJ,MAAO,OACR,IAAK,IACJ,MAAO,QACR,QACC,MAAO,QAAA,CAEV,CAEA,MAAMX,EAAa,CAAC,CAAE,KAAAY,KAEpBb,EAAAA,KAAC,MAAA,CAAI,UAAU,kDACd,SAAA,CAAAL,EAAAA,IAAC,MAAA,CAAI,UAAU,uCAAA,CAAwC,QACtD,OAAA,CAAK,UAAU,kDACd,SAAAU,EAAOQ,EAAM,aAAa,EAC5B,EACAlB,EAAAA,IAAC,MAAA,CAAI,UAAU,uCAAA,CAAwC,CAAA,EACxD,ECxMWmB,EAAoB,CAAC,CACjC,KAAAC,EACA,aAAAC,EACA,aAAAC,EACA,MAAAC,EACA,UAAAC,EACA,UAAAC,EAAY,EACb,IAA8B,CAC7B,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SACzC,MAAA,EAEK,CAACC,EAASC,CAAU,EAAIF,EAAAA,SAAS,EAAE,EAEzCjC,EAAAA,UAAU,IAAM,CACVyB,IACJO,EAAiB,MAAS,EAC1BG,EAAW,EAAE,EAEf,EAAG,CAACV,CAAI,CAAC,EAET,MAAMW,EAAgB,IAAM,CACvBL,GACHF,EAAU,CACT,KAAME,EACN,QAASG,GAAW,MAAA,CACpB,CAEH,EAEMG,EAAoB,CAACN,GAAiBD,EAE5C,aACEQ,EAAA,CAAO,KAAAb,EAAY,aAAAC,EACnB,SAAAhB,EAAAA,KAAC6B,EAAA,CAAc,mBAAkB,OAChC,SAAA,CAAAlC,EAAAA,IAACmC,EAAA,CACA,gBAACC,EAAA,CAAY,SAAA,CAAA,UAAQb,EAAM,QAAA,CAAA,CAAM,CAAA,CAClC,EAEAlB,EAAAA,KAAC,MAAA,CAAI,UAAU,YACb,SAAA,CAAAiB,UACC,MAAA,CACA,SAAA,CAAAtB,EAAAA,IAACqC,EAAA,CAAM,UAAU,aAAa,SAAA,gBAAa,EAC3CrC,EAAAA,IAACsC,EAAA,CACA,KAAMhB,EAAa,KACnB,KAAMA,EAAa,IAAA,CAAA,CACpB,EACD,SAGA,MAAA,CACA,SAAA,CAAAtB,MAACqC,EAAA,CAAM,QAAQ,gBAAgB,UAAU,aAAa,SAAA,gBAEtD,EACArC,EAAAA,IAACuC,EAAA,CACA,MAAOb,EACP,cAAeC,EACf,aAAY,EAAA,CAAA,CACb,EACD,SAEC,MAAA,CACA,SAAA,CAAA3B,MAACqC,EAAA,CAAM,QAAQ,UAAU,UAAU,aAAa,SAAA,oBAEhD,EACArC,EAAAA,IAACwC,EAAA,CACA,GAAG,UACH,MAAOX,EACP,SAAWY,GAAMX,EAAWW,EAAE,OAAO,KAAK,EAC1C,YAAY,+BAAA,CAAA,CACb,CAAA,CACD,CAAA,EACD,SAECC,EAAA,CACA,SAAA,CAAA1C,EAAAA,IAAC2C,EAAA,CACA,KAAK,SACL,QAAQ,UACR,QAAS,IAAMtB,EAAa,EAAK,EACjC,SAAUI,EACV,SAAA,OAAA,CAAA,EAGDzB,EAAAA,IAAC2C,EAAA,CACA,KAAK,SACL,QAASZ,EACT,SAAUC,EACV,QAASP,EACT,SAAA,QAAA,CAAA,CAED,CAAA,CACD,CAAA,CAAA,CACD,CAAA,CACD,CAEF,EASamB,EAAuB,IAAkC,CACrE,KAAM,CAACxB,EAAMyB,CAAO,EAAIjB,EAAAA,SAAS,EAAK,EAEhCkB,EAAa7D,EAAAA,YAAY,IAAM4D,EAAQ,EAAI,EAAG,CAAA,CAAE,EAChDE,EAAc9D,EAAAA,YAAY,IAAM4D,EAAQ,EAAK,EAAG,CAAA,CAAE,EAExD,MAAO,CACN,KAAAzB,EACA,aAAcyB,EACd,WAAAC,EACA,YAAAC,CAAA,CAEF","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"index-BhALpenO.js","sources":["../../node_modules/lucide-react/dist/esm/icons/rows-3.js","../../src/components/ui/run-logs/index.tsx","../../src/components/ui/change-state-dialog/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.562.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 __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M21 9H3\", key: \"1338ky\" }],\n [\"path\", { d: \"M21 15H3\", key: \"9uk58r\" }]\n];\nconst Rows3 = createLucideIcon(\"rows-3\", __iconNode);\n\nexport { __iconNode, Rows3 as default };\n//# sourceMappingURL=rows-3.js.map\n","import { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { cva } from \"class-variance-authority\";\nimport { isSameDay } from \"date-fns\";\nimport { format } from \"date-fns-tz\";\nimport { useCallback, useEffect, useRef } from \"react\";\nimport type { components } from \"@/api/prefect\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { cn } from \"@/utils\";\n\ntype RunLogsProps = {\n\tlogs: components[\"schemas\"][\"Log\"][];\n\ttaskRun?: components[\"schemas\"][\"TaskRun\"];\n\tonBottomReached: () => void;\n\tvirtualize?: boolean;\n\tclassName?: string;\n};\n\n/**\n * Displays logs from a run in a virtualized list.\n *\n * @param logs - Array of log entries to display\n * @param taskRun - Optional task run information to display with logs\n * @param onBottomReached - Callback function triggered when the user scrolls to the bottom of the logs\n *\n */\nexport const RunLogs = ({\n\tlogs,\n\ttaskRun,\n\tonBottomReached,\n\tvirtualize = true,\n\tclassName,\n}: RunLogsProps) => {\n\tconst parentRef = useRef<HTMLDivElement>(null);\n\n\t// Use a ref to store logs for stable getItemKey callback\n\tconst logsRef = useRef(logs);\n\tlogsRef.current = logs;\n\n\tconst getItemKey = useCallback(\n\t\t(index: number) => logsRef.current[index]?.id ?? index,\n\t\t[],\n\t);\n\n\tconst virtualizer = useVirtualizer({\n\t\tcount: logs.length,\n\t\tgetScrollElement: () => parentRef.current,\n\t\testimateSize: () => 75,\n\t\toverscan: 5,\n\t\tgetItemKey,\n\t});\n\n\t// Wrap measureElement in a stable callback to prevent infinite re-renders\n\tconst measureElement = useCallback(\n\t\t(el: HTMLElement | null) => {\n\t\t\tif (el) {\n\t\t\t\tvirtualizer.measureElement(el);\n\t\t\t}\n\t\t},\n\t\t[virtualizer],\n\t);\n\n\tconst virtualItems = virtualize\n\t\t? virtualizer.getVirtualItems()\n\t\t: Array.from({ length: logs.length }, (_, i) => ({\n\t\t\t\tindex: i,\n\t\t\t\tsize: 75,\n\t\t\t\tstart: i * 75,\n\t\t\t}));\n\n\t// Get the last visible item index for stable effect dependency\n\tconst lastVisibleIndex = virtualItems.at(-1)?.index;\n\n\t/**\n\t * This effect detects when the user has scrolled to the bottom of the logs.\n\t * It works by checking if the last visible virtual item is also the last item in the logs array.\n\t * When this condition is met, it calls the bottomReached callback to potentially load more logs.\n\t */\n\tuseEffect(() => {\n\t\tif (lastVisibleIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (lastVisibleIndex >= logs.length - 1) {\n\t\t\tonBottomReached();\n\t\t}\n\t}, [logs.length, lastVisibleIndex, onBottomReached]);\n\n\tconst showDivider = (index: number): boolean => {\n\t\tif (index === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst previous = logs[index - 1];\n\t\tconst current = logs[index];\n\n\t\treturn !isSameDay(previous.timestamp, current.timestamp);\n\t};\n\n\tif (logs.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"flex flex-col gap-2 bg-muted p-2 rounded-md font-mono\">\n\t\t\t\t<span className=\"text-muted-foreground\">No logs found</span>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div\n\t\t\tref={parentRef}\n\t\t\tclassName={cn(\n\t\t\t\t\"bg-muted rounded-md font-mono p-4 overflow-y-auto\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\trole=\"log\"\n\t\t>\n\t\t\t<ol\n\t\t\t\tclassName=\"relative\"\n\t\t\t\tstyle={{\n\t\t\t\t\theight: `${virtualizer.getTotalSize()}px`,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{virtualItems.map((virtualRow) => {\n\t\t\t\t\tconst log = logs[virtualRow.index];\n\t\t\t\t\tconst shouldShowDivider = showDivider(virtualRow.index);\n\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tkey={log.id}\n\t\t\t\t\t\t\tdata-index={virtualRow.index}\n\t\t\t\t\t\t\tref={measureElement}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\t\ttransform: `translateY(${virtualRow.start}px)`,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{shouldShowDivider && (\n\t\t\t\t\t\t\t\t<LogDivider date={new Date(log.timestamp)} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<RunLogRow log={log} taskRunName={taskRun?.name} />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</ol>\n\t\t</div>\n\t);\n};\n\ntype RunLogRowProps = {\n\tlog: components[\"schemas\"][\"Log\"];\n\ttaskRunName?: string;\n};\n\nconst RunLogRow = ({ log, taskRunName }: RunLogRowProps) => {\n\treturn (\n\t\t<div className=\"grid grid-cols-[84px_minmax(0,1fr)_150px] gap-2 text-sm\">\n\t\t\t<div>\n\t\t\t\t<LogLevelBadge level={log.level} />\n\t\t\t</div>\n\t\t\t<div className=\"select-auto whitespace-pre-wrap break-words\">\n\t\t\t\t{log.message}\n\t\t\t</div>\n\t\t\t<div className=\"text-xs grid grid-cols-1 gap-1 justify-items-end text-muted-foreground truncate\">\n\t\t\t\t<span>{format(log.timestamp, \"pp\")}</span>\n\t\t\t\t{taskRunName && <span>{taskRunName}</span>}\n\t\t\t\t<span className=\"font-bold break-all whitespace-normal\">\n\t\t\t\t\t{log.name}\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nconst logLevelBadgeVariants = cva(\"gap-1\", {\n\tvariants: {\n\t\tlevel: {\n\t\t\tCRITICAL: \"bg-red-600 text-red-50 hover:bg-red-600\",\n\t\t\tERROR: \"bg-red-600 text-red-50 hover:bg-red-600\",\n\t\t\tWARNING: \"bg-orange-600 text-orange-50 hover:bg-orange-600\",\n\t\t\tINFO: \"bg-sky-600 text-blue-50 hover:bg-sky-600\",\n\t\t\tDEBUG: \"bg-gray-700 text-gray-50 hover:bg-gray-700\",\n\t\t\tCUSTOM: \"bg-gray-700 text-gray-50 hover:bg-gray-700\",\n\t\t} satisfies Record<LogLevel, string>,\n\t},\n});\n\nexport const LogLevelBadge = ({ level }: { level: number }) => {\n\tconst levelLabel = logLevelLabel(level);\n\treturn (\n\t\t<Badge className={logLevelBadgeVariants({ level: levelLabel })}>\n\t\t\t{levelLabel}\n\t\t</Badge>\n\t);\n};\n\ntype LogLevel = \"CRITICAL\" | \"ERROR\" | \"WARNING\" | \"INFO\" | \"DEBUG\" | \"CUSTOM\";\n\nfunction logLevelLabel(level: number): LogLevel {\n\tconst [first] = level.toString();\n\n\tswitch (first) {\n\t\tcase \"5\":\n\t\t\treturn \"CRITICAL\";\n\t\tcase \"4\":\n\t\t\treturn \"ERROR\";\n\t\tcase \"3\":\n\t\t\treturn \"WARNING\";\n\t\tcase \"2\":\n\t\t\treturn \"INFO\";\n\t\tcase \"1\":\n\t\t\treturn \"DEBUG\";\n\t\tdefault:\n\t\t\treturn \"CUSTOM\";\n\t}\n}\n\nconst LogDivider = ({ date }: { date: Date }) => {\n\treturn (\n\t\t<div className=\"flex flex-row justify-center items-center gap-2\">\n\t\t\t<div className=\"h-[1px] w-full bg-muted-foreground/30\" />\n\t\t\t<span className=\"text-xs text-muted-foreground whitespace-nowrap\">\n\t\t\t\t{format(date, \"MMM d, yyyy\")}\n\t\t\t</span>\n\t\t\t<div className=\"h-[1px] w-full bg-muted-foreground/30\" />\n\t\t</div>\n\t);\n};\n","import { useCallback, useEffect, useState } from \"react\";\nimport type { components } from \"@/api/prefect\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n} from \"@/components/ui/dialog\";\nimport { Input } from \"@/components/ui/input\";\nimport { Label } from \"@/components/ui/label\";\nimport { StateBadge } from \"@/components/ui/state-badge\";\nimport { StateSelect } from \"@/components/ui/state-select\";\n\ntype StateType = components[\"schemas\"][\"StateType\"];\n\nexport type ChangeStateDialogProps = {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tcurrentState: { type: string; name: string } | null;\n\tlabel: string;\n\tonConfirm: (newState: { type: string; message?: string }) => void;\n\tisLoading?: boolean;\n};\n\nexport const ChangeStateDialog = ({\n\topen,\n\tonOpenChange,\n\tcurrentState,\n\tlabel,\n\tonConfirm,\n\tisLoading = false,\n}: ChangeStateDialogProps) => {\n\tconst [selectedState, setSelectedState] = useState<StateType | undefined>(\n\t\tundefined,\n\t);\n\tconst [message, setMessage] = useState(\"\");\n\n\tuseEffect(() => {\n\t\tif (!open) {\n\t\t\tsetSelectedState(undefined);\n\t\t\tsetMessage(\"\");\n\t\t}\n\t}, [open]);\n\n\tconst handleConfirm = () => {\n\t\tif (selectedState) {\n\t\t\tonConfirm({\n\t\t\t\ttype: selectedState,\n\t\t\t\tmessage: message || undefined,\n\t\t\t});\n\t\t}\n\t};\n\n\tconst isConfirmDisabled = !selectedState || isLoading;\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent aria-describedby={undefined}>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Change {label} State</DialogTitle>\n\t\t\t\t</DialogHeader>\n\n\t\t\t\t<div className=\"space-y-4\">\n\t\t\t\t\t{currentState && (\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<Label className=\"mb-2 block\">Current State</Label>\n\t\t\t\t\t\t\t<StateBadge\n\t\t\t\t\t\t\t\ttype={currentState.type as StateType}\n\t\t\t\t\t\t\t\tname={currentState.name}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<Label htmlFor=\"desired-state\" className=\"mb-2 block\">\n\t\t\t\t\t\t\tDesired State\n\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t<StateSelect\n\t\t\t\t\t\t\tvalue={selectedState}\n\t\t\t\t\t\t\tonValueChange={setSelectedState}\n\t\t\t\t\t\t\tterminalOnly\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<Label htmlFor=\"message\" className=\"mb-2 block\">\n\t\t\t\t\t\t\tReason (Optional)\n\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\tid=\"message\"\n\t\t\t\t\t\t\tvalue={message}\n\t\t\t\t\t\t\tonChange={(e) => setMessage(e.target.value)}\n\t\t\t\t\t\t\tplaceholder=\"State changed manually via UI\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<DialogFooter>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tonClick={() => onOpenChange(false)}\n\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t>\n\t\t\t\t\t\tClose\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t\t\tdisabled={isConfirmDisabled}\n\t\t\t\t\t\tloading={isLoading}\n\t\t\t\t\t>\n\t\t\t\t\t\tChange\n\t\t\t\t\t</Button>\n\t\t\t\t</DialogFooter>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n\nexport type UseChangeStateDialogResult = {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\topenDialog: () => void;\n\tcloseDialog: () => void;\n};\n\nexport const useChangeStateDialog = (): UseChangeStateDialogResult => {\n\tconst [open, setOpen] = useState(false);\n\n\tconst openDialog = useCallback(() => setOpen(true), []);\n\tconst closeDialog = useCallback(() => setOpen(false), []);\n\n\treturn {\n\t\topen,\n\t\tonOpenChange: setOpen,\n\t\topenDialog,\n\t\tcloseDialog,\n\t};\n};\n"],"names":["__iconNode","Rows3","createLucideIcon","RunLogs","logs","taskRun","onBottomReached","virtualize","className","parentRef","useRef","logsRef","getItemKey","useCallback","index","virtualizer","useVirtualizer","measureElement","el","virtualItems","_","i","lastVisibleIndex","useEffect","showDivider","previous","current","isSameDay","jsx","cn","virtualRow","log","shouldShowDivider","jsxs","LogDivider","RunLogRow","taskRunName","LogLevelBadge","format","logLevelBadgeVariants","cva","level","levelLabel","logLevelLabel","Badge","first","date","ChangeStateDialog","open","onOpenChange","currentState","label","onConfirm","isLoading","selectedState","setSelectedState","useState","message","setMessage","handleConfirm","isConfirmDisabled","Dialog","DialogContent","DialogHeader","DialogTitle","Label","StateBadge","StateSelect","Input","e","DialogFooter","Button","useChangeStateDialog","setOpen","openDialog","closeDialog"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as o}from"./vendor-tanstack-BK8oseNA.js";import{s}from"./index-D5RdrxkU.js";import{R as i}from"./route-error-state-BJXl8qkX.js";import{W as m}from"./header-B0ejRncu.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-forms-DxqqmhL5.js";import"./vendor-date-7GxEwcQM.js";function E({error:e,reset:t}){const r=s(e,"Failed to load work pools");if(r.type!=="server-error"&&r.type!=="client-error")throw e;return o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsx(m,{}),o.jsx(i,{error:r,onRetry:t})]})}export{E as errorComponent};
|
|
2
|
+
//# sourceMappingURL=index-BzN9bQeM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-BzN9bQeM.js","sources":["../../src/routes/work-pools/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useMemo, useState } from \"react\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport {\n\tbuildCountWorkPoolsQuery,\n\tbuildFilterWorkPoolsQuery,\n} from \"@/api/work-pools\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\nimport { WorkPoolsEmptyState } from \"@/components/work-pools/empty-state\";\nimport { WorkPoolsPageHeader } from \"@/components/work-pools/header\";\nimport { WorkPoolCard } from \"@/components/work-pools/work-pool-card/work-pool-card\";\nimport { pluralize } from \"@/utils\";\n\nfunction WorkPoolsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load work pools\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/work-pools/\")({\n\tcomponent: RouteComponent,\n\terrorComponent: WorkPoolsErrorComponent,\n\tloader: ({ context }) => {\n\t\tvoid context.queryClient.ensureQueryData(buildCountWorkPoolsQuery());\n\t\tvoid context.queryClient.ensureQueryData(\n\t\t\tbuildFilterWorkPoolsQuery({\n\t\t\t\tlimit: 200,\n\t\t\t\toffset: 0,\n\t\t\t}),\n\t\t);\n\t},\n\twrapInSuspense: true,\n});\n\nfunction RouteComponent() {\n\tconst [searchTerm, setSearchTerm] = useState(\"\");\n\n\tconst { data: workPoolCount = 0 } = useSuspenseQuery(\n\t\tbuildCountWorkPoolsQuery(),\n\t);\n\n\tconst { data: workPools = [] } = useSuspenseQuery(\n\t\tbuildFilterWorkPoolsQuery({\n\t\t\tlimit: 200,\n\t\t\toffset: 0,\n\t\t}),\n\t);\n\n\tconst filteredWorkPools = useMemo(() => {\n\t\treturn workPools.filter((workPool) =>\n\t\t\t[\n\t\t\t\tworkPool.name,\n\t\t\t\tworkPool.description,\n\t\t\t\tworkPool.type,\n\t\t\t\tJSON.stringify(workPool.base_job_template),\n\t\t\t\tworkPool.id,\n\t\t\t\tworkPool.default_queue_id,\n\t\t\t\tworkPool.status,\n\t\t\t]\n\t\t\t\t.join(\" \")\n\t\t\t\t.toLowerCase()\n\t\t\t\t.includes(searchTerm.toLowerCase()),\n\t\t);\n\t}, [workPools, searchTerm]);\n\n\tconst handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n\t\tsetSearchTerm(event.target.value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t{workPoolCount < 1 ? (\n\t\t\t\t<WorkPoolsEmptyState />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"flex items-end justify-between\">\n\t\t\t\t\t\t<div className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t{workPoolCount} {pluralize(workPoolCount, \"work pool\")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex gap-2\">\n\t\t\t\t\t\t\t<SearchInput\n\t\t\t\t\t\t\t\tplaceholder=\"Search work pools...\"\n\t\t\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\t\t\tonChange={handleSearchChange}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t{filteredWorkPools.map((workPool) => (\n\t\t\t\t\t\t\t<WorkPoolCard key={workPool.id} workPool={workPool} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"names":["WorkPoolsErrorComponent","error","reset","serverError","categorizeError","type","jsxs","jsx","WorkPoolsPageHeader","RouteErrorState"],"mappings":"mWAgBA,SAASA,EAAwB,CAAEC,MAAAA,EAAOC,MAAAA,CAA2B,EAAG,CACvE,MAAMC,EAAcC,EAAgBH,EAAO,2BAA2B,EAItE,GACCE,EAAYE,OAAS,gBACrBF,EAAYE,OAAS,eAErB,MAAMJ,EAGP,OACCK,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAmB,EACpBD,EAAAA,IAACE,EAAA,CAAgB,MAAON,EAAa,QAASD,CAAAA,CAAM,CAAA,EACrD,CAEF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as o}from"./vendor-tanstack-BK8oseNA.js";import{
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{j as o}from"./vendor-tanstack-BK8oseNA.js";import{s as m}from"./index-D5RdrxkU.js";import{D as s}from"./header-huSvwxKI.js";import{R as p}from"./route-error-state-BJXl8qkX.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-forms-DxqqmhL5.js";import"./vendor-date-7GxEwcQM.js";function j({error:e,reset:t}){const r=m(e,"Failed to load deployments");if(r.type!=="server-error"&&r.type!=="client-error")throw e;return o.jsxs("div",{className:"flex flex-col gap-4",children:[o.jsx(s,{}),o.jsx(p,{error:r,onRetry:t})]})}export{j as errorComponent};
|
|
2
|
+
//# sourceMappingURL=index-CBhi1P9g.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-CBhi1P9g.js","sources":["../../src/routes/deployments/index.tsx?tsr-split=errorComponent"],"sourcesContent":["import { useQuery, useSuspenseQueries } from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport type {\n\tColumnFiltersState,\n\tPaginationState,\n} from \"@tanstack/react-table\";\nimport { zodValidator } from \"@tanstack/zod-adapter\";\nimport { useCallback, useMemo } from \"react\";\nimport { z } from \"zod\";\nimport {\n\tbuildCountDeploymentsQuery,\n\tbuildPaginateDeploymentsQuery,\n\ttype DeploymentsPaginationFilter,\n} from \"@/api/deployments\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport { buildListFlowsQuery } from \"@/api/flows\";\nimport type { components } from \"@/api/prefect\";\nimport { DeploymentsDataTable } from \"@/components/deployments/data-table\";\nimport { DeploymentsEmptyState } from \"@/components/deployments/empty-state\";\nimport { DeploymentsPageHeader } from \"@/components/deployments/header\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\n\n/**\n * Schema for validating URL search parameters for the variables page.\n * @property {number} page - The page number to display. Must be positive. Defaults to 1.\n * @property {number} limit - The maximum number of items to return. Must be positive. Defaults to 10.\n */\nconst searchParams = z.object({\n\tpage: z.number().int().positive().optional().default(1).catch(1),\n\tlimit: z.number().int().positive().optional().default(10).catch(10),\n\tsort: z\n\t\t.enum([\"NAME_ASC\", \"NAME_DESC\", \"CREATED_DESC\", \"UPDATED_DESC\"])\n\t\t.optional()\n\t\t.default(\"NAME_ASC\")\n\t\t.catch(\"NAME_ASC\"),\n\tflowOrDeploymentName: z.string().optional().catch(\"\"),\n\ttags: z.array(z.string()).optional().catch([]),\n});\n\n/**\n * Builds pagination parameters for deployments query from search params\n *\n * @param search - Optional validated search parameters containing page and limit\n * @returns DeploymentsPaginationFilter with page, limit and sort order\n *\n * @example\n * ```ts\n * const filter = buildPaginationBody({ page: 2, limit: 25 })\n * // Returns { page: 2, limit: 25, sort: \"NAME_ASC\" }\n * ```\n */\nconst buildPaginationBody = (\n\tsearch?: z.infer<typeof searchParams>,\n): DeploymentsPaginationFilter => ({\n\tpage: search?.page ?? 1,\n\tlimit: search?.limit ?? 10,\n\tsort: search?.sort ?? \"NAME_ASC\",\n\tdeployments: {\n\t\toperator: \"and_\",\n\t\tflow_or_deployment_name: { like_: search?.flowOrDeploymentName ?? \"\" },\n\t\ttags: { operator: \"and_\", all_: search?.tags ?? [] },\n\t},\n});\n\nfunction DeploymentsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load deployments\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<DeploymentsPageHeader />\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/deployments/\")({\n\tvalidateSearch: zodValidator(searchParams),\n\tcomponent: RouteComponent,\n\terrorComponent: DeploymentsErrorComponent,\n\tloaderDeps: ({ search }) => buildPaginationBody(search),\n\tloader: async ({ deps, context }) => {\n\t\t// Get full count of deployments, don't block the UI\n\t\tconst deploymentsCountResult = context.queryClient.ensureQueryData(\n\t\t\tbuildCountDeploymentsQuery(),\n\t\t);\n\n\t\t// Get paginated deployments, wait for the result to get corresponding flows\n\t\tconst deploymentsPaginateResult = await context.queryClient.ensureQueryData(\n\t\t\tbuildPaginateDeploymentsQuery(deps),\n\t\t);\n\n\t\tconst deployments = deploymentsPaginateResult?.results ?? [];\n\n\t\tconst flowIds = [\n\t\t\t...new Set(deployments.map((deployment) => deployment.flow_id)),\n\t\t];\n\n\t\t// Get flows corresponding to the deployments\n\t\tconst flowsFilterResult = context.queryClient.ensureQueryData(\n\t\t\tbuildListFlowsQuery({\n\t\t\t\tflows: {\n\t\t\t\t\toperator: \"and_\",\n\t\t\t\t\tid: {\n\t\t\t\t\t\tany_: flowIds,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\toffset: 0,\n\t\t\t\tsort: \"NAME_ASC\",\n\t\t\t}),\n\t\t);\n\n\t\treturn {\n\t\t\tdeploymentsCountResult,\n\t\t\tdeploymentsPaginateResult,\n\t\t\tflowsFilterResult,\n\t\t};\n\t},\n\twrapInSuspense: true,\n});\n\n/**\n * Hook to manage pagination state and navigation for deployments table\n *\n * Handles conversion between 1-based page numbers in the URL and 0-based indices used by React Table.\n * Updates the URL search parameters when pagination changes.\n *\n * @returns A tuple containing:\n * - pagination: Current pagination state with pageIndex and pageSize\n * - onPaginationChange: Callback to update pagination and navigate with new search params\n */\nconst usePagination = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\t// React Table uses 0-based pagination, so we need to subtract 1 from the page number\n\tconst pageIndex = (search.page ?? 1) - 1;\n\tconst pageSize = search.limit ?? 10;\n\tconst pagination: PaginationState = useMemo(\n\t\t() => ({\n\t\t\tpageIndex,\n\t\t\tpageSize,\n\t\t}),\n\t\t[pageIndex, pageSize],\n\t);\n\n\tconst onPaginationChange = useCallback(\n\t\t(newPagination: PaginationState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tpage: newPagination.pageIndex + 1,\n\t\t\t\t\tlimit: newPagination.pageSize,\n\t\t\t\t}),\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [pagination, onPaginationChange] as const;\n};\n\n/**\n * Hook to manage sorting state and navigation for deployments table\n *\n * Handles updating the URL search parameters when sort order changes.\n * Returns the current sort value from URL and a callback to update it.\n *\n * @returns A tuple containing:\n * - sort: Current sort value from URL search params\n * - onSortingChange: Callback to update sort and navigate with new search params\n */\nconst useSort = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\n\tconst onSortingChange = (sort: components[\"schemas\"][\"DeploymentSort\"]) => {\n\t\tvoid navigate({\n\t\t\tto: \".\",\n\t\t\tsearch: (prev) => ({ ...prev, sort }),\n\t\t\treplace: true,\n\t\t});\n\t};\n\n\treturn [search.sort, onSortingChange] as const;\n};\n\nconst useDeploymentsColumnFilters = () => {\n\tconst search = Route.useSearch();\n\tconst navigate = Route.useNavigate();\n\tconst columnFilters: ColumnFiltersState = useMemo(\n\t\t() => [\n\t\t\t{ id: \"flowOrDeploymentName\", value: search.flowOrDeploymentName },\n\t\t\t{ id: \"tags\", value: search.tags },\n\t\t],\n\t\t[search.flowOrDeploymentName, search.tags],\n\t);\n\n\tconst onColumnFiltersChange = useCallback(\n\t\t(newColumnFilters: ColumnFiltersState) => {\n\t\t\tvoid navigate({\n\t\t\t\tto: \".\",\n\t\t\t\tsearch: (prev) => {\n\t\t\t\t\tconst flowOrDeploymentName = newColumnFilters.find(\n\t\t\t\t\t\t(filter) => filter.id === \"flowOrDeploymentName\",\n\t\t\t\t\t)?.value as string | undefined;\n\t\t\t\t\tconst tags = newColumnFilters.find((filter) => filter.id === \"tags\")\n\t\t\t\t\t\t?.value as string[] | undefined;\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\toffset: 0,\n\t\t\t\t\t\tflowOrDeploymentName,\n\t\t\t\t\t\ttags,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\treplace: true,\n\t\t\t});\n\t\t},\n\t\t[navigate],\n\t);\n\n\treturn [columnFilters, onColumnFiltersChange] as const;\n};\n\nfunction RouteComponent() {\n\tconst search = Route.useSearch();\n\tconst [pagination, onPaginationChange] = usePagination();\n\tconst [sort, onSortChange] = useSort();\n\tconst [columnFilters, onColumnFiltersChange] = useDeploymentsColumnFilters();\n\n\tconst [{ data: deploymentsCount }, { data: deploymentsPage }] =\n\t\tuseSuspenseQueries({\n\t\t\tqueries: [\n\t\t\t\tbuildCountDeploymentsQuery(),\n\t\t\t\tbuildPaginateDeploymentsQuery(buildPaginationBody(search)),\n\t\t\t],\n\t\t});\n\n\tconst deployments = deploymentsPage?.results ?? [];\n\n\tconst { data: flows } = useQuery(\n\t\tbuildListFlowsQuery({\n\t\t\tflows: {\n\t\t\t\toperator: \"and_\",\n\t\t\t\tid: {\n\t\t\t\t\tany_: [\n\t\t\t\t\t\t...new Set(deployments.map((deployment) => deployment.flow_id)),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\toffset: 0,\n\t\t\tsort: \"NAME_ASC\",\n\t\t}),\n\t);\n\n\tconst deploymentsWithFlows = deployments.map((deployment) => ({\n\t\t...deployment,\n\t\tflow: flows?.find((flow) => flow.id === deployment.flow_id),\n\t}));\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<DeploymentsPageHeader />\n\t\t\t{deploymentsCount === 0 ? (\n\t\t\t\t<DeploymentsEmptyState />\n\t\t\t) : (\n\t\t\t\t<DeploymentsDataTable\n\t\t\t\t\tdeployments={deploymentsWithFlows}\n\t\t\t\t\tcurrentDeploymentsCount={deploymentsCount}\n\t\t\t\t\tpageCount={deploymentsPage?.pages ?? 0}\n\t\t\t\t\tpagination={pagination}\n\t\t\t\t\tsort={sort}\n\t\t\t\t\tcolumnFilters={columnFilters}\n\t\t\t\t\tonPaginationChange={onPaginationChange}\n\t\t\t\t\tonSortChange={onSortChange}\n\t\t\t\t\tonColumnFiltersChange={onColumnFiltersChange}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"names":["DeploymentsErrorComponent","error","reset","serverError","categorizeError","type","jsxs","jsx","DeploymentsPageHeader","RouteErrorState"],"mappings":"wWAiEA,SAASA,EAA0B,CAAEC,MAAAA,EAAOC,MAAAA,CAA2B,EAAG,CACzE,MAAMC,EAAcC,EAAgBH,EAAO,4BAA4B,EAIvE,GACCE,EAAYE,OAAS,gBACrBF,EAAYE,OAAS,eAErB,MAAMJ,EAGP,OACCK,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAC,EAAAA,IAACC,EAAA,EAAqB,EACtBD,EAAAA,IAACE,EAAA,CAAgB,MAAON,EAAa,QAASD,CAAAA,CAAM,CAAA,EACrD,CAEF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e,L as p,r as i,p as m}from"./vendor-tanstack-BK8oseNA.js";import{E as g,
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{j as e,L as p,r as i,p as m}from"./vendor-tanstack-BK8oseNA.js";import{E as g,t as C,v as f,w as y,x as N,q as x,I as u,D as k,y as o,W,A as S,F as v,G as P,H as E,J as D,C as b,m as I,n as T,o as _,K as L,M as A,N as M,O}from"./index-D5RdrxkU.js";import{W as R}from"./header-B0ejRncu.js";import{S as z}from"./index-Cutg_A1j.js";import{D as w,a as $,b as F,c as B,d}from"./dropdown-menu-e0Fqb6aw.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-forms-DxqqmhL5.js";import"./vendor-date-7GxEwcQM.js";const K=()=>e.jsxs(g,{children:[e.jsx(C,{id:"Cpu"}),e.jsx(f,{children:"Add a work pool to get started"}),e.jsx(y,{children:"Work pools allow you to prioritize and manage deployments and control the infrastructure they run on."}),e.jsxs(N,{children:[e.jsx(p,{to:"/work-pools/create",children:e.jsxs(x,{children:["Add Work Pool ",e.jsx(u,{id:"Plus",className:"size-4 ml-2"})]})}),e.jsx(k,{id:"work-pools-guide"})]})]}),H=({workPool:s,onDelete:a})=>{const n=r=>{navigator.clipboard.writeText(r),o.success("ID copied")};return e.jsxs(w,{children:[e.jsx($,{asChild:!0,children:e.jsxs(x,{variant:"outline",className:"size-8 p-0",children:[e.jsx("span",{className:"sr-only",children:"Open menu"}),e.jsx(u,{id:"MoreVertical",className:"size-4"})]})}),e.jsxs(F,{align:"end",children:[e.jsx(B,{children:"Actions"}),e.jsx(d,{onClick:()=>n(s.id),children:"Copy ID"}),e.jsx(p,{to:"/work-pools/work-pool/$workPoolName/edit",params:{workPoolName:s.name},children:e.jsx(d,{children:"Edit"})}),e.jsx(d,{onClick:a,children:"Delete"})]})]})},Q=({workPoolName:s})=>e.jsx(W,{workPoolName:s}),U=({workPool:s})=>{const[a,n]=i.useState(s.status==="PAUSED"),{pauseWorkPool:r,isPending:c}=S(),{resumeWorkPool:l,isPending:t}=v(),j=i.useMemo(()=>c||t,[c,t]),h=()=>{a?l(s.name,{onSuccess:()=>{n(!1),o.success(`${s.name} resumed`)},onError:()=>{o.error(`Failed to resume ${s.name}`)}}):r(s.name,{onSuccess:()=>{n(!0),o.success(`${s.name} paused`)},onError:()=>{o.error(`Failed to pause ${s.name}`)}})};return e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm text-muted-foreground",children:a?"Paused":"Active"}),e.jsx(P,{checked:!a,onCheckedChange:h,disabled:j,"aria-label":a?"Resume work pool":"Pause work pool"})]})},q={process:"Process",ecs:"ECS","azure-container-instance":"Azure Container Instance",docker:"Docker","cloud-run":"Cloud Run","cloud-run-v2":"Cloud Run v2","vertex-ai":"Vertex AI",kubernetes:"Kubernetes"},J={process:"Cpu",ecs:"Cpu","azure-container-instance":"Cpu",docker:"Cpu","cloud-run":"Cpu","cloud-run-v2":"Cpu","vertex-ai":"Cpu",kubernetes:"Cpu"},V=s=>q[s]??s,Y=s=>J[s]??"Cpu",G=({type:s})=>e.jsxs(E,{children:[e.jsx(u,{id:Y(s)}),V(s)]}),X=({workPool:s})=>{const{deleteWorkPool:a}=D(),n=()=>{a(s.name,{onSuccess:()=>{o.success(`${s.name} deleted`)},onError:r=>{o.error(`Failed to delete work pool: ${r instanceof Error?r.message:"Unknown error"}`)}})};return e.jsxs(b,{className:"gap-2",children:[e.jsxs(I,{className:"flex flex-row items-center justify-between",children:[e.jsxs(T,{className:"flex items-center gap-2",children:[e.jsx(Q,{workPoolName:s.name}),s.status&&e.jsx(z,{status:s.status})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(U,{workPool:s}),e.jsx(H,{workPool:s,onDelete:n})]})]}),e.jsxs(_,{className:"flex flex-col gap-1",children:[e.jsx("div",{className:"flex items-center gap-1",children:e.jsx(G,{type:s.type})}),e.jsxs("div",{className:"text-sm text-muted-foreground",children:["Concurrency:"," ",e.jsx("span",{className:"text-foreground",children:s.concurrency_limit?s.concurrency_limit:"Unlimited"})]})]})]})};function le(){const[s,a]=i.useState(""),{data:n=0}=m(L()),{data:r=[]}=m(A({limit:200,offset:0})),c=i.useMemo(()=>r.filter(t=>[t.name,t.description,t.type,JSON.stringify(t.base_job_template),t.id,t.default_queue_id,t.status].join(" ").toLowerCase().includes(s.toLowerCase())),[r,s]),l=t=>{a(t.target.value)};return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx(R,{}),n<1?e.jsx(K,{}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-end justify-between",children:[e.jsxs("div",{className:"text-sm text-muted-foreground",children:[n," ",M(n,"work pool")]}),e.jsx("div",{className:"flex gap-2",children:e.jsx(O,{placeholder:"Search work pools...",value:s,onChange:l})})]}),e.jsx("div",{className:"flex flex-col gap-4",children:c.map(t=>e.jsx(X,{workPool:t},t.id))})]})]})}export{le as component};
|
|
2
|
+
//# sourceMappingURL=index-CRDz4nhM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-UN2Tx4jH.js","sources":["../../src/components/work-pools/empty-state.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-context-menu.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-name.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-pause-resume-toggle.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-type-badge.tsx","../../src/components/work-pools/work-pool-card/work-pool-card.tsx","../../src/routes/work-pools/index.tsx?tsr-split=component"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { Button } from \"@/components/ui/button\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport {\n\tEmptyState,\n\tEmptyStateActions,\n\tEmptyStateDescription,\n\tEmptyStateIcon,\n\tEmptyStateTitle,\n} from \"@/components/ui/empty-state\";\nimport { Icon } from \"@/components/ui/icons\";\n\nexport const WorkPoolsEmptyState = () => (\n\t<EmptyState>\n\t\t<EmptyStateIcon id=\"Cpu\" />\n\t\t<EmptyStateTitle>Add a work pool to get started</EmptyStateTitle>\n\t\t<EmptyStateDescription>\n\t\t\tWork pools allow you to prioritize and manage deployments and control the\n\t\t\tinfrastructure they run on.\n\t\t</EmptyStateDescription>\n\t\t<EmptyStateActions>\n\t\t\t<Link to=\"/work-pools/create\">\n\t\t\t\t<Button>\n\t\t\t\t\tAdd Work Pool <Icon id=\"Plus\" className=\"size-4 ml-2\" />\n\t\t\t\t</Button>\n\t\t\t</Link>\n\t\t\t<DocsLink id=\"work-pools-guide\" />\n\t\t</EmptyStateActions>\n\t</EmptyState>\n);\n","import { Link } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Icon } from \"@/components/ui/icons\";\n\nexport type WorkPoolContextMenuProps = {\n\tworkPool: WorkPool;\n\tonDelete: () => void;\n};\n\nexport const WorkPoolContextMenu = ({\n\tworkPool,\n\tonDelete,\n}: WorkPoolContextMenuProps) => {\n\tconst handleCopyId = (id: string) => {\n\t\tvoid navigator.clipboard.writeText(id);\n\t\ttoast.success(\"ID copied\");\n\t};\n\n\treturn (\n\t\t<DropdownMenu>\n\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t<Button variant=\"outline\" className=\"size-8 p-0\">\n\t\t\t\t\t<span className=\"sr-only\">Open menu</span>\n\t\t\t\t\t<Icon id=\"MoreVertical\" className=\"size-4\" />\n\t\t\t\t</Button>\n\t\t\t</DropdownMenuTrigger>\n\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t<DropdownMenuLabel>Actions</DropdownMenuLabel>\n\t\t\t\t<DropdownMenuItem onClick={() => handleCopyId(workPool.id)}>\n\t\t\t\t\tCopy ID\n\t\t\t\t</DropdownMenuItem>\n\t\t\t\t<Link\n\t\t\t\t\tto=\"/work-pools/work-pool/$workPoolName/edit\"\n\t\t\t\t\tparams={{ workPoolName: workPool.name }}\n\t\t\t\t>\n\t\t\t\t\t<DropdownMenuItem>Edit</DropdownMenuItem>\n\t\t\t\t</Link>\n\t\t\t\t<DropdownMenuItem onClick={onDelete}>Delete</DropdownMenuItem>\n\t\t\t</DropdownMenuContent>\n\t\t</DropdownMenu>\n\t);\n};\n","import { WorkPoolIconText } from \"@/components/work-pools/work-pool-icon-text\";\n\ntype WorkPoolNameProps = {\n\tworkPoolName: string;\n};\n\nexport const WorkPoolName = ({ workPoolName }: WorkPoolNameProps) => {\n\treturn <WorkPoolIconText workPoolName={workPoolName} />;\n};\n","import { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { usePauseWorkPool, useResumeWorkPool } from \"@/api/work-pools\";\nimport { Switch } from \"@/components/ui/switch\";\nexport type WorkPoolPauseResumeToggleParams = {\n\tworkPool: WorkPool;\n};\n\nexport const WorkPoolPauseResumeToggle = ({\n\tworkPool,\n}: WorkPoolPauseResumeToggleParams) => {\n\tconst [isPaused, setIsPaused] = useState(workPool.status === \"PAUSED\");\n\n\tconst { pauseWorkPool, isPending: isPausing } = usePauseWorkPool();\n\tconst { resumeWorkPool, isPending: isResuming } = useResumeWorkPool();\n\n\tconst disabled = useMemo(() => {\n\t\treturn isPausing || isResuming;\n\t}, [isPausing, isResuming]);\n\n\tconst handleTogglePause = () => {\n\t\tif (isPaused) {\n\t\t\tresumeWorkPool(workPool.name, {\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tsetIsPaused(false);\n\t\t\t\t\ttoast.success(`${workPool.name} resumed`);\n\t\t\t\t},\n\t\t\t\tonError: () => {\n\t\t\t\t\ttoast.error(`Failed to resume ${workPool.name}`);\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tpauseWorkPool(workPool.name, {\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tsetIsPaused(true);\n\t\t\t\t\ttoast.success(`${workPool.name} paused`);\n\t\t\t\t},\n\t\t\t\tonError: () => {\n\t\t\t\t\ttoast.error(`Failed to pause ${workPool.name}`);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t};\n\n\treturn (\n\t\t<span className=\"flex items-center gap-2\">\n\t\t\t<span className=\"text-sm text-muted-foreground\">\n\t\t\t\t{isPaused ? \"Paused\" : \"Active\"}\n\t\t\t</span>\n\t\t\t<Switch\n\t\t\t\tchecked={!isPaused}\n\t\t\t\tonCheckedChange={handleTogglePause}\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={isPaused ? \"Resume work pool\" : \"Pause work pool\"}\n\t\t\t/>\n\t\t</span>\n\t);\n};\n","import type { WorkPool } from \"@/api/work-pools\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Icon, type IconId } from \"@/components/ui/icons\";\n\ntype WorkPoolTypeBadgeProps = {\n\ttype: WorkPool[\"type\"];\n};\n\nconst WORK_POOL_TYPE_LABELS: Record<WorkPool[\"type\"], string> = {\n\tprocess: \"Process\",\n\tecs: \"ECS\",\n\t\"azure-container-instance\": \"Azure Container Instance\",\n\tdocker: \"Docker\",\n\t\"cloud-run\": \"Cloud Run\",\n\t\"cloud-run-v2\": \"Cloud Run v2\",\n\t\"vertex-ai\": \"Vertex AI\",\n\tkubernetes: \"Kubernetes\",\n} as const;\n\nconst WORK_POOL_TYPE_ICONS: Record<WorkPool[\"type\"], IconId> = {\n\tprocess: \"Cpu\",\n\tecs: \"Cpu\",\n\t\"azure-container-instance\": \"Cpu\",\n\tdocker: \"Cpu\",\n\t\"cloud-run\": \"Cpu\",\n\t\"cloud-run-v2\": \"Cpu\",\n\t\"vertex-ai\": \"Cpu\",\n\tkubernetes: \"Cpu\",\n} as const;\n\nconst getWorkPoolTypeLabel = (type: WorkPool[\"type\"]) => {\n\treturn WORK_POOL_TYPE_LABELS[type] ?? type;\n};\n\nconst getWorkPoolTypeIcon = (type: WorkPool[\"type\"]) => {\n\treturn WORK_POOL_TYPE_ICONS[type] ?? \"Cpu\";\n};\n\nexport const WorkPoolTypeBadge = ({ type }: WorkPoolTypeBadgeProps) => {\n\treturn (\n\t\t<Badge>\n\t\t\t<Icon id={getWorkPoolTypeIcon(type)} />\n\t\t\t{getWorkPoolTypeLabel(type)}\n\t\t</Badge>\n\t);\n};\n","import { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { useDeleteWorkPool } from \"@/api/work-pools\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { StatusBadge } from \"@/components/ui/status-badge\";\nimport { WorkPoolContextMenu } from \"./components/work-pool-context-menu\";\nimport { WorkPoolName } from \"./components/work-pool-name\";\nimport { WorkPoolPauseResumeToggle } from \"./components/work-pool-pause-resume-toggle\";\nimport { WorkPoolTypeBadge } from \"./components/work-pool-type-badge\";\n\ntype WorkPoolCardProps = {\n\tworkPool: WorkPool;\n};\n\nexport const WorkPoolCard = ({ workPool }: WorkPoolCardProps) => {\n\tconst { deleteWorkPool } = useDeleteWorkPool();\n\n\tconst handleDelete = () => {\n\t\tdeleteWorkPool(workPool.name, {\n\t\t\tonSuccess: () => {\n\t\t\t\ttoast.success(`${workPool.name} deleted`);\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\ttoast.error(\n\t\t\t\t\t`Failed to delete work pool: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n\treturn (\n\t\t<Card className=\"gap-2\">\n\t\t\t<CardHeader className=\"flex flex-row items-center justify-between\">\n\t\t\t\t<CardTitle className=\"flex items-center gap-2\">\n\t\t\t\t\t<WorkPoolName workPoolName={workPool.name} />\n\t\t\t\t\t{workPool.status && <StatusBadge status={workPool.status} />}\n\t\t\t\t</CardTitle>\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<WorkPoolPauseResumeToggle workPool={workPool} />\n\t\t\t\t\t<WorkPoolContextMenu workPool={workPool} onDelete={handleDelete} />\n\t\t\t\t</div>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex flex-col gap-1\">\n\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t<WorkPoolTypeBadge type={workPool.type} />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"text-sm text-muted-foreground\">\n\t\t\t\t\tConcurrency:{\" \"}\n\t\t\t\t\t<span className=\"text-foreground\">\n\t\t\t\t\t\t{workPool.concurrency_limit\n\t\t\t\t\t\t\t? workPool.concurrency_limit\n\t\t\t\t\t\t\t: \"Unlimited\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useMemo, useState } from \"react\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport {\n\tbuildCountWorkPoolsQuery,\n\tbuildFilterWorkPoolsQuery,\n} from \"@/api/work-pools\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\nimport { WorkPoolsEmptyState } from \"@/components/work-pools/empty-state\";\nimport { WorkPoolsPageHeader } from \"@/components/work-pools/header\";\nimport { WorkPoolCard } from \"@/components/work-pools/work-pool-card/work-pool-card\";\nimport { pluralize } from \"@/utils\";\n\nfunction WorkPoolsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load work pools\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/work-pools/\")({\n\tcomponent: RouteComponent,\n\terrorComponent: WorkPoolsErrorComponent,\n\tloader: ({ context }) => {\n\t\tvoid context.queryClient.ensureQueryData(buildCountWorkPoolsQuery());\n\t\tvoid context.queryClient.ensureQueryData(\n\t\t\tbuildFilterWorkPoolsQuery({\n\t\t\t\tlimit: 200,\n\t\t\t\toffset: 0,\n\t\t\t}),\n\t\t);\n\t},\n\twrapInSuspense: true,\n});\n\nfunction RouteComponent() {\n\tconst [searchTerm, setSearchTerm] = useState(\"\");\n\n\tconst { data: workPoolCount = 0 } = useSuspenseQuery(\n\t\tbuildCountWorkPoolsQuery(),\n\t);\n\n\tconst { data: workPools = [] } = useSuspenseQuery(\n\t\tbuildFilterWorkPoolsQuery({\n\t\t\tlimit: 200,\n\t\t\toffset: 0,\n\t\t}),\n\t);\n\n\tconst filteredWorkPools = useMemo(() => {\n\t\treturn workPools.filter((workPool) =>\n\t\t\t[\n\t\t\t\tworkPool.name,\n\t\t\t\tworkPool.description,\n\t\t\t\tworkPool.type,\n\t\t\t\tJSON.stringify(workPool.base_job_template),\n\t\t\t\tworkPool.id,\n\t\t\t\tworkPool.default_queue_id,\n\t\t\t\tworkPool.status,\n\t\t\t]\n\t\t\t\t.join(\" \")\n\t\t\t\t.toLowerCase()\n\t\t\t\t.includes(searchTerm.toLowerCase()),\n\t\t);\n\t}, [workPools, searchTerm]);\n\n\tconst handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n\t\tsetSearchTerm(event.target.value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t{workPoolCount < 1 ? (\n\t\t\t\t<WorkPoolsEmptyState />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"flex items-end justify-between\">\n\t\t\t\t\t\t<div className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t{workPoolCount} {pluralize(workPoolCount, \"work pool\")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex gap-2\">\n\t\t\t\t\t\t\t<SearchInput\n\t\t\t\t\t\t\t\tplaceholder=\"Search work pools...\"\n\t\t\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\t\t\tonChange={handleSearchChange}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t{filteredWorkPools.map((workPool) => (\n\t\t\t\t\t\t\t<WorkPoolCard key={workPool.id} workPool={workPool} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"names":["WorkPoolsEmptyState","jsxs","EmptyState","jsx","EmptyStateIcon","EmptyStateTitle","EmptyStateDescription","EmptyStateActions","Link","Button","Icon","DocsLink","WorkPoolContextMenu","workPool","onDelete","handleCopyId","id","toast","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","DropdownMenuItem","WorkPoolName","workPoolName","WorkPoolIconText","WorkPoolPauseResumeToggle","isPaused","setIsPaused","useState","pauseWorkPool","isPausing","usePauseWorkPool","resumeWorkPool","isResuming","useResumeWorkPool","disabled","useMemo","handleTogglePause","Switch","WORK_POOL_TYPE_LABELS","WORK_POOL_TYPE_ICONS","getWorkPoolTypeLabel","type","getWorkPoolTypeIcon","WorkPoolTypeBadge","Badge","WorkPoolCard","deleteWorkPool","useDeleteWorkPool","handleDelete","error","Card","CardHeader","CardTitle","StatusBadge","CardContent","RouteComponent","searchTerm","setSearchTerm","data","workPoolCount","useSuspenseQuery","buildCountWorkPoolsQuery","workPools","buildFilterWorkPoolsQuery","limit","offset","filteredWorkPools","filter","name","description","JSON","stringify","base_job_template","default_queue_id","status","join","toLowerCase","includes","handleSearchChange","event","target","value","WorkPoolsPageHeader","Fragment","pluralize","SearchInput","map"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CRDz4nhM.js","sources":["../../src/components/work-pools/empty-state.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-context-menu.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-name.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-pause-resume-toggle.tsx","../../src/components/work-pools/work-pool-card/components/work-pool-type-badge.tsx","../../src/components/work-pools/work-pool-card/work-pool-card.tsx","../../src/routes/work-pools/index.tsx?tsr-split=component"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { Button } from \"@/components/ui/button\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport {\n\tEmptyState,\n\tEmptyStateActions,\n\tEmptyStateDescription,\n\tEmptyStateIcon,\n\tEmptyStateTitle,\n} from \"@/components/ui/empty-state\";\nimport { Icon } from \"@/components/ui/icons\";\n\nexport const WorkPoolsEmptyState = () => (\n\t<EmptyState>\n\t\t<EmptyStateIcon id=\"Cpu\" />\n\t\t<EmptyStateTitle>Add a work pool to get started</EmptyStateTitle>\n\t\t<EmptyStateDescription>\n\t\t\tWork pools allow you to prioritize and manage deployments and control the\n\t\t\tinfrastructure they run on.\n\t\t</EmptyStateDescription>\n\t\t<EmptyStateActions>\n\t\t\t<Link to=\"/work-pools/create\">\n\t\t\t\t<Button>\n\t\t\t\t\tAdd Work Pool <Icon id=\"Plus\" className=\"size-4 ml-2\" />\n\t\t\t\t</Button>\n\t\t\t</Link>\n\t\t\t<DocsLink id=\"work-pools-guide\" />\n\t\t</EmptyStateActions>\n\t</EmptyState>\n);\n","import { Link } from \"@tanstack/react-router\";\nimport { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuLabel,\n\tDropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Icon } from \"@/components/ui/icons\";\n\nexport type WorkPoolContextMenuProps = {\n\tworkPool: WorkPool;\n\tonDelete: () => void;\n};\n\nexport const WorkPoolContextMenu = ({\n\tworkPool,\n\tonDelete,\n}: WorkPoolContextMenuProps) => {\n\tconst handleCopyId = (id: string) => {\n\t\tvoid navigator.clipboard.writeText(id);\n\t\ttoast.success(\"ID copied\");\n\t};\n\n\treturn (\n\t\t<DropdownMenu>\n\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t<Button variant=\"outline\" className=\"size-8 p-0\">\n\t\t\t\t\t<span className=\"sr-only\">Open menu</span>\n\t\t\t\t\t<Icon id=\"MoreVertical\" className=\"size-4\" />\n\t\t\t\t</Button>\n\t\t\t</DropdownMenuTrigger>\n\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t<DropdownMenuLabel>Actions</DropdownMenuLabel>\n\t\t\t\t<DropdownMenuItem onClick={() => handleCopyId(workPool.id)}>\n\t\t\t\t\tCopy ID\n\t\t\t\t</DropdownMenuItem>\n\t\t\t\t<Link\n\t\t\t\t\tto=\"/work-pools/work-pool/$workPoolName/edit\"\n\t\t\t\t\tparams={{ workPoolName: workPool.name }}\n\t\t\t\t>\n\t\t\t\t\t<DropdownMenuItem>Edit</DropdownMenuItem>\n\t\t\t\t</Link>\n\t\t\t\t<DropdownMenuItem onClick={onDelete}>Delete</DropdownMenuItem>\n\t\t\t</DropdownMenuContent>\n\t\t</DropdownMenu>\n\t);\n};\n","import { WorkPoolIconText } from \"@/components/work-pools/work-pool-icon-text\";\n\ntype WorkPoolNameProps = {\n\tworkPoolName: string;\n};\n\nexport const WorkPoolName = ({ workPoolName }: WorkPoolNameProps) => {\n\treturn <WorkPoolIconText workPoolName={workPoolName} />;\n};\n","import { useMemo, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { usePauseWorkPool, useResumeWorkPool } from \"@/api/work-pools\";\nimport { Switch } from \"@/components/ui/switch\";\nexport type WorkPoolPauseResumeToggleParams = {\n\tworkPool: WorkPool;\n};\n\nexport const WorkPoolPauseResumeToggle = ({\n\tworkPool,\n}: WorkPoolPauseResumeToggleParams) => {\n\tconst [isPaused, setIsPaused] = useState(workPool.status === \"PAUSED\");\n\n\tconst { pauseWorkPool, isPending: isPausing } = usePauseWorkPool();\n\tconst { resumeWorkPool, isPending: isResuming } = useResumeWorkPool();\n\n\tconst disabled = useMemo(() => {\n\t\treturn isPausing || isResuming;\n\t}, [isPausing, isResuming]);\n\n\tconst handleTogglePause = () => {\n\t\tif (isPaused) {\n\t\t\tresumeWorkPool(workPool.name, {\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tsetIsPaused(false);\n\t\t\t\t\ttoast.success(`${workPool.name} resumed`);\n\t\t\t\t},\n\t\t\t\tonError: () => {\n\t\t\t\t\ttoast.error(`Failed to resume ${workPool.name}`);\n\t\t\t\t},\n\t\t\t});\n\t\t} else {\n\t\t\tpauseWorkPool(workPool.name, {\n\t\t\t\tonSuccess: () => {\n\t\t\t\t\tsetIsPaused(true);\n\t\t\t\t\ttoast.success(`${workPool.name} paused`);\n\t\t\t\t},\n\t\t\t\tonError: () => {\n\t\t\t\t\ttoast.error(`Failed to pause ${workPool.name}`);\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t};\n\n\treturn (\n\t\t<span className=\"flex items-center gap-2\">\n\t\t\t<span className=\"text-sm text-muted-foreground\">\n\t\t\t\t{isPaused ? \"Paused\" : \"Active\"}\n\t\t\t</span>\n\t\t\t<Switch\n\t\t\t\tchecked={!isPaused}\n\t\t\t\tonCheckedChange={handleTogglePause}\n\t\t\t\tdisabled={disabled}\n\t\t\t\taria-label={isPaused ? \"Resume work pool\" : \"Pause work pool\"}\n\t\t\t/>\n\t\t</span>\n\t);\n};\n","import type { WorkPool } from \"@/api/work-pools\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Icon, type IconId } from \"@/components/ui/icons\";\n\ntype WorkPoolTypeBadgeProps = {\n\ttype: WorkPool[\"type\"];\n};\n\nconst WORK_POOL_TYPE_LABELS: Record<WorkPool[\"type\"], string> = {\n\tprocess: \"Process\",\n\tecs: \"ECS\",\n\t\"azure-container-instance\": \"Azure Container Instance\",\n\tdocker: \"Docker\",\n\t\"cloud-run\": \"Cloud Run\",\n\t\"cloud-run-v2\": \"Cloud Run v2\",\n\t\"vertex-ai\": \"Vertex AI\",\n\tkubernetes: \"Kubernetes\",\n} as const;\n\nconst WORK_POOL_TYPE_ICONS: Record<WorkPool[\"type\"], IconId> = {\n\tprocess: \"Cpu\",\n\tecs: \"Cpu\",\n\t\"azure-container-instance\": \"Cpu\",\n\tdocker: \"Cpu\",\n\t\"cloud-run\": \"Cpu\",\n\t\"cloud-run-v2\": \"Cpu\",\n\t\"vertex-ai\": \"Cpu\",\n\tkubernetes: \"Cpu\",\n} as const;\n\nconst getWorkPoolTypeLabel = (type: WorkPool[\"type\"]) => {\n\treturn WORK_POOL_TYPE_LABELS[type] ?? type;\n};\n\nconst getWorkPoolTypeIcon = (type: WorkPool[\"type\"]) => {\n\treturn WORK_POOL_TYPE_ICONS[type] ?? \"Cpu\";\n};\n\nexport const WorkPoolTypeBadge = ({ type }: WorkPoolTypeBadgeProps) => {\n\treturn (\n\t\t<Badge>\n\t\t\t<Icon id={getWorkPoolTypeIcon(type)} />\n\t\t\t{getWorkPoolTypeLabel(type)}\n\t\t</Badge>\n\t);\n};\n","import { toast } from \"sonner\";\nimport type { WorkPool } from \"@/api/work-pools\";\nimport { useDeleteWorkPool } from \"@/api/work-pools\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport { StatusBadge } from \"@/components/ui/status-badge\";\nimport { WorkPoolContextMenu } from \"./components/work-pool-context-menu\";\nimport { WorkPoolName } from \"./components/work-pool-name\";\nimport { WorkPoolPauseResumeToggle } from \"./components/work-pool-pause-resume-toggle\";\nimport { WorkPoolTypeBadge } from \"./components/work-pool-type-badge\";\n\ntype WorkPoolCardProps = {\n\tworkPool: WorkPool;\n};\n\nexport const WorkPoolCard = ({ workPool }: WorkPoolCardProps) => {\n\tconst { deleteWorkPool } = useDeleteWorkPool();\n\n\tconst handleDelete = () => {\n\t\tdeleteWorkPool(workPool.name, {\n\t\t\tonSuccess: () => {\n\t\t\t\ttoast.success(`${workPool.name} deleted`);\n\t\t\t},\n\t\t\tonError: (error) => {\n\t\t\t\ttoast.error(\n\t\t\t\t\t`Failed to delete work pool: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t\t\t);\n\t\t\t},\n\t\t});\n\t};\n\treturn (\n\t\t<Card className=\"gap-2\">\n\t\t\t<CardHeader className=\"flex flex-row items-center justify-between\">\n\t\t\t\t<CardTitle className=\"flex items-center gap-2\">\n\t\t\t\t\t<WorkPoolName workPoolName={workPool.name} />\n\t\t\t\t\t{workPool.status && <StatusBadge status={workPool.status} />}\n\t\t\t\t</CardTitle>\n\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t<WorkPoolPauseResumeToggle workPool={workPool} />\n\t\t\t\t\t<WorkPoolContextMenu workPool={workPool} onDelete={handleDelete} />\n\t\t\t\t</div>\n\t\t\t</CardHeader>\n\t\t\t<CardContent className=\"flex flex-col gap-1\">\n\t\t\t\t<div className=\"flex items-center gap-1\">\n\t\t\t\t\t<WorkPoolTypeBadge type={workPool.type} />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"text-sm text-muted-foreground\">\n\t\t\t\t\tConcurrency:{\" \"}\n\t\t\t\t\t<span className=\"text-foreground\">\n\t\t\t\t\t\t{workPool.concurrency_limit\n\t\t\t\t\t\t\t? workPool.concurrency_limit\n\t\t\t\t\t\t\t: \"Unlimited\"}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</CardContent>\n\t\t</Card>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport type { ErrorComponentProps } from \"@tanstack/react-router\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { useMemo, useState } from \"react\";\nimport { categorizeError } from \"@/api/error-utils\";\nimport {\n\tbuildCountWorkPoolsQuery,\n\tbuildFilterWorkPoolsQuery,\n} from \"@/api/work-pools\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport { RouteErrorState } from \"@/components/ui/route-error-state\";\nimport { WorkPoolsEmptyState } from \"@/components/work-pools/empty-state\";\nimport { WorkPoolsPageHeader } from \"@/components/work-pools/header\";\nimport { WorkPoolCard } from \"@/components/work-pools/work-pool-card/work-pool-card\";\nimport { pluralize } from \"@/utils\";\n\nfunction WorkPoolsErrorComponent({ error, reset }: ErrorComponentProps) {\n\tconst serverError = categorizeError(error, \"Failed to load work pools\");\n\n\t// Only handle API errors (server-error, client-error) at route level\n\t// Let network errors and unknown errors bubble up to root error component\n\tif (\n\t\tserverError.type !== \"server-error\" &&\n\t\tserverError.type !== \"client-error\"\n\t) {\n\t\tthrow error;\n\t}\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t<RouteErrorState error={serverError} onRetry={reset} />\n\t\t</div>\n\t);\n}\n\nexport const Route = createFileRoute(\"/work-pools/\")({\n\tcomponent: RouteComponent,\n\terrorComponent: WorkPoolsErrorComponent,\n\tloader: ({ context }) => {\n\t\tvoid context.queryClient.ensureQueryData(buildCountWorkPoolsQuery());\n\t\tvoid context.queryClient.ensureQueryData(\n\t\t\tbuildFilterWorkPoolsQuery({\n\t\t\t\tlimit: 200,\n\t\t\t\toffset: 0,\n\t\t\t}),\n\t\t);\n\t},\n\twrapInSuspense: true,\n});\n\nfunction RouteComponent() {\n\tconst [searchTerm, setSearchTerm] = useState(\"\");\n\n\tconst { data: workPoolCount = 0 } = useSuspenseQuery(\n\t\tbuildCountWorkPoolsQuery(),\n\t);\n\n\tconst { data: workPools = [] } = useSuspenseQuery(\n\t\tbuildFilterWorkPoolsQuery({\n\t\t\tlimit: 200,\n\t\t\toffset: 0,\n\t\t}),\n\t);\n\n\tconst filteredWorkPools = useMemo(() => {\n\t\treturn workPools.filter((workPool) =>\n\t\t\t[\n\t\t\t\tworkPool.name,\n\t\t\t\tworkPool.description,\n\t\t\t\tworkPool.type,\n\t\t\t\tJSON.stringify(workPool.base_job_template),\n\t\t\t\tworkPool.id,\n\t\t\t\tworkPool.default_queue_id,\n\t\t\t\tworkPool.status,\n\t\t\t]\n\t\t\t\t.join(\" \")\n\t\t\t\t.toLowerCase()\n\t\t\t\t.includes(searchTerm.toLowerCase()),\n\t\t);\n\t}, [workPools, searchTerm]);\n\n\tconst handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n\t\tsetSearchTerm(event.target.value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<WorkPoolsPageHeader />\n\t\t\t{workPoolCount < 1 ? (\n\t\t\t\t<WorkPoolsEmptyState />\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"flex items-end justify-between\">\n\t\t\t\t\t\t<div className=\"text-sm text-muted-foreground\">\n\t\t\t\t\t\t\t{workPoolCount} {pluralize(workPoolCount, \"work pool\")}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"flex gap-2\">\n\t\t\t\t\t\t\t<SearchInput\n\t\t\t\t\t\t\t\tplaceholder=\"Search work pools...\"\n\t\t\t\t\t\t\t\tvalue={searchTerm}\n\t\t\t\t\t\t\t\tonChange={handleSearchChange}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t\t\t{filteredWorkPools.map((workPool) => (\n\t\t\t\t\t\t\t<WorkPoolCard key={workPool.id} workPool={workPool} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"names":["WorkPoolsEmptyState","jsxs","EmptyState","jsx","EmptyStateIcon","EmptyStateTitle","EmptyStateDescription","EmptyStateActions","Link","Button","Icon","DocsLink","WorkPoolContextMenu","workPool","onDelete","handleCopyId","id","toast","DropdownMenu","DropdownMenuTrigger","DropdownMenuContent","DropdownMenuLabel","DropdownMenuItem","WorkPoolName","workPoolName","WorkPoolIconText","WorkPoolPauseResumeToggle","isPaused","setIsPaused","useState","pauseWorkPool","isPausing","usePauseWorkPool","resumeWorkPool","isResuming","useResumeWorkPool","disabled","useMemo","handleTogglePause","Switch","WORK_POOL_TYPE_LABELS","WORK_POOL_TYPE_ICONS","getWorkPoolTypeLabel","type","getWorkPoolTypeIcon","WorkPoolTypeBadge","Badge","WorkPoolCard","deleteWorkPool","useDeleteWorkPool","handleDelete","error","Card","CardHeader","CardTitle","StatusBadge","CardContent","RouteComponent","searchTerm","setSearchTerm","data","workPoolCount","useSuspenseQuery","buildCountWorkPoolsQuery","workPools","buildFilterWorkPoolsQuery","limit","offset","filteredWorkPools","filter","name","description","JSON","stringify","base_job_template","default_queue_id","status","join","toLowerCase","includes","handleSearchChange","event","target","value","WorkPoolsPageHeader","Fragment","pluralize","SearchInput","map"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as l,j as s,s as E,L as Me,F as $e,m as ot,E as rt}from"./vendor-tanstack-BK8oseNA.js";import{a8 as Ye,a9 as lt,aa as it,ab as be,ac as ct,ad as ut,ae as dt,af as mt,ag as ft,ah as gt,ai as ht,aj as Ee,ak as oe,al as re,am as pt,y as ee,N as qe,q as le,I as V,an as xt,ao as wt,ap as St,aq as vt,ar as kt,as as yt,at as Ft,_ as jt,$ as Ct,a0 as Rt,a1 as bt,a2 as Tt,p as Dt,a3 as _t,au as ie,av as Nt,i as O,aw as Mt,ax as Et,ay as Ae,az as Pe,C as At,o as Pt,G as It,O as Ie,B as Lt,g as zt,h as Ot,E as Vt,t as Ht,v as Wt,w as Bt,x as Ut,D as Qt,aA as Ge,aB as j,aC as $t,aD as Yt,aE as Le,aF as ze,aG as qt,aH as Oe,aI as Gt,aJ as Xt,aK as Kt,aL as Jt}from"./index-D5RdrxkU.js";import{D as Zt,W as es}from"./work-pool-filter-Ddhp_M-L.js";import{S as ts}from"./sort-filter-DHPFdKZ2.js";import{S as ss,F as as,a as ns}from"./flow-runs-pagination-Bq2ZUzM6.js";import{u as os,F as rs}from"./use-flow-runs-selected-rows-DfwmswyR.js";import{D as Xe}from"./delete-confirmation-dialog-CqKsUEj_.js";import{D as ls,a as is,b as cs,d as te,e as us}from"./dropdown-menu-e0Fqb6aw.js";import{g as ds,S as ms}from"./state-colors-CAAf0Eg3.js";import{R as fs,S as gs,X as hs,Y as ps,T as xs,d as ws}from"./vendor-recharts-D4imLXNl.js";import{c as Ss}from"./vendor-date-7GxEwcQM.js";import{T as vs,a as ks,b as ys}from"./task-runs-pagination-B7D5K_FM.js";import{u as Fs}from"./use-delete-confirmation-dialog-CvQEyyhU.js";import{T as js}from"./tags-input-BLzMOTDb.js";import{a as Cs}from"./zod-DgSl2Nua.js";import{c as Rs,o as Ke,s as _,e as se,n as ae,b as bs}from"./vendor-forms-DxqqmhL5.js";import{F as Ts,b as Ds,c as _s,d as Ns,e as Ms,a as Es}from"./form-DNerk3LS.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-CznP1SOq.js";const As=({value:e,onValueChange:t,className:n})=>{const a=l.useMemo(()=>Ye(e),[e]),o=i=>{t(it(i))};return s.jsx(lt,{value:a,onValueChange:o,placeholder:"All time",clearable:!0,className:n})},Ve=2,Ps=({selectedFlows:e,onSelectFlows:t})=>{const[n,a]=l.useState(""),o=l.useDeferredValue(n),{data:i=[]}=E(be({flows:o?{operator:"and_",name:{like_:o}}:void 0,limit:100,offset:0,sort:"NAME_ASC"})),{data:r=[]}=E(be({flows:e.size>0?{operator:"and_",id:{any_:Array.from(e)}}:void 0,limit:e.size||1,offset:0,sort:"NAME_ASC"},{enabled:e.size>0})),u=m=>{const h=new Set(e);e.has(m)?h.delete(m):h.add(m),t(h)},c=()=>{t(new Set)},d=()=>{if(e.size===0)return"All flows";const m=r.filter(S=>e.has(S.id)).map(S=>S.name),h=m.slice(0,Ve),x=m.length-Ve;return s.jsxs("div",{className:"flex flex-1 min-w-0 items-center gap-2",children:[s.jsx("div",{className:"flex flex-1 min-w-0 items-center gap-2 overflow-hidden",children:s.jsx("span",{className:"truncate",children:h.join(", ")})}),x>0&&s.jsxs(re,{variant:"bodySmall",className:"shrink-0",children:["+ ",x]})]})},f=l.useMemo(()=>i.filter(m=>!o||m.name.toLowerCase().includes(o.toLowerCase())),[i,o]);return s.jsxs(ct,{children:[s.jsx(ut,{"aria-label":"Filter by flow",selected:e.size===0,children:d()}),s.jsxs(dt,{children:[s.jsx(mt,{value:n,onValueChange:a,placeholder:"Search flows..."}),s.jsxs(ft,{children:[s.jsx(gt,{children:"No flows found"}),s.jsxs(ht,{children:[s.jsxs(Ee,{"aria-label":"All flows",onSelect:c,closeOnSelect:!1,value:"__all__",children:[s.jsx(oe,{checked:e.size===0}),"All flows"]}),f.map(m=>s.jsxs(Ee,{"aria-label":m.name,onSelect:()=>u(m.id),closeOnSelect:!1,value:m.id,children:[s.jsx(oe,{checked:e.has(m.id)}),m.name]},m.id))]})]})]})]})},Is=()=>{const[e,t]=Fs(),{mutateAsync:n}=pt(),a=async(i,r=()=>{})=>{try{const u=await Promise.allSettled(i.map(f=>n({id:f}))),{numFails:c,numSuccess:d}=u.reduce((f,m)=>(m.status==="rejected"?f.numFails+=1:f.numSuccess+=1,f),{numFails:0,numSuccess:0});c>1?ee.error(`${c} task runs failed to delete`):c===1?ee.error("Task run failed to delete"):d>1?ee.success(`${d} task runs deleted`):ee.success("Task run deleted")}catch(u){console.error("Unknown error while deleting task run.",u)}finally{r()}};return[e,(i,r=()=>{})=>t({title:"Delete Task Runs",description:"Are you sure you want to delete selected task runs?",onConfirm:()=>{a(i,r)}})]},Ls=({count:e=0,...t})=>"results"in t&&"setSelectedRows"in t&&"selectedRows"in t?s.jsx(zs,{count:e,...t}):s.jsxs(re,{variant:"bodySmall",className:"text-muted-foreground",children:[e," ",qe(e,"Task run")]});function zs({count:e=0,results:t=[],setSelectedRows:n,selectedRows:a}){const[o,i]=Is(),r=l.useMemo(()=>t.map(({id:d})=>d),[t]),u=Array.from(a),c=()=>{const d=r.every(h=>a.has(h)),f=r.some(h=>a.has(h));let m=!1;return d?m=!0:f&&(m="indeterminate"),s.jsx(oe,{className:"block",checked:m,onCheckedChange:h=>{n(h?new Set(r):new Set)},"aria-label":"Toggle all"})};return a.size>0?s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"flex items-center gap-2",children:[s.jsx(c,{}),s.jsxs(re,{variant:"bodySmall",className:"text-muted-foreground",children:[u.length," selected"]}),s.jsx(le,{"aria-label":"Delete rows",size:"icon",variant:"secondary",onClick:()=>{i(u,()=>n(new Set))},children:s.jsx(V,{id:"Trash2",className:"size-4"})})]}),s.jsx(Xe,{...o})]}):s.jsxs("div",{className:"flex items-center gap-2",children:[t&&n&&a&&s.jsx(oe,{className:"block",checked:!1,onCheckedChange:d=>{n(new Set(d?r:void 0))},"aria-label":"Toggle all"}),s.jsxs(re,{variant:"bodySmall",className:"text-muted-foreground",children:[e," ",qe(e,"Task run")]})]})}const Os=e=>{const[t,n]=l.useState(new Set(e)),a=c=>n(d=>new Set(d).add(c)),o=c=>n(d=>{const f=new Set(d);return f.delete(c),f});return[t,n,{addRow:a,removeRow:o,onSelectRow:(c,d)=>{d?a(c):o(c)},clearSet:()=>n(new Set)}]},Je="Custom",Vs="Unsaved";function Hs(e){return e?e.name===Je||e.name===Vs:!0}const Ws=({currentFilter:e,savedFilters:t,onSelect:n,onSave:a,onDelete:o,onSetDefault:i,onRemoveDefault:r,permissions:u={canSave:!0,canDelete:!0}})=>{const[c,d]=l.useState(!1),f=e?.name??Je,m=Hs(e),h=m&&u.canSave,x=e?.id&&u.canDelete,S=!m,y=()=>{e?.id&&(o(e.id),d(!1))},g=()=>{e?.id&&(e.isDefault?r(e.id):i(e.id))};return s.jsxs(s.Fragment,{children:[s.jsxs(ls,{children:[s.jsx(is,{asChild:!0,children:s.jsxs(le,{variant:"outline",className:"gap-2",children:[s.jsx(V,{id:"SlidersVertical",className:"size-4"}),s.jsx("span",{children:f}),s.jsx(V,{id:"ChevronDown",className:"size-4"})]})}),s.jsxs(cs,{align:"start",className:"min-w-[200px]",children:[t.map(p=>s.jsxs(te,{onClick:()=>n(p),className:"flex items-center justify-between",children:[s.jsx("span",{children:p.name}),p.isDefault&&s.jsx(V,{id:"CircleCheck",className:"size-4 text-green-500"})]},p.id??p.name)),(h||x||S)&&s.jsx(us,{}),h&&s.jsxs(te,{onClick:a,children:[s.jsx(V,{id:"Plus",className:"mr-2 size-4"}),"Save current filters"]}),x&&s.jsxs(te,{variant:"destructive",onClick:()=>d(!0),children:[s.jsx(V,{id:"Trash2",className:"mr-2 size-4"}),"Delete"]}),S&&s.jsxs(te,{onClick:g,children:[s.jsx(V,{id:"CircleCheck",className:"mr-2 size-4"}),e?.isDefault?"Remove as default":"Set as default"]})]})]}),s.jsx(Xe,{isOpen:c,title:"Delete saved filter",description:`Are you sure you want to delete "${e?.name}"? This action cannot be undone.`,onConfirm:y,onClose:()=>d(!1)})]})},Bs=({cx:e,cy:t,payload:n})=>{if(e===void 0||t===void 0||!n)return null;const a=ds(n.stateType)||ms[n.stateType]||"#6b7280";return s.jsx("circle",{cx:e,cy:t,r:6,fill:a,stroke:a,strokeWidth:1,opacity:.7,className:"hover:opacity-100 transition-opacity cursor-pointer"})},Us=({active:e,payload:t})=>{const a=t?.[0]?.payload,o=a?.id,{data:i}=E({...xt(o??""),enabled:e&&!!o,staleTime:300*1e3}),{data:r}=E({...wt(i?.flow_id??""),enabled:!!i?.flow_id,staleTime:300*1e3});if(!e||!t||t.length===0||!a)return null;const u=new Date(a.timestamp);return s.jsxs("div",{className:"bg-background border rounded-lg p-3 shadow-lg flex flex-col gap-2 min-w-48",children:[s.jsxs("div",{className:"flex items-center gap-1 text-sm text-muted-foreground",children:[i?.flow_id&&s.jsxs(s.Fragment,{children:[s.jsx(Me,{to:"/flows/flow/$id",params:{id:i.flow_id},className:"font-semibold hover:underline truncate max-w-32",children:r?.name??"..."}),s.jsx(St,{className:"size-3 flex-shrink-0"})]}),s.jsx(Me,{to:"/runs/flow-run/$id",params:{id:a.id},className:"hover:underline truncate max-w-32",children:i?.name??a.id.slice(0,8)})]}),s.jsx("div",{children:s.jsx(vt,{type:a.stateType})}),s.jsx("hr",{className:"border-border"}),s.jsxs("div",{className:"flex flex-col gap-1",children:[s.jsxs("span",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[s.jsx(yt,{className:"size-4"}),kt(Math.ceil(a.duration*1e3),{largest:2,round:!0})]}),s.jsxs("span",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:[s.jsx(Ft,{className:"size-4"}),u.toLocaleString()]})]})]})},Qs=e=>t=>t===0?"0s":e<1?`${Math.round(t*1e3)}ms`:e<10?`${t.toFixed(1)}s`:e<60?`${Math.round(t)}s`:Ss(0,t*1e3,{addSuffix:!1}),$s=(e,t)=>i=>{const r=new Date(i);if(t<1e3||e<1e4){const u=r.getSeconds(),c=r.getMilliseconds();return`${r.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})}:${u.toString().padStart(2,"0")}.${Math.floor(c/100)}`}return t<6e4||e<10*6e4?r.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:"2-digit"}):e>=864e5?r.getHours()===0&&r.getMinutes()===0&&r.getSeconds()===0&&r.getMilliseconds()===0?r.toLocaleDateString(void 0,{weekday:"short",day:"numeric"}):r.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):r.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"})},Ys=({history:e,startDate:t,endDate:n})=>{const a=l.useRef(null),[o,i]=l.useState(0);l.useEffect(()=>{const g=a.current;if(!g)return;const p=new ResizeObserver(w=>{for(const k of w)i(k.contentRect.width)});return p.observe(g),i(g.getBoundingClientRect().width),()=>p.disconnect()},[]);const r=l.useMemo(()=>e.map(g=>({x:new Date(g.timestamp).getTime(),y:g.duration,stateType:g.state_type,id:g.id,duration:g.duration,lateness:g.lateness,timestamp:g.timestamp})),[e]),{xDomain:u,xDomainMin:c,xDomainMax:d}=l.useMemo(()=>{if(t&&n)return{xDomain:[t.getTime(),n.getTime()],xDomainMin:t.getTime(),xDomainMax:n.getTime()};if(r.length===0){const k=Date.now(),b=k-1440*60*1e3;return{xDomain:[b,k],xDomainMin:b,xDomainMax:k}}const g=r.map(k=>k.x),p=Math.min(...g),w=Math.max(...g);return{xDomain:[p,w],xDomainMin:p,xDomainMax:w}},[t,n,r]),f=l.useMemo(()=>r.length===0?60:Math.max(...r.map(g=>g.y)),[r]),m=l.useMemo(()=>{if(r.length<2)return Number.POSITIVE_INFINITY;const g=r.map(w=>w.x).sort((w,k)=>w-k);let p=Number.POSITIVE_INFINITY;for(let w=1;w<g.length;w++){const k=g[w]-g[w-1];k>0&&k<p&&(p=k)}return p},[r]),h=d-c,x=l.useMemo(()=>$s(h,m),[h,m]),S=l.useMemo(()=>Qs(f),[f]),y=l.useMemo(()=>{const w=o-60,k=Math.max(2,Math.ceil(w/100)),b=1440*60*1e3,F=d-c;if(F>=b){const v=[],W=new Date(c),H=new Date(W);H.setHours(24,0,0,0),v.push(c);let P=H.getTime();for(;P<d;)v.push(P),P+=b;const B=v[v.length-1];if(d-B>F/k/2&&v.push(d),v.length<k){const M=[];for(let T=0;T<v.length-1;T++){M.push(v[T]);const I=v[T+1]-v[T],L=Math.max(1,Math.floor(I/(F/k)));if(L>1){const U=I/L;for(let z=1;z<L;z++)M.push(v[T]+U*z)}}return M.push(v[v.length-1]),M}return v}const N=[],A=(d-c)/(k-1);for(let v=0;v<k;v++)N.push(c+A*v);return N},[o,c,d]);return e.length===0?null:s.jsx("div",{ref:a,className:"hidden md:block w-full h-64","data-testid":"scatter-plot",children:s.jsx(fs,{width:"100%",height:"100%",children:s.jsxs(gs,{children:[s.jsx(hs,{type:"number",dataKey:"x",scale:"time",domain:u,ticks:y,tickFormatter:x,tick:{fontSize:12},tickLine:!1,axisLine:{stroke:"#e5e7eb"}}),s.jsx(ps,{type:"number",dataKey:"y",tickFormatter:S,tick:{fontSize:12},tickLine:!1,axisLine:{stroke:"#e5e7eb"},width:60}),s.jsx(xs,{content:s.jsx(Us,{}),cursor:{strokeDasharray:"3 3"},animationDuration:0}),s.jsx(ws,{data:r,shape:s.jsx(Bs,{}),isAnimationActive:!1})]})})})},qs=Ke({name:_().min(1,{message:"Name is required"}).max(100,{message:"Name must be 100 characters or less"})}),Gs=({open:e,onOpenChange:t,onSave:n})=>{const a=Rs({resolver:Cs(qs),defaultValues:{name:""}});l.useEffect(()=>{e&&a.reset({name:""})},[e,a]);const o=i=>{n(i.name),t(!1)};return s.jsx(jt,{open:e,onOpenChange:t,children:s.jsxs(Ct,{children:[s.jsx(Rt,{children:s.jsx(bt,{children:"Save Filter"})}),s.jsx(Tt,{children:"Save your current filter configuration for quick access later."}),s.jsx(Ts,{...a,children:s.jsxs("form",{onSubmit:i=>{a.handleSubmit(o)(i)},className:"space-y-4",children:[s.jsx(Ds,{control:a.control,name:"name",render:({field:i})=>s.jsxs(_s,{children:[s.jsx(Ns,{children:"Filter Name"}),s.jsx(Ms,{children:s.jsx(Dt,{autoComplete:"off",placeholder:"e.g., Failed runs this week",...i})}),s.jsx(Es,{})]})}),s.jsxs(_t,{children:[s.jsx(le,{type:"button",variant:"outline",onClick:()=>t(!1),children:"Cancel"}),s.jsx(le,{type:"submit",children:"Save"})]})]})})]})})},Xs="prefect-ui-v2-saved-filters",Ks="prefect-ui-v2-default-filter-id",Ze="system-past-week",et="system-hide-scheduled";function Js(e){return e===Ze||e===et}const tt=[{id:Ze,name:"Past week",filters:{range:"past-7-days"}},{id:et,name:"Hide scheduled runs",filters:{range:"past-7-days",state:[...Nt]}}],Zs=tt[0];function ea(){return`${Date.now()}-${Math.random().toString(36).substring(2,9)}`}function ta(e,t){const n=(a,o)=>{if(a===void 0&&o===void 0)return!0;if(a===void 0||o===void 0||a.length!==o.length)return!1;const i=[...a].sort(),r=[...o].sort();return i.every((u,c)=>u===r[c])};return n(e.state,t.state)&&n(e.flows,t.flows)&&n(e.deployments,t.deployments)&&n(e.workPools,t.workPools)&&n(e.tags,t.tags)&&e.range===t.range&&e.start===t.start&&e.end===t.end}function st(){const[e,t]=ie(Xs,[]),[n,a]=ie(Ks,null),o=l.useMemo(()=>[...tt,...e],[e]),i=l.useCallback(h=>{const x={id:ea(),name:h.name,filters:h.filters};return t(S=>[...S,x]),x},[t]),r=l.useCallback(h=>{t(x=>x.filter(S=>S.id!==h)),a(x=>x===h?null:x)},[t,a]),u=l.useCallback((h,x)=>{t(S=>S.map(y=>y.id===h?{...y,...x.name!==void 0&&{name:x.name},...x.filters!==void 0&&{filters:x.filters}}:y))},[t]),c=l.useCallback(h=>{a(h)},[a]),d=l.useCallback(h=>o.find(x=>x.id===h),[o]),f=l.useCallback(h=>o.find(x=>ta(x.filters,h)),[o]),m=l.useMemo(()=>h=>n===h,[n]);return{savedFilters:o,defaultFilterId:n,saveFilter:i,deleteFilter:r,updateFilter:u,setDefaultFilter:c,getFilterById:d,findMatchingFilter:f,isDefaultFilter:m}}const sa=({tab:e,onTabChange:t,flowRunsCount:n,taskRunsCount:a,hasAnyFlowRuns:o,hasAnyTaskRuns:i,flowRuns:r,flowRunsPages:u,pagination:c,onPaginationChange:d,onPrefetchPage:f,sort:m,onSortChange:h,hideSubflows:x,onHideSubflowsChange:S,flowRunSearch:y,onFlowRunSearchChange:g,selectedStates:p,onStateFilterChange:w,selectedFlows:k,onFlowFilterChange:b,selectedDeployments:F,onDeploymentFilterChange:N,selectedTags:A,onTagsFilterChange:v,selectedWorkPools:W,onWorkPoolFilterChange:H,dateRange:P,onDateRangeChange:B,flowRunHistory:M,scatterPlotDateRange:T,taskRuns:I,taskRunsPages:L,taskRunsPagination:U,onTaskRunsPaginationChange:z,onTaskRunsPrefetchPage:Q,taskRunsSort:de,onTaskRunsSortChange:me,taskRunSearch:fe,onTaskRunSearchChange:ge,onClearTaskRunFilters:he,currentFilter:X,savedFilters:pe,onSelectFilter:xe,onSaveFilter:we,onDeleteFilter:Se,onSetDefault:ve,onRemoveDefault:ke,isSaveDialogOpen:$,onCloseSaveDialog:Y,onConfirmSave:ye})=>{const q=!o&&!i,[K,Fe,{onSelectRow:je}]=os(),[J,Ce,{onSelectRow:C}]=Os(),D=[...new Set(r.map(R=>R.flow_id))],{data:Z}=E(be({flows:{operator:"and_",id:{any_:D}},offset:0,sort:"NAME_ASC"},{enabled:D.length>0})),G=r.map(R=>({...R,flow:Z?.find(Re=>Re.id===R.flow_id)}));return q?s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsx(He,{}),s.jsx(aa,{})]}):s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx(He,{}),s.jsx(Ws,{currentFilter:X,savedFilters:pe,onSelect:xe,onSave:we,onDelete:Se,onSetDefault:ve,onRemoveDefault:ke,permissions:{canSave:!0,canDelete:!Js(X?.id??null)}})]}),s.jsxs("div",{className:"flex flex-col gap-2",children:[s.jsxs("div",{className:"flex flex-wrap gap-2 lg:grid lg:grid-flow-col lg:auto-cols-fr",children:[s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"Date Range"}),s.jsx(As,{value:P,onValueChange:B})]}),s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"States"}),s.jsx(ss,{selectedFilters:p,onSelectFilter:w})]})]}),s.jsxs("div",{className:"flex flex-wrap gap-2 lg:grid lg:grid-flow-col lg:auto-cols-fr",children:[s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"Flows"}),s.jsx(Ps,{selectedFlows:k,onSelectFlows:b})]}),s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"Deployments"}),s.jsx(Zt,{selectedDeployments:F,onSelectDeployments:N})]}),s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"Work Pools"}),s.jsx(es,{selectedWorkPools:W,onSelectWorkPools:H})]}),s.jsxs("div",{className:"flex flex-col gap-1 w-full lg:w-auto",children:[s.jsx(O,{className:"text-xs text-muted-foreground",children:"Tags"}),s.jsx(js,{value:Array.from(A),onChange:R=>{const Re=Array.isArray(R)?R:[];v(new Set(Re))},placeholder:"All tags"})]})]})]}),s.jsx(Gs,{open:$,onOpenChange:Y,onSave:ye}),s.jsxs(Mt,{value:e,onValueChange:t,children:[s.jsxs(Et,{children:[s.jsx(Ae,{value:"flow-runs",children:"Flow Runs"}),s.jsx(Ae,{value:"task-runs",children:"Task Runs"})]}),s.jsx(Pe,{value:"flow-runs",children:s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsx(At,{children:s.jsx(Pt,{children:s.jsx(Ys,{history:M,startDate:T.startDate,endDate:T.endDate})})}),s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx(rs,{count:n,results:G,selectedRows:K,setSelectedRows:Fe}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsxs("div",{className:"flex items-center gap-2 whitespace-nowrap",children:[s.jsx(It,{id:"hide-subflows",checked:x,onCheckedChange:S}),s.jsx(O,{htmlFor:"hide-subflows",children:"Hide subflows"})]}),s.jsx(Ie,{value:y,onChange:R=>g(R.target.value),placeholder:"Search by flow run name","aria-label":"Search by flow run name",className:"w-64",debounceMs:1200}),s.jsx(ts,{value:m,onSelect:h})]})]}),s.jsx(as,{count:n,pages:u,pagination:c,onChangePagination:d,onPrefetchPage:f}),s.jsx(ns,{flowRuns:G,selectedRows:K,onSelect:je})]})}),s.jsx(Pe,{value:"task-runs",children:s.jsxs("div",{className:"flex flex-col gap-4",children:[s.jsxs("div",{className:"flex items-center justify-between",children:[s.jsx(Ls,{count:a,results:I,selectedRows:J,setSelectedRows:Ce}),s.jsxs("div",{className:"flex items-center gap-4",children:[s.jsx(Ie,{value:fe,onChange:R=>ge(R.target.value),placeholder:"Search by task run name","aria-label":"Search by task run name",className:"w-64",debounceMs:1200}),s.jsx(vs,{value:de,onSelect:me})]})]}),s.jsx(ks,{count:a,pages:L,pagination:U,onChangePagination:z,onPrefetchPage:Q}),s.jsx(ys,{taskRuns:I,selectedRows:J,onSelect:C,onClearFilters:he})]})})]})]})},He=()=>s.jsx("div",{className:"flex items-center gap-2",children:s.jsx(Lt,{children:s.jsx(zt,{children:s.jsx(Ot,{className:"text-xl font-semibold",children:"Runs"})})})}),aa=()=>s.jsxs(Vt,{children:[s.jsx(Ht,{id:"Workflow"}),s.jsx(Wt,{children:"Run a task or flow to get started"}),s.jsx(Bt,{children:"Runs store the state history for each execution of a task or flow."}),s.jsx(Ut,{children:s.jsx(Qt,{id:"getting-started"})})]}),ce=$e("/runs/");function na(e){const t=u=>u?u.split(",").filter(c=>c.trim().length>0):[],n=t(e.state),a=t(e.flows),o=t(e.deployments),i=t(e["work-pools"]),r=t(e.tags);return{...n.length>0&&{state:n},...a.length>0&&{flows:a},...o.length>0&&{deployments:o},...i.length>0&&{workPools:i},...r.length>0&&{tags:r},...e.range&&{range:e.range},...e.start&&{start:e.start},...e.end&&{end:e.end}}}function at(e){return{state:e.state?.join(",")??"",flows:e.flows?.join(",")??"",deployments:e.deployments?.join(",")??"","work-pools":e.workPools?.join(",")??"",tags:e.tags?.join(",")??"",range:e.range,start:e.start,end:e.end}}function We(e,t){return{id:e.id,name:e.name,isDefault:e.id===t}}function oa(){const e=ce.useSearch(),t=ce.useNavigate(),{savedFilters:n,defaultFilterId:a,saveFilter:o,deleteFilter:i,setDefaultFilter:r,findMatchingFilter:u}=st(),[c,d]=l.useState(!1),f=l.useMemo(()=>na(e),[e]),m=l.useMemo(()=>u(f),[u,f]),h=l.useMemo(()=>n.map(F=>We(F,a)),[n,a]),x=l.useMemo(()=>m?We(m,a):f.state?.length||f.flows?.length||f.deployments?.length||f.workPools?.length||f.tags?.length||f.range||f.start||f.end?{id:null,name:"Unsaved",isDefault:!1}:{id:null,name:"Custom",isDefault:!1},[m,a,f]),S=l.useCallback(F=>{const N=n.find(v=>v.id===F.id);if(!N)return;const A=at(N.filters);t({to:".",search:v=>({...v,...A,page:1}),replace:!0})},[t,n]),y=l.useCallback(()=>{d(!0)},[]),g=l.useCallback(F=>{o({name:F,filters:f}),d(!1)},[o,f]),p=l.useCallback(()=>{d(!1)},[]),w=l.useCallback(F=>{i(F)},[i]),k=l.useCallback(F=>{r(F)},[r]),b=l.useCallback(()=>{r(null)},[r]);return{currentFilter:x,savedFiltersForMenu:h,onSelectFilter:S,onSaveFilter:y,onDeleteFilter:w,onSetDefault:k,onRemoveDefault:b,isSaveDialogOpen:c,closeSaveDialog:p,confirmSave:g}}function ra(){const e=ce.useNavigate(),t=ce.useSearch(),{defaultFilterId:n,getFilterById:a}=st(),o=l.useRef(!1),i=l.useMemo(()=>!!(t.state||t.flows||t.deployments||t["work-pools"]||t.tags||t.range||t.start||t.end),[t]);l.useEffect(()=>{if(o.current||i)return;let r;n&&(r=a(n)),r||(r=Zs),o.current=!0;const u=at(r.filters);e({to:".",search:c=>({...c,...u,page:1}),replace:!0})},[n,i,a,e])}const Be=$e("/runs/"),la=e=>e?e.split(",").filter(t=>Ge.includes(t)):[],ne=e=>e?e.split(",").filter(t=>t.trim().length>0):[];function ia(){const e=Be.useSearch(),t=Be.useNavigate(),n=l.useMemo(()=>new Set(la(e.state??"")),[e.state]),a=l.useMemo(()=>new Set(ne(e.flows??"")),[e.flows]),o=l.useMemo(()=>new Set(ne(e.deployments??"")),[e.deployments]),i=l.useMemo(()=>new Set(ne(e["work-pools"]??"")),[e["work-pools"]]),r=l.useMemo(()=>new Set(ne(e.tags??"")),[e.tags]),u=l.useMemo(()=>({range:e.range,start:e.start,end:e.end}),[e.range,e.start,e.end]),c=l.useCallback(g=>{const p=Array.from(g);t({to:".",search:w=>({...w,state:p.length>0?p.join(","):"",page:1}),replace:!0})},[t]),d=l.useCallback(g=>{const p=Array.from(g);t({to:".",search:w=>({...w,flows:p.length>0?p.join(","):"",page:1}),replace:!0})},[t]),f=l.useCallback(g=>{const p=Array.from(g);t({to:".",search:w=>({...w,deployments:p.length>0?p.join(","):"",page:1}),replace:!0})},[t]),m=l.useCallback(g=>{const p=Array.from(g);t({to:".",search:w=>({...w,"work-pools":p.length>0?p.join(","):"",page:1}),replace:!0})},[t]),h=l.useCallback(g=>{const p=Array.from(g);t({to:".",search:w=>({...w,tags:p.length>0?p.join(","):"",page:1}),replace:!0})},[t]),x=l.useCallback(g=>{t({to:".",search:p=>({...p,range:g.range,start:g.start,end:g.end,page:1}),replace:!0})},[t]),S=l.useMemo(()=>n.size>0||a.size>0||o.size>0||i.size>0||r.size>0||u.range!==void 0||u.start!==void 0||u.end!==void 0,[n,a,o,i,r,u]),y=l.useCallback(()=>{t({to:".",search:g=>({...g,state:"",flows:"",deployments:"","work-pools":"",tags:"",range:void 0,start:void 0,end:void 0,page:1}),replace:!0})},[t]);return{states:n,flows:a,deployments:o,workPools:i,tags:r,dateRange:u,onStatesChange:c,onFlowsChange:d,onDeploymentsChange:f,onWorkPoolsChange:m,onTagsChange:h,onDateRangeChange:x,clearAllFilters:y,hasActiveFilters:S}}Ke({tab:se(["flow-runs","task-runs"]).optional().default("flow-runs"),page:ae().int().positive().optional().default(1).catch(1),limit:ae().int().positive().optional().catch(void 0),sort:se(Jt).optional().default("START_TIME_DESC"),"hide-subflows":bs().optional().default(!1),"flow-run-search":_().optional().default(""),state:_().optional().default(""),flows:_().optional().default(""),deployments:_().optional().default(""),"work-pools":_().optional().default(""),tags:_().optional().default(""),range:se(Kt).optional(),start:_().optional(),end:_().optional(),"task-runs-page":ae().int().positive().optional().default(1).catch(1),"task-runs-limit":ae().int().positive().optional().catch(void 0),"task-runs-sort":se(Xt).optional().default("EXPECTED_START_TIME_DESC"),"task-run-search":_().optional().default("")});const Te=e=>e?e.split(",").filter(t=>Ge.includes(t)):[],ue=e=>{if(!e)return;const t={range:e.range,start:e.start,end:e.end},n=Ye(t);if(!n)return;const a=Gt(n);if(a)return{after_:a.startDate.toISOString(),before_:a.endDate.toISOString()}},De=e=>e?e.split(",").filter(t=>t.trim().length>0):[],_e=e=>e?e.split(",").filter(t=>t.trim().length>0):[],nt=e=>e?e.split(",").filter(t=>t.trim().length>0):[],Ne=e=>e?e.split(",").filter(t=>t.trim().length>0):[],Ue=e=>{const t=e?.["hide-subflows"],n=e?.["flow-run-search"],a=Te(e?.state??""),o=De(e?.flows??""),i=_e(e?.deployments??""),r=nt(e?.["work-pools"]??""),u=Ne(e?.tags??""),c=ue(e),d=a.length>0?a:void 0,f=o.length>0?o:void 0,m=i.length>0?i:void 0,h=r.length>0?r:void 0,S=t||n||d||f||m||u.length>0||c?{operator:"and_",...t&&{parent_task_run_id:{operator:"and_",is_null_:!0}},...n&&{name:{like_:n}},...d&&{state:{operator:"and_",name:{any_:d}}},...u.length>0&&{tags:{operator:"and_",any_:u}},...c&&{expected_start_time:c}}:void 0,y=f?{operator:"and_",id:{any_:f}}:void 0,g=m?{operator:"and_",id:{any_:m}}:void 0,p=h?{operator:"and_",name:{any_:h}}:void 0;return{page:e?.page??1,limit:e?.limit??100,sort:e?.sort??"START_TIME_DESC",flow_runs:S,flows:y,deployments:g,work_pools:p}},Qe=e=>{const t=e?.["task-run-search"],n=Te(e?.state??""),a=De(e?.flows??""),o=_e(e?.deployments??""),i=Ne(e?.tags??""),r=ue(e),u=t?{operator:"and_",name:{like_:t}}:void 0,c=n.length>0?n:void 0,f=c||i.length>0||r?{operator:"and_",...c&&{state:{operator:"and_",name:{any_:c}}},...i.length>0&&{tags:{operator:"and_",any_:i}},...r&&{expected_start_time:r}}:void 0,m=a.length>0?a:void 0,h=m?{operator:"and_",id:{any_:m}}:void 0,x=o.length>0?o:void 0,S=x?{operator:"and_",id:{any_:x}}:void 0;return{page:e?.["task-runs-page"]??1,limit:e?.["task-runs-limit"]??100,sort:e?.["task-runs-sort"]??"EXPECTED_START_TIME_DESC",task_runs:u,flow_runs:f,flows:h,deployments:S}},ca=e=>{const t=e?.["hide-subflows"],n=Te(e?.state??""),a=De(e?.flows??""),o=_e(e?.deployments??""),i=nt(e?.["work-pools"]??""),r=Ne(e?.tags??""),u=ue(e),c=n.length>0?n:void 0,d=a.length>0?a:void 0,f=o.length>0?o:void 0,m=i.length>0?i:void 0;return{sort:"EXPECTED_START_TIME_DESC",limit:1e3,offset:0,flow_runs:t||c||r.length>0||u?{operator:"and_",...t&&{parent_task_run_id:{operator:"and_",is_null_:!0}},...c&&{state:{operator:"and_",name:{any_:c}}},...r.length>0&&{tags:{operator:"and_",any_:r}},...u&&{expected_start_time:u}}:void 0,flows:d?{operator:"and_",id:{any_:d}}:void 0,deployments:f?{operator:"and_",id:{any_:f}}:void 0,work_pools:m?{operator:"and_",name:{any_:m}}:void 0}},ua=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useMemo(()=>({page:e.page??1,limit:e.limit??100}),[e.page,e.limit]),a=l.useCallback(o=>{t({to:".",search:i=>({...i,page:o.page,limit:o.limit}),replace:!0})},[t]);return[n,a]},da=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,sort:a,page:1}),replace:!0})},[t]);return[e.sort,n]},ma=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,"hide-subflows":a,page:1}),replace:!0})},[t]);return[e["hide-subflows"],n]},fa=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,tab:a,page:1}),replace:!0})},[t]);return[e.tab,n]},ga=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,"flow-run-search":a,page:1}),replace:!0})},[t]);return[e["flow-run-search"],n]},ha=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useMemo(()=>({page:e["task-runs-page"]??1,limit:e["task-runs-limit"]??100}),[e["task-runs-page"],e["task-runs-limit"]]),a=l.useCallback(o=>{t({to:".",search:i=>({...i,"task-runs-page":o.page,"task-runs-limit":o.limit}),replace:!0})},[t]);return[n,a]},pa=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,"task-runs-sort":a,"task-runs-page":1}),replace:!0})},[t]);return[e["task-runs-sort"],n]},xa=()=>{const e=j.useSearch(),t=j.useNavigate(),n=l.useCallback(a=>{t({to:".",search:o=>({...o,"task-run-search":a,"task-runs-page":1}),replace:!0})},[t]);return[e["task-run-search"],n]};function La(){const e=ot(),t=j.useSearch(),n=j.useNavigate(),[a,o]=ie("workspace-flow-runs-list-limit",100),[i,r]=ie("workspace-task-runs-list-limit",100),u=l.useRef(!1);l.useEffect(()=>{if(u.current)return;u.current=!0;const C=t.limit===void 0,D=t["task-runs-limit"]===void 0;(C||D)&&n({to:".",search:Z=>({...Z,...C&&{limit:a},...D&&{"task-runs-limit":i}}),replace:!0})},[n,t.limit,t["task-runs-limit"],a,i]),l.useEffect(()=>{t.limit!==void 0&&t.limit!==a&&o(t.limit)},[t.limit,a,o]),l.useEffect(()=>{t["task-runs-limit"]!==void 0&&t["task-runs-limit"]!==i&&r(t["task-runs-limit"])},[t["task-runs-limit"],i,r]);const[c,d]=ua(),[f,m]=da(),[h,x]=ma(),[S,y]=fa(),[g,p]=ga(),{states:w,flows:k,deployments:b,workPools:F,tags:N,dateRange:A,onStatesChange:v,onFlowsChange:W,onDeploymentsChange:H,onWorkPoolsChange:P,onTagsChange:B,onDateRangeChange:M}=ia(),[T,I]=ha(),[L,U]=pa(),[z,Q]=xa(),{currentFilter:de,savedFiltersForMenu:me,onSelectFilter:fe,onSaveFilter:ge,onDeleteFilter:he,onSetDefault:X,onRemoveDefault:pe,isSaveDialogOpen:xe,closeSaveDialog:we,confirmSave:Se}=oa();ra();const[{data:ve},{data:ke}]=rt({queries:[$t(),Yt()]}),{data:$}=E(Le(Ue(t),3e4)),{data:Y}=E(ze(Qe(t),3e4)),{data:ye}=E(qt(ca(t),3e4)),q=$?.results??[],K=Y?.results??[],Fe=l.useMemo(()=>{const C=ue(t);return{startDate:C?.after_?new Date(C.after_):void 0,endDate:C?.before_?new Date(C.before_):void 0}},[t]);l.useEffect(()=>{const C=q.map(D=>D.id);C.length>0&&e.prefetchQuery(Oe(C))},[e,q]);const je=l.useCallback(C=>{const D=Ue({...t,page:C});(async()=>{const G=(await e.ensureQueryData(Le(D,3e4)))?.results?.map(R=>R.id)??[];G.length>0&&e.prefetchQuery(Oe(G))})()},[e,t]),J=l.useCallback(C=>{const D=Qe({...t,"task-runs-page":C});e.prefetchQuery(ze(D,3e4))},[e,t]),Ce=l.useCallback(()=>{Q("")},[Q]);return s.jsx(sa,{tab:S,onTabChange:y,flowRunsCount:$?.count??0,taskRunsCount:Y?.count??0,hasAnyFlowRuns:(ve??0)>0,hasAnyTaskRuns:(ke??0)>0,flowRuns:q,flowRunsPages:$?.pages??0,pagination:c,onPaginationChange:d,onPrefetchPage:je,sort:f,onSortChange:m,hideSubflows:h,onHideSubflowsChange:x,flowRunSearch:g,onFlowRunSearchChange:p,selectedStates:w,onStateFilterChange:v,selectedFlows:k,onFlowFilterChange:W,selectedDeployments:b,onDeploymentFilterChange:H,selectedTags:N,onTagsFilterChange:B,selectedWorkPools:F,onWorkPoolFilterChange:P,dateRange:A,onDateRangeChange:M,flowRunHistory:ye??[],scatterPlotDateRange:Fe,taskRuns:K,taskRunsPages:Y?.pages??0,taskRunsPagination:T,onTaskRunsPaginationChange:I,onTaskRunsPrefetchPage:J,taskRunsSort:L,onTaskRunsSortChange:U,taskRunSearch:z,onTaskRunSearchChange:Q,onClearTaskRunFilters:Ce,currentFilter:de,savedFilters:me,onSelectFilter:fe,onSaveFilter:ge,onDeleteFilter:he,onSetDefault:X,onRemoveDefault:pe,isSaveDialogOpen:xe,onCloseSaveDialog:we,onConfirmSave:Se})}export{La as component};
|
|
2
|
+
//# sourceMappingURL=index-CTnoa3Ho.js.map
|