@burdenoff/microfe-planmagnet 2026.1001.6 → 2026.1001.8

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 (94) hide show
  1. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoutes.js +10 -6
  3. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  4. package/dist/planmagnet/automation/automationRuleTypes.d.ts +31 -19
  5. package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -1
  6. package/dist/planmagnet/automation/automationRuleTypes.js +4 -8
  7. package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -1
  8. package/dist/planmagnet/controls/FeatureControls.d.ts +18 -1
  9. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
  10. package/dist/planmagnet/controls/FeatureControls.js +259 -202
  11. package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
  12. package/dist/planmagnet/controls/FeedbackControls.d.ts +70 -0
  13. package/dist/planmagnet/controls/FeedbackControls.d.ts.map +1 -0
  14. package/dist/planmagnet/controls/FeedbackControls.js +153 -0
  15. package/dist/planmagnet/controls/FeedbackControls.js.map +1 -0
  16. package/dist/planmagnet/controls/SyncControls.d.ts.map +1 -1
  17. package/dist/planmagnet/controls/SyncControls.js +1 -0
  18. package/dist/planmagnet/controls/SyncControls.js.map +1 -1
  19. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts +47 -0
  20. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +1 -0
  21. package/dist/planmagnet/controls/WebhookSubscriptionControls.js +542 -0
  22. package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +1 -0
  23. package/dist/planmagnet/dashboards/DashboardUI.js +7 -7
  24. package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +4 -4
  25. package/dist/planmagnet/forecast/DeliveryForecastCard.js +8 -8
  26. package/dist/planmagnet/forecast/ProjectOutlookCard.js +10 -10
  27. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +9 -9
  28. package/dist/planmagnet/forecast/ResourceForecastCard.js +6 -6
  29. package/dist/planmagnet/hooks/useLiveRefresh.d.ts +33 -2
  30. package/dist/planmagnet/hooks/useLiveRefresh.d.ts.map +1 -1
  31. package/dist/planmagnet/hooks/useLiveRefresh.js +71 -42
  32. package/dist/planmagnet/hooks/useLiveRefresh.js.map +1 -1
  33. package/dist/planmagnet/integrations/syncTypes.d.ts +2 -1
  34. package/dist/planmagnet/integrations/syncTypes.d.ts.map +1 -1
  35. package/dist/planmagnet/integrations/syncTypes.js +19 -9
  36. package/dist/planmagnet/integrations/syncTypes.js.map +1 -1
  37. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +8 -8
  38. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +23 -23
  39. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  40. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +340 -248
  41. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  42. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +1 -1
  43. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +172 -167
  44. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +1 -1
  45. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +1 -1
  46. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +92 -83
  47. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +1 -1
  48. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts +2 -0
  49. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +1 -0
  50. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +175 -0
  51. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +1 -0
  52. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  53. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +151 -126
  54. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  55. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  56. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +136 -129
  57. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  58. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  59. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +149 -119
  60. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  61. package/dist/planmagnet/pages/ProductsProductsPagePage.js +13 -13
  62. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.d.ts.map +1 -1
  63. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js +153 -117
  64. package/dist/planmagnet/pages/ProductsRoadmapAnalyticsPagePage.js.map +1 -1
  65. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
  66. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +173 -138
  67. package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
  68. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +9 -9
  69. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +8 -8
  70. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +12 -12
  71. package/dist/planmagnet/pages/ReportsReportsPagePage.js +23 -23
  72. package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +18 -18
  73. package/dist/planmagnet/pages/TasksMyWorkPagePage.js +10 -10
  74. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +5 -5
  75. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -8
  76. package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +6 -6
  77. package/dist/planmagnet/pages/analytics/MetricsCard.js +6 -6
  78. package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +6 -6
  79. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +8 -8
  80. package/dist/planmagnet/pages/analytics/StatusFlowCard.js +7 -7
  81. package/dist/planmagnet/pages/analytics/ThroughputCard.js +7 -7
  82. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +7 -7
  83. package/dist/planmagnet/people/People.d.ts +14 -0
  84. package/dist/planmagnet/people/People.d.ts.map +1 -1
  85. package/dist/planmagnet/people/People.js +36 -22
  86. package/dist/planmagnet/people/People.js.map +1 -1
  87. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.d.ts.map +1 -1
  88. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +171 -153
  89. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js.map +1 -1
  90. package/dist/planmagnet/webhooks/webhookTypes.d.ts +54 -0
  91. package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +1 -0
  92. package/dist/planmagnet/webhooks/webhookTypes.js +17 -0
  93. package/dist/planmagnet/webhooks/webhookTypes.js.map +1 -0
  94. package/package.json +1 -1
@@ -13,6 +13,7 @@ var e = [
13
13
  ], n = [
14
14
  "SOURCE_WINS",
15
15
  "TARGET_WINS",
16
+ "MERGE",
16
17
  "MANUAL"
17
18
  ], r = ["priority", "dueDate"], i = {
18
19
  priority: "priority:",
@@ -40,20 +41,29 @@ var s = {
40
41
  function c(e) {
41
42
  return s[e] ?? e;
42
43
  }
43
- function l(e, t) {
44
+ var l = {
45
+ SOURCE_WINS: "PlanMagnet wins",
46
+ TARGET_WINS: "Provider wins",
47
+ MERGE: "Merge",
48
+ MANUAL: "Manual"
49
+ };
50
+ function u(e) {
51
+ return l[e] ?? e;
52
+ }
53
+ function d(e, t) {
44
54
  return t === "INBOUND" ? e.supportsImport : t === "OUTBOUND" ? e.supportsExport : e.supportsBidirectional;
45
55
  }
46
- function u(e) {
56
+ function f(e) {
47
57
  return e.supportsImport || e.supportsExport || e.supportsBidirectional;
48
58
  }
49
- var d = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/, f = /^[A-Za-z0-9._-]{1,100}$/;
50
- function p(e) {
51
- return d.test(e.trim());
59
+ var p = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/, m = /^[A-Za-z0-9._-]{1,100}$/;
60
+ function h(e) {
61
+ return p.test(e.trim());
52
62
  }
53
- function m(e) {
54
- return f.test(e.trim());
63
+ function g(e) {
64
+ return m.test(e.trim());
55
65
  }
56
- function h(e) {
66
+ function _(e) {
57
67
  let t = {
58
68
  priority: "",
59
69
  dueDate: ""
@@ -66,6 +76,6 @@ function h(e) {
66
76
  return t;
67
77
  }
68
78
  //#endregion
69
- export { n as CONFLICT_RESOLUTIONS, i as GITHUB_FIELD_MAPPING_DEFAULTS, e as SYNC_DIRECTIONS, t as SYNC_STATUSES, c as directionLabel, l as directionSupported, p as isValidGithubOwner, m as isValidGithubRepo, h as parseGithubFieldMapping, u as providerIsLive, o as providerLabel };
79
+ export { n as CONFLICT_RESOLUTIONS, i as GITHUB_FIELD_MAPPING_DEFAULTS, e as SYNC_DIRECTIONS, t as SYNC_STATUSES, u as conflictStrategyLabel, c as directionLabel, d as directionSupported, h as isValidGithubOwner, g as isValidGithubRepo, _ as parseGithubFieldMapping, f as providerIsLive, o as providerLabel };
70
80
 
71
81
  //# sourceMappingURL=syncTypes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"syncTypes.js","names":[],"sources":["../../../src/planmagnet/integrations/syncTypes.ts"],"sourcesContent":["/**\n * Shared shapes and constants for External Sync (AUT-06/08/09/10/20/22/23/24/40) — GraphQL Hive doc comments and\n * `wspace-planmagnet-svc#63` are the source of truth for all of this, not guesswork:\n *\n * - GITHUB is the one provider with a real, live connector today (`github-connector.ts`); every other\n * `PlanmagnetSyncProvider` is accepted by `planmagnetCreateExternalSync` (a customer can configure it ahead of\n * time) but has no live connector, which `planmagnetSupportedSyncProviders` reports honestly (every capability\n * flag false except `supportsFileImport`, which is the unrelated `planmagnetImportExternalIssues` CSV/JSON\n * upload path, not an `ExternalSync` live run). The wizard reads that capability list rather than hard-coding\n * \"GitHub only\" — if a second connector ships, this UI lights up for it automatically.\n * - `ExternalSync.connectionConfig` for GITHUB is `{ token, owner, repo }` and is REDACTED server-side on every\n * read (`token` -> `[REDACTED]`; `owner`/`repo` are not secret and pass through). It must never be displayed as\n * if it still held the token, and never round-tripped back to the server as if `[REDACTED]` were a real value.\n * - `ExternalSync.fieldMapping` for GITHUB is exactly two optional label-prefix strings —\n * `{ priority?: string; dueDate?: string }` (default `\"priority:\"` / `\"due:\"`) — because GitHub Issues have no\n * native priority or due-date column; the connector encodes/decodes them as a label of the form\n * `{prefix}{value}` (e.g. `priority:HIGH`, `due:2026-10-01`). This is the only field-mapping shape the live\n * connector reads; it is NOT the (unrelated) CSV/JSON import's column-name mapping.\n * - `PlanmagnetUpdateExternalSyncInput.connectionConfig` REPLACES the whole stored config — it does not merge —\n * so an edit that changes only the token must resend `owner`/`repo` too (read back from the redacted\n * `connectionConfig`, which is safe since only `token` is masked), and an edit that changes owner/repo without a\n * new token cannot be sent at all (the real token can never be read back to resend it). See\n * `controls/SyncControls.tsx`'s `EditSyncConnectionDialog`.\n */\n\nexport const SYNC_PROVIDERS = [\n 'JIRA',\n 'GITHUB',\n 'GITLAB',\n 'AZURE_DEVOPS',\n 'ASANA',\n 'TRELLO',\n 'LINEAR',\n 'SHORTCUT',\n 'CLICKUP',\n 'CUSTOM',\n] as const;\nexport type SyncProvider = (typeof SYNC_PROVIDERS)[number];\n\nexport const SYNC_DIRECTIONS = ['INBOUND', 'OUTBOUND', 'BIDIRECTIONAL'] as const;\nexport type SyncDirection = (typeof SYNC_DIRECTIONS)[number];\n\nexport const SYNC_STATUSES = [\n 'IDLE',\n 'SYNCING',\n 'SUCCESS',\n 'FAILED',\n 'PAUSED',\n 'DISABLED',\n] as const;\nexport type SyncStatus = (typeof SYNC_STATUSES)[number];\n\nexport const CONFLICT_RESOLUTIONS = ['SOURCE_WINS', 'TARGET_WINS', 'MANUAL'] as const;\nexport type ConflictResolution = (typeof CONFLICT_RESOLUTIONS)[number];\n\nexport const CONFLICT_STATUSES = ['OPEN', 'RESOLVED'] as const;\nexport type ConflictStatus = (typeof CONFLICT_STATUSES)[number];\n\nexport const SYNC_RUN_STATUSES = ['SUCCEEDED', 'FAILED', 'PARTIAL'] as const;\nexport type SyncRunStatus = (typeof SYNC_RUN_STATUSES)[number];\n\n/** The two GitHub label-prefix keys `ExternalSync.fieldMapping` actually understands (github-connector.ts). */\nexport const GITHUB_FIELD_MAPPING_KEYS = ['priority', 'dueDate'] as const;\nexport type GithubFieldMappingKey = (typeof GITHUB_FIELD_MAPPING_KEYS)[number];\n/** The connector's own built-in defaults, used only as placeholder copy — never assumed server-side. */\nexport const GITHUB_FIELD_MAPPING_DEFAULTS: Record<GithubFieldMappingKey, string> = {\n priority: 'priority:',\n dueDate: 'due:',\n};\n\nexport interface ProjectRef {\n id: string;\n name: string;\n}\n\nexport interface RunHealth {\n lastRunAt: string | null;\n lastStatus: SyncRunStatus | null;\n consecutiveFailures: number;\n runsLast7Days: number;\n}\n\nexport interface ExternalSyncRow {\n id: string;\n provider: SyncProvider;\n direction: SyncDirection;\n status: SyncStatus;\n projectId: string;\n project: ProjectRef | null;\n externalProjectId: string;\n externalProjectUrl: string | null;\n conflictStrategy: ConflictResolution;\n fieldMapping: unknown;\n /** Stored but not yet read by any run (sync.service.ts) — surfaced honestly in the edit form, not hidden. */\n syncFilters: unknown;\n lastSyncedAt: string | null;\n lastSyncError: string | null;\n totalItemsSynced: number;\n createdAt: string;\n updatedAt: string;\n runHealth: RunHealth;\n}\n\nexport interface SyncProviderCapability {\n provider: SyncProvider;\n supportsImport: boolean;\n supportsExport: boolean;\n supportsBidirectional: boolean;\n supportsFileImport: boolean;\n supportsConnectionTest: boolean;\n}\n\nexport interface SyncRunRow {\n id: string;\n direction: SyncDirection;\n status: SyncRunStatus;\n startedAt: string;\n finishedAt: string;\n itemsCreated: number;\n itemsUpdated: number;\n itemsSkipped: number;\n errorCount: number;\n conflictCount: number;\n errorMessage: string | null;\n triggeredBy: string;\n}\n\nexport interface ExternalMappingRef {\n id: string;\n internalId: string;\n internalType: string;\n externalId: string;\n externalType: string;\n externalUrl: string | null;\n}\n\nexport interface SyncConflictRow {\n id: string;\n createdAt: string;\n fields: string[];\n localUpdatedAt: string;\n remoteUpdatedAt: string;\n resolution: ConflictResolution | null;\n resolvedAt: string | null;\n resolvedBy: string | null;\n status: ConflictStatus;\n mapping: ExternalMappingRef | null;\n mappingId: string;\n}\n\n/** `PlanmagnetSyncResult` — what `planmagnetStartSync` returns. */\nexport interface SyncRunResult {\n syncId: string;\n success: boolean;\n itemsCreated: number;\n itemsUpdated: number;\n itemsSkipped: number;\n errorCount: number;\n errors: string[] | null;\n conflictCount: number;\n durationMs: number | null;\n syncedAt: string;\n}\n\n/** `PlanmagnetSyncConnectionTestResult` — what `planmagnetTestExternalSync` returns. */\nexport interface SyncConnectionTestResult {\n ok: boolean;\n message: string;\n rateLimitRemaining: number | null;\n}\n\nconst PROVIDER_LABELS: Record<SyncProvider, string> = {\n JIRA: 'Jira',\n GITHUB: 'GitHub',\n GITLAB: 'GitLab',\n AZURE_DEVOPS: 'Azure DevOps',\n ASANA: 'Asana',\n TRELLO: 'Trello',\n LINEAR: 'Linear',\n SHORTCUT: 'Shortcut',\n CLICKUP: 'ClickUp',\n CUSTOM: 'Custom',\n};\n\nexport function providerLabel(provider: string): string {\n return PROVIDER_LABELS[provider as SyncProvider] ?? provider;\n}\n\nconst DIRECTION_LABELS: Record<SyncDirection, string> = {\n INBOUND: 'Inbound (provider → PlanMagnet)',\n OUTBOUND: 'Outbound (PlanMagnet → provider)',\n BIDIRECTIONAL: 'Bidirectional (both ways)',\n};\n\nexport function directionLabel(direction: string): string {\n return DIRECTION_LABELS[direction as SyncDirection] ?? direction;\n}\n\n/** Whether a capability supports a given direction at all — the single gate the wizard and the edit form both use. */\nexport function directionSupported(\n capability: Pick<\n SyncProviderCapability,\n 'supportsImport' | 'supportsExport' | 'supportsBidirectional'\n >,\n direction: SyncDirection\n): boolean {\n if (direction === 'INBOUND') return capability.supportsImport;\n if (direction === 'OUTBOUND') return capability.supportsExport;\n return capability.supportsBidirectional;\n}\n\n/** True once a provider can run at least one live direction — the gate for selecting it in the wizard at all. */\nexport function providerIsLive(\n capability: Pick<\n SyncProviderCapability,\n 'supportsImport' | 'supportsExport' | 'supportsBidirectional'\n >\n): boolean {\n return capability.supportsImport || capability.supportsExport || capability.supportsBidirectional;\n}\n\n/**\n * `ExternalSync.fieldMapping` -> the two GitHub label prefixes, as blank strings when unset (meaning \"the\n * connector's built-in default applies\"), never pre-filled with that default text — so an untouched form saves\n * nothing and a save always reflects a real, deliberate choice.\n */\n/** GitHub org/user name rules: 1-39 chars, alphanumeric or single hyphens, no leading/trailing hyphen. */\nconst GITHUB_OWNER_RE = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;\n/** GitHub repo name rules: 1-100 chars of letters, digits, `.`, `-`, `_`. */\nconst GITHUB_REPO_RE = /^[A-Za-z0-9._-]{1,100}$/;\n\nexport function isValidGithubOwner(value: string): boolean {\n return GITHUB_OWNER_RE.test(value.trim());\n}\nexport function isValidGithubRepo(value: string): boolean {\n return GITHUB_REPO_RE.test(value.trim());\n}\n\nexport function parseGithubFieldMapping(value: unknown): Record<GithubFieldMappingKey, string> {\n const out: Record<GithubFieldMappingKey, string> = { priority: '', dueDate: '' };\n if (!value || typeof value !== 'object' || Array.isArray(value)) return out;\n for (const key of GITHUB_FIELD_MAPPING_KEYS) {\n const raw = (value as Record<string, unknown>)[key];\n if (typeof raw === 'string' && raw.trim()) out[key] = raw.trim();\n }\n return out;\n}\n"],"mappings":";AAuCA,IAAa,IAAkB;CAAC;CAAW;CAAY;CAAgB,EAG1D,IAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACD,EAGY,IAAuB;CAAC;CAAe;CAAe;CAAS,EAU/D,IAA4B,CAAC,YAAY,UAAU,EAGnD,IAAuE;CAClF,UAAU;CACV,SAAS;CACV,EAuGK,IAAgD;CACpD,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;CACT;AAED,SAAgB,EAAc,GAA0B;AACtD,QAAO,EAAgB,MAA6B;;AAGtD,IAAM,IAAkD;CACtD,SAAS;CACT,UAAU;CACV,eAAe;CAChB;AAED,SAAgB,EAAe,GAA2B;AACxD,QAAO,EAAiB,MAA+B;;AAIzD,SAAgB,EACd,GAIA,GACS;AAGT,QAFI,MAAc,YAAkB,EAAW,iBAC3C,MAAc,aAAmB,EAAW,iBACzC,EAAW;;AAIpB,SAAgB,EACd,GAIS;AACT,QAAO,EAAW,kBAAkB,EAAW,kBAAkB,EAAW;;AAS9E,IAAM,IAAkB,mDAElB,IAAiB;AAEvB,SAAgB,EAAmB,GAAwB;AACzD,QAAO,EAAgB,KAAK,EAAM,MAAM,CAAC;;AAE3C,SAAgB,EAAkB,GAAwB;AACxD,QAAO,EAAe,KAAK,EAAM,MAAM,CAAC;;AAG1C,SAAgB,EAAwB,GAAuD;CAC7F,IAAM,IAA6C;EAAE,UAAU;EAAI,SAAS;EAAI;AAChF,KAAI,CAAC,KAAS,OAAO,KAAU,YAAY,MAAM,QAAQ,EAAM,CAAE,QAAO;AACxE,MAAK,IAAM,KAAO,GAA2B;EAC3C,IAAM,IAAO,EAAkC;AAC/C,EAAI,OAAO,KAAQ,YAAY,EAAI,MAAM,KAAE,EAAI,KAAO,EAAI,MAAM;;AAElE,QAAO"}
1
+ {"version":3,"file":"syncTypes.js","names":[],"sources":["../../../src/planmagnet/integrations/syncTypes.ts"],"sourcesContent":["/**\n * Shared shapes and constants for External Sync (AUT-06/08/09/10/20/22/23/24/40) — GraphQL Hive doc comments and\n * `wspace-planmagnet-svc#63` are the source of truth for all of this, not guesswork:\n *\n * - GITHUB is the one provider with a real, live connector today (`github-connector.ts`); every other\n * `PlanmagnetSyncProvider` is accepted by `planmagnetCreateExternalSync` (a customer can configure it ahead of\n * time) but has no live connector, which `planmagnetSupportedSyncProviders` reports honestly (every capability\n * flag false except `supportsFileImport`, which is the unrelated `planmagnetImportExternalIssues` CSV/JSON\n * upload path, not an `ExternalSync` live run). The wizard reads that capability list rather than hard-coding\n * \"GitHub only\" — if a second connector ships, this UI lights up for it automatically.\n * - `ExternalSync.connectionConfig` for GITHUB is `{ token, owner, repo }` and is REDACTED server-side on every\n * read (`token` -> `[REDACTED]`; `owner`/`repo` are not secret and pass through). It must never be displayed as\n * if it still held the token, and never round-tripped back to the server as if `[REDACTED]` were a real value.\n * - `ExternalSync.fieldMapping` for GITHUB is exactly two optional label-prefix strings —\n * `{ priority?: string; dueDate?: string }` (default `\"priority:\"` / `\"due:\"`) — because GitHub Issues have no\n * native priority or due-date column; the connector encodes/decodes them as a label of the form\n * `{prefix}{value}` (e.g. `priority:HIGH`, `due:2026-10-01`). This is the only field-mapping shape the live\n * connector reads; it is NOT the (unrelated) CSV/JSON import's column-name mapping.\n * - `PlanmagnetUpdateExternalSyncInput.connectionConfig` REPLACES the whole stored config — it does not merge —\n * so an edit that changes only the token must resend `owner`/`repo` too (read back from the redacted\n * `connectionConfig`, which is safe since only `token` is masked), and an edit that changes owner/repo without a\n * new token cannot be sent at all (the real token can never be read back to resend it). See\n * `controls/SyncControls.tsx`'s `EditSyncConnectionDialog`.\n */\n\nexport const SYNC_PROVIDERS = [\n 'JIRA',\n 'GITHUB',\n 'GITLAB',\n 'AZURE_DEVOPS',\n 'ASANA',\n 'TRELLO',\n 'LINEAR',\n 'SHORTCUT',\n 'CLICKUP',\n 'CUSTOM',\n] as const;\nexport type SyncProvider = (typeof SYNC_PROVIDERS)[number];\n\nexport const SYNC_DIRECTIONS = ['INBOUND', 'OUTBOUND', 'BIDIRECTIONAL'] as const;\nexport type SyncDirection = (typeof SYNC_DIRECTIONS)[number];\n\nexport const SYNC_STATUSES = [\n 'IDLE',\n 'SYNCING',\n 'SUCCESS',\n 'FAILED',\n 'PAUSED',\n 'DISABLED',\n] as const;\nexport type SyncStatus = (typeof SYNC_STATUSES)[number];\n\n// AUT-24: MERGE added alongside the two whole-side picks and the manual flag — PlanmagnetSyncConflictResolution's\n// own doc comment (graphql/wspace.graphql) has the exact field-level policy: each sync leg keeps whichever\n// side's title/description it is NOT overwriting, while status/priority/dueDate/labels still follow that leg's\n// normal direction.\nexport const CONFLICT_RESOLUTIONS = ['SOURCE_WINS', 'TARGET_WINS', 'MERGE', 'MANUAL'] as const;\nexport type ConflictResolution = (typeof CONFLICT_RESOLUTIONS)[number];\n\nexport const CONFLICT_STATUSES = ['OPEN', 'RESOLVED'] as const;\nexport type ConflictStatus = (typeof CONFLICT_STATUSES)[number];\n\nexport const SYNC_RUN_STATUSES = ['SUCCEEDED', 'FAILED', 'PARTIAL'] as const;\nexport type SyncRunStatus = (typeof SYNC_RUN_STATUSES)[number];\n\n/** The two GitHub label-prefix keys `ExternalSync.fieldMapping` actually understands (github-connector.ts). */\nexport const GITHUB_FIELD_MAPPING_KEYS = ['priority', 'dueDate'] as const;\nexport type GithubFieldMappingKey = (typeof GITHUB_FIELD_MAPPING_KEYS)[number];\n/** The connector's own built-in defaults, used only as placeholder copy — never assumed server-side. */\nexport const GITHUB_FIELD_MAPPING_DEFAULTS: Record<GithubFieldMappingKey, string> = {\n priority: 'priority:',\n dueDate: 'due:',\n};\n\nexport interface ProjectRef {\n id: string;\n name: string;\n}\n\nexport interface RunHealth {\n lastRunAt: string | null;\n lastStatus: SyncRunStatus | null;\n consecutiveFailures: number;\n runsLast7Days: number;\n}\n\nexport interface ExternalSyncRow {\n id: string;\n provider: SyncProvider;\n direction: SyncDirection;\n status: SyncStatus;\n projectId: string;\n project: ProjectRef | null;\n externalProjectId: string;\n externalProjectUrl: string | null;\n conflictStrategy: ConflictResolution;\n fieldMapping: unknown;\n /** Stored but not yet read by any run (sync.service.ts) — surfaced honestly in the edit form, not hidden. */\n syncFilters: unknown;\n lastSyncedAt: string | null;\n lastSyncError: string | null;\n totalItemsSynced: number;\n createdAt: string;\n updatedAt: string;\n runHealth: RunHealth;\n}\n\nexport interface SyncProviderCapability {\n provider: SyncProvider;\n supportsImport: boolean;\n supportsExport: boolean;\n supportsBidirectional: boolean;\n supportsFileImport: boolean;\n supportsConnectionTest: boolean;\n}\n\nexport interface SyncRunRow {\n id: string;\n direction: SyncDirection;\n status: SyncRunStatus;\n startedAt: string;\n finishedAt: string;\n itemsCreated: number;\n itemsUpdated: number;\n itemsSkipped: number;\n errorCount: number;\n conflictCount: number;\n errorMessage: string | null;\n triggeredBy: string;\n}\n\nexport interface ExternalMappingRef {\n id: string;\n internalId: string;\n internalType: string;\n externalId: string;\n externalType: string;\n externalUrl: string | null;\n}\n\nexport interface SyncConflictRow {\n id: string;\n createdAt: string;\n fields: string[];\n localUpdatedAt: string;\n remoteUpdatedAt: string;\n resolution: ConflictResolution | null;\n resolvedAt: string | null;\n resolvedBy: string | null;\n status: ConflictStatus;\n mapping: ExternalMappingRef | null;\n mappingId: string;\n}\n\n/** `PlanmagnetSyncResult` — what `planmagnetStartSync` returns. */\nexport interface SyncRunResult {\n syncId: string;\n success: boolean;\n itemsCreated: number;\n itemsUpdated: number;\n itemsSkipped: number;\n errorCount: number;\n errors: string[] | null;\n conflictCount: number;\n durationMs: number | null;\n syncedAt: string;\n}\n\n/** `PlanmagnetSyncConnectionTestResult` — what `planmagnetTestExternalSync` returns. */\nexport interface SyncConnectionTestResult {\n ok: boolean;\n message: string;\n rateLimitRemaining: number | null;\n}\n\nconst PROVIDER_LABELS: Record<SyncProvider, string> = {\n JIRA: 'Jira',\n GITHUB: 'GitHub',\n GITLAB: 'GitLab',\n AZURE_DEVOPS: 'Azure DevOps',\n ASANA: 'Asana',\n TRELLO: 'Trello',\n LINEAR: 'Linear',\n SHORTCUT: 'Shortcut',\n CLICKUP: 'ClickUp',\n CUSTOM: 'Custom',\n};\n\nexport function providerLabel(provider: string): string {\n return PROVIDER_LABELS[provider as SyncProvider] ?? provider;\n}\n\nconst DIRECTION_LABELS: Record<SyncDirection, string> = {\n INBOUND: 'Inbound (provider → PlanMagnet)',\n OUTBOUND: 'Outbound (PlanMagnet → provider)',\n BIDIRECTIONAL: 'Bidirectional (both ways)',\n};\n\nexport function directionLabel(direction: string): string {\n return DIRECTION_LABELS[direction as SyncDirection] ?? direction;\n}\n\n/** Short labels for `ExternalSync.conflictStrategy` / `SyncConflict.resolution` — friendlier than `enumLabel`'s\n * literal \"Source wins\"/\"Target wins\" (this is the one place PlanMagnet calls itself \"PlanMagnet\", not \"source\",\n * to the person choosing the strategy). Covers all four `PlanmagnetSyncConflictResolution` values, including\n * `MERGE` (AUT-24) — a prior version of this UI fell through to \"Manual\" for it in two places that read the raw\n * enum with a 3-way ternary instead of this map. */\nconst CONFLICT_STRATEGY_LABELS: Record<ConflictResolution, string> = {\n SOURCE_WINS: 'PlanMagnet wins',\n TARGET_WINS: 'Provider wins',\n MERGE: 'Merge',\n MANUAL: 'Manual',\n};\n\nexport function conflictStrategyLabel(value: string): string {\n return CONFLICT_STRATEGY_LABELS[value as ConflictResolution] ?? value;\n}\n\n/** Whether a capability supports a given direction at all — the single gate the wizard and the edit form both use. */\nexport function directionSupported(\n capability: Pick<\n SyncProviderCapability,\n 'supportsImport' | 'supportsExport' | 'supportsBidirectional'\n >,\n direction: SyncDirection\n): boolean {\n if (direction === 'INBOUND') return capability.supportsImport;\n if (direction === 'OUTBOUND') return capability.supportsExport;\n return capability.supportsBidirectional;\n}\n\n/** True once a provider can run at least one live direction — the gate for selecting it in the wizard at all. */\nexport function providerIsLive(\n capability: Pick<\n SyncProviderCapability,\n 'supportsImport' | 'supportsExport' | 'supportsBidirectional'\n >\n): boolean {\n return capability.supportsImport || capability.supportsExport || capability.supportsBidirectional;\n}\n\n/**\n * `ExternalSync.fieldMapping` -> the two GitHub label prefixes, as blank strings when unset (meaning \"the\n * connector's built-in default applies\"), never pre-filled with that default text — so an untouched form saves\n * nothing and a save always reflects a real, deliberate choice.\n */\n/** GitHub org/user name rules: 1-39 chars, alphanumeric or single hyphens, no leading/trailing hyphen. */\nconst GITHUB_OWNER_RE = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;\n/** GitHub repo name rules: 1-100 chars of letters, digits, `.`, `-`, `_`. */\nconst GITHUB_REPO_RE = /^[A-Za-z0-9._-]{1,100}$/;\n\nexport function isValidGithubOwner(value: string): boolean {\n return GITHUB_OWNER_RE.test(value.trim());\n}\nexport function isValidGithubRepo(value: string): boolean {\n return GITHUB_REPO_RE.test(value.trim());\n}\n\nexport function parseGithubFieldMapping(value: unknown): Record<GithubFieldMappingKey, string> {\n const out: Record<GithubFieldMappingKey, string> = { priority: '', dueDate: '' };\n if (!value || typeof value !== 'object' || Array.isArray(value)) return out;\n for (const key of GITHUB_FIELD_MAPPING_KEYS) {\n const raw = (value as Record<string, unknown>)[key];\n if (typeof raw === 'string' && raw.trim()) out[key] = raw.trim();\n }\n return out;\n}\n"],"mappings":";AAuCA,IAAa,IAAkB;CAAC;CAAW;CAAY;CAAgB,EAG1D,IAAgB;CAC3B;CACA;CACA;CACA;CACA;CACA;CACD,EAOY,IAAuB;CAAC;CAAe;CAAe;CAAS;CAAS,EAUxE,IAA4B,CAAC,YAAY,UAAU,EAGnD,IAAuE;CAClF,UAAU;CACV,SAAS;CACV,EAuGK,IAAgD;CACpD,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,cAAc;CACd,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACT,QAAQ;CACT;AAED,SAAgB,EAAc,GAA0B;AACtD,QAAO,EAAgB,MAA6B;;AAGtD,IAAM,IAAkD;CACtD,SAAS;CACT,UAAU;CACV,eAAe;CAChB;AAED,SAAgB,EAAe,GAA2B;AACxD,QAAO,EAAiB,MAA+B;;AAQzD,IAAM,IAA+D;CACnE,aAAa;CACb,aAAa;CACb,OAAO;CACP,QAAQ;CACT;AAED,SAAgB,EAAsB,GAAuB;AAC3D,QAAO,EAAyB,MAAgC;;AAIlE,SAAgB,EACd,GAIA,GACS;AAGT,QAFI,MAAc,YAAkB,EAAW,iBAC3C,MAAc,aAAmB,EAAW,iBACzC,EAAW;;AAIpB,SAAgB,EACd,GAIS;AACT,QAAO,EAAW,kBAAkB,EAAW,kBAAkB,EAAW;;AAS9E,IAAM,IAAkB,mDAElB,IAAiB;AAEvB,SAAgB,EAAmB,GAAwB;AACzD,QAAO,EAAgB,KAAK,EAAM,MAAM,CAAC;;AAE3C,SAAgB,EAAkB,GAAwB;AACxD,QAAO,EAAe,KAAK,EAAM,MAAM,CAAC;;AAG1C,SAAgB,EAAwB,GAAuD;CAC7F,IAAM,IAA6C;EAAE,UAAU;EAAI,SAAS;EAAI;AAChF,KAAI,CAAC,KAAS,OAAO,KAAU,YAAY,MAAM,QAAQ,EAAM,CAAE,QAAO;AACxE,MAAK,IAAM,KAAO,GAA2B;EAC3C,IAAM,IAAO,EAAkC;AAC/C,EAAI,OAAO,KAAQ,YAAY,EAAI,MAAM,KAAE,EAAI,KAAO,EAAI,MAAM;;AAElE,QAAO"}
@@ -29,8 +29,8 @@ import { useSearchParams as Ee } from "react-router";
29
29
  import { gql as f } from "@apollo/client";
30
30
  import { useQuery as p } from "@apollo/client/react";
31
31
  import { Fragment as De, jsx as m, jsxs as h } from "react/jsx-runtime";
32
- import { useI18n as Oe } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
33
- import { Badge as ke, Card as g, CardContent as _, CardHeader as v, CardTitle as y, Input as b, Select as x, SelectContent as S, SelectItem as C, SelectTrigger as Ae, SelectValue as je } from "@burdenoff/fe-libs/ui";
32
+ import { Badge as Oe, Card as g, CardContent as _, CardHeader as v, CardTitle as y, Input as b, Select as x, SelectContent as S, SelectItem as C, SelectTrigger as ke, SelectValue as Ae } from "@burdenoff/fe-libs/ui";
33
+ import { useI18n as je } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
34
34
  //#region src/planmagnet/pages/AnalyticsAnalyticsPagePage.tsx
35
35
  var Me = f`
36
36
  query AnalyticsProjectSprints($workspaceId: ID!, $projectId: String) {
@@ -179,7 +179,7 @@ function T(e) {
179
179
  return `${t.getUTCMonth() + 1}/${t.getUTCDate()}`;
180
180
  }
181
181
  function E() {
182
- let { workspaceId: f } = e(), { t: E } = Oe(), [ze, D] = u(""), [O, Be] = Ee(), k = O.get("from"), A = O.get("to"), [j, M] = u(() => k && A && l(k, A) ? {
182
+ let { workspaceId: f } = e(), { t: E } = je(), [ze, D] = u(""), [O, Be] = Ee(), k = O.get("from"), A = O.get("to"), [j, M] = u(() => k && A && l(k, A) ? {
183
183
  from: k,
184
184
  to: A
185
185
  } : ye("30")), [Ve, He] = u(j), [N, Ue] = u(O.get("project") || "all"), P = be(N), F = ve(j), I = l(j.from, j.to), We = I ? null : E("planmagnet.analytics.range.invalid", "\"From\" must be on or before \"To\".");
@@ -381,10 +381,10 @@ function E() {
381
381
  }), /* @__PURE__ */ h(x, {
382
382
  value: N,
383
383
  onValueChange: Je,
384
- children: [/* @__PURE__ */ m(Ae, {
384
+ children: [/* @__PURE__ */ m(ke, {
385
385
  className: "h-8 w-56",
386
386
  "data-testid": "analytics-project",
387
- children: /* @__PURE__ */ m(je, { placeholder: E("planmagnet.analytics.range.allProjects", "All projects") })
387
+ children: /* @__PURE__ */ m(Ae, { placeholder: E("planmagnet.analytics.range.allProjects", "All projects") })
388
388
  }), /* @__PURE__ */ h(S, { children: [/* @__PURE__ */ m(C, {
389
389
  value: "all",
390
390
  children: E("planmagnet.analytics.range.allProjects", "All projects")
@@ -487,9 +487,9 @@ function E() {
487
487
  children: /* @__PURE__ */ h(x, {
488
488
  value: G,
489
489
  onValueChange: D,
490
- children: [/* @__PURE__ */ m(Ae, {
490
+ children: [/* @__PURE__ */ m(ke, {
491
491
  className: "h-8 w-48",
492
- children: /* @__PURE__ */ m(je, { placeholder: E("planmagnet.analytics.delivery.sprintPlaceholder", "Select sprint") })
492
+ children: /* @__PURE__ */ m(Ae, { placeholder: E("planmagnet.analytics.delivery.sprintPlaceholder", "Select sprint") })
493
493
  }), /* @__PURE__ */ m(S, { children: W.map((e) => /* @__PURE__ */ m(C, {
494
494
  value: e.id,
495
495
  children: e.name
@@ -763,7 +763,7 @@ function E() {
763
763
  className: "text-sm w-12 text-right",
764
764
  children: [t, "%"]
765
765
  }),
766
- /* @__PURE__ */ m(ke, {
766
+ /* @__PURE__ */ m(Oe, {
767
767
  variant: "outline",
768
768
  className: "capitalize text-xs w-20 justify-center",
769
769
  children: n.replace("_", " ")
@@ -9,8 +9,8 @@ import { AlertTriangle as m, ArrowUpRight as h, Calendar as g, CheckSquare as _,
9
9
  import { gql as C } from "@apollo/client";
10
10
  import { useQuery as w } from "@apollo/client/react";
11
11
  import { Fragment as T, jsx as E, jsxs as D } from "react/jsx-runtime";
12
- import { useI18n as O } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
- import { Badge as k, Card as A, CardContent as j, CardHeader as M, CardTitle as N } from "@burdenoff/fe-libs/ui";
12
+ import { Badge as O, Card as k, CardContent as A, CardHeader as j, CardTitle as M } from "@burdenoff/fe-libs/ui";
13
+ import { useI18n as N } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
14
  //#region src/planmagnet/pages/DashboardDashboardPagePage.tsx
15
15
  var P = [
16
16
  "GetDashboardData",
@@ -121,7 +121,7 @@ var P = [
121
121
  }
122
122
  `;
123
123
  function I() {
124
- let { workspaceId: C } = e(), { t: I } = O(), { data: L, loading: R, error: z } = w(F, { variables: {
124
+ let { workspaceId: C } = e(), { t: I } = N(), { data: L, loading: R, error: z } = w(F, { variables: {
125
125
  workspaceId: C ?? "default",
126
126
  today: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
127
127
  } }), B = i(), V = a(), H = t(), U = f({
@@ -181,16 +181,16 @@ function I() {
181
181
  }),
182
182
  /* @__PURE__ */ E("div", {
183
183
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-4",
184
- children: Y.map((e) => /* @__PURE__ */ D(A, {
184
+ children: Y.map((e) => /* @__PURE__ */ D(k, {
185
185
  "data-testid": "dashboard-tile-link",
186
186
  ...l(() => H(`/analytics/analytics-page${u(d("30"))}`), `${e.label}: ${e.value}. ${I("planmagnet.dashboard.metrics.openAnalytics", "Open in Analytics")}`),
187
- children: [/* @__PURE__ */ D(M, {
187
+ children: [/* @__PURE__ */ D(j, {
188
188
  className: "flex flex-row items-center justify-between space-y-0 pb-2",
189
- children: [/* @__PURE__ */ E(N, {
189
+ children: [/* @__PURE__ */ E(M, {
190
190
  className: "text-sm font-medium",
191
191
  children: e.label
192
192
  }), /* @__PURE__ */ E(b, { className: "h-4 w-4 text-muted-foreground" })]
193
- }), /* @__PURE__ */ D(j, { children: [/* @__PURE__ */ E("div", {
193
+ }), /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ E("div", {
194
194
  className: "text-2xl font-bold",
195
195
  children: e.value
196
196
  }), /* @__PURE__ */ E("p", {
@@ -201,12 +201,12 @@ function I() {
201
201
  }),
202
202
  /* @__PURE__ */ D("div", {
203
203
  className: "grid gap-6 lg:grid-cols-12",
204
- children: [/* @__PURE__ */ D(A, {
204
+ children: [/* @__PURE__ */ D(k, {
205
205
  className: "lg:col-span-8",
206
- children: [/* @__PURE__ */ E(M, { children: /* @__PURE__ */ D(N, {
206
+ children: [/* @__PURE__ */ E(j, { children: /* @__PURE__ */ D(M, {
207
207
  className: "flex items-center gap-2 text-base",
208
208
  children: [/* @__PURE__ */ E(S, { className: "h-5 w-5 text-blue-500" }), I("planmagnet.dashboard.activeSprints.title", "Active Sprints")]
209
- }) }), /* @__PURE__ */ D(j, {
209
+ }) }), /* @__PURE__ */ D(A, {
210
210
  className: "space-y-4",
211
211
  children: [K.map((e) => {
212
212
  let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), n = e.workItems.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0), r = e.workItems.length, i = e.workItems.filter((e) => e.status === "DONE").length, a = o(e.workItems) ?? 0;
@@ -231,7 +231,7 @@ function I() {
231
231
  " ",
232
232
  e.project?.name ?? I("planmagnet.dashboard.shared.projectUnavailable", "not available")
233
233
  ] })
234
- })] }), /* @__PURE__ */ D(k, {
234
+ })] }), /* @__PURE__ */ D(O, {
235
235
  variant: "secondary",
236
236
  children: [
237
237
  n,
@@ -273,25 +273,25 @@ function I() {
273
273
  })]
274
274
  }), /* @__PURE__ */ D("div", {
275
275
  className: "lg:col-span-4 space-y-6",
276
- children: [G.length > 0 && /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ E(M, { children: /* @__PURE__ */ D(N, {
276
+ children: [G.length > 0 && /* @__PURE__ */ D(k, { children: [/* @__PURE__ */ E(j, { children: /* @__PURE__ */ D(M, {
277
277
  className: "flex items-center gap-2 text-base",
278
278
  children: [/* @__PURE__ */ E(m, { className: "h-5 w-5 text-orange-500" }), I("planmagnet.dashboard.onHoldProjects.title", "On-Hold Projects")]
279
- }) }), /* @__PURE__ */ E(j, {
279
+ }) }), /* @__PURE__ */ E(A, {
280
280
  className: "space-y-3",
281
281
  children: G.map((e) => /* @__PURE__ */ D("div", {
282
282
  className: "flex items-center justify-between rounded border p-2",
283
283
  children: [/* @__PURE__ */ E("div", { children: /* @__PURE__ */ E("p", {
284
284
  className: "text-sm font-medium",
285
285
  children: e.name
286
- }) }), /* @__PURE__ */ E(k, {
286
+ }) }), /* @__PURE__ */ E(O, {
287
287
  variant: "destructive",
288
288
  children: e.status.toLowerCase().replace("_", " ")
289
289
  })]
290
290
  }, e.id))
291
- })] }), /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ E(M, { children: /* @__PURE__ */ D(N, {
291
+ })] }), /* @__PURE__ */ D(k, { children: [/* @__PURE__ */ E(j, { children: /* @__PURE__ */ D(M, {
292
292
  className: "flex items-center gap-2 text-base",
293
293
  children: [/* @__PURE__ */ E(g, { className: "h-5 w-5 text-green-500" }), I("planmagnet.dashboard.upcomingMilestones.title", "Upcoming Milestones")]
294
- }) }), /* @__PURE__ */ D(j, {
294
+ }) }), /* @__PURE__ */ D(A, {
295
295
  className: "space-y-3",
296
296
  children: [q.map((e) => /* @__PURE__ */ D("div", {
297
297
  ...l(() => H(c("/projects/milestone-detail-page", e.id)), e.name),
@@ -321,7 +321,7 @@ function I() {
321
321
  ]
322
322
  })
323
323
  ]
324
- }), /* @__PURE__ */ E(k, {
324
+ }), /* @__PURE__ */ E(O, {
325
325
  variant: "secondary",
326
326
  className: "text-xs flex-shrink-0 capitalize",
327
327
  children: e.status.toLowerCase().replace("_", " ")
@@ -335,10 +335,10 @@ function I() {
335
335
  }),
336
336
  /* @__PURE__ */ D("div", {
337
337
  className: "grid gap-6 lg:grid-cols-2",
338
- children: [/* @__PURE__ */ D(A, { children: [/* @__PURE__ */ E(M, { children: /* @__PURE__ */ D(N, {
338
+ children: [/* @__PURE__ */ D(k, { children: [/* @__PURE__ */ E(j, { children: /* @__PURE__ */ D(M, {
339
339
  className: "flex items-center gap-2 text-base",
340
340
  children: [/* @__PURE__ */ E(_, { className: "h-5 w-5 text-purple-500" }), I("planmagnet.dashboard.recentWorkItems.title", "Recent Work Items")]
341
- }) }), /* @__PURE__ */ D(j, {
341
+ }) }), /* @__PURE__ */ D(A, {
342
342
  className: "space-y-3",
343
343
  children: [J.map((e) => /* @__PURE__ */ D("div", {
344
344
  ...l(() => H(`/tasks/task-detail-page?taskId=${encodeURIComponent(e.id)}`), `${e.key} ${e.title}`),
@@ -361,7 +361,7 @@ function I() {
361
361
  })]
362
362
  }), /* @__PURE__ */ D("div", {
363
363
  className: "flex items-center gap-2 flex-shrink-0",
364
- children: [/* @__PURE__ */ D(k, {
364
+ children: [/* @__PURE__ */ D(O, {
365
365
  variant: "outline",
366
366
  className: "text-xs",
367
367
  children: [
@@ -369,7 +369,7 @@ function I() {
369
369
  " ",
370
370
  I("planmagnet.dashboard.shared.pointsShort", "pts")
371
371
  ]
372
- }), /* @__PURE__ */ E(k, {
372
+ }), /* @__PURE__ */ E(O, {
373
373
  variant: "secondary",
374
374
  className: "text-xs capitalize",
375
375
  children: e.status.toLowerCase().replace("_", " ")
@@ -379,10 +379,10 @@ function I() {
379
379
  className: "text-sm text-muted-foreground text-center py-4",
380
380
  children: I("planmagnet.dashboard.recentWorkItems.empty", "No work items yet.")
381
381
  })]
382
- })] }), /* @__PURE__ */ D(A, { children: [/* @__PURE__ */ E(M, { children: /* @__PURE__ */ D(N, {
382
+ })] }), /* @__PURE__ */ D(k, { children: [/* @__PURE__ */ E(j, { children: /* @__PURE__ */ D(M, {
383
383
  className: "flex items-center gap-2 text-base",
384
384
  children: [/* @__PURE__ */ E(v, { className: "h-5 w-5 text-cyan-500" }), I("planmagnet.dashboard.projectStatus.title", "Project Status")]
385
- }) }), /* @__PURE__ */ D(j, {
385
+ }) }), /* @__PURE__ */ D(A, {
386
386
  className: "space-y-3",
387
387
  children: [W.map((e) => /* @__PURE__ */ D("div", {
388
388
  ...l(() => H(c("/projects/project-detail-page", e.id)), e.name),
@@ -1 +1 @@
1
- {"version":3,"file":"DocsDocDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/DocsDocDetailPagePage.tsx"],"names":[],"mappings":"AAiRA,wBAAgB,qBAAqB,4CAsrBpC"}
1
+ {"version":3,"file":"DocsDocDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/DocsDocDetailPagePage.tsx"],"names":[],"mappings":"AAwTA,wBAAgB,qBAAqB,4CA+wBpC"}