prefect 3.6.14.dev1__py3-none-any.whl → 3.6.14.dev2__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/_observers.py +20 -8
- prefect/cli/server.py +18 -3
- prefect/deployments/runner.py +448 -8
- prefect/flows.py +162 -34
- prefect/runner/runner.py +48 -0
- prefect/server/orchestration/global_policy.py +4 -2
- prefect/server/ui-v2/assets/{artifact-card-DkgEVahF.js → artifact-card-D41jcvLX.js} +2 -2
- prefect/server/ui-v2/assets/{artifact-card-DkgEVahF.js.map → artifact-card-D41jcvLX.js.map} +1 -1
- prefect/server/ui-v2/assets/{artifact._id-C7yJhkKY.js → artifact._id-CYMvBFBb.js} +2 -2
- prefect/server/ui-v2/assets/{artifact._id-C7yJhkKY.js.map → artifact._id-CYMvBFBb.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation-wizard-BLI4sqs9.js → automation-wizard-DHsWJ8JS.js} +2 -2
- prefect/server/ui-v2/assets/{automation-wizard-BLI4sqs9.js.map → automation-wizard-DHsWJ8JS.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation._id-OLes3du9.js → automation._id-CCroE1-1.js} +2 -2
- prefect/server/ui-v2/assets/{automation._id-OLes3du9.js.map → automation._id-CCroE1-1.js.map} +1 -1
- prefect/server/ui-v2/assets/{automation_._id.edit-QrSzkDDB.js → automation_._id.edit-BgpDmMq7.js} +2 -2
- prefect/server/ui-v2/assets/{automation_._id.edit-QrSzkDDB.js.map → automation_._id.edit-BgpDmMq7.js.map} +1 -1
- prefect/server/ui-v2/assets/{automations-header-BoJc9HK8.js → automations-header-BEZXZmli.js} +2 -2
- prefect/server/ui-v2/assets/{automations-header-BoJc9HK8.js.map → automations-header-BEZXZmli.js.map} +1 -1
- prefect/server/ui-v2/assets/{base-job-template-form-section-Br6s0jNS.js → base-job-template-form-section-BubT4OHj.js} +2 -2
- prefect/server/ui-v2/assets/{base-job-template-form-section-Br6s0jNS.js.map → base-job-template-form-section-BubT4OHj.js.map} +1 -1
- prefect/server/ui-v2/assets/{block-type-details-BSbBP-Nm.js → block-type-details-DCWuBOwb.js} +2 -2
- prefect/server/ui-v2/assets/{block-type-details-BSbBP-Nm.js.map → block-type-details-DCWuBOwb.js.map} +1 -1
- prefect/server/ui-v2/assets/{block-type-logo-DNFERTyH.js → block-type-logo-SZMe2NdY.js} +2 -2
- prefect/server/ui-v2/assets/{block-type-logo-DNFERTyH.js.map → block-type-logo-SZMe2NdY.js.map} +1 -1
- prefect/server/ui-v2/assets/{block._id-DO6Hulrv.js → block._id-B6_kwTZ-.js} +2 -2
- prefect/server/ui-v2/assets/{block._id-DO6Hulrv.js.map → block._id-B6_kwTZ-.js.map} +1 -1
- prefect/server/ui-v2/assets/{block_._id.edit-BWF0TQvv.js → block_._id.edit-Bjg9WgY6.js} +2 -2
- prefect/server/ui-v2/assets/{block_._id.edit-BWF0TQvv.js.map → block_._id.edit-Bjg9WgY6.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog-BlaqZP0r.js → catalog-Bv8x-rIx.js} +2 -2
- prefect/server/ui-v2/assets/{catalog-BlaqZP0r.js.map → catalog-Bv8x-rIx.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog_._slug-BZWiMtjq.js → catalog_._slug-2GldfHc0.js} +2 -2
- prefect/server/ui-v2/assets/{catalog_._slug-BZWiMtjq.js.map → catalog_._slug-2GldfHc0.js.map} +1 -1
- prefect/server/ui-v2/assets/{catalog_._slug_.create-oHffbeMs.js → catalog_._slug_.create-Bjt7az95.js} +2 -2
- prefect/server/ui-v2/assets/{catalog_._slug_.create-oHffbeMs.js.map → catalog_._slug_.create-Bjt7az95.js.map} +1 -1
- prefect/server/ui-v2/assets/{collapsible-D45P93xU.js → collapsible-BT0EnMmT.js} +2 -2
- prefect/server/ui-v2/assets/{collapsible-D45P93xU.js.map → collapsible-BT0EnMmT.js.map} +1 -1
- prefect/server/ui-v2/assets/{concurrency-limit._id-B6oyPVya.js → concurrency-limit._id-Ba5Uof4l.js} +2 -2
- prefect/server/ui-v2/assets/{concurrency-limit._id-B6oyPVya.js.map → concurrency-limit._id-Ba5Uof4l.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-CcYMd6w6.js → create-DK8Cy1hG.js} +2 -2
- prefect/server/ui-v2/assets/{create-CcYMd6w6.js.map → create-DK8Cy1hG.js.map} +1 -1
- prefect/server/ui-v2/assets/{create-DK1WvDhf.js → create-Ds8Lheyk.js} +2 -2
- prefect/server/ui-v2/assets/{create-DK1WvDhf.js.map → create-Ds8Lheyk.js.map} +1 -1
- prefect/server/ui-v2/assets/cronstrue-C72j5NDa.js +2 -0
- prefect/server/ui-v2/assets/cronstrue-C72j5NDa.js.map +1 -0
- prefect/server/ui-v2/assets/{data-table-B_iyrrTm.js → data-table-B6bdz5Zj.js} +2 -2
- prefect/server/ui-v2/assets/{data-table-B_iyrrTm.js.map → data-table-B6bdz5Zj.js.map} +1 -1
- prefect/server/ui-v2/assets/{delete-confirmation-dialog-7GKqeKy1.js → delete-confirmation-dialog-CV8ITEEW.js} +2 -2
- prefect/server/ui-v2/assets/{delete-confirmation-dialog-7GKqeKy1.js.map → delete-confirmation-dialog-CV8ITEEW.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-action-header-DrvnfE9Y.js → deployment-action-header-DpjOcab0.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-action-header-DrvnfE9Y.js.map → deployment-action-header-DpjOcab0.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-form-DsAij22s.js → deployment-form-CjIPPnwV.js} +3 -3
- prefect/server/ui-v2/assets/{deployment-form-DsAij22s.js.map → deployment-form-CjIPPnwV.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment-links-BwqfKWQX.js → deployment-links--VkBo9wV.js} +2 -2
- prefect/server/ui-v2/assets/{deployment-links-BwqfKWQX.js.map → deployment-links--VkBo9wV.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment._id-E5e5s6bO.js → deployment._id-CW00MZGG.js} +2 -2
- prefect/server/ui-v2/assets/{deployment._id-E5e5s6bO.js.map → deployment._id-CW00MZGG.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment._id-U6KrtWw0.js → deployment._id-DjYh9IiR.js} +2 -2
- prefect/server/ui-v2/assets/{deployment._id-U6KrtWw0.js.map → deployment._id-DjYh9IiR.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.duplicate-18ZQHHgI.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.duplicate-C_kNyCA9.js.map → deployment_._id.duplicate-18ZQHHgI.js.map} +1 -1
- prefect/server/ui-v2/assets/deployment_._id.edit-C9H0Teuv.js +2 -0
- prefect/server/ui-v2/assets/{deployment_._id.edit-BP8pfTOR.js.map → deployment_._id.edit-C9H0Teuv.js.map} +1 -1
- prefect/server/ui-v2/assets/{deployment_._id.run-Di3-4Mtk.js → deployment_._id.run-CwHYw8j1.js} +2 -2
- prefect/server/ui-v2/assets/{deployment_._id.run-Di3-4Mtk.js.map → deployment_._id.run-CwHYw8j1.js.map} +1 -1
- prefect/server/ui-v2/assets/{dropdown-menu-iS8iJMpx.js → dropdown-menu-BYgkpoqb.js} +2 -2
- prefect/server/ui-v2/assets/{dropdown-menu-iS8iJMpx.js.map → dropdown-menu-BYgkpoqb.js.map} +1 -1
- prefect/server/ui-v2/assets/{event._eventDate._eventId-CG15qDSZ.js → event._eventDate._eventId-mPwFHce2.js} +2 -2
- prefect/server/ui-v2/assets/{event._eventDate._eventId-CG15qDSZ.js.map → event._eventDate._eventId-mPwFHce2.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run-graph-BMp5vJJa.js +2 -0
- prefect/server/ui-v2/assets/flow-run-graph-BMp5vJJa.js.map +1 -0
- prefect/server/ui-v2/assets/{flow-run._id-D_eAHZ5z.js → flow-run._id-CafHaMND.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-D_eAHZ5z.js.map → flow-run._id-CafHaMND.js.map} +1 -1
- prefect/server/ui-v2/assets/flow-run._id-CelqqA9P.js +4 -0
- prefect/server/ui-v2/assets/flow-run._id-CelqqA9P.js.map +1 -0
- prefect/server/ui-v2/assets/{flow-run._id-wco0Q19f.js → flow-run._id-hVuHWXbi.js} +2 -2
- prefect/server/ui-v2/assets/{flow-run._id-wco0Q19f.js.map → flow-run._id-hVuHWXbi.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow-runs-pagination-DzGHOht3.js → flow-runs-pagination-CqjL9gOj.js} +2 -2
- prefect/server/ui-v2/assets/{flow-runs-pagination-DzGHOht3.js.map → flow-runs-pagination-CqjL9gOj.js.map} +1 -1
- prefect/server/ui-v2/assets/{flow._id-Dn2so3rK.js → flow._id-C1Djus0m.js} +2 -2
- prefect/server/ui-v2/assets/{flow._id-Dn2so3rK.js.map → flow._id-C1Djus0m.js.map} +1 -1
- prefect/server/ui-v2/assets/{form-rC8pxeRl.js → form-z_RaFdEo.js} +2 -2
- prefect/server/ui-v2/assets/{form-rC8pxeRl.js.map → form-z_RaFdEo.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-CuAwmJ64.js → header-B-PvVnN7.js} +2 -2
- prefect/server/ui-v2/assets/{header-CuAwmJ64.js.map → header-B-PvVnN7.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-C0zV3WDn.js → header-BSXYXvPS.js} +2 -2
- prefect/server/ui-v2/assets/{header-C0zV3WDn.js.map → header-BSXYXvPS.js.map} +1 -1
- prefect/server/ui-v2/assets/{header-C6ko3O7G.js → header-CKVO4oLE.js} +2 -2
- prefect/server/ui-v2/assets/{header-C6ko3O7G.js.map → header-CKVO4oLE.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CotXErTe.js → index-B5zctA6A.js} +2 -2
- prefect/server/ui-v2/assets/{index-CotXErTe.js.map → index-B5zctA6A.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-k2161reF.js → index-BCzGofA2.js} +2 -2
- prefect/server/ui-v2/assets/{index-k2161reF.js.map → index-BCzGofA2.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-BdgomKuA.js → index-BOuQzuoR.js} +2 -2
- prefect/server/ui-v2/assets/{index-BdgomKuA.js.map → index-BOuQzuoR.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-pE_31vXF.js → index-BQOxk1xu.js} +2 -2
- prefect/server/ui-v2/assets/{index-pE_31vXF.js.map → index-BQOxk1xu.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-Benf9xn3.js → index-BU1Y-wgo.js} +2 -2
- prefect/server/ui-v2/assets/{index-Benf9xn3.js.map → index-BU1Y-wgo.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CYpFLd7y.js → index-BxGluvOD.js} +2 -2
- prefect/server/ui-v2/assets/{index-CYpFLd7y.js.map → index-BxGluvOD.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CcVSC2pV.js → index-CAbBPipD.js} +2 -2
- prefect/server/ui-v2/assets/{index-CcVSC2pV.js.map → index-CAbBPipD.js.map} +1 -1
- prefect/server/ui-v2/assets/index-CHwhYh-B.js +2 -0
- prefect/server/ui-v2/assets/{index-BYQ1P2TC.js.map → index-CHwhYh-B.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-0g8aAM30.js → index-CIKCrLeZ.js} +2 -2
- prefect/server/ui-v2/assets/{index-0g8aAM30.js.map → index-CIKCrLeZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-fhrsIceD.js → index-CLUjhc4A.js} +2 -2
- prefect/server/ui-v2/assets/{index-fhrsIceD.js.map → index-CLUjhc4A.js.map} +1 -1
- prefect/server/ui-v2/assets/index-CX5uU1zd.js +2 -0
- prefect/server/ui-v2/assets/index-CX5uU1zd.js.map +1 -0
- prefect/server/ui-v2/assets/{index-DwkedbVy.js → index-CXVePXfG.js} +2 -2
- prefect/server/ui-v2/assets/{index-DwkedbVy.js.map → index-CXVePXfG.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-DB2qeheX.js → index-D-ZIgaBw.js} +2 -2
- prefect/server/ui-v2/assets/{index-DB2qeheX.js.map → index-D-ZIgaBw.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-D8fZaZa7.js → index-D10Svo9k.js} +2 -2
- prefect/server/ui-v2/assets/{index-D8fZaZa7.js.map → index-D10Svo9k.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CEStyUb-.js → index-D2EEipYt.js} +2 -2
- prefect/server/ui-v2/assets/{index-CEStyUb-.js.map → index-D2EEipYt.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-BIqzfifB.js → index-DV5fpxXB.js} +2 -2
- prefect/server/ui-v2/assets/{index-BIqzfifB.js.map → index-DV5fpxXB.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-C3D0Re7U.js → index-FHRYGk_R.js} +2 -2
- prefect/server/ui-v2/assets/{index-C3D0Re7U.js.map → index-FHRYGk_R.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-CCs20W5W.js → index-IGxqySze.js} +2 -2
- prefect/server/ui-v2/assets/{index-CCs20W5W.js.map → index-IGxqySze.js.map} +1 -1
- prefect/server/ui-v2/assets/{index-BKbBu9gL.js → index-P2xc38Yh.js} +2 -2
- prefect/server/ui-v2/assets/{index-BKbBu9gL.js.map → index-P2xc38Yh.js.map} +1 -1
- prefect/server/ui-v2/assets/index-Yzhlw6-Q.js +17 -0
- prefect/server/ui-v2/assets/index-Yzhlw6-Q.js.map +1 -0
- prefect/server/ui-v2/assets/{index-BjsWjEUO.js → index-n7YFiQkB.js} +2 -2
- prefect/server/ui-v2/assets/{index-BjsWjEUO.js.map → index-n7YFiQkB.js.map} +1 -1
- prefect/server/ui-v2/assets/{json-input-C9dkBSdc.js → json-input-Dlzy_XLK.js} +2 -2
- prefect/server/ui-v2/assets/{json-input-C9dkBSdc.js.map → json-input-Dlzy_XLK.js.map} +1 -1
- prefect/server/ui-v2/assets/{key._key-BBVH44_R.js → key._key-DN_txnIw.js} +2 -2
- prefect/server/ui-v2/assets/{key._key-BBVH44_R.js.map → key._key-DN_txnIw.js.map} +1 -1
- prefect/server/ui-v2/assets/{lazy-markdown-BoMKGRXo.js → lazy-markdown-CPQjrQrX.js} +2 -2
- prefect/server/ui-v2/assets/{lazy-markdown-BoMKGRXo.js.map → lazy-markdown-CPQjrQrX.js.map} +1 -1
- prefect/server/ui-v2/assets/{login-BmmIDesJ.js → login-BsnFlv-8.js} +2 -2
- prefect/server/ui-v2/assets/{login-BmmIDesJ.js.map → login-BsnFlv-8.js.map} +1 -1
- prefect/server/ui-v2/assets/{markdown-input-C6P8cYT1.js → markdown-input-b0zl1NLl.js} +2 -2
- prefect/server/ui-v2/assets/{markdown-input-C6P8cYT1.js.map → markdown-input-b0zl1NLl.js.map} +1 -1
- prefect/server/ui-v2/assets/{python-example-snippet-DPumgTpL.js → python-example-snippet-W9Z_3hjQ.js} +3 -3
- prefect/server/ui-v2/assets/{python-example-snippet-DPumgTpL.js.map → python-example-snippet-W9Z_3hjQ.js.map} +1 -1
- prefect/server/ui-v2/assets/{python-input-DX4uV8MF.js → python-input-EKDBgTDE.js} +2 -2
- prefect/server/ui-v2/assets/{python-input-DX4uV8MF.js.map → python-input-EKDBgTDE.js.map} +1 -1
- prefect/server/ui-v2/assets/{radio-group-DeNK-Ob0.js → radio-group-BMeznoY8.js} +2 -2
- prefect/server/ui-v2/assets/{radio-group-DeNK-Ob0.js.map → radio-group-BMeznoY8.js.map} +1 -1
- prefect/server/ui-v2/assets/{route-error-state-C9CbByMx.js → route-error-state-BGOi4dn-.js} +2 -2
- prefect/server/ui-v2/assets/{route-error-state-C9CbByMx.js.map → route-error-state-BGOi4dn-.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-B45xnsnK.js → schema-form-BHWTZ8Sy.js} +2 -2
- prefect/server/ui-v2/assets/{schema-form-B45xnsnK.js.map → schema-form-BHWTZ8Sy.js.map} +1 -1
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BJj81bu-.js → schema-form-input-string-format-datetime-hWIr4wQr.js} +4 -4
- prefect/server/ui-v2/assets/{schema-form-input-string-format-datetime-BJj81bu-.js.map → schema-form-input-string-format-datetime-hWIr4wQr.js.map} +1 -1
- prefect/server/ui-v2/assets/{settings-CbkeWqQ9.js → settings-DVSPGBen.js} +2 -2
- prefect/server/ui-v2/assets/{settings-CbkeWqQ9.js.map → settings-DVSPGBen.js.map} +1 -1
- prefect/server/ui-v2/assets/{sort-filter-DM7SvBB0.js → sort-filter-MiwMjIYc.js} +2 -2
- prefect/server/ui-v2/assets/{sort-filter-DM7SvBB0.js.map → sort-filter-MiwMjIYc.js.map} +1 -1
- prefect/server/ui-v2/assets/{table-CEPo6xb_.js → table-BJkw82b1.js} +2 -2
- prefect/server/ui-v2/assets/{table-CEPo6xb_.js.map → table-BJkw82b1.js.map} +1 -1
- prefect/server/ui-v2/assets/{tags-input-DJiZSVHp.js → tags-input-1KkWhGJZ.js} +2 -2
- prefect/server/ui-v2/assets/{tags-input-DJiZSVHp.js.map → tags-input-1KkWhGJZ.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-vJEkvqWp.js → task-run-concurrency-limits-reset-dialog-ClBlDic_.js} +2 -2
- prefect/server/ui-v2/assets/{task-run-concurrency-limits-reset-dialog-vJEkvqWp.js.map → task-run-concurrency-limits-reset-dialog-ClBlDic_.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-BCnDnXrL.js → task-run._id-48TwMBP1.js} +2 -2
- prefect/server/ui-v2/assets/{task-run._id-BCnDnXrL.js.map → task-run._id-48TwMBP1.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-run._id-ByJw1K82.js → task-run._id-BmK7HGNl.js} +2 -2
- prefect/server/ui-v2/assets/{task-run._id-ByJw1K82.js.map → task-run._id-BmK7HGNl.js.map} +1 -1
- prefect/server/ui-v2/assets/{task-runs-pagination-DbjB6XnY.js → task-runs-pagination-DA4izCRv.js} +2 -2
- prefect/server/ui-v2/assets/{task-runs-pagination-DbjB6XnY.js.map → task-runs-pagination-DA4izCRv.js.map} +1 -1
- prefect/server/ui-v2/assets/{textarea-BX8KbLGx.js → textarea-BqtBNhJB.js} +2 -2
- prefect/server/ui-v2/assets/{textarea-BX8KbLGx.js.map → textarea-BqtBNhJB.js.map} +1 -1
- prefect/server/ui-v2/assets/{timezone-select-TBj2n6Ox.js → timezone-select-BgD_PENN.js} +2 -2
- prefect/server/ui-v2/assets/{timezone-select-TBj2n6Ox.js.map → timezone-select-BgD_PENN.js.map} +1 -1
- prefect/server/ui-v2/assets/{toggle-group-D7mfSUim.js → toggle-group-ChA-JYQB.js} +2 -2
- prefect/server/ui-v2/assets/{toggle-group-D7mfSUim.js.map → toggle-group-ChA-JYQB.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-BpBSjz60.js → use-delete-automation-confirmation-dialog-Da1iWNZ_.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-automation-confirmation-dialog-BpBSjz60.js.map → use-delete-automation-confirmation-dialog-Da1iWNZ_.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-BjKsNw6b.js → use-delete-block-document-confirmation-dialog-DfrxGSyY.js} +2 -2
- prefect/server/ui-v2/assets/{use-delete-block-document-confirmation-dialog-BjKsNw6b.js.map → use-delete-block-document-confirmation-dialog-DfrxGSyY.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-B_BlBMic.js → use-flow-runs-selected-rows-CYOsQ-Df.js} +2 -2
- prefect/server/ui-v2/assets/{use-flow-runs-selected-rows-B_BlBMic.js.map → use-flow-runs-selected-rows-CYOsQ-Df.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-BfE433bC.js → use-get-artifacts-flow-task-runs-C0V3_gYz.js} +2 -2
- prefect/server/ui-v2/assets/{use-get-artifacts-flow-task-runs-BfE433bC.js.map → use-get-artifacts-flow-task-runs-C0V3_gYz.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-quick-run-qrtcF-DD.js → use-quick-run-CgM0EheE.js} +2 -2
- prefect/server/ui-v2/assets/{use-quick-run-qrtcF-DD.js.map → use-quick-run-CgM0EheE.js.map} +1 -1
- prefect/server/ui-v2/assets/{use-stepper-CVy1_GBw.js → use-stepper-CSAs1T4U.js} +2 -2
- prefect/server/ui-v2/assets/{use-stepper-CVy1_GBw.js.map → use-stepper-CSAs1T4U.js.map} +1 -1
- prefect/server/ui-v2/assets/{utilities-D5-00wjP.js → utilities-DqaYuzh1.js} +2 -2
- prefect/server/ui-v2/assets/{utilities-D5-00wjP.js.map → utilities-DqaYuzh1.js.map} +1 -1
- prefect/server/ui-v2/assets/{vendor-date-7GxEwcQM.js → vendor-date-JS-ReHrg.js} +2 -2
- prefect/server/ui-v2/assets/{vendor-date-7GxEwcQM.js.map → vendor-date-JS-ReHrg.js.map} +1 -1
- prefect/server/ui-v2/assets/{vendor-graphs-R8z6S3Jg.js → vendor-graphs-BRVnayIy.js} +2 -2
- prefect/server/ui-v2/assets/{vendor-graphs-R8z6S3Jg.js.map → vendor-graphs-BRVnayIy.js.map} +1 -1
- prefect/server/ui-v2/assets/{vendor-radix-CznP1SOq.js → vendor-radix-BZJHvSaq.js} +9 -9
- prefect/server/ui-v2/assets/{vendor-radix-CznP1SOq.js.map → vendor-radix-BZJHvSaq.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool-filter-D8MkTbSW.js → work-pool-filter-T6dM4jKE.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-filter-D8MkTbSW.js.map → work-pool-filter-T6dM4jKE.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-CbI7Gfu5.js → work-pool-queue-toggle-CdUw2mAH.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool-queue-toggle-CbI7Gfu5.js.map → work-pool-queue-toggle-CdUw2mAH.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool._workPoolName-CCzzgVV2.js → work-pool._workPoolName-DD8gh9X-.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool._workPoolName-CCzzgVV2.js.map → work-pool._workPoolName-DD8gh9X-.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-BAgiuU_j.js → work-pool_._workPoolName.edit-mmnZTSTy.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.edit-BAgiuU_j.js.map → work-pool_._workPoolName.edit-mmnZTSTy.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-BUawWJEy.js → work-pool_._workPoolName.queue._workQueueName-fbwQqkVN.js} +2 -2
- prefect/server/ui-v2/assets/{work-pool_._workPoolName.queue._workQueueName-BUawWJEy.js.map → work-pool_._workPoolName.queue._workQueueName-fbwQqkVN.js.map} +1 -1
- prefect/server/ui-v2/assets/{work-queue-icon-text-D_G_UCJX.js → work-queue-icon-text-YyKOH96e.js} +2 -2
- prefect/server/ui-v2/assets/{work-queue-icon-text-D_G_UCJX.js.map → work-queue-icon-text-YyKOH96e.js.map} +1 -1
- prefect/server/ui-v2/index.html +3 -3
- prefect/settings/models/runner.py +11 -0
- prefect/tasks.py +30 -4
- {prefect-3.6.14.dev1.dist-info → prefect-3.6.14.dev2.dist-info}/METADATA +1 -1
- {prefect-3.6.14.dev1.dist-info → prefect-3.6.14.dev2.dist-info}/RECORD +215 -215
- prefect/server/ui-v2/assets/cronstrue-WDy4rv2V.js +0 -2
- prefect/server/ui-v2/assets/cronstrue-WDy4rv2V.js.map +0 -1
- prefect/server/ui-v2/assets/deployment_._id.duplicate-C_kNyCA9.js +0 -2
- prefect/server/ui-v2/assets/deployment_._id.edit-BP8pfTOR.js +0 -2
- prefect/server/ui-v2/assets/flow-run-graph-B1vF1w0Z.js +0 -2
- prefect/server/ui-v2/assets/flow-run-graph-B1vF1w0Z.js.map +0 -1
- prefect/server/ui-v2/assets/flow-run._id-BHY61H6u.js +0 -4
- prefect/server/ui-v2/assets/flow-run._id-BHY61H6u.js.map +0 -1
- prefect/server/ui-v2/assets/index-BYQ1P2TC.js +0 -2
- prefect/server/ui-v2/assets/index-Cd7pM9pk.js +0 -17
- prefect/server/ui-v2/assets/index-Cd7pM9pk.js.map +0 -1
- prefect/server/ui-v2/assets/index-DvKYj8ko.js +0 -2
- prefect/server/ui-v2/assets/index-DvKYj8ko.js.map +0 -1
- {prefect-3.6.14.dev1.dist-info → prefect-3.6.14.dev2.dist-info}/WHEEL +0 -0
- {prefect-3.6.14.dev1.dist-info → prefect-3.6.14.dev2.dist-info}/entry_points.txt +0 -0
- {prefect-3.6.14.dev1.dist-info → prefect-3.6.14.dev2.dist-info}/licenses/LICENSE +0 -0
prefect/flows.py
CHANGED
|
@@ -47,7 +47,7 @@ from rich.console import Console
|
|
|
47
47
|
from typing_extensions import Literal, ParamSpec
|
|
48
48
|
|
|
49
49
|
from prefect._experimental.sla.objects import SlaTypes
|
|
50
|
-
from prefect._internal.concurrency.api import create_call, from_async
|
|
50
|
+
from prefect._internal.concurrency.api import create_call, from_async, from_sync
|
|
51
51
|
from prefect._versioning import VersionType
|
|
52
52
|
from prefect.client.schemas.filters import WorkerFilter, WorkerFilterStatus
|
|
53
53
|
from prefect.client.schemas.objects import ConcurrencyLimitConfig, FlowRun
|
|
@@ -83,7 +83,6 @@ from prefect.utilities.annotations import NotSet
|
|
|
83
83
|
from prefect.utilities.asyncutils import (
|
|
84
84
|
run_coro_as_sync,
|
|
85
85
|
run_sync_in_worker_thread,
|
|
86
|
-
sync_compatible,
|
|
87
86
|
)
|
|
88
87
|
from prefect.utilities.callables import (
|
|
89
88
|
ParameterSchema,
|
|
@@ -1382,8 +1381,7 @@ class Flow(Generic[P, R]):
|
|
|
1382
1381
|
|
|
1383
1382
|
return flow
|
|
1384
1383
|
|
|
1385
|
-
|
|
1386
|
-
async def deploy(
|
|
1384
|
+
async def adeploy(
|
|
1387
1385
|
self,
|
|
1388
1386
|
name: str,
|
|
1389
1387
|
work_pool_name: Optional[str] = None,
|
|
@@ -1414,6 +1412,8 @@ class Flow(Generic[P, R]):
|
|
|
1414
1412
|
"""
|
|
1415
1413
|
Deploys a flow to run on dynamic infrastructure via a work pool.
|
|
1416
1414
|
|
|
1415
|
+
This is the async version of deploy().
|
|
1416
|
+
|
|
1417
1417
|
By default, calling this method will build a Docker image for the flow, push it to a registry,
|
|
1418
1418
|
and create a deployment via the Prefect API that will run the flow on the given schedule.
|
|
1419
1419
|
|
|
@@ -1473,6 +1473,7 @@ class Flow(Generic[P, R]):
|
|
|
1473
1473
|
Deploy a local flow to a work pool:
|
|
1474
1474
|
|
|
1475
1475
|
```python
|
|
1476
|
+
import asyncio
|
|
1476
1477
|
from prefect import flow
|
|
1477
1478
|
|
|
1478
1479
|
@flow
|
|
@@ -1480,27 +1481,11 @@ class Flow(Generic[P, R]):
|
|
|
1480
1481
|
print(f"hello {name}")
|
|
1481
1482
|
|
|
1482
1483
|
if __name__ == "__main__":
|
|
1483
|
-
my_flow.
|
|
1484
|
+
asyncio.run(my_flow.adeploy(
|
|
1484
1485
|
"example-deployment",
|
|
1485
1486
|
work_pool_name="my-work-pool",
|
|
1486
1487
|
image="my-repository/my-image:dev",
|
|
1487
|
-
)
|
|
1488
|
-
```
|
|
1489
|
-
|
|
1490
|
-
Deploy a remotely stored flow to a work pool:
|
|
1491
|
-
|
|
1492
|
-
```python
|
|
1493
|
-
from prefect import flow
|
|
1494
|
-
|
|
1495
|
-
if __name__ == "__main__":
|
|
1496
|
-
flow.from_source(
|
|
1497
|
-
source="https://github.com/org/repo.git",
|
|
1498
|
-
entrypoint="flows.py:my_flow",
|
|
1499
|
-
).deploy(
|
|
1500
|
-
"example-deployment",
|
|
1501
|
-
work_pool_name="my-work-pool",
|
|
1502
|
-
image="my-repository/my-image:dev",
|
|
1503
|
-
)
|
|
1488
|
+
))
|
|
1504
1489
|
```
|
|
1505
1490
|
"""
|
|
1506
1491
|
if not (
|
|
@@ -1528,7 +1513,7 @@ class Flow(Generic[P, R]):
|
|
|
1528
1513
|
" deploying this flow."
|
|
1529
1514
|
) from exc
|
|
1530
1515
|
|
|
1531
|
-
|
|
1516
|
+
deployment = await self.ato_deployment(
|
|
1532
1517
|
name=name,
|
|
1533
1518
|
interval=interval,
|
|
1534
1519
|
cron=cron,
|
|
@@ -1550,14 +1535,9 @@ class Flow(Generic[P, R]):
|
|
|
1550
1535
|
_sla=_sla,
|
|
1551
1536
|
)
|
|
1552
1537
|
|
|
1553
|
-
|
|
1554
|
-
deployment = await to_deployment_coro
|
|
1555
|
-
else:
|
|
1556
|
-
deployment = to_deployment_coro
|
|
1557
|
-
|
|
1558
|
-
from prefect.deployments.runner import deploy
|
|
1538
|
+
from prefect.deployments.runner import adeploy
|
|
1559
1539
|
|
|
1560
|
-
|
|
1540
|
+
deployment_ids = await adeploy(
|
|
1561
1541
|
deployment,
|
|
1562
1542
|
work_pool_name=work_pool_name,
|
|
1563
1543
|
image=image,
|
|
@@ -1566,10 +1546,6 @@ class Flow(Generic[P, R]):
|
|
|
1566
1546
|
print_next_steps_message=False,
|
|
1567
1547
|
ignore_warnings=ignore_warnings,
|
|
1568
1548
|
)
|
|
1569
|
-
if TYPE_CHECKING:
|
|
1570
|
-
assert inspect.isawaitable(deploy_coro)
|
|
1571
|
-
|
|
1572
|
-
deployment_ids = await deploy_coro
|
|
1573
1549
|
|
|
1574
1550
|
if print_next_steps:
|
|
1575
1551
|
console = Console()
|
|
@@ -1603,6 +1579,158 @@ class Flow(Generic[P, R]):
|
|
|
1603
1579
|
|
|
1604
1580
|
return deployment_ids[0]
|
|
1605
1581
|
|
|
1582
|
+
@async_dispatch(adeploy)
|
|
1583
|
+
def deploy(
|
|
1584
|
+
self,
|
|
1585
|
+
name: str,
|
|
1586
|
+
work_pool_name: Optional[str] = None,
|
|
1587
|
+
image: Optional[Union[str, "DockerImage"]] = None,
|
|
1588
|
+
build: bool = True,
|
|
1589
|
+
push: bool = True,
|
|
1590
|
+
work_queue_name: Optional[str] = None,
|
|
1591
|
+
job_variables: Optional[dict[str, Any]] = None,
|
|
1592
|
+
interval: Optional[Union[int, float, datetime.timedelta]] = None,
|
|
1593
|
+
cron: Optional[str] = None,
|
|
1594
|
+
rrule: Optional[str] = None,
|
|
1595
|
+
paused: Optional[bool] = None,
|
|
1596
|
+
schedule: Optional[Schedule] = None,
|
|
1597
|
+
schedules: Optional[list[Schedule]] = None,
|
|
1598
|
+
concurrency_limit: Optional[Union[int, ConcurrencyLimitConfig, None]] = None,
|
|
1599
|
+
triggers: Optional[list[Union[DeploymentTriggerTypes, TriggerTypes]]] = None,
|
|
1600
|
+
parameters: Optional[dict[str, Any]] = None,
|
|
1601
|
+
description: Optional[str] = None,
|
|
1602
|
+
tags: Optional[list[str]] = None,
|
|
1603
|
+
version: Optional[str] = None,
|
|
1604
|
+
version_type: Optional[VersionType] = None,
|
|
1605
|
+
enforce_parameter_schema: bool = True,
|
|
1606
|
+
entrypoint_type: EntrypointType = EntrypointType.FILE_PATH,
|
|
1607
|
+
print_next_steps: bool = True,
|
|
1608
|
+
ignore_warnings: bool = False,
|
|
1609
|
+
_sla: Optional[Union[SlaTypes, list[SlaTypes]]] = None,
|
|
1610
|
+
) -> UUID:
|
|
1611
|
+
"""
|
|
1612
|
+
Deploys a flow to run on dynamic infrastructure via a work pool.
|
|
1613
|
+
|
|
1614
|
+
By default, calling this method will build a Docker image for the flow, push it to a registry,
|
|
1615
|
+
and create a deployment via the Prefect API that will run the flow on the given schedule.
|
|
1616
|
+
|
|
1617
|
+
If you want to use an existing image, you can pass `build=False` to skip building and pushing
|
|
1618
|
+
an image.
|
|
1619
|
+
|
|
1620
|
+
Args:
|
|
1621
|
+
name: The name to give the created deployment.
|
|
1622
|
+
work_pool_name: The name of the work pool to use for this deployment. Defaults to
|
|
1623
|
+
the value of `PREFECT_DEFAULT_WORK_POOL_NAME`.
|
|
1624
|
+
image: The name of the Docker image to build, including the registry and
|
|
1625
|
+
repository. Pass a DockerImage instance to customize the Dockerfile used
|
|
1626
|
+
and build arguments.
|
|
1627
|
+
build: Whether or not to build a new image for the flow. If False, the provided
|
|
1628
|
+
image will be used as-is and pulled at runtime.
|
|
1629
|
+
push: Whether or not to skip pushing the built image to a registry.
|
|
1630
|
+
work_queue_name: The name of the work queue to use for this deployment's scheduled runs.
|
|
1631
|
+
If not provided the default work queue for the work pool will be used.
|
|
1632
|
+
job_variables: Settings used to override the values specified default base job template
|
|
1633
|
+
of the chosen work pool. Refer to the base job template of the chosen work pool for
|
|
1634
|
+
available settings.
|
|
1635
|
+
interval: An interval on which to execute the deployment. Accepts a number or a
|
|
1636
|
+
timedelta object to create a single schedule. If a number is given, it will be
|
|
1637
|
+
interpreted as seconds. Also accepts an iterable of numbers or timedelta to create
|
|
1638
|
+
multiple schedules.
|
|
1639
|
+
cron: A cron schedule string of when to execute runs of this deployment.
|
|
1640
|
+
Also accepts an iterable of cron schedule strings to create multiple schedules.
|
|
1641
|
+
rrule: An rrule schedule string of when to execute runs of this deployment.
|
|
1642
|
+
Also accepts an iterable of rrule schedule strings to create multiple schedules.
|
|
1643
|
+
triggers: A list of triggers that will kick off runs of this deployment.
|
|
1644
|
+
paused: Whether or not to set this deployment as paused.
|
|
1645
|
+
schedule: A schedule object defining when to execute runs of this deployment.
|
|
1646
|
+
Used to provide additional scheduling options like `timezone` or `parameters`.
|
|
1647
|
+
schedules: A list of schedule objects defining when to execute runs of this deployment.
|
|
1648
|
+
Used to define multiple schedules or additional scheduling options like `timezone`.
|
|
1649
|
+
concurrency_limit: The maximum number of runs that can be executed concurrently.
|
|
1650
|
+
parameters: A dictionary of default parameter values to pass to runs of this deployment.
|
|
1651
|
+
description: A description for the created deployment. Defaults to the flow's
|
|
1652
|
+
description if not provided.
|
|
1653
|
+
tags: A list of tags to associate with the created deployment for organizational
|
|
1654
|
+
purposes.
|
|
1655
|
+
version: A version for the created deployment. Defaults to the flow's version.
|
|
1656
|
+
version_type: The type of version to use for the created deployment. The version type
|
|
1657
|
+
will be inferred if not provided.
|
|
1658
|
+
enforce_parameter_schema: Whether or not the Prefect API should enforce the
|
|
1659
|
+
parameter schema for the created deployment.
|
|
1660
|
+
entrypoint_type: Type of entrypoint to use for the deployment. When using a module path
|
|
1661
|
+
entrypoint, ensure that the module will be importable in the execution environment.
|
|
1662
|
+
print_next_steps_message: Whether or not to print a message with next steps
|
|
1663
|
+
after deploying the deployments.
|
|
1664
|
+
ignore_warnings: Whether or not to ignore warnings about the work pool type.
|
|
1665
|
+
_sla: (Experimental) SLA configuration for the deployment. May be removed or modified at any time. Currently only supported on Prefect Cloud.
|
|
1666
|
+
Returns:
|
|
1667
|
+
The ID of the created/updated deployment.
|
|
1668
|
+
|
|
1669
|
+
Examples:
|
|
1670
|
+
Deploy a local flow to a work pool:
|
|
1671
|
+
|
|
1672
|
+
```python
|
|
1673
|
+
from prefect import flow
|
|
1674
|
+
|
|
1675
|
+
@flow
|
|
1676
|
+
def my_flow(name):
|
|
1677
|
+
print(f"hello {name}")
|
|
1678
|
+
|
|
1679
|
+
if __name__ == "__main__":
|
|
1680
|
+
my_flow.deploy(
|
|
1681
|
+
"example-deployment",
|
|
1682
|
+
work_pool_name="my-work-pool",
|
|
1683
|
+
image="my-repository/my-image:dev",
|
|
1684
|
+
)
|
|
1685
|
+
```
|
|
1686
|
+
|
|
1687
|
+
Deploy a remotely stored flow to a work pool:
|
|
1688
|
+
|
|
1689
|
+
```python
|
|
1690
|
+
from prefect import flow
|
|
1691
|
+
|
|
1692
|
+
if __name__ == "__main__":
|
|
1693
|
+
flow.from_source(
|
|
1694
|
+
source="https://github.com/org/repo.git",
|
|
1695
|
+
entrypoint="flows.py:my_flow",
|
|
1696
|
+
).deploy(
|
|
1697
|
+
"example-deployment",
|
|
1698
|
+
work_pool_name="my-work-pool",
|
|
1699
|
+
image="my-repository/my-image:dev",
|
|
1700
|
+
)
|
|
1701
|
+
```
|
|
1702
|
+
"""
|
|
1703
|
+
return from_sync.call_soon_in_loop_thread(
|
|
1704
|
+
create_call(
|
|
1705
|
+
self.adeploy,
|
|
1706
|
+
name=name,
|
|
1707
|
+
work_pool_name=work_pool_name,
|
|
1708
|
+
image=image,
|
|
1709
|
+
build=build,
|
|
1710
|
+
push=push,
|
|
1711
|
+
work_queue_name=work_queue_name,
|
|
1712
|
+
job_variables=job_variables,
|
|
1713
|
+
interval=interval,
|
|
1714
|
+
cron=cron,
|
|
1715
|
+
rrule=rrule,
|
|
1716
|
+
paused=paused,
|
|
1717
|
+
schedule=schedule,
|
|
1718
|
+
schedules=schedules,
|
|
1719
|
+
concurrency_limit=concurrency_limit,
|
|
1720
|
+
triggers=triggers,
|
|
1721
|
+
parameters=parameters,
|
|
1722
|
+
description=description,
|
|
1723
|
+
tags=tags,
|
|
1724
|
+
version=version,
|
|
1725
|
+
version_type=version_type,
|
|
1726
|
+
enforce_parameter_schema=enforce_parameter_schema,
|
|
1727
|
+
entrypoint_type=entrypoint_type,
|
|
1728
|
+
print_next_steps=print_next_steps,
|
|
1729
|
+
ignore_warnings=ignore_warnings,
|
|
1730
|
+
_sla=_sla,
|
|
1731
|
+
)
|
|
1732
|
+
).result()
|
|
1733
|
+
|
|
1606
1734
|
@overload
|
|
1607
1735
|
def __call__(self: "Flow[P, NoReturn]", *args: P.args, **kwargs: P.kwargs) -> None:
|
|
1608
1736
|
# `NoReturn` matches if a type can't be inferred for the function which stops a
|
prefect/runner/runner.py
CHANGED
|
@@ -1448,6 +1448,51 @@ class Runner:
|
|
|
1448
1448
|
)
|
|
1449
1449
|
return state
|
|
1450
1450
|
|
|
1451
|
+
async def _handle_cancellation_observer_failure(self) -> None:
|
|
1452
|
+
"""Handle failure of the cancellation observer.
|
|
1453
|
+
|
|
1454
|
+
This is called when both the websocket and polling mechanisms for detecting
|
|
1455
|
+
cancellation events have failed. Without cancellation observing, flow runs
|
|
1456
|
+
cannot be cancelled and may run indefinitely.
|
|
1457
|
+
|
|
1458
|
+
Behavior depends on the `PREFECT_RUNNER_CRASH_ON_CANCELLATION_FAILURE` setting:
|
|
1459
|
+
- When enabled: kills all in-flight flow run processes, which triggers crash
|
|
1460
|
+
handling when the processes terminate, and stops the runner
|
|
1461
|
+
- When disabled (default): logs an error but allows execution to continue
|
|
1462
|
+
"""
|
|
1463
|
+
will_crash = get_current_settings().runner.crash_on_cancellation_failure
|
|
1464
|
+
crash_message = (
|
|
1465
|
+
"Cancellation observing failed - both websocket and polling mechanisms "
|
|
1466
|
+
"are unavailable. Killing flow run process to prevent indefinite execution."
|
|
1467
|
+
)
|
|
1468
|
+
continue_message = (
|
|
1469
|
+
"Cancellation observing failed - both websocket and polling mechanisms "
|
|
1470
|
+
"are unavailable. Flow run will continue executing but cannot be "
|
|
1471
|
+
"cancelled. Set PREFECT_RUNNER_CRASH_ON_CANCELLATION_FAILURE=true to "
|
|
1472
|
+
"crash flow runs and shut down the runner when this occurs."
|
|
1473
|
+
)
|
|
1474
|
+
|
|
1475
|
+
if will_crash:
|
|
1476
|
+
self.stopping = True
|
|
1477
|
+
|
|
1478
|
+
# Copy to list to avoid dictionary size changing during iteration
|
|
1479
|
+
process_entries = list(self._flow_run_process_map.items())
|
|
1480
|
+
for flow_run_id, process_entry in process_entries:
|
|
1481
|
+
flow_run = process_entry["flow_run"]
|
|
1482
|
+
run_logger = self._get_flow_run_logger(flow_run)
|
|
1483
|
+
if will_crash:
|
|
1484
|
+
run_logger.error(crash_message)
|
|
1485
|
+
pid = process_entry.get("pid")
|
|
1486
|
+
if pid:
|
|
1487
|
+
try:
|
|
1488
|
+
await self._kill_process(pid)
|
|
1489
|
+
except Exception:
|
|
1490
|
+
run_logger.exception(
|
|
1491
|
+
f"Failed to kill process {pid} for flow run '{flow_run.id}'"
|
|
1492
|
+
)
|
|
1493
|
+
else:
|
|
1494
|
+
run_logger.warning(continue_message)
|
|
1495
|
+
|
|
1451
1496
|
async def _mark_flow_run_as_cancelled(
|
|
1452
1497
|
self, flow_run: "FlowRun", state_updates: Optional[dict[str, Any]] = None
|
|
1453
1498
|
) -> None:
|
|
@@ -1561,6 +1606,9 @@ class Runner:
|
|
|
1561
1606
|
on_cancelling=lambda flow_run_id: self._runs_task_group.start_soon(
|
|
1562
1607
|
self._cancel_run, flow_run_id
|
|
1563
1608
|
),
|
|
1609
|
+
on_failure=lambda _: self._runs_task_group.start_soon(
|
|
1610
|
+
self._handle_cancellation_observer_failure
|
|
1611
|
+
),
|
|
1564
1612
|
polling_interval=self.query_seconds,
|
|
1565
1613
|
)
|
|
1566
1614
|
)
|
|
@@ -225,8 +225,10 @@ class SetEndTime(
|
|
|
225
225
|
|
|
226
226
|
# if entering a final state...
|
|
227
227
|
if context.proposed_state.is_final():
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
if not context.run.end_time:
|
|
229
|
+
# Set start_time if not set (for flows that fail before execution)
|
|
230
|
+
if not context.run.start_time:
|
|
231
|
+
context.run.start_time = context.proposed_state.timestamp
|
|
230
232
|
context.run.end_time = context.proposed_state.timestamp
|
|
231
233
|
|
|
232
234
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as o,j as e,L as t}from"./vendor-tanstack-BK8oseNA.js";import{L as n}from"./lazy-markdown-
|
|
2
|
-
//# sourceMappingURL=artifact-card-
|
|
1
|
+
import{r as o,j as e,L as t}from"./vendor-tanstack-BK8oseNA.js";import{L as n}from"./lazy-markdown-CPQjrQrX.js";import{aM as i,C as m,m as x,al as r,o as c,aW as d}from"./index-Yzhlw6-Q.js";const f=({artifact:s,compact:a=!1})=>{const l=o.useMemo(()=>i(new Date(s.created??""),"dateTime"),[s.created]);return e.jsx(t,{to:"/artifacts/key/$key",params:{key:s.key??""},children:e.jsxs(m,{className:"hover:shadow-lg hover:border-blue-700",children:[e.jsx(x,{children:e.jsx(r,{variant:"bodySmall",className:"font-bold text-muted-foreground",children:s.type?.toUpperCase()})}),e.jsxs(c,{children:[e.jsxs("div",{className:d("flex",a?"flex-row justify-between":"flex-col"),children:[e.jsx(r,{variant:a?"h4":"h3",className:"font-bold",children:s.key}),e.jsxs("div",{className:d("flex mt-2",a?"flex-col-reverse items-end":"justify-between"),children:[e.jsx(r,{variant:a?"bodySmall":"xsmall",className:"",fontFamily:"mono",children:l}),e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground",children:"Created"})]})]}),e.jsx("hr",{className:"my-2"}),s.description?e.jsx("div",{className:"text-muted-foreground overflow-hidden truncate",children:e.jsx(n,{children:s.description??""})}):e.jsx(r,{variant:"bodySmall",className:"text-muted-foreground italic",children:"No description"})]})]})})};export{f as A};
|
|
2
|
+
//# sourceMappingURL=artifact-card-D41jcvLX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-card-
|
|
1
|
+
{"version":3,"file":"artifact-card-D41jcvLX.js","sources":["../../src/components/artifacts/artifact-card.tsx"],"sourcesContent":["import { Link } from \"@tanstack/react-router\";\nimport { useMemo } from \"react\";\nimport type { Artifact } from \"@/api/artifacts\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { cn } from \"@/utils\";\nimport { formatDate } from \"@/utils/date\";\nimport { Card, CardContent, CardHeader } from \"../ui/card\";\nimport { Typography } from \"../ui/typography\";\n\nexport type ArtifactsCardProps = {\n\tartifact: Artifact;\n\tcompact?: boolean;\n};\n\nexport const ArtifactCard = ({\n\tartifact,\n\tcompact = false,\n}: ArtifactsCardProps) => {\n\tconst createdAtDate = useMemo(() => {\n\t\treturn formatDate(new Date(artifact.created ?? \"\"), \"dateTime\");\n\t}, [artifact.created]);\n\treturn (\n\t\t<Link to=\"/artifacts/key/$key\" params={{ key: artifact.key ?? \"\" }}>\n\t\t\t<Card className=\"hover:shadow-lg hover:border-blue-700\">\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<Typography\n\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\tclassName=\"font-bold text-muted-foreground\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{artifact.type?.toUpperCase()}\n\t\t\t\t\t</Typography>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"flex\",\n\t\t\t\t\t\t\tcompact ? \"flex-row justify-between\" : \"flex-col\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Typography variant={compact ? \"h4\" : \"h3\"} className=\"font-bold\">\n\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\"flex mt-2\",\n\t\t\t\t\t\t\t\tcompact ? \"flex-col-reverse items-end\" : \"justify-between\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\t\tvariant={compact ? \"bodySmall\" : \"xsmall\"}\n\t\t\t\t\t\t\t\tclassName=\"\"\n\t\t\t\t\t\t\t\tfontFamily=\"mono\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{createdAtDate}\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t\t<Typography variant=\"bodySmall\" className=\"text-muted-foreground\">\n\t\t\t\t\t\t\t\tCreated\n\t\t\t\t\t\t\t</Typography>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<hr className=\"my-2\" />\n\t\t\t\t\t{artifact.description ? (\n\t\t\t\t\t\t<div className=\"text-muted-foreground overflow-hidden truncate\">\n\t\t\t\t\t\t\t<LazyMarkdown>{artifact.description ?? \"\"}</LazyMarkdown>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<Typography\n\t\t\t\t\t\t\tvariant=\"bodySmall\"\n\t\t\t\t\t\t\tclassName=\"text-muted-foreground italic\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tNo description\n\t\t\t\t\t\t</Typography>\n\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t</Link>\n\t);\n};\n"],"names":["ArtifactCard","artifact","compact","createdAtDate","useMemo","formatDate","jsx","Link","jsxs","Card","CardHeader","Typography","CardContent","cn","LazyMarkdown"],"mappings":"8LAcO,MAAMA,EAAe,CAAC,CAC5B,SAAAC,EACA,QAAAC,EAAU,EACX,IAA0B,CACzB,MAAMC,EAAgBC,EAAAA,QAAQ,IACtBC,EAAW,IAAI,KAAKJ,EAAS,SAAW,EAAE,EAAG,UAAU,EAC5D,CAACA,EAAS,OAAO,CAAC,EACrB,OACCK,EAAAA,IAACC,EAAA,CAAK,GAAG,sBAAsB,OAAQ,CAAE,IAAKN,EAAS,KAAO,EAAA,EAC7D,SAAAO,EAAAA,KAACC,EAAA,CAAK,UAAU,wCACf,SAAA,CAAAH,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,kCAET,SAAAV,EAAS,MAAM,YAAA,CAAY,CAAA,EAE9B,SACCW,EAAA,CACA,SAAA,CAAAJ,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,OACAX,EAAU,2BAA6B,UAAA,EAGxC,SAAA,CAAAI,EAAAA,IAACK,EAAA,CAAW,QAAST,EAAU,KAAO,KAAM,UAAU,YACpD,WAAS,GAAA,CACX,EACAM,EAAAA,KAAC,MAAA,CACA,UAAWK,EACV,YACAX,EAAU,6BAA+B,iBAAA,EAG1C,SAAA,CAAAI,EAAAA,IAACK,EAAA,CACA,QAAST,EAAU,YAAc,SACjC,UAAU,GACV,WAAW,OAEV,SAAAC,CAAA,CAAA,QAEDQ,EAAA,CAAW,QAAQ,YAAY,UAAU,wBAAwB,SAAA,SAAA,CAElE,CAAA,CAAA,CAAA,CACD,CAAA,CAAA,EAEDL,EAAAA,IAAC,KAAA,CAAG,UAAU,MAAA,CAAO,EACpBL,EAAS,YACTK,MAAC,MAAA,CAAI,UAAU,iDACd,SAAAA,EAAAA,IAACQ,EAAA,CAAc,SAAAb,EAAS,aAAe,EAAA,CAAG,CAAA,CAC3C,EAEAK,EAAAA,IAACK,EAAA,CACA,QAAQ,YACR,UAAU,+BACV,SAAA,gBAAA,CAAA,CAED,CAAA,CAEF,CAAA,CAAA,CACD,CAAA,CACD,CAEF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{j as e,r as l,p as y}from"./vendor-tanstack-BK8oseNA.js";import{B as j,g as p,h as c,bs as u,bB as x,D as w,al as h,q as b,I as v,y as N,O as k,dw as D,dv as S}from"./index-
|
|
2
|
-
//# sourceMappingURL=artifact._id-
|
|
1
|
+
import{j as e,r as l,p as y}from"./vendor-tanstack-BK8oseNA.js";import{B as j,g as p,h as c,bs as u,bB as x,D as w,al as h,q as b,I as v,y as N,O as k,dw as D,dv as S}from"./index-Yzhlw6-Q.js";import{a as T}from"./use-get-artifacts-flow-task-runs-C0V3_gYz.js";import{L as f}from"./lazy-markdown-CPQjrQrX.js";import{u as C,E as L}from"./vendor-codemirror-CXN7nd_v.js";import{T as B,a as _,b as g,c as A,d as R,e as I}from"./table-BJkw82b1.js";import"./vendor-react-Bce9NwRC.js";import"./vendor-radix-BZJHvSaq.js";import"./vendor-recharts-D4imLXNl.js";import"./vendor-forms-DxqqmhL5.js";import"./vendor-date-JS-ReHrg.js";const M=({artifact:s})=>{let a=e.jsx(e.Fragment,{});return s.key?a=e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(j,{children:e.jsxs(p,{children:[e.jsx(c,{children:e.jsx(u,{to:"/artifacts/key/$key",params:{key:s.key},className:"text-xl font-semibold",children:s.key})}),e.jsx(x,{}),e.jsx(c,{className:"text-xl font-semibold",children:s.id})]})})}):a=e.jsx("div",{className:"flex items-center gap-2",children:e.jsx(j,{children:e.jsxs(p,{children:[s.flow_run&&e.jsxs(e.Fragment,{children:[e.jsx(c,{children:e.jsx(u,{to:"/runs/flow-run/$id",params:{id:s.flow_run_id??""},className:"text-xl font-semibold",children:s.flow_run.name})}),e.jsx(x,{})]}),s.task_run&&e.jsxs(e.Fragment,{children:[e.jsx(c,{children:e.jsx(u,{to:"/runs/task-run/$id",params:{id:s.task_run_id??""},className:"text-xl font-semibold",children:s.task_run.name})}),e.jsx(x,{})]}),e.jsx(c,{className:"text-xl font-semibold",children:s.id})]})})}),e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex items-center justify-between",children:[a,e.jsx(w,{id:"artifacts-guide",label:"Documentation"})]}),s.description&&e.jsx("div",{className:"",children:e.jsx(h,{variant:"h2",className:"my-4 font-bold prose lg:prose-xl",children:e.jsx(f,{children:s.description})})}),e.jsx("hr",{})]})},E=({artifact:s})=>{const[a,r]=l.useState(!1),d=()=>{r(o=>!o)},n=l.useRef(null),m={highlightActiveLine:!1,foldGutter:!1,highlightActiveLineGutter:!1},{setContainer:t}=C({container:n.current,extensions:[L.lineWrapping],value:String(s.data),indentWithTab:!1,editable:!0,basicSetup:m});l.useEffect(()=>{n.current&&t(n.current)},[t]);const i=o=>{N.success("Copied to clipboard"),navigator.clipboard.writeText(o)};return e.jsxs("div",{className:"flex flex-col justify-center items-center",children:[e.jsxs(b,{"data-testid":"show-raw-data-button",variant:"outline",onClick:d,className:"my-4",children:[a?"Hide":"Show"," Raw Data"]}),e.jsx("div",{className:"rounded-md border shadow-xs focus-within:outline-hidden focus-within:ring-1 focus-within:ring-ring relative",style:{display:a?"block":"none"},ref:o=>{n.current=o},"data-testid":"raw-data-display",children:e.jsx(b,{onClick:()=>i(s.data),variant:"ghost",size:"icon",className:"absolute top-0 right-0 z-10","aria-label":"copy",children:e.jsx(v,{id:"Copy",className:"size-2"})})})]})},F=({url:s})=>e.jsxs("div",{"data-testid":s,className:"prose mt-2",children:[e.jsx("img",{"data-testid":`image-${s}`,src:s,alt:"artifact-image",className:"w-full"}),e.jsxs(h,{variant:"bodyLarge",children:["Image URL:"," ",e.jsx("a",{className:"text-blue-700 hover:underline",target:"_blank",href:s,rel:"noreferrer",children:s})]})]}),H=({markdown:s})=>e.jsx("div",{"data-testid":"markdown-display",className:"mt-4 prose",children:e.jsx(f,{children:s})}),O=({progress:s})=>e.jsxs(h,{"data-testid":"progress-display",variant:"bodyLarge",children:["Progress: ",s,"%"]}),z=({tableData:s})=>{const a=JSON.parse(s),r=Object.keys(a[0]),[d,n]=l.useState(""),m=l.useMemo(()=>a.filter(t=>Object.values(t).some(i=>String(i).toLowerCase().includes(d.toLowerCase()))),[d,a]);return e.jsxs("div",{"data-testid":"table-display",className:"mt-4",children:[e.jsx("div",{className:"flex flex-row justify-end items-center mb-2",children:e.jsx("div",{children:e.jsx(k,{placeholder:"Search",value:d,onChange:t=>n(t.target.value)})})}),e.jsx("div",{className:"rounded-md border",children:e.jsxs(B,{children:[e.jsx(_,{className:"bg-muted",children:e.jsx(g,{children:r.map(t=>e.jsx(A,{className:"py-2 text-foreground",children:t},t))})}),e.jsx(R,{children:m.map(t=>e.jsx(g,{children:r.map(i=>e.jsx(I,{children:t[i]},i))},t.id))})]})})]})},G=({artifact:s})=>{const a=l.useMemo(()=>{switch(s.type){case"markdown":case"link":return e.jsx(H,{markdown:s.data});case"image":return e.jsx(F,{url:s.data});case"progress":return e.jsx(O,{progress:s.data});case"table":return e.jsx(z,{tableData:s.data});default:return e.jsx("pre",{children:JSON.stringify(s.data,null,2)})}},[s]);return e.jsxs("div",{children:[e.jsx(M,{artifact:s}),a,e.jsx(E,{artifact:s})]})};function Z(){const{id:s}=D.useParams(),{data:a}=y(S(s)),r=T(s);return e.jsx(G,{artifact:r??a})}export{Z as component};
|
|
2
|
+
//# sourceMappingURL=artifact._id-CYMvBFBb.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact._id-C7yJhkKY.js","sources":["../../src/components/artifacts/artifact/artifact-detail-header.tsx","../../src/components/artifacts/artifact/artifact-raw-data-display.tsx","../../src/components/artifacts/artifact/detail-image.tsx","../../src/components/artifacts/artifact/detail-markdown.tsx","../../src/components/artifacts/artifact/detail-progress.tsx","../../src/components/artifacts/artifact/detail-table.tsx","../../src/components/artifacts/artifact/artifact-detail-page.tsx","../../src/routes/artifacts/artifact.$id.tsx?tsr-split=component"],"sourcesContent":["import type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport {\n\tBreadcrumb,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbList,\n\tBreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { Typography } from \"@/components/ui/typography\";\n\nexport type ArtifactDetailHeaderProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailHeader = ({\n\tartifact,\n}: ArtifactDetailHeaderProps) => {\n\tlet header = <></>;\n\tif (artifact.key) {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\tto=\"/artifacts/key/$key\"\n\t\t\t\t\t\t\t\tparams={{ key: artifact.key }}\n\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t} else {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t{artifact.flow_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/flow-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.flow_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.flow_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{artifact.task_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/task-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.task_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.task_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t}\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t{header}\n\t\t\t\t<DocsLink id=\"artifacts-guide\" label=\"Documentation\" />\n\t\t\t</div>\n\t\t\t{artifact.description && (\n\t\t\t\t<div className=\"\">\n\t\t\t\t\t<Typography variant=\"h2\" className=\"my-4 font-bold prose lg:prose-xl\">\n\t\t\t\t\t\t<LazyMarkdown>{artifact.description}</LazyMarkdown>\n\t\t\t\t\t</Typography>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<hr />\n\t\t</>\n\t);\n};\n","import { EditorView, useCodeMirror } from \"@uiw/react-codemirror\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { Button } from \"@/components/ui/button\";\nimport { Icon } from \"@/components/ui/icons\";\n\ntype ArtifactDataDisplayProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDataDisplay = ({ artifact }: ArtifactDataDisplayProps) => {\n\tconst [showData, setShowData] = useState(false);\n\n\tconst toggleShowData = () => {\n\t\tsetShowData((val) => !val);\n\t};\n\n\tconst editor = useRef<HTMLDivElement | null>(null);\n\tconst basicSetup = {\n\t\thighlightActiveLine: false,\n\t\tfoldGutter: false,\n\t\thighlightActiveLineGutter: false,\n\t};\n\tconst { setContainer } = useCodeMirror({\n\t\tcontainer: editor.current,\n\t\textensions: [EditorView.lineWrapping],\n\t\tvalue: String(artifact.data),\n\t\tindentWithTab: false,\n\t\teditable: true,\n\t\tbasicSetup,\n\t});\n\n\tuseEffect(() => {\n\t\tif (editor.current) {\n\t\t\tsetContainer(editor.current);\n\t\t}\n\t}, [setContainer]);\n\n\tconst handleCopy = (_value: string) => {\n\t\ttoast.success(\"Copied to clipboard\");\n\t\tvoid navigator.clipboard.writeText(_value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col justify-center items-center\">\n\t\t\t<Button\n\t\t\t\tdata-testid=\"show-raw-data-button\"\n\t\t\t\tvariant={\"outline\"}\n\t\t\t\tonClick={toggleShowData}\n\t\t\t\tclassName=\"my-4\"\n\t\t\t>\n\t\t\t\t{showData ? \"Hide\" : \"Show\"} Raw Data\n\t\t\t</Button>\n\n\t\t\t<div\n\t\t\t\tclassName=\"rounded-md border shadow-xs focus-within:outline-hidden focus-within:ring-1 focus-within:ring-ring relative\"\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: showData ? \"block\" : \"none\",\n\t\t\t\t}}\n\t\t\t\tref={(node) => {\n\t\t\t\t\teditor.current = node;\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"raw-data-display\"\n\t\t\t>\n\t\t\t\t<Button\n\t\t\t\t\tonClick={() => handleCopy(artifact.data as string)}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\tclassName=\"absolute top-0 right-0 z-10\"\n\t\t\t\t\taria-label=\"copy\"\n\t\t\t\t>\n\t\t\t\t\t<Icon id=\"Copy\" className=\"size-2\" />\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailImageProps = {\n\turl: string;\n};\n\nexport const DetailImage = ({ url }: DetailImageProps) => {\n\treturn (\n\t\t<div data-testid={url} className=\"prose mt-2\">\n\t\t\t<img\n\t\t\t\tdata-testid={`image-${url}`}\n\t\t\t\tsrc={url}\n\t\t\t\talt=\"artifact-image\"\n\t\t\t\tclassName=\"w-full\"\n\t\t\t/>\n\n\t\t\t<Typography variant=\"bodyLarge\">\n\t\t\t\tImage URL:{\" \"}\n\t\t\t\t<a\n\t\t\t\t\tclassName=\"text-blue-700 hover:underline\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\thref={url}\n\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t>\n\t\t\t\t\t{url}\n\t\t\t\t</a>\n\t\t\t</Typography>\n\t\t</div>\n\t);\n};\n","import { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\n\nexport type DetailMarkdownProps = {\n\tmarkdown: string;\n};\n\nexport const DetailMarkdown = ({ markdown }: DetailMarkdownProps) => {\n\treturn (\n\t\t<div data-testid=\"markdown-display\" className=\"mt-4 prose\">\n\t\t\t<LazyMarkdown>{markdown}</LazyMarkdown>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailProgressProps = {\n\tprogress: number;\n};\n\nexport const DetailProgress = ({ progress }: DetailProgressProps) => {\n\treturn (\n\t\t<Typography data-testid=\"progress-display\" variant=\"bodyLarge\">\n\t\t\tProgress: {progress}%\n\t\t</Typography>\n\t);\n};\n","import { useMemo, useState } from \"react\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRow,\n} from \"@/components/ui/table\";\n\nexport type DetailTableProps = {\n\ttableData: string;\n};\n\nexport const DetailTable = ({ tableData }: DetailTableProps) => {\n\tconst table = JSON.parse(tableData) as Record<string, string>[];\n\tconst headers = Object.keys(table[0]);\n\tconst [input, setInput] = useState<string>(\"\");\n\n\tconst filteredTable = useMemo(() => {\n\t\treturn table.filter((row) => {\n\t\t\treturn Object.values(row).some((value: string) =>\n\t\t\t\tString(value).toLowerCase().includes(input.toLowerCase()),\n\t\t\t);\n\t\t});\n\t}, [input, table]);\n\n\treturn (\n\t\t<div data-testid=\"table-display\" className=\"mt-4\">\n\t\t\t<div className=\"flex flex-row justify-end items-center mb-2\">\n\t\t\t\t<div>\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tvalue={input}\n\t\t\t\t\t\tonChange={(e) => setInput(e.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"rounded-md border\">\n\t\t\t\t<Table>\n\t\t\t\t\t<TableHeader className=\"bg-muted\">\n\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<TableHead key={header} className=\"py-2 text-foreground\">\n\t\t\t\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t</TableHeader>\n\t\t\t\t\t<TableBody>\n\t\t\t\t\t\t{filteredTable.map((row) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TableRow key={row.id}>\n\t\t\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\t\t\treturn <TableCell key={header}>{row[header]}</TableCell>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TableBody>\n\t\t\t\t</Table>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useMemo } from \"react\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { ArtifactDetailHeader } from \"./artifact-detail-header\";\nimport { ArtifactDataDisplay } from \"./artifact-raw-data-display\";\nimport { DetailImage } from \"./detail-image\";\nimport { DetailMarkdown } from \"./detail-markdown\";\nimport { DetailProgress } from \"./detail-progress\";\nimport { DetailTable } from \"./detail-table\";\n\nexport type ArtifactDetailPageProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailPage = ({ artifact }: ArtifactDetailPageProps) => {\n\tconst mapArtifactHoc = useMemo(() => {\n\t\tswitch (artifact.type) {\n\t\t\tcase \"markdown\":\n\t\t\tcase \"link\":\n\t\t\t\treturn <DetailMarkdown markdown={artifact.data as string} />;\n\t\t\tcase \"image\":\n\t\t\t\treturn <DetailImage url={artifact.data as string} />;\n\t\t\tcase \"progress\":\n\t\t\t\treturn <DetailProgress progress={artifact.data as number} />;\n\t\t\tcase \"table\":\n\t\t\t\treturn <DetailTable tableData={artifact.data as string} />;\n\t\t\tdefault:\n\t\t\t\treturn <pre>{JSON.stringify(artifact.data, null, 2)}</pre>;\n\t\t}\n\t}, [artifact]);\n\treturn (\n\t\t<div>\n\t\t\t<ArtifactDetailHeader artifact={artifact} />\n\t\t\t{mapArtifactHoc}\n\t\t\t<ArtifactDataDisplay artifact={artifact} />\n\t\t</div>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { buildGetArtifactQuery } from \"@/api/artifacts\";\nimport { useGetArtifactFlowTaskRuns } from \"@/api/artifacts/use-get-artifacts-flow-task-runs/use-get-artifacts-flow-task-runs\";\nimport { ArtifactDetailPage } from \"@/components/artifacts/artifact/artifact-detail-page\";\n\nexport const Route = createFileRoute(\"/artifacts/artifact/$id\")({\n\tcomponent: RouteComponent,\n\tloader: async ({ context, params }) => {\n\t\tconst { id } = params;\n\n\t\tconst artifact = await context.queryClient.ensureQueryData(\n\t\t\tbuildGetArtifactQuery(id),\n\t\t);\n\n\t\treturn { artifact };\n\t},\n});\n\nfunction RouteComponent() {\n\tconst { id } = Route.useParams();\n\n\tconst { data: artifact } = useSuspenseQuery(buildGetArtifactQuery(id));\n\n\tconst artifactWithMetadata = useGetArtifactFlowTaskRuns(id);\n\n\treturn <ArtifactDetailPage artifact={artifactWithMetadata ?? artifact} />;\n}\n"],"names":["ArtifactDetailHeader","artifact","header","jsx","Fragment","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","jsxs","DocsLink","Typography","LazyMarkdown","ArtifactDataDisplay","showData","setShowData","useState","toggleShowData","val","editor","useRef","basicSetup","setContainer","useCodeMirror","EditorView","useEffect","handleCopy","_value","toast","Button","node","Icon","DetailImage","url","DetailMarkdown","markdown","DetailProgress","progress","DetailTable","tableData","table","headers","input","setInput","filteredTable","useMemo","row","value","SearchInput","e","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","ArtifactDetailPage","mapArtifactHoc","RouteComponent","id","Route","useParams","data","useSuspenseQuery","buildGetArtifactQuery","artifactWithMetadata","useGetArtifactFlowTaskRuns"],"mappings":"2mBAgBO,MAAMA,EAAuB,CAAC,CACpC,SAAAC,CACD,IAAiC,CAChC,IAAIC,EAASC,EAAAA,IAAAC,EAAAA,SAAA,EAAE,EACf,OAAIH,EAAS,IACZC,QACE,MAAA,CAAI,UAAU,0BACd,SAAAC,MAACE,EAAA,CACA,gBAACC,EAAA,CACA,SAAA,CAAAH,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,GAAG,sBACH,OAAQ,CAAE,IAAKP,EAAS,GAAA,EACxB,UAAU,wBAET,SAAAA,EAAS,GAAA,CAAA,EAEZ,QACCQ,EAAA,EAAoB,EACrBN,EAAAA,IAACI,EAAA,CAAe,UAAU,wBACxB,WAAS,EAAA,CACX,CAAA,CAAA,CACD,EACD,EACD,EAGDL,QACE,MAAA,CAAI,UAAU,0BACd,SAAAC,MAACE,EAAA,CACA,gBAACC,EAAA,CACC,SAAA,CAAAL,EAAS,UACTS,EAAAA,KAAAN,EAAAA,SAAA,CACC,SAAA,CAAAD,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,GAAG,qBACH,OAAQ,CAAE,GAAIP,EAAS,aAAe,EAAA,EACtC,UAAU,wBAET,WAAS,SAAS,IAAA,CAAA,EAErB,QACCQ,EAAA,CAAA,CAAoB,CAAA,EACtB,EAEAR,EAAS,UACTS,EAAAA,KAAAN,EAAAA,SAAA,CACC,SAAA,CAAAD,MAACI,EAAA,CACA,SAAAJ,EAAAA,IAACK,EAAA,CACA,GAAG,qBACH,OAAQ,CAAE,GAAIP,EAAS,aAAe,EAAA,EACtC,UAAU,wBAET,WAAS,SAAS,IAAA,CAAA,EAErB,QACCQ,EAAA,CAAA,CAAoB,CAAA,EACtB,EAEDN,EAAAA,IAACI,EAAA,CAAe,UAAU,wBACxB,WAAS,EAAA,CACX,CAAA,CAAA,CACD,EACD,EACD,EAIDG,EAAAA,KAAAN,WAAA,CACC,SAAA,CAAAM,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAR,EACDC,EAAAA,IAACQ,EAAA,CAAS,GAAG,kBAAkB,MAAM,eAAA,CAAgB,CAAA,EACtD,EACCV,EAAS,aACTE,MAAC,MAAA,CAAI,UAAU,GACd,SAAAA,EAAAA,IAACS,EAAA,CAAW,QAAQ,KAAK,UAAU,mCAClC,SAAAT,EAAAA,IAACU,GAAc,SAAAZ,EAAS,YAAY,EACrC,CAAA,CACD,QAEA,KAAA,CAAA,CAAG,CAAA,EACL,CAEF,ECxFaa,EAAsB,CAAC,CAAE,SAAAb,KAAyC,CAC9E,KAAM,CAACc,EAAUC,CAAW,EAAIC,EAAAA,SAAS,EAAK,EAExCC,EAAiB,IAAM,CAC5BF,EAAaG,GAAQ,CAACA,CAAG,CAC1B,EAEMC,EAASC,EAAAA,OAA8B,IAAI,EAC3CC,EAAa,CAClB,oBAAqB,GACrB,WAAY,GACZ,0BAA2B,EAAA,EAEtB,CAAE,aAAAC,CAAA,EAAiBC,EAAc,CACtC,UAAWJ,EAAO,QAClB,WAAY,CAACK,EAAW,YAAY,EACpC,MAAO,OAAOxB,EAAS,IAAI,EAC3B,cAAe,GACf,SAAU,GACV,WAAAqB,CAAA,CACA,EAEDI,EAAAA,UAAU,IAAM,CACXN,EAAO,SACVG,EAAaH,EAAO,OAAO,CAE7B,EAAG,CAACG,CAAY,CAAC,EAEjB,MAAMI,EAAcC,GAAmB,CACtCC,EAAM,QAAQ,qBAAqB,EAC9B,UAAU,UAAU,UAAUD,CAAM,CAC1C,EAEA,OACClB,EAAAA,KAAC,MAAA,CAAI,UAAU,4CACd,SAAA,CAAAA,EAAAA,KAACoB,EAAA,CACA,cAAY,uBACZ,QAAS,UACT,QAASZ,EACT,UAAU,OAET,SAAA,CAAAH,EAAW,OAAS,OAAO,WAAA,CAAA,CAAA,EAG7BZ,EAAAA,IAAC,MAAA,CACA,UAAU,8GACV,MAAO,CACN,QAASY,EAAW,QAAU,MAAA,EAE/B,IAAMgB,GAAS,CACdX,EAAO,QAAUW,CAClB,EACA,cAAY,mBAEZ,SAAA5B,EAAAA,IAAC2B,EAAA,CACA,QAAS,IAAMH,EAAW1B,EAAS,IAAc,EACjD,QAAQ,QACR,KAAK,OACL,UAAU,8BACV,aAAW,OAEX,SAAAE,EAAAA,IAAC6B,EAAA,CAAK,GAAG,OAAO,UAAU,QAAA,CAAS,CAAA,CAAA,CACpC,CAAA,CACD,EACD,CAEF,ECvEaC,EAAc,CAAC,CAAE,IAAAC,KAE5BxB,EAAAA,KAAC,MAAA,CAAI,cAAawB,EAAK,UAAU,aAChC,SAAA,CAAA/B,EAAAA,IAAC,MAAA,CACA,cAAa,SAAS+B,CAAG,GACzB,IAAKA,EACL,IAAI,iBACJ,UAAU,QAAA,CAAA,EAGXxB,EAAAA,KAACE,EAAA,CAAW,QAAQ,YAAY,SAAA,CAAA,aACpB,IACXT,EAAAA,IAAC,IAAA,CACA,UAAU,gCACV,OAAO,SACP,KAAM+B,EACN,IAAI,aAEH,SAAAA,CAAA,CAAA,CACF,CAAA,CACD,CAAA,EACD,ECrBWC,EAAiB,CAAC,CAAE,SAAAC,KAE/BjC,EAAAA,IAAC,OAAI,cAAY,mBAAmB,UAAU,aAC7C,SAAAA,EAAAA,IAACU,EAAA,CAAc,SAAAuB,CAAA,CAAS,CAAA,CACzB,ECJWC,EAAiB,CAAC,CAAE,SAAAC,KAE/B5B,EAAAA,KAACE,EAAA,CAAW,cAAY,mBAAmB,QAAQ,YAAY,SAAA,CAAA,aACnD0B,EAAS,GAAA,EACrB,ECKWC,EAAc,CAAC,CAAE,UAAAC,KAAkC,CAC/D,MAAMC,EAAQ,KAAK,MAAMD,CAAS,EAC5BE,EAAU,OAAO,KAAKD,EAAM,CAAC,CAAC,EAC9B,CAACE,EAAOC,CAAQ,EAAI3B,EAAAA,SAAiB,EAAE,EAEvC4B,EAAgBC,EAAAA,QAAQ,IACtBL,EAAM,OAAQM,GACb,OAAO,OAAOA,CAAG,EAAE,KAAMC,GAC/B,OAAOA,CAAK,EAAE,cAAc,SAASL,EAAM,YAAA,CAAa,CAAA,CAEzD,EACC,CAACA,EAAOF,CAAK,CAAC,EAEjB,OACC/B,EAAAA,KAAC,MAAA,CAAI,cAAY,gBAAgB,UAAU,OAC1C,SAAA,CAAAP,MAAC,MAAA,CAAI,UAAU,8CACd,SAAAA,MAAC,MAAA,CACA,SAAAA,EAAAA,IAAC8C,EAAA,CACA,YAAY,SACZ,MAAON,EACP,SAAWO,GAAMN,EAASM,EAAE,OAAO,KAAK,CAAA,CAAA,EAE1C,CAAA,CACD,EACA/C,MAAC,MAAA,CAAI,UAAU,oBACd,gBAACgD,EAAA,CACA,SAAA,CAAAhD,EAAAA,IAACiD,EAAA,CAAY,UAAU,WACtB,SAAAjD,EAAAA,IAACkD,GACC,SAAAX,EAAQ,IAAKxC,GAEZC,EAAAA,IAACmD,EAAA,CAAuB,UAAU,uBAChC,YADcpD,CAEhB,CAED,EACF,EACD,EACAC,EAAAA,IAACoD,EAAA,CACC,SAAAV,EAAc,IAAKE,GAElB5C,EAAAA,IAACkD,EAAA,CACC,SAAAX,EAAQ,IAAKxC,GACNC,EAAAA,IAACqD,EAAA,CAAwB,SAAAT,EAAI7C,CAAM,GAAnBA,CAAqB,CAC5C,CAAA,EAHa6C,EAAI,EAInB,CAED,CAAA,CACF,CAAA,CAAA,CACD,CAAA,CACD,CAAA,EACD,CAEF,ECtDaU,EAAqB,CAAC,CAAE,SAAAxD,KAAwC,CAC5E,MAAMyD,EAAiBZ,EAAAA,QAAQ,IAAM,CACpC,OAAQ7C,EAAS,KAAA,CAChB,IAAK,WACL,IAAK,OACJ,OAAOE,EAAAA,IAACgC,EAAA,CAAe,SAAUlC,EAAS,IAAA,CAAgB,EAC3D,IAAK,QACJ,OAAOE,EAAAA,IAAC8B,EAAA,CAAY,IAAKhC,EAAS,IAAA,CAAgB,EACnD,IAAK,WACJ,OAAOE,EAAAA,IAACkC,EAAA,CAAe,SAAUpC,EAAS,IAAA,CAAgB,EAC3D,IAAK,QACJ,OAAOE,EAAAA,IAACoC,EAAA,CAAY,UAAWtC,EAAS,IAAA,CAAgB,EACzD,QACC,OAAOE,MAAC,OAAK,SAAA,KAAK,UAAUF,EAAS,KAAM,KAAM,CAAC,CAAA,CAAE,CAAA,CAEvD,EAAG,CAACA,CAAQ,CAAC,EACb,cACE,MAAA,CACA,SAAA,CAAAE,MAACH,GAAqB,SAAAC,EAAoB,EACzCyD,EACDvD,MAACW,GAAoB,SAAAb,CAAA,CAAoB,CAAA,EAC1C,CAEF,ECjBA,SAAS0D,GAAiB,CACzB,KAAM,CAAEC,GAAAA,CAAAA,EAAOC,EAAMC,UAAAA,EAEf,CAAEC,KAAM9D,CAAAA,EAAa+D,EAAiBC,EAAsBL,CAAE,CAAC,EAE/DM,EAAuBC,EAA2BP,CAAE,EAE1D,OAAOzD,EAAAA,IAACsD,EAAA,CAAmB,SAAUS,GAAwBjE,CAAAA,CAAS,CACvE"}
|
|
1
|
+
{"version":3,"file":"artifact._id-CYMvBFBb.js","sources":["../../src/components/artifacts/artifact/artifact-detail-header.tsx","../../src/components/artifacts/artifact/artifact-raw-data-display.tsx","../../src/components/artifacts/artifact/detail-image.tsx","../../src/components/artifacts/artifact/detail-markdown.tsx","../../src/components/artifacts/artifact/detail-progress.tsx","../../src/components/artifacts/artifact/detail-table.tsx","../../src/components/artifacts/artifact/artifact-detail-page.tsx","../../src/routes/artifacts/artifact.$id.tsx?tsr-split=component"],"sourcesContent":["import type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport {\n\tBreadcrumb,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbList,\n\tBreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { DocsLink } from \"@/components/ui/docs-link\";\nimport { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\nimport { Typography } from \"@/components/ui/typography\";\n\nexport type ArtifactDetailHeaderProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailHeader = ({\n\tartifact,\n}: ArtifactDetailHeaderProps) => {\n\tlet header = <></>;\n\tif (artifact.key) {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\tto=\"/artifacts/key/$key\"\n\t\t\t\t\t\t\t\tparams={{ key: artifact.key }}\n\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{artifact.key}\n\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t} else {\n\t\theader = (\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<Breadcrumb>\n\t\t\t\t\t<BreadcrumbList>\n\t\t\t\t\t\t{artifact.flow_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/flow-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.flow_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.flow_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{artifact.task_run && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\t\t\t\tto=\"/runs/task-run/$id\"\n\t\t\t\t\t\t\t\t\t\tparams={{ id: artifact.task_run_id ?? \"\" }}\n\t\t\t\t\t\t\t\t\t\tclassName=\"text-xl font-semibold\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{artifact.task_run.name}\n\t\t\t\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<BreadcrumbItem className=\"text-xl font-semibold\">\n\t\t\t\t\t\t\t{artifact.id}\n\t\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t\t</BreadcrumbList>\n\t\t\t\t</Breadcrumb>\n\t\t\t</div>\n\t\t);\n\t}\n\treturn (\n\t\t<>\n\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t{header}\n\t\t\t\t<DocsLink id=\"artifacts-guide\" label=\"Documentation\" />\n\t\t\t</div>\n\t\t\t{artifact.description && (\n\t\t\t\t<div className=\"\">\n\t\t\t\t\t<Typography variant=\"h2\" className=\"my-4 font-bold prose lg:prose-xl\">\n\t\t\t\t\t\t<LazyMarkdown>{artifact.description}</LazyMarkdown>\n\t\t\t\t\t</Typography>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<hr />\n\t\t</>\n\t);\n};\n","import { EditorView, useCodeMirror } from \"@uiw/react-codemirror\";\nimport { useEffect, useRef, useState } from \"react\";\nimport { toast } from \"sonner\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { Button } from \"@/components/ui/button\";\nimport { Icon } from \"@/components/ui/icons\";\n\ntype ArtifactDataDisplayProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDataDisplay = ({ artifact }: ArtifactDataDisplayProps) => {\n\tconst [showData, setShowData] = useState(false);\n\n\tconst toggleShowData = () => {\n\t\tsetShowData((val) => !val);\n\t};\n\n\tconst editor = useRef<HTMLDivElement | null>(null);\n\tconst basicSetup = {\n\t\thighlightActiveLine: false,\n\t\tfoldGutter: false,\n\t\thighlightActiveLineGutter: false,\n\t};\n\tconst { setContainer } = useCodeMirror({\n\t\tcontainer: editor.current,\n\t\textensions: [EditorView.lineWrapping],\n\t\tvalue: String(artifact.data),\n\t\tindentWithTab: false,\n\t\teditable: true,\n\t\tbasicSetup,\n\t});\n\n\tuseEffect(() => {\n\t\tif (editor.current) {\n\t\t\tsetContainer(editor.current);\n\t\t}\n\t}, [setContainer]);\n\n\tconst handleCopy = (_value: string) => {\n\t\ttoast.success(\"Copied to clipboard\");\n\t\tvoid navigator.clipboard.writeText(_value);\n\t};\n\n\treturn (\n\t\t<div className=\"flex flex-col justify-center items-center\">\n\t\t\t<Button\n\t\t\t\tdata-testid=\"show-raw-data-button\"\n\t\t\t\tvariant={\"outline\"}\n\t\t\t\tonClick={toggleShowData}\n\t\t\t\tclassName=\"my-4\"\n\t\t\t>\n\t\t\t\t{showData ? \"Hide\" : \"Show\"} Raw Data\n\t\t\t</Button>\n\n\t\t\t<div\n\t\t\t\tclassName=\"rounded-md border shadow-xs focus-within:outline-hidden focus-within:ring-1 focus-within:ring-ring relative\"\n\t\t\t\tstyle={{\n\t\t\t\t\tdisplay: showData ? \"block\" : \"none\",\n\t\t\t\t}}\n\t\t\t\tref={(node) => {\n\t\t\t\t\teditor.current = node;\n\t\t\t\t}}\n\t\t\t\tdata-testid=\"raw-data-display\"\n\t\t\t>\n\t\t\t\t<Button\n\t\t\t\t\tonClick={() => handleCopy(artifact.data as string)}\n\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\tsize=\"icon\"\n\t\t\t\t\tclassName=\"absolute top-0 right-0 z-10\"\n\t\t\t\t\taria-label=\"copy\"\n\t\t\t\t>\n\t\t\t\t\t<Icon id=\"Copy\" className=\"size-2\" />\n\t\t\t\t</Button>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailImageProps = {\n\turl: string;\n};\n\nexport const DetailImage = ({ url }: DetailImageProps) => {\n\treturn (\n\t\t<div data-testid={url} className=\"prose mt-2\">\n\t\t\t<img\n\t\t\t\tdata-testid={`image-${url}`}\n\t\t\t\tsrc={url}\n\t\t\t\talt=\"artifact-image\"\n\t\t\t\tclassName=\"w-full\"\n\t\t\t/>\n\n\t\t\t<Typography variant=\"bodyLarge\">\n\t\t\t\tImage URL:{\" \"}\n\t\t\t\t<a\n\t\t\t\t\tclassName=\"text-blue-700 hover:underline\"\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\thref={url}\n\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t>\n\t\t\t\t\t{url}\n\t\t\t\t</a>\n\t\t\t</Typography>\n\t\t</div>\n\t);\n};\n","import { LazyMarkdown } from \"@/components/ui/lazy-markdown\";\n\nexport type DetailMarkdownProps = {\n\tmarkdown: string;\n};\n\nexport const DetailMarkdown = ({ markdown }: DetailMarkdownProps) => {\n\treturn (\n\t\t<div data-testid=\"markdown-display\" className=\"mt-4 prose\">\n\t\t\t<LazyMarkdown>{markdown}</LazyMarkdown>\n\t\t</div>\n\t);\n};\n","import { Typography } from \"@/components/ui/typography\";\n\nexport type DetailProgressProps = {\n\tprogress: number;\n};\n\nexport const DetailProgress = ({ progress }: DetailProgressProps) => {\n\treturn (\n\t\t<Typography data-testid=\"progress-display\" variant=\"bodyLarge\">\n\t\t\tProgress: {progress}%\n\t\t</Typography>\n\t);\n};\n","import { useMemo, useState } from \"react\";\nimport { SearchInput } from \"@/components/ui/input\";\nimport {\n\tTable,\n\tTableBody,\n\tTableCell,\n\tTableHead,\n\tTableHeader,\n\tTableRow,\n} from \"@/components/ui/table\";\n\nexport type DetailTableProps = {\n\ttableData: string;\n};\n\nexport const DetailTable = ({ tableData }: DetailTableProps) => {\n\tconst table = JSON.parse(tableData) as Record<string, string>[];\n\tconst headers = Object.keys(table[0]);\n\tconst [input, setInput] = useState<string>(\"\");\n\n\tconst filteredTable = useMemo(() => {\n\t\treturn table.filter((row) => {\n\t\t\treturn Object.values(row).some((value: string) =>\n\t\t\t\tString(value).toLowerCase().includes(input.toLowerCase()),\n\t\t\t);\n\t\t});\n\t}, [input, table]);\n\n\treturn (\n\t\t<div data-testid=\"table-display\" className=\"mt-4\">\n\t\t\t<div className=\"flex flex-row justify-end items-center mb-2\">\n\t\t\t\t<div>\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Search\"\n\t\t\t\t\t\tvalue={input}\n\t\t\t\t\t\tonChange={(e) => setInput(e.target.value)}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"rounded-md border\">\n\t\t\t\t<Table>\n\t\t\t\t\t<TableHeader className=\"bg-muted\">\n\t\t\t\t\t\t<TableRow>\n\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<TableHead key={header} className=\"py-2 text-foreground\">\n\t\t\t\t\t\t\t\t\t\t{header}\n\t\t\t\t\t\t\t\t\t</TableHead>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t</TableHeader>\n\t\t\t\t\t<TableBody>\n\t\t\t\t\t\t{filteredTable.map((row) => {\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<TableRow key={row.id}>\n\t\t\t\t\t\t\t\t\t{headers.map((header) => {\n\t\t\t\t\t\t\t\t\t\treturn <TableCell key={header}>{row[header]}</TableCell>;\n\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t</TableRow>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t</TableBody>\n\t\t\t\t</Table>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","import { useMemo } from \"react\";\nimport type { ArtifactWithFlowRunAndTaskRun } from \"@/api/artifacts\";\nimport { ArtifactDetailHeader } from \"./artifact-detail-header\";\nimport { ArtifactDataDisplay } from \"./artifact-raw-data-display\";\nimport { DetailImage } from \"./detail-image\";\nimport { DetailMarkdown } from \"./detail-markdown\";\nimport { DetailProgress } from \"./detail-progress\";\nimport { DetailTable } from \"./detail-table\";\n\nexport type ArtifactDetailPageProps = {\n\tartifact: ArtifactWithFlowRunAndTaskRun;\n};\n\nexport const ArtifactDetailPage = ({ artifact }: ArtifactDetailPageProps) => {\n\tconst mapArtifactHoc = useMemo(() => {\n\t\tswitch (artifact.type) {\n\t\t\tcase \"markdown\":\n\t\t\tcase \"link\":\n\t\t\t\treturn <DetailMarkdown markdown={artifact.data as string} />;\n\t\t\tcase \"image\":\n\t\t\t\treturn <DetailImage url={artifact.data as string} />;\n\t\t\tcase \"progress\":\n\t\t\t\treturn <DetailProgress progress={artifact.data as number} />;\n\t\t\tcase \"table\":\n\t\t\t\treturn <DetailTable tableData={artifact.data as string} />;\n\t\t\tdefault:\n\t\t\t\treturn <pre>{JSON.stringify(artifact.data, null, 2)}</pre>;\n\t\t}\n\t}, [artifact]);\n\treturn (\n\t\t<div>\n\t\t\t<ArtifactDetailHeader artifact={artifact} />\n\t\t\t{mapArtifactHoc}\n\t\t\t<ArtifactDataDisplay artifact={artifact} />\n\t\t</div>\n\t);\n};\n","import { useSuspenseQuery } from \"@tanstack/react-query\";\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { buildGetArtifactQuery } from \"@/api/artifacts\";\nimport { useGetArtifactFlowTaskRuns } from \"@/api/artifacts/use-get-artifacts-flow-task-runs/use-get-artifacts-flow-task-runs\";\nimport { ArtifactDetailPage } from \"@/components/artifacts/artifact/artifact-detail-page\";\n\nexport const Route = createFileRoute(\"/artifacts/artifact/$id\")({\n\tcomponent: RouteComponent,\n\tloader: async ({ context, params }) => {\n\t\tconst { id } = params;\n\n\t\tconst artifact = await context.queryClient.ensureQueryData(\n\t\t\tbuildGetArtifactQuery(id),\n\t\t);\n\n\t\treturn { artifact };\n\t},\n});\n\nfunction RouteComponent() {\n\tconst { id } = Route.useParams();\n\n\tconst { data: artifact } = useSuspenseQuery(buildGetArtifactQuery(id));\n\n\tconst artifactWithMetadata = useGetArtifactFlowTaskRuns(id);\n\n\treturn <ArtifactDetailPage artifact={artifactWithMetadata ?? artifact} />;\n}\n"],"names":["ArtifactDetailHeader","artifact","header","jsx","Fragment","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","jsxs","DocsLink","Typography","LazyMarkdown","ArtifactDataDisplay","showData","setShowData","useState","toggleShowData","val","editor","useRef","basicSetup","setContainer","useCodeMirror","EditorView","useEffect","handleCopy","_value","toast","Button","node","Icon","DetailImage","url","DetailMarkdown","markdown","DetailProgress","progress","DetailTable","tableData","table","headers","input","setInput","filteredTable","useMemo","row","value","SearchInput","e","Table","TableHeader","TableRow","TableHead","TableBody","TableCell","ArtifactDetailPage","mapArtifactHoc","RouteComponent","id","Route","useParams","data","useSuspenseQuery","buildGetArtifactQuery","artifactWithMetadata","useGetArtifactFlowTaskRuns"],"mappings":"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"}
|