@knpkv/control-center 0.8.0 → 0.8.1
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/dist/client/.vite/manifest.json +66 -66
- package/dist/client/assets/ActiveWorkPage-DKlotZGc.js +2 -0
- package/dist/client/assets/{ActiveWorkPage-C6lIQfjL.js.map → ActiveWorkPage-DKlotZGc.js.map} +1 -1
- package/dist/client/assets/{AgentPage-DqB5BilE.js → AgentPage-Cxm1gj2C.js} +3 -3
- package/dist/client/assets/{AgentPage-DqB5BilE.js.map → AgentPage-Cxm1gj2C.js.map} +1 -1
- package/dist/client/assets/{AtlassianOAuthCallbackPage-DzTO6SqN.js → AtlassianOAuthCallbackPage-fEFUJE2g.js} +2 -2
- package/dist/client/assets/{AtlassianOAuthCallbackPage-DzTO6SqN.js.map → AtlassianOAuthCallbackPage-fEFUJE2g.js.map} +1 -1
- package/dist/client/assets/{AuthorizedSharePage-V_E5giT7.js → AuthorizedSharePage-Dh7Y_gmJ.js} +2 -2
- package/dist/client/assets/{AuthorizedSharePage-V_E5giT7.js.map → AuthorizedSharePage-Dh7Y_gmJ.js.map} +1 -1
- package/dist/client/assets/{BrowserSessionHydrator-CEypgMkR.js → BrowserSessionHydrator-DkomS8Yl.js} +2 -2
- package/dist/client/assets/{BrowserSessionHydrator-CEypgMkR.js.map → BrowserSessionHydrator-DkomS8Yl.js.map} +1 -1
- package/dist/client/assets/{CommandSearch-syQMt_rx.js → CommandSearch-nf16HEqz.js} +2 -2
- package/dist/client/assets/{CommandSearch-syQMt_rx.js.map → CommandSearch-nf16HEqz.js.map} +1 -1
- package/dist/client/assets/{ItemsPage-Cr3--iJc.js → ItemsPage-Bok8Vpy4.js} +2 -2
- package/dist/client/assets/{ItemsPage-Cr3--iJc.js.map → ItemsPage-Bok8Vpy4.js.map} +1 -1
- package/dist/client/assets/{OpenPullRequestPage-BYoRmtui.js → OpenPullRequestPage-DdL7PhKZ.js} +2 -2
- package/dist/client/assets/{OpenPullRequestPage-BYoRmtui.js.map → OpenPullRequestPage-DdL7PhKZ.js.map} +1 -1
- package/dist/client/assets/{PairPage-ByOBKuBB.js → PairPage-BCtzYqK6.js} +2 -2
- package/dist/client/assets/{PairPage-ByOBKuBB.js.map → PairPage-BCtzYqK6.js.map} +1 -1
- package/dist/client/assets/{PortfolioOverview-BacOXO-c.js → PortfolioOverview-C-jqvYgQ.js} +2 -2
- package/dist/client/assets/{PortfolioOverview-BacOXO-c.js.map → PortfolioOverview-C-jqvYgQ.js.map} +1 -1
- package/dist/client/assets/{ReleaseRoute-C-MfQKnL.js → ReleaseRoute-cuvP4ug5.js} +2 -2
- package/dist/client/assets/{ReleaseRoute-C-MfQKnL.js.map → ReleaseRoute-cuvP4ug5.js.map} +1 -1
- package/dist/client/assets/{ReleaseWorkset-MV3I0HCi.js → ReleaseWorkset-DImwmjS3.js} +2 -2
- package/dist/client/assets/{ReleaseWorkset-MV3I0HCi.js.map → ReleaseWorkset-DImwmjS3.js.map} +1 -1
- package/dist/client/assets/{ServicesPage-BjeCOlsh.js → ServicesPage-CrM8R820.js} +2 -2
- package/dist/client/assets/{ServicesPage-BjeCOlsh.js.map → ServicesPage-CrM8R820.js.map} +1 -1
- package/dist/client/assets/{TimelinePage-Ccnp6Mmg.js → TimelinePage-FrvepGa_.js} +2 -2
- package/dist/client/assets/{TimelinePage-Ccnp6Mmg.js.map → TimelinePage-FrvepGa_.js.map} +1 -1
- package/dist/client/assets/{WorkspaceEntityLink-D3TXDcD0.js → WorkspaceEntityLink-CAj42f02.js} +2 -2
- package/dist/client/assets/{WorkspaceEntityLink-D3TXDcD0.js.map → WorkspaceEntityLink-CAj42f02.js.map} +1 -1
- package/dist/client/assets/WorkspaceEntityRoute-rQ9ccetx.js +14 -0
- package/dist/client/assets/{WorkspaceEntityRoute-uUK6vwM_.js.map → WorkspaceEntityRoute-rQ9ccetx.js.map} +1 -1
- package/dist/client/assets/WorkspaceHomeLink-ObQ3AQVw.js +2 -0
- package/dist/client/assets/{WorkspaceHomeLink-D5SdEgJJ.js.map → WorkspaceHomeLink-ObQ3AQVw.js.map} +1 -1
- package/dist/client/assets/{WorkspacePullRequestDetails-CKedGIT8.js → WorkspacePullRequestDetails-BhxoqR7V.js} +2 -2
- package/dist/client/assets/{WorkspacePullRequestDetails-CKedGIT8.js.map → WorkspacePullRequestDetails-BhxoqR7V.js.map} +1 -1
- package/dist/client/assets/{WorkspaceReleaseLayout-Bdvl0q99.js → WorkspaceReleaseLayout-BWL66Fff.js} +2 -2
- package/dist/client/assets/{WorkspaceReleaseLayout-Bdvl0q99.js.map → WorkspaceReleaseLayout-BWL66Fff.js.map} +1 -1
- package/dist/client/assets/{WorkspaceSettingsPage-BxFq65Vf.js → WorkspaceSettingsPage-DutfiGPe.js} +2 -2
- package/dist/client/assets/{WorkspaceSettingsPage-BxFq65Vf.js.map → WorkspaceSettingsPage-DutfiGPe.js.map} +1 -1
- package/dist/client/assets/{controlCenterRelayDock-D7375HPG.js → controlCenterRelayDock-CyYeXh75.js} +3 -3
- package/dist/client/assets/{controlCenterRelayDock-D7375HPG.js.map → controlCenterRelayDock-CyYeXh75.js.map} +1 -1
- package/dist/client/assets/{controlCenterRelayDockChrome-B7jSUI3t.js → controlCenterRelayDockChrome-upgtq649.js} +2 -2
- package/dist/client/assets/{controlCenterRelayDockChrome-B7jSUI3t.js.map → controlCenterRelayDockChrome-upgtq649.js.map} +1 -1
- package/dist/client/assets/{index-BVikncBH.js → index-kmYFvwT0.js} +3 -3
- package/dist/client/assets/{index-BVikncBH.js.map → index-kmYFvwT0.js.map} +1 -1
- package/dist/client/assets/patterns-DuFUSnJW.js +2 -0
- package/dist/client/assets/patterns-DuFUSnJW.js.map +1 -0
- package/dist/client/assets/{useWorkspaceDefaultLanding-DMWfrZfF.js → useWorkspaceDefaultLanding-BmaR7aTj.js} +2 -2
- package/dist/client/assets/{useWorkspaceDefaultLanding-DMWfrZfF.js.map → useWorkspaceDefaultLanding-BmaR7aTj.js.map} +1 -1
- package/dist/client/assets/{workspaceEntityRoutes-BJ-SC0Jd.js → workspaceEntityRoutes-BHccxrFj.js} +2 -2
- package/dist/client/assets/{workspaceEntityRoutes-BJ-SC0Jd.js.map → workspaceEntityRoutes-BHccxrFj.js.map} +1 -1
- package/dist/client/assets/{workspaceScrollCapture-CwBIBHg8.js → workspaceScrollCapture-BzsNJoL7.js} +2 -2
- package/dist/client/assets/{workspaceScrollCapture-CwBIBHg8.js.map → workspaceScrollCapture-BzsNJoL7.js.map} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/server/assets/{BindConfig-D8aIjI_R.js → BindConfig-BG-FGtB5.js} +13 -4
- package/dist/server/assets/BindConfig-BG-FGtB5.js.map +1 -0
- package/dist/server/server/cli.js +1 -1
- package/dist/server/server/index.js +1 -1
- package/package.json +5 -5
- package/dist/client/assets/ActiveWorkPage-C6lIQfjL.js +0 -2
- package/dist/client/assets/WorkspaceEntityRoute-uUK6vwM_.js +0 -14
- package/dist/client/assets/WorkspaceHomeLink-D5SdEgJJ.js +0 -2
- package/dist/client/assets/patterns-DAeEdyxU.js +0 -2
- package/dist/client/assets/patterns-DAeEdyxU.js.map +0 -1
- package/dist/server/assets/BindConfig-D8aIjI_R.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ItemsPage-Cr3--iJc.js","names":[],"sources":["../../../src/client/items/ItemsPage.module.css","../../../src/client/items/AuthorizedSharePanel.tsx","../../../src/client/items/ItemsPage.tsx"],"sourcesContent":[".page,\n.hero,\n.filters,\n.items,\n.item,\n.itemLink,\n.meta,\n.selection {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > * {\n margin: 0;\n}\n\n.filters {\n grid-template-columns: minmax(16rem, 2fr) repeat(4, minmax(9rem, 1fr));\n gap: var(--rly-space-12);\n align-items: end;\n}\n\n.filters label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.filters input,\n.filters select {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.filters input:focus-visible,\n.filters select:focus-visible,\n.itemLink:focus-visible,\n.membershipChoices a:focus-visible,\n.shareLink:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.resultHeading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rly-space-12);\n}\n\n.resultHeading h2 {\n margin: 0;\n}\n\n.selection {\n gap: var(--rly-space-12);\n scroll-margin-block-start: var(--rly-space-24);\n}\n\n.selection > * {\n margin: 0;\n}\n\n.selectionHeader,\n.selectionActions,\n.membershipChoices {\n display: flex;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.selectionActions {\n justify-content: space-between;\n}\n\n.membershipChoices {\n flex-wrap: wrap;\n}\n\n.membershipChoices a {\n display: grid;\n gap: var(--rly-space-2);\n min-block-size: 3rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\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 text-decoration: none;\n}\n\n.membershipChoices a span {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.items {\n gap: var(--rly-space-8);\n}\n\n.item {\n grid-template-columns: auto minmax(0, 1fr) auto auto;\n align-items: center;\n gap: var(--rly-space-16);\n min-block-size: 5.5rem;\n padding: var(--rly-space-16) var(--rly-space-20);\n}\n\n.itemLink {\n gap: var(--rly-space-2);\n min-inline-size: 0;\n color: inherit;\n text-decoration: none;\n}\n\n.shareLink {\n min-block-size: 2.5rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n color: var(--rly-color-text-1);\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 text-decoration: none;\n}\n\n.itemLink span,\n.meta {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.owners {\n min-inline-size: max-content;\n}\n\n.ownerGroup {\n display: grid;\n gap: var(--rly-space-4);\n min-inline-size: 0;\n}\n\n.ownerLimit {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.itemLink strong {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta {\n grid-auto-flow: column;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.shareForm,\n.shareResult {\n display: grid;\n grid-template-columns: minmax(12rem, 1fr) minmax(8rem, auto) minmax(8rem, auto) auto;\n gap: var(--rly-space-12);\n align-items: end;\n padding-block: var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-2);\n}\n\n.shareForm > div,\n.shareResult > div {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.shareForm h3,\n.shareForm p,\n.shareResult h3,\n.shareResult p {\n margin: 0;\n}\n\n.shareForm label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.shareForm select {\n min-block-size: 3rem;\n padding-inline: var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.shareForm select:focus-visible,\n.shareResult a:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.shareResult {\n grid-template-columns: minmax(0, 1fr) auto auto;\n}\n\n.shareResult a {\n overflow-wrap: anywhere;\n color: var(--rly-color-text-1);\n}\n\n@media (max-width: 64rem) {\n .filters {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n\n .search {\n grid-column: 1 / -1;\n }\n\n .item {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .meta {\n grid-column: 2;\n grid-auto-flow: row;\n grid-template-columns: repeat(2, minmax(0, max-content));\n }\n\n .shareLink {\n grid-column: 2;\n justify-self: start;\n }\n\n .shareForm,\n .shareResult {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-items: end;\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: 1 / -1;\n }\n}\n\n@media (max-width: 40rem) {\n .filters {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .search {\n grid-column: auto;\n }\n\n .meta,\n .shareForm,\n .shareResult {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: auto;\n }\n}\n","import { Button, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport { type FormEvent, type ReactElement, useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link } from \"react-router\"\n\nimport type { WorkspaceEntityOwner } from \"../../api/deliveryGraph.js\"\nimport type { EntityId, ShareId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport {\n browserAuthorizedShareTransport,\n type AuthorizedShareLifetime,\n type AuthorizedShareTransport,\n type CreateAuthorizedShareTransportInput\n} from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\n\ninterface ShareGrantee {\n readonly displayName: string\n readonly personId: PersonId\n}\n\ntype AuthorizedSharePanelState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"creating\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoking\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoked\" }\n\nexport interface AuthorizedSharePanelProps {\n readonly currentPersonId: PersonId\n readonly entityId: EntityId\n readonly grantees: ReadonlyArray<WorkspaceEntityOwner>\n readonly transport?: AuthorizedShareTransport\n readonly workspaceId: WorkspaceId\n}\n\nconst shareLifetime = (value: string): AuthorizedShareLifetime => (value === \"hour\" || value === \"week\" ? value : \"day\")\n\nconst shareGrantees = (\n currentPersonId: PersonId,\n grantees: ReadonlyArray<WorkspaceEntityOwner>\n): ReadonlyArray<ShareGrantee> => {\n const byId = new Map<PersonId, ShareGrantee>()\n byId.set(currentPersonId, { displayName: \"You\", personId: currentPersonId })\n for (const grantee of grantees) {\n byId.set(grantee.personId, { displayName: grantee.displayName, personId: grantee.personId })\n }\n return [...byId.values()]\n}\n\n/** Owner-only creation and revocation controls for one exact item share. */\nexport const AuthorizedSharePanel = ({\n currentPersonId,\n entityId,\n grantees,\n transport = browserAuthorizedShareTransport,\n workspaceId\n}: AuthorizedSharePanelProps): ReactElement => {\n const options = useMemo(() => shareGrantees(currentPersonId, grantees), [currentPersonId, grantees])\n const [granteePersonId, setGranteePersonId] = useState<PersonId>(options[0]?.personId ?? currentPersonId)\n const [lifetime, setLifetime] = useState<AuthorizedShareLifetime>(\"day\")\n const [state, setState] = useState<AuthorizedSharePanelState>({ _tag: \"idle\" })\n const createIntent = useRef<CreateAuthorizedShareTransportInput | null>(null)\n const currentRequest = useRef<AbortController | null>(null)\n const statusRegion = useRef<HTMLElement | null>(null)\n\n useEffect(() => () => currentRequest.current?.abort(), [])\n useEffect(() => {\n if (state._tag === \"ready\" || state._tag === \"revoked\") statusRegion.current?.focus()\n }, [state._tag])\n\n const create = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"creating\" })\n const existingIntent = createIntent.current\n const intent =\n existingIntent !== null &&\n existingIntent.entityId === entityId &&\n existingIntent.granteePersonId === granteePersonId &&\n existingIntent.lifetime === lifetime\n ? Promise.resolve(existingIntent)\n : transport.prepareCreate({ entityId, granteePersonId, lifetime }).then((nextIntent) => {\n createIntent.current = nextIntent\n return nextIntent\n })\n intent\n .then((currentIntent) => transport.create(currentIntent, request.signal))\n .then(\n (share) => {\n if (request.signal.aborted) return\n const currentIntent = createIntent.current\n if (\n currentIntent === null ||\n share.shareId !== currentIntent.shareId ||\n share.entityId !== currentIntent.entityId ||\n share.granteePersonId !== currentIntent.granteePersonId\n ) {\n setState({ _tag: \"failed\" })\n return\n }\n if (share.revokedAt !== null) {\n setState({ _tag: \"revoked\" })\n return\n }\n setState({\n _tag: \"ready\",\n shareId: share.shareId,\n expiresAt: DateTime.formatIso(share.expiresAt)\n })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n }\n\n const revoke = (shareId: ShareId, expiresAt: string): void => {\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"revoking\", shareId, expiresAt })\n transport.revoke(workspaceId, shareId, request.signal).then(\n () => {\n if (!request.signal.aborted) setState({ _tag: \"revoked\" })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"ready\", shareId, expiresAt })\n }\n )\n }\n\n const selectGrantee = (value: string): void => {\n createIntent.current = null\n setGranteePersonId(PersonId.make(value))\n }\n const selectLifetime = (value: string): void => {\n createIntent.current = null\n setLifetime(shareLifetime(value))\n }\n const createAnother = (): void => {\n createIntent.current = null\n setState({ _tag: \"idle\" })\n }\n\n if (state._tag === \"ready\" || state._tag === \"revoking\") {\n const sharePath = `/shares/${workspaceId}/${state.shareId}`\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Authorized link ready\n </Text>\n <Text tone=\"secondary\">Only the selected person can open this exact item. Expires {state.expiresAt}.</Text>\n </div>\n <Link to={sharePath}>{sharePath}</Link>\n <Button disabled={state._tag === \"revoking\"} onClick={() => revoke(state.shareId, state.expiresAt)}>\n {state._tag === \"revoking\" ? \"Revoking…\" : \"Revoke link\"}\n </Button>\n </section>\n )\n }\n\n if (state._tag === \"revoked\") {\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <StateLabel label=\"Revoked\" size=\"compact\" tone=\"neutral\" />\n <Text tone=\"secondary\">This link no longer resolves.</Text>\n <Button onClick={createAnother}>Create another</Button>\n </section>\n )\n }\n\n return (\n <form className={styles.shareForm} onSubmit={create}>\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Share this exact item\n </Text>\n <Text tone=\"secondary\">Authenticated access only. Related releases and relationships stay private.</Text>\n </div>\n <label>\n <span>Person</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectGrantee(event.currentTarget.value)}\n value={granteePersonId}\n >\n {options.map((option) => (\n <option key={option.personId} value={option.personId}>\n {option.displayName}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Expires</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectLifetime(event.currentTarget.value)}\n value={lifetime}\n >\n <option value=\"hour\">In 1 hour</option>\n <option value=\"day\">In 1 day</option>\n <option value=\"week\">In 7 days</option>\n </select>\n </label>\n <Button disabled={state._tag === \"creating\"} type=\"submit\">\n {state._tag === \"creating\" ? \"Creating…\" : \"Create authorized link\"}\n </Button>\n {state._tag === \"failed\" ? (\n <Text role=\"alert\" tone=\"secondary\">\n Could not create the link. Check the person and try again.\n </Text>\n ) : null}\n </form>\n )\n}\n","import { PeopleStrip, ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StateLabel, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\nimport { type ReactElement, useMemo, useState } from \"react\"\nimport { Link, useLocation, useNavigate, useOutletContext, useSearchParams } from \"react-router\"\n\nimport type { DeliveryEntityKind, DeliveryEntityService } from \"../../domain/deliveryGraph.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { PortfolioOverviewView, type PortfolioOverviewState } from \"../portfolio/PortfolioOverview.js\"\nimport type { WorkspaceReleaseOutletContext } from \"../releases/WorkspaceReleaseLayout.js\"\nimport { makeReleaseRouteState, releaseOriginFromLocation } from \"../releases/releaseRoutes.js\"\nimport { releaseWorksetSessionKey } from \"../releases/ReleaseWorkset.js\"\nimport { rememberWorkspaceScrollPosition, shouldRememberWorkspaceScrollPosition } from \"../workspaceScrollCapture.js\"\nimport {\n type WorkspaceItemPresentation,\n type WorkspaceItemStatus,\n workspaceItemReleaseHref\n} from \"./presentWorkspaceItems.js\"\nimport { browserWorkspaceItemsTransport, useWorkspaceItems, type WorkspaceItemsTransport } from \"./useWorkspaceItems.js\"\nimport { AuthorizedSharePanel } from \"./AuthorizedSharePanel.js\"\nimport type { AuthorizedShareTransport } from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\nimport { entityOriginFromLocation, makeWorkspaceEntityRouteState } from \"./workspaceEntityRoutes.js\"\n\ninterface ItemFilters {\n readonly query: string\n readonly owner: PersonId | \"all\"\n readonly service: DeliveryEntityService | \"all\"\n readonly status: WorkspaceItemStatus | \"all\"\n readonly type: DeliveryEntityKind | \"all\"\n}\n\nexport interface ItemsPageProps {\n readonly shareTransport?: AuthorizedShareTransport\n readonly transport?: WorkspaceItemsTransport\n}\n\nconst entityKinds: ReadonlyArray<DeliveryEntityKind> = [\n \"issue\",\n \"pull-request\",\n \"page\",\n \"pipeline-execution\",\n \"deployment\",\n \"time-entry\"\n]\nconst services: ReadonlyArray<DeliveryEntityService> = [\"jira\", \"codecommit\", \"confluence\", \"codepipeline\", \"clockify\"]\nconst freshnessFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nexport const formatItemFreshness = (freshness: string): string => freshnessFormatter.format(Date.parse(freshness))\n\nexport const itemsLocationWithSearch = (location: Pick<Location, \"hash\" | \"pathname\">, params: URLSearchParams) => ({\n hash: location.hash,\n pathname: location.pathname,\n search: params.size === 0 ? \"\" : `?${params.toString()}`\n})\n\nexport const unlinkedItemLocation = (pathname: string, params: URLSearchParams, entityId: string) => {\n const next = new URLSearchParams(params)\n next.set(\"object\", entityId)\n return {\n hash: \"#item-details\",\n pathname,\n search: `?${next.toString()}`\n }\n}\n\nconst entityKind = (value: string | null): DeliveryEntityKind | \"all\" =>\n entityKinds.find((candidate) => candidate === value) ?? \"all\"\n\nconst itemStatus = (value: string | null): WorkspaceItemStatus | \"all\" =>\n value === \"active\" || value === \"done\" || value === \"failed\" ? value : \"all\"\n\nconst itemOwner = (value: string | null): PersonId | \"all\" => {\n const decoded = Schema.decodeUnknownOption(PersonId)(value)\n return Option.isSome(decoded) ? decoded.value : \"all\"\n}\n\nconst filtersFrom = (params: URLSearchParams): ItemFilters => ({\n owner: itemOwner(params.get(\"owner\")),\n query: params.get(\"q\")?.trim() ?? \"\",\n service: services.find((candidate) => candidate === params.get(\"service\")) ?? \"all\",\n status: itemStatus(params.get(\"status\")),\n type: entityKind(params.get(\"type\"))\n})\n\nexport const filterWorkspaceItems = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n filters: ItemFilters\n): ReadonlyArray<WorkspaceItemPresentation> => {\n const query = filters.query.toLocaleLowerCase(\"en-US\")\n return items.filter(\n (item) =>\n (query.length === 0 || `${item.key} ${item.title} ${item.status}`.toLocaleLowerCase(\"en-US\").includes(query)) &&\n (filters.service === \"all\" || item.service === filters.service) &&\n (filters.owner === \"all\" || item.owners.some(({ id }) => id === filters.owner)) &&\n (filters.status === \"all\" || item.statusGroup === filters.status) &&\n (filters.type === \"all\" || item.kind === filters.type)\n )\n}\n\nconst ItemOwners = ({ item }: { readonly item: WorkspaceItemPresentation }): ReactElement => {\n const [expanded, setExpanded] = useState(false)\n if (item.owners.length === 0) return <span>Unassigned</span>\n return (\n <span className={styles.ownerGroup}>\n <PeopleStrip\n aria-label={`${item.key} collaborators${item.ownersTruncated ? \", more collaborators not shown\" : \"\"}`}\n className={styles.owners}\n expanded={expanded}\n limit={2}\n onExpandedChange={setExpanded}\n people={item.owners}\n size=\"compact\"\n />\n {item.ownersTruncated ? <span className={styles.ownerLimit}>20+ people · More not shown</span> : null}\n </span>\n )\n}\n\nexport const selectWorkspaceItem = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n entityId: string | null\n): WorkspaceItemPresentation | null =>\n entityId === null ? null : (items.find((item) => item.entityId === entityId) ?? null)\n\nconst labelForKind = (kind: DeliveryEntityKind): string =>\n kind\n .split(\"-\")\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nexport const workspaceItemMembershipDescription = (item: WorkspaceItemPresentation): string => {\n if (item.releaseIds.length === 0) {\n return \"This current object is not linked to a release yet. Its provider-specific full view will remain available here when that integration is connected.\"\n }\n if (item.routableReleaseIds.length === 0) {\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"} outside the current portfolio. Its membership remains visible without routing to an unavailable release page.`\n }\n if (item.releaseIds.length === 1) {\n return \"This object is linked to one release and can be opened in its complete delivery context.\"\n }\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} releases. Choose the exact release context to avoid silently substituting another delivery trace.`\n}\n\n/** Compact workspace-wide index of normalized delivery objects. */\nexport const ItemsPage = ({\n shareTransport,\n transport = browserWorkspaceItemsTransport\n}: ItemsPageProps = {}): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const browserSession = useBrowserSession()\n const location = useLocation()\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n const portfolio = context.controller.state._tag === \"ready\" ? context.controller.state.portfolio : null\n const releaseById = useMemo(\n () => new Map(portfolio?.releases.map((release) => [release.id, release]) ?? []),\n [portfolio]\n )\n const routableReleaseIds = useMemo(() => new Set(portfolio?.releases.map(({ id }) => id) ?? []), [portfolio])\n const refreshKey =\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.generatedAt : \"pending\"\n const sessionKey = releaseWorksetSessionKey(browserSession.state)\n const filters = filtersFrom(searchParams)\n const controller = useWorkspaceItems(\n context.workspaceId,\n routableReleaseIds,\n filters,\n refreshKey,\n sessionKey,\n browserSession.invalidateSession,\n transport\n )\n const replaceSearch = (next: URLSearchParams): void => {\n navigate(itemsLocationWithSearch(location, next), { replace: true })\n }\n const update = (key: keyof ItemFilters, value: string): void => {\n const next = new URLSearchParams(searchParams)\n if (value.length === 0 || value === \"all\") next.delete(key === \"query\" ? \"q\" : key)\n else next.set(key === \"query\" ? \"q\" : key, value)\n replaceSearch(next)\n }\n\n const portfolioBoundary: PortfolioOverviewState | null =\n context.controller.state._tag !== \"ready\"\n ? context.controller.state\n : sessionKey === null\n ? {\n _tag: \"session\",\n reason: browserSession.state._tag === \"authenticated\" ? \"checking\" : browserSession.state._tag\n }\n : null\n if (portfolioBoundary?._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (portfolioBoundary !== null) {\n return (\n <PortfolioOverviewView\n onPreviewRelease={() => undefined}\n onRetry={context.controller.onRetry}\n state={portfolioBoundary}\n />\n )\n }\n if (controller.state._tag === \"idle\" || controller.state._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (controller.state._tag === \"failed\") {\n return (\n <StatePanel\n action={<Button onClick={controller.retry}>Try again</Button>}\n description=\"Control Center could not read the normalized delivery index. Saved source facts remain unchanged.\"\n title=\"Items unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n const visibleItems = controller.state.items\n const hasSelectedOwnerOption =\n filters.owner === \"all\" || controller.state.ownerOptions.some(({ personId }) => personId === filters.owner)\n const selectedOwner =\n filters.owner === \"all\"\n ? undefined\n : controller.state.items.flatMap(({ owners }) => owners).find(({ id }) => id === filters.owner)\n const selectedEntityId = searchParams.get(\"object\")\n const selectedItem = selectWorkspaceItem(controller.state.items, selectedEntityId)\n const shareOwnerPersonId =\n browserSession.state._tag === \"authenticated\" &&\n browserSession.state.session.permission === \"workspace-owner\" &&\n browserSession.state.session.actor._tag === \"human\"\n ? browserSession.state.session.actor.personId\n : null\n const clearSelection = (): void => {\n const next = new URLSearchParams(searchParams)\n next.delete(\"object\")\n navigate(\n {\n hash: \"#results\",\n pathname: location.pathname,\n search: next.size === 0 ? \"\" : `?${next.toString()}`\n },\n { replace: true }\n )\n }\n return (\n <article className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n Workspace items\n </Text>\n <Text as=\"h1\" variant=\"verdict\">\n Find release work.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n One quiet index across tickets, pull requests, docs, pipelines, deployments, and time.\n </Text>\n </header>\n\n <section aria-label=\"Item filters\" className={styles.filters}>\n <label className={styles.search}>\n <span>Search</span>\n <input\n maxLength={200}\n onChange={(event) => update(\"query\", event.currentTarget.value)}\n placeholder=\"Key, title, or status\"\n type=\"search\"\n value={filters.query}\n />\n </label>\n <label>\n <span>Service</span>\n <select onChange={(event) => update(\"service\", event.currentTarget.value)} value={filters.service}>\n <option value=\"all\">All services</option>\n {services.map((service) => (\n <option key={service} value={service}>\n {service}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Owner</span>\n <select onChange={(event) => update(\"owner\", event.currentTarget.value)} value={filters.owner}>\n <option value=\"all\">Anyone</option>\n {filters.owner !== \"all\" && !hasSelectedOwnerOption ? (\n <option value={filters.owner}>{selectedOwner?.name ?? `Owner …${filters.owner.slice(-6)}`}</option>\n ) : null}\n {controller.state.ownerOptions.map((owner) => (\n <option key={owner.personId} value={owner.personId}>\n {owner.displayName}\n </option>\n ))}\n {controller.state.ownerOptionsTruncated ? <option disabled>More owners not shown</option> : null}\n </select>\n </label>\n <label>\n <span>Type</span>\n <select onChange={(event) => update(\"type\", event.currentTarget.value)} value={filters.type}>\n <option value=\"all\">All types</option>\n {entityKinds.map((kind) => (\n <option key={kind} value={kind}>\n {labelForKind(kind)}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Status</span>\n <select onChange={(event) => update(\"status\", event.currentTarget.value)} value={filters.status}>\n <option value=\"all\">Any status</option>\n <option value=\"active\">Active</option>\n <option value=\"done\">Done</option>\n <option value=\"failed\">Needs attention</option>\n </select>\n </label>\n </section>\n\n {selectedEntityId === null ? null : selectedItem === null ? (\n <div id=\"item-details\">\n <StatePanel\n action={<Button onClick={clearSelection}>Back to items</Button>}\n description=\"This item is not present in the current bounded workspace index. It may have been deleted or fall outside this result prefix.\"\n title=\"Item unavailable\"\n tone=\"caution\"\n />\n </div>\n ) : (\n <Surface as=\"section\" className={styles.selection} id=\"item-details\" padding=\"spacious\" tone=\"secondary\">\n <div className={styles.selectionHeader}>\n <ServiceMark service={selectedItem.service} size=\"compact\" />\n <StateLabel label={selectedItem.status} size=\"compact\" tone={selectedItem.tone} />\n </div>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n {selectedItem.key} · {labelForKind(selectedItem.kind)}\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {selectedItem.title}\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n {workspaceItemMembershipDescription(selectedItem)}\n </Text>\n <ItemOwners item={selectedItem} />\n {shareOwnerPersonId === null ? null : (\n <AuthorizedSharePanel\n key={selectedItem.entityId}\n currentPersonId={shareOwnerPersonId}\n entityId={selectedItem.entityId}\n grantees={controller.state.ownerOptions}\n workspaceId={context.workspaceId}\n {...(shareTransport === undefined ? {} : { transport: shareTransport })}\n />\n )}\n <div className={styles.selectionActions}>\n <div className={styles.membershipChoices}>\n {selectedItem.routableReleaseIds.map((releaseId) => {\n const release = releaseById.get(releaseId)\n return (\n <Link\n key={releaseId}\n state={makeReleaseRouteState(context.workspaceId, releaseId, releaseOriginFromLocation(location))}\n to={workspaceItemReleaseHref(context.workspaceId, releaseId, selectedItem.entityId)}\n >\n Open {release === undefined ? `release ${releaseId.slice(-6)}` : release.relay.codename}\n {release === undefined ? null : <span>{release.version}</span>}\n </Link>\n )\n })}\n </div>\n <Button onClick={clearSelection}>Back to items</Button>\n </div>\n </Surface>\n )}\n\n <div className={styles.resultHeading} id=\"results\">\n <Text as=\"h2\" variant=\"section-title\">\n {controller.state.matchedCount} of {controller.state.totalCount} workspace items\n </Text>\n <StateLabel\n label={\n controller.state.refreshing\n ? \"Updating results\"\n : controller.state.truncated\n ? \"Bounded workspace result\"\n : \"Workspace scope\"\n }\n size=\"compact\"\n tone={controller.state.truncated && !controller.state.refreshing ? \"caution\" : \"neutral\"}\n />\n </div>\n\n {visibleItems.length === 0 ? (\n <StatePanel\n action={<Button onClick={() => replaceSearch(new URLSearchParams())}>Clear filters</Button>}\n description=\"Try a broader word, owner, service, type, or status. No demo object is substituted.\"\n title=\"No matching items\"\n />\n ) : (\n <div className={styles.items}>\n {visibleItems.map((item) => (\n <Surface as=\"article\" className={styles.item} key={item.entityId} padding=\"none\" tone=\"secondary\">\n <ServiceMark service={item.service} size=\"compact\" />\n <Link\n className={styles.itemLink}\n onClick={(event) => {\n if (shouldRememberWorkspaceScrollPosition(event, event.currentTarget.target)) {\n rememberWorkspaceScrollPosition(location, item.href)\n }\n }}\n state={makeWorkspaceEntityRouteState(\n location.state,\n context.workspaceId,\n item.entityId,\n entityOriginFromLocation(location)\n )}\n to={item.href}\n >\n <span>{item.key}</span>\n <strong>{item.title}</strong>\n </Link>\n <div className={styles.meta}>\n <StateLabel label={item.status} size=\"compact\" tone={item.tone} />\n <span>{labelForKind(item.kind)}</span>\n <span>\n {item.releaseIds.length === 0\n ? \"Unlinked\"\n : `${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"}`}\n </span>\n <ItemOwners item={item} />\n <time dateTime={item.freshness} title={`Synchronized ${item.freshness}`}>\n {formatItemFreshness(item.freshness)}\n </time>\n </div>\n {shareOwnerPersonId === null ? null : (\n <Link\n className={styles.shareLink}\n to={unlinkedItemLocation(location.pathname, searchParams, item.entityId)}\n >\n Share\n </Link>\n )}\n </Surface>\n ))}\n </div>\n )}\n </article>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ItemsPage-Bok8Vpy4.js","names":[],"sources":["../../../src/client/items/ItemsPage.module.css","../../../src/client/items/AuthorizedSharePanel.tsx","../../../src/client/items/ItemsPage.tsx"],"sourcesContent":[".page,\n.hero,\n.filters,\n.items,\n.item,\n.itemLink,\n.meta,\n.selection {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > * {\n margin: 0;\n}\n\n.filters {\n grid-template-columns: minmax(16rem, 2fr) repeat(4, minmax(9rem, 1fr));\n gap: var(--rly-space-12);\n align-items: end;\n}\n\n.filters label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.filters input,\n.filters select {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.filters input:focus-visible,\n.filters select:focus-visible,\n.itemLink:focus-visible,\n.membershipChoices a:focus-visible,\n.shareLink:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.resultHeading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--rly-space-12);\n}\n\n.resultHeading h2 {\n margin: 0;\n}\n\n.selection {\n gap: var(--rly-space-12);\n scroll-margin-block-start: var(--rly-space-24);\n}\n\n.selection > * {\n margin: 0;\n}\n\n.selectionHeader,\n.selectionActions,\n.membershipChoices {\n display: flex;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.selectionActions {\n justify-content: space-between;\n}\n\n.membershipChoices {\n flex-wrap: wrap;\n}\n\n.membershipChoices a {\n display: grid;\n gap: var(--rly-space-2);\n min-block-size: 3rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\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 text-decoration: none;\n}\n\n.membershipChoices a span {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.items {\n gap: var(--rly-space-8);\n}\n\n.item {\n grid-template-columns: auto minmax(0, 1fr) auto auto;\n align-items: center;\n gap: var(--rly-space-16);\n min-block-size: 5.5rem;\n padding: var(--rly-space-16) var(--rly-space-20);\n}\n\n.itemLink {\n gap: var(--rly-space-2);\n min-inline-size: 0;\n color: inherit;\n text-decoration: none;\n}\n\n.shareLink {\n min-block-size: 2.5rem;\n padding: var(--rly-space-8) var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n color: var(--rly-color-text-1);\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 text-decoration: none;\n}\n\n.itemLink span,\n.meta {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.owners {\n min-inline-size: max-content;\n}\n\n.ownerGroup {\n display: grid;\n gap: var(--rly-space-4);\n min-inline-size: 0;\n}\n\n.ownerLimit {\n color: var(--rly-color-text-2);\n font: var(--rly-type-meta-weight) var(--rly-type-meta-size) / var(--rly-type-meta-line-height)\n var(--rly-type-meta-font);\n}\n\n.itemLink strong {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.meta {\n grid-auto-flow: column;\n align-items: center;\n gap: var(--rly-space-12);\n}\n\n.shareForm,\n.shareResult {\n display: grid;\n grid-template-columns: minmax(12rem, 1fr) minmax(8rem, auto) minmax(8rem, auto) auto;\n gap: var(--rly-space-12);\n align-items: end;\n padding-block: var(--rly-space-12);\n border-block: 1px solid var(--rly-color-border-2);\n}\n\n.shareForm > div,\n.shareResult > div {\n display: grid;\n gap: var(--rly-space-4);\n}\n\n.shareForm h3,\n.shareForm p,\n.shareResult h3,\n.shareResult p {\n margin: 0;\n}\n\n.shareForm label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.shareForm select {\n min-block-size: 3rem;\n padding-inline: var(--rly-space-12);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.shareForm select:focus-visible,\n.shareResult a:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n\n.shareResult {\n grid-template-columns: minmax(0, 1fr) auto auto;\n}\n\n.shareResult a {\n overflow-wrap: anywhere;\n color: var(--rly-color-text-1);\n}\n\n@media (max-width: 64rem) {\n .filters {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n\n .search {\n grid-column: 1 / -1;\n }\n\n .item {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .meta {\n grid-column: 2;\n grid-auto-flow: row;\n grid-template-columns: repeat(2, minmax(0, max-content));\n }\n\n .shareLink {\n grid-column: 2;\n justify-self: start;\n }\n\n .shareForm,\n .shareResult {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n align-items: end;\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: 1 / -1;\n }\n}\n\n@media (max-width: 40rem) {\n .filters {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .search {\n grid-column: auto;\n }\n\n .meta,\n .shareForm,\n .shareResult {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .shareForm > div,\n .shareResult > div {\n grid-column: auto;\n }\n}\n","import { Button, StateLabel, Text } from \"@knpkv/rly/primitives\"\nimport * as DateTime from \"effect/DateTime\"\nimport { type FormEvent, type ReactElement, useEffect, useMemo, useRef, useState } from \"react\"\nimport { Link } from \"react-router\"\n\nimport type { WorkspaceEntityOwner } from \"../../api/deliveryGraph.js\"\nimport type { EntityId, ShareId, WorkspaceId } from \"../../domain/identifiers.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport {\n browserAuthorizedShareTransport,\n type AuthorizedShareLifetime,\n type AuthorizedShareTransport,\n type CreateAuthorizedShareTransportInput\n} from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\n\ninterface ShareGrantee {\n readonly displayName: string\n readonly personId: PersonId\n}\n\ntype AuthorizedSharePanelState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"creating\" }\n | { readonly _tag: \"failed\" }\n | { readonly _tag: \"ready\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoking\"; readonly shareId: ShareId; readonly expiresAt: string }\n | { readonly _tag: \"revoked\" }\n\nexport interface AuthorizedSharePanelProps {\n readonly currentPersonId: PersonId\n readonly entityId: EntityId\n readonly grantees: ReadonlyArray<WorkspaceEntityOwner>\n readonly transport?: AuthorizedShareTransport\n readonly workspaceId: WorkspaceId\n}\n\nconst shareLifetime = (value: string): AuthorizedShareLifetime => (value === \"hour\" || value === \"week\" ? value : \"day\")\n\nconst shareGrantees = (\n currentPersonId: PersonId,\n grantees: ReadonlyArray<WorkspaceEntityOwner>\n): ReadonlyArray<ShareGrantee> => {\n const byId = new Map<PersonId, ShareGrantee>()\n byId.set(currentPersonId, { displayName: \"You\", personId: currentPersonId })\n for (const grantee of grantees) {\n byId.set(grantee.personId, { displayName: grantee.displayName, personId: grantee.personId })\n }\n return [...byId.values()]\n}\n\n/** Owner-only creation and revocation controls for one exact item share. */\nexport const AuthorizedSharePanel = ({\n currentPersonId,\n entityId,\n grantees,\n transport = browserAuthorizedShareTransport,\n workspaceId\n}: AuthorizedSharePanelProps): ReactElement => {\n const options = useMemo(() => shareGrantees(currentPersonId, grantees), [currentPersonId, grantees])\n const [granteePersonId, setGranteePersonId] = useState<PersonId>(options[0]?.personId ?? currentPersonId)\n const [lifetime, setLifetime] = useState<AuthorizedShareLifetime>(\"day\")\n const [state, setState] = useState<AuthorizedSharePanelState>({ _tag: \"idle\" })\n const createIntent = useRef<CreateAuthorizedShareTransportInput | null>(null)\n const currentRequest = useRef<AbortController | null>(null)\n const statusRegion = useRef<HTMLElement | null>(null)\n\n useEffect(() => () => currentRequest.current?.abort(), [])\n useEffect(() => {\n if (state._tag === \"ready\" || state._tag === \"revoked\") statusRegion.current?.focus()\n }, [state._tag])\n\n const create = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"creating\" })\n const existingIntent = createIntent.current\n const intent =\n existingIntent !== null &&\n existingIntent.entityId === entityId &&\n existingIntent.granteePersonId === granteePersonId &&\n existingIntent.lifetime === lifetime\n ? Promise.resolve(existingIntent)\n : transport.prepareCreate({ entityId, granteePersonId, lifetime }).then((nextIntent) => {\n createIntent.current = nextIntent\n return nextIntent\n })\n intent\n .then((currentIntent) => transport.create(currentIntent, request.signal))\n .then(\n (share) => {\n if (request.signal.aborted) return\n const currentIntent = createIntent.current\n if (\n currentIntent === null ||\n share.shareId !== currentIntent.shareId ||\n share.entityId !== currentIntent.entityId ||\n share.granteePersonId !== currentIntent.granteePersonId\n ) {\n setState({ _tag: \"failed\" })\n return\n }\n if (share.revokedAt !== null) {\n setState({ _tag: \"revoked\" })\n return\n }\n setState({\n _tag: \"ready\",\n shareId: share.shareId,\n expiresAt: DateTime.formatIso(share.expiresAt)\n })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"failed\" })\n }\n )\n }\n\n const revoke = (shareId: ShareId, expiresAt: string): void => {\n currentRequest.current?.abort()\n const request = new AbortController()\n currentRequest.current = request\n setState({ _tag: \"revoking\", shareId, expiresAt })\n transport.revoke(workspaceId, shareId, request.signal).then(\n () => {\n if (!request.signal.aborted) setState({ _tag: \"revoked\" })\n },\n () => {\n if (!request.signal.aborted) setState({ _tag: \"ready\", shareId, expiresAt })\n }\n )\n }\n\n const selectGrantee = (value: string): void => {\n createIntent.current = null\n setGranteePersonId(PersonId.make(value))\n }\n const selectLifetime = (value: string): void => {\n createIntent.current = null\n setLifetime(shareLifetime(value))\n }\n const createAnother = (): void => {\n createIntent.current = null\n setState({ _tag: \"idle\" })\n }\n\n if (state._tag === \"ready\" || state._tag === \"revoking\") {\n const sharePath = `/shares/${workspaceId}/${state.shareId}`\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Authorized link ready\n </Text>\n <Text tone=\"secondary\">Only the selected person can open this exact item. Expires {state.expiresAt}.</Text>\n </div>\n <Link to={sharePath}>{sharePath}</Link>\n <Button disabled={state._tag === \"revoking\"} onClick={() => revoke(state.shareId, state.expiresAt)}>\n {state._tag === \"revoking\" ? \"Revoking…\" : \"Revoke link\"}\n </Button>\n </section>\n )\n }\n\n if (state._tag === \"revoked\") {\n return (\n <section\n aria-label=\"Authorized share\"\n aria-live=\"polite\"\n className={styles.shareResult}\n ref={statusRegion}\n role=\"status\"\n tabIndex={-1}\n >\n <StateLabel label=\"Revoked\" size=\"compact\" tone=\"neutral\" />\n <Text tone=\"secondary\">This link no longer resolves.</Text>\n <Button onClick={createAnother}>Create another</Button>\n </section>\n )\n }\n\n return (\n <form className={styles.shareForm} onSubmit={create}>\n <div>\n <Text as=\"h3\" variant=\"body-large\">\n Share this exact item\n </Text>\n <Text tone=\"secondary\">Authenticated access only. Related releases and relationships stay private.</Text>\n </div>\n <label>\n <span>Person</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectGrantee(event.currentTarget.value)}\n value={granteePersonId}\n >\n {options.map((option) => (\n <option key={option.personId} value={option.personId}>\n {option.displayName}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Expires</span>\n <select\n disabled={state._tag === \"creating\"}\n onChange={(event) => selectLifetime(event.currentTarget.value)}\n value={lifetime}\n >\n <option value=\"hour\">In 1 hour</option>\n <option value=\"day\">In 1 day</option>\n <option value=\"week\">In 7 days</option>\n </select>\n </label>\n <Button disabled={state._tag === \"creating\"} type=\"submit\">\n {state._tag === \"creating\" ? \"Creating…\" : \"Create authorized link\"}\n </Button>\n {state._tag === \"failed\" ? (\n <Text role=\"alert\" tone=\"secondary\">\n Could not create the link. Check the person and try again.\n </Text>\n ) : null}\n </form>\n )\n}\n","import { PeopleStrip, ServiceMark } from \"@knpkv/rly/patterns\"\nimport { Button, Skeleton, StateLabel, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Schema from \"effect/Schema\"\nimport { type ReactElement, useMemo, useState } from \"react\"\nimport { Link, useLocation, useNavigate, useOutletContext, useSearchParams } from \"react-router\"\n\nimport type { DeliveryEntityKind, DeliveryEntityService } from \"../../domain/deliveryGraph.js\"\nimport { PersonId } from \"../../domain/identifiers.js\"\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { PortfolioOverviewView, type PortfolioOverviewState } from \"../portfolio/PortfolioOverview.js\"\nimport type { WorkspaceReleaseOutletContext } from \"../releases/WorkspaceReleaseLayout.js\"\nimport { makeReleaseRouteState, releaseOriginFromLocation } from \"../releases/releaseRoutes.js\"\nimport { releaseWorksetSessionKey } from \"../releases/ReleaseWorkset.js\"\nimport { rememberWorkspaceScrollPosition, shouldRememberWorkspaceScrollPosition } from \"../workspaceScrollCapture.js\"\nimport {\n type WorkspaceItemPresentation,\n type WorkspaceItemStatus,\n workspaceItemReleaseHref\n} from \"./presentWorkspaceItems.js\"\nimport { browserWorkspaceItemsTransport, useWorkspaceItems, type WorkspaceItemsTransport } from \"./useWorkspaceItems.js\"\nimport { AuthorizedSharePanel } from \"./AuthorizedSharePanel.js\"\nimport type { AuthorizedShareTransport } from \"./authorizedShareTransport.js\"\nimport styles from \"./ItemsPage.module.css\"\nimport { entityOriginFromLocation, makeWorkspaceEntityRouteState } from \"./workspaceEntityRoutes.js\"\n\ninterface ItemFilters {\n readonly query: string\n readonly owner: PersonId | \"all\"\n readonly service: DeliveryEntityService | \"all\"\n readonly status: WorkspaceItemStatus | \"all\"\n readonly type: DeliveryEntityKind | \"all\"\n}\n\nexport interface ItemsPageProps {\n readonly shareTransport?: AuthorizedShareTransport\n readonly transport?: WorkspaceItemsTransport\n}\n\nconst entityKinds: ReadonlyArray<DeliveryEntityKind> = [\n \"issue\",\n \"pull-request\",\n \"page\",\n \"pipeline-execution\",\n \"deployment\",\n \"time-entry\"\n]\nconst services: ReadonlyArray<DeliveryEntityService> = [\"jira\", \"codecommit\", \"confluence\", \"codepipeline\", \"clockify\"]\nconst freshnessFormatter = new Intl.DateTimeFormat(\"en-GB\", {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n timeZone: \"UTC\"\n})\n\nexport const formatItemFreshness = (freshness: string): string => freshnessFormatter.format(Date.parse(freshness))\n\nexport const itemsLocationWithSearch = (location: Pick<Location, \"hash\" | \"pathname\">, params: URLSearchParams) => ({\n hash: location.hash,\n pathname: location.pathname,\n search: params.size === 0 ? \"\" : `?${params.toString()}`\n})\n\nexport const unlinkedItemLocation = (pathname: string, params: URLSearchParams, entityId: string) => {\n const next = new URLSearchParams(params)\n next.set(\"object\", entityId)\n return {\n hash: \"#item-details\",\n pathname,\n search: `?${next.toString()}`\n }\n}\n\nconst entityKind = (value: string | null): DeliveryEntityKind | \"all\" =>\n entityKinds.find((candidate) => candidate === value) ?? \"all\"\n\nconst itemStatus = (value: string | null): WorkspaceItemStatus | \"all\" =>\n value === \"active\" || value === \"done\" || value === \"failed\" ? value : \"all\"\n\nconst itemOwner = (value: string | null): PersonId | \"all\" => {\n const decoded = Schema.decodeUnknownOption(PersonId)(value)\n return Option.isSome(decoded) ? decoded.value : \"all\"\n}\n\nconst filtersFrom = (params: URLSearchParams): ItemFilters => ({\n owner: itemOwner(params.get(\"owner\")),\n query: params.get(\"q\")?.trim() ?? \"\",\n service: services.find((candidate) => candidate === params.get(\"service\")) ?? \"all\",\n status: itemStatus(params.get(\"status\")),\n type: entityKind(params.get(\"type\"))\n})\n\nexport const filterWorkspaceItems = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n filters: ItemFilters\n): ReadonlyArray<WorkspaceItemPresentation> => {\n const query = filters.query.toLocaleLowerCase(\"en-US\")\n return items.filter(\n (item) =>\n (query.length === 0 || `${item.key} ${item.title} ${item.status}`.toLocaleLowerCase(\"en-US\").includes(query)) &&\n (filters.service === \"all\" || item.service === filters.service) &&\n (filters.owner === \"all\" || item.owners.some(({ id }) => id === filters.owner)) &&\n (filters.status === \"all\" || item.statusGroup === filters.status) &&\n (filters.type === \"all\" || item.kind === filters.type)\n )\n}\n\nconst ItemOwners = ({ item }: { readonly item: WorkspaceItemPresentation }): ReactElement => {\n const [expanded, setExpanded] = useState(false)\n if (item.owners.length === 0) return <span>Unassigned</span>\n return (\n <span className={styles.ownerGroup}>\n <PeopleStrip\n aria-label={`${item.key} collaborators${item.ownersTruncated ? \", more collaborators not shown\" : \"\"}`}\n className={styles.owners}\n expanded={expanded}\n limit={2}\n onExpandedChange={setExpanded}\n people={item.owners}\n size=\"compact\"\n />\n {item.ownersTruncated ? <span className={styles.ownerLimit}>20+ people · More not shown</span> : null}\n </span>\n )\n}\n\nexport const selectWorkspaceItem = (\n items: ReadonlyArray<WorkspaceItemPresentation>,\n entityId: string | null\n): WorkspaceItemPresentation | null =>\n entityId === null ? null : (items.find((item) => item.entityId === entityId) ?? null)\n\nconst labelForKind = (kind: DeliveryEntityKind): string =>\n kind\n .split(\"-\")\n .map((part) => `${part.charAt(0).toLocaleUpperCase(\"en-US\")}${part.slice(1)}`)\n .join(\" \")\n\nexport const workspaceItemMembershipDescription = (item: WorkspaceItemPresentation): string => {\n if (item.releaseIds.length === 0) {\n return \"This current object is not linked to a release yet. Its provider-specific full view will remain available here when that integration is connected.\"\n }\n if (item.routableReleaseIds.length === 0) {\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"} outside the current portfolio. Its membership remains visible without routing to an unavailable release page.`\n }\n if (item.releaseIds.length === 1) {\n return \"This object is linked to one release and can be opened in its complete delivery context.\"\n }\n return `This object is linked to ${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} releases. Choose the exact release context to avoid silently substituting another delivery trace.`\n}\n\n/** Compact workspace-wide index of normalized delivery objects. */\nexport const ItemsPage = ({\n shareTransport,\n transport = browserWorkspaceItemsTransport\n}: ItemsPageProps = {}): ReactElement => {\n const context = useOutletContext<WorkspaceReleaseOutletContext>()\n const browserSession = useBrowserSession()\n const location = useLocation()\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n const portfolio = context.controller.state._tag === \"ready\" ? context.controller.state.portfolio : null\n const releaseById = useMemo(\n () => new Map(portfolio?.releases.map((release) => [release.id, release]) ?? []),\n [portfolio]\n )\n const routableReleaseIds = useMemo(() => new Set(portfolio?.releases.map(({ id }) => id) ?? []), [portfolio])\n const refreshKey =\n context.controller.state._tag === \"ready\" ? context.controller.state.portfolio.generatedAt : \"pending\"\n const sessionKey = releaseWorksetSessionKey(browserSession.state)\n const filters = filtersFrom(searchParams)\n const controller = useWorkspaceItems(\n context.workspaceId,\n routableReleaseIds,\n filters,\n refreshKey,\n sessionKey,\n browserSession.invalidateSession,\n transport\n )\n const replaceSearch = (next: URLSearchParams): void => {\n navigate(itemsLocationWithSearch(location, next), { replace: true })\n }\n const update = (key: keyof ItemFilters, value: string): void => {\n const next = new URLSearchParams(searchParams)\n if (value.length === 0 || value === \"all\") next.delete(key === \"query\" ? \"q\" : key)\n else next.set(key === \"query\" ? \"q\" : key, value)\n replaceSearch(next)\n }\n\n const portfolioBoundary: PortfolioOverviewState | null =\n context.controller.state._tag !== \"ready\"\n ? context.controller.state\n : sessionKey === null\n ? {\n _tag: \"session\",\n reason: browserSession.state._tag === \"authenticated\" ? \"checking\" : browserSession.state._tag\n }\n : null\n if (portfolioBoundary?._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (portfolioBoundary !== null) {\n return (\n <PortfolioOverviewView\n onPreviewRelease={() => undefined}\n onRetry={context.controller.onRetry}\n state={portfolioBoundary}\n />\n )\n }\n if (controller.state._tag === \"idle\" || controller.state._tag === \"loading\") {\n return (\n <section aria-label=\"Loading delivery items\" className={styles.page}>\n <Skeleton height=\"8rem\" variant=\"block\" />\n <Skeleton height=\"20rem\" variant=\"block\" />\n </section>\n )\n }\n if (controller.state._tag === \"failed\") {\n return (\n <StatePanel\n action={<Button onClick={controller.retry}>Try again</Button>}\n description=\"Control Center could not read the normalized delivery index. Saved source facts remain unchanged.\"\n title=\"Items unavailable\"\n tone=\"caution\"\n />\n )\n }\n\n const visibleItems = controller.state.items\n const hasSelectedOwnerOption =\n filters.owner === \"all\" || controller.state.ownerOptions.some(({ personId }) => personId === filters.owner)\n const selectedOwner =\n filters.owner === \"all\"\n ? undefined\n : controller.state.items.flatMap(({ owners }) => owners).find(({ id }) => id === filters.owner)\n const selectedEntityId = searchParams.get(\"object\")\n const selectedItem = selectWorkspaceItem(controller.state.items, selectedEntityId)\n const shareOwnerPersonId =\n browserSession.state._tag === \"authenticated\" &&\n browserSession.state.session.permission === \"workspace-owner\" &&\n browserSession.state.session.actor._tag === \"human\"\n ? browserSession.state.session.actor.personId\n : null\n const clearSelection = (): void => {\n const next = new URLSearchParams(searchParams)\n next.delete(\"object\")\n navigate(\n {\n hash: \"#results\",\n pathname: location.pathname,\n search: next.size === 0 ? \"\" : `?${next.toString()}`\n },\n { replace: true }\n )\n }\n return (\n <article className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n Workspace items\n </Text>\n <Text as=\"h1\" variant=\"verdict\">\n Find release work.\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n One quiet index across tickets, pull requests, docs, pipelines, deployments, and time.\n </Text>\n </header>\n\n <section aria-label=\"Item filters\" className={styles.filters}>\n <label className={styles.search}>\n <span>Search</span>\n <input\n maxLength={200}\n onChange={(event) => update(\"query\", event.currentTarget.value)}\n placeholder=\"Key, title, or status\"\n type=\"search\"\n value={filters.query}\n />\n </label>\n <label>\n <span>Service</span>\n <select onChange={(event) => update(\"service\", event.currentTarget.value)} value={filters.service}>\n <option value=\"all\">All services</option>\n {services.map((service) => (\n <option key={service} value={service}>\n {service}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Owner</span>\n <select onChange={(event) => update(\"owner\", event.currentTarget.value)} value={filters.owner}>\n <option value=\"all\">Anyone</option>\n {filters.owner !== \"all\" && !hasSelectedOwnerOption ? (\n <option value={filters.owner}>{selectedOwner?.name ?? `Owner …${filters.owner.slice(-6)}`}</option>\n ) : null}\n {controller.state.ownerOptions.map((owner) => (\n <option key={owner.personId} value={owner.personId}>\n {owner.displayName}\n </option>\n ))}\n {controller.state.ownerOptionsTruncated ? <option disabled>More owners not shown</option> : null}\n </select>\n </label>\n <label>\n <span>Type</span>\n <select onChange={(event) => update(\"type\", event.currentTarget.value)} value={filters.type}>\n <option value=\"all\">All types</option>\n {entityKinds.map((kind) => (\n <option key={kind} value={kind}>\n {labelForKind(kind)}\n </option>\n ))}\n </select>\n </label>\n <label>\n <span>Status</span>\n <select onChange={(event) => update(\"status\", event.currentTarget.value)} value={filters.status}>\n <option value=\"all\">Any status</option>\n <option value=\"active\">Active</option>\n <option value=\"done\">Done</option>\n <option value=\"failed\">Needs attention</option>\n </select>\n </label>\n </section>\n\n {selectedEntityId === null ? null : selectedItem === null ? (\n <div id=\"item-details\">\n <StatePanel\n action={<Button onClick={clearSelection}>Back to items</Button>}\n description=\"This item is not present in the current bounded workspace index. It may have been deleted or fall outside this result prefix.\"\n title=\"Item unavailable\"\n tone=\"caution\"\n />\n </div>\n ) : (\n <Surface as=\"section\" className={styles.selection} id=\"item-details\" padding=\"spacious\" tone=\"secondary\">\n <div className={styles.selectionHeader}>\n <ServiceMark service={selectedItem.service} size=\"compact\" />\n <StateLabel label={selectedItem.status} size=\"compact\" tone={selectedItem.tone} />\n </div>\n <Text as=\"p\" tone=\"secondary\" variant=\"label\">\n {selectedItem.key} · {labelForKind(selectedItem.kind)}\n </Text>\n <Text as=\"h2\" variant=\"section-title\">\n {selectedItem.title}\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n {workspaceItemMembershipDescription(selectedItem)}\n </Text>\n <ItemOwners item={selectedItem} />\n {shareOwnerPersonId === null ? null : (\n <AuthorizedSharePanel\n key={selectedItem.entityId}\n currentPersonId={shareOwnerPersonId}\n entityId={selectedItem.entityId}\n grantees={controller.state.ownerOptions}\n workspaceId={context.workspaceId}\n {...(shareTransport === undefined ? {} : { transport: shareTransport })}\n />\n )}\n <div className={styles.selectionActions}>\n <div className={styles.membershipChoices}>\n {selectedItem.routableReleaseIds.map((releaseId) => {\n const release = releaseById.get(releaseId)\n return (\n <Link\n key={releaseId}\n state={makeReleaseRouteState(context.workspaceId, releaseId, releaseOriginFromLocation(location))}\n to={workspaceItemReleaseHref(context.workspaceId, releaseId, selectedItem.entityId)}\n >\n Open {release === undefined ? `release ${releaseId.slice(-6)}` : release.relay.codename}\n {release === undefined ? null : <span>{release.version}</span>}\n </Link>\n )\n })}\n </div>\n <Button onClick={clearSelection}>Back to items</Button>\n </div>\n </Surface>\n )}\n\n <div className={styles.resultHeading} id=\"results\">\n <Text as=\"h2\" variant=\"section-title\">\n {controller.state.matchedCount} of {controller.state.totalCount} workspace items\n </Text>\n <StateLabel\n label={\n controller.state.refreshing\n ? \"Updating results\"\n : controller.state.truncated\n ? \"Bounded workspace result\"\n : \"Workspace scope\"\n }\n size=\"compact\"\n tone={controller.state.truncated && !controller.state.refreshing ? \"caution\" : \"neutral\"}\n />\n </div>\n\n {visibleItems.length === 0 ? (\n <StatePanel\n action={<Button onClick={() => replaceSearch(new URLSearchParams())}>Clear filters</Button>}\n description=\"Try a broader word, owner, service, type, or status. No demo object is substituted.\"\n title=\"No matching items\"\n />\n ) : (\n <div className={styles.items}>\n {visibleItems.map((item) => (\n <Surface as=\"article\" className={styles.item} key={item.entityId} padding=\"none\" tone=\"secondary\">\n <ServiceMark service={item.service} size=\"compact\" />\n <Link\n className={styles.itemLink}\n onClick={(event) => {\n if (shouldRememberWorkspaceScrollPosition(event, event.currentTarget.target)) {\n rememberWorkspaceScrollPosition(location, item.href)\n }\n }}\n state={makeWorkspaceEntityRouteState(\n location.state,\n context.workspaceId,\n item.entityId,\n entityOriginFromLocation(location)\n )}\n to={item.href}\n >\n <span>{item.key}</span>\n <strong>{item.title}</strong>\n </Link>\n <div className={styles.meta}>\n <StateLabel label={item.status} size=\"compact\" tone={item.tone} />\n <span>{labelForKind(item.kind)}</span>\n <span>\n {item.releaseIds.length === 0\n ? \"Unlinked\"\n : `${item.releaseIds.length}${item.releaseMembershipsTruncated ? \"+\" : \"\"} release${item.releaseIds.length === 1 ? \"\" : \"s\"}`}\n </span>\n <ItemOwners item={item} />\n <time dateTime={item.freshness} title={`Synchronized ${item.freshness}`}>\n {formatItemFreshness(item.freshness)}\n </time>\n </div>\n {shareOwnerPersonId === null ? null : (\n <Link\n className={styles.shareLink}\n to={unlinkedItemLocation(location.pathname, searchParams, item.entityId)}\n >\n Share\n </Link>\n )}\n </Surface>\n ))}\n </div>\n )}\n </article>\n )\n}\n"],"mappings":"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"}
|
package/dist/client/assets/{OpenPullRequestPage-BYoRmtui.js → OpenPullRequestPage-DdL7PhKZ.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{o as n}from"./hooks-K-sIfGqH.js";import{t as r}from"./jsx-runtime-NZYk81nU.js";import{g as i,r as a}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{p as o}from"./index-
|
|
2
|
-
//# sourceMappingURL=OpenPullRequestPage-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{o as n}from"./hooks-K-sIfGqH.js";import{t as r}from"./jsx-runtime-NZYk81nU.js";import{g as i,r as a}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{p as o}from"./index-kmYFvwT0.js";import{n as s,t as c}from"./primitives-DYGtIZqB-r-Glkv2i.js";import{Oa as l,Ya as u,nr as d}from"./agent-api-CUWP1qs8.js";import{n as f}from"./Domain-cJ5aJFpE.js";import{n as p}from"./workspaceEntityPaths-xAl2jRFm.js";import{browserOpenPullRequestTransport as m}from"./openPullRequest-BMlmibLP.js";var h=e(t(),1),g={page:`_page_1u3g0_1`,hero:`_hero_1u3g0_2`,form:`_form_1u3g0_3`,matches:`_matches_1u3g0_4`,card:`_card_1u3g0_23`},_=r(),v=({transport:e=m}={})=>{let t=o(),r=n(),[v,y]=(0,h.useState)(``),[b,x]=(0,h.useState)(``),[S,C]=(0,h.useState)({_tag:`idle`}),[w,T]=(0,h.useState)(0),E=t.state._tag===`authenticated`||t.state._tag===`storage-unavailable`?t.state.session:null,D=t.state._tag===`authenticated`&&(t.state.session.permission===`workspace-owner`||t.state.session.permission===`workspace-approver`)?t.state.session:null;return(0,h.useEffect)(()=>{if(b.length===0){C({_tag:`idle`});return}if(D===null)return;let n=l(d(f)(b));if(n===null){C({_tag:`invalid`});return}let i=new AbortController;return C({_tag:`loading`}),e.resolve(n,i.signal).then(e=>{if(!i.signal.aborted){if(e._tag===`found`){r(p(D.workspaceId,e.candidate.entityId),{replace:!0});return}C(e)}},e=>{if(!i.signal.aborted){if(u(`UnauthorizedApiError`)(e)){t.invalidateSession(D.sessionId);return}C({_tag:`failed`})}}),()=>i.abort()},[t,w,r,b,D,e]),E===null?(0,_.jsx)(i,{description:`Pair this browser with Control Center before resolving a private CodeCommit pull request.`,title:`Browser session required`,tone:`caution`}):t.state._tag===`storage-unavailable`?(0,_.jsx)(i,{description:`Enable session storage, then pair this browser again before resolving a private CodeCommit pull request.`,title:`Browser storage required`,tone:`caution`}):D===null?(0,_.jsx)(i,{description:`Opening a shared CodeCommit PR requires workspace-wide read access.`,title:`Workspace reader required`,tone:`caution`}):(0,_.jsxs)(`section`,{className:g.page,children:[(0,_.jsxs)(`header`,{className:g.hero,children:[(0,_.jsx)(s,{as:`h1`,variant:`page-title`,children:`Open CodeCommit PR`}),(0,_.jsx)(s,{tone:`secondary`,variant:`body-large`,children:`Paste a CodeCommit PR URL from any AWS region. Control Center resolves it inside this workspace; no PR search required.`})]}),(0,_.jsx)(c,{as:`section`,className:g.card,form:`grouped`,padding:`spacious`,tone:`secondary`,children:(0,_.jsxs)(`form`,{className:g.form,onSubmit:e=>{e.preventDefault();let t=v.trim();x(t),T(e=>e+1)},children:[(0,_.jsxs)(`label`,{children:[(0,_.jsx)(`span`,{children:`Pull request URL`}),(0,_.jsx)(`input`,{autoComplete:`url`,onChange:e=>y(e.currentTarget.value),placeholder:`https://REGION.console.aws.amazon.com/codesuite/codecommit/repositories/…`,spellCheck:!1,type:`url`,value:v})]}),(0,_.jsx)(a,{loading:S._tag===`loading`,size:`principal`,type:`submit`,variant:`primary`,children:`Open pull request`})]})}),S._tag===`invalid`?(0,_.jsx)(i,{description:`Use the full AWS CodeCommit pull-request console URL.`,title:`Link not recognized`,tone:`caution`}):S._tag===`failed`?(0,_.jsx)(i,{description:`The workspace index could not be read. Nothing was changed.`,title:`Lookup failed`,tone:`caution`}):S._tag===`not-found`?(0,_.jsx)(i,{description:S.indexTruncated?`The bounded workspace result was incomplete. Narrow the followed CodeCommit resources, then retry.`:`This PR is not synchronized into the current workspace yet. Follow its CodeCommit account or repository, then retry.`,title:`PR not found`,tone:`neutral`}):S._tag===`account-identity-unavailable`?(0,_.jsx)(i,{description:`Control Center could not map every match to a browser-safe AWS account identity. Refresh Services, then retry.`,title:`Account identity unavailable`,tone:`caution`}):S._tag===`ambiguous`?(0,_.jsxs)(c,{as:`section`,className:g.matches,form:`grouped`,padding:`spacious`,tone:`secondary`,children:[(0,_.jsx)(s,{as:`h2`,variant:`section-title`,children:`Choose the connected account`}),(0,_.jsx)(s,{tone:`secondary`,variant:`body`,children:`AWS Console links omit the account. These followed connections contain the same repository and PR number.`}),S.candidates.map(e=>(0,_.jsx)(a,{onClick:()=>r(p(D.workspaceId,e.entityId)),variant:`secondary`,children:`${e.accountLabel} · ${e.title}`},e.entityId))]}):null]})};export{v as OpenPullRequestPage};
|
|
2
|
+
//# sourceMappingURL=OpenPullRequestPage-DdL7PhKZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenPullRequestPage-BYoRmtui.js","names":[],"sources":["../../../src/client/openPullRequest/OpenPullRequestPage.module.css","../../../src/client/openPullRequest/OpenPullRequestPage.tsx"],"sourcesContent":[".page,\n.hero,\n.form,\n.matches {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero,\n.matches {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > *,\n.matches > * {\n margin: 0;\n}\n\n.card {\n max-inline-size: 52rem;\n}\n\n.form {\n gap: var(--rly-space-16);\n}\n\n.form label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.form input {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.form input:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n","import * as Domain from \"@knpkv/codecommit-core/Domain.js\"\nimport { Button, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport { type FormEvent, type ReactElement, useEffect, useState } from \"react\"\nimport { useNavigate } from \"react-router\"\n\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\nimport {\n browserOpenPullRequestTransport,\n type OpenPullRequestResolution,\n type OpenPullRequestTransport\n} from \"./openPullRequest.js\"\nimport styles from \"./OpenPullRequestPage.module.css\"\n\ntype LookupState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"invalid\" }\n | { readonly _tag: \"failed\" }\n | OpenPullRequestResolution\n\nexport interface OpenPullRequestPageProps {\n readonly transport?: OpenPullRequestTransport\n}\n\n/** Open one followed CodeCommit PR from the console URL another person shared. */\nexport const OpenPullRequestPage = ({\n transport = browserOpenPullRequestTransport\n}: OpenPullRequestPageProps = {}): ReactElement => {\n const browserSession = useBrowserSession()\n const navigate = useNavigate()\n const [input, setInput] = useState(\"\")\n const [requestedUrl, setRequestedUrl] = useState(\"\")\n const [lookup, setLookup] = useState<LookupState>({ _tag: \"idle\" })\n const [lookupAttempt, setLookupAttempt] = useState(0)\n const readableSession =\n browserSession.state._tag === \"authenticated\" || browserSession.state._tag === \"storage-unavailable\"\n ? browserSession.state.session\n : null\n const session =\n browserSession.state._tag === \"authenticated\" &&\n (browserSession.state.session.permission === \"workspace-owner\" ||\n browserSession.state.session.permission === \"workspace-approver\")\n ? browserSession.state.session\n : null\n\n useEffect(() => {\n if (requestedUrl.length === 0) {\n setLookup({ _tag: \"idle\" })\n return\n }\n if (session === null) return\n const locator = Option.getOrNull(Schema.decodeUnknownOption(Domain.CodeCommitPullRequestUrl)(requestedUrl))\n if (locator === null) {\n setLookup({ _tag: \"invalid\" })\n return\n }\n const abort = new AbortController()\n setLookup({ _tag: \"loading\" })\n transport.resolve(locator, abort.signal).then(\n (resolution) => {\n if (abort.signal.aborted) return\n if (resolution._tag === \"found\") {\n navigate(workspaceEntityPath(session.workspaceId, resolution.candidate.entityId), { replace: true })\n return\n }\n setLookup(resolution)\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) {\n browserSession.invalidateSession(session.sessionId)\n return\n }\n setLookup({ _tag: \"failed\" })\n }\n )\n return () => abort.abort()\n }, [browserSession, lookupAttempt, navigate, requestedUrl, session, transport])\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n const url = input.trim()\n setRequestedUrl(url)\n setLookupAttempt((current) => current + 1)\n }\n\n if (readableSession === null) {\n return (\n <StatePanel\n description=\"Pair this browser with Control Center before resolving a private CodeCommit pull request.\"\n title=\"Browser session required\"\n tone=\"caution\"\n />\n )\n }\n\n if (browserSession.state._tag === \"storage-unavailable\") {\n return (\n <StatePanel\n description=\"Enable session storage, then pair this browser again before resolving a private CodeCommit pull request.\"\n title=\"Browser storage required\"\n tone=\"caution\"\n />\n )\n }\n\n if (session === null) {\n return (\n <StatePanel\n description=\"Opening a shared CodeCommit PR requires workspace-wide read access.\"\n title=\"Workspace reader required\"\n tone=\"caution\"\n />\n )\n }\n\n return (\n <section className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"h1\" variant=\"page-title\">\n Open CodeCommit PR\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Paste a CodeCommit PR URL from any AWS region. Control Center resolves it inside this workspace; no PR search\n required.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.card} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <form className={styles.form} onSubmit={submit}>\n <label>\n <span>Pull request URL</span>\n <input\n autoComplete=\"url\"\n onChange={(event) => setInput(event.currentTarget.value)}\n placeholder=\"https://REGION.console.aws.amazon.com/codesuite/codecommit/repositories/…\"\n spellCheck={false}\n type=\"url\"\n value={input}\n />\n </label>\n <Button loading={lookup._tag === \"loading\"} size=\"principal\" type=\"submit\" variant=\"primary\">\n Open pull request\n </Button>\n </form>\n </Surface>\n {lookup._tag === \"invalid\" ? (\n <StatePanel\n description=\"Use the full AWS CodeCommit pull-request console URL.\"\n title=\"Link not recognized\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"failed\" ? (\n <StatePanel\n description=\"The workspace index could not be read. Nothing was changed.\"\n title=\"Lookup failed\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"not-found\" ? (\n <StatePanel\n description={\n lookup.indexTruncated\n ? \"The bounded workspace result was incomplete. Narrow the followed CodeCommit resources, then retry.\"\n : \"This PR is not synchronized into the current workspace yet. Follow its CodeCommit account or repository, then retry.\"\n }\n title=\"PR not found\"\n tone=\"neutral\"\n />\n ) : lookup._tag === \"account-identity-unavailable\" ? (\n <StatePanel\n description=\"Control Center could not map every match to a browser-safe AWS account identity. Refresh Services, then retry.\"\n title=\"Account identity unavailable\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"ambiguous\" ? (\n <Surface as=\"section\" className={styles.matches} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <Text as=\"h2\" variant=\"section-title\">\n Choose the connected account\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n AWS Console links omit the account. These followed connections contain the same repository and PR number.\n </Text>\n {lookup.candidates.map((candidate) => (\n <Button\n key={candidate.entityId}\n onClick={() => navigate(workspaceEntityPath(session.workspaceId, candidate.entityId))}\n variant=\"secondary\"\n >\n {`${candidate.accountLabel} · ${candidate.title}`}\n </Button>\n ))}\n </Surface>\n ) : null}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"OpenPullRequestPage-DdL7PhKZ.js","names":[],"sources":["../../../src/client/openPullRequest/OpenPullRequestPage.module.css","../../../src/client/openPullRequest/OpenPullRequestPage.tsx"],"sourcesContent":[".page,\n.hero,\n.form,\n.matches {\n display: grid;\n}\n\n.page {\n gap: var(--rly-space-32);\n}\n\n.hero,\n.matches {\n gap: var(--rly-space-8);\n max-inline-size: 52rem;\n}\n\n.hero > *,\n.matches > * {\n margin: 0;\n}\n\n.card {\n max-inline-size: 52rem;\n}\n\n.form {\n gap: var(--rly-space-16);\n}\n\n.form label {\n display: grid;\n gap: var(--rly-space-6);\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}\n\n.form input {\n min-block-size: 3.5rem;\n inline-size: 100%;\n padding-inline: var(--rly-space-16);\n border: 1px solid var(--rly-color-border-2);\n border-radius: var(--rly-radius-control);\n background: var(--rly-color-surface-1);\n color: var(--rly-color-text-1);\n font: inherit;\n}\n\n.form input:focus-visible {\n outline: 2px solid var(--rly-color-focus);\n outline-offset: var(--rly-space-2);\n}\n","import * as Domain from \"@knpkv/codecommit-core/Domain.js\"\nimport { Button, StatePanel, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Option from \"effect/Option\"\nimport * as Predicate from \"effect/Predicate\"\nimport * as Schema from \"effect/Schema\"\nimport { type FormEvent, type ReactElement, useEffect, useState } from \"react\"\nimport { useNavigate } from \"react-router\"\n\nimport { useBrowserSession } from \"../BrowserSession.js\"\nimport { workspaceEntityPath } from \"../workspaceEntityPaths.js\"\nimport {\n browserOpenPullRequestTransport,\n type OpenPullRequestResolution,\n type OpenPullRequestTransport\n} from \"./openPullRequest.js\"\nimport styles from \"./OpenPullRequestPage.module.css\"\n\ntype LookupState =\n | { readonly _tag: \"idle\" }\n | { readonly _tag: \"loading\" }\n | { readonly _tag: \"invalid\" }\n | { readonly _tag: \"failed\" }\n | OpenPullRequestResolution\n\nexport interface OpenPullRequestPageProps {\n readonly transport?: OpenPullRequestTransport\n}\n\n/** Open one followed CodeCommit PR from the console URL another person shared. */\nexport const OpenPullRequestPage = ({\n transport = browserOpenPullRequestTransport\n}: OpenPullRequestPageProps = {}): ReactElement => {\n const browserSession = useBrowserSession()\n const navigate = useNavigate()\n const [input, setInput] = useState(\"\")\n const [requestedUrl, setRequestedUrl] = useState(\"\")\n const [lookup, setLookup] = useState<LookupState>({ _tag: \"idle\" })\n const [lookupAttempt, setLookupAttempt] = useState(0)\n const readableSession =\n browserSession.state._tag === \"authenticated\" || browserSession.state._tag === \"storage-unavailable\"\n ? browserSession.state.session\n : null\n const session =\n browserSession.state._tag === \"authenticated\" &&\n (browserSession.state.session.permission === \"workspace-owner\" ||\n browserSession.state.session.permission === \"workspace-approver\")\n ? browserSession.state.session\n : null\n\n useEffect(() => {\n if (requestedUrl.length === 0) {\n setLookup({ _tag: \"idle\" })\n return\n }\n if (session === null) return\n const locator = Option.getOrNull(Schema.decodeUnknownOption(Domain.CodeCommitPullRequestUrl)(requestedUrl))\n if (locator === null) {\n setLookup({ _tag: \"invalid\" })\n return\n }\n const abort = new AbortController()\n setLookup({ _tag: \"loading\" })\n transport.resolve(locator, abort.signal).then(\n (resolution) => {\n if (abort.signal.aborted) return\n if (resolution._tag === \"found\") {\n navigate(workspaceEntityPath(session.workspaceId, resolution.candidate.entityId), { replace: true })\n return\n }\n setLookup(resolution)\n },\n (failure) => {\n if (abort.signal.aborted) return\n if (Predicate.isTagged(\"UnauthorizedApiError\")(failure)) {\n browserSession.invalidateSession(session.sessionId)\n return\n }\n setLookup({ _tag: \"failed\" })\n }\n )\n return () => abort.abort()\n }, [browserSession, lookupAttempt, navigate, requestedUrl, session, transport])\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n const url = input.trim()\n setRequestedUrl(url)\n setLookupAttempt((current) => current + 1)\n }\n\n if (readableSession === null) {\n return (\n <StatePanel\n description=\"Pair this browser with Control Center before resolving a private CodeCommit pull request.\"\n title=\"Browser session required\"\n tone=\"caution\"\n />\n )\n }\n\n if (browserSession.state._tag === \"storage-unavailable\") {\n return (\n <StatePanel\n description=\"Enable session storage, then pair this browser again before resolving a private CodeCommit pull request.\"\n title=\"Browser storage required\"\n tone=\"caution\"\n />\n )\n }\n\n if (session === null) {\n return (\n <StatePanel\n description=\"Opening a shared CodeCommit PR requires workspace-wide read access.\"\n title=\"Workspace reader required\"\n tone=\"caution\"\n />\n )\n }\n\n return (\n <section className={styles.page}>\n <header className={styles.hero}>\n <Text as=\"h1\" variant=\"page-title\">\n Open CodeCommit PR\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Paste a CodeCommit PR URL from any AWS region. Control Center resolves it inside this workspace; no PR search\n required.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.card} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <form className={styles.form} onSubmit={submit}>\n <label>\n <span>Pull request URL</span>\n <input\n autoComplete=\"url\"\n onChange={(event) => setInput(event.currentTarget.value)}\n placeholder=\"https://REGION.console.aws.amazon.com/codesuite/codecommit/repositories/…\"\n spellCheck={false}\n type=\"url\"\n value={input}\n />\n </label>\n <Button loading={lookup._tag === \"loading\"} size=\"principal\" type=\"submit\" variant=\"primary\">\n Open pull request\n </Button>\n </form>\n </Surface>\n {lookup._tag === \"invalid\" ? (\n <StatePanel\n description=\"Use the full AWS CodeCommit pull-request console URL.\"\n title=\"Link not recognized\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"failed\" ? (\n <StatePanel\n description=\"The workspace index could not be read. Nothing was changed.\"\n title=\"Lookup failed\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"not-found\" ? (\n <StatePanel\n description={\n lookup.indexTruncated\n ? \"The bounded workspace result was incomplete. Narrow the followed CodeCommit resources, then retry.\"\n : \"This PR is not synchronized into the current workspace yet. Follow its CodeCommit account or repository, then retry.\"\n }\n title=\"PR not found\"\n tone=\"neutral\"\n />\n ) : lookup._tag === \"account-identity-unavailable\" ? (\n <StatePanel\n description=\"Control Center could not map every match to a browser-safe AWS account identity. Refresh Services, then retry.\"\n title=\"Account identity unavailable\"\n tone=\"caution\"\n />\n ) : lookup._tag === \"ambiguous\" ? (\n <Surface as=\"section\" className={styles.matches} form=\"grouped\" padding=\"spacious\" tone=\"secondary\">\n <Text as=\"h2\" variant=\"section-title\">\n Choose the connected account\n </Text>\n <Text tone=\"secondary\" variant=\"body\">\n AWS Console links omit the account. These followed connections contain the same repository and PR number.\n </Text>\n {lookup.candidates.map((candidate) => (\n <Button\n key={candidate.entityId}\n onClick={() => navigate(workspaceEntityPath(session.workspaceId, candidate.entityId))}\n variant=\"secondary\"\n >\n {`${candidate.accountLabel} · ${candidate.title}`}\n </Button>\n ))}\n </Surface>\n ) : null}\n </section>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{o as n}from"./hooks-K-sIfGqH.js";import{a as r}from"./lib-6h955hh9.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{l as a,r as o}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{p as s}from"./index-
|
|
2
|
-
//# sourceMappingURL=PairPage-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{o as n}from"./hooks-K-sIfGqH.js";import{a as r}from"./lib-6h955hh9.js";import{t as i}from"./jsx-runtime-NZYk81nU.js";import{l as a,r as o}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{p as s}from"./index-kmYFvwT0.js";import{n as c,t as l}from"./primitives-DYGtIZqB-r-Glkv2i.js";import{Ga as u,Ja as d,Ti as f,_i as p,f as m,ki as h,mi as g,tr as _}from"./agent-api-CUWP1qs8.js";import{a as v,t as y}from"./client-D3WRV6yl.js";import{c as b,u as x}from"./serviceOnboarding-F9Lj6a7y.js";import{t as S}from"./pages.module-CpW6k_pw.js";var C=e(t(),1),w=new Set([`ConflictApiError`,`InvalidRequestApiError`,`ParseError`,`UnauthorizedApiError`]),T=e=>{if(u(e,`_tag`))return d(e._tag)?e._tag:void 0},E=e=>{let t=T(e);return t!==void 0&&w.has(t)?`That code is invalid, expired, or already used.`:t===`ForbiddenApiError`?`Pairing is blocked on this connection. Open Control Center through trusted HTTPS and try again.`:`Control Center is unavailable right now. Check that the server is running, then try again.`},D=i(),O=g(`PairPage.pairBrowser`)(e=>p(function*(){let t=yield*_(m)(e.trim());return yield*(yield*y()).session.pair({payload:{pairingCode:t}})}).pipe(f(v))),k=e=>e===null?`/`:x(e),A=()=>{let e=n(),[t]=r(),{establishSession:i}=s(),[u,d]=(0,C.useState)(``),[f,p]=(0,C.useState)(),[m,g]=(0,C.useState)(!1);return(0,D.jsxs)(`section`,{"aria-labelledby":`pair-title`,className:S.page,children:[(0,D.jsxs)(`header`,{className:S.sectionHeading,children:[(0,D.jsx)(c,{as:`h1`,id:`pair-title`,variant:`page-title`,children:`Pair this browser`}),(0,D.jsx)(c,{tone:`secondary`,variant:`body-large`,children:`Use the one-time code printed by the local Control Center server. It expires after ten minutes.`})]}),(0,D.jsx)(l,{as:`section`,className:S.pairCard,padding:`spacious`,form:`grouped`,tone:`secondary`,children:(0,D.jsxs)(`form`,{className:S.pairForm,onSubmit:n=>{n.preventDefault(),p(void 0),g(!0),h(O(u)).then(n=>{i(n.csrfToken,n.session);let r=b(t,`service`);e(k(r),{replace:!0})},e=>{p(E(e)),g(!1)})},children:[(0,D.jsx)(a,{description:`The code stays in this request and is never placed in a URL.`,label:`Pairing code`,required:!0,...f===void 0?{}:{error:f},children:e=>(0,D.jsx)(`input`,{...e,autoComplete:`one-time-code`,inputMode:`text`,maxLength:64,onChange:e=>d(e.currentTarget.value),spellCheck:!1,value:u})}),(0,D.jsx)(o,{disabled:u.trim().length!==64,loading:m,size:`principal`,type:`submit`,variant:`primary`,children:`Pair browser`})]})})]})};export{A as PairPage,k as pairedBrowserDestination};
|
|
2
|
+
//# sourceMappingURL=PairPage-BCtzYqK6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PairPage-
|
|
1
|
+
{"version":3,"file":"PairPage-BCtzYqK6.js","names":[],"sources":["../../../src/client/PairingFailure.ts","../../../src/client/PairPage.tsx"],"sourcesContent":["import * as Predicate from \"effect/Predicate\"\n\nconst CREDENTIAL_FAILURE_TAGS = new Set([\n \"ConflictApiError\",\n \"InvalidRequestApiError\",\n \"ParseError\",\n \"UnauthorizedApiError\"\n])\n\nconst failureTag = <UnparsedInput>(failure: UnparsedInput): string | undefined => {\n if (!Predicate.hasProperty(failure, \"_tag\")) return undefined\n return Predicate.isString(failure._tag) ? failure._tag : undefined\n}\n\n/** Convert pairing failures into honest, actionable browser copy. */\nexport const pairingFailureMessage = <UnparsedInput>(failure: UnparsedInput): string => {\n const tag = failureTag(failure)\n if (tag !== undefined && CREDENTIAL_FAILURE_TAGS.has(tag)) {\n return \"That code is invalid, expired, or already used.\"\n }\n if (tag === \"ForbiddenApiError\") {\n return \"Pairing is blocked on this connection. Open Control Center through trusted HTTPS and try again.\"\n }\n return \"Control Center is unavailable right now. Check that the server is running, then try again.\"\n}\n","import { Button, Field, Surface, Text } from \"@knpkv/rly/primitives\"\nimport * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\"\nimport { type FormEvent, type ReactElement, useState } from \"react\"\nimport { useNavigate, useSearchParams } from \"react-router\"\n\nimport { makeControlCenterApiClient } from \"../api/client.js\"\nimport { PairingCode } from \"../api/session.js\"\nimport type { ProviderId } from \"../domain/sourceRevision.js\"\nimport { useBrowserSession } from \"./BrowserSession.js\"\nimport { pairingFailureMessage } from \"./PairingFailure.js\"\nimport { selectedServiceProvider, serviceSetupPath } from \"./services/serviceOnboarding.js\"\nimport styles from \"./pages.module.css\"\n\nconst pairBrowser = Effect.fn(\"PairPage.pairBrowser\")((rawPairingCode: string) =>\n Effect.gen(function* () {\n const pairingCode = yield* Schema.decodeUnknownEffect(PairingCode)(rawPairingCode.trim())\n const client = yield* makeControlCenterApiClient()\n return yield* client.session.pair({ payload: { pairingCode } })\n }).pipe(Effect.provide(FetchHttpClient.layer))\n)\n\n/** Preserve explicit service onboarding while ordinary pairing resolves workspace settings. */\nexport const pairedBrowserDestination = (selectedProvider: ProviderId | null): string =>\n selectedProvider === null ? \"/\" : serviceSetupPath(selectedProvider)\n\n/** Pair the current tab without ever exposing the opaque session cookie to JavaScript. */\nexport const PairPage = (): ReactElement => {\n const navigate = useNavigate()\n const [searchParams] = useSearchParams()\n const { establishSession } = useBrowserSession()\n const [pairingCode, setPairingCode] = useState(\"\")\n const [error, setError] = useState<string | undefined>()\n const [isPairing, setIsPairing] = useState(false)\n\n const submit = (event: FormEvent<HTMLFormElement>): void => {\n event.preventDefault()\n setError(undefined)\n setIsPairing(true)\n Effect.runPromise(pairBrowser(pairingCode)).then(\n (result) => {\n establishSession(result.csrfToken, result.session)\n const selectedProvider = selectedServiceProvider(searchParams, \"service\")\n navigate(pairedBrowserDestination(selectedProvider), { replace: true })\n },\n (failure) => {\n setError(pairingFailureMessage(failure))\n setIsPairing(false)\n }\n )\n }\n\n return (\n <section aria-labelledby=\"pair-title\" className={styles.page}>\n <header className={styles.sectionHeading}>\n <Text as=\"h1\" id=\"pair-title\" variant=\"page-title\">\n Pair this browser\n </Text>\n <Text tone=\"secondary\" variant=\"body-large\">\n Use the one-time code printed by the local Control Center server. It expires after ten minutes.\n </Text>\n </header>\n <Surface as=\"section\" className={styles.pairCard} padding=\"spacious\" form=\"grouped\" tone=\"secondary\">\n <form className={styles.pairForm} onSubmit={submit}>\n <Field\n description=\"The code stays in this request and is never placed in a URL.\"\n label=\"Pairing code\"\n required\n {...(error === undefined ? {} : { error })}\n >\n {(controlProps) => (\n <input\n {...controlProps}\n autoComplete=\"one-time-code\"\n inputMode=\"text\"\n maxLength={64}\n onChange={(event) => setPairingCode(event.currentTarget.value)}\n spellCheck={false}\n value={pairingCode}\n />\n )}\n </Field>\n <Button\n disabled={pairingCode.trim().length !== 64}\n loading={isPairing}\n size=\"principal\"\n type=\"submit\"\n variant=\"primary\"\n >\n Pair browser\n </Button>\n </form>\n </Surface>\n </section>\n )\n}\n"],"mappings":"6nBAEM,EAA0B,IAAI,IAAI,CACtC,mBACA,yBACA,aACA,sBACF,CAAC,EAEK,EAA6B,GAA+C,CAC3E,KAAsB,EAAS,MAAM,EAC1C,OAAO,EAAmB,EAAQ,IAAI,EAAI,EAAQ,KAAO,IAAA,EAC3D,EAGa,EAAwC,GAAmC,CACtF,IAAM,EAAM,EAAW,CAAO,EAO9B,OANI,IAAQ,IAAA,IAAa,EAAwB,IAAI,CAAG,EAC/C,kDAEL,IAAQ,oBACH,kGAEF,4FACT,QCTM,EAAc,EAAU,sBAAsB,CAAC,CAAE,GACrD,EAAW,WAAa,CACtB,IAAM,EAAc,MAAO,EAA2B,CAAW,CAAC,CAAC,EAAe,KAAK,CAAC,EAExF,OAAO,OAAO,MADQ,EAA2B,EAAA,CAC5B,QAAQ,KAAK,CAAE,QAAS,CAAE,aAAY,CAAE,CAAC,CAChE,CAAC,CAAC,CAAC,KAAK,EAAe,CAAqB,CAAC,CAC/C,EAGa,EAA4B,GACvC,IAAqB,KAAO,IAAM,EAAiB,CAAgB,EAGxD,MAA+B,CAC1C,IAAM,EAAW,EAAY,EACvB,CAAC,GAAgB,EAAgB,EACjC,CAAE,oBAAqB,EAAkB,EACzC,CAAC,EAAa,IAAA,EAAkB,EAAA,SAAA,CAAS,EAAE,EAC3C,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAA6B,EACjD,CAAC,EAAW,IAAA,EAAgB,EAAA,SAAA,CAAS,EAAK,EAmBhD,OACE,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,kBAAgB,aAAa,UAAW,EAAO,KAAxD,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAW,EAAO,eAA1B,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAM,GAAG,KAAK,GAAG,aAAa,QAAQ,aAAa,SAAA,mBAE7C,CAAA,GACN,EAAA,EAAA,IAAA,CAAC,EAAD,CAAM,KAAK,YAAY,QAAQ,aAAa,SAAA,iGAEtC,CAAA,CACA,CACR,CAAA,GAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CAAS,GAAG,UAAU,UAAW,EAAO,SAAU,QAAQ,WAAW,KAAK,UAAU,KAAK,YACvF,UAAA,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAU,SA5BxB,GAA4C,CAC1D,EAAM,eAAe,EACrB,EAAS,IAAA,EAAS,EAClB,EAAa,EAAI,EACjB,EAAkB,EAAY,CAAW,CAAC,CAAC,CAAC,KACzC,GAAW,CACV,EAAiB,EAAO,UAAW,EAAO,OAAO,EACjD,IAAM,EAAmB,EAAwB,EAAc,SAAS,EACxE,EAAS,EAAyB,CAAgB,EAAG,CAAE,QAAS,EAAK,CAAC,CACxE,EACC,GAAY,CACX,EAAS,EAAsB,CAAO,CAAC,EACvC,EAAa,EAAK,CACpB,CACF,CACF,EAaM,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,YAAY,+DACZ,MAAM,eACN,SAAA,GACA,GAAK,IAAU,IAAA,GAAY,CAAC,EAAI,CAAE,OAAM,EAEtC,SAAA,IACA,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,GAAI,EACJ,aAAa,gBACb,UAAU,OACV,UAAW,GACX,SAAW,GAAU,EAAe,EAAM,cAAc,KAAK,EAC7D,WAAY,GACZ,MAAO,CACR,CAAA,CAEE,CAAA,GACP,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,SAAU,EAAY,KAAK,CAAC,CAAC,SAAW,GACxC,QAAS,EACT,KAAK,YACL,KAAK,SACL,QAAQ,UACT,SAAA,cAEO,CAAA,CACJ,GACC,CAAA,CACF,GAEb"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{r as n}from"./hooks-K-sIfGqH.js";import{o as r,s as i,t as a}from"./lib-6h955hh9.js";import{t as o}from"./jsx-runtime-NZYk81nU.js";import{d as s,g as c,r as l,v as u}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{i as ee}from"./releasePaths-XoI2BHX3.js";import{p as d}from"./index-BVikncBH.js";import{d as f,n as p,u as te}from"./patterns-DAeEdyxU.js";import{n as m}from"./primitives-DYGtIZqB-r-Glkv2i.js";import{Ai as ne,Ci as h,Di as g,Fi as _,Ga as re,Hi as v,Ii as ie,Ja as ae,Ki as oe,Mi as se,Ni as y,Pi as ce,Ti as le,Ui as ue,Yi as b,_i as x,bi as de,ca as fe,di as S,ga as pe,ii as me,ma as he,mi as C,ni as w,pi as T,ra as E,xn as D}from"./agent-api-CUWP1qs8.js";import{a as O,t as k}from"./client-D3WRV6yl.js";import{d as A,u as j}from"./serviceOnboarding-F9Lj6a7y.js";import{t as M}from"./pages.module-CpW6k_pw.js";import{c as N}from"./releaseRoutes-h4FVwFvJ.js";import{t as P}from"./useWorkspaceDefaultLanding-DMWfrZfF.js";import{t as F}from"./presentPortfolio-DVP-zqTg.js";var I=e(t(),1),L=o(),R=oe,ge=(e=>ue(t=>y(e(t.getRef(R)))))(e=>e.nextDoubleUnsafe()),_e=e=>e===`workspace-owner`?`Owner browser paired`:`Browser paired`,ve=({anonymousAction:e=`link`}={})=>{let{state:t}=d(),n=(0,I.useRef)(null);return(0,I.useEffect)(()=>{t._tag===`storage-unavailable`&&n.current?.focus()},[t._tag]),t._tag===`anonymous`?e===`status`?(0,L.jsx)(m,{className:M.sessionStatus,tone:`secondary`,variant:`label`,children:`Browser not paired`}):(0,L.jsx)(a,{className:M.linkButton,to:`/pair`,children:`Pair this browser`}):t._tag===`authenticated`?(0,L.jsxs)(m,{className:M.sessionBadge,variant:`label`,children:[(0,L.jsx)(`span`,{"aria-hidden":`true`,children:`✓`}),` `,_e(t.session.permission)]}):t._tag===`storage-unavailable`?(0,L.jsx)(m,{"aria-atomic":`true`,as:`span`,className:M.sessionStatus,ref:n,role:`alert`,tabIndex:-1,tone:`secondary`,variant:`label`,children:t.session===null?`Session storage is unavailable. Check storage permissions or space, then reload.`:`Browser paired, but session storage is unavailable. Check storage permissions or space, then reload.`}):(0,L.jsx)(m,{className:M.sessionStatus,tone:`secondary`,variant:`label`,children:t._tag===`checking`?`Checking this browser…`:t._tag===`blocked`?`Session access blocked on this connection`:`Server unavailable`})},z={all:`All`,attention:`Need attention`,deploying:`Deploying`,shipped:`Shipped`},ye=[`all`,`attention`,`deploying`,`shipped`],be=e=>{let t=new URLSearchParams(e).get(`status`);return t===`attention`||t===`deploying`||t===`shipped`?t:`all`},B=(e,t)=>{let n=new URLSearchParams(e);t===`all`?n.delete(`status`):n.set(`status`,t);let r=n.toString();return r.length===0?``:`?${r}`},xe=(e,t)=>{switch(t){case`all`:return!0;case`attention`:return e.readinessVerdict===`blocked`||e.readinessVerdict===`held`||e.readinessVerdict===`unknown`;case`deploying`:return e.readinessVerdict===`deploying`||e.readinessVerdict===`building`;case`shipped`:return e.readinessVerdict===`shipped`}},V=(e,t)=>e.filter(e=>xe(e,t)),H=e=>ye.map(t=>({count:V(e,t).length,id:t,label:z[t]})),Se=e=>z[e],U=(e,t)=>e===null||t>e?t:e,Ce=(e,t)=>{switch(t._tag){case`clear`:return{_tag:`idle`};case`begin`:return{_tag:`loading`,sessionKey:t.sessionKey};case`failed`:return{_tag:`failed`,sessionKey:t.sessionKey,failure:t.failure};case`initial-snapshot`:return{_tag:`loaded`,awaitingResetSnapshot:!1,connection:{_tag:`connecting`},isSnapshotStale:!1,minimumRefreshCursor:null,sessionKey:t.sessionKey,snapshot:t.snapshot};case`caught-up`:return e._tag!==`loaded`||e.awaitingResetSnapshot||e.minimumRefreshCursor!==null&&e.minimumRefreshCursor>e.snapshot.eventCursor?e:{...e,awaitingResetSnapshot:!1,connection:{_tag:`connected`},isSnapshotStale:!1,minimumRefreshCursor:null};case`stream-snapshot`:return e._tag!==`loaded`||e.minimumRefreshCursor!==null&&t.snapshot.eventCursor<e.minimumRefreshCursor||!e.awaitingResetSnapshot&&t.snapshot.eventCursor<e.snapshot.eventCursor?e:{...e,awaitingResetSnapshot:!1,connection:{_tag:`connected`},isSnapshotStale:!1,minimumRefreshCursor:null,snapshot:t.snapshot};case`invalidated`:return e._tag!==`loaded`||e.awaitingResetSnapshot||t.eventCursor<=e.snapshot.eventCursor?e:{...e,isSnapshotStale:!0,minimumRefreshCursor:U(e.minimumRefreshCursor,t.eventCursor)};case`reset-required`:return e._tag===`loaded`?{...e,awaitingResetSnapshot:!0,isSnapshotStale:!0,minimumRefreshCursor:U(e.minimumRefreshCursor,t.headCursor)}:e;case`reconnecting`:return e._tag===`loaded`?{...e,connection:{_tag:`reconnecting`,attempt:t.attempt},isSnapshotStale:!0}:e;case`offline`:return e._tag===`loaded`?{...e,connection:{_tag:`offline`},isSnapshotStale:!0}:e}},W=e=>e._tag===`loaded`?e.snapshot.eventCursor:null,we=3e4,Te=500,Ee=16,G=class extends b(`PortfolioStreamProtocolError`){},De=class extends b(`PortfolioStreamClosedError`){},K=e=>!re(e,`_tag`)||!ae(e._tag)?`unavailable`:e._tag===`UnauthorizedApiError`?`session-expired`:e._tag===`ForbiddenApiError`?`blocked`:`unavailable`,Oe=(e,t)=>{let n=Math.min(Math.max(e-1,0),Ee),r=Math.min(we,Te*2**n)/2;return Math.max(1,Math.floor(r+r*Math.min(Math.max(t,0),1)))},ke=e=>ge.pipe(de(t=>Oe(e,t)),T(se)),Ae=e=>{if(e.prunedThroughCursor>e.headCursor)return!1;switch(e.reason){case`retention`:return e.requestedCursor<e.prunedThroughCursor;case`cursor-ahead`:return e.requestedCursor>e.headCursor;case`gap`:return e.prunedThroughCursor<=e.requestedCursor&&e.requestedCursor<e.headCursor;case`replay-budget`:return e.requestedCursor<=e.headCursor}},je={isOnline:_(()=>navigator.onLine),waitUntilOnline:ce(()=>navigator.onLine?v:me(e=>{let t=()=>e(v);return window.addEventListener(`online`,t,{once:!0}),_(()=>window.removeEventListener(`online`,t))}))},Me=x(function*(){let e=yield*k();return{loadSnapshot:e.portfolio.snapshot(),openStream:t=>e.liveEvents.stream({headers:{"last-event-id":t},query:{after:t}})}}),q=({failure:e,onSessionExpired:t,sessionKey:n})=>{let r=K(e);return r===`session-expired`&&t(n),{_tag:`failed`,sessionKey:n,failure:r}},Ne=C(`PortfolioLiveController.run`)(function*({connectivity:e,onSessionExpired:t,onState:n,sessionKey:r,transport:i}){let a={_tag:`loading`,sessionKey:r},o=e=>_(()=>{a=Ce(a,e),n(a)}),s=yield*g(i.loadSnapshot);if(he(s))return yield*o({_tag:`failed`,failure:q({failure:s.failure,onSessionExpired:t,sessionKey:r}).failure,sessionKey:r}),yield*h;yield*o({_tag:`initial-snapshot`,sessionKey:r,snapshot:s.success});let c=C(`PortfolioLiveController.refreshSnapshot`)(function*(e){let t=yield*i.loadSnapshot;if(t.eventCursor<e)return yield*S(new G);yield*o({_tag:`stream-snapshot`,snapshot:t})}),l=C(`PortfolioLiveController.consumeStream`)(function*(e,t,n){let r=!1,i=a._tag===`loaded`&&a.awaitingResetSnapshot?a.minimumRefreshCursor:null,s=t,l=e=>{e>s&&(s=e)},u=e=>{switch(e.event){case`portfolio.snapshot`:{if(e.id!==e.data.eventCursor)return S(new G);let t=W(a);return t===null||i!==null&&e.id<i?S(new G):(i===null?l(e.id):s=e.id,i===null&&e.id<t?v:(i=null,o({_tag:`stream-snapshot`,snapshot:e.data})))}case`portfolio.invalidated`:{if(i!==null||e.id!==e.data.eventCursor)return S(new G);l(e.id);let t=W(a);return t===null||e.id<=t?v:o({_tag:`invalidated`,eventCursor:e.id}).pipe(w(c(e.id)))}case`stream.reset-required`:return e.data.requestedCursor!==s||!Ae(e.data)?S(new G):(i=i===null||e.data.headCursor>i?e.data.headCursor:i,o({_tag:`reset-required`,headCursor:i}));case`stream.heartbeat`:if(i!==null)return S(new G);{let t=W(a);return t===null?S(new G):(l(e.data.eventCursor),e.data.eventCursor<=t?o({_tag:`caught-up`}):o({_tag:`invalidated`,eventCursor:e.data.eventCursor}).pipe(w(c(e.data.eventCursor))))}}};return yield*D(e,e=>u(e).pipe(ie(()=>r?v:(r=!0,n)))),yield*S(new De)});return yield*C(`PortfolioLiveController.reconnect`)(function*(){let n=0;for(;;){(yield*e.isOnline)?n>0&&(yield*o({_tag:`reconnecting`,attempt:n}),yield*ke(n)):(yield*o({_tag:`offline`}),yield*e.waitUntilOnline);let s=W(a);if(s===null)return yield*h;let c=yield*g(x(function*(){let e=yield*i.openStream(s);return yield*l(e,s,_(()=>{n=0}))}));if(pe(c))return yield*h;let u=K(c.failure);if(u===`session-expired`||u===`blocked`){let e=q({failure:c.failure,onSessionExpired:t,sessionKey:r});return yield*o({_tag:`failed`,failure:e.failure,sessionKey:r}),yield*h}n+=1}})()}),Pe=e=>Ne(e),Fe=(e,t,n)=>{let[r,i]=(0,I.useState)(0),[a,o]=(0,I.useState)({_tag:`idle`});return(0,I.useEffect)(()=>{if(e===null){o({_tag:`idle`});return}let r=new AbortController,i=!0;o({_tag:`loading`,sessionKey:e});let a=(n,r)=>Pe({connectivity:r,onSessionExpired:t,onState:e=>{i&&o(e)},sessionKey:e,transport:n}),s=n===void 0?T(Me,e=>a(e,je)).pipe(le(O)):a(n.transport,n.connectivity);return ne(s,{signal:r.signal}).then(t=>{!i||fe(t)||E(t.cause)||o({_tag:`failed`,failure:`unavailable`,sessionKey:e})}),()=>{i=!1,r.abort()}},[n,t,r,e]),{retry:(0,I.useCallback)(()=>i(e=>e+1),[]),state:a}},J={root:`_root_10gd5_1`,hero:`_hero_10gd5_6`,heroCopy:`_heroCopy_10gd5_13`,title:`_title_10gd5_18`,lede:`_lede_10gd5_23`,session:`_session_10gd5_28`,liveStatus:`_liveStatus_10gd5_34`,content:`_content_10gd5_42`,readyPortfolio:`_readyPortfolio_10gd5_43`,releaseList:`_releaseList_10gd5_44`,filters:`_filters_10gd5_53`,filter:`_filter_10gd5_53`,filterCount:`_filterCount_10gd5_100`,statePanel:`_statePanel_10gd5_115`,firstService:`_firstService_10gd5_119`,firstServiceCopy:`_firstServiceCopy_10gd5_124`,serviceLauncher:`_serviceLauncher_10gd5_130`,serviceChoice:`_serviceChoice_10gd5_136`,serviceAction:`_serviceAction_10gd5_187`,pairAction:`_pairAction_10gd5_193`,loading:`_loading_10gd5_207`,loadingRail:`_loadingRail_10gd5_213`,releaseEntry:`_releaseEntry_10gd5_219`,stageRail:`_stageRail_10gd5_239`,sourceWarning:`_sourceWarning_10gd5_244`},Ie=(e,t)=>{switch(e._tag){case`connecting`:return{detail:`Connecting to live updates.`,label:`Connecting`,tone:`progress`};case`reconnecting`:return{detail:`Showing the last snapshot; it may be stale.`,label:`Reconnecting`,tone:`caution`};case`offline`:return{detail:`Showing the last snapshot; it may be stale.`,label:`Offline`,tone:`caution`};case`connected`:return t?{detail:`Refreshing the authoritative snapshot.`,label:`Updating`,tone:`progress`}:{detail:`Snapshot up to date.`,label:`Live`,tone:`positive`}}},Le=({connection:e,isSnapshotStale:t})=>{let n=Ie(e,t);return(0,L.jsxs)(`div`,{"aria-atomic":`true`,"aria-live":`polite`,className:J.liveStatus,role:`status`,children:[(0,L.jsx)(s,{label:n.label,size:`compact`,tone:n.tone}),(0,L.jsx)(m,{tone:`tertiary`,variant:`meta`,children:n.detail})]})},Re=()=>(0,L.jsxs)(`section`,{"aria-labelledby":`first-service-title`,className:J.firstService,children:[(0,L.jsxs)(`div`,{className:J.firstServiceCopy,children:[(0,L.jsx)(m,{as:`h2`,id:`first-service-title`,variant:`page-title`,children:`Choose your first service`}),(0,L.jsx)(m,{tone:`secondary`,variant:`body-large`,children:`Enable and verify one source. Its releases, people, and delivery evidence will appear here automatically.`})]}),(0,L.jsx)(`nav`,{"aria-label":`Services available to enable`,className:J.serviceLauncher,children:A.map(e=>(0,L.jsxs)(a,{className:J.serviceChoice,"data-service":e.providerId,to:j(e.providerId),children:[(0,L.jsx)(p,{service:e.providerId}),(0,L.jsx)(`span`,{className:J.serviceAction,children:`Enable`})]},e.providerId))})]}),ze=()=>(0,L.jsxs)(`div`,{className:J.loading,children:[(0,L.jsx)(u,{decorative:!1,height:`1.25rem`,label:`Loading releases`,width:`10rem`}),(0,L.jsx)(u,{decorative:!0,height:`8rem`,variant:`block`}),(0,L.jsxs)(`div`,{className:J.loadingRail,children:[(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`}),(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`}),(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`})]})]}),Y=e=>{switch(e){case`anonymous`:return{description:`Pair this browser to read the workspace portfolio. Release facts never load before authentication.`,title:`Release facts stay private`};case`checking`:return{description:`Control Center is confirming whether this browser can read the workspace portfolio.`,title:`Checking this browser`};case`blocked`:return{announce:`assertive`,description:`This connection cannot read private release facts. Use an allowed Control Center address.`,title:`Portfolio access blocked`,tone:`critical`};case`storage-unavailable`:return{announce:`assertive`,description:`This browser cannot retain the private session proof. Check storage permissions or space, then reload.`,title:`Session storage unavailable`,tone:`caution`};case`unavailable`:return{announce:`assertive`,description:`Control Center could not check this browser session. Check the server, then reload this page.`,title:`Control Center unavailable`,tone:`critical`}}},Be=({reason:e})=>{let t=Y(e);return(0,L.jsx)(c,{...t,action:e===`anonymous`?(0,L.jsx)(a,{className:J.pairAction,to:`/pair`,children:`Pair this browser`}):void 0,className:J.statePanel})},Ve=({failure:e,onRetry:t})=>e===`session-expired`?(0,L.jsx)(c,{action:(0,L.jsx)(a,{className:J.pairAction,to:`/pair`,children:`Pair this browser`}),announce:`assertive`,className:J.statePanel,description:`Pair this browser again to read the workspace portfolio.`,title:`Pairing expired`,tone:`caution`}):e===`blocked`?(0,L.jsx)(c,{announce:`assertive`,className:J.statePanel,description:`This connection cannot read private release facts. Use an allowed Control Center address.`,title:`Portfolio access blocked`,tone:`critical`}):(0,L.jsx)(c,{action:(0,L.jsx)(l,{onClick:t,children:`Try again`}),announce:`assertive`,className:J.statePanel,description:`Control Center could not read the saved portfolio. Check the server, then try again.`,title:`Overview unavailable`,tone:`critical`}),X=({onPreview:e,release:t,transitionNames:n})=>(0,L.jsxs)(`div`,{className:J.releaseEntry,"data-portfolio-release-id":t.id,children:[(0,L.jsx)(f,{onPreview:e,previewLabel:`Preview ${t.relay.codename}`,release:t.release,...n===void 0?{}:{transitionNames:n}}),(0,L.jsx)(te,{className:J.stageRail,heading:`Delivery`,size:`compact`,stages:t.stages}),t.source.warning===null?null:(0,L.jsx)(c,{announce:`polite`,className:J.sourceWarning,description:t.source.warning,title:`Showing preserved source facts`,tone:`caution`})]}),He=({activeFilter:e,portfolio:t})=>{let r=n();return(0,L.jsx)(`nav`,{"aria-label":`Release filters`,className:J.filters,children:H(t.releases).map(t=>(0,L.jsxs)(a,{"aria-current":t.id===e?`page`:void 0,className:J.filter,"data-active":t.id===e?`true`:`false`,to:{pathname:r.pathname,search:B(r.search,t.id)},children:[(0,L.jsx)(`span`,{children:t.label}),(0,L.jsx)(`span`,{"aria-label":`${String(t.count)} ${t.count===1?`release`:`releases`}`,className:J.filterCount,children:t.count})]},t.id))})},Ue=({filter:e})=>{let t=n();return(0,L.jsx)(c,{action:(0,L.jsx)(a,{className:J.pairAction,to:{pathname:t.pathname,search:B(t.search,`all`)},children:`Show all releases`}),className:J.statePanel,description:`No releases currently match ${Se(e)}. Live updates may change this view.`,title:`Nothing here right now`})},We=({onPreview:e,originPath:t,previewPath:i,release:a})=>{let o=n(),s=r(i);return(0,L.jsx)(X,{onPreview:e,release:a,...s&&o.pathname===t?{transitionNames:N(a.id)}:{}})},Ge=({onPreviewRelease:e,portfolio:t,previewPathForRelease:r})=>{if(t.releases.length===0)return(0,L.jsx)(Re,{});let i=be(n().search),a=V(t.releases,i);return(0,L.jsxs)(`div`,{className:J.readyPortfolio,children:[(0,L.jsx)(He,{activeFilter:i,portfolio:t}),a.length===0?(0,L.jsx)(Ue,{filter:i}):(0,L.jsx)(`div`,{className:J.releaseList,children:a.map(n=>r===void 0?(0,L.jsx)(X,{onPreview:()=>e(n.id),release:n},n.id):(0,L.jsx)(We,{onPreview:()=>e(n.id),originPath:ee(t.workspaceId),previewPath:r(n.id),release:n},n.id))})]})},Z=({onPreviewRelease:e,onRetry:t,previewPathForRelease:n,state:r})=>(0,L.jsxs)(`section`,{"aria-labelledby":`portfolio-title`,className:J.root,children:[(0,L.jsxs)(`header`,{className:J.hero,children:[(0,L.jsxs)(`div`,{className:J.heroCopy,children:[(0,L.jsx)(m,{as:`h1`,className:J.title,id:`portfolio-title`,tabIndex:-1,variant:`verdict`,children:`Every release. One view.`}),(0,L.jsx)(m,{className:J.lede,tone:`secondary`,variant:`body-large`,children:`One factual view of releases, people, source health, and every handoff still to prove.`})]}),(0,L.jsxs)(`div`,{className:J.session,children:[r._tag===`session`&&r.reason===`storage-unavailable`?null:(0,L.jsx)(ve,{anonymousAction:`status`}),r._tag===`ready`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(Le,{connection:r.connection,isSnapshotStale:r.isSnapshotStale}),(0,L.jsxs)(m,{as:`time`,dateTime:r.portfolio.generatedAt,tone:`tertiary`,variant:`meta`,children:[`Snapshot `,r.portfolio.generatedTime]})]}):null]})]}),(0,L.jsxs)(`div`,{className:J.content,children:[r._tag===`session`?(0,L.jsx)(Be,{...r}):null,r._tag===`loading`?(0,L.jsx)(ze,{}):null,r._tag===`failed`?(0,L.jsx)(Ve,{failure:r.failure,onRetry:t}):null,r._tag===`ready`?(0,L.jsx)(Ge,{onPreviewRelease:e,portfolio:r.portfolio,...n===void 0?{}:{previewPathForRelease:n}}):null]})]}),Ke=e=>{switch(e._tag){case`idle`:return{_tag:`session`,reason:`anonymous`};case`loading`:return{_tag:`loading`};case`failed`:return{_tag:`failed`,failure:e.failure};case`loaded`:return{_tag:`ready`,connection:e.connection,isSnapshotStale:e.isSnapshotStale,portfolio:F(e.snapshot)}}},Q=(e,t,n=`anonymous`)=>t===null?{_tag:`session`,reason:n}:e._tag===`idle`||e.sessionKey!==t?{_tag:`loading`}:Ke(e),$=()=>{let{invalidateSession:e,state:t}=d(),n=t._tag===`authenticated`||t._tag===`storage-unavailable`?t.session:null,r=Fe(n?.sessionId??null,e);return{onRetry:r.retry,state:Q(r.state,n?.sessionId??null,t._tag===`authenticated`?`checking`:t._tag)}},qe=()=>{let e=$(),{state:t}=e,n=t._tag===`ready`?t.portfolio.workspaceId:null,r=P(n);return t._tag===`ready`&&r!==null?(0,L.jsx)(i,{replace:!0,to:r}):(0,L.jsx)(Z,{onPreviewRelease:()=>void 0,onRetry:e.onRetry,state:t})};export{qe as PortfolioOverview,Z as PortfolioOverviewView,Y as portfolioSessionBoundaryPresentation,Q as selectPortfolioOverviewState,$ as usePortfolioOverviewController};
|
|
2
|
-
//# sourceMappingURL=PortfolioOverview-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{t}from"./react-CwJFpaho.js";import{r as n}from"./hooks-K-sIfGqH.js";import{o as r,s as i,t as a}from"./lib-6h955hh9.js";import{t as o}from"./jsx-runtime-NZYk81nU.js";import{d as s,g as c,r as l,v as u}from"./Dialog-DSwimdwG-BeHnBpPp.js";import{i as ee}from"./releasePaths-XoI2BHX3.js";import{p as d}from"./index-kmYFvwT0.js";import{d as f,f as p,r as te}from"./patterns-DuFUSnJW.js";import{n as m}from"./primitives-DYGtIZqB-r-Glkv2i.js";import{Ai as ne,Ci as h,Di as g,Fi as _,Ga as re,Hi as v,Ii as ie,Ja as ae,Ki as oe,Mi as se,Ni as y,Pi as ce,Ti as le,Ui as ue,Yi as b,_i as x,bi as de,ca as fe,di as S,ga as pe,ii as me,ma as he,mi as C,ni as w,pi as T,ra as E,xn as D}from"./agent-api-CUWP1qs8.js";import{a as O,t as k}from"./client-D3WRV6yl.js";import{d as A,u as j}from"./serviceOnboarding-F9Lj6a7y.js";import{t as M}from"./pages.module-CpW6k_pw.js";import{c as N}from"./releaseRoutes-h4FVwFvJ.js";import{t as P}from"./useWorkspaceDefaultLanding-BmaR7aTj.js";import{t as F}from"./presentPortfolio-DVP-zqTg.js";var I=e(t(),1),L=o(),R=oe,ge=(e=>ue(t=>y(e(t.getRef(R)))))(e=>e.nextDoubleUnsafe()),_e=e=>e===`workspace-owner`?`Owner browser paired`:`Browser paired`,ve=({anonymousAction:e=`link`}={})=>{let{state:t}=d(),n=(0,I.useRef)(null);return(0,I.useEffect)(()=>{t._tag===`storage-unavailable`&&n.current?.focus()},[t._tag]),t._tag===`anonymous`?e===`status`?(0,L.jsx)(m,{className:M.sessionStatus,tone:`secondary`,variant:`label`,children:`Browser not paired`}):(0,L.jsx)(a,{className:M.linkButton,to:`/pair`,children:`Pair this browser`}):t._tag===`authenticated`?(0,L.jsxs)(m,{className:M.sessionBadge,variant:`label`,children:[(0,L.jsx)(`span`,{"aria-hidden":`true`,children:`✓`}),` `,_e(t.session.permission)]}):t._tag===`storage-unavailable`?(0,L.jsx)(m,{"aria-atomic":`true`,as:`span`,className:M.sessionStatus,ref:n,role:`alert`,tabIndex:-1,tone:`secondary`,variant:`label`,children:t.session===null?`Session storage is unavailable. Check storage permissions or space, then reload.`:`Browser paired, but session storage is unavailable. Check storage permissions or space, then reload.`}):(0,L.jsx)(m,{className:M.sessionStatus,tone:`secondary`,variant:`label`,children:t._tag===`checking`?`Checking this browser…`:t._tag===`blocked`?`Session access blocked on this connection`:`Server unavailable`})},z={all:`All`,attention:`Need attention`,deploying:`Deploying`,shipped:`Shipped`},ye=[`all`,`attention`,`deploying`,`shipped`],be=e=>{let t=new URLSearchParams(e).get(`status`);return t===`attention`||t===`deploying`||t===`shipped`?t:`all`},B=(e,t)=>{let n=new URLSearchParams(e);t===`all`?n.delete(`status`):n.set(`status`,t);let r=n.toString();return r.length===0?``:`?${r}`},xe=(e,t)=>{switch(t){case`all`:return!0;case`attention`:return e.readinessVerdict===`blocked`||e.readinessVerdict===`held`||e.readinessVerdict===`unknown`;case`deploying`:return e.readinessVerdict===`deploying`||e.readinessVerdict===`building`;case`shipped`:return e.readinessVerdict===`shipped`}},V=(e,t)=>e.filter(e=>xe(e,t)),H=e=>ye.map(t=>({count:V(e,t).length,id:t,label:z[t]})),Se=e=>z[e],U=(e,t)=>e===null||t>e?t:e,Ce=(e,t)=>{switch(t._tag){case`clear`:return{_tag:`idle`};case`begin`:return{_tag:`loading`,sessionKey:t.sessionKey};case`failed`:return{_tag:`failed`,sessionKey:t.sessionKey,failure:t.failure};case`initial-snapshot`:return{_tag:`loaded`,awaitingResetSnapshot:!1,connection:{_tag:`connecting`},isSnapshotStale:!1,minimumRefreshCursor:null,sessionKey:t.sessionKey,snapshot:t.snapshot};case`caught-up`:return e._tag!==`loaded`||e.awaitingResetSnapshot||e.minimumRefreshCursor!==null&&e.minimumRefreshCursor>e.snapshot.eventCursor?e:{...e,awaitingResetSnapshot:!1,connection:{_tag:`connected`},isSnapshotStale:!1,minimumRefreshCursor:null};case`stream-snapshot`:return e._tag!==`loaded`||e.minimumRefreshCursor!==null&&t.snapshot.eventCursor<e.minimumRefreshCursor||!e.awaitingResetSnapshot&&t.snapshot.eventCursor<e.snapshot.eventCursor?e:{...e,awaitingResetSnapshot:!1,connection:{_tag:`connected`},isSnapshotStale:!1,minimumRefreshCursor:null,snapshot:t.snapshot};case`invalidated`:return e._tag!==`loaded`||e.awaitingResetSnapshot||t.eventCursor<=e.snapshot.eventCursor?e:{...e,isSnapshotStale:!0,minimumRefreshCursor:U(e.minimumRefreshCursor,t.eventCursor)};case`reset-required`:return e._tag===`loaded`?{...e,awaitingResetSnapshot:!0,isSnapshotStale:!0,minimumRefreshCursor:U(e.minimumRefreshCursor,t.headCursor)}:e;case`reconnecting`:return e._tag===`loaded`?{...e,connection:{_tag:`reconnecting`,attempt:t.attempt},isSnapshotStale:!0}:e;case`offline`:return e._tag===`loaded`?{...e,connection:{_tag:`offline`},isSnapshotStale:!0}:e}},W=e=>e._tag===`loaded`?e.snapshot.eventCursor:null,we=3e4,Te=500,Ee=16,G=class extends b(`PortfolioStreamProtocolError`){},De=class extends b(`PortfolioStreamClosedError`){},K=e=>!re(e,`_tag`)||!ae(e._tag)?`unavailable`:e._tag===`UnauthorizedApiError`?`session-expired`:e._tag===`ForbiddenApiError`?`blocked`:`unavailable`,Oe=(e,t)=>{let n=Math.min(Math.max(e-1,0),Ee),r=Math.min(we,Te*2**n)/2;return Math.max(1,Math.floor(r+r*Math.min(Math.max(t,0),1)))},ke=e=>ge.pipe(de(t=>Oe(e,t)),T(se)),Ae=e=>{if(e.prunedThroughCursor>e.headCursor)return!1;switch(e.reason){case`retention`:return e.requestedCursor<e.prunedThroughCursor;case`cursor-ahead`:return e.requestedCursor>e.headCursor;case`gap`:return e.prunedThroughCursor<=e.requestedCursor&&e.requestedCursor<e.headCursor;case`replay-budget`:return e.requestedCursor<=e.headCursor}},je={isOnline:_(()=>navigator.onLine),waitUntilOnline:ce(()=>navigator.onLine?v:me(e=>{let t=()=>e(v);return window.addEventListener(`online`,t,{once:!0}),_(()=>window.removeEventListener(`online`,t))}))},Me=x(function*(){let e=yield*k();return{loadSnapshot:e.portfolio.snapshot(),openStream:t=>e.liveEvents.stream({headers:{"last-event-id":t},query:{after:t}})}}),q=({failure:e,onSessionExpired:t,sessionKey:n})=>{let r=K(e);return r===`session-expired`&&t(n),{_tag:`failed`,sessionKey:n,failure:r}},Ne=C(`PortfolioLiveController.run`)(function*({connectivity:e,onSessionExpired:t,onState:n,sessionKey:r,transport:i}){let a={_tag:`loading`,sessionKey:r},o=e=>_(()=>{a=Ce(a,e),n(a)}),s=yield*g(i.loadSnapshot);if(he(s))return yield*o({_tag:`failed`,failure:q({failure:s.failure,onSessionExpired:t,sessionKey:r}).failure,sessionKey:r}),yield*h;yield*o({_tag:`initial-snapshot`,sessionKey:r,snapshot:s.success});let c=C(`PortfolioLiveController.refreshSnapshot`)(function*(e){let t=yield*i.loadSnapshot;if(t.eventCursor<e)return yield*S(new G);yield*o({_tag:`stream-snapshot`,snapshot:t})}),l=C(`PortfolioLiveController.consumeStream`)(function*(e,t,n){let r=!1,i=a._tag===`loaded`&&a.awaitingResetSnapshot?a.minimumRefreshCursor:null,s=t,l=e=>{e>s&&(s=e)},u=e=>{switch(e.event){case`portfolio.snapshot`:{if(e.id!==e.data.eventCursor)return S(new G);let t=W(a);return t===null||i!==null&&e.id<i?S(new G):(i===null?l(e.id):s=e.id,i===null&&e.id<t?v:(i=null,o({_tag:`stream-snapshot`,snapshot:e.data})))}case`portfolio.invalidated`:{if(i!==null||e.id!==e.data.eventCursor)return S(new G);l(e.id);let t=W(a);return t===null||e.id<=t?v:o({_tag:`invalidated`,eventCursor:e.id}).pipe(w(c(e.id)))}case`stream.reset-required`:return e.data.requestedCursor!==s||!Ae(e.data)?S(new G):(i=i===null||e.data.headCursor>i?e.data.headCursor:i,o({_tag:`reset-required`,headCursor:i}));case`stream.heartbeat`:if(i!==null)return S(new G);{let t=W(a);return t===null?S(new G):(l(e.data.eventCursor),e.data.eventCursor<=t?o({_tag:`caught-up`}):o({_tag:`invalidated`,eventCursor:e.data.eventCursor}).pipe(w(c(e.data.eventCursor))))}}};return yield*D(e,e=>u(e).pipe(ie(()=>r?v:(r=!0,n)))),yield*S(new De)});return yield*C(`PortfolioLiveController.reconnect`)(function*(){let n=0;for(;;){(yield*e.isOnline)?n>0&&(yield*o({_tag:`reconnecting`,attempt:n}),yield*ke(n)):(yield*o({_tag:`offline`}),yield*e.waitUntilOnline);let s=W(a);if(s===null)return yield*h;let c=yield*g(x(function*(){let e=yield*i.openStream(s);return yield*l(e,s,_(()=>{n=0}))}));if(pe(c))return yield*h;let u=K(c.failure);if(u===`session-expired`||u===`blocked`){let e=q({failure:c.failure,onSessionExpired:t,sessionKey:r});return yield*o({_tag:`failed`,failure:e.failure,sessionKey:r}),yield*h}n+=1}})()}),Pe=e=>Ne(e),Fe=(e,t,n)=>{let[r,i]=(0,I.useState)(0),[a,o]=(0,I.useState)({_tag:`idle`});return(0,I.useEffect)(()=>{if(e===null){o({_tag:`idle`});return}let r=new AbortController,i=!0;o({_tag:`loading`,sessionKey:e});let a=(n,r)=>Pe({connectivity:r,onSessionExpired:t,onState:e=>{i&&o(e)},sessionKey:e,transport:n}),s=n===void 0?T(Me,e=>a(e,je)).pipe(le(O)):a(n.transport,n.connectivity);return ne(s,{signal:r.signal}).then(t=>{!i||fe(t)||E(t.cause)||o({_tag:`failed`,failure:`unavailable`,sessionKey:e})}),()=>{i=!1,r.abort()}},[n,t,r,e]),{retry:(0,I.useCallback)(()=>i(e=>e+1),[]),state:a}},J={root:`_root_10gd5_1`,hero:`_hero_10gd5_6`,heroCopy:`_heroCopy_10gd5_13`,title:`_title_10gd5_18`,lede:`_lede_10gd5_23`,session:`_session_10gd5_28`,liveStatus:`_liveStatus_10gd5_34`,content:`_content_10gd5_42`,readyPortfolio:`_readyPortfolio_10gd5_43`,releaseList:`_releaseList_10gd5_44`,filters:`_filters_10gd5_53`,filter:`_filter_10gd5_53`,filterCount:`_filterCount_10gd5_100`,statePanel:`_statePanel_10gd5_115`,firstService:`_firstService_10gd5_119`,firstServiceCopy:`_firstServiceCopy_10gd5_124`,serviceLauncher:`_serviceLauncher_10gd5_130`,serviceChoice:`_serviceChoice_10gd5_136`,serviceAction:`_serviceAction_10gd5_187`,pairAction:`_pairAction_10gd5_193`,loading:`_loading_10gd5_207`,loadingRail:`_loadingRail_10gd5_213`,releaseEntry:`_releaseEntry_10gd5_219`,stageRail:`_stageRail_10gd5_239`,sourceWarning:`_sourceWarning_10gd5_244`},Ie=(e,t)=>{switch(e._tag){case`connecting`:return{detail:`Connecting to live updates.`,label:`Connecting`,tone:`progress`};case`reconnecting`:return{detail:`Showing the last snapshot; it may be stale.`,label:`Reconnecting`,tone:`caution`};case`offline`:return{detail:`Showing the last snapshot; it may be stale.`,label:`Offline`,tone:`caution`};case`connected`:return t?{detail:`Refreshing the authoritative snapshot.`,label:`Updating`,tone:`progress`}:{detail:`Snapshot up to date.`,label:`Live`,tone:`positive`}}},Le=({connection:e,isSnapshotStale:t})=>{let n=Ie(e,t);return(0,L.jsxs)(`div`,{"aria-atomic":`true`,"aria-live":`polite`,className:J.liveStatus,role:`status`,children:[(0,L.jsx)(s,{label:n.label,size:`compact`,tone:n.tone}),(0,L.jsx)(m,{tone:`tertiary`,variant:`meta`,children:n.detail})]})},Re=()=>(0,L.jsxs)(`section`,{"aria-labelledby":`first-service-title`,className:J.firstService,children:[(0,L.jsxs)(`div`,{className:J.firstServiceCopy,children:[(0,L.jsx)(m,{as:`h2`,id:`first-service-title`,variant:`page-title`,children:`Choose your first service`}),(0,L.jsx)(m,{tone:`secondary`,variant:`body-large`,children:`Enable and verify one source. Its releases, people, and delivery evidence will appear here automatically.`})]}),(0,L.jsx)(`nav`,{"aria-label":`Services available to enable`,className:J.serviceLauncher,children:A.map(e=>(0,L.jsxs)(a,{className:J.serviceChoice,"data-service":e.providerId,to:j(e.providerId),children:[(0,L.jsx)(te,{service:e.providerId}),(0,L.jsx)(`span`,{className:J.serviceAction,children:`Enable`})]},e.providerId))})]}),ze=()=>(0,L.jsxs)(`div`,{className:J.loading,children:[(0,L.jsx)(u,{decorative:!1,height:`1.25rem`,label:`Loading releases`,width:`10rem`}),(0,L.jsx)(u,{decorative:!0,height:`8rem`,variant:`block`}),(0,L.jsxs)(`div`,{className:J.loadingRail,children:[(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`}),(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`}),(0,L.jsx)(u,{decorative:!0,height:`3rem`,variant:`block`})]})]}),Y=e=>{switch(e){case`anonymous`:return{description:`Pair this browser to read the workspace portfolio. Release facts never load before authentication.`,title:`Release facts stay private`};case`checking`:return{description:`Control Center is confirming whether this browser can read the workspace portfolio.`,title:`Checking this browser`};case`blocked`:return{announce:`assertive`,description:`This connection cannot read private release facts. Use an allowed Control Center address.`,title:`Portfolio access blocked`,tone:`critical`};case`storage-unavailable`:return{announce:`assertive`,description:`This browser cannot retain the private session proof. Check storage permissions or space, then reload.`,title:`Session storage unavailable`,tone:`caution`};case`unavailable`:return{announce:`assertive`,description:`Control Center could not check this browser session. Check the server, then reload this page.`,title:`Control Center unavailable`,tone:`critical`}}},Be=({reason:e})=>{let t=Y(e);return(0,L.jsx)(c,{...t,action:e===`anonymous`?(0,L.jsx)(a,{className:J.pairAction,to:`/pair`,children:`Pair this browser`}):void 0,className:J.statePanel})},Ve=({failure:e,onRetry:t})=>e===`session-expired`?(0,L.jsx)(c,{action:(0,L.jsx)(a,{className:J.pairAction,to:`/pair`,children:`Pair this browser`}),announce:`assertive`,className:J.statePanel,description:`Pair this browser again to read the workspace portfolio.`,title:`Pairing expired`,tone:`caution`}):e===`blocked`?(0,L.jsx)(c,{announce:`assertive`,className:J.statePanel,description:`This connection cannot read private release facts. Use an allowed Control Center address.`,title:`Portfolio access blocked`,tone:`critical`}):(0,L.jsx)(c,{action:(0,L.jsx)(l,{onClick:t,children:`Try again`}),announce:`assertive`,className:J.statePanel,description:`Control Center could not read the saved portfolio. Check the server, then try again.`,title:`Overview unavailable`,tone:`critical`}),X=({onPreview:e,release:t,transitionNames:n})=>(0,L.jsxs)(`div`,{className:J.releaseEntry,"data-portfolio-release-id":t.id,children:[(0,L.jsx)(f,{onPreview:e,previewLabel:`Preview ${t.relay.codename}`,release:t.release,...n===void 0?{}:{transitionNames:n}}),(0,L.jsx)(p,{className:J.stageRail,heading:`Delivery`,size:`compact`,stages:t.stages}),t.source.warning===null?null:(0,L.jsx)(c,{announce:`polite`,className:J.sourceWarning,description:t.source.warning,title:`Showing preserved source facts`,tone:`caution`})]}),He=({activeFilter:e,portfolio:t})=>{let r=n();return(0,L.jsx)(`nav`,{"aria-label":`Release filters`,className:J.filters,children:H(t.releases).map(t=>(0,L.jsxs)(a,{"aria-current":t.id===e?`page`:void 0,className:J.filter,"data-active":t.id===e?`true`:`false`,to:{pathname:r.pathname,search:B(r.search,t.id)},children:[(0,L.jsx)(`span`,{children:t.label}),(0,L.jsx)(`span`,{"aria-label":`${String(t.count)} ${t.count===1?`release`:`releases`}`,className:J.filterCount,children:t.count})]},t.id))})},Ue=({filter:e})=>{let t=n();return(0,L.jsx)(c,{action:(0,L.jsx)(a,{className:J.pairAction,to:{pathname:t.pathname,search:B(t.search,`all`)},children:`Show all releases`}),className:J.statePanel,description:`No releases currently match ${Se(e)}. Live updates may change this view.`,title:`Nothing here right now`})},We=({onPreview:e,originPath:t,previewPath:i,release:a})=>{let o=n(),s=r(i);return(0,L.jsx)(X,{onPreview:e,release:a,...s&&o.pathname===t?{transitionNames:N(a.id)}:{}})},Ge=({onPreviewRelease:e,portfolio:t,previewPathForRelease:r})=>{if(t.releases.length===0)return(0,L.jsx)(Re,{});let i=be(n().search),a=V(t.releases,i);return(0,L.jsxs)(`div`,{className:J.readyPortfolio,children:[(0,L.jsx)(He,{activeFilter:i,portfolio:t}),a.length===0?(0,L.jsx)(Ue,{filter:i}):(0,L.jsx)(`div`,{className:J.releaseList,children:a.map(n=>r===void 0?(0,L.jsx)(X,{onPreview:()=>e(n.id),release:n},n.id):(0,L.jsx)(We,{onPreview:()=>e(n.id),originPath:ee(t.workspaceId),previewPath:r(n.id),release:n},n.id))})]})},Z=({onPreviewRelease:e,onRetry:t,previewPathForRelease:n,state:r})=>(0,L.jsxs)(`section`,{"aria-labelledby":`portfolio-title`,className:J.root,children:[(0,L.jsxs)(`header`,{className:J.hero,children:[(0,L.jsxs)(`div`,{className:J.heroCopy,children:[(0,L.jsx)(m,{as:`h1`,className:J.title,id:`portfolio-title`,tabIndex:-1,variant:`verdict`,children:`Every release. One view.`}),(0,L.jsx)(m,{className:J.lede,tone:`secondary`,variant:`body-large`,children:`One factual view of releases, people, source health, and every handoff still to prove.`})]}),(0,L.jsxs)(`div`,{className:J.session,children:[r._tag===`session`&&r.reason===`storage-unavailable`?null:(0,L.jsx)(ve,{anonymousAction:`status`}),r._tag===`ready`?(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(Le,{connection:r.connection,isSnapshotStale:r.isSnapshotStale}),(0,L.jsxs)(m,{as:`time`,dateTime:r.portfolio.generatedAt,tone:`tertiary`,variant:`meta`,children:[`Snapshot `,r.portfolio.generatedTime]})]}):null]})]}),(0,L.jsxs)(`div`,{className:J.content,children:[r._tag===`session`?(0,L.jsx)(Be,{...r}):null,r._tag===`loading`?(0,L.jsx)(ze,{}):null,r._tag===`failed`?(0,L.jsx)(Ve,{failure:r.failure,onRetry:t}):null,r._tag===`ready`?(0,L.jsx)(Ge,{onPreviewRelease:e,portfolio:r.portfolio,...n===void 0?{}:{previewPathForRelease:n}}):null]})]}),Ke=e=>{switch(e._tag){case`idle`:return{_tag:`session`,reason:`anonymous`};case`loading`:return{_tag:`loading`};case`failed`:return{_tag:`failed`,failure:e.failure};case`loaded`:return{_tag:`ready`,connection:e.connection,isSnapshotStale:e.isSnapshotStale,portfolio:F(e.snapshot)}}},Q=(e,t,n=`anonymous`)=>t===null?{_tag:`session`,reason:n}:e._tag===`idle`||e.sessionKey!==t?{_tag:`loading`}:Ke(e),$=()=>{let{invalidateSession:e,state:t}=d(),n=t._tag===`authenticated`||t._tag===`storage-unavailable`?t.session:null,r=Fe(n?.sessionId??null,e);return{onRetry:r.retry,state:Q(r.state,n?.sessionId??null,t._tag===`authenticated`?`checking`:t._tag)}},qe=()=>{let e=$(),{state:t}=e,n=t._tag===`ready`?t.portfolio.workspaceId:null,r=P(n);return t._tag===`ready`&&r!==null?(0,L.jsx)(i,{replace:!0,to:r}):(0,L.jsx)(Z,{onPreviewRelease:()=>void 0,onRetry:e.onRetry,state:t})};export{qe as PortfolioOverview,Z as PortfolioOverviewView,Y as portfolioSessionBoundaryPresentation,Q as selectPortfolioOverviewState,$ as usePortfolioOverviewController};
|
|
2
|
+
//# sourceMappingURL=PortfolioOverview-C-jqvYgQ.js.map
|