@burdenoff/microfe-planmagnet 2026.1001.5 → 2026.1001.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +10 -6
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/automation/automationRuleTypes.d.ts +31 -19
- package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -1
- package/dist/planmagnet/automation/automationRuleTypes.js +4 -8
- package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -1
- package/dist/planmagnet/controls/CompetitorControls.d.ts +71 -0
- package/dist/planmagnet/controls/CompetitorControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/CompetitorControls.js +346 -12
- package/dist/planmagnet/controls/CompetitorControls.js.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts +23 -1
- package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/FeatureControls.js +431 -229
- package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
- package/dist/planmagnet/controls/FeedbackControls.d.ts +70 -0
- package/dist/planmagnet/controls/FeedbackControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/FeedbackControls.js +153 -0
- package/dist/planmagnet/controls/FeedbackControls.js.map +1 -0
- package/dist/planmagnet/controls/Pickers.d.ts +15 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +61 -1
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.d.ts +36 -0
- package/dist/planmagnet/controls/PrioritizationControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/PrioritizationControls.js +118 -1
- package/dist/planmagnet/controls/PrioritizationControls.js.map +1 -1
- package/dist/planmagnet/controls/SyncControls.d.ts.map +1 -1
- package/dist/planmagnet/controls/SyncControls.js +1 -0
- package/dist/planmagnet/controls/SyncControls.js.map +1 -1
- package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts +47 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +1 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js +542 -0
- package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +1 -0
- package/dist/planmagnet/dashboards/DashboardUI.js +8 -8
- package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +4 -4
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.d.ts.map +1 -1
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js +67 -59
- package/dist/planmagnet/dashboards/cards/SprintCapacityCard.js.map +1 -1
- package/dist/planmagnet/forecast/DeliveryForecastCard.js +8 -8
- package/dist/planmagnet/forecast/ProjectOutlookCard.js +10 -10
- package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +9 -9
- package/dist/planmagnet/forecast/ResourceForecastCard.js +6 -6
- package/dist/planmagnet/integrations/syncTypes.d.ts +2 -1
- package/dist/planmagnet/integrations/syncTypes.d.ts.map +1 -1
- package/dist/planmagnet/integrations/syncTypes.js +19 -9
- package/dist/planmagnet/integrations/syncTypes.js.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +290 -283
- package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js +126 -63
- package/dist/planmagnet/pages/CompetitorsCompetitorDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js +14 -0
- package/dist/planmagnet/pages/CompetitorsCompetitorsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js +93 -57
- package/dist/planmagnet/pages/CompetitorsCreateCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js +125 -83
- package/dist/planmagnet/pages/CompetitorsEditCompetitorPagePage.js.map +1 -1
- package/dist/planmagnet/pages/DashboardDashboardPagePage.js +23 -23
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +340 -248
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +172 -167
- package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +92 -83
- package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts +2 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +175 -0
- package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +1 -0
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js +226 -126
- package/dist/planmagnet/pages/PortfoliosPortfolioDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +151 -126
- package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +169 -122
- package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +165 -109
- package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsProductsPagePage.js +13 -13
- package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +9 -9
- package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +8 -8
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js +15 -3
- package/dist/planmagnet/pages/ProjectsPlanningDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +12 -12
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +23 -23
- package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +18 -18
- package/dist/planmagnet/pages/TasksMyWorkPagePage.js +10 -10
- package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +5 -5
- package/dist/planmagnet/pages/TeamTeamPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TeamTeamPagePage.js +59 -53
- package/dist/planmagnet/pages/TeamTeamPagePage.js.map +1 -1
- package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -8
- package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +6 -6
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts +8 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.d.ts.map +1 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js +164 -0
- package/dist/planmagnet/pages/analytics/MetricsCard.js.map +1 -0
- package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +6 -6
- package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +8 -8
- package/dist/planmagnet/pages/analytics/StatusFlowCard.js +7 -7
- package/dist/planmagnet/pages/analytics/ThroughputCard.js +7 -7
- package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +7 -7
- package/dist/planmagnet/people/People.d.ts +14 -0
- package/dist/planmagnet/people/People.d.ts.map +1 -1
- package/dist/planmagnet/people/People.js +36 -22
- package/dist/planmagnet/people/People.js.map +1 -1
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts +2 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.d.ts.map +1 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js +155 -0
- package/dist/planmagnet/team/UnmatchedCrewIdentities.js.map +1 -0
- package/dist/planmagnet/webhooks/webhookTypes.d.ts +54 -0
- package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +1 -0
- package/dist/planmagnet/webhooks/webhookTypes.js +17 -0
- package/dist/planmagnet/webhooks/webhookTypes.js.map +1 -0
- package/package.json +1 -1
|
@@ -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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsAnalyticsPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/AnalyticsAnalyticsPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AnalyticsAnalyticsPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/AnalyticsAnalyticsPagePage.tsx"],"names":[],"mappings":"AAkTA,wBAAgB,0BAA0B,4CAwvBzC"}
|