@knpkv/control-center 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -17
- package/dist/client/.vite/manifest.json +223 -178
- package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js → ActiveWorkPage-g2-Jyavo.js} +2 -2
- package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js.map → ActiveWorkPage-g2-Jyavo.js.map} +1 -1
- package/dist/client/assets/AgentPage-B6GQdZAs.css +1 -0
- package/dist/client/assets/AgentPage-DmVsEe13.js +6 -0
- package/dist/client/assets/AgentPage-DmVsEe13.js.map +1 -0
- package/dist/client/assets/AtlassianOAuthCallbackPage-C8u9ItMj.js +2 -0
- package/dist/client/assets/{AtlassianOAuthCallbackPage-D1F1xE_2.js.map → AtlassianOAuthCallbackPage-C8u9ItMj.js.map} +1 -1
- package/dist/client/assets/AuthorizedSharePage-CVBJ1NTm.js +2 -0
- package/dist/client/assets/AuthorizedSharePage-CVBJ1NTm.js.map +1 -0
- package/dist/client/assets/BrowserCrypto-3BoTVFdl.js +2 -0
- package/dist/client/assets/{BrowserCrypto-DVWR7DFd.js.map → BrowserCrypto-3BoTVFdl.js.map} +1 -1
- package/dist/client/assets/BrowserSessionHydrator-CpZnNm4X.js +2 -0
- package/dist/client/assets/BrowserSessionHydrator-CpZnNm4X.js.map +1 -0
- package/dist/client/assets/CommandSearch-DUeRRbV2.js +2 -0
- package/dist/client/assets/{CommandSearch-CP_QCbkm.js.map → CommandSearch-DUeRRbV2.js.map} +1 -1
- package/dist/client/assets/ItemsPage-BF2ZkSzh.js +2 -0
- package/dist/client/assets/{ItemsPage-BGFUkRL2.js.map → ItemsPage-BF2ZkSzh.js.map} +1 -1
- package/dist/client/assets/{PairPage-DIgzx0K2.js → PairPage-CkaZltHd.js} +2 -2
- package/dist/client/assets/{PairPage-DIgzx0K2.js.map → PairPage-CkaZltHd.js.map} +1 -1
- package/dist/client/assets/PortfolioOverview-CEUHJmGC.js +2 -0
- package/dist/client/assets/PortfolioOverview-CEUHJmGC.js.map +1 -0
- package/dist/client/assets/PullRequestReviewPanel-D1IpvHe2.js +6 -0
- package/dist/client/assets/PullRequestReviewPanel-D1IpvHe2.js.map +1 -0
- package/dist/client/assets/ReleaseRoute-BuQybrsg.js +2 -0
- package/dist/client/assets/{ReleaseRoute-DXJ8Jg60.js.map → ReleaseRoute-BuQybrsg.js.map} +1 -1
- package/dist/client/assets/ReleaseWorkset-BclY0Nvj.js +2 -0
- package/dist/client/assets/ReleaseWorkset-BclY0Nvj.js.map +1 -0
- package/dist/client/assets/ServicesPage-hw5Ee69-.js +2 -0
- package/dist/client/assets/ServicesPage-hw5Ee69-.js.map +1 -0
- package/dist/client/assets/TimelinePage-Cj3V98uI.js +2 -0
- package/dist/client/assets/TimelinePage-Cj3V98uI.js.map +1 -0
- package/dist/client/assets/WorkspaceEntityLink-C_rc8lxi.js +2 -0
- package/dist/client/assets/{WorkspaceEntityLink-AdZ_T-Wk.js.map → WorkspaceEntityLink-C_rc8lxi.js.map} +1 -1
- package/dist/client/assets/WorkspaceEntityRoute-DLLT6fY0.css +1 -0
- package/dist/client/assets/WorkspaceEntityRoute-kbnrQ_lY.js +14 -0
- package/dist/client/assets/WorkspaceEntityRoute-kbnrQ_lY.js.map +1 -0
- package/dist/client/assets/WorkspaceHomeLink-DeYYLEsH.js +2 -0
- package/dist/client/assets/{WorkspaceHomeLink-XbKSPths.js.map → WorkspaceHomeLink-DeYYLEsH.js.map} +1 -1
- package/dist/client/assets/{WorkspacePullRequestDetails-BErJ5bk8.js → WorkspacePullRequestDetails-CizqydjN.js} +3 -3
- package/dist/client/assets/WorkspacePullRequestDetails-CizqydjN.js.map +1 -0
- package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js → WorkspaceReleaseLayout-CXAQUhkh.js} +2 -2
- package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js.map → WorkspaceReleaseLayout-CXAQUhkh.js.map} +1 -1
- package/dist/client/assets/{WorkspaceRichText-D1M637Ff.js → WorkspaceRichText-CCOciILO.js} +2 -2
- package/dist/client/assets/WorkspaceRichText-CCOciILO.js.map +1 -0
- package/dist/client/assets/WorkspaceSettingsPage-GoBfQzBx.css +1 -0
- package/dist/client/assets/WorkspaceSettingsPage-JG-pN_CA.js +2 -0
- package/dist/client/assets/WorkspaceSettingsPage-JG-pN_CA.js.map +1 -0
- package/dist/client/assets/agent-api-Dl9TuGOJ.js +19 -0
- package/dist/client/assets/agent-api-Dl9TuGOJ.js.map +1 -0
- package/dist/client/assets/atlassianOAuthSetupIntentStorage-DE4ySCTb.js +2 -0
- package/dist/client/assets/atlassianOAuthSetupIntentStorage-DE4ySCTb.js.map +1 -0
- package/dist/client/assets/authenticatedMutationClient-DdowMjyo.js +2 -0
- package/dist/client/assets/{authenticatedMutationClient-Ccwguc3i.js.map → authenticatedMutationClient-DdowMjyo.js.map} +1 -1
- package/dist/client/assets/authorizedShareTransport-CnclcYai.js +2 -0
- package/dist/client/assets/{authorizedShareTransport-DZHgFEkh.js.map → authorizedShareTransport-CnclcYai.js.map} +1 -1
- package/dist/client/assets/client-Dq_XQE_l.js +5 -0
- package/dist/client/assets/client-Dq_XQE_l.js.map +1 -0
- package/dist/client/assets/confluenceTasks-DtKq8_eU.js +5 -0
- package/dist/client/assets/confluenceTasks-DtKq8_eU.js.map +1 -0
- package/dist/client/assets/connectionTestTransport-CPK98z7H.js +2 -0
- package/dist/client/assets/connectionTestTransport-CPK98z7H.js.map +1 -0
- package/dist/client/assets/index-zVjlBm9l.js +11 -0
- package/dist/client/assets/index-zVjlBm9l.js.map +1 -0
- package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js → patterns-5N-j-AD2-DLfaGePK.js} +2 -2
- package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js.map → patterns-5N-j-AD2-DLfaGePK.js.map} +1 -1
- package/dist/client/assets/{presentPortfolio-D3ZIcnqt.js → presentPortfolio-DLEq-vEz.js} +2 -2
- package/dist/client/assets/presentPortfolio-DLEq-vEz.js.map +1 -0
- package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js → presentWorkspaceItems-BOY3FbhO.js} +2 -2
- package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js.map → presentWorkspaceItems-BOY3FbhO.js.map} +1 -1
- package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js → pullRequestReviewFailures-CyjTVnSX.js} +2 -2
- package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js.map → pullRequestReviewFailures-CyjTVnSX.js.map} +1 -1
- package/dist/client/assets/pullRequestReviewThreadReplay-CXHspFTr.js +2 -0
- package/dist/client/assets/pullRequestReviewThreadReplay-CXHspFTr.js.map +1 -0
- package/dist/client/assets/releaseAgentTransport-DaO4svPu.js +2 -0
- package/dist/client/assets/releaseAgentTransport-DaO4svPu.js.map +1 -0
- package/dist/client/assets/releaseRoutes-B4ciNOJj.js +2 -0
- package/dist/client/assets/{releaseRoutes-BCuIdZyA.js.map → releaseRoutes-B4ciNOJj.js.map} +1 -1
- package/dist/client/assets/serviceOnboarding-D0FmodRi.js +2 -0
- package/dist/client/assets/{serviceOnboarding-Jg_0yNjf.js.map → serviceOnboarding-D0FmodRi.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js → useWorkspaceDefaultLanding-BaQdg0sY.js} +3 -3
- package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js.map → useWorkspaceDefaultLanding-BaQdg0sY.js.map} +1 -1
- package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js → useWorkspaceItems-B-7JHtm0.js} +2 -2
- package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js.map → useWorkspaceItems-B-7JHtm0.js.map} +1 -1
- package/dist/client/assets/workspaceEntityRoutes-DqqDa0AB.js +2 -0
- package/dist/client/assets/workspaceEntityRoutes-DqqDa0AB.js.map +1 -0
- package/dist/client/assets/workspaceScrollCapture-BYNfR2wo.js +2 -0
- package/dist/client/assets/workspaceScrollCapture-BYNfR2wo.js.map +1 -0
- package/dist/client/assets/workspaceSettingsTransport-Br4lBmvS.js +2 -0
- package/dist/client/assets/{workspaceSettingsTransport-CZWYL5T7.js.map → workspaceSettingsTransport-Br4lBmvS.js.map} +1 -1
- package/dist/client/build-graph.json +115 -0
- package/dist/client/index.html +1 -1
- package/dist/server/api/agent.d.ts +575 -44
- package/dist/server/api/agent.d.ts.map +1 -1
- package/dist/server/api/deliveryGraph.d.ts +474 -454
- package/dist/server/api/deliveryGraph.d.ts.map +1 -1
- package/dist/server/api/index.d.ts +2 -2
- package/dist/server/api/index.d.ts.map +1 -1
- package/dist/server/api/index.js +4 -4
- package/dist/server/api/liveEvents.d.ts +20 -0
- package/dist/server/api/liveEvents.d.ts.map +1 -1
- package/dist/server/api/portfolio.d.ts +23 -0
- package/dist/server/api/portfolio.d.ts.map +1 -1
- package/dist/server/api/session.d.ts +23 -1
- package/dist/server/api/session.d.ts.map +1 -1
- package/dist/server/api/shares.d.ts +4 -2
- package/dist/server/api/shares.d.ts.map +1 -1
- package/dist/server/assets/{BindConfig-DIsf2Rnh.js → BindConfig-DAASchDn.js} +2405 -322
- package/dist/server/assets/BindConfig-DAASchDn.js.map +1 -0
- package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js → CodePipelineStateDecoder-CNiFRgSi.js} +2 -2
- package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js.map → CodePipelineStateDecoder-CNiFRgSi.js.map} +1 -1
- package/dist/server/assets/{agent-CyZ40zs1.js → agent-xQhAQXly.js} +181 -11
- package/dist/server/assets/agent-xQhAQXly.js.map +1 -0
- package/dist/server/assets/{controlCenterApi-ZUX3Y-LE.js → controlCenterApi-DNXK7MT1.js} +6 -5
- package/dist/server/assets/controlCenterApi-DNXK7MT1.js.map +1 -0
- package/dist/server/assets/{descriptor-CKtTnhef.js → descriptor-CCvNzSZL.js} +10 -10
- package/dist/server/assets/{descriptor-CKtTnhef.js.map → descriptor-CCvNzSZL.js.map} +1 -1
- package/dist/server/assets/{failures-mgYDkUZy.js → failures-CesHLYbN.js} +2 -2
- package/dist/server/assets/{failures-mgYDkUZy.js.map → failures-CesHLYbN.js.map} +1 -1
- package/dist/server/assets/{firstPartyServices-D7b8BOek.js → firstPartyServices-Cdzjcs2H.js} +2 -2
- package/dist/server/assets/{firstPartyServices-D7b8BOek.js.map → firstPartyServices-Cdzjcs2H.js.map} +1 -1
- package/dist/server/assets/{manualPluginSynchronization-DFlhKvav.js → manualPluginSynchronization-DFIeUHP9.js} +6 -5
- package/dist/server/assets/manualPluginSynchronization-DFIeUHP9.js.map +1 -0
- package/dist/server/assets/{plugins-D__oMDpI.js → plugins-DiPrfzV8.js} +2 -2
- package/dist/server/assets/{plugins-D__oMDpI.js.map → plugins-DiPrfzV8.js.map} +1 -1
- package/dist/server/assets/{readiness-BhA-Nr9c.js → readiness-31Mqc-9H.js} +3 -3
- package/dist/server/assets/{readiness-BhA-Nr9c.js.map → readiness-31Mqc-9H.js.map} +1 -1
- package/dist/server/assets/{relationshipInferenceMaterialization-DYBcaWhQ.js → relationshipInferenceMaterialization-Dyix96px.js} +1158 -169
- package/dist/server/assets/relationshipInferenceMaterialization-Dyix96px.js.map +1 -0
- package/dist/server/assets/{workspaceSettings-BE713Oe8.js → workspaceSettings-sv8h_h2P.js} +2787 -2700
- package/dist/server/assets/workspaceSettings-sv8h_h2P.js.map +1 -0
- package/dist/server/build-graph.json +144 -4
- package/dist/server/domain/actors.d.ts +12 -12
- package/dist/server/domain/confluenceTasks.d.ts +27 -0
- package/dist/server/domain/confluenceTasks.d.ts.map +1 -0
- package/dist/server/domain/deliveryGraph.d.ts +51 -49
- package/dist/server/domain/deliveryGraph.d.ts.map +1 -1
- package/dist/server/domain/governedAction/bindings.d.ts +26 -12
- package/dist/server/domain/governedAction/bindings.d.ts.map +1 -1
- package/dist/server/domain/governedAction/lifecycle.d.ts +8 -8
- package/dist/server/domain/governedAction/model.d.ts +45 -18
- package/dist/server/domain/governedAction/model.d.ts.map +1 -1
- package/dist/server/domain/governedAction/stateMachine.d.ts +34 -34
- package/dist/server/domain/index.js +6 -6
- package/dist/server/domain/normalizedIssue.d.ts +1 -1
- package/dist/server/domain/normalizedPage.d.ts +1 -0
- package/dist/server/domain/normalizedPage.d.ts.map +1 -1
- package/dist/server/domain/prReview.d.ts +38 -0
- package/dist/server/domain/prReview.d.ts.map +1 -1
- package/dist/server/domain/prReviewReconciliation.d.ts +56 -0
- package/dist/server/domain/prReviewReconciliation.d.ts.map +1 -0
- package/dist/server/domain/prReviewRevision.d.ts +1 -0
- package/dist/server/domain/prReviewRevision.d.ts.map +1 -1
- package/dist/server/domain/readiness/model.d.ts +3 -3
- package/dist/server/domain/release.d.ts +3 -3
- package/dist/server/domain/releasePipelineApproval.d.ts +31 -0
- package/dist/server/domain/releasePipelineApproval.d.ts.map +1 -0
- package/dist/server/domain/releasePublication.d.ts +4 -0
- package/dist/server/domain/releasePublication.d.ts.map +1 -0
- package/dist/server/index.js +8 -8
- package/dist/server/server/agent/AgentJobWorker.d.ts +10 -1
- package/dist/server/server/agent/AgentJobWorker.d.ts.map +1 -1
- package/dist/server/server/agent/ReleaseAgentPrompt.d.ts.map +1 -1
- package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts +4 -3
- package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts +17 -1
- package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts +76 -2
- package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts.map +1 -1
- package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts +27 -0
- package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts.map +1 -0
- package/dist/server/server/api/ApplicationServices.d.ts +39 -5
- package/dist/server/server/api/ApplicationServices.d.ts.map +1 -1
- package/dist/server/server/api/Handlers.d.ts +1 -1
- package/dist/server/server/api/Handlers.d.ts.map +1 -1
- package/dist/server/server/api/RequestBoundary.d.ts.map +1 -1
- package/dist/server/server/application/GovernedReviewSuggestionPublicationGateway.d.ts.map +1 -1
- package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts +4 -0
- package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts.map +1 -1
- package/dist/server/server/application/deliveryGraphInspection.d.ts.map +1 -1
- package/dist/server/server/application/index.d.ts +1 -0
- package/dist/server/server/application/index.d.ts.map +1 -1
- package/dist/server/server/application/liveEvents.d.ts.map +1 -1
- package/dist/server/server/application/normalizedPluginPageMaterialization.d.ts.map +1 -1
- package/dist/server/server/application/pipelineExecutionProjection.d.ts +7 -6
- package/dist/server/server/application/pipelineExecutionProjection.d.ts.map +1 -1
- package/dist/server/server/application/portfolioSnapshots.d.ts +2018 -4
- package/dist/server/server/application/portfolioSnapshots.d.ts.map +1 -1
- package/dist/server/server/application/pullRequestReviews.d.ts.map +1 -1
- package/dist/server/server/application/releaseAgent.d.ts +11 -3
- package/dist/server/server/application/releaseAgent.d.ts.map +1 -1
- package/dist/server/server/application/releasePublicationIntent.d.ts +7 -0
- package/dist/server/server/application/releasePublicationIntent.d.ts.map +1 -0
- package/dist/server/server/application/releasePublicationMetadata.d.ts +61 -0
- package/dist/server/server/application/releasePublicationMetadata.d.ts.map +1 -0
- package/dist/server/server/application/releasePublicationSubmissions.d.ts +3730 -0
- package/dist/server/server/application/releasePublicationSubmissions.d.ts.map +1 -0
- package/dist/server/server/application/releaseRunbookHydration.d.ts +2310 -0
- package/dist/server/server/application/releaseRunbookHydration.d.ts.map +1 -0
- package/dist/server/server/application/releaseSynchronization.d.ts.map +1 -1
- package/dist/server/server/cli.js +8 -8
- package/dist/server/server/cli.js.map +1 -1
- package/dist/server/server/governance/governedActionDigests.d.ts +236 -218
- package/dist/server/server/governance/governedActionDigests.d.ts.map +1 -1
- package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts +3 -4
- package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts.map +1 -1
- package/dist/server/server/governance/internal/execution-store/begin.d.ts.map +1 -1
- package/dist/server/server/governance/internal/execution-store/dispatch-inbox.d.ts +1 -1
- package/dist/server/server/governance/internal/execution-store/dispatch-outcome.d.ts +8 -8
- package/dist/server/server/governance/internal/execution-store/provider-outcome-fold.d.ts +2 -2
- package/dist/server/server/governance/internal/execution-store/reconciliation-inbox.d.ts +1 -1
- package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts +37 -30
- package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts.map +1 -1
- package/dist/server/server/index.js +5 -5
- package/dist/server/server/internal/codepipeline-state-probe.js +1 -1
- package/dist/server/server/persistence/Database.d.ts +1 -1
- package/dist/server/server/persistence/Database.d.ts.map +1 -1
- package/dist/server/server/persistence/Persistence.d.ts +1549 -577
- package/dist/server/server/persistence/Persistence.d.ts.map +1 -1
- package/dist/server/server/persistence/backup/BackupArchive.d.ts.map +1 -1
- package/dist/server/server/persistence/object-store/BlobPublisher.d.ts.map +1 -1
- package/dist/server/server/persistence/object-store/PinnedDirectory.d.ts +2 -2
- package/dist/server/server/persistence/object-store/PinnedDirectory.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/agentJobModels.d.ts +345 -8
- package/dist/server/server/persistence/repositories/agentJobModels.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/agentJobRepository.d.ts +654 -192
- package/dist/server/server/persistence/repositories/agentJobRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts +148 -138
- package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts +27 -25
- package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts +117 -111
- package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts +28 -27
- package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts +50 -48
- package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts +117 -111
- package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/codec.d.ts +259 -234
- package/dist/server/server/persistence/repositories/governed-action/codec.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/contract.d.ts +68 -46
- package/dist/server/server/persistence/repositories/governed-action/contract.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/read.d.ts +668 -190
- package/dist/server/server/persistence/repositories/governed-action/read.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts +680 -206
- package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts +38 -31
- package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts +46 -32
- package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governed-action/write.d.ts +46 -32
- package/dist/server/server/persistence/repositories/governed-action/write.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/governedActionRepository.d.ts +678 -205
- package/dist/server/server/persistence/repositories/governedActionRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts +85 -4
- package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/models.d.ts +9 -9
- package/dist/server/server/persistence/repositories/peopleRepository.d.ts +36 -36
- package/dist/server/server/persistence/repositories/providerAccountRepository.d.ts +1 -1
- package/dist/server/server/persistence/repositories/readiness/assessments.d.ts +6 -6
- package/dist/server/server/persistence/repositories/readiness/contract.d.ts +450 -450
- package/dist/server/server/persistence/repositories/readiness/queue.d.ts +14 -14
- package/dist/server/server/persistence/repositories/readinessRepository.d.ts +7 -7
- package/dist/server/server/persistence/repositories/releaseRepository.d.ts +18 -18
- package/dist/server/server/persistence/repositories/retentionRepository.d.ts.map +1 -1
- package/dist/server/server/persistence/repositories/timelineRepository.d.ts +4 -4
- package/dist/server/server/plugins/atlassian/AtlassianOAuthGrants.d.ts.map +1 -1
- package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts +9 -0
- package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts.map +1 -0
- package/dist/server/server/plugins/atlassian/AtlassianProfiles.d.ts.map +1 -1
- package/dist/server/server/plugins/codecommit/CodeCommitPluginDefinition.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts +2 -2
- package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReadProvider.d.ts.map +1 -1
- package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts +8 -0
- package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts.map +1 -0
- package/dist/server/server/plugins/jira/index.d.ts +1 -1
- package/dist/server/server/plugins/jira/index.d.ts.map +1 -1
- package/dist/server/server/runtime/Bootstrap.d.ts +1 -1
- package/dist/server/server/runtime/Bootstrap.d.ts.map +1 -1
- package/dist/server/server/runtime/ControlCenterServer.d.ts +3 -3
- package/dist/server/server/runtime/ControlCenterServer.d.ts.map +1 -1
- package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts +11 -1
- package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts.map +1 -1
- package/dist/server/server/runtime/RetentionStartup.d.ts.map +1 -1
- package/dist/server/server/runtime/ServerLifecycle.d.ts.map +1 -1
- package/dist/server/server/secrets/SecretStore.d.ts.map +1 -1
- package/package.json +10 -9
- package/dist/client/assets/AgentPage-DGL93TJU.js +0 -3
- package/dist/client/assets/AgentPage-DGL93TJU.js.map +0 -1
- package/dist/client/assets/AgentPage-DVSgQgJa.css +0 -1
- package/dist/client/assets/AtlassianOAuthCallbackPage-D1F1xE_2.js +0 -2
- package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js +0 -2
- package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js.map +0 -1
- package/dist/client/assets/BrowserCrypto-DVWR7DFd.js +0 -2
- package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js +0 -2
- package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js.map +0 -1
- package/dist/client/assets/CommandSearch-CP_QCbkm.js +0 -2
- package/dist/client/assets/ItemsPage-BGFUkRL2.js +0 -2
- package/dist/client/assets/PortfolioOverview-D45rk8Hl.js +0 -2
- package/dist/client/assets/PortfolioOverview-D45rk8Hl.js.map +0 -1
- package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js +0 -6
- package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js.map +0 -1
- package/dist/client/assets/ReleaseRoute-DXJ8Jg60.js +0 -2
- package/dist/client/assets/ReleaseWorkset-Dtzalmji.js +0 -2
- package/dist/client/assets/ReleaseWorkset-Dtzalmji.js.map +0 -1
- package/dist/client/assets/ServicesPage-DGcUjd2H.js +0 -2
- package/dist/client/assets/ServicesPage-DGcUjd2H.js.map +0 -1
- package/dist/client/assets/TimelinePage-Bq1RTQlP.js +0 -2
- package/dist/client/assets/TimelinePage-Bq1RTQlP.js.map +0 -1
- package/dist/client/assets/WorkspaceEntityLink-AdZ_T-Wk.js +0 -2
- package/dist/client/assets/WorkspaceEntityRoute-9iMOV64J.css +0 -1
- package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js +0 -3
- package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js.map +0 -1
- package/dist/client/assets/WorkspaceHomeLink-XbKSPths.js +0 -2
- package/dist/client/assets/WorkspacePullRequestDetails-BErJ5bk8.js.map +0 -1
- package/dist/client/assets/WorkspaceRichText-D1M637Ff.js.map +0 -1
- package/dist/client/assets/WorkspaceSettingsPage-Fy7Wx8Y2.js +0 -2
- package/dist/client/assets/WorkspaceSettingsPage-Fy7Wx8Y2.js.map +0 -1
- package/dist/client/assets/WorkspaceSettingsPage-P6yfac0b.css +0 -1
- package/dist/client/assets/agent-api-QVqt4a0O.js +0 -19
- package/dist/client/assets/agent-api-QVqt4a0O.js.map +0 -1
- package/dist/client/assets/authenticatedMutationClient-Ccwguc3i.js +0 -2
- package/dist/client/assets/authorizedShareTransport-DZHgFEkh.js +0 -2
- package/dist/client/assets/client-D27unen8.js +0 -5
- package/dist/client/assets/client-D27unen8.js.map +0 -1
- package/dist/client/assets/connectionTestTransport-BQ55d6Me.js +0 -2
- package/dist/client/assets/connectionTestTransport-BQ55d6Me.js.map +0 -1
- package/dist/client/assets/index-j5ze816l.js +0 -11
- package/dist/client/assets/index-j5ze816l.js.map +0 -1
- package/dist/client/assets/presentPortfolio-D3ZIcnqt.js.map +0 -1
- package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js +0 -2
- package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js.map +0 -1
- package/dist/client/assets/releaseRoutes-BCuIdZyA.js +0 -2
- package/dist/client/assets/serviceOnboarding-Jg_0yNjf.js +0 -2
- package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js +0 -2
- package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js.map +0 -1
- package/dist/client/assets/workspaceSettingsTransport-CZWYL5T7.js +0 -2
- package/dist/server/assets/BindConfig-DIsf2Rnh.js.map +0 -1
- package/dist/server/assets/agent-CyZ40zs1.js.map +0 -1
- package/dist/server/assets/controlCenterApi-ZUX3Y-LE.js.map +0 -1
- package/dist/server/assets/manualPluginSynchronization-DFlhKvav.js.map +0 -1
- package/dist/server/assets/relationshipInferenceMaterialization-DYBcaWhQ.js.map +0 -1
- package/dist/server/assets/workspaceSettings-BE713Oe8.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServicesPage-hw5Ee69-.js","names":[],"sources":["../../../src/client/services/AtlassianAccountSetupForm.module.css","../../../src/client/services/serviceSetupValues.ts","../../../src/client/services/AtlassianAccountSetupForm.tsx","../../../src/client/services/AwsAccountSetupForm.module.css","../../../src/client/services/AwsAccountSetupForm.tsx","../../../src/client/services/ServicesPage.module.css","../../../src/client/services/ConnectionTestEvidence.tsx","../../../src/client/services/ConnectionAdministration.tsx","../../../src/client/services/ConnectionSynchronization.tsx","../../../src/client/services/connectionState.ts","../../../src/client/services/ProviderAccountCard.tsx","../../../src/client/services/ServicesPage.tsx"],"sourcesContent":[".form,\n.intro,\n.fallback {\n display: grid;\n gap: var(--rly-space-12);\n}\n\n.form {\n gap: var(--rly-space-20);\n}\n\n.intro {\n gap: var(--rly-space-4);\n}\n\n.resources {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--rly-space-12);\n}\n\n.actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--rly-space-8);\n}\n\n.error {\n color: var(--rly-color-blocked-ink);\n}\n\n@media (max-width: 40rem) {\n .resources {\n grid-template-columns: 1fr;\n }\n}\n","import type { CreatePluginConnectionValue, PluginServiceCatalogEntry } from \"../../api/plugins.js\"\n\n/** One provider adapter connection assembled by a setup workflow. */\nexport interface ServiceConnectionDraft {\n readonly catalog: PluginServiceCatalogEntry\n readonly displayName: string\n readonly values: ReadonlyArray<CreatePluginConnectionValue>\n}\n\n/** Convert one browser field value into the catalog-declared setup variant. */\nexport const serviceSetupValue = (\n field: PluginServiceCatalogEntry[\"configurationFields\"][number],\n value: string\n): CreatePluginConnectionValue => {\n switch (field.kind) {\n case \"integer\":\n return { _tag: \"integer\", key: field.key, value: Number(value) }\n case \"secret\":\n return { _tag: \"secret\", key: field.key, value }\n case \"text\":\n case \"url\":\n return { _tag: field.kind, key: field.key, value }\n }\n}\n\n/** Build a complete setup value list from catalog defaults and explicit overrides. */\nexport const serviceSetupValues = (\n catalog: PluginServiceCatalogEntry,\n overrides: ReadonlyMap<string, string>\n): ReadonlyArray<CreatePluginConnectionValue> =>\n catalog.configurationFields.flatMap((field) => {\n const value = overrides.get(field.key) ?? field.defaultValue\n return value === null && !field.required ? [] : [serviceSetupValue(field, value ?? \"\")]\n })\n","import { Button, Field, Text } from \"@knpkv/rly/primitives\"\nimport { type FormEvent, type ReactElement, useEffect, useRef, useState } from \"react\"\n\nimport type {\n AtlassianOAuthGrantStartResponse,\n AtlassianOAuthClientConfiguration,\n AtlassianOAuthProviderIntent,\n AtlassianProfileDiscoveryResponse,\n DiscoveredAtlassianProfile,\n PluginServiceCatalogEntry\n} from \"../../api/plugins.js\"\nimport styles from \"./AtlassianAccountSetupForm.module.css\"\nimport { rememberAtlassianOAuthSetupIntent } from \"./atlassianOAuthSetupIntentStorage.js\"\nimport { type ServiceConnectionDraft, serviceSetupValues } from \"./serviceSetupValues.js\"\n\ntype AuthenticationMode = \"oauth\" | \"api-token\"\nexport interface AtlassianSetupIntent {\n readonly preferredProfileId: string | null\n readonly preferredSiteId: string | null\n readonly providers: AtlassianOAuthProviderIntent\n readonly requestedOAuthProviders: AtlassianOAuthProviderIntent | null\n}\n\nconst selectedProfile = (\n profiles: AtlassianProfileDiscoveryResponse,\n profileId: string\n): DiscoveredAtlassianProfile | undefined => profiles.find((profile) => profile.profileId === profileId)\n\nconst isUsableProfile = (profile: DiscoveredAtlassianProfile, intent: AtlassianSetupIntent): boolean =>\n profile.status === \"valid\" &&\n (intent.preferredSiteId === null || profile.cloudId === intent.preferredSiteId) &&\n intent.providers.every((providerId) => profile.providers.includes(providerId))\n\nconst profileAvailability = (profile: DiscoveredAtlassianProfile): string => {\n if (profile.status === \"expired\") return \"expired\"\n if (!profile.providers.includes(\"jira\")) return \"Confluence only\"\n if (!profile.providers.includes(\"confluence\")) return \"Jira only\"\n return \"Jira + Confluence\"\n}\n\n/** Configure Jira and Confluence beneath one shared Atlassian identity. */\nexport const AtlassianAccountSetupForm = ({\n catalogs,\n isSubmitting,\n onCancel,\n onStartOAuth,\n onSubmit,\n profiles,\n profilesState,\n setupIntent\n}: {\n readonly catalogs: ReadonlyArray<PluginServiceCatalogEntry>\n readonly isSubmitting: boolean\n readonly onCancel: () => void\n readonly onStartOAuth: (\n providers: AtlassianOAuthProviderIntent,\n signal: AbortSignal,\n configuration?: AtlassianOAuthClientConfiguration\n ) => Promise<AtlassianOAuthGrantStartResponse>\n readonly onSubmit: (drafts: ReadonlyArray<ServiceConnectionDraft>) => Promise<boolean>\n readonly profiles: AtlassianProfileDiscoveryResponse\n readonly profilesState: \"failed\" | \"idle\" | \"loading\" | \"ready\"\n readonly setupIntent: AtlassianSetupIntent\n}): ReactElement => {\n const jira = catalogs.find(({ providerId }) => providerId === \"jira\")\n const confluence = catalogs.find(({ providerId }) => providerId === \"confluence\")\n const setupJira = setupIntent.providers.includes(\"jira\")\n const setupConfluence = setupIntent.providers.includes(\"confluence\")\n const [accountName, setAccountName] = useState(\"Atlassian workspace\")\n const [authenticationMode, setAuthenticationMode] = useState<AuthenticationMode>(\"oauth\")\n const [profileId, setProfileId] = useState(\"\")\n const [siteUrl, setSiteUrl] = useState(\"\")\n const [siteId, setSiteId] = useState(\"\")\n const [projectId, setProjectId] = useState(\"\")\n const [spaceId, setSpaceId] = useState(\"\")\n const [probePageId, setProbePageId] = useState(\"\")\n const [email, setEmail] = useState(\"\")\n const [apiToken, setApiToken] = useState(\"\")\n const [isStartingOAuth, setIsStartingOAuth] = useState(false)\n const [oauthCallbackUrl, setOAuthCallbackUrl] = useState<string | null>(null)\n const [oauthClientId, setOAuthClientId] = useState(\"\")\n const [oauthClientSecret, setOAuthClientSecret] = useState(\"\")\n const [setupError, setSetupError] = useState<string | null>(null)\n const startRequest = useRef<AbortController | null>(null)\n\n useEffect(() => () => startRequest.current?.abort(), [])\n\n useEffect(() => {\n if (authenticationMode !== \"oauth\") return\n const currentProfile = selectedProfile(profiles, profileId)\n if (currentProfile !== undefined && isUsableProfile(currentProfile, setupIntent)) return\n const preferredProfile =\n setupIntent.preferredProfileId === null ? undefined : selectedProfile(profiles, setupIntent.preferredProfileId)\n const initialProfile =\n preferredProfile !== undefined && isUsableProfile(preferredProfile, setupIntent)\n ? preferredProfile\n : profiles.find((profile) => isUsableProfile(profile, setupIntent))\n setProfileId(initialProfile?.profileId ?? \"\")\n }, [authenticationMode, profileId, profiles, setupIntent])\n\n useEffect(() => {\n if (setupIntent.preferredSiteId !== null) setSiteId(setupIntent.preferredSiteId)\n }, [setupIntent.preferredSiteId])\n\n useEffect(() => {\n if (authenticationMode !== \"oauth\") return\n const profile = selectedProfile(profiles, profileId)\n if (profile === undefined) return\n setSiteUrl(profile.siteUrl)\n setSiteId(profile.cloudId)\n }, [authenticationMode, profileId, profiles])\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setSetupError(null)\n if ((setupJira && jira === undefined) || (setupConfluence && confluence === undefined)) {\n setSetupError(\"The installed Atlassian adapters are unavailable.\")\n return\n }\n const normalizedAccountName = accountName.trim()\n const normalizedSiteUrl = siteUrl.trim()\n const normalizedSiteId = siteId.trim()\n const normalizedProjectId = projectId.trim()\n const normalizedSpaceId = spaceId.trim()\n const normalizedProbePageId = probePageId.trim()\n if (\n normalizedAccountName.length === 0 ||\n normalizedSiteUrl.length === 0 ||\n normalizedSiteId.length === 0 ||\n (setupJira && normalizedProjectId.length === 0) ||\n (setupConfluence && (normalizedSpaceId.length === 0 || normalizedProbePageId.length === 0))\n ) {\n setSetupError(\n setupJira && setupConfluence\n ? \"Add the Atlassian site identity, Jira project, Confluence space, and readable health page.\"\n : setupJira\n ? \"Add the Atlassian site identity and Jira project.\"\n : \"Add the Atlassian site identity, Confluence space, and readable health page.\"\n )\n return\n }\n const authentication: ReadonlyArray<readonly [string, string]> =\n authenticationMode === \"oauth\"\n ? [\n [\"authMode\", \"oauth\"],\n [\"oauthProfileId\", profileId]\n ]\n : [\n [\"authMode\", \"api-token\"],\n [\"email\", email.trim()],\n [\"apiToken\", apiToken]\n ]\n const oauthProfile = selectedProfile(profiles, profileId)\n if (authenticationMode === \"oauth\" && (oauthProfile === undefined || !isUsableProfile(oauthProfile, setupIntent))) {\n setSetupError(\"Choose a valid profile for the products being connected, or use an API token instead.\")\n return\n }\n if (authenticationMode === \"api-token\" && (email.trim().length === 0 || apiToken.length === 0)) {\n setSetupError(\"Add the Atlassian email and API token.\")\n return\n }\n if (authenticationMode === \"api-token\" && setupJira && setupIntent.preferredSiteId !== null) {\n setSetupError(\"Use a matching OAuth profile to add a Jira project to this Atlassian site.\")\n return\n }\n const sharedValues: ReadonlyArray<readonly [string, string]> = [\n ...authentication,\n [\"webBaseUrl\", normalizedSiteUrl],\n [\"siteBaseUrl\", normalizedSiteUrl],\n [\"siteId\", normalizedSiteId],\n [\"projectId\", normalizedProjectId],\n [\"spaceId\", normalizedSpaceId],\n [\"probePageId\", normalizedProbePageId]\n ]\n const overrides = new Map<string, string>(sharedValues)\n const drafts: ReadonlyArray<ServiceConnectionDraft> = [\n ...(setupJira && jira !== undefined\n ? [\n {\n catalog: jira,\n displayName: `${normalizedAccountName} · Jira`,\n values: serviceSetupValues(jira, overrides)\n }\n ]\n : []),\n ...(setupConfluence && confluence !== undefined\n ? [\n {\n catalog: confluence,\n displayName: `${normalizedAccountName} · Confluence`,\n values: serviceSetupValues(confluence, overrides)\n }\n ]\n : [])\n ]\n void onSubmit(drafts).then((didCreate) => {\n if (!didCreate) setSetupError(\"Some Atlassian services could not be connected. Review the cards below and retry.\")\n })\n }\n\n const startOAuth = (configuration?: AtlassianOAuthClientConfiguration): void => {\n if (setupIntent.requestedOAuthProviders === null) return\n setSetupError(null)\n setOAuthCallbackUrl(null)\n setIsStartingOAuth(true)\n startRequest.current?.abort()\n const request = new AbortController()\n startRequest.current = request\n void onStartOAuth(setupIntent.requestedOAuthProviders, request.signal, configuration).then(\n (result) => {\n if (request.signal.aborted) return\n if (result._tag === \"configuration-required\") {\n setOAuthCallbackUrl(result.callbackUrl)\n setSetupError(\"OAuth needs a one-time local client configuration before sign-in.\")\n setIsStartingOAuth(false)\n return\n }\n if (\n !rememberAtlassianOAuthSetupIntent(result.authorizationUrl, {\n preferredSiteId: setupIntent.preferredSiteId,\n providers: setupIntent.providers\n })\n ) {\n setSetupError(\"Control Center could not preserve this Atlassian setup across sign-in. Try again.\")\n setIsStartingOAuth(false)\n return\n }\n window.location.assign(result.authorizationUrl)\n },\n () => {\n if (request.signal.aborted) return\n setSetupError(\"Control Center could not start Atlassian sign-in. Try again.\")\n setIsStartingOAuth(false)\n }\n )\n }\n\n const configureOAuth = (): void => {\n const clientId = oauthClientId.trim()\n if (clientId.length === 0 || oauthClientSecret.length === 0) {\n setSetupError(\"Add the Atlassian OAuth client ID and client secret.\")\n return\n }\n startOAuth({ clientId, clientSecret: oauthClientSecret })\n }\n\n const useApiToken = (): void => {\n startRequest.current?.abort()\n startRequest.current = null\n setIsStartingOAuth(false)\n setAuthenticationMode(\"api-token\")\n }\n\n const discoveryMessage =\n profilesState === \"loading\"\n ? \"Finding local Atlassian OAuth profiles…\"\n : profilesState === \"failed\"\n ? \"OAuth profile discovery is unavailable. API token fallback remains available.\"\n : profilesState === \"ready\"\n ? `${profiles.filter((profile) => isUsableProfile(profile, setupIntent)).length} ${setupJira && setupConfluence ? \"shared \" : \"\"}OAuth ${profiles.filter((profile) => isUsableProfile(profile, setupIntent)).length === 1 ? \"profile\" : \"profiles\"} ready`\n : \"OAuth profiles stay on this machine and are shared by Jira and Confluence.\"\n\n return (\n <form className={styles.form} onSubmit={submit}>\n <div className={styles.intro}>\n <Text as=\"h3\" variant=\"card-title\">\n {setupJira && setupConfluence\n ? \"One identity. Jira and Confluence together.\"\n : setupJira\n ? \"Connect Jira with your Atlassian identity.\"\n : \"Connect Confluence with your Atlassian identity.\"}\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n OAuth is preferred. Control Center reads the selected local profile only inside the server runtime.\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {discoveryMessage}\n </Text>\n </div>\n <Field label=\"Account name\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n maxLength={90}\n onChange={(event) => setAccountName(event.currentTarget.value)}\n value={accountName}\n />\n )}\n </Field>\n {authenticationMode === \"oauth\" ? (\n <>\n <Button\n disabled={setupIntent.requestedOAuthProviders === null}\n loading={isStartingOAuth}\n onClick={() => startOAuth()}\n type=\"button\"\n variant=\"primary\"\n >\n Sign in with Atlassian\n </Button>\n {oauthCallbackUrl === null ? null : (\n <div className={styles.fallback}>\n <Text as=\"p\" tone=\"secondary\" variant=\"meta\">\n Create an OAuth 2.0 integration in Atlassian Developer Console and add <code>{oauthCallbackUrl}</code>\n as its callback URL. The credentials stay on this Control Center machine.\n </Text>\n <Field label=\"OAuth client ID\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"off\"\n maxLength={500}\n onChange={(event) => setOAuthClientId(event.currentTarget.value)}\n value={oauthClientId}\n />\n )}\n </Field>\n <Field label=\"OAuth client secret\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"off\"\n maxLength={16_384}\n onChange={(event) => setOAuthClientSecret(event.currentTarget.value)}\n type=\"password\"\n value={oauthClientSecret}\n />\n )}\n </Field>\n <Button loading={isStartingOAuth} onClick={configureOAuth} type=\"button\" variant=\"primary\">\n Save OAuth app and continue\n </Button>\n </div>\n )}\n <Field label=\"OAuth profile\" required size=\"compact\">\n {(controlProps) => (\n <select {...controlProps} onChange={(event) => setProfileId(event.currentTarget.value)} value={profileId}>\n <option value=\"\">Choose a profile already on this machine</option>\n {profiles\n .filter(\n (profile) => setupIntent.preferredSiteId === null || profile.cloudId === setupIntent.preferredSiteId\n )\n .map((profile) => (\n <option\n disabled={!isUsableProfile(profile, setupIntent)}\n key={profile.profileId}\n value={profile.profileId}\n >\n {profile.name} · {profileAvailability(profile)}\n </option>\n ))}\n </select>\n )}\n </Field>\n {setupJira && setupIntent.preferredSiteId !== null ? null : (\n <Button onClick={useApiToken} type=\"button\" variant=\"quiet\">\n Use API token instead\n </Button>\n )}\n </>\n ) : (\n <div className={styles.fallback}>\n <Field label=\"Atlassian email\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"username\"\n onChange={(event) => setEmail(event.currentTarget.value)}\n type=\"email\"\n value={email}\n />\n )}\n </Field>\n <Field label=\"API token\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"off\"\n maxLength={16_384}\n onChange={(event) => setApiToken(event.currentTarget.value)}\n type=\"password\"\n value={apiToken}\n />\n )}\n </Field>\n <Button onClick={() => setAuthenticationMode(\"oauth\")} type=\"button\" variant=\"quiet\">\n Use OAuth profile\n </Button>\n </div>\n )}\n <Field label=\"Atlassian site URL\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n disabled={authenticationMode === \"oauth\"}\n onChange={(event) => setSiteUrl(event.currentTarget.value)}\n placeholder=\"https://team.atlassian.net/\"\n type=\"url\"\n value={siteUrl}\n />\n )}\n </Field>\n <Field\n description=\"The stable Atlassian cloud ID; filled from OAuth when available.\"\n label=\"Site ID\"\n required\n size=\"compact\"\n >\n {(controlProps) => (\n <input\n {...controlProps}\n disabled={authenticationMode === \"oauth\" || setupIntent.preferredSiteId !== null}\n onChange={(event) => setSiteId(event.currentTarget.value)}\n value={siteId}\n />\n )}\n </Field>\n {setupJira ? (\n <Field\n description=\"The immutable Jira project ID followed by this connection.\"\n label=\"Jira project ID\"\n required\n size=\"compact\"\n >\n {(controlProps) => (\n <input {...controlProps} onChange={(event) => setProjectId(event.currentTarget.value)} value={projectId} />\n )}\n </Field>\n ) : null}\n {setupConfluence ? (\n <div className={styles.resources}>\n <Field label=\"Confluence space ID\" required size=\"compact\">\n {(controlProps) => (\n <input {...controlProps} onChange={(event) => setSpaceId(event.currentTarget.value)} value={spaceId} />\n )}\n </Field>\n <Field\n description=\"A readable page used only for the connection check.\"\n label=\"Health page ID\"\n required\n size=\"compact\"\n >\n {(controlProps) => (\n <input\n {...controlProps}\n onChange={(event) => setProbePageId(event.currentTarget.value)}\n value={probePageId}\n />\n )}\n </Field>\n </div>\n ) : null}\n {setupError === null ? null : (\n <Text as=\"p\" className={styles.error} role=\"alert\" variant=\"body\">\n {setupError}\n </Text>\n )}\n <div className={styles.actions}>\n <Button disabled={isSubmitting} onClick={onCancel} type=\"button\" variant=\"secondary\">\n Cancel\n </Button>\n <Button loading={isSubmitting} type=\"submit\" variant=\"primary\">\n Connect Atlassian\n </Button>\n </div>\n </form>\n )\n}\n",".form {\n display: grid;\n gap: var(--rly-space-20);\n}\n\n.intro {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.resources {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: var(--rly-space-12);\n}\n\n.resources textarea {\n min-block-size: 7rem;\n resize: vertical;\n}\n\n.discoveryActions,\n.resourcePanelHeading {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--rly-space-8);\n}\n\n.resourcePanel {\n display: grid;\n align-content: start;\n gap: var(--rly-space-8);\n min-inline-size: 0;\n padding: var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n}\n\n.resourcePanelHeading {\n justify-content: space-between;\n}\n\n.choiceList {\n display: grid;\n gap: var(--rly-space-4);\n max-block-size: 13rem;\n overflow: auto;\n}\n\n.choice {\n display: flex;\n align-items: center;\n gap: var(--rly-space-8);\n padding: var(--rly-space-4);\n}\n\n.actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--rly-space-8);\n}\n\n.error {\n color: var(--rly-color-blocked-ink);\n}\n\n@media (max-width: 40rem) {\n .resources {\n grid-template-columns: 1fr;\n }\n}\n","import { Button, Field, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { type FormEvent, type ReactElement, useEffect, useRef, useState } from \"react\"\n\nimport type {\n AwsProfileDiscoveryResponse,\n AwsResourceDiscoveryRequest,\n AwsResourceDiscoveryResponse,\n AwsServiceResourceDiscovery,\n PluginServiceCatalogEntry\n} from \"../../api/plugins.js\"\nimport styles from \"./AwsAccountSetupForm.module.css\"\nimport { type ServiceConnectionDraft, serviceSetupValues } from \"./serviceSetupValues.js\"\n\nconst MAXIMUM_FOLLOWED_RESOURCES = 20\n\ntype ResourceDiscoveryState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly response: AwsResourceDiscoveryResponse }\n\nconst parseResourceNames = (input: string): ReadonlyArray<string> => [\n ...new Set(\n input\n .split(/[\\n,]/u)\n .map((name) => name.trim())\n .filter((name) => name.length > 0)\n )\n]\n\nconst mergeResourceNames = (selected: ReadonlySet<string>, manual: string): ReadonlyArray<string> => [\n ...new Set([...selected, ...parseResourceNames(manual)])\n]\n\n/** Preserve explicit choices across refreshes, including temporarily undiscoverable names. */\nexport const refreshedAwsResourceChoices = (\n discovered: ReadonlyArray<string>,\n selected: ReadonlySet<string>\n): ReadonlyArray<string> => [...new Set([...discovered, ...selected])].sort((left, right) => left.localeCompare(right))\n\n/** Case-insensitive resource search used by both AWS service lists. */\nexport const searchAwsResourceNames = (names: ReadonlyArray<string>, query: string): ReadonlyArray<string> => {\n const normalizedQuery = query.trim().toLocaleLowerCase()\n return normalizedQuery.length === 0\n ? names\n : names.filter((name) => name.toLocaleLowerCase().includes(normalizedQuery))\n}\n\nconst connectionDrafts = ({\n accountName,\n codeCommit,\n codePipeline,\n pipelineNames,\n profile,\n region,\n repositoryNames\n}: {\n readonly accountName: string\n readonly codeCommit: PluginServiceCatalogEntry\n readonly codePipeline: PluginServiceCatalogEntry\n readonly pipelineNames: ReadonlyArray<string>\n readonly profile: string\n readonly region: string\n readonly repositoryNames: ReadonlyArray<string>\n}): ReadonlyArray<ServiceConnectionDraft> => [\n ...repositoryNames.map((repositoryName) => ({\n catalog: codeCommit,\n displayName: `${accountName} · ${repositoryName}`,\n values: serviceSetupValues(\n codeCommit,\n new Map([\n [\"profile\", profile],\n [\"region\", region],\n [\"repositoryName\", repositoryName]\n ])\n )\n })),\n ...pipelineNames.map((pipelineName) => ({\n catalog: codePipeline,\n displayName: `${accountName} · ${pipelineName}`,\n values: serviceSetupValues(\n codePipeline,\n new Map([\n [\"profile\", profile],\n [\"region\", region],\n [\"pipelineName\", pipelineName]\n ])\n )\n }))\n]\n\nconst profileDiscoveryMessage = (profileCount: number, state: \"failed\" | \"idle\" | \"loading\" | \"ready\"): string => {\n switch (state) {\n case \"loading\":\n return \"Discovering local AWS profiles…\"\n case \"ready\":\n return `${profileCount} local AWS ${profileCount === 1 ? \"profile\" : \"profiles\"} detected`\n case \"failed\":\n return \"Profile discovery unavailable. Enter a profile manually.\"\n case \"idle\":\n return \"AWS profiles are discovered locally by the Control Center server.\"\n }\n}\n\nconst failureMessage = (service: \"CodeCommit\" | \"CodePipeline\", failureClass: string): string =>\n failureClass === \"authorization\"\n ? `${service} access was denied. Select names manually or update this profile's permissions.`\n : `${service} discovery is unavailable (${failureClass}). Select names manually or refresh.`\n\nconst ResourcePicker = ({\n label,\n query,\n selected,\n service,\n setQuery,\n setSelected\n}: {\n readonly label: string\n readonly query: string\n readonly selected: ReadonlySet<string>\n readonly service: AwsServiceResourceDiscovery\n readonly setQuery: (query: string) => void\n readonly setSelected: (selected: ReadonlySet<string>) => void\n}): ReactElement => {\n if (service._tag === \"failed\") {\n const preservedNames = [...selected].sort((left, right) => left.localeCompare(right))\n return (\n <div className={styles.resourcePanel}>\n <div className={styles.resourcePanelHeading}>\n <Text as=\"h4\" variant=\"card-title\">\n {label}\n </Text>\n <StateLabel label={`${selected.size} selected`} size=\"compact\" tone=\"neutral\" />\n </div>\n <Text as=\"p\" className={styles.error} role=\"status\" variant=\"body\">\n {failureMessage(label === \"Repositories\" ? \"CodeCommit\" : \"CodePipeline\", service.failureClass)}\n </Text>\n {preservedNames.length === 0 ? null : (\n <>\n <Text tone=\"secondary\" variant=\"meta\">\n Preserved from the previous discovery. Clear any resource you no longer want to connect.\n </Text>\n <div className={styles.choiceList}>\n {preservedNames.map((name) => (\n <label className={styles.choice} key={name}>\n <input\n checked\n onChange={() => {\n const next = new Set(selected)\n next.delete(name)\n setSelected(next)\n }}\n type=\"checkbox\"\n />\n <span>{name}</span>\n </label>\n ))}\n </div>\n </>\n )}\n </div>\n )\n }\n const names = refreshedAwsResourceChoices(service.names, selected)\n const visibleNames = searchAwsResourceNames(names, query)\n return (\n <div className={styles.resourcePanel}>\n <div className={styles.resourcePanelHeading}>\n <Text as=\"h4\" variant=\"card-title\">\n {label}\n </Text>\n <StateLabel label={`${selected.size} selected`} size=\"compact\" tone=\"neutral\" />\n </div>\n {names.length === 0 ? (\n <Text tone=\"secondary\" variant=\"body\">\n No {label.toLocaleLowerCase()} were found in this region.\n </Text>\n ) : (\n <>\n <Field label={`Search ${label.toLocaleLowerCase()}`} size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n onChange={(event) => setQuery(event.currentTarget.value)}\n type=\"search\"\n value={query}\n />\n )}\n </Field>\n <div className={styles.choiceList}>\n {visibleNames.map((name) => (\n <label className={styles.choice} key={name}>\n <input\n checked={selected.has(name)}\n onChange={(event) => {\n const next = new Set(selected)\n if (event.currentTarget.checked) next.add(name)\n else next.delete(name)\n setSelected(next)\n }}\n type=\"checkbox\"\n />\n <span>{name}</span>\n </label>\n ))}\n </div>\n {visibleNames.length === 0 ? (\n <Text tone=\"secondary\" variant=\"body\">\n No matching resources.\n </Text>\n ) : null}\n {service.truncated ? (\n <Text tone=\"secondary\" variant=\"meta\">\n Showing the first 20 names. Use manual entry for another name.\n </Text>\n ) : null}\n </>\n )}\n </div>\n )\n}\n\n/** Configure one AWS account and the repositories and pipelines followed beneath it. */\nexport const AwsAccountSetupForm = ({\n awsProfiles,\n awsProfilesState,\n catalogs,\n isSubmitting,\n onCancel,\n onDiscover,\n onSubmit\n}: {\n readonly awsProfiles: AwsProfileDiscoveryResponse\n readonly awsProfilesState: \"failed\" | \"idle\" | \"loading\" | \"ready\"\n readonly catalogs: ReadonlyArray<PluginServiceCatalogEntry>\n readonly isSubmitting: boolean\n readonly onCancel: () => void\n readonly onDiscover: (\n request: AwsResourceDiscoveryRequest,\n signal: AbortSignal\n ) => Promise<AwsResourceDiscoveryResponse>\n readonly onSubmit: (drafts: ReadonlyArray<ServiceConnectionDraft>) => Promise<boolean>\n}): ReactElement => {\n const codeCommit = catalogs.find(({ providerId }) => providerId === \"codecommit\")\n const codePipeline = catalogs.find(({ providerId }) => providerId === \"codepipeline\")\n const [accountName, setAccountName] = useState(\"AWS account\")\n const [profile, setProfile] = useState(\"default\")\n const [region, setRegion] = useState(\"\")\n const [repositoryNames, setRepositoryNames] = useState(\"\")\n const [pipelineNames, setPipelineNames] = useState(\"\")\n const [selectedRepositories, setSelectedRepositories] = useState<ReadonlySet<string>>(new Set())\n const [selectedPipelines, setSelectedPipelines] = useState<ReadonlySet<string>>(new Set())\n const [repositoryQuery, setRepositoryQuery] = useState(\"\")\n const [pipelineQuery, setPipelineQuery] = useState(\"\")\n const [isManualEntryOpen, setIsManualEntryOpen] = useState(true)\n const [discoveryState, setDiscoveryState] = useState<ResourceDiscoveryState>({ _tag: \"idle\" })\n const [setupError, setSetupError] = useState<string | null>(null)\n const discoveryRequest = useRef<AbortController | null>(null)\n\n useEffect(() => () => discoveryRequest.current?.abort(), [])\n\n useEffect(() => {\n const detectedRegion = awsProfiles.find((candidate) => candidate.profile === profile)?.region\n if (detectedRegion !== null && detectedRegion !== undefined) {\n setRegion((current) => (current.trim().length === 0 ? detectedRegion : current))\n }\n }, [awsProfiles, profile])\n\n const resetDiscovery = (): void => {\n discoveryRequest.current?.abort()\n discoveryRequest.current = null\n setDiscoveryState({ _tag: \"idle\" })\n setSelectedRepositories(new Set())\n setSelectedPipelines(new Set())\n }\n\n const discover = (): void => {\n setSetupError(null)\n const request = { profile: profile.trim(), region: region.trim() }\n if (request.profile.length === 0 || request.region.length === 0) {\n setSetupError(\"Add an AWS profile and region before testing discovery.\")\n return\n }\n discoveryRequest.current?.abort()\n const controller = new AbortController()\n discoveryRequest.current = controller\n setDiscoveryState({ _tag: \"loading\" })\n onDiscover(request, controller.signal).then(\n (response) => {\n if (controller.signal.aborted) return\n discoveryRequest.current = null\n setDiscoveryState({ _tag: \"ready\", response })\n },\n () => {\n if (controller.signal.aborted) return\n discoveryRequest.current = null\n setDiscoveryState({ _tag: \"failed\" })\n }\n )\n }\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setSetupError(null)\n if (codeCommit === undefined || codePipeline === undefined) {\n setSetupError(\"The installed AWS adapters are unavailable.\")\n return\n }\n const normalizedAccountName = accountName.trim()\n const normalizedProfile = profile.trim()\n const normalizedRegion = region.trim()\n if (normalizedAccountName.length === 0 || normalizedProfile.length === 0 || normalizedRegion.length === 0) {\n setSetupError(\"Add an account name, AWS profile, and region.\")\n return\n }\n const repositories = mergeResourceNames(selectedRepositories, isManualEntryOpen ? repositoryNames : \"\")\n const pipelines = mergeResourceNames(selectedPipelines, isManualEntryOpen ? pipelineNames : \"\")\n if (repositories.length === 0 && pipelines.length === 0) {\n setSetupError(\"Select or manually add at least one repository or pipeline to follow.\")\n return\n }\n if (repositories.length > MAXIMUM_FOLLOWED_RESOURCES || pipelines.length > MAXIMUM_FOLLOWED_RESOURCES) {\n setSetupError(`Follow at most ${MAXIMUM_FOLLOWED_RESOURCES} repositories and pipelines per account.`)\n return\n }\n if ([...repositories, ...pipelines].some((name) => name.length > 100)) {\n setSetupError(\"Repository and pipeline names must be 100 characters or fewer.\")\n return\n }\n const drafts = connectionDrafts({\n accountName: normalizedAccountName,\n codeCommit,\n codePipeline,\n pipelineNames: pipelines,\n profile: normalizedProfile,\n region: normalizedRegion,\n repositoryNames: repositories\n })\n void onSubmit(drafts).then((didCreate) => {\n if (!didCreate) setSetupError(\"Some AWS resources could not be connected. Review the cards below and retry.\")\n })\n }\n\n return (\n <form className={styles.form} onSubmit={submit}>\n <div className={styles.intro}>\n <Text as=\"h3\" variant=\"card-title\">\n One account. Many delivery streams.\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n Choose one local AWS profile and region, verify its account, then select CodeCommit repositories and\n CodePipeline pipelines.\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {profileDiscoveryMessage(awsProfiles.length, awsProfilesState)}\n </Text>\n </div>\n <Field label=\"Account name\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n maxLength={90}\n onChange={(event) => setAccountName(event.currentTarget.value)}\n value={accountName}\n />\n )}\n </Field>\n <Field label=\"AWS profile\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n list={awsProfiles.length > 0 ? \"aws-account-profiles\" : undefined}\n maxLength={200}\n onChange={(event) => {\n const nextProfile = event.currentTarget.value\n const detectedRegion = awsProfiles.find((candidate) => candidate.profile === nextProfile)?.region\n setProfile(nextProfile)\n setRegion(detectedRegion ?? \"\")\n resetDiscovery()\n }}\n value={profile}\n />\n )}\n </Field>\n <Field label=\"AWS region\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n maxLength={100}\n onChange={(event) => {\n setRegion(event.currentTarget.value)\n resetDiscovery()\n }}\n value={region}\n />\n )}\n </Field>\n <div className={styles.discoveryActions}>\n <Button loading={discoveryState._tag === \"loading\"} onClick={discover} type=\"button\" variant=\"secondary\">\n {discoveryState._tag === \"ready\" ? \"Refresh discovery\" : \"Test & discover\"}\n </Button>\n {discoveryState._tag === \"ready\" ? (\n <Text tone=\"secondary\" variant=\"body\">\n Verified AWS account {discoveryState.response.accountId}\n </Text>\n ) : discoveryState._tag === \"failed\" ? (\n <Text as=\"p\" className={styles.error} role=\"alert\" variant=\"body\">\n Account verification failed. Check the profile and region, or enter resource names manually.\n </Text>\n ) : null}\n </div>\n {discoveryState._tag === \"ready\" ? (\n <div className={styles.resources}>\n <ResourcePicker\n label=\"Repositories\"\n query={repositoryQuery}\n selected={selectedRepositories}\n service={discoveryState.response.codeCommit}\n setQuery={setRepositoryQuery}\n setSelected={setSelectedRepositories}\n />\n <ResourcePicker\n label=\"Pipelines\"\n query={pipelineQuery}\n selected={selectedPipelines}\n service={discoveryState.response.codePipeline}\n setQuery={setPipelineQuery}\n setSelected={setSelectedPipelines}\n />\n </div>\n ) : null}\n <div>\n <Button onClick={() => setIsManualEntryOpen((current) => !current)} type=\"button\" variant=\"quiet\">\n {isManualEntryOpen ? \"Hide manual name entry\" : \"Enter resource names manually\"}\n </Button>\n </div>\n {isManualEntryOpen ? (\n <div className={styles.resources}>\n <Field\n description=\"Comma or line separated. Maximum 20 including selected names.\"\n label=\"Repository names\"\n size=\"compact\"\n >\n {(controlProps) => (\n <textarea\n {...controlProps}\n maxLength={4_096}\n onChange={(event) => setRepositoryNames(event.currentTarget.value)}\n placeholder=\"payments-api\\nrisk-engine\"\n value={repositoryNames}\n />\n )}\n </Field>\n <Field\n description=\"Comma or line separated. Maximum 20 including selected names.\"\n label=\"Pipeline names\"\n size=\"compact\"\n >\n {(controlProps) => (\n <textarea\n {...controlProps}\n maxLength={4_096}\n onChange={(event) => setPipelineNames(event.currentTarget.value)}\n placeholder=\"payments-production\\nrisk-production\"\n value={pipelineNames}\n />\n )}\n </Field>\n </div>\n ) : null}\n {awsProfiles.length > 0 ? (\n <datalist id=\"aws-account-profiles\">\n {awsProfiles.map((candidate) => (\n <option\n key={candidate.profile}\n label={candidate.region ?? \"Region not configured\"}\n value={candidate.profile}\n />\n ))}\n </datalist>\n ) : null}\n {setupError === null ? null : (\n <Text as=\"p\" className={styles.error} role=\"alert\" variant=\"body\">\n {setupError}\n </Text>\n )}\n <div className={styles.actions}>\n <Button disabled={isSubmitting} onClick={onCancel} type=\"button\" variant=\"secondary\">\n Cancel\n </Button>\n <Button loading={isSubmitting} type=\"submit\" variant=\"primary\">\n Connect AWS account\n </Button>\n </div>\n </form>\n )\n}\n",".page {\n display: grid;\n gap: var(--rly-space-40);\n}\n\n.heading {\n display: grid;\n max-inline-size: 48rem;\n gap: var(--rly-space-12);\n}\n\n.grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));\n gap: var(--rly-space-16);\n}\n\n.accounts,\n.accountCard,\n.accountIdentity,\n.resourceList,\n.resource,\n.sectionHeading {\n display: grid;\n}\n\n.accounts,\n.accountCard {\n gap: var(--rly-space-20);\n}\n\n.sectionHeading,\n.accountIdentity,\n.resourceBody {\n gap: var(--rly-space-8);\n}\n\n.resourceList {\n overflow: hidden;\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n}\n\n.accountGrid {\n display: grid;\n gap: var(--rly-space-16);\n}\n\n.accountHeading,\n.resourceSummary,\n.resourceStatus,\n.accountActions,\n.resourceActions {\n display: flex;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.accountHeading,\n.resourceSummary {\n justify-content: space-between;\n}\n\n.accountActions,\n.resourceActions {\n flex-wrap: wrap;\n}\n\n.accountActions {\n padding-block-start: var(--rly-space-4);\n}\n\n.resource + .resource {\n border-block-start: 1px solid var(--rly-color-border-2);\n}\n\n.resource[data-status-tone=\"positive\"] {\n box-shadow: inset 3px 0 var(--rly-color-success-ink);\n}\n\n.resource[data-status-tone=\"positive\"]:dir(rtl) {\n box-shadow: inset -3px 0 var(--rly-color-success-ink);\n}\n\n.resource[data-status-tone=\"critical\"] {\n box-shadow: inset 3px 0 var(--rly-color-blocked-ink);\n}\n\n.resource[data-status-tone=\"critical\"]:dir(rtl) {\n box-shadow: inset -3px 0 var(--rly-color-blocked-ink);\n}\n\n.resource[data-status-tone=\"caution\"],\n.resource[data-status-tone=\"progress\"] {\n box-shadow: inset 3px 0 var(--rly-color-text-2);\n}\n\n.resource[data-status-tone=\"caution\"]:dir(rtl),\n.resource[data-status-tone=\"progress\"]:dir(rtl) {\n box-shadow: inset -3px 0 var(--rly-color-text-2);\n}\n\n.resourceSummary {\n min-block-size: var(--rly-space-48);\n padding: var(--rly-space-16);\n background: var(--rly-color-surface-2);\n cursor: pointer;\n list-style: none;\n}\n\n.resourceSummary::-webkit-details-marker {\n display: none;\n}\n\n.resourceSummary:focus-visible {\n outline: 2px solid var(--rly-color-text-1);\n outline-offset: -2px;\n}\n\n.resourceStatus {\n flex: none;\n}\n\n.disclosure {\n display: inline-flex;\n align-items: center;\n color: var(--rly-color-text-2);\n font: var(--rly-type-label-weight) var(--rly-type-label-size) / var(--rly-type-label-line-height)\n var(--rly-type-label-font);\n gap: var(--rly-space-4);\n}\n\n.disclosure span {\n font-size: 1.1em;\n}\n\n.resource[open] .disclosure span {\n transform: rotate(90deg);\n}\n\n.resourceBody {\n display: grid;\n padding: 0 var(--rly-space-16) var(--rly-space-16);\n background: var(--rly-color-surface-2);\n}\n\n.card {\n display: grid;\n align-content: start;\n gap: var(--rly-space-24);\n}\n\n.cardHeading,\n.cardAction {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rly-space-16);\n}\n\n.synchronization,\n.syncState {\n display: grid;\n gap: var(--rly-space-6);\n}\n\n.administration,\n.administrationSection,\n.credentialRecovery,\n.diagnostics,\n.accountEdit {\n display: grid;\n gap: var(--rly-space-12);\n}\n\n.administration {\n padding-block: var(--rly-space-16);\n border-block: 1px solid var(--rly-color-border-2);\n}\n\n.administrationLabels,\n.diagnostic,\n.accountEditAction {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--rly-space-8);\n}\n\n.diagnostic {\n flex-wrap: nowrap;\n}\n\n.accountEdit {\n max-inline-size: 32rem;\n}\n\n.accountEditAction {\n justify-content: flex-end;\n}\n\n.syncActions {\n display: flex;\n flex-wrap: wrap;\n gap: var(--rly-space-8);\n}\n\n.connectionIdentity {\n display: flex;\n min-inline-size: 0;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.testEvidence {\n display: grid;\n gap: var(--rly-space-12);\n padding: var(--rly-space-16);\n border-inline-start: 2px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-2);\n}\n\n.identity {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.setupForm {\n display: grid;\n gap: var(--rly-space-16);\n}\n\n.setupActions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--rly-space-8);\n}\n\n.setupError {\n color: var(--rly-color-blocked-ink);\n}\n\n.identifier {\n overflow-wrap: anywhere;\n}\n\n@media (max-width: 32rem) {\n .cardHeading,\n .cardAction,\n .accountHeading,\n .resourceSummary {\n align-items: flex-start;\n flex-direction: column;\n }\n\n .resourceStatus {\n inline-size: 100%;\n justify-content: space-between;\n }\n}\n","import { StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport type { ReactElement } from \"react\"\n\nimport type { PluginConnectionTestResult } from \"../../api/plugins.js\"\nimport type { ConnectionTestState } from \"./connectionState.js\"\nimport styles from \"./ServicesPage.module.css\"\n\nconst checkedAt = (result: PluginConnectionTestResult): string => DateTime.formatIso(result.checkedAt)\n\n/** Provider identity and timing evidence from the most recent explicit live test. */\nexport const ConnectionTestEvidence = ({\n state\n}: {\n readonly state: ConnectionTestState | undefined\n}): ReactElement | null => {\n if (state === undefined || state._tag === \"testing\") return null\n if (state._tag === \"request-failed\") {\n return (\n <div aria-live=\"polite\" className={styles.testEvidence} role=\"status\">\n <StateLabel label=\"Test failed\" tone=\"critical\" />\n <Text tone=\"secondary\" variant=\"body\">\n Control Center could not complete the test. Check the server and try again.\n </Text>\n </div>\n )\n }\n const result = state.result\n const checkedAtIso = checkedAt(result)\n return (\n <div aria-live=\"polite\" className={styles.testEvidence} role=\"status\">\n <StateLabel\n label={result._tag === \"healthy\" ? \"Connection healthy\" : \"Test failed\"}\n tone={result._tag === \"healthy\" ? \"positive\" : \"critical\"}\n />\n {result._tag === \"healthy\" ? (\n <div className={styles.identity}>\n <Text tone=\"secondary\" variant=\"meta\">\n {result.identity.label}\n </Text>\n <Text as=\"span\" variant=\"card-title\">\n {result.identity.displayName}\n </Text>\n <Text className={styles.identifier} tone=\"secondary\" variant=\"body\">\n {result.identity.providerImmutableId}\n </Text>\n </div>\n ) : (\n <Text tone=\"secondary\" variant=\"body\">\n {result.safeMessage}\n </Text>\n )}\n <Text tone=\"secondary\" variant=\"meta\">\n Checked <time dateTime={checkedAtIso}>{checkedAtIso}</time> · {result.latencyMilliseconds} ms\n </Text>\n </div>\n )\n}\n","import { Button, Field, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport { type FormEvent, type ReactElement, useEffect, useRef, useState } from \"react\"\n\nimport type {\n AtlassianOAuthClientConfiguration,\n AtlassianOAuthGrantStartResponse,\n AtlassianOAuthProviderIntent,\n PluginConnectionAdministration,\n PluginCredentialReplacement\n} from \"../../api/plugins.js\"\nimport { rememberAtlassianOAuthSetupIntent } from \"./atlassianOAuthSetupIntentStorage.js\"\n\nimport styles from \"./ServicesPage.module.css\"\n\nexport type ConnectionAdministrationViewState =\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly administration: PluginConnectionAdministration }\n\nconst diagnosticTone = (\n severity: PluginConnectionAdministration[\"diagnostics\"][number][\"severity\"]\n): \"critical\" | \"caution\" | \"neutral\" =>\n severity === \"critical\" ? \"critical\" : severity === \"warning\" ? \"caution\" : \"neutral\"\n\n/** Secret-safe connection recovery controls backed by the administration read model. */\nexport const ConnectionAdministration = ({\n atlassianOAuthProviders,\n canConfigure,\n onReauthorize,\n onRevoke,\n onStartAtlassianOAuth,\n state\n}: {\n readonly atlassianOAuthProviders?: AtlassianOAuthProviderIntent\n readonly canConfigure: boolean\n readonly onReauthorize: (credentials: ReadonlyArray<PluginCredentialReplacement>) => Promise<boolean>\n readonly onRevoke: () => Promise<boolean>\n readonly onStartAtlassianOAuth:\n | ((\n providers: AtlassianOAuthProviderIntent,\n signal: AbortSignal,\n configuration?: AtlassianOAuthClientConfiguration\n ) => Promise<AtlassianOAuthGrantStartResponse>)\n | undefined\n readonly state: ConnectionAdministrationViewState | undefined\n}): ReactElement | null => {\n const [credentialValues, setCredentialValues] = useState<ReadonlyMap<string, string>>(new Map())\n const [mutation, setMutation] = useState<\"idle\" | \"reauthorizing\" | \"revoking\" | \"failed\">(\"idle\")\n const [oauthState, setOAuthState] = useState<\"idle\" | \"starting\" | \"configuration-required\" | \"failed\">(\"idle\")\n const [oauthCallbackUrl, setOAuthCallbackUrl] = useState<string | null>(null)\n const [oauthClientId, setOAuthClientId] = useState(\"\")\n const [oauthClientSecret, setOAuthClientSecret] = useState(\"\")\n const oauthRequest = useRef<AbortController | null>(null)\n\n useEffect(() => {\n setCredentialValues(new Map())\n setMutation(\"idle\")\n setOAuthState(\"idle\")\n setOAuthCallbackUrl(null)\n oauthRequest.current?.abort()\n oauthRequest.current = null\n }, [state?._tag === \"ready\" ? state.administration.configuration.revision : state?._tag])\n\n useEffect(() => () => oauthRequest.current?.abort(), [])\n\n if (state === undefined) return null\n if (state._tag === \"loading\") {\n return (\n <Text tone=\"secondary\" variant=\"meta\">\n Loading permissions and diagnostics…\n </Text>\n )\n }\n if (state._tag === \"failed\") {\n return (\n <Text className={styles.setupError} role=\"alert\" variant=\"body\">\n Administration details are unavailable.\n </Text>\n )\n }\n\n const { administration } = state\n const manualCredentialFields = administration.credentialFields.filter(({ key }) => key !== \"oauthProfileId\")\n const supportsOAuthRecovery =\n administration.credentialFields.some(({ key }) => key === \"oauthProfileId\") &&\n (administration.connection.providerId === \"jira\" || administration.connection.providerId === \"confluence\") &&\n onStartAtlassianOAuth !== undefined\n const configuredSite = administration.configuration.values.find(({ key }) => key === \"siteId\")\n const preferredSiteId =\n configuredSite?._tag === \"text\" || configuredSite?._tag === \"url\" ? configuredSite.value : null\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n const credentials = manualCredentialFields.flatMap((field) => {\n const entered = credentialValues.get(field.key) ?? \"\"\n if (entered.trim().length === 0) return []\n return [{ key: field.key, value: field.kind === \"secret\" ? entered : entered.trim() }]\n })\n if (credentials.length === 0) return\n setMutation(\"reauthorizing\")\n void onReauthorize(credentials).then((succeeded) => {\n setMutation(succeeded ? \"idle\" : \"failed\")\n if (succeeded) setCredentialValues(new Map())\n })\n }\n\n const revoke = (): void => {\n setMutation(\"revoking\")\n void onRevoke().then((succeeded) => setMutation(succeeded ? \"idle\" : \"failed\"))\n }\n\n const startOAuth = (configuration?: AtlassianOAuthClientConfiguration): void => {\n if (!supportsOAuthRecovery || onStartAtlassianOAuth === undefined) return\n const providers =\n atlassianOAuthProviders ?? (administration.connection.providerId === \"jira\" ? [\"jira\"] : [\"confluence\"])\n oauthRequest.current?.abort()\n const request = new AbortController()\n oauthRequest.current = request\n setOAuthState(\"starting\")\n setOAuthCallbackUrl(null)\n void onStartAtlassianOAuth(providers, request.signal, configuration).then(\n (result) => {\n if (request.signal.aborted) return\n if (result._tag === \"configuration-required\") {\n setOAuthCallbackUrl(result.callbackUrl)\n setOAuthState(\"configuration-required\")\n return\n }\n if (\n !rememberAtlassianOAuthSetupIntent(result.authorizationUrl, {\n preferredSiteId,\n providers,\n recoveryConnectionId: administration.connection.pluginConnectionId\n })\n ) {\n setOAuthState(\"failed\")\n return\n }\n window.location.assign(result.authorizationUrl)\n },\n () => {\n if (!request.signal.aborted) setOAuthState(\"failed\")\n }\n )\n }\n\n const configureOAuth = (): void => {\n const clientId = oauthClientId.trim()\n if (clientId.length === 0 || oauthClientSecret.length === 0) {\n setOAuthState(\"failed\")\n return\n }\n startOAuth({ clientId, clientSecret: oauthClientSecret })\n }\n\n return (\n <section aria-label=\"Connection administration\" className={styles.administration}>\n <div className={styles.administrationSection}>\n <Text as=\"h4\" variant=\"label\">\n Permissions\n </Text>\n <div className={styles.administrationLabels}>\n {administration.permissions.map((permission) => (\n <StateLabel\n key={`${permission.capabilityId}:${permission.version}`}\n label={`${permission.capabilityId} v${permission.version}`}\n size=\"compact\"\n tone={permission.state === \"available\" ? \"positive\" : \"neutral\"}\n />\n ))}\n {administration.permissions.length === 0 ? (\n <Text tone=\"secondary\" variant=\"meta\">\n No provider operations were negotiated.\n </Text>\n ) : null}\n </div>\n </div>\n <div className={styles.administrationSection}>\n <Text as=\"h4\" variant=\"label\">\n Schedule and freshness\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n {administration.schedule.mode === \"manual\"\n ? \"Manual synchronization\"\n : \"This provider does not support synchronization\"}\n {administration.synchronization?.lastSuccessAt === null ||\n administration.synchronization?.lastSuccessAt === undefined\n ? \" · No successful sync recorded\"\n : ` · Last successful sync ${administration.synchronization.lastSuccessAt}`}\n </Text>\n </div>\n <div className={styles.administrationSection}>\n <Text as=\"h4\" variant=\"label\">\n Diagnostics\n </Text>\n <div className={styles.diagnostics}>\n {administration.diagnostics.map((diagnostic) => (\n <div className={styles.diagnostic} key={diagnostic.code}>\n <StateLabel label={diagnostic.severity} size=\"compact\" tone={diagnosticTone(diagnostic.severity)} />\n <Text variant=\"meta\">{diagnostic.summary}</Text>\n </div>\n ))}\n </div>\n </div>\n {canConfigure && administration.credentialFields.length > 0 ? (\n <form className={styles.credentialRecovery} onSubmit={submit}>\n <Text as=\"h4\" variant=\"label\">\n Credential recovery\n </Text>\n <Text tone=\"secondary\" variant=\"meta\">\n Values are sent directly to the machine-local secret store and are never returned by this page.\n </Text>\n {manualCredentialFields.map((field) => (\n <Field description={field.description} key={field.key} label={field.label} size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"off\"\n maxLength={16_384}\n onChange={(event) => {\n const value = event.currentTarget.value\n setCredentialValues((current) => new Map(current).set(field.key, value))\n }}\n type=\"password\"\n value={credentialValues.get(field.key) ?? \"\"}\n />\n )}\n </Field>\n ))}\n {supportsOAuthRecovery ? (\n <div className={styles.administrationSection}>\n <Text variant=\"meta\">\n Atlassian OAuth recovery creates a new machine-local profile and verifies this connection’s existing\n site and resource before applying it.\n </Text>\n <Button\n loading={oauthState === \"starting\"}\n onClick={() => startOAuth()}\n type=\"button\"\n variant=\"secondary\"\n >\n Sign in with Atlassian\n </Button>\n {oauthState === \"configuration-required\" ? (\n <>\n <Text tone=\"secondary\" variant=\"meta\">\n Configure the OAuth callback URL in Atlassian: {oauthCallbackUrl}\n </Text>\n <Field label=\"OAuth client ID\" size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n onChange={(event) => setOAuthClientId(event.currentTarget.value)}\n value={oauthClientId}\n />\n )}\n </Field>\n <Field label=\"OAuth client secret\" size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"off\"\n onChange={(event) => setOAuthClientSecret(event.currentTarget.value)}\n type=\"password\"\n value={oauthClientSecret}\n />\n )}\n </Field>\n <Button onClick={configureOAuth} type=\"button\" variant=\"secondary\">\n Save client and sign in\n </Button>\n </>\n ) : null}\n {oauthState === \"failed\" ? (\n <Text className={styles.setupError} role=\"alert\" variant=\"body\">\n Atlassian sign-in could not start. Verify the local OAuth client and try again.\n </Text>\n ) : null}\n </div>\n ) : null}\n <div className={styles.resourceActions}>\n {manualCredentialFields.length > 0 ? (\n <Button\n disabled={mutation === \"revoking\"}\n loading={mutation === \"reauthorizing\"}\n type=\"submit\"\n variant=\"secondary\"\n >\n Replace credentials and test\n </Button>\n ) : null}\n <Button\n disabled={mutation === \"reauthorizing\"}\n loading={mutation === \"revoking\"}\n onClick={revoke}\n type=\"button\"\n variant=\"quiet\"\n >\n Revoke credentials\n </Button>\n </div>\n {mutation === \"failed\" ? (\n <Text className={styles.setupError} role=\"alert\" variant=\"body\">\n The credential change was not applied. Refresh the details and try again.\n </Text>\n ) : null}\n </form>\n ) : null}\n </section>\n )\n}\n","import { Button, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport type { ReactElement } from \"react\"\n\nimport type { PluginSynchronizationState } from \"../../api/plugins.js\"\nimport styles from \"./ServicesPage.module.css\"\n\n/** Browser lifecycle for one connection's durable manual synchronization state. */\nexport type ConnectionSynchronizationViewState =\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"syncing\"; readonly previous: PluginSynchronizationState | null }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly synchronization: PluginSynchronizationState }\n\nconst resultPresentation = (\n result: PluginSynchronizationState[\"result\"]\n): { readonly label: string; readonly tone: \"critical\" | \"neutral\" | \"positive\" | \"progress\" } => {\n switch (result) {\n case \"never\":\n return { label: \"Never synchronized\", tone: \"neutral\" }\n case \"running\":\n return { label: \"Synchronizing\", tone: \"progress\" }\n case \"synchronized\":\n return { label: \"Synchronized\", tone: \"positive\" }\n case \"source-unavailable\":\n return { label: \"Source unavailable\", tone: \"critical\" }\n case \"interrupted\":\n return { label: \"Interrupted\", tone: \"critical\" }\n }\n}\n\nconst StateDetails = ({\n isSyncing,\n synchronization\n}: {\n readonly isSyncing: boolean\n readonly synchronization: PluginSynchronizationState\n}): ReactElement => {\n // While an attempt is in flight, surface the in-progress state instead of the\n // stale prior result. Progress is indeterminate: pages committed only persist\n // once the attempt completes, so the prior count reads as trailing context.\n const presentation: ReturnType<typeof resultPresentation> = isSyncing\n ? { label: \"Synchronizing…\", tone: \"progress\" }\n : resultPresentation(synchronization.result)\n return (\n <div className={styles.syncState}>\n <StateLabel label={presentation.label} size=\"compact\" tone={presentation.tone} />\n <Text tone=\"secondary\" variant=\"meta\">\n Last attempt:{\" \"}\n {synchronization.lastAttemptAt === null ? \"never\" : DateTime.formatIso(synchronization.lastAttemptAt)} · Last\n success: {synchronization.lastSuccessAt === null ? \"never\" : DateTime.formatIso(synchronization.lastSuccessAt)}\n {` · ${synchronization.pagesCommitted} ${synchronization.pagesCommitted === 1 ? \"page\" : \"pages\"}`}\n </Text>\n </div>\n )\n}\n\n/** Compact read/action presentation for the shared manual-sync API. */\nexport const ConnectionSynchronization = ({\n canSynchronize,\n onRefresh,\n onSynchronize,\n state\n}: {\n readonly canSynchronize: boolean\n readonly onRefresh: () => void\n readonly onSynchronize: () => void\n readonly state: ConnectionSynchronizationViewState | undefined\n}): ReactElement | null => {\n if (state === undefined) return null\n const isSyncing = state._tag === \"syncing\"\n const synchronization =\n state._tag === \"ready\" ? state.synchronization : state._tag === \"syncing\" ? state.previous : null\n return (\n <div className={styles.synchronization}>\n {synchronization === null ? (\n isSyncing ? (\n <StateLabel label=\"Synchronizing…\" size=\"compact\" tone=\"progress\" />\n ) : null\n ) : (\n <StateDetails isSyncing={isSyncing} synchronization={synchronization} />\n )}\n {state._tag === \"loading\" ? (\n <Text tone=\"secondary\" variant=\"meta\">\n Loading synchronization state…\n </Text>\n ) : null}\n {state._tag === \"failed\" ? (\n <Text as=\"p\" className={styles.setupError} role=\"alert\" variant=\"body\">\n Synchronization state is unavailable.\n </Text>\n ) : null}\n <div className={styles.syncActions}>\n <Button\n disabled={!canSynchronize || state._tag === \"loading\" || state._tag === \"syncing\"}\n loading={state._tag === \"syncing\"}\n onClick={onSynchronize}\n variant=\"secondary\"\n >\n Sync now\n </Button>\n {state._tag === \"failed\" ? (\n <Button onClick={onRefresh} variant=\"quiet\">\n Refresh state\n </Button>\n ) : null}\n </div>\n </div>\n )\n}\n","import type { PluginConnectionSummary, PluginConnectionTestResult } from \"../../api/plugins.js\"\n\nexport type ConnectionTestState =\n | { readonly _tag: \"testing\" }\n | { readonly _tag: \"result\"; readonly result: PluginConnectionTestResult }\n | { readonly _tag: \"request-failed\" }\n\nexport type ConnectionEnablementState = \"changing\" | \"request-failed\"\n\n/** Present durable and freshly tested connection state with one consistent vocabulary. */\nexport const connectionStatus = (\n connection: PluginConnectionSummary,\n testState: ConnectionTestState | undefined\n): { readonly label: string; readonly tone: \"neutral\" | \"positive\" | \"critical\" | \"caution\" | \"progress\" } => {\n if (!connection.isEnabled) return { label: \"Disabled\", tone: \"neutral\" }\n if (testState?._tag === \"testing\") return { label: \"Checking\", tone: \"progress\" }\n if (testState?._tag === \"result\") {\n return testState.result._tag === \"healthy\"\n ? { label: \"Healthy\", tone: \"positive\" }\n : { label: \"Unavailable\", tone: \"critical\" }\n }\n if (connection.health === null) return { label: \"Not checked\", tone: \"neutral\" }\n switch (connection.health._tag) {\n case \"healthy\":\n return { label: \"Healthy\", tone: \"positive\" }\n case \"degraded\":\n return { label: \"Degraded\", tone: \"caution\" }\n case \"unavailable\":\n return { label: \"Unavailable\", tone: \"critical\" }\n case \"disabled\":\n return { label: \"Not checked\", tone: \"neutral\" }\n }\n}\n","import { ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Field, StateLabel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport { type FormEvent, type ReactElement, useEffect, useRef, useState } from \"react\"\n\nimport type {\n AtlassianOAuthProviderIntent,\n PluginConnectionSummary,\n PluginCredentialReplacement,\n ProviderAccountSummary\n} from \"../../api/plugins.js\"\nimport type { PluginConnectionId } from \"../../domain/identifiers.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\nimport { ConnectionTestEvidence } from \"./ConnectionTestEvidence.js\"\nimport { ConnectionAdministration, type ConnectionAdministrationViewState } from \"./ConnectionAdministration.js\"\nimport { ConnectionSynchronization, type ConnectionSynchronizationViewState } from \"./ConnectionSynchronization.js\"\nimport type { ConnectionTestTransport } from \"./connectionTestTransport.js\"\nimport { type ConnectionEnablementState, type ConnectionTestState, connectionStatus } from \"./connectionState.js\"\nimport styles from \"./ServicesPage.module.css\"\n\nconst resourceKind = (providerId: ProviderId): string => {\n switch (providerId) {\n case \"codecommit\":\n return \"Repository\"\n case \"codepipeline\":\n return \"Pipeline\"\n case \"jira\":\n return \"Project\"\n case \"confluence\":\n return \"Space\"\n case \"clockify\":\n return \"Workspace\"\n }\n}\n\nconst atlassianProvidersForAccount = (account: ProviderAccountSummary): AtlassianOAuthProviderIntent | undefined => {\n const providers: Array<\"jira\" | \"confluence\"> = []\n if (account.resources.some(({ providerId }) => providerId === \"jira\")) providers.push(\"jira\")\n if (account.resources.some(({ providerId }) => providerId === \"confluence\")) providers.push(\"confluence\")\n return providers.length === 0 ? undefined : providers\n}\n\nconst resourceSummaryContent = (\n resource: ProviderAccountSummary[\"resources\"][number],\n status: ReturnType<typeof connectionStatus>,\n hasControls: boolean\n): ReactElement => (\n <>\n <div className={styles.connectionIdentity}>\n <ServiceMark service={resource.providerId} size=\"compact\" />\n <div className={styles.identity}>\n <Text as=\"h3\" variant=\"card-title\">\n {resource.displayName}\n </Text>\n <Text className={styles.identifier} tone=\"secondary\" variant=\"meta\">\n {resourceKind(resource.providerId)} · {resource.providerImmutableId}\n </Text>\n </div>\n </div>\n <div className={styles.resourceStatus}>\n <StateLabel label={status.label} size=\"compact\" tone={status.tone} />\n {hasControls ? (\n <span className={styles.disclosure}>\n Controls <span aria-hidden=\"true\">›</span>\n </span>\n ) : null}\n </div>\n </>\n)\n\nconst ConnectedProviderResource = ({\n administrationState,\n atlassianOAuthProviders,\n canConfigure,\n connection,\n enablementState,\n onReauthorize,\n onRefreshSynchronization,\n onRevoke,\n onSetEnabled,\n onStartAtlassianOAuth,\n onSynchronize,\n onTest,\n resource,\n synchronizationState,\n testState\n}: {\n readonly atlassianOAuthProviders?: AtlassianOAuthProviderIntent\n readonly canConfigure: boolean\n readonly connection: PluginConnectionSummary\n readonly enablementState: ConnectionEnablementState | undefined\n readonly onRefreshSynchronization: (pluginConnectionId: PluginConnectionId) => void\n readonly onReauthorize: (\n pluginConnectionId: PluginConnectionId,\n credentials: ReadonlyArray<PluginCredentialReplacement>\n ) => Promise<boolean>\n readonly onRevoke: (pluginConnectionId: PluginConnectionId) => Promise<boolean>\n readonly onStartAtlassianOAuth: ConnectionTestTransport[\"startAtlassianOAuthGrant\"]\n readonly onSetEnabled: (pluginConnectionId: PluginConnectionId, isEnabled: boolean) => void\n readonly onSynchronize: (pluginConnectionId: PluginConnectionId) => void\n readonly onTest: (pluginConnectionId: PluginConnectionId) => void\n readonly resource: ProviderAccountSummary[\"resources\"][number]\n readonly synchronizationState: ConnectionSynchronizationViewState | undefined\n readonly testState: ConnectionTestState | undefined\n readonly administrationState: ConnectionAdministrationViewState | undefined\n}): ReactElement => {\n const status = connectionStatus(connection, testState)\n const isTesting = testState?._tag === \"testing\"\n const isChanging = enablementState === \"changing\"\n const needsAttention = status.tone === \"caution\" || status.tone === \"critical\" || status.tone === \"progress\"\n const disclosure = useRef<HTMLDetailsElement>(null)\n const previouslyNeededAttention = useRef(false)\n\n useEffect(() => {\n if (needsAttention && !previouslyNeededAttention.current && disclosure.current !== null) {\n disclosure.current.open = true\n }\n previouslyNeededAttention.current = needsAttention\n }, [needsAttention])\n\n return (\n <details className={styles.resource} data-status-tone={status.tone} ref={disclosure}>\n <summary className={styles.resourceSummary}>{resourceSummaryContent(resource, status, true)}</summary>\n <div className={styles.resourceBody}>\n <ConnectionTestEvidence state={testState} />\n <ConnectionSynchronization\n canSynchronize={canConfigure && connection.isEnabled}\n onRefresh={() => onRefreshSynchronization(connection.pluginConnectionId)}\n onSynchronize={() => onSynchronize(connection.pluginConnectionId)}\n state={synchronizationState}\n />\n <ConnectionAdministration\n {...(atlassianOAuthProviders === undefined ? {} : { atlassianOAuthProviders })}\n canConfigure={canConfigure}\n onReauthorize={(credentials) => onReauthorize(connection.pluginConnectionId, credentials)}\n onRevoke={() => onRevoke(connection.pluginConnectionId)}\n onStartAtlassianOAuth={onStartAtlassianOAuth}\n state={administrationState}\n />\n <div className={styles.resourceActions}>\n <Button\n disabled={!canConfigure || isChanging || isTesting || !connection.isEnabled}\n loading={isTesting}\n onClick={() => onTest(connection.pluginConnectionId)}\n variant=\"secondary\"\n >\n Test\n </Button>\n <Button\n disabled={!canConfigure || isChanging}\n loading={isChanging}\n onClick={() => onSetEnabled(connection.pluginConnectionId, !connection.isEnabled)}\n variant=\"quiet\"\n >\n {connection.isEnabled ? \"Disable\" : \"Enable\"}\n </Button>\n </div>\n {enablementState === \"request-failed\" ? (\n <Text as=\"p\" className={styles.setupError} role=\"alert\" variant=\"body\">\n Control Center could not change this service. Refresh and try again.\n </Text>\n ) : null}\n </div>\n </details>\n )\n}\n\n/** Compact account-level view of independently actionable provider resources. */\nexport const ProviderAccountCard = ({\n account,\n administrationStates,\n canConfigure,\n connections,\n enablementStates,\n onAdd,\n onReauthorize,\n onRefreshSynchronization,\n onRename,\n onRevoke,\n onSetEnabled,\n onStartAtlassianOAuth,\n onSynchronize,\n onTest,\n synchronizationStates,\n testStates\n}: {\n readonly account: ProviderAccountSummary\n readonly canConfigure: boolean\n readonly connections: ReadonlyArray<PluginConnectionSummary>\n readonly administrationStates: ReadonlyMap<PluginConnectionId, ConnectionAdministrationViewState>\n readonly enablementStates: ReadonlyMap<PluginConnectionId, ConnectionEnablementState>\n readonly onAdd: (providerId: ProviderId, providerImmutableId: string) => void\n readonly onSetEnabled: (pluginConnectionId: PluginConnectionId, isEnabled: boolean) => void\n readonly onRefreshSynchronization: (pluginConnectionId: PluginConnectionId) => void\n readonly onReauthorize: (\n pluginConnectionId: PluginConnectionId,\n credentials: ReadonlyArray<PluginCredentialReplacement>\n ) => Promise<boolean>\n readonly onRename: (displayName: string) => Promise<boolean>\n readonly onRevoke: (pluginConnectionId: PluginConnectionId) => Promise<boolean>\n readonly onStartAtlassianOAuth: ConnectionTestTransport[\"startAtlassianOAuthGrant\"]\n readonly onSynchronize: (pluginConnectionId: PluginConnectionId) => void\n readonly synchronizationStates: ReadonlyMap<PluginConnectionId, ConnectionSynchronizationViewState>\n readonly onTest: (pluginConnectionId: PluginConnectionId) => void\n readonly testStates: ReadonlyMap<PluginConnectionId, ConnectionTestState>\n}): ReactElement => {\n const [isEditing, setIsEditing] = useState(false)\n const [displayName, setDisplayName] = useState(account.displayName)\n const [renameState, setRenameState] = useState<\"idle\" | \"saving\" | \"failed\">(\"idle\")\n\n useEffect(() => setDisplayName(account.displayName), [account.displayName])\n\n const rename = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setRenameState(\"saving\")\n void onRename(displayName.trim()).then((succeeded) => {\n setRenameState(succeeded ? \"idle\" : \"failed\")\n if (succeeded) setIsEditing(false)\n })\n }\n\n return (\n <Surface as=\"article\" className={styles.accountCard} padding=\"default\" shape=\"grouped\">\n <div className={styles.accountHeading}>\n <div className={styles.accountIdentity}>\n <Text as=\"h2\" variant=\"section-title\">\n {account.providerFamily === \"aws\"\n ? \"AWS account\"\n : account.providerFamily === \"atlassian\"\n ? \"Atlassian site\"\n : \"Provider account\"}{\" \"}\n {account.displayName}\n </Text>\n <Text className={styles.identifier} tone=\"secondary\" variant=\"meta\">\n Verified identity · {account.providerImmutableId}\n </Text>\n </div>\n <StateLabel\n label={`${account.resources.length} ${account.resources.length === 1 ? \"resource\" : \"resources\"}`}\n size=\"compact\"\n tone=\"positive\"\n />\n </div>\n {canConfigure ? (\n isEditing ? (\n <form className={styles.accountEdit} onSubmit={rename}>\n <Field label=\"Account display name\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n maxLength={200}\n onChange={(event) => setDisplayName(event.currentTarget.value)}\n value={displayName}\n />\n )}\n </Field>\n <div className={styles.resourceActions}>\n <Button loading={renameState === \"saving\"} type=\"submit\" variant=\"secondary\">\n Save account name\n </Button>\n <Button\n disabled={renameState === \"saving\"}\n onClick={() => {\n setDisplayName(account.displayName)\n setIsEditing(false)\n setRenameState(\"idle\")\n }}\n type=\"button\"\n variant=\"quiet\"\n >\n Cancel\n </Button>\n </div>\n {renameState === \"failed\" ? (\n <Text className={styles.setupError} role=\"alert\" variant=\"body\">\n The account changed elsewhere. Refresh and try again.\n </Text>\n ) : null}\n </form>\n ) : (\n <div className={styles.accountEditAction}>\n <Button onClick={() => setIsEditing(true)} variant=\"quiet\">\n Edit account name\n </Button>\n </div>\n )\n ) : null}\n <div className={styles.resourceList}>\n {account.resources.map((resource) => {\n const connection = connections.find(\n (candidate) => candidate.followedResourceId === resource.followedResourceId\n )\n const testState = connection === undefined ? undefined : testStates.get(connection.pluginConnectionId)\n const enablementState =\n connection === undefined ? undefined : enablementStates.get(connection.pluginConnectionId)\n const status: ReturnType<typeof connectionStatus> =\n connection === undefined ? { label: \"Followed\", tone: \"neutral\" } : connectionStatus(connection, testState)\n if (connection === undefined) {\n return (\n <div className={styles.resource} data-status-tone={status.tone} key={resource.followedResourceId}>\n <div className={styles.resourceSummary}>{resourceSummaryContent(resource, status, false)}</div>\n </div>\n )\n }\n const atlassianOAuthProviders = atlassianProvidersForAccount(account)\n return (\n <ConnectedProviderResource\n {...(atlassianOAuthProviders === undefined ? {} : { atlassianOAuthProviders })}\n canConfigure={canConfigure}\n connection={connection}\n administrationState={administrationStates.get(connection.pluginConnectionId)}\n enablementState={enablementState}\n key={resource.followedResourceId}\n onRefreshSynchronization={onRefreshSynchronization}\n onReauthorize={onReauthorize}\n onRevoke={onRevoke}\n onStartAtlassianOAuth={onStartAtlassianOAuth}\n onSetEnabled={onSetEnabled}\n onSynchronize={onSynchronize}\n onTest={onTest}\n resource={resource}\n synchronizationState={synchronizationStates.get(connection.pluginConnectionId)}\n testState={testState}\n />\n )\n })}\n </div>\n {account.providerFamily === \"aws\" ? (\n <div className={styles.accountActions}>\n <Button\n disabled={!canConfigure}\n onClick={() => onAdd(\"codecommit\", account.providerImmutableId)}\n variant=\"secondary\"\n >\n Add repository\n </Button>\n <Button\n disabled={!canConfigure}\n onClick={() => onAdd(\"codepipeline\", account.providerImmutableId)}\n variant=\"secondary\"\n >\n Add pipeline\n </Button>\n </div>\n ) : account.providerFamily === \"atlassian\" ? (\n <div className={styles.accountActions}>\n <Button\n disabled={!canConfigure}\n onClick={() => onAdd(\"jira\", account.providerImmutableId)}\n variant=\"secondary\"\n >\n Add Jira project\n </Button>\n <Button\n disabled={!canConfigure}\n onClick={() => onAdd(\"confluence\", account.providerImmutableId)}\n variant=\"secondary\"\n >\n Add Confluence space\n </Button>\n </div>\n ) : null}\n </Surface>\n )\n}\n","import { ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Field, StateLabel, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Predicate from \"effect/Predicate\"\nimport { type FormEvent, type ReactElement, useCallback, useEffect, useRef, useState } from \"react\"\nimport { useNavigate, useSearchParams } from \"react-router\"\n\nimport type {\n AtlassianOAuthClientConfiguration,\n AtlassianOAuthGrantStartResponse,\n AtlassianOAuthProviderIntent,\n AtlassianProfileDiscoveryResponse,\n AwsProfileDiscoveryResponse,\n AwsResourceDiscoveryRequest,\n AwsResourceDiscoveryResponse,\n CreatePluginConnectionRequest,\n CreatePluginConnectionResponse,\n CreatePluginConnectionValue,\n PluginConnectionSummary,\n PluginCredentialReplacement,\n PluginOverviewResponse,\n PluginServiceCatalogEntry\n} from \"../../api/plugins.js\"\nimport type { PluginConnectionId, ProviderAccountId } from \"../../domain/identifiers.js\"\nimport { firstPartyServiceIdentities, type FirstPartyServiceIdentity } from \"../../domain/firstPartyServices.js\"\nimport type { ProviderId } from \"../../domain/sourceRevision.js\"\nimport { browserReadableSessionKey, useBrowserSession } from \"../BrowserSession.js\"\nimport { AtlassianAccountSetupForm, type AtlassianSetupIntent } from \"./AtlassianAccountSetupForm.js\"\nimport { AwsAccountSetupForm } from \"./AwsAccountSetupForm.js\"\nimport { ConnectionTestEvidence } from \"./ConnectionTestEvidence.js\"\nimport { ConnectionAdministration, type ConnectionAdministrationViewState } from \"./ConnectionAdministration.js\"\nimport { ConnectionSynchronization, type ConnectionSynchronizationViewState } from \"./ConnectionSynchronization.js\"\nimport { browserConnectionTestTransport, type ConnectionTestTransport } from \"./connectionTestTransport.js\"\nimport { type ConnectionEnablementState, type ConnectionTestState, connectionStatus } from \"./connectionState.js\"\nimport { ProviderAccountCard } from \"./ProviderAccountCard.js\"\nimport { type ServiceConnectionDraft, serviceSetupValue } from \"./serviceSetupValues.js\"\nimport {\n selectedAtlassianOAuthProfileId,\n selectedAtlassianOAuthProviders,\n selectedAtlassianOAuthSiteId,\n selectedAtlassianRecoveryConnectionId,\n selectedAtlassianRecoveryProfileId,\n selectedServiceProvider,\n servicePairingPath\n} from \"./serviceOnboarding.js\"\nimport styles from \"./ServicesPage.module.css\"\n\ntype AwsProfilesState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly profiles: AwsProfileDiscoveryResponse }\n\ntype AtlassianProfilesState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly profiles: AtlassianProfileDiscoveryResponse }\n\ntype ConnectionsState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly overview: PluginOverviewResponse }\n\nconst setupDraftKey = (draft: ServiceConnectionDraft): string => `${draft.catalog.providerId}\\0${draft.displayName}`\n\nconst allAtlassianProducts: AtlassianOAuthProviderIntent = [\"jira\", \"confluence\"]\n\nconst allAtlassianProductsIntent: AtlassianSetupIntent = {\n preferredProfileId: null,\n preferredSiteId: null,\n providers: allAtlassianProducts,\n requestedOAuthProviders: allAtlassianProducts\n}\n\nconst missingAtlassianProducts = (\n connections: ReadonlyArray<PluginConnectionSummary>\n): AtlassianOAuthProviderIntent => {\n const providers = allAtlassianProducts.filter(\n (providerId) => !connections.some((connection) => connection.providerId === providerId)\n )\n return providers.length === 0 ? allAtlassianProducts : providers\n}\n\nconst hasCanonicalProfileForConnectedProduct = (\n connections: ReadonlyArray<PluginConnectionSummary>,\n profiles: AtlassianProfileDiscoveryResponse,\n setupProviders: AtlassianOAuthProviderIntent\n): boolean =>\n setupProviders.length === 1 &&\n allAtlassianProducts.some(\n (providerId) =>\n !setupProviders.includes(providerId) &&\n connections.some((connection) => connection.providerId === providerId) &&\n profiles.some((profile) => !profile.profileId.startsWith(\"legacy:\") && profile.providers.includes(providerId))\n )\n\nconst hasConnectedProductOutsideSetup = (\n connections: ReadonlyArray<PluginConnectionSummary>,\n setupProviders: AtlassianOAuthProviderIntent\n): boolean =>\n setupProviders.length === 1 &&\n allAtlassianProducts.some(\n (providerId) =>\n !setupProviders.includes(providerId) && connections.some((connection) => connection.providerId === providerId)\n )\n\nconst missingAtlassianProductsIntent = (\n connections: ReadonlyArray<PluginConnectionSummary>,\n requestedProvider?: \"jira\" | \"confluence\"\n): AtlassianSetupIntent => {\n const providers =\n requestedProvider !== undefined && connections.some(({ providerId }) => providerId === requestedProvider)\n ? [requestedProvider]\n : missingAtlassianProducts(connections)\n return {\n preferredProfileId: null,\n preferredSiteId: null,\n providers,\n requestedOAuthProviders: null\n }\n}\n\nconst resolvedAtlassianSetupIntent = (\n intent: AtlassianSetupIntent,\n connections: ReadonlyArray<PluginConnectionSummary>,\n profilesState: AtlassianProfilesState\n): AtlassianSetupIntent => {\n if (intent.requestedOAuthProviders !== null) return intent\n const hasOutsideConnection = hasConnectedProductOutsideSetup(connections, intent.providers)\n if (hasOutsideConnection && (profilesState._tag === \"idle\" || profilesState._tag === \"loading\")) {\n return intent\n }\n const profiles = profilesState._tag === \"ready\" ? profilesState.profiles : []\n return {\n ...intent,\n requestedOAuthProviders:\n (hasOutsideConnection && profilesState._tag === \"failed\") ||\n hasCanonicalProfileForConnectedProduct(connections, profiles, intent.providers)\n ? allAtlassianProducts\n : intent.providers\n }\n}\n\nconst ConnectionCard = ({\n administrationState,\n canConfigure,\n canTest,\n connection,\n enablementState,\n onConfigure,\n onReauthorize,\n onRefreshSynchronization,\n onRevoke,\n onSetEnabled,\n onStartAtlassianOAuth,\n onSynchronize,\n onTest,\n synchronizationState,\n testState\n}: {\n readonly canConfigure: boolean\n readonly canTest: boolean\n readonly connection: PluginConnectionSummary\n readonly administrationState: ConnectionAdministrationViewState | undefined\n readonly enablementState: ConnectionEnablementState | undefined\n readonly onConfigure: () => void\n readonly onSetEnabled: (pluginConnectionId: PluginConnectionId, isEnabled: boolean) => void\n readonly onRefreshSynchronization: (pluginConnectionId: PluginConnectionId) => void\n readonly onReauthorize: (\n pluginConnectionId: PluginConnectionId,\n credentials: ReadonlyArray<PluginCredentialReplacement>\n ) => Promise<boolean>\n readonly onRevoke: (pluginConnectionId: PluginConnectionId) => Promise<boolean>\n readonly onStartAtlassianOAuth: ConnectionTestTransport[\"startAtlassianOAuthGrant\"]\n readonly onSynchronize: (pluginConnectionId: PluginConnectionId) => void\n readonly synchronizationState: ConnectionSynchronizationViewState | undefined\n readonly onTest: (pluginConnectionId: PluginConnectionId) => void\n readonly testState: ConnectionTestState | undefined\n}): ReactElement => {\n const isTesting = testState?._tag === \"testing\"\n const hasTested = testState !== undefined && testState._tag !== \"testing\"\n const isChanging = enablementState === \"changing\"\n const status = connectionStatus(connection, testState)\n return (\n <Surface as=\"article\" className={styles.card} padding=\"default\" shape=\"grouped\">\n <div className={styles.cardHeading}>\n <div className={styles.connectionIdentity}>\n <ServiceMark service={connection.providerId} size=\"compact\" />\n <Text as=\"h2\" variant=\"card-title\">\n {connection.displayName}\n </Text>\n </div>\n <StateLabel label={status.label} size=\"compact\" tone={status.tone} />\n </div>\n <ConnectionTestEvidence state={testState} />\n <ConnectionSynchronization\n canSynchronize={canConfigure && connection.isEnabled}\n onRefresh={() => onRefreshSynchronization(connection.pluginConnectionId)}\n onSynchronize={() => onSynchronize(connection.pluginConnectionId)}\n state={synchronizationState}\n />\n <ConnectionAdministration\n {...(connection.providerId === \"jira\"\n ? { atlassianOAuthProviders: [\"jira\"] }\n : connection.providerId === \"confluence\"\n ? { atlassianOAuthProviders: [\"confluence\"] }\n : {})}\n canConfigure={canConfigure}\n onReauthorize={(credentials) => onReauthorize(connection.pluginConnectionId, credentials)}\n onRevoke={() => onRevoke(connection.pluginConnectionId)}\n onStartAtlassianOAuth={onStartAtlassianOAuth}\n state={administrationState}\n />\n <div className={styles.cardAction}>\n <Button\n disabled={!canTest || isChanging || isTesting || !connection.isEnabled}\n loading={isTesting}\n onClick={() => onTest(connection.pluginConnectionId)}\n variant=\"secondary\"\n >\n {hasTested ? \"Retry test\" : \"Test connection\"}\n </Button>\n <Button disabled={!canConfigure} onClick={onConfigure} variant=\"secondary\">\n Add connection\n </Button>\n <Button\n disabled={!canConfigure || isChanging}\n loading={isChanging}\n onClick={() => onSetEnabled(connection.pluginConnectionId, !connection.isEnabled)}\n variant={connection.isEnabled ? \"secondary\" : \"primary\"}\n >\n {connection.isEnabled ? \"Disable\" : \"Enable service\"}\n </Button>\n {!canTest ? (\n <Text tone=\"secondary\" variant=\"meta\">\n Owner access is required.\n </Text>\n ) : null}\n </div>\n {enablementState === \"request-failed\" ? (\n <Text as=\"p\" className={styles.setupError} role=\"alert\" variant=\"body\">\n Control Center could not change this service. Refresh and try again.\n </Text>\n ) : null}\n </Surface>\n )\n}\n\nconst SetupForm = ({\n catalog,\n isSubmitting,\n onCancel,\n onSubmit\n}: {\n readonly catalog: PluginServiceCatalogEntry\n readonly isSubmitting: boolean\n readonly onCancel: () => void\n readonly onSubmit: (displayName: string, values: ReadonlyArray<CreatePluginConnectionValue>) => Promise<boolean>\n}): ReactElement => {\n const [displayName, setDisplayName] = useState(catalog.displayName)\n const [setupError, setSetupError] = useState<string | null>(null)\n const [values, setValues] = useState<ReadonlyMap<string, string>>(\n new Map(catalog.configurationFields.map((field) => [field.key, field.defaultValue ?? \"\"]))\n )\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setSetupError(null)\n const requestValues = catalog.configurationFields.map((field) =>\n serviceSetupValue(field, values.get(field.key) ?? \"\")\n )\n void onSubmit(displayName, requestValues).then((didCreate) => {\n if (!didCreate) {\n setSetupError(\"Control Center could not create this connection. Check the fields and try again.\")\n return\n }\n setValues((current) => {\n const cleared = new Map(current)\n for (const field of catalog.configurationFields) {\n if (field.kind === \"secret\") cleared.set(field.key, \"\")\n }\n return cleared\n })\n })\n }\n\n const updateValue = (key: string, value: string): void => {\n setValues((current) => new Map(current).set(key, value))\n }\n\n return (\n <form className={styles.setupForm} onSubmit={submit}>\n <Field label=\"Connection name\" required size=\"compact\">\n {(controlProps) => (\n <input\n {...controlProps}\n maxLength={200}\n onChange={(event) => setDisplayName(event.currentTarget.value)}\n value={displayName}\n />\n )}\n </Field>\n {catalog.configurationFields.map((field) => (\n <Field\n description={field.description}\n key={field.key}\n label={field.label}\n required={field.required}\n size=\"compact\"\n >\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete={field.kind === \"secret\" ? \"off\" : undefined}\n disabled={field.isReadOnly}\n max={field.maximum ?? undefined}\n maxLength={field.kind === \"integer\" ? undefined : field.kind === \"secret\" ? 16_384 : 4_096}\n min={field.minimum ?? undefined}\n onChange={(event) => updateValue(field.key, event.currentTarget.value)}\n type={\n field.kind === \"secret\"\n ? \"password\"\n : field.kind === \"integer\"\n ? \"number\"\n : field.kind === \"url\"\n ? \"url\"\n : \"text\"\n }\n value={values.get(field.key) ?? \"\"}\n />\n )}\n </Field>\n ))}\n {setupError === null ? null : (\n <Text as=\"p\" className={styles.setupError} role=\"alert\" variant=\"body\">\n {setupError}\n </Text>\n )}\n <div className={styles.setupActions}>\n <Button disabled={isSubmitting} onClick={onCancel} type=\"button\" variant=\"secondary\">\n Cancel\n </Button>\n <Button loading={isSubmitting} type=\"submit\" variant=\"primary\">\n Enable and test\n </Button>\n </div>\n </form>\n )\n}\n\nconst CatalogCard = ({\n atlassianProfiles,\n atlassianProfilesState,\n atlassianSetupIntent,\n awsProfiles,\n awsProfilesState,\n canConfigure,\n catalog,\n catalogs,\n isAdditional,\n isOpen,\n isRecovery,\n isSubmitting,\n onCancel,\n onDiscoverAws,\n onOpen,\n onStartAtlassianOAuth,\n onSubmit,\n onSubmitAtlassian,\n onSubmitAws\n}: {\n readonly atlassianProfiles: AtlassianProfileDiscoveryResponse\n readonly atlassianProfilesState: AtlassianProfilesState[\"_tag\"]\n readonly atlassianSetupIntent: AtlassianSetupIntent\n readonly awsProfiles: AwsProfileDiscoveryResponse\n readonly awsProfilesState: AwsProfilesState[\"_tag\"]\n readonly canConfigure: boolean\n readonly catalog: PluginServiceCatalogEntry\n readonly catalogs: ReadonlyArray<PluginServiceCatalogEntry>\n readonly isAdditional: boolean\n readonly isOpen: boolean\n readonly isSubmitting: boolean\n readonly isRecovery: boolean\n readonly onCancel: () => void\n readonly onDiscoverAws: (\n request: AwsResourceDiscoveryRequest,\n signal: AbortSignal\n ) => Promise<AwsResourceDiscoveryResponse>\n readonly onOpen: () => void\n readonly onStartAtlassianOAuth: (\n providers: AtlassianOAuthProviderIntent,\n signal: AbortSignal,\n configuration?: AtlassianOAuthClientConfiguration\n ) => Promise<AtlassianOAuthGrantStartResponse>\n readonly onSubmit: (displayName: string, values: ReadonlyArray<CreatePluginConnectionValue>) => Promise<boolean>\n readonly onSubmitAtlassian: (drafts: ReadonlyArray<ServiceConnectionDraft>) => Promise<boolean>\n readonly onSubmitAws: (drafts: ReadonlyArray<ServiceConnectionDraft>) => Promise<boolean>\n}): ReactElement => {\n const isAws = catalog.providerId === \"codecommit\" || catalog.providerId === \"codepipeline\"\n const isAtlassian = catalog.providerId === \"jira\" || catalog.providerId === \"confluence\"\n return (\n <Surface as=\"article\" className={styles.card} padding=\"default\" shape=\"grouped\">\n <div className={styles.cardHeading}>\n <div className={styles.connectionIdentity}>\n <ServiceMark service={catalog.providerId} size=\"compact\" />\n <Text as=\"h2\" variant=\"card-title\">\n {catalog.displayName}\n </Text>\n </div>\n <StateLabel\n label={isRecovery ? \"Needs correction\" : isAdditional ? \"Add another\" : \"Not configured\"}\n size=\"compact\"\n tone={isRecovery ? \"critical\" : \"neutral\"}\n />\n </div>\n <Text tone=\"secondary\" variant=\"body\">\n {catalog.description}\n </Text>\n {isOpen ? (\n isAws ? (\n <AwsAccountSetupForm\n awsProfiles={awsProfiles}\n awsProfilesState={awsProfilesState}\n catalogs={catalogs}\n isSubmitting={isSubmitting}\n onCancel={onCancel}\n onDiscover={onDiscoverAws}\n onSubmit={onSubmitAws}\n />\n ) : isAtlassian ? (\n <AtlassianAccountSetupForm\n catalogs={catalogs}\n isSubmitting={isSubmitting}\n onCancel={onCancel}\n onStartOAuth={onStartAtlassianOAuth}\n onSubmit={onSubmitAtlassian}\n profiles={atlassianProfiles}\n profilesState={atlassianProfilesState}\n setupIntent={atlassianSetupIntent}\n />\n ) : (\n <SetupForm catalog={catalog} isSubmitting={isSubmitting} onCancel={onCancel} onSubmit={onSubmit} />\n )\n ) : (\n <div className={styles.cardAction}>\n <Button disabled={!canConfigure} onClick={onOpen} variant=\"secondary\">\n {isAws\n ? \"Configure AWS account\"\n : isAdditional && catalog.providerId === \"jira\"\n ? \"Add Jira project\"\n : isAdditional && catalog.providerId === \"confluence\"\n ? \"Add Confluence space\"\n : isAtlassian\n ? \"Configure Atlassian\"\n : \"Enable service\"}\n </Button>\n {!canConfigure ? (\n <Text tone=\"secondary\" variant=\"meta\">\n Owner access is required.\n </Text>\n ) : null}\n </div>\n )}\n </Surface>\n )\n}\n\nconst ServicePreviewCard = ({\n actionLabel = \"Pair to enable\",\n isActionDisabled = false,\n onEnable,\n service,\n statusLabel = \"Available\",\n statusTone = \"positive\"\n}: {\n readonly actionLabel?: string\n readonly isActionDisabled?: boolean\n readonly onEnable: () => void\n readonly service: FirstPartyServiceIdentity\n readonly statusLabel?: string\n readonly statusTone?: \"critical\" | \"neutral\" | \"positive\" | \"progress\"\n}): ReactElement => (\n <Surface as=\"article\" className={styles.card} padding=\"default\" shape=\"grouped\">\n <div className={styles.cardHeading}>\n <div className={styles.connectionIdentity}>\n <ServiceMark service={service.providerId} size=\"compact\" />\n <Text as=\"h2\" variant=\"card-title\">\n {service.displayName}\n </Text>\n </div>\n <StateLabel label={statusLabel} size=\"compact\" tone={statusTone} />\n </div>\n <Text tone=\"secondary\" variant=\"body\">\n {service.description}\n </Text>\n <div className={styles.cardAction}>\n <Button disabled={isActionDisabled} onClick={onEnable} variant=\"primary\">\n {actionLabel}\n </Button>\n </div>\n </Surface>\n)\n\n/** Manage fixed first-party providers and prove configured identities with owner-only live checks. */\nexport const ServicesPage = ({\n transport = browserConnectionTestTransport\n}: {\n readonly transport?: ConnectionTestTransport\n} = {}): ReactElement => {\n const navigate = useNavigate()\n const [searchParams, setSearchParams] = useSearchParams()\n const { invalidateSession, state: sessionState } = useBrowserSession()\n const sessionKey = browserReadableSessionKey(sessionState)\n const [requestRevision, setRequestRevision] = useState(0)\n const [connectionsState, setConnectionsState] = useState<ConnectionsState>({ _tag: \"idle\" })\n const [awsProfilesState, setAwsProfilesState] = useState<AwsProfilesState>({ _tag: \"idle\" })\n const [atlassianProfilesState, setAtlassianProfilesState] = useState<AtlassianProfilesState>({ _tag: \"idle\" })\n const [testStates, setTestStates] = useState<ReadonlyMap<PluginConnectionId, ConnectionTestState>>(new Map())\n const [enablementStates, setEnablementStates] = useState<ReadonlyMap<PluginConnectionId, ConnectionEnablementState>>(\n new Map()\n )\n const [synchronizationStates, setSynchronizationStates] = useState<\n ReadonlyMap<PluginConnectionId, ConnectionSynchronizationViewState>\n >(new Map())\n const [administrationStates, setAdministrationStates] = useState<\n ReadonlyMap<PluginConnectionId, ConnectionAdministrationViewState>\n >(new Map())\n const [openProvider, setOpenProvider] = useState<ProviderId | null>(null)\n const [atlassianSetupIntent, setAtlassianSetupIntent] = useState<AtlassianSetupIntent | null>(null)\n const [submittingProvider, setSubmittingProvider] = useState<ProviderId | null>(null)\n const testRequests = useRef(new Map<PluginConnectionId, AbortController>())\n const createRequest = useRef<AbortController | null>(null)\n const completedBatchDrafts = useRef(new Map<ProviderId, Set<string>>())\n const enablementRequests = useRef(new Map<PluginConnectionId, AbortController>())\n const awsProfileRequest = useRef<AbortController | null>(null)\n const atlassianProfileRequest = useRef<AbortController | null>(null)\n const synchronizationRequests = useRef(new Map<PluginConnectionId, AbortController>())\n const administrationRequests = useRef(new Map<PluginConnectionId, AbortController>())\n const administrationMutations = useRef(new Map<PluginConnectionId, AbortController>())\n const accountMutations = useRef(new Map<ProviderAccountId, AbortController>())\n\n const refreshAdministration = useCallback(\n (pluginConnectionId: PluginConnectionId): void => {\n if (sessionKey === null || transport.administration === undefined) return\n administrationRequests.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n administrationRequests.current.set(pluginConnectionId, request)\n setAdministrationStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"loading\" }))\n transport.administration(pluginConnectionId, request.signal).then(\n (administration) => {\n if (request.signal.aborted) return\n administrationRequests.current.delete(pluginConnectionId)\n setAdministrationStates((current) =>\n new Map(current).set(pluginConnectionId, { _tag: \"ready\", administration })\n )\n },\n (failure) => {\n if (request.signal.aborted) return\n administrationRequests.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setAdministrationStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"failed\" }))\n }\n )\n },\n [invalidateSession, sessionKey, transport]\n )\n\n const refreshSynchronization = useCallback(\n (pluginConnectionId: PluginConnectionId): void => {\n if (sessionKey === null || transport.synchronization === undefined) return\n synchronizationRequests.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n synchronizationRequests.current.set(pluginConnectionId, request)\n setSynchronizationStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"loading\" }))\n transport.synchronization(pluginConnectionId, request.signal).then(\n (synchronization) => {\n if (request.signal.aborted) return\n synchronizationRequests.current.delete(pluginConnectionId)\n setSynchronizationStates((current) =>\n new Map(current).set(pluginConnectionId, { _tag: \"ready\", synchronization })\n )\n },\n (failure) => {\n if (request.signal.aborted) return\n synchronizationRequests.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setSynchronizationStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"failed\" }))\n }\n )\n },\n [invalidateSession, sessionKey, transport]\n )\n\n const synchronizeConnection = useCallback(\n (pluginConnectionId: PluginConnectionId): void => {\n if (sessionKey === null || transport.synchronize === undefined) return\n synchronizationRequests.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n synchronizationRequests.current.set(pluginConnectionId, request)\n setSynchronizationStates((current) => {\n const existing = current.get(pluginConnectionId)\n const previous = existing?._tag === \"ready\" ? existing.synchronization : null\n return new Map(current).set(pluginConnectionId, { _tag: \"syncing\", previous })\n })\n transport.synchronize(pluginConnectionId, request.signal).then(\n (synchronization) => {\n if (request.signal.aborted) return\n synchronizationRequests.current.delete(pluginConnectionId)\n setSynchronizationStates((current) =>\n new Map(current).set(pluginConnectionId, { _tag: \"ready\", synchronization })\n )\n },\n (failure) => {\n if (request.signal.aborted) return\n synchronizationRequests.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setSynchronizationStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"failed\" }))\n }\n )\n },\n [invalidateSession, sessionKey, transport]\n )\n\n useEffect(() => {\n if (sessionKey === null) {\n setConnectionsState({ _tag: \"idle\" })\n return\n }\n const request = new AbortController()\n setConnectionsState({ _tag: \"loading\" })\n transport.overview(request.signal).then(\n (overview) => {\n if (!request.signal.aborted) setConnectionsState({ _tag: \"ready\", overview })\n },\n (failure) => {\n if (request.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setConnectionsState({ _tag: \"failed\" })\n }\n )\n return () => request.abort()\n }, [invalidateSession, requestRevision, sessionKey, transport])\n\n useEffect(() => {\n if (connectionsState._tag !== \"ready\" || transport.synchronization === undefined) return\n const synchronizable = connectionsState.overview.connections.filter(\n ({ supportsSynchronization }) => supportsSynchronization\n )\n const synchronizableIds = new Set(synchronizable.map(({ pluginConnectionId }) => pluginConnectionId))\n for (const [pluginConnectionId, request] of synchronizationRequests.current) {\n if (synchronizableIds.has(pluginConnectionId)) continue\n request.abort()\n synchronizationRequests.current.delete(pluginConnectionId)\n }\n setSynchronizationStates((current) => {\n const next = new Map(current)\n let changed = false\n for (const pluginConnectionId of next.keys()) {\n if (synchronizableIds.has(pluginConnectionId)) continue\n next.delete(pluginConnectionId)\n changed = true\n }\n return changed ? next : current\n })\n for (const connection of synchronizable) refreshSynchronization(connection.pluginConnectionId)\n return () => {\n for (const connection of synchronizable) {\n synchronizationRequests.current.get(connection.pluginConnectionId)?.abort()\n synchronizationRequests.current.delete(connection.pluginConnectionId)\n }\n }\n }, [connectionsState, refreshSynchronization, transport.synchronization])\n\n useEffect(() => {\n if (connectionsState._tag !== \"ready\" || transport.administration === undefined) return\n const connectionIds = new Set(\n connectionsState.overview.connections.map(({ pluginConnectionId }) => pluginConnectionId)\n )\n for (const [pluginConnectionId, request] of administrationRequests.current) {\n if (connectionIds.has(pluginConnectionId)) continue\n request.abort()\n administrationRequests.current.delete(pluginConnectionId)\n }\n setAdministrationStates((current) => {\n const next = new Map(current)\n let changed = false\n for (const pluginConnectionId of next.keys()) {\n if (connectionIds.has(pluginConnectionId)) continue\n next.delete(pluginConnectionId)\n changed = true\n }\n return changed ? next : current\n })\n for (const pluginConnectionId of connectionIds) refreshAdministration(pluginConnectionId)\n return () => {\n for (const pluginConnectionId of connectionIds) {\n administrationRequests.current.get(pluginConnectionId)?.abort()\n administrationRequests.current.delete(pluginConnectionId)\n }\n }\n }, [connectionsState, refreshAdministration, transport.administration])\n\n useEffect(() => {\n if (sessionKey === null || (openProvider !== \"codecommit\" && openProvider !== \"codepipeline\")) return\n awsProfileRequest.current?.abort()\n const request = new AbortController()\n awsProfileRequest.current = request\n setAwsProfilesState({ _tag: \"loading\" })\n const discoverAwsProfiles = transport.discoverAwsProfiles\n if (discoverAwsProfiles === undefined) {\n setAwsProfilesState({ _tag: \"failed\" })\n return () => request.abort()\n }\n discoverAwsProfiles(request.signal).then(\n (profiles) => {\n if (!request.signal.aborted) setAwsProfilesState({ _tag: \"ready\", profiles })\n },\n (failure) => {\n if (request.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setAwsProfilesState({ _tag: \"failed\" })\n }\n )\n return () => request.abort()\n }, [invalidateSession, openProvider, sessionKey, transport])\n\n useEffect(() => {\n if (sessionKey === null || (openProvider !== \"jira\" && openProvider !== \"confluence\")) return\n atlassianProfileRequest.current?.abort()\n const request = new AbortController()\n atlassianProfileRequest.current = request\n setAtlassianProfilesState({ _tag: \"loading\" })\n const discoverAtlassianProfiles = transport.discoverAtlassianProfiles\n if (discoverAtlassianProfiles === undefined) {\n setAtlassianProfilesState({ _tag: \"failed\" })\n return () => request.abort()\n }\n discoverAtlassianProfiles(request.signal).then(\n (profiles) => {\n if (!request.signal.aborted) setAtlassianProfilesState({ _tag: \"ready\", profiles })\n },\n (failure) => {\n if (request.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setAtlassianProfilesState({ _tag: \"failed\" })\n }\n )\n return () => request.abort()\n }, [invalidateSession, openProvider, sessionKey, transport])\n\n useEffect(() => {\n setTestStates(new Map())\n setEnablementStates(new Map())\n setSynchronizationStates(new Map())\n setAdministrationStates(new Map())\n setOpenProvider(null)\n setAtlassianSetupIntent(null)\n setSubmittingProvider(null)\n setAwsProfilesState({ _tag: \"idle\" })\n setAtlassianProfilesState({ _tag: \"idle\" })\n completedBatchDrafts.current.clear()\n return () => {\n for (const request of testRequests.current.values()) request.abort()\n testRequests.current.clear()\n createRequest.current?.abort()\n createRequest.current = null\n awsProfileRequest.current?.abort()\n awsProfileRequest.current = null\n atlassianProfileRequest.current?.abort()\n atlassianProfileRequest.current = null\n for (const request of synchronizationRequests.current.values()) request.abort()\n synchronizationRequests.current.clear()\n for (const request of enablementRequests.current.values()) request.abort()\n enablementRequests.current.clear()\n for (const request of administrationRequests.current.values()) request.abort()\n administrationRequests.current.clear()\n for (const request of administrationMutations.current.values()) request.abort()\n administrationMutations.current.clear()\n for (const request of accountMutations.current.values()) request.abort()\n accountMutations.current.clear()\n }\n }, [sessionKey])\n\n useEffect(() => {\n if (\n connectionsState._tag !== \"ready\" ||\n sessionState._tag !== \"authenticated\" ||\n sessionState.session.permission !== \"workspace-owner\"\n ) {\n return\n }\n const requestedProvider = selectedServiceProvider(searchParams, \"enable\")\n if (requestedProvider === null) return\n if (!connectionsState.overview.catalog.some(({ providerId }) => providerId === requestedProvider)) return\n if (requestedProvider === \"jira\" || requestedProvider === \"confluence\") {\n const callbackProviders = selectedAtlassianOAuthProviders(searchParams)\n const hasAlignedCallbackIntent = callbackProviders?.includes(requestedProvider) === true\n setAtlassianSetupIntent(\n !hasAlignedCallbackIntent\n ? missingAtlassianProductsIntent(connectionsState.overview.connections, requestedProvider)\n : {\n preferredProfileId: selectedAtlassianOAuthProfileId(searchParams),\n preferredSiteId: selectedAtlassianOAuthSiteId(searchParams),\n providers: callbackProviders,\n requestedOAuthProviders: callbackProviders\n }\n )\n }\n setOpenProvider(requestedProvider)\n const nextSearchParams = new URLSearchParams(searchParams)\n nextSearchParams.delete(\"enable\")\n nextSearchParams.delete(\"atlassianProfile\")\n nextSearchParams.delete(\"atlassianProvider\")\n nextSearchParams.delete(\"atlassianSite\")\n setSearchParams(nextSearchParams, { replace: true })\n }, [connectionsState, searchParams, sessionState, setSearchParams])\n\n const testConnection = useCallback(\n (pluginConnectionId: PluginConnectionId): void => {\n if (sessionKey === null) return\n testRequests.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n testRequests.current.set(pluginConnectionId, request)\n setTestStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"testing\" }))\n transport.test(pluginConnectionId, request.signal).then(\n (result) => {\n if (request.signal.aborted) return\n testRequests.current.delete(pluginConnectionId)\n setTestStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"result\", result }))\n },\n (failure) => {\n if (request.signal.aborted) return\n testRequests.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setTestStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"request-failed\" }))\n }\n )\n },\n [invalidateSession, sessionKey, transport]\n )\n\n const createConnections = useCallback(\n async (drafts: ReadonlyArray<ServiceConnectionDraft>, originProvider: ProviderId): Promise<boolean> => {\n if (sessionKey === null) return false\n createRequest.current?.abort()\n const request = new AbortController()\n createRequest.current = request\n setSubmittingProvider(originProvider)\n let hasFailedTest = false\n let hasSetupFailure = false\n let shouldRefreshOverview = false\n const completed = completedBatchDrafts.current.get(originProvider) ?? new Set<string>()\n completedBatchDrafts.current.set(originProvider, completed)\n const acceptResponse = (draftKey: string, response: CreatePluginConnectionResponse): void => {\n completed.add(draftKey)\n hasFailedTest = hasFailedTest || response.test._tag !== \"healthy\"\n shouldRefreshOverview = shouldRefreshOverview || response.connection.providerAccountId !== null\n setConnectionsState((current) =>\n current._tag === \"ready\"\n ? {\n _tag: \"ready\",\n overview: {\n ...current.overview,\n connections: [...current.overview.connections, response.connection]\n }\n }\n : current\n )\n setTestStates((current) =>\n new Map(current).set(response.connection.pluginConnectionId, {\n _tag: \"result\",\n result: response.test\n })\n )\n }\n try {\n const pending = drafts.filter((draft) => !completed.has(setupDraftKey(draft)))\n if (transport.createBatch !== undefined && pending.length > 0) {\n const draftKeysByConnectionId = new Map<PluginConnectionId, string>()\n const connections: Array<CreatePluginConnectionRequest> = []\n for (const draft of pending) {\n const pluginConnectionId = await transport.makeConnectionId()\n draftKeysByConnectionId.set(pluginConnectionId, setupDraftKey(draft))\n connections.push({\n pluginConnectionId,\n providerId: draft.catalog.providerId,\n displayName: draft.displayName,\n values: draft.values\n })\n }\n const batch = await transport.createBatch({ connections }, request.signal)\n if (request.signal.aborted) return false\n const completedConnectionIds = new Set<PluginConnectionId>()\n for (const result of batch.results) {\n const pluginConnectionId =\n result._tag === \"failed\" ? result.pluginConnectionId : result.response.connection.pluginConnectionId\n if (!draftKeysByConnectionId.has(pluginConnectionId) || completedConnectionIds.has(pluginConnectionId)) {\n hasSetupFailure = true\n continue\n }\n completedConnectionIds.add(pluginConnectionId)\n if (result._tag === \"failed\") {\n hasSetupFailure = true\n continue\n }\n const draftKey = draftKeysByConnectionId.get(result.response.connection.pluginConnectionId)\n if (draftKey !== undefined) acceptResponse(draftKey, result.response)\n }\n hasSetupFailure = hasSetupFailure || completedConnectionIds.size !== connections.length\n } else\n for (const draft of pending) {\n const draftKey = setupDraftKey(draft)\n const pluginConnectionId = await transport.makeConnectionId()\n const response = await transport.create(\n {\n pluginConnectionId,\n providerId: draft.catalog.providerId,\n displayName: draft.displayName,\n values: draft.values\n },\n request.signal\n )\n if (request.signal.aborted) return false\n acceptResponse(draftKey, response)\n }\n if (shouldRefreshOverview) {\n try {\n const refreshedOverview = await transport.overview(request.signal)\n if (!request.signal.aborted) setConnectionsState({ _tag: \"ready\", overview: refreshedOverview })\n } catch (failure: unknown) {\n if (request.signal.aborted) return false\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n }\n }\n if (hasSetupFailure) completedBatchDrafts.current.set(originProvider, completed)\n else completedBatchDrafts.current.delete(originProvider)\n createRequest.current = null\n setOpenProvider(hasFailedTest || hasSetupFailure ? originProvider : null)\n setSubmittingProvider(null)\n return !hasSetupFailure\n } catch (failure: unknown) {\n if (request.signal.aborted) return false\n createRequest.current = null\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setSubmittingProvider(null)\n return false\n }\n },\n [invalidateSession, sessionKey, transport]\n )\n\n const createConnection = useCallback(\n (\n catalog: PluginServiceCatalogEntry,\n displayName: string,\n values: ReadonlyArray<CreatePluginConnectionValue>\n ): Promise<boolean> => createConnections([{ catalog, displayName, values }], catalog.providerId),\n [createConnections]\n )\n\n const setConnectionEnabled = useCallback(\n (pluginConnectionId: PluginConnectionId, isEnabled: boolean): void => {\n if (sessionKey === null) return\n if (!isEnabled) {\n testRequests.current.get(pluginConnectionId)?.abort()\n testRequests.current.delete(pluginConnectionId)\n setTestStates((current) => {\n const next = new Map(current)\n next.delete(pluginConnectionId)\n return next\n })\n }\n enablementRequests.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n enablementRequests.current.set(pluginConnectionId, request)\n setEnablementStates((current) => new Map(current).set(pluginConnectionId, \"changing\"))\n transport.setEnabled(pluginConnectionId, isEnabled, request.signal).then(\n (connection) => {\n if (request.signal.aborted) return\n enablementRequests.current.delete(pluginConnectionId)\n setConnectionsState((current) =>\n current._tag === \"ready\"\n ? {\n _tag: \"ready\",\n overview: {\n ...current.overview,\n connections: current.overview.connections.map((candidate) =>\n candidate.pluginConnectionId === pluginConnectionId ? connection : candidate\n )\n }\n }\n : current\n )\n setEnablementStates((current) => {\n const next = new Map(current)\n next.delete(pluginConnectionId)\n return next\n })\n if (isEnabled) {\n testConnection(pluginConnectionId)\n } else {\n setTestStates((current) => {\n const next = new Map(current)\n next.delete(pluginConnectionId)\n return next\n })\n }\n },\n (failure) => {\n if (request.signal.aborted) return\n enablementRequests.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n setEnablementStates((current) => new Map(current).set(pluginConnectionId, \"request-failed\"))\n }\n )\n },\n [invalidateSession, sessionKey, testConnection, transport]\n )\n\n const reauthorizeConnection = useCallback(\n async (\n pluginConnectionId: PluginConnectionId,\n credentials: ReadonlyArray<PluginCredentialReplacement>\n ): Promise<boolean> => {\n if (sessionKey === null || transport.reauthorize === undefined) return false\n const administrationState = administrationStates.get(pluginConnectionId)\n if (administrationState?._tag !== \"ready\") return false\n administrationMutations.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n administrationMutations.current.set(pluginConnectionId, request)\n try {\n const response = await transport.reauthorize(\n pluginConnectionId,\n administrationState.administration.configuration.revision,\n credentials,\n request.signal\n )\n if (request.signal.aborted) return false\n administrationMutations.current.delete(pluginConnectionId)\n setConnectionsState((current) =>\n current._tag === \"ready\"\n ? {\n _tag: \"ready\",\n overview: {\n ...current.overview,\n connections: current.overview.connections.map((candidate) =>\n candidate.pluginConnectionId === pluginConnectionId ? response.connection : candidate\n )\n }\n }\n : current\n )\n setTestStates((current) => new Map(current).set(pluginConnectionId, { _tag: \"result\", result: response.test }))\n refreshAdministration(pluginConnectionId)\n return true\n } catch (failure: unknown) {\n if (request.signal.aborted) return false\n administrationMutations.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n refreshAdministration(pluginConnectionId)\n return false\n }\n },\n [administrationStates, invalidateSession, refreshAdministration, sessionKey, transport]\n )\n\n useEffect(() => {\n if (\n connectionsState._tag !== \"ready\" ||\n sessionState._tag !== \"authenticated\" ||\n sessionState.session.permission !== \"workspace-owner\"\n )\n return\n const pluginConnectionId = selectedAtlassianRecoveryConnectionId(searchParams)\n const profileId = selectedAtlassianRecoveryProfileId(searchParams)\n if (pluginConnectionId === null || profileId === null) return\n const connection = connectionsState.overview.connections.find(\n (candidate) => candidate.pluginConnectionId === pluginConnectionId\n )\n const administration = administrationStates.get(pluginConnectionId)\n const oauthProfileField =\n administration?._tag === \"ready\"\n ? administration.administration.credentialFields.find(({ key }) => key === \"oauthProfileId\")\n : undefined\n if (\n (connection?.providerId !== \"jira\" && connection?.providerId !== \"confluence\") ||\n administration?._tag !== \"ready\" ||\n oauthProfileField === undefined\n )\n return\n const nextSearchParams = new URLSearchParams(searchParams)\n nextSearchParams.delete(\"atlassianRecoveryConnection\")\n nextSearchParams.delete(\"atlassianRecoveryProfile\")\n setSearchParams(nextSearchParams, { replace: true })\n void reauthorizeConnection(pluginConnectionId, [{ key: oauthProfileField.key, value: profileId }])\n }, [administrationStates, connectionsState, reauthorizeConnection, searchParams, sessionState, setSearchParams])\n\n const revokeConnection = useCallback(\n async (pluginConnectionId: PluginConnectionId): Promise<boolean> => {\n if (sessionKey === null || transport.revoke === undefined) return false\n const administrationState = administrationStates.get(pluginConnectionId)\n if (administrationState?._tag !== \"ready\") return false\n administrationMutations.current.get(pluginConnectionId)?.abort()\n const request = new AbortController()\n administrationMutations.current.set(pluginConnectionId, request)\n try {\n const connection = await transport.revoke(\n pluginConnectionId,\n administrationState.administration.configuration.revision,\n request.signal\n )\n if (request.signal.aborted) return false\n administrationMutations.current.delete(pluginConnectionId)\n setConnectionsState((current) =>\n current._tag === \"ready\"\n ? {\n _tag: \"ready\",\n overview: {\n ...current.overview,\n connections: current.overview.connections.map((candidate) =>\n candidate.pluginConnectionId === pluginConnectionId ? connection : candidate\n )\n }\n }\n : current\n )\n setTestStates((current) => {\n const next = new Map(current)\n next.delete(pluginConnectionId)\n return next\n })\n refreshAdministration(pluginConnectionId)\n return true\n } catch (failure: unknown) {\n if (request.signal.aborted) return false\n administrationMutations.current.delete(pluginConnectionId)\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n refreshAdministration(pluginConnectionId)\n return false\n }\n },\n [administrationStates, invalidateSession, refreshAdministration, sessionKey, transport]\n )\n\n const renameProviderAccount = useCallback(\n async (account: PluginOverviewResponse[\"accounts\"][number], displayName: string): Promise<boolean> => {\n if (sessionKey === null || transport.patchAccount === undefined || displayName.length === 0) return false\n accountMutations.current.get(account.providerAccountId)?.abort()\n const request = new AbortController()\n accountMutations.current.set(account.providerAccountId, request)\n try {\n const updated = await transport.patchAccount(\n account.providerAccountId,\n { expectedRevision: account.revision, displayName },\n request.signal\n )\n if (request.signal.aborted) return false\n if (accountMutations.current.get(account.providerAccountId) === request) {\n accountMutations.current.delete(account.providerAccountId)\n }\n setConnectionsState((current) =>\n current._tag === \"ready\"\n ? {\n _tag: \"ready\",\n overview: {\n ...current.overview,\n accounts: current.overview.accounts.map((candidate) =>\n candidate.providerAccountId === updated.providerAccountId ? updated : candidate\n )\n }\n }\n : current\n )\n return true\n } catch (failure: unknown) {\n if (request.signal.aborted) return false\n if (accountMutations.current.get(account.providerAccountId) === request) {\n accountMutations.current.delete(account.providerAccountId)\n }\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) invalidateSession(sessionKey)\n return false\n }\n },\n [invalidateSession, sessionKey, transport]\n )\n\n const session =\n sessionState._tag === \"authenticated\" || sessionState._tag === \"storage-unavailable\" ? sessionState.session : null\n const canConfigure = sessionState._tag === \"authenticated\" && sessionState.session.permission === \"workspace-owner\"\n\n return (\n <section aria-labelledby=\"services-title\" className={styles.page}>\n <header className={styles.heading}>\n <Text as=\"h1\" id=\"services-title\" variant=\"page-title\">\n Services\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n {session === null || (connectionsState._tag === \"ready\" && connectionsState.overview.connections.length === 0)\n ? \"Choose a service below. Control Center will enable it and verify the exact account before using it.\"\n : \"Configure first-party providers and verify the exact account each connection represents.\"}\n </Text>\n </header>\n {session === null && sessionState._tag !== \"checking\" ? (\n <div className={styles.grid}>\n {firstPartyServiceIdentities.map((service) => (\n <ServicePreviewCard\n key={service.providerId}\n onEnable={() => navigate(servicePairingPath(service.providerId))}\n service={service}\n />\n ))}\n </div>\n ) : connectionsState._tag === \"loading\" || connectionsState._tag === \"idle\" ? (\n <div className={styles.grid}>\n {firstPartyServiceIdentities.map((service) => (\n <ServicePreviewCard\n actionLabel=\"Loading connections\"\n isActionDisabled\n key={service.providerId}\n onEnable={() => undefined}\n service={service}\n statusLabel=\"Loading\"\n statusTone=\"progress\"\n />\n ))}\n </div>\n ) : connectionsState._tag === \"failed\" ? (\n <>\n <StatePanel\n action={<Button onClick={() => setRequestRevision((revision) => revision + 1)}>Try again</Button>}\n description=\"Control Center could not load connection details. The installed services remain visible below.\"\n title=\"Connections unavailable\"\n />\n <div className={styles.grid}>\n {firstPartyServiceIdentities.map((service) => (\n <ServicePreviewCard\n actionLabel=\"Retry connections\"\n key={service.providerId}\n onEnable={() => setRequestRevision((revision) => revision + 1)}\n service={service}\n statusLabel=\"Installed\"\n statusTone=\"neutral\"\n />\n ))}\n </div>\n </>\n ) : (\n <>\n {connectionsState.overview.accounts.length === 0 ? null : (\n <section aria-labelledby=\"connected-accounts-title\" className={styles.accounts}>\n <div className={styles.sectionHeading}>\n <Text as=\"h2\" id=\"connected-accounts-title\" variant=\"section-title\">\n Connected accounts\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n One verified provider identity can own several followed resources.\n </Text>\n </div>\n <div className={styles.accountGrid}>\n {connectionsState.overview.accounts.map((account) => (\n <ProviderAccountCard\n account={account}\n administrationStates={administrationStates}\n canConfigure={canConfigure}\n connections={connectionsState.overview.connections}\n enablementStates={enablementStates}\n key={account.providerAccountId}\n onAdd={(providerId, providerImmutableId) => {\n if (providerId === \"jira\" || providerId === \"confluence\") {\n setAtlassianSetupIntent({\n preferredProfileId: null,\n preferredSiteId: providerImmutableId,\n providers: [providerId],\n requestedOAuthProviders: null\n })\n }\n setOpenProvider(providerId)\n }}\n onSetEnabled={setConnectionEnabled}\n onRefreshSynchronization={refreshSynchronization}\n onReauthorize={reauthorizeConnection}\n onRename={(displayName) => renameProviderAccount(account, displayName)}\n onRevoke={revokeConnection}\n onStartAtlassianOAuth={transport.startAtlassianOAuthGrant}\n onSynchronize={synchronizeConnection}\n synchronizationStates={synchronizationStates}\n onTest={testConnection}\n testStates={testStates}\n />\n ))}\n </div>\n </section>\n )}\n <div className={styles.grid}>\n {connectionsState.overview.catalog.flatMap((catalog) => {\n const configured = connectionsState.overview.connections.filter(\n (connection) => connection.providerId === catalog.providerId\n )\n const groupedResourceIds = new Set(\n connectionsState.overview.accounts.flatMap(({ resources }) =>\n resources.map(({ followedResourceId }) => followedResourceId)\n )\n )\n const hasGroupedResource = configured.some(\n ({ followedResourceId }) => followedResourceId !== null && groupedResourceIds.has(followedResourceId)\n )\n const standaloneConnections = configured.filter(\n ({ followedResourceId }) => followedResourceId === null || !groupedResourceIds.has(followedResourceId)\n )\n const missingAtlassianIntent = missingAtlassianProductsIntent(\n connectionsState.overview.connections,\n catalog.providerId === \"jira\" || catalog.providerId === \"confluence\" ? catalog.providerId : undefined\n )\n const setupIntent = resolvedAtlassianSetupIntent(\n atlassianSetupIntent ?? missingAtlassianIntent,\n connectionsState.overview.connections,\n atlassianProfilesState\n )\n const cards = standaloneConnections.map((connection) => (\n <ConnectionCard\n administrationState={administrationStates.get(connection.pluginConnectionId)}\n canConfigure={canConfigure}\n canTest={canConfigure}\n connection={connection}\n enablementState={enablementStates.get(connection.pluginConnectionId)}\n key={connection.pluginConnectionId}\n onConfigure={() => {\n if (catalog.providerId === \"jira\" || catalog.providerId === \"confluence\") {\n setAtlassianSetupIntent(allAtlassianProductsIntent)\n }\n setOpenProvider(catalog.providerId)\n }}\n onSetEnabled={setConnectionEnabled}\n onRefreshSynchronization={refreshSynchronization}\n onReauthorize={reauthorizeConnection}\n onRevoke={revokeConnection}\n onStartAtlassianOAuth={transport.startAtlassianOAuthGrant}\n onSynchronize={synchronizeConnection}\n onTest={testConnection}\n synchronizationState={synchronizationStates.get(connection.pluginConnectionId)}\n testState={testStates.get(connection.pluginConnectionId)}\n />\n ))\n if (\n configured.length > 0 &&\n openProvider !== catalog.providerId &&\n (hasGroupedResource || (catalog.providerId !== \"jira\" && catalog.providerId !== \"confluence\"))\n )\n return cards\n return [\n ...cards,\n <CatalogCard\n atlassianProfiles={atlassianProfilesState._tag === \"ready\" ? atlassianProfilesState.profiles : []}\n atlassianProfilesState={atlassianProfilesState._tag}\n atlassianSetupIntent={setupIntent}\n awsProfiles={awsProfilesState._tag === \"ready\" ? awsProfilesState.profiles : []}\n awsProfilesState={awsProfilesState._tag}\n canConfigure={canConfigure}\n catalog={catalog}\n catalogs={connectionsState.overview.catalog}\n isAdditional={\n configured.length > 0 && (catalog.providerId === \"jira\" || catalog.providerId === \"confluence\")\n }\n isOpen={openProvider === catalog.providerId}\n isRecovery={standaloneConnections.length > 0}\n isSubmitting={submittingProvider === catalog.providerId}\n key={`${catalog.providerId}-catalog`}\n onCancel={() => {\n completedBatchDrafts.current.delete(catalog.providerId)\n setAtlassianSetupIntent(null)\n setOpenProvider(null)\n }}\n onDiscoverAws={(request, signal) => {\n const discover = transport.discoverAwsResources\n if (discover === undefined)\n return Promise.reject(new Error(\"AWS resource discovery is unavailable\"))\n return discover(request, signal).catch((failure: unknown) => {\n if (sessionKey !== null && Predicate.isTagged(\"UnauthorizedApiError\")(failure)) {\n invalidateSession(sessionKey)\n }\n return Promise.reject(failure)\n })\n }}\n onOpen={() => {\n if (openProvider !== catalog.providerId) {\n completedBatchDrafts.current.delete(catalog.providerId)\n }\n if (catalog.providerId === \"jira\" || catalog.providerId === \"confluence\") {\n setAtlassianSetupIntent(missingAtlassianIntent)\n }\n setOpenProvider(catalog.providerId)\n }}\n onStartAtlassianOAuth={(providers, signal, configuration) => {\n const start = transport.startAtlassianOAuthGrant\n if (start === undefined) return Promise.reject(new Error(\"Atlassian OAuth is unavailable\"))\n return start(providers, signal, configuration)\n }}\n onSubmit={(displayName, values) => createConnection(catalog, displayName, values)}\n onSubmitAtlassian={(drafts) => createConnections(drafts, catalog.providerId)}\n onSubmitAws={(drafts) => createConnections(drafts, catalog.providerId)}\n />\n ]\n })}\n </div>\n </>\n )}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{t}from"./react-CZI7_Jkm.js";import{t as n,u as r}from"./lib-BzlsKFNV.js";import{t as i}from"./jsx-runtime-By8HlURe.js";import{a,i as o,n as s,r as c,t as l}from"./Dialog-xSrBk0Vv-ClGyDPlc.js";import{d as u,f as d,s as f,u as p}from"./index-zVjlBm9l.js";import{a as m,v as h}from"./patterns-5N-j-AD2-DLfaGePK.js";import{r as g}from"./primitives-nKxQGSsE-CJNmac__.js";import{Hr as _,Ir as v,Kn as y,Kt as b,Rr as x,_i as S,ai as C,ja as w,pi as T}from"./agent-api-Dl9TuGOJ.js";import{a as E,t as D}from"./client-Dq_XQE_l.js";import{t as O}from"./WorkspaceEntityLink-C_rc8lxi.js";var k=e(t(),1),A={body:`_body_vqgmt_1`,loading:`_loading_vqgmt_2`,content:`_content_vqgmt_3`,identity:`_identity_vqgmt_4`,identityMeta:`_identityMeta_vqgmt_5`,section:`_section_vqgmt_6`,ledger:`_ledger_vqgmt_7`,footerLink:`_footerLink_vqgmt_70`},j=w(`UnauthorizedApiError`),M={load:(e,t)=>S(C(function*(){return yield*(yield*D()).timeline.detail({params:{eventKey:e}})}).pipe(T(E)),{signal:t})},N=(e,t,n,r=M)=>{let[i,a]=(0,k.useState)(0),[o,s]=(0,k.useState)({_tag:`idle`});(0,k.useEffect)(()=>{if(e===null||t===null){s({_tag:`idle`});return}let i=new AbortController;return s({_tag:`loading`,eventKey:e,sessionKey:t}),r.load(e,i.signal).then(n=>{i.signal.aborted||s({_tag:`ready`,detail:n,eventKey:e,sessionKey:t})},r=>{i.signal.aborted||(j(r)&&n(t),s({_tag:`failed`,eventKey:e,sessionKey:t}))}),()=>i.abort()},[e,n,i,t,r]);let c=e===null||t===null?{_tag:`idle`}:o._tag===`idle`||o.eventKey!==e||o.sessionKey!==t?{_tag:`loading`,eventKey:e,sessionKey:t}:o;return{retry:(0,k.useCallback)(()=>a(e=>e+1),[]),state:c}},P=i(),F={action:`Governed action`,"plugin-sync":`Service sync`,relationship:`Delivery link`,system:`Control Center`},I=e=>x(e.occurredAt,{day:`2-digit`,hour:`2-digit`,hour12:!1,locale:`en-GB`,minute:`2-digit`,month:`short`,second:`2-digit`,year:`numeric`}),L=e=>{let t=[{label:`Actor`,value:e.identifiers.actorId},{label:`Agent job`,value:e.agentJob?.jobId??null},{label:`Action`,value:e.identifiers.actionId},{label:`Relationship`,value:e.identifiers.relationshipId},{label:`Connection`,value:e.identifiers.pluginConnectionId},{label:`Release`,value:e.identifiers.releaseId},{label:`Entity`,value:e.identifiers.entityId}];return[{label:`Event`,value:e.event.eventKey},{label:`Type`,value:e.event.eventType},...t.filter(e=>e.value!==null)]},R=({agentHref:e,event:t,onClose:r,onSessionExpired:i,sessionKey:u,transport:d})=>{let f=N(t?.eventKey??null,u,i,d);return(0,P.jsx)(o.Root,{onOpenChange:e=>{e||r()},open:t!==null,children:(0,P.jsxs)(o.Content,{closeLabel:`Close event details`,description:`Durable provenance for this exact workspace event.`,title:`Event details`,children:[(0,P.jsx)(o.Body,{className:A.body,children:t===null||f.state._tag===`idle`||f.state._tag===`loading`?(0,P.jsxs)(`div`,{"aria-busy":`true`,"aria-label":`Loading event details`,className:A.loading,children:[(0,P.jsx)(a,{height:`10rem`}),(0,P.jsx)(a,{height:`14rem`})]}):f.state._tag===`failed`?(0,P.jsx)(s,{action:(0,P.jsx)(l,{onClick:f.retry,children:`Try again`}),description:`The Timeline row remains unchanged. Its provenance could not be loaded.`,title:`Event details unavailable`,tone:`caution`}):(0,P.jsxs)(`div`,{className:A.content,children:[(0,P.jsxs)(`section`,{"aria-labelledby":`timeline-detail-title`,className:A.identity,children:[(0,P.jsx)(g,{tone:`secondary`,variant:`label`,children:F[f.state.detail.event.sourceKind]}),(0,P.jsx)(g,{as:`h2`,id:`timeline-detail-title`,variant:`page-title`,children:f.state.detail.event.title}),(0,P.jsxs)(`div`,{className:A.identityMeta,children:[(0,P.jsx)(c,{label:f.state.detail.event.actor.kind,size:`compact`,tone:f.state.detail.event.actor.kind===`agent`?`progress`:`neutral`}),f.state.detail.event.service===null?null:(0,P.jsx)(h,{service:f.state.detail.event.service,size:`compact`}),(0,P.jsx)(g,{tone:`secondary`,variant:`meta`,children:f.state.detail.event.actor.label}),(0,P.jsxs)(g,{as:`time`,dateTime:v(f.state.detail.event.occurredAt),tone:`secondary`,variant:`meta`,children:[I(f.state.detail.event),` UTC`]})]})]}),(0,P.jsxs)(`section`,{"aria-labelledby":`timeline-provenance-title`,className:A.section,children:[(0,P.jsx)(g,{as:`h3`,id:`timeline-provenance-title`,variant:`section-title`,children:`Provenance`}),(0,P.jsx)(`dl`,{className:A.ledger,children:L(f.state.detail).map(({label:e,value:t})=>(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`dt`,{children:e}),(0,P.jsx)(`dd`,{children:t})]},e))})]})]})}),(0,P.jsx)(o.Footer,{children:(0,P.jsx)(n,{className:A.footerLink,to:e,children:`Ask Relay about this event`})})]})})},z={page:`_page_18su2_1`,hero:`_hero_18su2_2`,intro:`_intro_18su2_22`,askRelay:`_askRelay_18su2_26`,summary:`_summary_18su2_40`,filters:`_filters_18su2_89`,events:`_events_18su2_115`,rowActor:`_rowActor_18su2_122`},B={load:(e,t,n)=>S(C(function*(){let e=yield*D(),r=t.from.length===0?void 0:yield*y(b)(`${t.from}T00:00:00.000Z`),i=t.to.length===0?void 0:yield*y(b)(`${t.to}T23:59:59.999Z`);return yield*e.timeline.page({query:{...t.actorKind===`all`?{}:{actor:t.actorKind},...n===null?{}:{beforeEventKey:n.eventKey,beforeOccurredAt:n.occurredAt},...r===void 0?{}:{from:r},limit:50,...i===void 0?{}:{to:i}}})}).pipe(T(E)),{signal:e})},V=w(`UnauthorizedApiError`),H=(e,t,n,r=B)=>{let[i,a]=(0,k.useState)(0),[o,s]=(0,k.useState)({_tag:`idle`}),c=(0,k.useRef)(null);return(0,k.useEffect)(()=>{if(c.current?.abort(),t===null){s({_tag:`idle`});return}let i=new AbortController;return c.current=i,s({_tag:`loading`}),r.load(i.signal,e,null).then(e=>{i.signal.aborted||s({_tag:`ready`,events:e.events,isLoadingMore:!1,nextCursor:e.nextCursor})},e=>{i.signal.aborted||(V(e)&&n(t),s({_tag:`failed`}))}),()=>i.abort()},[`${e.actorKind}|${e.from}|${e.to}`,e,n,i,t,r]),{loadMore:(0,k.useCallback)(()=>{if(t===null||o._tag!==`ready`||o.nextCursor===null||o.isLoadingMore)return;c.current?.abort();let i=new AbortController;c.current=i;let a=o;s({...a,isLoadingMore:!0}),r.load(i.signal,e,a.nextCursor).then(e=>{i.signal.aborted||s({_tag:`ready`,events:[...a.events,...e.events],isLoadingMore:!1,nextCursor:e.nextCursor})},e=>{i.signal.aborted||(V(e)&&n(t),s({...a,isLoadingMore:!1}))})},[e,n,t,o,r]),retry:(0,k.useCallback)(()=>a(e=>e+1),[]),state:o}},U=e=>new Intl.DateTimeFormat(`en-GB`,{dateStyle:`medium`,timeStyle:`short`,timeZone:`UTC`}).format(_(e)),W=[{label:`Everyone`,value:`all`},{label:`People`,value:`human`},{label:`Agents`,value:`agent`},{label:`Services`,value:`plugin`},{label:`System`,value:`system`}],G=[`action`,`relationship`,`plugin-sync`,`system`],K=e=>W.find(t=>t.value===e)?.value??`all`,q={action:{label:`Governed action`},"plugin-sync":{label:`Service sync`},relationship:{label:`Delivery link`},system:{label:`Control Center`}},J=({actor:e,continued:t,event:n})=>(0,P.jsx)(m,{continued:t,event:{actor:e??n.actor.label,actorKind:n.actor.kind,dateTime:v(n.occurredAt),detail:q[n.sourceKind].label,...n.href===null?{}:{href:n.href},id:n.eventKey,...n.service===null?{}:{service:n.service},time:U(n.occurredAt),title:n.title}}),Y=e=>{switch(e._tag){case`authenticated`:return e.session.permission===`workspace-owner`;case`storage-unavailable`:return e.session?.permission===`workspace-owner`;case`anonymous`:case`blocked`:case`checking`:case`unavailable`:return!1}},X=(e,t,n,r)=>{let i=new URLSearchParams(t);return i.set(`event`,r),f(e,`?${i.toString()}`,n)},Z=({events:e})=>{let t=(0,k.useMemo)(()=>new Map([[`action`,e.filter(({sourceKind:e})=>e===`action`).length],[`relationship`,e.filter(({sourceKind:e})=>e===`relationship`).length],[`plugin-sync`,e.filter(({sourceKind:e})=>e===`plugin-sync`).length],[`system`,e.filter(({sourceKind:e})=>e===`system`).length]]),[e]);return(0,P.jsx)(`dl`,{className:z.summary,children:G.map(e=>(0,P.jsxs)(`div`,{"data-source":e,children:[(0,P.jsx)(`dt`,{children:q[e].label}),(0,P.jsx)(`dd`,{children:t.get(e)??0})]},e))})},Q=({detailTransport:e,transport:t=B}={})=>{let i=r(),a=u(),o=p(a.state),[c,m]=(0,k.useState)({actorKind:`all`,from:``,to:``}),[h,_]=(0,k.useState)(null),v=H(c,o,a.invalidateSession,t),y=f(i.pathname,i.search,i.hash),b=Y(a.state);if(v.state._tag===`idle`||v.state._tag===`loading`)return(0,P.jsx)(s,{description:`Combining durable activity across your connected services.`,title:`Loading Timeline`});if(v.state._tag===`failed`)return(0,P.jsx)(s,{action:(0,P.jsx)(l,{onClick:v.retry,children:`Try again`}),description:`The Timeline could not be read.`,title:`Timeline unavailable`});let x=v.state;return(0,P.jsxs)(`article`,{className:z.page,children:[(0,P.jsxs)(`header`,{className:z.hero,children:[(0,P.jsx)(g,{as:`p`,tone:`secondary`,variant:`label`,children:`Timeline`}),(0,P.jsxs)(g,{as:`h1`,variant:`verdict`,children:[`Everything`,(0,P.jsx)(`br`,{}),`that moved.`]}),(0,P.jsx)(g,{className:z.intro,tone:`secondary`,variant:`body-large`,children:`One chronological truth across people, agents, code, delivery links, and connected services.`}),(0,P.jsx)(n,{className:z.askRelay,to:y,children:`Ask Relay about this Timeline`})]}),(0,P.jsx)(Z,{events:x.events}),(0,P.jsxs)(`section`,{"aria-label":`Timeline filters`,className:z.filters,children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Actor`}),(0,P.jsx)(`select`,{value:c.actorKind,onChange:e=>m({...c,actorKind:K(e.currentTarget.value)}),children:W.map(e=>(0,P.jsx)(`option`,{value:e.value,children:e.label},e.value))})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`From`}),(0,P.jsx)(`input`,{type:`date`,value:c.from,onChange:e=>m({...c,from:e.currentTarget.value})})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`To`}),(0,P.jsx)(`input`,{type:`date`,value:c.to,onChange:e=>m({...c,to:e.currentTarget.value})})]})]}),x.events.length===0?(0,P.jsx)(s,{description:`Try a wider date range or another actor.`,title:`No activity in this view`}):(0,P.jsx)(d,{component:O,children:(0,P.jsx)(`ol`,{className:z.events,children:x.events.map((e,t)=>(0,P.jsx)(J,{actor:b?(0,P.jsxs)(`span`,{className:z.rowActor,children:[(0,P.jsx)(`span`,{children:e.actor.label}),(0,P.jsx)(l,{onClick:()=>_(e),size:`compact`,variant:`quiet`,children:`Inspect`})]}):void 0,continued:t<x.events.length-1,event:e},e.eventKey))})}),x.nextCursor===null?null:(0,P.jsx)(l,{disabled:x.isLoadingMore,onClick:v.loadMore,size:`principal`,stretch:!0,children:x.isLoadingMore?`Loading…`:`Show earlier activity`}),(0,P.jsx)(R,{agentHref:h===null?y:X(i.pathname,i.search,i.hash,h.eventKey),event:h,onClose:()=>_(null),onSessionExpired:a.invalidateSession,sessionKey:o,...e===void 0?{}:{transport:e}})]})};export{Q as TimelinePage,Y as canInspectTimelineDetails,X as timelineEventAgentPath};
|
|
2
|
+
//# sourceMappingURL=TimelinePage-Cj3V98uI.js.map
|