@burdenoff/microfe-planmagnet 2026.930.21 → 2026.930.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/dist/node_modules/lodash/_arrayEach.js +14 -0
  2. package/dist/node_modules/lodash/_arrayEach.js.map +1 -0
  3. package/dist/node_modules/lodash/_assignValue.js +17 -0
  4. package/dist/node_modules/lodash/_assignValue.js.map +1 -0
  5. package/dist/node_modules/lodash/_baseAssign.js +16 -0
  6. package/dist/node_modules/lodash/_baseAssign.js.map +1 -0
  7. package/dist/node_modules/lodash/_baseAssignIn.js +16 -0
  8. package/dist/node_modules/lodash/_baseAssignIn.js.map +1 -0
  9. package/dist/node_modules/lodash/_baseClone.js +64 -0
  10. package/dist/node_modules/lodash/_baseClone.js.map +1 -0
  11. package/dist/node_modules/lodash/_baseCreate.js +21 -0
  12. package/dist/node_modules/lodash/_baseCreate.js.map +1 -0
  13. package/dist/node_modules/lodash/_baseIsMap.js +16 -0
  14. package/dist/node_modules/lodash/_baseIsMap.js.map +1 -0
  15. package/dist/node_modules/lodash/_baseIsSet.js +16 -0
  16. package/dist/node_modules/lodash/_baseIsSet.js.map +1 -0
  17. package/dist/node_modules/lodash/_baseKeysIn.js +20 -0
  18. package/dist/node_modules/lodash/_baseKeysIn.js.map +1 -0
  19. package/dist/node_modules/lodash/_baseSum.js +17 -0
  20. package/dist/node_modules/lodash/_baseSum.js.map +1 -0
  21. package/dist/node_modules/lodash/_baseUnset.js +26 -0
  22. package/dist/node_modules/lodash/_baseUnset.js.map +1 -0
  23. package/dist/node_modules/lodash/_cloneArrayBuffer.js +16 -0
  24. package/dist/node_modules/lodash/_cloneArrayBuffer.js.map +1 -0
  25. package/dist/node_modules/lodash/_cloneBuffer.js +17 -0
  26. package/dist/node_modules/lodash/_cloneBuffer.js.map +1 -0
  27. package/dist/node_modules/lodash/_cloneDataView.js +16 -0
  28. package/dist/node_modules/lodash/_cloneDataView.js.map +1 -0
  29. package/dist/node_modules/lodash/_cloneRegExp.js +15 -0
  30. package/dist/node_modules/lodash/_cloneRegExp.js.map +1 -0
  31. package/dist/node_modules/lodash/_cloneSymbol.js +15 -0
  32. package/dist/node_modules/lodash/_cloneSymbol.js.map +1 -0
  33. package/dist/node_modules/lodash/_cloneTypedArray.js +16 -0
  34. package/dist/node_modules/lodash/_cloneTypedArray.js.map +1 -0
  35. package/dist/node_modules/lodash/_copyArray.js +15 -0
  36. package/dist/node_modules/lodash/_copyArray.js.map +1 -0
  37. package/dist/node_modules/lodash/_copyObject.js +22 -0
  38. package/dist/node_modules/lodash/_copyObject.js.map +1 -0
  39. package/dist/node_modules/lodash/_copySymbols.js +16 -0
  40. package/dist/node_modules/lodash/_copySymbols.js.map +1 -0
  41. package/dist/node_modules/lodash/_copySymbolsIn.js +16 -0
  42. package/dist/node_modules/lodash/_copySymbolsIn.js.map +1 -0
  43. package/dist/node_modules/lodash/_customOmitClone.js +15 -0
  44. package/dist/node_modules/lodash/_customOmitClone.js.map +1 -0
  45. package/dist/node_modules/lodash/_flatRest.js +17 -0
  46. package/dist/node_modules/lodash/_flatRest.js.map +1 -0
  47. package/dist/node_modules/lodash/_getAllKeysIn.js +17 -0
  48. package/dist/node_modules/lodash/_getAllKeysIn.js.map +1 -0
  49. package/dist/node_modules/lodash/_getSymbolsIn.js +18 -0
  50. package/dist/node_modules/lodash/_getSymbolsIn.js.map +1 -0
  51. package/dist/node_modules/lodash/_initCloneArray.js +15 -0
  52. package/dist/node_modules/lodash/_initCloneArray.js.map +1 -0
  53. package/dist/node_modules/lodash/_initCloneByTag.js +40 -0
  54. package/dist/node_modules/lodash/_initCloneByTag.js.map +1 -0
  55. package/dist/node_modules/lodash/_initCloneObject.js +17 -0
  56. package/dist/node_modules/lodash/_initCloneObject.js.map +1 -0
  57. package/dist/node_modules/lodash/_nativeKeysIn.js +15 -0
  58. package/dist/node_modules/lodash/_nativeKeysIn.js.map +1 -0
  59. package/dist/node_modules/lodash/_parent.js +16 -0
  60. package/dist/node_modules/lodash/_parent.js.map +1 -0
  61. package/dist/node_modules/lodash/flatten.js +15 -0
  62. package/dist/node_modules/lodash/flatten.js.map +1 -0
  63. package/dist/node_modules/lodash/isMap.js +14 -0
  64. package/dist/node_modules/lodash/isMap.js.map +1 -0
  65. package/dist/node_modules/lodash/isSet.js +14 -0
  66. package/dist/node_modules/lodash/isSet.js.map +1 -0
  67. package/dist/node_modules/lodash/keysIn.js +17 -0
  68. package/dist/node_modules/lodash/keysIn.js.map +1 -0
  69. package/dist/node_modules/lodash/maxBy.js +17 -0
  70. package/dist/node_modules/lodash/maxBy.js.map +1 -0
  71. package/dist/node_modules/lodash/omit.js +28 -0
  72. package/dist/node_modules/lodash/omit.js.map +1 -0
  73. package/dist/node_modules/lodash/sumBy.js +16 -0
  74. package/dist/node_modules/lodash/sumBy.js.map +1 -0
  75. package/dist/node_modules/recharts/es6/chart/Sankey.js +556 -0
  76. package/dist/node_modules/recharts/es6/chart/Sankey.js.map +1 -0
  77. package/dist/node_modules/recharts/es6/chart/Treemap.js +545 -0
  78. package/dist/node_modules/recharts/es6/chart/Treemap.js.map +1 -0
  79. package/dist/node_modules/recharts/es6/shape/Polygon.js +112 -0
  80. package/dist/node_modules/recharts/es6/shape/Polygon.js.map +1 -0
  81. package/dist/node_modules/recharts/es6/util/Constants.js +31 -0
  82. package/dist/node_modules/recharts/es6/util/Constants.js.map +1 -0
  83. package/dist/node_modules/recharts/es6/util/ReactUtils.js +15 -10
  84. package/dist/node_modules/recharts/es6/util/ReactUtils.js.map +1 -1
  85. package/dist/planmagnet/controls/AutomationRuleControls.js +10 -10
  86. package/dist/planmagnet/controls/CompetitorControls.js +7 -7
  87. package/dist/planmagnet/controls/FeatureControls.js +38 -38
  88. package/dist/planmagnet/controls/ProgramControls.js +8 -8
  89. package/dist/planmagnet/dependency/DependencyGraph.d.ts.map +1 -1
  90. package/dist/planmagnet/dependency/DependencyGraph.js +13 -10
  91. package/dist/planmagnet/dependency/DependencyGraph.js.map +1 -1
  92. package/dist/planmagnet/dependency/DependencyPanel.js +13 -13
  93. package/dist/planmagnet/dependency/GanttChart.d.ts.map +1 -1
  94. package/dist/planmagnet/dependency/GanttChart.js +11 -5
  95. package/dist/planmagnet/dependency/GanttChart.js.map +1 -1
  96. package/dist/planmagnet/pages/ActivityActivityPagePage.js +16 -16
  97. package/dist/planmagnet/pages/ActivityActivityPagePage.js.map +1 -1
  98. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
  99. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +91 -73
  100. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  101. package/dist/planmagnet/pages/AutomationAutomationRulesPagePage.js +6 -6
  102. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +4 -4
  103. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +11 -11
  104. package/dist/planmagnet/pages/DashboardsProjectManagerPagePage.js +5 -5
  105. package/dist/planmagnet/pages/DashboardsTeamUtilizationPagePage.js +5 -5
  106. package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js +6 -6
  107. package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js.map +1 -1
  108. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +8 -8
  109. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +10 -10
  110. package/dist/planmagnet/pages/ProjectsCriticalPathPagePage.js +6 -6
  111. package/dist/planmagnet/pages/ProjectsEditProjectPagePage.js +5 -5
  112. package/dist/planmagnet/pages/ProjectsPlanningPagePage.js +8 -8
  113. package/dist/planmagnet/pages/SprintsStartSprintPagePage.js +4 -4
  114. package/dist/planmagnet/pages/analytics/StatusFlowCard.d.ts +8 -0
  115. package/dist/planmagnet/pages/analytics/StatusFlowCard.d.ts.map +1 -0
  116. package/dist/planmagnet/pages/analytics/StatusFlowCard.js +234 -0
  117. package/dist/planmagnet/pages/analytics/StatusFlowCard.js.map +1 -0
  118. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.d.ts +6 -0
  119. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.d.ts.map +1 -0
  120. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +367 -0
  121. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js.map +1 -0
  122. package/dist/planmagnet/roadmaps/RoadmapControls.js +17 -17
  123. package/dist/planmagnet/utils/statusColor.d.ts +8 -9
  124. package/dist/planmagnet/utils/statusColor.d.ts.map +1 -1
  125. package/dist/planmagnet/utils/statusColor.js +8 -40
  126. package/dist/planmagnet/utils/statusColor.js.map +1 -1
  127. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"IntegrationsNewSyncPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/IntegrationsNewSyncPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Checkbox,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, CheckCircle2, Github, Loader2, Plug, ShieldQuestion } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { isForbidden, mutationErrorMessage } from '../utils/graphqlErrors';\nimport { ErrorLine } from '../controls/ConfirmButton';\nimport { ProjectSelect } from '../controls/Pickers';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport {\n RunNowButton,\n SyncRunResultSummary,\n TestConnectionButton,\n CONFLICT_STRATEGY_EXPLANATION,\n} from '../controls/SyncControls';\nimport { useSyncProviderCapabilities } from '../integrations/useSyncProviderCapabilities';\nimport {\n CONFLICT_RESOLUTIONS,\n directionLabel,\n directionSupported,\n GITHUB_FIELD_MAPPING_DEFAULTS,\n isValidGithubOwner,\n isValidGithubRepo,\n providerIsLive,\n providerLabel,\n SYNC_DIRECTIONS,\n type ConflictResolution,\n type SyncDirection,\n type SyncProvider,\n type SyncProviderCapability,\n type SyncRunResult,\n} from '../integrations/syncTypes';\n\n/**\n * Sync setup wizard (AUT-08): create an ExternalSync step by step, driven entirely by\n * `planmagnetSupportedSyncProviders` — a provider is selectable, and a direction is offered, only when the\n * capability list says it is real, never a hard-coded \"GitHub only\" rule. Today that capability list happens to\n * make GITHUB the only live choice (BOFF-4446); the connection fields below (owner/repo/token) are GitHub's own\n * documented `connectionConfig` shape and only make sense for it — there is nothing to generalize them to until\n * a second connector ships.\n */\n\nconst label = 'text-sm font-medium';\n\nconst CREATE_SYNC = gql`\n mutation NewSyncCreate($input: PlanmagnetCreateExternalSyncInput!) {\n planmagnetCreateExternalSync(input: $input) {\n id\n provider\n status\n project {\n id\n name\n }\n }\n }\n`;\n\ninterface CreatedSync {\n id: string;\n provider: string;\n status: string;\n project: { id: string; name: string } | null;\n}\n\nfunction ProviderStep({\n capabilities,\n capabilitiesLoading,\n provider,\n onSelect,\n}: {\n capabilities: SyncProviderCapability[];\n capabilitiesLoading: boolean;\n provider: SyncProvider | '';\n onSelect: (p: SyncProvider) => void;\n}) {\n return (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>1. Provider</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {capabilitiesLoading && <p className=\"text-sm text-muted-foreground\">Loading providers…</p>}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n {capabilities.map((c) => {\n const live = providerIsLive(c);\n const selected = provider === c.provider;\n return (\n <button\n key={c.provider}\n type=\"button\"\n disabled={!live}\n aria-pressed={selected}\n data-testid={`sync-wizard-provider-${c.provider}`}\n onClick={() => live && onSelect(c.provider)}\n className={`flex items-start gap-2 rounded-md border p-3 text-left text-sm transition-colors ${\n selected ? 'border-primary bg-primary/5' : 'border-input'\n } ${live ? 'hover:bg-muted' : 'cursor-not-allowed opacity-50'}`}\n >\n {c.provider === 'GITHUB' ? (\n <Github className=\"mt-0.5 h-4 w-4 shrink-0\" />\n ) : (\n <Plug className=\"mt-0.5 h-4 w-4 shrink-0\" />\n )}\n <span>\n <span className=\"block font-medium\">{providerLabel(c.provider)}</span>\n <span className=\"block text-xs text-muted-foreground\">\n {live\n ? [\n c.supportsImport && 'inbound',\n c.supportsExport && 'outbound',\n c.supportsBidirectional && 'bidirectional',\n ]\n .filter(Boolean)\n .join(', ') + ' sync'\n : 'No live connector yet — inbound, outbound and bidirectional sync are all unavailable for this provider.'}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function IntegrationsNewSyncPagePage() {\n const navigate = usePlanMagnetNavigate();\n const { capabilities, loading: capabilitiesLoading } = useSyncProviderCapabilities();\n\n const [provider, setProvider] = useState<SyncProvider | ''>('');\n const [projectId, setProjectId] = useState('');\n const [owner, setOwner] = useState('');\n const [repo, setRepo] = useState('');\n const [direction, setDirection] = useState<SyncDirection | ''>('');\n const [token, setToken] = useState('');\n const [conflictStrategy, setConflictStrategy] = useState<ConflictResolution>('MANUAL');\n const [priorityPrefix, setPriorityPrefix] = useState('');\n const [dueDatePrefix, setDueDatePrefix] = useState('');\n const [verifyBeforeCreate, setVerifyBeforeCreate] = useState(true);\n const [formError, setFormError] = useState<string | null>(null);\n const [created, setCreated] = useState<CreatedSync | null>(null);\n const [runResult, setRunResult] = useState<SyncRunResult | null>(null);\n\n const [create, state] = useMutation<{ planmagnetCreateExternalSync: CreatedSync }>(CREATE_SYNC, {\n refetchQueries: ['SyncsList'],\n });\n\n const capability = capabilities.find((c) => c.provider === provider);\n const isGithub = provider === 'GITHUB';\n const allowedDirections = capability\n ? SYNC_DIRECTIONS.filter((d) => directionSupported(capability, d))\n : [];\n\n const ownerValid = owner.trim() !== '' && isValidGithubOwner(owner);\n const repoValid = repo.trim() !== '' && isValidGithubRepo(repo);\n const step2Complete =\n !!provider && !!projectId && (!isGithub || (ownerValid && repoValid)) && !!direction;\n const step3Complete = step2Complete && token.trim() !== '';\n\n const buildInput = () => {\n const fieldMapping: Record<string, string> = {};\n if (priorityPrefix.trim()) fieldMapping.priority = priorityPrefix.trim();\n if (dueDatePrefix.trim()) fieldMapping.dueDate = dueDatePrefix.trim();\n return {\n projectId,\n provider,\n direction,\n externalProjectId: isGithub ? `${owner.trim()}/${repo.trim()}` : '',\n externalProjectUrl: isGithub\n ? `https://github.com/${owner.trim()}/${repo.trim()}`\n : undefined,\n connectionConfig: isGithub\n ? { token: token.trim(), owner: owner.trim(), repo: repo.trim() }\n : {},\n conflictStrategy,\n ...(Object.keys(fieldMapping).length > 0 ? { fieldMapping } : {}),\n testConnection: verifyBeforeCreate,\n };\n };\n\n const submit = async () => {\n setFormError(null);\n if (!step3Complete) {\n setFormError(\n 'Fill in the project, external project and credentials above before creating the sync.'\n );\n return;\n }\n try {\n const res = await throwOnError(create({ variables: { input: buildInput() } }));\n if (res.data) setCreated(res.data.planmagnetCreateExternalSync);\n } catch (e) {\n setFormError(\n isForbidden(e)\n ? 'Your role can view integrations but not set them up.'\n : mutationErrorMessage(e, 'The sync could not be created.')\n );\n }\n };\n\n if (created) {\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <Card data-testid=\"sync-wizard-created\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <CheckCircle2 className=\"h-5 w-5 text-status-success-text\" />\n Sync created\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">\n {providerLabel(created.provider)} sync for {created.project?.name ?? 'the project'} is\n set up and idle. Test the connection and run the first sync now, or do either later\n from the sync&apos;s own page.\n </p>\n <div className=\"flex flex-wrap items-center gap-3\">\n <TestConnectionButton syncId={created.id} />\n <RunNowButton syncId={created.id} onResult={setRunResult} />\n </div>\n {runResult && <SyncRunResultSummary result={runResult} />}\n <Button\n onClick={() => navigate(detailPath('/integrations/sync-detail-page', created.id))}\n data-testid=\"sync-wizard-view\"\n >\n View sync\n </Button>\n </CardContent>\n </Card>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <div className=\"flex items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Back to Integrations\"\n onClick={() => navigate('/integrations/syncs-page')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Set up a sync</h1>\n <p className=\"text-sm text-muted-foreground\">\n Connect a PlanMagnet project to an external issue tracker so work items stay in step on\n both sides.\n </p>\n </div>\n </div>\n\n <ProviderStep\n capabilities={capabilities}\n capabilitiesLoading={capabilitiesLoading}\n provider={provider}\n onSelect={(p) => {\n setProvider(p);\n setDirection('');\n setOwner('');\n setRepo('');\n setToken('');\n }}\n />\n\n {provider && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>2. Project, external project and direction</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label htmlFor=\"sync-wizard-project\" className={label}>\n PlanMagnet project\n </label>\n <div className=\"mt-1\">\n <ProjectSelect\n id=\"sync-wizard-project\"\n value={projectId}\n noneLabel=\"Choose a project\"\n onChange={setProjectId}\n />\n </div>\n </div>\n {isGithub && (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label htmlFor=\"sync-wizard-owner\" className={label}>\n GitHub owner (user or org)\n </label>\n <Input\n id=\"sync-wizard-owner\"\n className=\"mt-1\"\n placeholder=\"e.g. algoshred\"\n value={owner}\n data-testid=\"sync-wizard-owner\"\n onChange={(e) => setOwner(e.target.value)}\n />\n {owner.trim() !== '' && !ownerValid && (\n <ErrorLine message=\"Not a valid GitHub owner name.\" />\n )}\n </div>\n <div>\n <label htmlFor=\"sync-wizard-repo\" className={label}>\n Repository\n </label>\n <Input\n id=\"sync-wizard-repo\"\n className=\"mt-1\"\n placeholder=\"e.g. wspace-planmagnet-svc\"\n value={repo}\n data-testid=\"sync-wizard-repo\"\n onChange={(e) => setRepo(e.target.value)}\n />\n {repo.trim() !== '' && !repoValid && (\n <ErrorLine message=\"Not a valid repository name.\" />\n )}\n </div>\n </div>\n )}\n <div>\n <span className={label}>Direction</span>\n {allowedDirections.length === 0 ? (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n This provider offers no live sync direction yet.\n </p>\n ) : (\n <div className=\"mt-1 flex flex-col gap-1\" role=\"radiogroup\" aria-label=\"Direction\">\n {allowedDirections.map((d) => (\n <label key={d} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n name=\"sync-wizard-direction\"\n checked={direction === d}\n data-testid={`sync-wizard-direction-${d}`}\n onChange={() => setDirection(d)}\n />\n {directionLabel(d)}\n </label>\n ))}\n </div>\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {step2Complete && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>3. Credentials</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {isGithub && (\n <>\n <p className=\"text-sm text-muted-foreground\">\n Use a GitHub fine-grained personal access token scoped to{' '}\n <strong>\n {owner}/{repo}\n </strong>\n , with Issues set to <strong>Read and write</strong> — no other repository\n permission is needed.\n </p>\n <div className=\"max-w-sm\">\n <label htmlFor=\"sync-wizard-token\" className={label}>\n Personal access token\n </label>\n <Input\n id=\"sync-wizard-token\"\n type=\"password\"\n autoComplete=\"off\"\n className=\"mt-1\"\n value={token}\n data-testid=\"sync-wizard-token\"\n onChange={(e) => setToken(e.target.value)}\n />\n </div>\n </>\n )}\n </CardContent>\n </Card>\n )}\n\n {step3Complete && (\n <>\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>4. Conflict strategy</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">\n What happens when the same item changed on both sides since the last sync.\n </p>\n <div className=\"flex flex-col gap-1\" role=\"radiogroup\" aria-label=\"Conflict strategy\">\n {CONFLICT_RESOLUTIONS.map((r) => (\n <label key={r} className=\"flex items-start gap-2 text-sm\">\n <input\n type=\"radio\"\n name=\"sync-wizard-strategy\"\n className=\"mt-0.5\"\n checked={conflictStrategy === r}\n data-testid={`sync-wizard-strategy-${r}`}\n onChange={() => setConflictStrategy(r)}\n />\n <span>\n <span className=\"font-medium\">{enumLabel(r)}</span>\n <span className=\"block text-xs text-muted-foreground\">\n {CONFLICT_STRATEGY_EXPLANATION[r]}\n </span>\n </span>\n </label>\n ))}\n </div>\n </CardContent>\n </Card>\n\n {isGithub && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>5. Field mapping (optional)</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n GitHub issues have no native priority or due-date field — PlanMagnet encodes each\n as a label of the form <code>prefix+value</code> (e.g. <code>priority:HIGH</code>,{' '}\n <code>due:2026-10-01</code>\n ). Leave both blank to use the built-in prefixes.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"sync-wizard-priority-prefix\"\n className=\"text-xs text-muted-foreground\"\n >\n Priority label prefix (default &quot;{GITHUB_FIELD_MAPPING_DEFAULTS.priority}\n &quot;)\n </label>\n <Input\n id=\"sync-wizard-priority-prefix\"\n className=\"mt-1\"\n placeholder={GITHUB_FIELD_MAPPING_DEFAULTS.priority}\n value={priorityPrefix}\n onChange={(e) => setPriorityPrefix(e.target.value)}\n />\n </div>\n <div>\n <label\n htmlFor=\"sync-wizard-duedate-prefix\"\n className=\"text-xs text-muted-foreground\"\n >\n Due-date label prefix (default &quot;{GITHUB_FIELD_MAPPING_DEFAULTS.dueDate}\n &quot;)\n </label>\n <Input\n id=\"sync-wizard-duedate-prefix\"\n className=\"mt-1\"\n placeholder={GITHUB_FIELD_MAPPING_DEFAULTS.dueDate}\n value={dueDatePrefix}\n onChange={(e) => setDueDatePrefix(e.target.value)}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>6. Review &amp; create</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <dl className=\"grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-1 text-sm\">\n <dt className=\"text-muted-foreground\">Provider</dt>\n <dd>{providerLabel(provider)}</dd>\n <dt className=\"text-muted-foreground\">Direction</dt>\n <dd>{direction ? directionLabel(direction) : '—'}</dd>\n <dt className=\"text-muted-foreground\">External project</dt>\n <dd>{isGithub ? `${owner}/${repo}` : '—'}</dd>\n <dt className=\"text-muted-foreground\">Conflict strategy</dt>\n <dd>{enumLabel(conflictStrategy)}</dd>\n </dl>\n <label className=\"flex items-start gap-2 text-sm\">\n <Checkbox\n checked={verifyBeforeCreate}\n onCheckedChange={(checked) => setVerifyBeforeCreate(checked === true)}\n data-testid=\"sync-wizard-verify\"\n />\n <span>\n Verify the connection before creating (recommended)\n <span className=\"block text-xs text-muted-foreground\">\n Probes the credentials first; the sync is not created if the probe fails.\n </span>\n </span>\n </label>\n {formError && <ErrorLine message={formError} />}\n <Button\n onClick={() => void submit()}\n disabled={state.loading}\n data-testid=\"sync-wizard-create\"\n >\n {state.loading ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <ShieldQuestion className=\"mr-1 h-4 w-4\" />\n )}\n Create sync\n </Button>\n </CardContent>\n </Card>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"IntegrationsNewSyncPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/IntegrationsNewSyncPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Checkbox,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport { ArrowLeft, CheckCircle2, Github, Loader2, Plug, ShieldQuestion } from 'lucide-react';\nimport { usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath } from '../utils/rowNavigation';\nimport { throwOnError } from '../utils/mutationResult';\nimport { isForbidden, mutationErrorMessage } from '../utils/graphqlErrors';\nimport { ErrorLine } from '../controls/ConfirmButton';\nimport { ProjectSelect } from '../controls/Pickers';\nimport { enumLabel } from '../controls/WorkItemControls';\nimport {\n RunNowButton,\n SyncRunResultSummary,\n TestConnectionButton,\n CONFLICT_STRATEGY_EXPLANATION,\n} from '../controls/SyncControls';\nimport { useSyncProviderCapabilities } from '../integrations/useSyncProviderCapabilities';\nimport {\n CONFLICT_RESOLUTIONS,\n directionLabel,\n directionSupported,\n GITHUB_FIELD_MAPPING_DEFAULTS,\n isValidGithubOwner,\n isValidGithubRepo,\n providerIsLive,\n providerLabel,\n SYNC_DIRECTIONS,\n type ConflictResolution,\n type SyncDirection,\n type SyncProvider,\n type SyncProviderCapability,\n type SyncRunResult,\n} from '../integrations/syncTypes';\n\n/**\n * Sync setup wizard (AUT-08): create an ExternalSync step by step, driven entirely by\n * `planmagnetSupportedSyncProviders` — a provider is selectable, and a direction is offered, only when the\n * capability list says it is real, never a hard-coded \"GitHub only\" rule. Today that capability list happens to\n * make GITHUB the only live choice (BOFF-4446); the connection fields below (owner/repo/token) are GitHub's own\n * documented `connectionConfig` shape and only make sense for it — there is nothing to generalize them to until\n * a second connector ships.\n */\n\nconst label = 'text-sm font-medium';\n\nconst CREATE_SYNC = gql`\n mutation NewSyncCreate($input: PlanmagnetCreateExternalSyncInput!) {\n planmagnetCreateExternalSync(input: $input) {\n id\n provider\n status\n project {\n id\n name\n }\n }\n }\n`;\n\ninterface CreatedSync {\n id: string;\n provider: string;\n status: string;\n project: { id: string; name: string } | null;\n}\n\nfunction ProviderStep({\n capabilities,\n capabilitiesLoading,\n provider,\n onSelect,\n}: {\n capabilities: SyncProviderCapability[];\n capabilitiesLoading: boolean;\n provider: SyncProvider | '';\n onSelect: (p: SyncProvider) => void;\n}) {\n return (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>1. Provider</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {capabilitiesLoading && <p className=\"text-sm text-muted-foreground\">Loading providers…</p>}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n {capabilities.map((c) => {\n const live = providerIsLive(c);\n const selected = provider === c.provider;\n return (\n <button\n key={c.provider}\n type=\"button\"\n disabled={!live}\n aria-pressed={selected}\n data-testid={`sync-wizard-provider-${c.provider}`}\n onClick={() => live && onSelect(c.provider)}\n className={`flex items-start gap-2 rounded-md border p-3 text-left text-sm transition-colors ${\n selected ? 'border-primary bg-primary/5' : 'border-input'\n } ${live ? 'hover:bg-muted' : 'cursor-not-allowed opacity-50'}`}\n >\n {c.provider === 'GITHUB' ? (\n <Github className=\"mt-0.5 h-4 w-4 shrink-0\" />\n ) : (\n <Plug className=\"mt-0.5 h-4 w-4 shrink-0\" />\n )}\n <span>\n <span className=\"block font-medium\">{providerLabel(c.provider)}</span>\n <span className=\"block text-xs text-muted-foreground\">\n {live\n ? [\n c.supportsImport && 'inbound',\n c.supportsExport && 'outbound',\n c.supportsBidirectional && 'bidirectional',\n ]\n .filter(Boolean)\n .join(', ') + ' sync'\n : 'No live connector yet — inbound, outbound and bidirectional sync are all unavailable for this provider.'}\n </span>\n </span>\n </button>\n );\n })}\n </div>\n </CardContent>\n </Card>\n );\n}\n\nexport function IntegrationsNewSyncPagePage() {\n const navigate = usePlanMagnetNavigate();\n const { capabilities, loading: capabilitiesLoading } = useSyncProviderCapabilities();\n\n const [provider, setProvider] = useState<SyncProvider | ''>('');\n const [projectId, setProjectId] = useState('');\n const [owner, setOwner] = useState('');\n const [repo, setRepo] = useState('');\n const [direction, setDirection] = useState<SyncDirection | ''>('');\n const [token, setToken] = useState('');\n const [conflictStrategy, setConflictStrategy] = useState<ConflictResolution>('MANUAL');\n const [priorityPrefix, setPriorityPrefix] = useState('');\n const [dueDatePrefix, setDueDatePrefix] = useState('');\n const [verifyBeforeCreate, setVerifyBeforeCreate] = useState(true);\n const [formError, setFormError] = useState<string | null>(null);\n const [created, setCreated] = useState<CreatedSync | null>(null);\n const [runResult, setRunResult] = useState<SyncRunResult | null>(null);\n\n const [create, state] = useMutation<{ planmagnetCreateExternalSync: CreatedSync }>(CREATE_SYNC, {\n refetchQueries: ['SyncsList'],\n });\n\n const capability = capabilities.find((c) => c.provider === provider);\n const isGithub = provider === 'GITHUB';\n const allowedDirections = capability\n ? SYNC_DIRECTIONS.filter((d) => directionSupported(capability, d))\n : [];\n\n const ownerValid = owner.trim() !== '' && isValidGithubOwner(owner);\n const repoValid = repo.trim() !== '' && isValidGithubRepo(repo);\n const step2Complete =\n !!provider && !!projectId && (!isGithub || (ownerValid && repoValid)) && !!direction;\n const step3Complete = step2Complete && token.trim() !== '';\n\n const buildInput = () => {\n const fieldMapping: Record<string, string> = {};\n if (priorityPrefix.trim()) fieldMapping.priority = priorityPrefix.trim();\n if (dueDatePrefix.trim()) fieldMapping.dueDate = dueDatePrefix.trim();\n return {\n projectId,\n provider,\n direction,\n externalProjectId: isGithub ? `${owner.trim()}/${repo.trim()}` : '',\n externalProjectUrl: isGithub\n ? `https://github.com/${owner.trim()}/${repo.trim()}`\n : undefined,\n connectionConfig: isGithub\n ? { token: token.trim(), owner: owner.trim(), repo: repo.trim() }\n : {},\n conflictStrategy,\n ...(Object.keys(fieldMapping).length > 0 ? { fieldMapping } : {}),\n testConnection: verifyBeforeCreate,\n };\n };\n\n const submit = async () => {\n setFormError(null);\n if (!step3Complete) {\n setFormError(\n 'Fill in the project, external project and credentials above before creating the sync.'\n );\n return;\n }\n try {\n const res = await throwOnError(create({ variables: { input: buildInput() } }));\n if (res.data) setCreated(res.data.planmagnetCreateExternalSync);\n } catch (e) {\n setFormError(\n isForbidden(e)\n ? 'Your role can view integrations but not set them up.'\n : mutationErrorMessage(e, 'The sync could not be created.')\n );\n }\n };\n\n if (created) {\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <Card data-testid=\"sync-wizard-created\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <CheckCircle2 className=\"h-5 w-5 text-status-success-text\" />\n Sync created\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">\n {providerLabel(created.provider)} sync for {created.project?.name ?? 'the project'} is\n set up and idle. Test the connection and run the first sync now, or do either later\n from the sync&apos;s own page.\n </p>\n <div className=\"flex flex-wrap items-center gap-3\">\n <TestConnectionButton syncId={created.id} />\n <RunNowButton syncId={created.id} onResult={setRunResult} />\n </div>\n {runResult && <SyncRunResultSummary result={runResult} />}\n <Button\n onClick={() => navigate(detailPath('/integrations/sync-detail-page', created.id))}\n data-testid=\"sync-wizard-view\"\n >\n View sync\n </Button>\n </CardContent>\n </Card>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6 max-w-2xl\">\n <div className=\"flex items-start gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"Back to Integrations\"\n onClick={() => navigate('/integrations/syncs-page')}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div>\n <h1 className=\"text-2xl font-semibold\">Set up a sync</h1>\n <p className=\"text-sm text-muted-foreground\">\n Connect a PlanMagnet project to an external issue tracker so work items stay in step on\n both sides.\n </p>\n </div>\n </div>\n\n <ProviderStep\n capabilities={capabilities}\n capabilitiesLoading={capabilitiesLoading}\n provider={provider}\n onSelect={(p) => {\n setProvider(p);\n setDirection('');\n setOwner('');\n setRepo('');\n setToken('');\n }}\n />\n\n {provider && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>2. Project, external project and direction</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label htmlFor=\"sync-wizard-project\" className={label}>\n PlanMagnet project\n </label>\n <div className=\"mt-1\">\n <ProjectSelect\n id=\"sync-wizard-project\"\n value={projectId}\n noneLabel=\"Choose a project\"\n onChange={setProjectId}\n />\n </div>\n </div>\n {isGithub && (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label htmlFor=\"sync-wizard-owner\" className={label}>\n GitHub owner (user or org)\n </label>\n <Input\n id=\"sync-wizard-owner\"\n className=\"mt-1\"\n placeholder=\"e.g. algoshred\"\n value={owner}\n data-testid=\"sync-wizard-owner\"\n onChange={(e) => setOwner(e.target.value)}\n />\n {owner.trim() !== '' && !ownerValid && (\n <ErrorLine message=\"Not a valid GitHub owner name.\" />\n )}\n </div>\n <div>\n <label htmlFor=\"sync-wizard-repo\" className={label}>\n Repository\n </label>\n <Input\n id=\"sync-wizard-repo\"\n className=\"mt-1\"\n placeholder=\"e.g. wspace-planmagnet-svc\"\n value={repo}\n data-testid=\"sync-wizard-repo\"\n onChange={(e) => setRepo(e.target.value)}\n />\n {repo.trim() !== '' && !repoValid && (\n <ErrorLine message=\"Not a valid repository name.\" />\n )}\n </div>\n </div>\n )}\n <div>\n <span className={label}>Direction</span>\n {allowedDirections.length === 0 ? (\n <p className=\"mt-1 text-sm text-muted-foreground\">\n This provider offers no live sync direction yet.\n </p>\n ) : (\n <div className=\"mt-1 flex flex-col gap-1\" role=\"radiogroup\" aria-label=\"Direction\">\n {allowedDirections.map((d) => (\n <label key={d} className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"radio\"\n name=\"sync-wizard-direction\"\n checked={direction === d}\n data-testid={`sync-wizard-direction-${d}`}\n onChange={() => setDirection(d)}\n />\n {directionLabel(d)}\n </label>\n ))}\n </div>\n )}\n </div>\n </CardContent>\n </Card>\n )}\n\n {step2Complete && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>3. Credentials</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {isGithub && (\n <>\n <p className=\"text-sm text-muted-foreground\">\n Use a GitHub fine-grained personal access token scoped to{' '}\n <strong>\n {owner}/{repo}\n </strong>\n , with Issues set to <strong>Read and write</strong> — no other repository\n permission is needed.\n </p>\n <div className=\"max-w-sm\">\n <label htmlFor=\"sync-wizard-token\" className={label}>\n Personal access token\n </label>\n <Input\n id=\"sync-wizard-token\"\n type=\"password\"\n autoComplete=\"off\"\n className=\"mt-1\"\n value={token}\n data-testid=\"sync-wizard-token\"\n onChange={(e) => setToken(e.target.value)}\n />\n </div>\n </>\n )}\n </CardContent>\n </Card>\n )}\n\n {step3Complete && (\n <>\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>4. Conflict strategy</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground\">\n What happens when the same item changed on both sides since the last sync.\n </p>\n <div className=\"flex flex-col gap-1\" role=\"radiogroup\" aria-label=\"Conflict strategy\">\n {CONFLICT_RESOLUTIONS.map((r) => (\n <label key={r} className=\"flex items-start gap-2 text-sm\">\n <input\n type=\"radio\"\n name=\"sync-wizard-strategy\"\n className=\"mt-0.5\"\n checked={conflictStrategy === r}\n data-testid={`sync-wizard-strategy-${r}`}\n onChange={() => setConflictStrategy(r)}\n />\n <span>\n <span className=\"font-medium\">{enumLabel(r)}</span>\n <span className=\"block text-xs text-muted-foreground\">\n {CONFLICT_STRATEGY_EXPLANATION[r]}\n </span>\n </span>\n </label>\n ))}\n </div>\n </CardContent>\n </Card>\n\n {isGithub && (\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>5. Field mapping (optional)</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n GitHub issues have no native priority or due-date field — PlanMagnet encodes each\n as a label of the form <code>prefix+value</code> (e.g. <code>priority:HIGH</code>,{' '}\n <code>due:2026-10-01</code>\n ). Leave both blank to use the built-in prefixes.\n </p>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3\">\n <div>\n <label\n htmlFor=\"sync-wizard-priority-prefix\"\n className=\"text-xs text-muted-foreground\"\n >\n Priority label prefix (default &quot;{GITHUB_FIELD_MAPPING_DEFAULTS.priority}\n &quot;)\n </label>\n <Input\n id=\"sync-wizard-priority-prefix\"\n className=\"mt-1\"\n placeholder={GITHUB_FIELD_MAPPING_DEFAULTS.priority}\n value={priorityPrefix}\n onChange={(e) => setPriorityPrefix(e.target.value)}\n />\n </div>\n <div>\n <label\n htmlFor=\"sync-wizard-duedate-prefix\"\n className=\"text-xs text-muted-foreground\"\n >\n Due-date label prefix (default &quot;{GITHUB_FIELD_MAPPING_DEFAULTS.dueDate}\n &quot;)\n </label>\n <Input\n id=\"sync-wizard-duedate-prefix\"\n className=\"mt-1\"\n placeholder={GITHUB_FIELD_MAPPING_DEFAULTS.dueDate}\n value={dueDatePrefix}\n onChange={(e) => setDueDatePrefix(e.target.value)}\n />\n </div>\n </div>\n </CardContent>\n </Card>\n )}\n\n <Card data-testid=\"sync-wizard-step\">\n <CardHeader>\n <CardTitle>6. Review &amp; create</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <dl className=\"grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-1 text-sm\">\n <dt className=\"text-muted-foreground\">Provider</dt>\n <dd>{providerLabel(provider)}</dd>\n <dt className=\"text-muted-foreground\">Direction</dt>\n <dd>{direction ? directionLabel(direction) : '—'}</dd>\n <dt className=\"text-muted-foreground\">External project</dt>\n <dd>{isGithub ? `${owner}/${repo}` : '—'}</dd>\n <dt className=\"text-muted-foreground\">Conflict strategy</dt>\n <dd>{enumLabel(conflictStrategy)}</dd>\n </dl>\n <label className=\"flex items-start gap-2 text-sm\">\n <Checkbox\n checked={verifyBeforeCreate}\n onCheckedChange={(checked) => setVerifyBeforeCreate(checked === true)}\n data-testid=\"sync-wizard-verify\"\n />\n <span>\n Verify the connection before creating (recommended)\n <span className=\"block text-xs text-muted-foreground\">\n Probes the credentials first; the sync is not created if the probe fails.\n </span>\n </span>\n </label>\n {formError && <ErrorLine message={formError} />}\n <Button\n onClick={() => void submit()}\n disabled={state.loading}\n data-testid=\"sync-wizard-create\"\n >\n {state.loading ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <ShieldQuestion className=\"mr-1 h-4 w-4\" />\n )}\n Create sync\n </Button>\n </CardContent>\n </Card>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAqDA,IAAM,IAAQ,uBAER,KAAc,CAAG;;;;;;;;;;;;;AAqBvB,SAAS,GAAa,EACpB,iBACA,wBACA,aACA,eAMC;AACD,QACE,kBAAC,GAAD;EAAM,eAAY;YAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,eAAuB,CAAA,EACvB,CAAA,EACb,kBAAC,GAAD;GAAa,WAAU;aAAvB,CACG,KAAuB,kBAAC,KAAD;IAAG,WAAU;cAAgC;IAAsB,CAAA,EAC3F,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAa,KAAK,MAAM;KACvB,IAAM,IAAO,EAAe,EAAE,EACxB,IAAW,MAAa,EAAE;AAChC,YACE,kBAAC,UAAD;MAEE,MAAK;MACL,UAAU,CAAC;MACX,gBAAc;MACd,eAAa,wBAAwB,EAAE;MACvC,eAAe,KAAQ,EAAS,EAAE,SAAS;MAC3C,WAAW,oFACT,IAAW,gCAAgC,eAC5C,GAAG,IAAO,mBAAmB;gBAThC,CAWG,EAAE,aAAa,WACd,kBAAC,GAAD,EAAQ,WAAU,2BAA4B,CAAA,GAE9C,kBAAC,GAAD,EAAM,WAAU,2BAA4B,CAAA,EAE9C,kBAAC,QAAD,EAAA,UAAA,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAqB,EAAc,EAAE,SAAS;OAAQ,CAAA,EACtE,kBAAC,QAAD;OAAM,WAAU;iBACb,IACG;QACE,EAAE,kBAAkB;QACpB,EAAE,kBAAkB;QACpB,EAAE,yBAAyB;QAC5B,CACE,OAAO,QAAQ,CACf,KAAK,KAAK,GAAG,UAChB;OACC,CAAA,CACF,EAAA,CAAA,CACA;QA7BF,EAAE,SA6BA;MAEX;IACE,CAAA,CACM;KACT;;;AAIX,SAAgB,IAA8B;CAC5C,IAAM,IAAW,GAAuB,EAClC,EAAE,iBAAc,SAAS,MAAwB,GAA6B,EAE9E,CAAC,GAAU,KAAe,EAA4B,GAAG,EACzD,CAAC,GAAW,MAAgB,EAAS,GAAG,EACxC,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAW,KAAgB,EAA6B,GAAG,EAC5D,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAkB,MAAuB,EAA6B,SAAS,EAChF,CAAC,GAAgB,MAAqB,EAAS,GAAG,EAClD,CAAC,GAAe,MAAoB,EAAS,GAAG,EAChD,CAAC,GAAoB,MAAyB,EAAS,GAAK,EAC5D,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,CAAC,GAAS,MAAc,EAA6B,KAAK,EAC1D,CAAC,GAAW,MAAgB,EAA+B,KAAK,EAEhE,CAAC,GAAQ,KAAS,GAA2D,IAAa,EAC9F,gBAAgB,CAAC,YAAY,EAC9B,CAAC,EAEI,IAAa,EAAa,MAAM,MAAM,EAAE,aAAa,EAAS,EAC9D,IAAW,MAAa,UACxB,IAAoB,IACtB,GAAgB,QAAQ,MAAM,GAAmB,GAAY,EAAE,CAAC,GAChE,EAAE,EAEA,IAAa,EAAM,MAAM,KAAK,MAAM,GAAmB,EAAM,EAC7D,IAAY,EAAK,MAAM,KAAK,MAAM,GAAkB,EAAK,EACzD,IACJ,CAAC,CAAC,KAAY,CAAC,CAAC,MAAc,CAAC,KAAa,KAAc,MAAe,CAAC,CAAC,GACvE,IAAgB,KAAiB,EAAM,MAAM,KAAK,IAElD,WAAmB;EACvB,IAAM,IAAuC,EAAE;AAG/C,SAFI,EAAe,MAAM,KAAE,EAAa,WAAW,EAAe,MAAM,GACpE,EAAc,MAAM,KAAE,EAAa,UAAU,EAAc,MAAM,GAC9D;GACL;GACA;GACA;GACA,mBAAmB,IAAW,GAAG,EAAM,MAAM,CAAC,GAAG,EAAK,MAAM,KAAK;GACjE,oBAAoB,IAChB,sBAAsB,EAAM,MAAM,CAAC,GAAG,EAAK,MAAM,KACjD,KAAA;GACJ,kBAAkB,IACd;IAAE,OAAO,EAAM,MAAM;IAAE,OAAO,EAAM,MAAM;IAAE,MAAM,EAAK,MAAM;IAAE,GAC/D,EAAE;GACN;GACA,GAAI,OAAO,KAAK,EAAa,CAAC,SAAS,IAAI,EAAE,iBAAc,GAAG,EAAE;GAChE,gBAAgB;GACjB;IAGG,KAAS,YAAY;AAEzB,MADA,EAAa,KAAK,EACd,CAAC,GAAe;AAClB,KACE,wFACD;AACD;;AAEF,MAAI;GACF,IAAM,IAAM,MAAM,EAAa,EAAO,EAAE,WAAW,EAAE,OAAO,IAAY,EAAE,EAAE,CAAC,CAAC;AAC9E,GAAI,EAAI,QAAM,GAAW,EAAI,KAAK,6BAA6B;WACxD,GAAG;AACV,KACE,EAAY,EAAE,GACV,yDACA,EAAqB,GAAG,iCAAiC,CAC9D;;;AAqCL,QAjCI,IAEA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GAAM,eAAY;aAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD;IAAW,WAAU;cAArB,CACE,kBAAC,IAAD,EAAc,WAAU,oCAAqC,CAAA,EAAA,eAEnD;OACD,CAAA,EACb,kBAAC,GAAD;IAAa,WAAU;cAAvB;KACE,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACG,EAAc,EAAQ,SAAS;OAAC;OAAW,EAAQ,SAAS,QAAQ;OAAc;OAGjF;;KACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAsB,QAAQ,EAAQ,IAAM,CAAA,EAC5C,kBAAC,IAAD;OAAc,QAAQ,EAAQ;OAAI,UAAU;OAAgB,CAAA,CACxD;;KACL,KAAa,kBAAC,IAAD,EAAsB,QAAQ,GAAa,CAAA;KACzD,kBAAC,GAAD;MACE,eAAe,EAAS,GAAW,kCAAkC,EAAQ,GAAG,CAAC;MACjF,eAAY;gBACb;MAEQ,CAAA;KACG;MACT;;EACH,CAAA,GAKR,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KACE,SAAQ;KACR,MAAK;KACL,cAAW;KACX,eAAe,EAAS,2BAA2B;eAEnD,kBAAC,IAAD,EAAW,WAAU,WAAY,CAAA;KAC1B,CAAA,EACT,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;KAAI,WAAU;eAAyB;KAAkB,CAAA,EACzD,kBAAC,KAAD;KAAG,WAAU;eAAgC;KAGzC,CAAA,CACA,EAAA,CAAA,CACF;;GAEN,kBAAC,IAAD;IACgB;IACO;IACX;IACV,WAAW,MAAM;AAKf,KAJA,EAAY,EAAE,EACd,EAAa,GAAG,EAChB,EAAS,GAAG,EACZ,EAAQ,GAAG,EACX,EAAS,GAAG;;IAEd,CAAA;GAED,KACC,kBAAC,GAAD;IAAM,eAAY;cAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,8CAAsD,CAAA,EACtD,CAAA,EACb,kBAAC,GAAD;KAAa,WAAU;eAAvB;MACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAsB,WAAW;iBAAO;OAE/C,CAAA,EACR,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,IAAD;QACE,IAAG;QACH,OAAO;QACP,WAAU;QACV,UAAU;QACV,CAAA;OACE,CAAA,CACF,EAAA,CAAA;MACL,KACC,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,SAAD;SAAO,SAAQ;SAAoB,WAAW;mBAAO;SAE7C,CAAA;QACR,kBAAC,GAAD;SACE,IAAG;SACH,WAAU;SACV,aAAY;SACZ,OAAO;SACP,eAAY;SACZ,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;SACzC,CAAA;QACD,EAAM,MAAM,KAAK,MAAM,CAAC,KACvB,kBAAC,GAAD,EAAW,SAAQ,kCAAmC,CAAA;QAEpD,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,SAAD;SAAO,SAAQ;SAAmB,WAAW;mBAAO;SAE5C,CAAA;QACR,kBAAC,GAAD;SACE,IAAG;SACH,WAAU;SACV,aAAY;SACZ,OAAO;SACP,eAAY;SACZ,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;SACxC,CAAA;QACD,EAAK,MAAM,KAAK,MAAM,CAAC,KACtB,kBAAC,GAAD,EAAW,SAAQ,gCAAiC,CAAA;QAElD,EAAA,CAAA,CACF;;MAER,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;OAAM,WAAW;iBAAO;OAAgB,CAAA,EACvC,EAAkB,WAAW,IAC5B,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAE9C,CAAA,GAEJ,kBAAC,OAAD;OAAK,WAAU;OAA2B,MAAK;OAAa,cAAW;iBACpE,EAAkB,KAAK,MACtB,kBAAC,SAAD;QAAe,WAAU;kBAAzB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,MAAK;SACL,SAAS,MAAc;SACvB,eAAa,yBAAyB;SACtC,gBAAgB,EAAa,EAAE;SAC/B,CAAA,EACD,EAAe,EAAE,CACZ;UATI,EASJ,CACR;OACE,CAAA,CAEJ,EAAA,CAAA;MACM;OACT;;GAGR,KACC,kBAAC,GAAD;IAAM,eAAY;cAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,kBAA0B,CAAA,EAC1B,CAAA,EACb,kBAAC,GAAD;KAAa,WAAU;eACpB,KACC,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAb;OAA6C;OACe;OAC1D,kBAAC,UAAD,EAAA,UAAA;QACG;QAAM;QAAE;QACF,EAAA,CAAA;;OACY,kBAAC,UAAD,EAAA,UAAQ,kBAAuB,CAAA;;OAElD;SACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,SAAQ;OAAoB,WAAW;iBAAO;OAE7C,CAAA,EACR,kBAAC,GAAD;OACE,IAAG;OACH,MAAK;OACL,cAAa;OACb,WAAU;OACV,OAAO;OACP,eAAY;OACZ,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;OACzC,CAAA,CACE;QACL,EAAA,CAAA;KAEO,CAAA,CACT;;GAGR,KACC,kBAAA,GAAA,EAAA,UAAA;IACE,kBAAC,GAAD;KAAM,eAAY;eAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,wBAAgC,CAAA,EAChC,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAgC;OAEzC,CAAA,EACJ,kBAAC,OAAD;OAAK,WAAU;OAAsB,MAAK;OAAa,cAAW;iBAC/D,EAAqB,KAAK,MACzB,kBAAC,SAAD;QAAe,WAAU;kBAAzB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,MAAK;SACL,WAAU;SACV,SAAS,MAAqB;SAC9B,eAAa,wBAAwB;SACrC,gBAAgB,GAAoB,EAAE;SACtC,CAAA,EACF,kBAAC,QAAD,EAAA,UAAA,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAe,EAAU,EAAE;SAAQ,CAAA,EACnD,kBAAC,QAAD;SAAM,WAAU;mBACb,GAA8B;SAC1B,CAAA,CACF,EAAA,CAAA,CACD;UAfI,EAeJ,CACR;OACE,CAAA,CACM;QACT;;IAEN,KACC,kBAAC,GAAD;KAAM,eAAY;eAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,+BAAuC,CAAA,EACvC,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAb;QAA6C;QAEpB,kBAAC,QAAD,EAAA,UAAM,gBAAmB,CAAA;;QAAO,kBAAC,QAAD,EAAA,UAAM,iBAAoB,CAAA;;QAAE;QACnF,kBAAC,QAAD,EAAA,UAAM,kBAAqB,CAAA;;QAEzB;UACJ,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QACE,SAAQ;QACR,WAAU;kBAFZ;SAGC;SACuC,EAA8B;SAAS;SAEvE;WACR,kBAAC,GAAD;QACE,IAAG;QACH,WAAU;QACV,aAAa,EAA8B;QAC3C,OAAO;QACP,WAAW,MAAM,GAAkB,EAAE,OAAO,MAAM;QAClD,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QACE,SAAQ;QACR,WAAU;kBAFZ;SAGC;SACuC,EAA8B;SAAQ;SAEtE;WACR,kBAAC,GAAD;QACE,IAAG;QACH,WAAU;QACV,aAAa,EAA8B;QAC3C,OAAO;QACP,WAAW,MAAM,GAAiB,EAAE,OAAO,MAAM;QACjD,CAAA,CACE,EAAA,CAAA,CACF;SACM;QACT;;IAGT,kBAAC,GAAD;KAAM,eAAY;eAAlB,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAW,sBAAkC,CAAA,EAClC,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACE,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAa,CAAA;SACnD,kBAAC,MAAD,EAAA,UAAK,EAAc,EAAS,EAAM,CAAA;SAClC,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAc,CAAA;SACpD,kBAAC,MAAD,EAAA,UAAK,IAAY,EAAe,EAAU,GAAG,KAAS,CAAA;SACtD,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAqB,CAAA;SAC3D,kBAAC,MAAD,EAAA,UAAK,IAAW,GAAG,EAAM,GAAG,MAAS,KAAS,CAAA;SAC9C,kBAAC,MAAD;UAAI,WAAU;oBAAwB;UAAsB,CAAA;SAC5D,kBAAC,MAAD,EAAA,UAAK,EAAU,EAAiB,EAAM,CAAA;SACnC;;OACL,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,IAAD;SACE,SAAS;SACT,kBAAkB,MAAY,GAAsB,MAAY,GAAK;SACrE,eAAY;SACZ,CAAA,EACF,kBAAC,QAAD,EAAA,UAAA,CAAM,uDAEJ,kBAAC,QAAD;SAAM,WAAU;mBAAsC;SAE/C,CAAA,CACF,EAAA,CAAA,CACD;;OACP,KAAa,kBAAC,GAAD,EAAW,SAAS,GAAa,CAAA;OAC/C,kBAAC,GAAD;QACE,eAAe,KAAK,IAAQ;QAC5B,UAAU,EAAM;QAChB,eAAY;kBAHd,CAKG,EAAM,UACL,kBAAC,IAAD,EAAS,WAAU,6BAA8B,CAAA,GAEjD,kBAAC,IAAD,EAAgB,WAAU,gBAAiB,CAAA,EAC3C,cAEK;;OACG;QACT;;IACN,EAAA,CAAA;GAED"}
@@ -1,7 +1,7 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
2
  import { enumLabel as n } from "../controls/WorkItemControls.js";
3
- import { ProjectSelect as r } from "../controls/Pickers.js";
4
- import { detailPath as i, rowLinkProps as a, stopRowActivation as o } from "../utils/rowNavigation.js";
3
+ import { detailPath as r, rowLinkProps as i, stopRowActivation as a } from "../utils/rowNavigation.js";
4
+ import { ProjectSelect as o } from "../controls/Pickers.js";
5
5
  import { SYNC_STATUSES as s, directionLabel as c, providerLabel as l } from "../integrations/syncTypes.js";
6
6
  import { PauseResumeButton as u, RunNowButton as d, SyncHealthSummary as f, SyncRunResultSummary as p, SyncStatusBadge as m, TruncatedText as h } from "../controls/SyncControls.js";
7
7
  import { useDeferredValue as g, useState as _ } from "react";
@@ -119,7 +119,7 @@ function M() {
119
119
  }), /* @__PURE__ */ w("div", {
120
120
  className: "w-48",
121
121
  "data-testid": "sync-list-project-filter",
122
- children: /* @__PURE__ */ w(r, {
122
+ children: /* @__PURE__ */ w(o, {
123
123
  id: "sync-list-filter-project",
124
124
  value: P,
125
125
  onChange: F,
@@ -163,7 +163,7 @@ function M() {
163
163
  /* @__PURE__ */ w("ul", {
164
164
  className: "space-y-3",
165
165
  children: Y.map((e) => {
166
- let t = a(() => S(i("/integrations/sync-detail-page", e.id)), `${l(e.provider)} sync for ${e.project?.name ?? "unknown project"}`);
166
+ let t = i(() => S(r("/integrations/sync-detail-page", e.id)), `${l(e.provider)} sync for ${e.project?.name ?? "unknown project"}`);
167
167
  return /* @__PURE__ */ T("li", {
168
168
  "data-testid": "sync-row",
169
169
  ...t,
@@ -197,7 +197,7 @@ function M() {
197
197
  target: "_blank",
198
198
  rel: "noreferrer noopener",
199
199
  className: "inline-flex items-center gap-1 text-primary hover:underline",
200
- onClick: o,
200
+ onClick: a,
201
201
  children: [e.externalProjectId, /* @__PURE__ */ w(v, { className: "h-3 w-3" })]
202
202
  }) : e.externalProjectId,
203
203
  " · ",
@@ -220,7 +220,7 @@ function M() {
220
220
  ]
221
221
  }), /* @__PURE__ */ T("div", {
222
222
  className: "flex shrink-0 flex-wrap items-center gap-2",
223
- onClick: o,
223
+ onClick: a,
224
224
  onKeyDown: (e) => e.stopPropagation(),
225
225
  children: [
226
226
  /* @__PURE__ */ w(d, {
@@ -237,13 +237,13 @@ function M() {
237
237
  /* @__PURE__ */ w(E, {
238
238
  size: "sm",
239
239
  variant: "ghost",
240
- onClick: () => S(i("/integrations/sync-detail-page", e.id)),
240
+ onClick: () => S(r("/integrations/sync-detail-page", e.id)),
241
241
  children: "Open"
242
242
  })
243
243
  ]
244
244
  })]
245
245
  }), B[e.id] && /* @__PURE__ */ w("div", {
246
- onClick: o,
246
+ onClick: a,
247
247
  onKeyDown: (e) => e.stopPropagation(),
248
248
  children: /* @__PURE__ */ w(p, { result: B[e.id] })
249
249
  })]
@@ -1,8 +1,8 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
2
  import { BUDGET_STATE_STYLE as n, budgetState as r, budgetUsage as i, money as a } from "../budgets/budgetMath.js";
3
3
  import { enumLabel as o } from "../controls/WorkItemControls.js";
4
- import { ProjectSelect as s } from "../controls/Pickers.js";
5
- import { detailPath as c, rowLinkProps as l } from "../utils/rowNavigation.js";
4
+ import { detailPath as s, rowLinkProps as c } from "../utils/rowNavigation.js";
5
+ import { ProjectSelect as l } from "../controls/Pickers.js";
6
6
  import { BUDGET_STATUSES as u, CreateBudgetDialog as d } from "../budgets/BudgetControls.js";
7
7
  import { useDeferredValue as f, useState as p } from "react";
8
8
  import { Wallet as m } from "lucide-react";
@@ -63,14 +63,14 @@ function O() {
63
63
  children: R ? O("planmagnet.budgets.subtitle", "{{count}} budget(s) across projects", { count: H }) : O("planmagnet.budgets.subtitleFallback", "Financial plans, tracked against actuals")
64
64
  })] }), /* @__PURE__ */ v(d, {
65
65
  presetProjectId: A || void 0,
66
- onCreated: (e) => g(c("/projects/budget-detail-page", e))
66
+ onCreated: (e) => g(s("/projects/budget-detail-page", e))
67
67
  })]
68
68
  }),
69
69
  /* @__PURE__ */ y("div", {
70
70
  className: "flex flex-wrap items-center gap-3",
71
71
  children: [/* @__PURE__ */ v("div", {
72
72
  className: "w-full max-w-xs",
73
- children: /* @__PURE__ */ v(s, {
73
+ children: /* @__PURE__ */ v(l, {
74
74
  id: "budgets-project-filter",
75
75
  value: A,
76
76
  onChange: j,
@@ -116,9 +116,9 @@ function O() {
116
116
  /* @__PURE__ */ v("div", {
117
117
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
118
118
  children: V.map((e) => {
119
- let t = i(e.plannedAmount, e.spentAmount), s = n[r(t)], u = t === null ? null : Math.round(t * 100);
119
+ let t = i(e.plannedAmount, e.spentAmount), l = n[r(t)], u = t === null ? null : Math.round(t * 100);
120
120
  return /* @__PURE__ */ y(x, {
121
- ...l(() => g(c("/projects/budget-detail-page", e.id)), e.name),
121
+ ...c(() => g(s("/projects/budget-detail-page", e.id)), e.name),
122
122
  children: [/* @__PURE__ */ v(C, {
123
123
  className: "pb-2",
124
124
  children: /* @__PURE__ */ y("div", {
@@ -159,15 +159,15 @@ function O() {
159
159
  "aria-valuemax": Math.max(100, u ?? 0),
160
160
  "aria-valuenow": u ?? 0,
161
161
  "aria-label": `${e.name}: ${u === null ? "no plan" : `${u}%`} spent`,
162
- className: `h-2 w-full overflow-hidden rounded-full ${s.track}`,
162
+ className: `h-2 w-full overflow-hidden rounded-full ${l.track}`,
163
163
  children: /* @__PURE__ */ v("div", {
164
- className: `h-full rounded-full ${s.fill}`,
164
+ className: `h-full rounded-full ${l.fill}`,
165
165
  style: { width: `${Math.min(u ?? 0, 100)}%` }
166
166
  })
167
167
  }),
168
168
  /* @__PURE__ */ y("span", {
169
- className: `flex items-center gap-1 text-xs ${s.text}`,
170
- children: [/* @__PURE__ */ v(s.icon, {
169
+ className: `flex items-center gap-1 text-xs ${l.text}`,
170
+ children: [/* @__PURE__ */ v(l.icon, {
171
171
  className: "h-3 w-3",
172
172
  "aria-hidden": !0
173
173
  }), u === null ? O("planmagnet.budgets.noPlan", "No plan set") : `${u}%`]
@@ -1,7 +1,7 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
- import { ProjectSelect as n } from "../controls/Pickers.js";
3
- import { useEntityId as r } from "../hooks/useEntityId.js";
4
- import { DependencyGraph as i } from "../dependency/DependencyGraph.js";
2
+ import { DependencyGraph as n } from "../dependency/DependencyGraph.js";
3
+ import { ProjectSelect as r } from "../controls/Pickers.js";
4
+ import { useEntityId as i } from "../hooks/useEntityId.js";
5
5
  import { criticalEdgeIdsFromPath as ee, useProjectWorkItemsGraph as a } from "../dependency/useProjectWorkItemsGraph.js";
6
6
  import { useEffect as o, useState as s } from "react";
7
7
  import { AlertTriangle as c, List as l, Route as u, Waypoints as d } from "lucide-react";
@@ -60,7 +60,7 @@ function E(e) {
60
60
  return r === 0 ? `${i}h` : i > 0 ? `${r}d ${i}h` : `${r} day${r === 1 ? "" : "s"}`;
61
61
  }
62
62
  function D() {
63
- let f = r(), { workspaceId: D } = e(), O = t(), [k, A] = s(""), [j, M] = s("list"), { data: N, loading: P, error: F } = p(S, {
63
+ let f = i(), { workspaceId: D } = e(), O = t(), [k, A] = s(""), [j, M] = s("list"), { data: N, loading: P, error: F } = p(S, {
64
64
  variables: {
65
65
  workspaceId: D ?? "",
66
66
  projectId: f
@@ -117,7 +117,7 @@ function D() {
117
117
  className: "text-sm font-medium",
118
118
  children: "Project"
119
119
  }),
120
- /* @__PURE__ */ h(n, {
120
+ /* @__PURE__ */ h(r, {
121
121
  id: "critical-path-project",
122
122
  value: k,
123
123
  onChange: A,
@@ -218,7 +218,7 @@ function D() {
218
218
  " are graphed."
219
219
  ]
220
220
  }),
221
- /* @__PURE__ */ h(i, {
221
+ /* @__PURE__ */ h(n, {
222
222
  nodes: B.items.map((e) => ({
223
223
  id: e.id,
224
224
  key: e.key,
@@ -1,8 +1,8 @@
1
1
  import { usePlanMagnetNavigate as e } from "../providers/PlanMagnetProvider.js";
2
2
  import { throwOnError as t } from "../utils/mutationResult.js";
3
3
  import { enumLabel as n } from "../controls/WorkItemControls.js";
4
- import { PortfolioSelect as r, ProgramSelect as i } from "../controls/Pickers.js";
5
- import { detailPath as a } from "../utils/rowNavigation.js";
4
+ import { detailPath as r } from "../utils/rowNavigation.js";
5
+ import { PortfolioSelect as i, ProgramSelect as a } from "../controls/Pickers.js";
6
6
  import { endBeforeStart as o } from "../utils/formValidation.js";
7
7
  import { useEntityId as s } from "../hooks/useEntityId.js";
8
8
  import { PROJECT_STATUSES as c } from "../controls/ProjectControls.js";
@@ -101,7 +101,7 @@ function E() {
101
101
  variant: "ghost",
102
102
  size: "sm",
103
103
  "aria-label": "Back to the project",
104
- onClick: () => E(a("/projects/project-detail-page", p)),
104
+ onClick: () => E(r("/projects/project-detail-page", p)),
105
105
  children: /* @__PURE__ */ g(d, { className: "h-4 w-4" })
106
106
  }), /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("h1", {
107
107
  className: "text-2xl font-semibold",
@@ -203,7 +203,7 @@ function E() {
203
203
  children: "Program"
204
204
  }), /* @__PURE__ */ g("div", {
205
205
  className: "mt-1",
206
- children: /* @__PURE__ */ g(i, {
206
+ children: /* @__PURE__ */ g(a, {
207
207
  id: "project-program",
208
208
  value: I.programId,
209
209
  onChange: (e) => L({
@@ -219,7 +219,7 @@ function E() {
219
219
  children: "Portfolio"
220
220
  }), /* @__PURE__ */ g("div", {
221
221
  className: "mt-1",
222
- children: /* @__PURE__ */ g(r, {
222
+ children: /* @__PURE__ */ g(i, {
223
223
  id: "project-portfolio",
224
224
  value: I.portfolioId,
225
225
  onChange: (e) => L({
@@ -1,6 +1,6 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
- import { TeamSelect as n } from "../controls/Pickers.js";
3
- import { detailPath as r, rowLinkProps as i } from "../utils/rowNavigation.js";
2
+ import { detailPath as n, rowLinkProps as r } from "../utils/rowNavigation.js";
3
+ import { TeamSelect as i } from "../controls/Pickers.js";
4
4
  import { NewSprintDialog as a } from "../sprints/SprintControls.js";
5
5
  import { useState as o } from "react";
6
6
  import { CalendarClock as s, FolderKanban as c, Users as l } from "lucide-react";
@@ -73,19 +73,19 @@ function S() {
73
73
  children: [T?.planmagnetSprints?.totalCount ?? O.length, " sprints across all projects"]
74
74
  })] }), /* @__PURE__ */ m("div", {
75
75
  className: "flex items-center gap-2",
76
- children: [/* @__PURE__ */ p(n, {
76
+ children: [/* @__PURE__ */ p(i, {
77
77
  value: C,
78
78
  onChange: w,
79
79
  noneLabel: "All teams"
80
- }), /* @__PURE__ */ p(a, { onCreated: (e) => S(r("/projects/planning-detail-page", e)) })]
80
+ }), /* @__PURE__ */ p(a, { onCreated: (e) => S(n("/projects/planning-detail-page", e)) })]
81
81
  })]
82
82
  }),
83
83
  /* @__PURE__ */ p("div", {
84
84
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
85
85
  children: O.map((e) => {
86
- let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), n = e.capacity ?? 0, a = n > 0 ? Math.round(t / n * 100) : 0;
86
+ let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), i = e.capacity ?? 0, a = i > 0 ? Math.round(t / i * 100) : 0;
87
87
  return /* @__PURE__ */ m(g, {
88
- ...i(() => S(r("/projects/planning-detail-page", e.id)), e.name),
88
+ ...r(() => S(n("/projects/planning-detail-page", e.id)), e.name),
89
89
  children: [/* @__PURE__ */ p(v, {
90
90
  className: "pb-2",
91
91
  children: /* @__PURE__ */ m("div", {
@@ -133,7 +133,7 @@ function S() {
133
133
  ]
134
134
  }), /* @__PURE__ */ m("span", { children: [e.workItems.length, " work items"] })]
135
135
  }),
136
- n > 0 && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("div", {
136
+ i > 0 && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("div", {
137
137
  className: "flex justify-between text-xs mb-1",
138
138
  children: [/* @__PURE__ */ p("span", {
139
139
  className: "text-muted-foreground",
@@ -143,7 +143,7 @@ function S() {
143
143
  children: [
144
144
  t,
145
145
  "/",
146
- n,
146
+ i,
147
147
  " pts (",
148
148
  a,
149
149
  "%)"
@@ -1,8 +1,8 @@
1
1
  import { usePlanMagnet as e, usePlanMagnetNavigate as t } from "../providers/PlanMagnetProvider.js";
2
2
  import { PersonAvatar as n } from "../people/People.js";
3
3
  import { countLabel as r, useSprintCounts as i, workProgress as a } from "../hooks/useCounts.js";
4
- import { TeamSelect as o } from "../controls/Pickers.js";
5
- import { detailPath as s } from "../utils/rowNavigation.js";
4
+ import { detailPath as o } from "../utils/rowNavigation.js";
5
+ import { TeamSelect as s } from "../controls/Pickers.js";
6
6
  import { NewSprintDialog as c, SprintLifecycleActions as l } from "../sprints/SprintControls.js";
7
7
  import { SprintDates as u } from "../sprints/SprintDates.js";
8
8
  import { useState as d } from "react";
@@ -113,7 +113,7 @@ function E() {
113
113
  ...O
114
114
  }
115
115
  }
116
- }), F = i(), I = k?.planmagnetSprints?.items ?? [], L = [...N?.planmagnetSprints.items ?? [], ...P?.planmagnetSprints.items ?? []], R = I.filter((e) => e.status === "PLANNING"), z = I.filter((e) => e.status === "COMPLETED" || e.status === "CANCELLED"), B = t(), V = (e) => B(s("/projects/planning-detail-page", e));
116
+ }), F = i(), I = k?.planmagnetSprints?.items ?? [], L = [...N?.planmagnetSprints.items ?? [], ...P?.planmagnetSprints.items ?? []], R = I.filter((e) => e.status === "PLANNING"), z = I.filter((e) => e.status === "COMPLETED" || e.status === "CANCELLED"), B = t(), V = (e) => B(o("/projects/planning-detail-page", e));
117
117
  return A && !k ? /* @__PURE__ */ g("div", {
118
118
  className: "flex items-center justify-center p-12",
119
119
  children: /* @__PURE__ */ g("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
@@ -138,7 +138,7 @@ function E() {
138
138
  ]
139
139
  })] }), /* @__PURE__ */ _("div", {
140
140
  className: "flex items-center gap-2",
141
- children: [/* @__PURE__ */ g(o, {
141
+ children: [/* @__PURE__ */ g(s, {
142
142
  value: E,
143
143
  onChange: D,
144
144
  noneLabel: "All teams"
@@ -0,0 +1,8 @@
1
+ export declare function StatusFlowCard({ workspaceId, projectId, startDate, endDate, }: {
2
+ workspaceId?: string | null;
3
+ /** Status flow is always one project (`projectId: ID!` on the server) — same convention as CycleTimeCard. */
4
+ projectId: string;
5
+ startDate: string;
6
+ endDate: string;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=StatusFlowCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusFlowCard.d.ts","sourceRoot":"","sources":["../../../../src/planmagnet/pages/analytics/StatusFlowCard.tsx"],"names":[],"mappings":"AAoLA,wBAAgB,cAAc,CAAC,EAC7B,WAAW,EACX,SAAS,EACT,SAAS,EACT,OAAO,GACR,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6GAA6G;IAC7G,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,2CAuJA"}