@memberjunction/ng-dashboards 5.9.0 → 5.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +10 -10
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +16 -22
- package/dist/DataExplorer/components/view-selector/view-selector.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +31 -11
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +7 -7
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +1 -1
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.d.ts.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +12 -12
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +55 -143
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/package.json +40 -40
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-data.service.js","sourceRoot":"","sources":["../../../src/Integration/services/integration-data.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Metadata, RunView, IRunViewProvider } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport {\n MJCompanyIntegrationEntityMapEntity,\n MJCompanyIntegrationFieldMapEntity\n} from '@memberjunction/core-entities';\nimport {\n GraphQLDataProvider,\n GraphQLIntegrationClient,\n GraphQLActionClient,\n DiscoveredObjectResult,\n DiscoveredFieldResult,\n DiscoveryResult,\n ConnectionTestGraphQLResult,\n SchemaPreviewObjectInput,\n SchemaPreviewResult,\n DefaultConfigResult\n} from '@memberjunction/graphql-dataprovider';\n\n/**\n * Simple row types for read-only data loaded via ResultType: 'simple'\n */\nexport interface IntegrationRow {\n ID: string;\n Name: string;\n IsActive: boolean | null;\n LastRunID: string | null;\n LastRunStartedAt: string | null;\n LastRunEndedAt: string | null;\n Company: string;\n Integration: string;\n DriverClassName: string | null;\n}\n\nexport interface IntegrationRunRow {\n ID: string;\n CompanyIntegrationID: string;\n StartedAt: string | null;\n EndedAt: string | null;\n TotalRecords: number;\n Status: 'Failed' | 'In Progress' | 'Pending' | 'Success';\n ErrorLog: string | null;\n Integration: string;\n Company: string;\n RunByUser: string;\n}\n\nexport interface SourceTypeRow {\n ID: string;\n Name: string;\n Description: string | null;\n DriverClass: string;\n IconClass: string | null;\n Status: 'Active' | 'Inactive';\n}\n\nexport interface EntityMapRow {\n ID: string;\n CompanyIntegrationID: string;\n ExternalObjectName: string;\n ExternalObjectLabel: string | null;\n EntityID: string;\n SyncDirection: 'Bidirectional' | 'Pull' | 'Push';\n SyncEnabled: boolean;\n MatchStrategy: string | null;\n ConflictResolution: 'DestWins' | 'Manual' | 'MostRecent' | 'SourceWins';\n Priority: number;\n DeleteBehavior: 'DoNothing' | 'HardDelete' | 'SoftDelete';\n Status: 'Active' | 'Inactive';\n Entity: string;\n}\n\nexport interface FieldMapRow {\n ID: string;\n EntityMapID: string;\n SourceFieldName: string;\n SourceFieldLabel: string | null;\n DestinationFieldName: string;\n DestinationFieldLabel: string | null;\n Direction: 'Both' | 'DestToSource' | 'SourceToDest';\n TransformPipeline: string | null;\n IsKeyField: boolean;\n IsRequired: boolean;\n DefaultValue: string | null;\n Priority: number;\n Status: 'Active' | 'Inactive';\n}\n\n/** Aggregated per-entity stats for a run (computed client-side from raw detail records) */\nexport interface RunDetailRow {\n EntityID: string;\n Entity: string;\n RecordsProcessed: number;\n RecordsCreated: number;\n RecordsUpdated: number;\n RecordsDeleted: number;\n RecordsErrored: number;\n RecordsSkipped: number;\n}\n\n/** Raw record from MJ: Company Integration Run Details (one row per record operation) */\ninterface RawRunDetailRecord {\n ID: string;\n CompanyIntegrationRunID: string;\n EntityID: string;\n RecordID: string;\n Action: string;\n IsSuccess: boolean;\n Entity: string;\n}\n\n/** Master integration definition (e.g., \"HubSpot\", \"Salesforce\") */\nexport interface IntegrationDefinitionRow {\n ID: string;\n Name: string;\n Description: string | null;\n ClassName: string | null;\n ImportPath: string | null;\n NavigationBaseURL: string | null;\n BatchMaxRequestCount: number;\n BatchRequestWaitTime: number;\n CredentialTypeID: string | null;\n SourceTypeID: string | null;\n}\n\n/** Aggregated summary for a single integration, used by the Control Tower UI */\nexport interface IntegrationSummary {\n Integration: IntegrationRow;\n SourceType: SourceTypeRow | null;\n LatestRun: IntegrationRunRow | null;\n RecentRuns: IntegrationRunRow[];\n StatusColor: 'green' | 'amber' | 'red' | 'gray';\n RelativeTime: string;\n TotalRecordsSyncedToday: number;\n TotalErrors: number;\n DurationMs: number | null;\n}\n\n/** KPI data for the Control Tower top strip */\nexport interface IntegrationKPIs {\n TotalIntegrations: number;\n ActiveSyncs: number;\n RecordsSyncedToday: number;\n ErrorRate: number;\n AverageSyncDurationMs: number | null;\n}\n\n/** Activity feed item for the Control Tower bottom section */\nexport interface ActivityFeedItem {\n RunID: string;\n IntegrationName: string;\n Status: 'Failed' | 'In Progress' | 'Pending' | 'Success';\n StatusColor: 'amber' | 'green' | 'red';\n StartedAt: string | null;\n RelativeTime: string;\n TotalRecords: number;\n RunByUser: string;\n}\n\n/** Daily record count for the bar chart */\nexport interface DailyRecordCount {\n Date: string;\n Label: string;\n Records: number;\n}\n\n/** Schedule row for the Schedules component (includes new scheduling fields) */\nexport interface ScheduleRow {\n ID: string;\n Name: string;\n Integration: string;\n Company: string;\n IsActive: boolean | null;\n ScheduleEnabled: boolean;\n ScheduleType: 'Manual' | 'Interval' | 'Cron';\n ScheduleIntervalMinutes: number | null;\n CronExpression: string | null;\n NextScheduledRunAt: string | null;\n LastScheduledRunAt: string | null;\n IsLocked: boolean;\n LockedAt: string | null;\n}\n\n/** Watermark row for the Activity detail panel */\nexport interface WatermarkRow {\n ID: string;\n EntityMapID: string;\n WatermarkType: string;\n WatermarkValue: string | null;\n Direction: 'Pull' | 'Push';\n EntityMap: string;\n}\n\n/** Shared icon resolution map for integration names to Font Awesome icon classes */\nconst INTEGRATION_ICON_MAP: Array<{ Pattern: RegExp; Icon: string }> = [\n { Pattern: /hubspot/i, Icon: 'fa-brands fa-hubspot' },\n { Pattern: /salesforce/i, Icon: 'fa-brands fa-salesforce' },\n { Pattern: /google/i, Icon: 'fa-brands fa-google' },\n { Pattern: /microsoft|dynamics|azure/i, Icon: 'fa-brands fa-microsoft' },\n { Pattern: /slack/i, Icon: 'fa-brands fa-slack' },\n { Pattern: /jira|atlassian/i, Icon: 'fa-brands fa-atlassian' },\n { Pattern: /github/i, Icon: 'fa-brands fa-github' },\n { Pattern: /stripe/i, Icon: 'fa-brands fa-stripe' },\n { Pattern: /shopify/i, Icon: 'fa-brands fa-shopify' },\n { Pattern: /mailchimp/i, Icon: 'fa-brands fa-mailchimp' },\n { Pattern: /wordpress/i, Icon: 'fa-brands fa-wordpress' },\n { Pattern: /dropbox/i, Icon: 'fa-brands fa-dropbox' },\n { Pattern: /csv|file|import/i, Icon: 'fa-solid fa-file-csv' },\n { Pattern: /postgres|mysql|sql|database|db/i, Icon: 'fa-solid fa-database' },\n { Pattern: /api|rest|graphql/i, Icon: 'fa-solid fa-code' },\n { Pattern: /member|membership/i, Icon: 'fa-solid fa-users' },\n { Pattern: /email|mail/i, Icon: 'fa-solid fa-envelope' },\n { Pattern: /calendar|event/i, Icon: 'fa-solid fa-calendar' }\n];\n\n/** Resolve an integration name to a Font Awesome icon class */\nexport function ResolveIntegrationIcon(name: string): string {\n const match = INTEGRATION_ICON_MAP.find(m => m.Pattern.test(name));\n return match ? match.Icon : 'fa-solid fa-plug';\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class IntegrationDataService {\n\n async LoadIntegrationSummaries(provider?: IRunViewProvider | null): Promise<IntegrationSummary[]> {\n const rv = this.createRunView(provider);\n const [integrationsResult, runsResult, sourceTypesResult, defsResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Company Integrations',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'IsActive', 'LastRunID',\n 'LastRunStartedAt', 'LastRunEndedAt', 'Company', 'Integration',\n 'DriverClassName'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Integration Source Types',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'Description', 'DriverClass', 'IconClass', 'Status'],\n ResultType: 'simple'\n },\n {\n EntityName: 'MJ: Integrations',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'Description', 'ClassName', 'ImportPath',\n 'NavigationBaseURL', 'BatchMaxRequestCount', 'BatchRequestWaitTime',\n 'CredentialTypeID', 'SourceTypeID'],\n ResultType: 'simple'\n }\n ]);\n\n const integrations = integrationsResult.Results as IntegrationRow[];\n const runs = runsResult.Results as IntegrationRunRow[];\n const sourceTypes = sourceTypesResult.Results as SourceTypeRow[];\n const defs = defsResult.Results as IntegrationDefinitionRow[];\n\n return integrations.map(integration => this.buildSummary(integration, runs, sourceTypes, defs));\n }\n\n async LoadEntityMaps(companyIntegrationID: string, provider?: IRunViewProvider | null): Promise<EntityMapRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<EntityMapRow>({\n EntityName: 'MJ: Company Integration Entity Maps',\n ExtraFilter: `CompanyIntegrationID='${companyIntegrationID}'`,\n OrderBy: 'Priority, ExternalObjectName',\n Fields: ['ID', 'CompanyIntegrationID', 'ExternalObjectName', 'ExternalObjectLabel',\n 'EntityID', 'SyncDirection', 'SyncEnabled', 'MatchStrategy',\n 'ConflictResolution', 'Priority', 'DeleteBehavior', 'Status', 'Entity'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadFieldMaps(entityMapID: string, provider?: IRunViewProvider | null): Promise<FieldMapRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<FieldMapRow>({\n EntityName: 'MJ: Company Integration Field Maps',\n ExtraFilter: `EntityMapID='${entityMapID}'`,\n OrderBy: 'Priority, SourceFieldName',\n Fields: ['ID', 'EntityMapID', 'SourceFieldName', 'SourceFieldLabel',\n 'DestinationFieldName', 'DestinationFieldLabel', 'Direction',\n 'TransformPipeline', 'IsKeyField', 'IsRequired', 'DefaultValue',\n 'Priority', 'Status'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadRunHistory(companyIntegrationID: string, limit: number = 10, provider?: IRunViewProvider | null): Promise<IntegrationRunRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `CompanyIntegrationID='${companyIntegrationID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: limit,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadRunDetails(runID: string, provider?: IRunViewProvider | null): Promise<RunDetailRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<RawRunDetailRecord>({\n EntityName: 'MJ: Company Integration Run Details',\n ExtraFilter: `CompanyIntegrationRunID='${runID}'`,\n OrderBy: 'Entity',\n Fields: ['ID', 'CompanyIntegrationRunID', 'EntityID', 'RecordID',\n 'Action', 'IsSuccess', 'Entity'],\n ResultType: 'simple'\n });\n return this.aggregateRunDetails(result.Results);\n }\n\n /** Aggregate raw per-record detail rows into per-entity summary rows */\n private aggregateRunDetails(rawRecords: RawRunDetailRecord[]): RunDetailRow[] {\n const entityMap = new Map<string, RunDetailRow>();\n\n for (const rec of rawRecords) {\n const key = rec.EntityID.toLowerCase();\n let row = entityMap.get(key);\n if (!row) {\n row = {\n EntityID: rec.EntityID,\n Entity: rec.Entity,\n RecordsProcessed: 0,\n RecordsCreated: 0,\n RecordsUpdated: 0,\n RecordsDeleted: 0,\n RecordsErrored: 0,\n RecordsSkipped: 0\n };\n entityMap.set(key, row);\n }\n\n row.RecordsProcessed++;\n\n if (!rec.IsSuccess) {\n row.RecordsErrored++;\n } else {\n const action = (rec.Action ?? '').toUpperCase();\n if (action === 'INSERT' || action === 'CREATE') {\n row.RecordsCreated++;\n } else if (action === 'UPDATE') {\n row.RecordsUpdated++;\n } else if (action === 'DELETE') {\n row.RecordsDeleted++;\n } else if (action === 'SKIP' || action === 'SKIPPED') {\n row.RecordsSkipped++;\n }\n }\n }\n\n return Array.from(entityMap.values()).sort((a, b) => a.Entity.localeCompare(b.Entity));\n }\n\n async LoadIntegrationDefinitions(provider?: IRunViewProvider | null): Promise<IntegrationDefinitionRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<IntegrationDefinitionRow>({\n EntityName: 'MJ: Integrations',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'Description', 'ClassName', 'ImportPath',\n 'NavigationBaseURL', 'BatchMaxRequestCount', 'BatchRequestWaitTime',\n 'CredentialTypeID', 'SourceTypeID'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadSourceTypes(provider?: IRunViewProvider | null): Promise<SourceTypeRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<SourceTypeRow>({\n EntityName: 'MJ: Integration Source Types',\n ExtraFilter: 'Status=\\'Active\\'',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'Description', 'DriverClass', 'IconClass', 'Status'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadRecentRuns(limit: number = 20, provider?: IRunViewProvider | null): Promise<ActivityFeedItem[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n MaxRows: limit,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n return result.Results.map(run => this.buildActivityFeedItem(run));\n }\n\n async LoadDailyRecordCounts(days: number = 7, provider?: IRunViewProvider | null): Promise<DailyRecordCount[]> {\n const rv = this.createRunView(provider);\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n const cutoffStr = cutoffDate.toISOString().split('T')[0];\n\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `StartedAt >= '${cutoffStr}'`,\n OrderBy: 'StartedAt ASC',\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n\n return this.aggregateDailyCounts(result.Results, days);\n }\n\n ComputeKPIs(summaries: IntegrationSummary[]): IntegrationKPIs {\n const totalIntegrations = summaries.length;\n const activeSyncs = summaries.filter(\n s => s.LatestRun?.Status === 'In Progress' || s.LatestRun?.Status === 'Pending'\n ).length;\n const recordsSyncedToday = summaries.reduce((acc, s) => acc + s.TotalRecordsSyncedToday, 0);\n\n const totalRuns = summaries.reduce((acc, s) => acc + s.RecentRuns.length, 0);\n const totalErrors = summaries.reduce((acc, s) => acc + s.TotalErrors, 0);\n const errorRate = totalRuns > 0 ? (totalErrors / totalRuns) * 100 : 0;\n\n const durationsMs = summaries\n .filter(s => s.DurationMs != null)\n .map(s => s.DurationMs as number);\n const averageSyncDurationMs = durationsMs.length > 0\n ? durationsMs.reduce((a, b) => a + b, 0) / durationsMs.length\n : null;\n\n return {\n TotalIntegrations: totalIntegrations,\n ActiveSyncs: activeSyncs,\n RecordsSyncedToday: recordsSyncedToday,\n ErrorRate: Math.round(errorRate * 10) / 10,\n AverageSyncDurationMs: averageSyncDurationMs\n };\n }\n\n FormatDuration(ms: number | null): string {\n if (ms == null) return '--';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return `${minutes}m ${seconds}s`;\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}h ${remainingMinutes}m`;\n }\n\n ComputeRelativeTime(dateStr: string | null): string {\n return this.computeRelativeTime(dateStr);\n }\n\n // --- Entity Map CRUD ---\n\n async CreateEntityMap(params: {\n CompanyIntegrationID: string;\n ExternalObjectName: string;\n ExternalObjectLabel?: string;\n EntityID: string;\n SyncDirection?: 'Pull' | 'Push' | 'Bidirectional';\n ConflictResolution?: 'SourceWins' | 'DestWins' | 'MostRecent' | 'Manual';\n Priority?: number;\n DeleteBehavior?: 'SoftDelete' | 'DoNothing' | 'HardDelete';\n }): Promise<MJCompanyIntegrationEntityMapEntity | null> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n em.NewRecord();\n em.CompanyIntegrationID = params.CompanyIntegrationID;\n em.ExternalObjectName = params.ExternalObjectName;\n if (params.ExternalObjectLabel) em.ExternalObjectLabel = params.ExternalObjectLabel;\n em.EntityID = params.EntityID;\n em.SyncDirection = params.SyncDirection ?? 'Pull';\n em.ConflictResolution = params.ConflictResolution ?? 'SourceWins';\n em.Priority = params.Priority ?? 0;\n em.DeleteBehavior = params.DeleteBehavior ?? 'SoftDelete';\n em.Status = 'Active';\n em.SyncEnabled = true;\n\n const saved = await em.Save();\n if (!saved) {\n console.error('[IntegrationDataService] Failed to create entity map:', em.LatestResult?.CompleteMessage);\n return null;\n }\n return em;\n }\n\n async DeleteEntityMap(entityMapID: string): Promise<boolean> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n await em.Load(entityMapID);\n return em.Delete();\n }\n\n async ToggleEntityMapEnabled(entityMapID: string, enabled: boolean): Promise<boolean> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n await em.Load(entityMapID);\n em.SyncEnabled = enabled;\n return em.Save();\n }\n\n // --- Field Map CRUD ---\n\n async CreateFieldMap(params: {\n EntityMapID: string;\n SourceFieldName: string;\n SourceFieldLabel?: string;\n DestinationFieldName: string;\n DestinationFieldLabel?: string;\n IsKeyField?: boolean;\n IsRequired?: boolean;\n Direction?: 'SourceToDest' | 'DestToSource' | 'Both';\n TransformPipeline?: string | null;\n Priority?: number;\n }): Promise<MJCompanyIntegrationFieldMapEntity | null> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n fm.NewRecord();\n fm.EntityMapID = params.EntityMapID;\n fm.SourceFieldName = params.SourceFieldName;\n if (params.SourceFieldLabel) fm.SourceFieldLabel = params.SourceFieldLabel;\n fm.DestinationFieldName = params.DestinationFieldName;\n if (params.DestinationFieldLabel) fm.DestinationFieldLabel = params.DestinationFieldLabel;\n fm.IsKeyField = params.IsKeyField ?? false;\n fm.IsRequired = params.IsRequired ?? false;\n fm.Direction = params.Direction ?? 'SourceToDest';\n if (params.TransformPipeline !== undefined) fm.TransformPipeline = params.TransformPipeline;\n fm.Status = 'Active';\n fm.Priority = params.Priority ?? 0;\n\n const saved = await fm.Save();\n if (!saved) {\n console.error('[IntegrationDataService] Failed to create field map:', fm.LatestResult?.CompleteMessage);\n return null;\n }\n return fm;\n }\n\n async DeleteFieldMap(fieldMapID: string): Promise<boolean> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n await fm.Load(fieldMapID);\n return fm.Delete();\n }\n\n async UpdateFieldMap(fieldMapID: string, updates: {\n SourceFieldName?: string;\n DestinationFieldName?: string;\n IsKeyField?: boolean;\n IsRequired?: boolean;\n Direction?: 'SourceToDest' | 'DestToSource' | 'Both';\n Status?: 'Active' | 'Inactive';\n TransformPipeline?: string | null;\n }): Promise<boolean> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n await fm.Load(fieldMapID);\n if (updates.SourceFieldName !== undefined) fm.SourceFieldName = updates.SourceFieldName;\n if (updates.DestinationFieldName !== undefined) fm.DestinationFieldName = updates.DestinationFieldName;\n if (updates.IsKeyField !== undefined) fm.IsKeyField = updates.IsKeyField;\n if (updates.IsRequired !== undefined) fm.IsRequired = updates.IsRequired;\n if (updates.Direction !== undefined) fm.Direction = updates.Direction;\n if (updates.Status !== undefined) fm.Status = updates.Status;\n if (updates.TransformPipeline !== undefined) fm.TransformPipeline = updates.TransformPipeline;\n return fm.Save();\n }\n\n /** Load available MJ entities for mapping target selection */\n async LoadMJEntities(provider?: IRunViewProvider | null): Promise<Array<{ ID: string; Name: string }>> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<{ ID: string; Name: string }>({\n EntityName: 'MJ: Entities',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n /** Load entity fields for a given entity (for field mapping destination picker) */\n async LoadEntityFields(entityID: string, provider?: IRunViewProvider | null): Promise<Array<{ ID: string; Name: string; Type: string; IsRequired: boolean }>> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<{ ID: string; Name: string; Type: string; IsRequired: boolean }>({\n EntityName: 'MJ: Entity Fields',\n ExtraFilter: `EntityID='${entityID}'`,\n OrderBy: 'Sequence',\n Fields: ['ID', 'Name', 'Type', 'IsRequired'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n // --- Discovery (via GraphQL) ---\n\n /** Discover external objects available for a company integration */\n async DiscoverObjects(companyIntegrationID: string): Promise<DiscoveryResult<DiscoveredObjectResult[]>> {\n const client = this.getIntegrationClient();\n return client.DiscoverObjects(companyIntegrationID);\n }\n\n /** Discover fields on a specific external object */\n async DiscoverFields(companyIntegrationID: string, objectName: string): Promise<DiscoveryResult<DiscoveredFieldResult[]>> {\n const client = this.getIntegrationClient();\n return client.DiscoverFields(companyIntegrationID, objectName);\n }\n\n /** Generate DDL preview for creating tables from discovered objects */\n async SchemaPreview(\n companyIntegrationID: string,\n objects: SchemaPreviewObjectInput[],\n platform: string = 'sqlserver'\n ): Promise<SchemaPreviewResult> {\n const client = this.getIntegrationClient();\n return client.SchemaPreview(companyIntegrationID, objects, platform);\n }\n\n /** Get the connector's default configuration for quick setup */\n async GetDefaultConfig(companyIntegrationID: string): Promise<DefaultConfigResult> {\n const client = this.getIntegrationClient();\n return client.GetDefaultConfig(companyIntegrationID);\n }\n\n /** Test connection to the external system */\n async TestConnection(companyIntegrationID: string): Promise<ConnectionTestGraphQLResult> {\n const client = this.getIntegrationClient();\n return client.TestConnection(companyIntegrationID);\n }\n\n /** Preview source data from the external system via connector's FetchChanges */\n async PreviewSourceData(\n companyIntegrationID: string,\n objectName: string,\n limit: number = 5\n ): Promise<Array<Record<string, string | number | boolean | null>>> {\n const client = this.getIntegrationClient();\n const result = await client.PreviewData(companyIntegrationID, objectName, limit);\n if (!result.Success || !result.Records) {\n console.warn('[IntegrationDataService] PreviewSourceData failed:', result.Message);\n return [];\n }\n return result.Records.map(r => {\n try {\n return JSON.parse(r.Data) as Record<string, string | number | boolean | null>;\n } catch {\n return { _raw: r.Data } as Record<string, string | number | boolean | null>;\n }\n });\n }\n\n /** Preview destination data by loading a few records from the target entity */\n async PreviewDestinationData(\n entityID: string,\n limit: number = 5,\n provider?: IRunViewProvider | null\n ): Promise<Array<Record<string, string | number | boolean | null>>> {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => UUIDsEqual(e.ID, entityID));\n if (!entityInfo) return [];\n\n // Load first N fields (skip internal __mj fields) to keep preview compact\n const fields = entityInfo.Fields\n .filter(f => !f.Name.startsWith('__mj'))\n .slice(0, 8)\n .map(f => f.Name);\n\n const rv = this.createRunView(provider);\n const result = await rv.RunView<Record<string, string | number | boolean | null>>({\n EntityName: entityInfo.Name,\n ExtraFilter: '',\n OrderBy: `${fields[0]} ASC`,\n MaxRows: limit,\n Fields: fields,\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n /** Get a count of records in the destination MJ entity */\n async GetDestinationRecordCount(\n entityID: string,\n provider?: IRunViewProvider | null\n ): Promise<number> {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => UUIDsEqual(e.ID, entityID));\n if (!entityInfo) return 0;\n\n const rv = this.createRunView(provider);\n const result = await rv.RunView<{ TotalCount: number }>({\n EntityName: entityInfo.Name,\n ExtraFilter: '',\n Fields: [entityInfo.FirstPrimaryKey?.Name ?? 'ID'],\n ResultType: 'simple'\n });\n return result.TotalRowCount ?? result.Results.length;\n }\n\n /** Get the most recent run that touched a given entity */\n async GetLastSyncForEntity(\n companyIntegrationID: string,\n entityID: string,\n provider?: IRunViewProvider | null\n ): Promise<{ StartedAt: string | null; EndedAt: string | null; Status: string; TotalRecords: number } | null> {\n const rv = this.createRunView(provider);\n // Get runs for this integration, most recent first\n const runsResult = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `CompanyIntegrationID='${companyIntegrationID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: 5,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords', 'Status'],\n ResultType: 'simple'\n });\n if (runsResult.Results.length === 0) return null;\n\n // Check each run's details to find one that touched this entity\n for (const run of runsResult.Results) {\n const detailResult = await rv.RunView<{ EntityID: string }>({\n EntityName: 'MJ: Company Integration Run Details',\n ExtraFilter: `CompanyIntegrationRunID='${run.ID}' AND EntityID='${entityID}'`,\n MaxRows: 1,\n Fields: ['EntityID'],\n ResultType: 'simple'\n });\n if (detailResult.Results.length > 0) {\n return {\n StartedAt: run.StartedAt,\n EndedAt: run.EndedAt,\n Status: run.Status,\n TotalRecords: run.TotalRecords\n };\n }\n }\n // No run touched this entity — return the most recent run anyway as context\n const latest = runsResult.Results[0];\n return {\n StartedAt: latest.StartedAt,\n EndedAt: latest.EndedAt,\n Status: latest.Status,\n TotalRecords: latest.TotalRecords\n };\n }\n\n /** Run an integration sync via the \"Run Integration Sync\" action */\n async RunSync(companyIntegrationID: string): Promise<{ Success: boolean; Message: string }> {\n const actionID = await this.lookupActionID('Run Integration Sync');\n if (!actionID) {\n return {\n Success: false,\n Message: 'Action \"Run Integration Sync\" not found. Ensure the action is registered.'\n };\n }\n\n const provider = Metadata.Provider as GraphQLDataProvider;\n const actionClient = new GraphQLActionClient(provider);\n const result = await actionClient.RunAction(actionID, [\n { Name: 'CompanyIntegrationID', Value: companyIntegrationID, Type: 'Input' }\n ]);\n return { Success: result.Success, Message: result.Message ?? '' };\n }\n\n /** Load schedule data for all company integrations (includes new scheduling fields) */\n async LoadSchedules(provider?: IRunViewProvider | null): Promise<ScheduleRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<ScheduleRow>({\n EntityName: 'MJ: Company Integrations',\n ExtraFilter: '',\n OrderBy: 'Name',\n Fields: ['ID', 'Name', 'Integration', 'Company', 'IsActive',\n 'ScheduleEnabled', 'ScheduleType', 'ScheduleIntervalMinutes',\n 'CronExpression', 'NextScheduledRunAt', 'LastScheduledRunAt',\n 'IsLocked', 'LockedAt'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n /** Load sync watermarks for a specific company integration's entity maps */\n async LoadWatermarks(companyIntegrationID: string, provider?: IRunViewProvider | null): Promise<WatermarkRow[]> {\n const rv = this.createRunView(provider);\n // First get entity maps for this integration, then load their watermarks\n const entityMaps = await this.LoadEntityMaps(companyIntegrationID, provider);\n if (entityMaps.length === 0) return [];\n\n const mapIDs = entityMaps.map(em => `'${em.ID}'`).join(',');\n const result = await rv.RunView<WatermarkRow>({\n EntityName: 'MJ: Company Integration Sync Watermarks',\n ExtraFilter: `EntityMapID IN (${mapIDs})`,\n OrderBy: 'EntityMap',\n Fields: ['ID', 'EntityMapID', 'WatermarkType', 'WatermarkValue', 'Direction', 'EntityMap'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n /** Load entity map count per company integration (used by Overview cards) */\n async LoadEntityMapCounts(provider?: IRunViewProvider | null): Promise<Map<string, number>> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<{ CompanyIntegrationID: string }>({\n EntityName: 'MJ: Company Integration Entity Maps',\n ExtraFilter: 'SyncEnabled=1',\n Fields: ['CompanyIntegrationID'],\n ResultType: 'simple'\n });\n const counts = new Map<string, number>();\n for (const row of result.Results) {\n const key = row.CompanyIntegrationID.toLowerCase();\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n return counts;\n }\n\n private async lookupActionID(actionName: string): Promise<string | null> {\n const rv = new RunView();\n const result = await rv.RunView<{ ID: string }>({\n EntityName: 'MJ: Actions',\n ExtraFilter: `Name='${actionName}'`,\n Fields: ['ID'],\n MaxRows: 1,\n ResultType: 'simple'\n });\n return result.Results.length > 0 ? result.Results[0].ID : null;\n }\n\n private getIntegrationClient(): GraphQLIntegrationClient {\n const provider = Metadata.Provider as GraphQLDataProvider;\n return new GraphQLIntegrationClient(provider);\n }\n\n private createRunView(provider?: IRunViewProvider | null): RunView {\n return new RunView(provider ?? null);\n }\n\n private buildSummary(\n integration: IntegrationRow,\n allRuns: IntegrationRunRow[],\n sourceTypes: SourceTypeRow[],\n defs: IntegrationDefinitionRow[]\n ): IntegrationSummary {\n const integrationRuns = allRuns.filter(r => UUIDsEqual(r.CompanyIntegrationID, integration.ID));\n const latestRun = integrationRuns.length > 0 ? integrationRuns[0] : null;\n const recentRuns = integrationRuns.slice(0, 5);\n const statusColor = this.computeStatusColor(latestRun, integration.IsActive);\n const relativeTime = this.computeRelativeTime(latestRun?.StartedAt ?? null);\n const totalRecordsSyncedToday = this.computeRecordsSyncedToday(integrationRuns);\n const totalErrors = integrationRuns.filter(r => r.Status === 'Failed').length;\n const durationMs = this.computeDuration(latestRun);\n const sourceType = this.resolveSourceType(integration, defs, sourceTypes);\n\n return {\n Integration: integration,\n SourceType: sourceType,\n LatestRun: latestRun,\n RecentRuns: recentRuns,\n StatusColor: statusColor,\n RelativeTime: relativeTime,\n TotalRecordsSyncedToday: totalRecordsSyncedToday,\n TotalErrors: totalErrors,\n DurationMs: durationMs\n };\n }\n\n private resolveSourceType(\n integration: IntegrationRow,\n defs: IntegrationDefinitionRow[],\n sourceTypes: SourceTypeRow[]\n ): SourceTypeRow | null {\n // Match CompanyIntegration.Integration (name) to Integration definition, then look up SourceTypeID\n const def = defs.find(d => d.Name === integration.Integration);\n if (!def?.SourceTypeID) return null;\n return sourceTypes.find(st => UUIDsEqual(st.ID, def.SourceTypeID)) ?? null;\n }\n\n private buildActivityFeedItem(run: IntegrationRunRow): ActivityFeedItem {\n return {\n RunID: run.ID,\n IntegrationName: run.Integration,\n Status: run.Status,\n StatusColor: this.runStatusColor(run),\n StartedAt: run.StartedAt,\n RelativeTime: this.computeRelativeTime(run.StartedAt),\n TotalRecords: run.TotalRecords,\n RunByUser: run.RunByUser\n };\n }\n\n private runStatusColor(run: IntegrationRunRow): 'amber' | 'green' | 'red' {\n if (run.Status === 'Failed') return 'red';\n if (run.Status === 'Success') return 'green';\n return 'amber';\n }\n\n private computeRecordsSyncedToday(runs: IntegrationRunRow[]): number {\n const todayStart = new Date();\n todayStart.setHours(0, 0, 0, 0);\n return runs\n .filter(r => r.StartedAt && new Date(r.StartedAt) >= todayStart)\n .reduce((acc, r) => acc + r.TotalRecords, 0);\n }\n\n private computeDuration(run: IntegrationRunRow | null): number | null {\n if (!run?.StartedAt || !run?.EndedAt) return null;\n return new Date(run.EndedAt).getTime() - new Date(run.StartedAt).getTime();\n }\n\n private aggregateDailyCounts(runs: IntegrationRunRow[], days: number): DailyRecordCount[] {\n const result: DailyRecordCount[] = [];\n const today = new Date();\n\n for (let i = days - 1; i >= 0; i--) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n const dateStr = date.toISOString().split('T')[0];\n const label = date.toLocaleDateString(undefined, { weekday: 'short' });\n\n const dayRecords = runs\n .filter(r => r.StartedAt && r.StartedAt.startsWith(dateStr))\n .reduce((acc, r) => acc + r.TotalRecords, 0);\n\n result.push({ Date: dateStr, Label: label, Records: dayRecords });\n }\n return result;\n }\n\n private computeStatusColor(\n latestRun: IntegrationRunRow | null,\n isActive: boolean | null\n ): 'green' | 'amber' | 'red' | 'gray' {\n if (!isActive) return 'gray';\n if (!latestRun) return 'gray';\n if (latestRun.Status === 'Failed') return 'red';\n if (latestRun.Status === 'In Progress' || latestRun.Status === 'Pending') return 'amber';\n if (latestRun.Status === 'Success') {\n return this.isStale(latestRun.StartedAt) ? 'amber' : 'green';\n }\n return 'gray';\n }\n\n private isStale(startedAt: string | null): boolean {\n if (!startedAt) return true;\n const runDate = new Date(startedAt);\n const hoursAgo = (Date.now() - runDate.getTime()) / (1000 * 60 * 60);\n return hoursAgo > 24;\n }\n\n private computeRelativeTime(dateStr: string | null): string {\n if (!dateStr) return 'Never run';\n const date = new Date(dateStr);\n const diffMs = Date.now() - date.getTime();\n const diffMinutes = Math.floor(diffMs / (1000 * 60));\n\n if (diffMinutes < 1) return 'Just now';\n if (diffMinutes < 60) return `${diffMinutes}m ago`;\n const diffHours = Math.floor(diffMinutes / 60);\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n if (diffDays < 30) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"integration-data.service.js","sourceRoot":"","sources":["../../../src/Integration/services/integration-data.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Metadata, RunView, IRunViewProvider } from '@memberjunction/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport {\n MJCompanyIntegrationEntityMapEntity,\n MJCompanyIntegrationFieldMapEntity,\n MJCompanyIntegrationEntity,\n MJIntegrationEntity,\n MJIntegrationSourceTypeEntity,\n MJCompanyIntegrationSyncWatermarkEntity,\n} from '@memberjunction/core-entities';\nimport { IntegrationEngineBase } from '@memberjunction/integration-engine-base';\nimport {\n GraphQLDataProvider,\n GraphQLIntegrationClient,\n GraphQLActionClient,\n DiscoveredObjectResult,\n DiscoveredFieldResult,\n DiscoveryResult,\n ConnectionTestGraphQLResult,\n SchemaPreviewObjectInput,\n SchemaPreviewResult,\n DefaultConfigResult\n} from '@memberjunction/graphql-dataprovider';\n\n/**\n * Simple row types for read-only data loaded via ResultType: 'simple'\n */\nexport interface IntegrationRow {\n ID: string;\n Name: string;\n IsActive: boolean | null;\n LastRunID: string | null;\n LastRunStartedAt: string | null;\n LastRunEndedAt: string | null;\n Company: string;\n Integration: string;\n DriverClassName: string | null;\n}\n\nexport interface IntegrationRunRow {\n ID: string;\n CompanyIntegrationID: string;\n StartedAt: string | null;\n EndedAt: string | null;\n TotalRecords: number;\n Status: 'Failed' | 'In Progress' | 'Pending' | 'Success';\n ErrorLog: string | null;\n Integration: string;\n Company: string;\n RunByUser: string;\n}\n\nexport interface SourceTypeRow {\n ID: string;\n Name: string;\n Description: string | null;\n DriverClass: string;\n IconClass: string | null;\n Status: 'Active' | 'Inactive';\n}\n\nexport interface EntityMapRow {\n ID: string;\n CompanyIntegrationID: string;\n ExternalObjectName: string;\n ExternalObjectLabel: string | null;\n EntityID: string;\n SyncDirection: 'Bidirectional' | 'Pull' | 'Push';\n SyncEnabled: boolean;\n MatchStrategy: string | null;\n ConflictResolution: 'DestWins' | 'Manual' | 'MostRecent' | 'SourceWins';\n Priority: number;\n DeleteBehavior: 'DoNothing' | 'HardDelete' | 'SoftDelete';\n Status: 'Active' | 'Inactive';\n Entity: string;\n}\n\nexport interface FieldMapRow {\n ID: string;\n EntityMapID: string;\n SourceFieldName: string;\n SourceFieldLabel: string | null;\n DestinationFieldName: string;\n DestinationFieldLabel: string | null;\n Direction: 'Both' | 'DestToSource' | 'SourceToDest';\n TransformPipeline: string | null;\n IsKeyField: boolean;\n IsRequired: boolean;\n DefaultValue: string | null;\n Priority: number;\n Status: 'Active' | 'Inactive';\n}\n\n/** Aggregated per-entity stats for a run (computed client-side from raw detail records) */\nexport interface RunDetailRow {\n EntityID: string;\n Entity: string;\n RecordsProcessed: number;\n RecordsCreated: number;\n RecordsUpdated: number;\n RecordsDeleted: number;\n RecordsErrored: number;\n RecordsSkipped: number;\n}\n\n/** Raw record from MJ: Company Integration Run Details (one row per record operation) */\ninterface RawRunDetailRecord {\n ID: string;\n CompanyIntegrationRunID: string;\n EntityID: string;\n RecordID: string;\n Action: string;\n IsSuccess: boolean;\n Entity: string;\n}\n\n/** Master integration definition (e.g., \"HubSpot\", \"Salesforce\") */\nexport interface IntegrationDefinitionRow {\n ID: string;\n Name: string;\n Description: string | null;\n ClassName: string | null;\n ImportPath: string | null;\n NavigationBaseURL: string | null;\n BatchMaxRequestCount: number;\n BatchRequestWaitTime: number;\n CredentialTypeID: string | null;\n SourceTypeID: string | null;\n}\n\n/** Aggregated summary for a single integration, used by the Control Tower UI */\nexport interface IntegrationSummary {\n Integration: MJCompanyIntegrationEntity;\n SourceType: MJIntegrationSourceTypeEntity | null;\n LatestRun: IntegrationRunRow | null;\n RecentRuns: IntegrationRunRow[];\n StatusColor: 'green' | 'amber' | 'red' | 'gray';\n RelativeTime: string;\n TotalRecordsSyncedToday: number;\n TotalErrors: number;\n DurationMs: number | null;\n}\n\n/** KPI data for the Control Tower top strip */\nexport interface IntegrationKPIs {\n TotalIntegrations: number;\n ActiveSyncs: number;\n RecordsSyncedToday: number;\n ErrorRate: number;\n AverageSyncDurationMs: number | null;\n}\n\n/** Activity feed item for the Control Tower bottom section */\nexport interface ActivityFeedItem {\n RunID: string;\n IntegrationName: string;\n Status: 'Failed' | 'In Progress' | 'Pending' | 'Success';\n StatusColor: 'amber' | 'green' | 'red';\n StartedAt: string | null;\n RelativeTime: string;\n TotalRecords: number;\n RunByUser: string;\n}\n\n/** Daily record count for the bar chart */\nexport interface DailyRecordCount {\n Date: string;\n Label: string;\n Records: number;\n}\n\n/** Schedule row for the Schedules component (includes new scheduling fields) */\nexport interface ScheduleRow {\n ID: string;\n Name: string;\n Integration: string;\n Company: string;\n IsActive: boolean | null;\n ScheduleEnabled: boolean;\n ScheduleType: 'Manual' | 'Interval' | 'Cron';\n ScheduleIntervalMinutes: number | null;\n CronExpression: string | null;\n NextScheduledRunAt: string | null;\n LastScheduledRunAt: string | null;\n IsLocked: boolean;\n LockedAt: string | null;\n}\n\n/** Watermark row for the Activity detail panel */\nexport interface WatermarkRow {\n ID: string;\n EntityMapID: string;\n WatermarkType: string;\n WatermarkValue: string | null;\n Direction: 'Pull' | 'Push';\n EntityMap: string;\n}\n\n/** Shared icon resolution map for integration names to Font Awesome icon classes */\nconst INTEGRATION_ICON_MAP: Array<{ Pattern: RegExp; Icon: string }> = [\n { Pattern: /hubspot/i, Icon: 'fa-brands fa-hubspot' },\n { Pattern: /salesforce/i, Icon: 'fa-brands fa-salesforce' },\n { Pattern: /google/i, Icon: 'fa-brands fa-google' },\n { Pattern: /microsoft|dynamics|azure/i, Icon: 'fa-brands fa-microsoft' },\n { Pattern: /slack/i, Icon: 'fa-brands fa-slack' },\n { Pattern: /jira|atlassian/i, Icon: 'fa-brands fa-atlassian' },\n { Pattern: /github/i, Icon: 'fa-brands fa-github' },\n { Pattern: /stripe/i, Icon: 'fa-brands fa-stripe' },\n { Pattern: /shopify/i, Icon: 'fa-brands fa-shopify' },\n { Pattern: /mailchimp/i, Icon: 'fa-brands fa-mailchimp' },\n { Pattern: /wordpress/i, Icon: 'fa-brands fa-wordpress' },\n { Pattern: /dropbox/i, Icon: 'fa-brands fa-dropbox' },\n { Pattern: /csv|file|import/i, Icon: 'fa-solid fa-file-csv' },\n { Pattern: /postgres|mysql|sql|database|db/i, Icon: 'fa-solid fa-database' },\n { Pattern: /api|rest|graphql/i, Icon: 'fa-solid fa-code' },\n { Pattern: /member|membership/i, Icon: 'fa-solid fa-users' },\n { Pattern: /email|mail/i, Icon: 'fa-solid fa-envelope' },\n { Pattern: /calendar|event/i, Icon: 'fa-solid fa-calendar' }\n];\n\n/** Resolve an integration name to a Font Awesome icon class */\nexport function ResolveIntegrationIcon(name: string): string {\n const match = INTEGRATION_ICON_MAP.find(m => m.Pattern.test(name));\n return match ? match.Icon : 'fa-solid fa-plug';\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class IntegrationDataService {\n\n async LoadIntegrationSummaries(provider?: IRunViewProvider | null): Promise<IntegrationSummary[]> {\n const engine = IntegrationEngineBase.Instance;\n const rv = this.createRunView(provider);\n\n // Engine provides cached metadata; only runs are dynamic and need a RunView call\n const [, runsResult] = await Promise.all([\n engine.Config(false),\n rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n })\n ]);\n\n const integrations = engine.CompanyIntegrations;\n const runs = runsResult.Results;\n const sourceTypes = engine.SourceTypes;\n\n return integrations.map(integration => this.buildSummary(integration, runs, sourceTypes));\n }\n\n async LoadEntityMaps(companyIntegrationID: string, _provider?: IRunViewProvider | null): Promise<MJCompanyIntegrationEntityMapEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n return IntegrationEngineBase.Instance.GetEntityMapsForCompanyIntegration(companyIntegrationID);\n }\n\n async LoadFieldMaps(entityMapID: string, _provider?: IRunViewProvider | null): Promise<MJCompanyIntegrationFieldMapEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n return IntegrationEngineBase.Instance.GetFieldMapsForEntityMap(entityMapID);\n }\n\n async LoadRunHistory(companyIntegrationID: string, limit: number = 10, provider?: IRunViewProvider | null): Promise<IntegrationRunRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `CompanyIntegrationID='${companyIntegrationID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: limit,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n async LoadRunDetails(runID: string, provider?: IRunViewProvider | null): Promise<RunDetailRow[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<RawRunDetailRecord>({\n EntityName: 'MJ: Company Integration Run Details',\n ExtraFilter: `CompanyIntegrationRunID='${runID}'`,\n OrderBy: 'Entity',\n Fields: ['ID', 'CompanyIntegrationRunID', 'EntityID', 'RecordID',\n 'Action', 'IsSuccess', 'Entity'],\n ResultType: 'simple'\n });\n return this.aggregateRunDetails(result.Results);\n }\n\n /** Aggregate raw per-record detail rows into per-entity summary rows */\n private aggregateRunDetails(rawRecords: RawRunDetailRecord[]): RunDetailRow[] {\n const entityMap = new Map<string, RunDetailRow>();\n\n for (const rec of rawRecords) {\n const key = rec.EntityID.toLowerCase();\n let row = entityMap.get(key);\n if (!row) {\n row = {\n EntityID: rec.EntityID,\n Entity: rec.Entity,\n RecordsProcessed: 0,\n RecordsCreated: 0,\n RecordsUpdated: 0,\n RecordsDeleted: 0,\n RecordsErrored: 0,\n RecordsSkipped: 0\n };\n entityMap.set(key, row);\n }\n\n row.RecordsProcessed++;\n\n if (!rec.IsSuccess) {\n row.RecordsErrored++;\n } else {\n const action = (rec.Action ?? '').toUpperCase();\n if (action === 'INSERT' || action === 'CREATE') {\n row.RecordsCreated++;\n } else if (action === 'UPDATE') {\n row.RecordsUpdated++;\n } else if (action === 'DELETE') {\n row.RecordsDeleted++;\n } else if (action === 'SKIP' || action === 'SKIPPED') {\n row.RecordsSkipped++;\n }\n }\n }\n\n return Array.from(entityMap.values()).sort((a, b) => a.Entity.localeCompare(b.Entity));\n }\n\n async LoadIntegrationDefinitions(_provider?: IRunViewProvider | null): Promise<MJIntegrationEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n return IntegrationEngineBase.Instance.Integrations;\n }\n\n async LoadSourceTypes(_provider?: IRunViewProvider | null): Promise<MJIntegrationSourceTypeEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n return IntegrationEngineBase.Instance.SourceTypes.filter(st => st.Status === 'Active');\n }\n\n async LoadRecentRuns(limit: number = 20, provider?: IRunViewProvider | null): Promise<ActivityFeedItem[]> {\n const rv = this.createRunView(provider);\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: '',\n OrderBy: 'StartedAt DESC',\n MaxRows: limit,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n return result.Results.map(run => this.buildActivityFeedItem(run));\n }\n\n async LoadDailyRecordCounts(days: number = 7, provider?: IRunViewProvider | null): Promise<DailyRecordCount[]> {\n const rv = this.createRunView(provider);\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n const cutoffStr = cutoffDate.toISOString().split('T')[0];\n\n const result = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `StartedAt >= '${cutoffStr}'`,\n OrderBy: 'StartedAt ASC',\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords',\n 'Status', 'ErrorLog', 'Integration', 'Company', 'RunByUser'],\n ResultType: 'simple'\n });\n\n return this.aggregateDailyCounts(result.Results, days);\n }\n\n ComputeKPIs(summaries: IntegrationSummary[]): IntegrationKPIs {\n const totalIntegrations = summaries.length;\n const activeSyncs = summaries.filter(\n s => s.LatestRun?.Status === 'In Progress' || s.LatestRun?.Status === 'Pending'\n ).length;\n const recordsSyncedToday = summaries.reduce((acc, s) => acc + s.TotalRecordsSyncedToday, 0);\n\n const totalRuns = summaries.reduce((acc, s) => acc + s.RecentRuns.length, 0);\n const totalErrors = summaries.reduce((acc, s) => acc + s.TotalErrors, 0);\n const errorRate = totalRuns > 0 ? (totalErrors / totalRuns) * 100 : 0;\n\n const durationsMs = summaries\n .filter(s => s.DurationMs != null)\n .map(s => s.DurationMs as number);\n const averageSyncDurationMs = durationsMs.length > 0\n ? durationsMs.reduce((a, b) => a + b, 0) / durationsMs.length\n : null;\n\n return {\n TotalIntegrations: totalIntegrations,\n ActiveSyncs: activeSyncs,\n RecordsSyncedToday: recordsSyncedToday,\n ErrorRate: Math.round(errorRate * 10) / 10,\n AverageSyncDurationMs: averageSyncDurationMs\n };\n }\n\n FormatDuration(ms: number | null): string {\n if (ms == null) return '--';\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return `${minutes}m ${seconds}s`;\n const hours = Math.floor(minutes / 60);\n const remainingMinutes = minutes % 60;\n return `${hours}h ${remainingMinutes}m`;\n }\n\n ComputeRelativeTime(dateStr: string | null): string {\n return this.computeRelativeTime(dateStr);\n }\n\n // --- Entity Map CRUD ---\n\n async CreateEntityMap(params: {\n CompanyIntegrationID: string;\n ExternalObjectName: string;\n ExternalObjectLabel?: string;\n EntityID: string;\n SyncDirection?: 'Pull' | 'Push' | 'Bidirectional';\n ConflictResolution?: 'SourceWins' | 'DestWins' | 'MostRecent' | 'Manual';\n Priority?: number;\n DeleteBehavior?: 'SoftDelete' | 'DoNothing' | 'HardDelete';\n }): Promise<MJCompanyIntegrationEntityMapEntity | null> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n em.NewRecord();\n em.CompanyIntegrationID = params.CompanyIntegrationID;\n em.ExternalObjectName = params.ExternalObjectName;\n if (params.ExternalObjectLabel) em.ExternalObjectLabel = params.ExternalObjectLabel;\n em.EntityID = params.EntityID;\n em.SyncDirection = params.SyncDirection ?? 'Pull';\n em.ConflictResolution = params.ConflictResolution ?? 'SourceWins';\n em.Priority = params.Priority ?? 0;\n em.DeleteBehavior = params.DeleteBehavior ?? 'SoftDelete';\n em.Status = 'Active';\n em.SyncEnabled = true;\n\n const saved = await em.Save();\n if (!saved) {\n console.error('[IntegrationDataService] Failed to create entity map:', em.LatestResult?.CompleteMessage);\n return null;\n }\n return em;\n }\n\n async DeleteEntityMap(entityMapID: string): Promise<boolean> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n await em.Load(entityMapID);\n return em.Delete();\n }\n\n async ToggleEntityMapEnabled(entityMapID: string, enabled: boolean): Promise<boolean> {\n const md = new Metadata();\n const em = await md.GetEntityObject<MJCompanyIntegrationEntityMapEntity>('MJ: Company Integration Entity Maps');\n await em.Load(entityMapID);\n em.SyncEnabled = enabled;\n return em.Save();\n }\n\n // --- Field Map CRUD ---\n\n async CreateFieldMap(params: {\n EntityMapID: string;\n SourceFieldName: string;\n SourceFieldLabel?: string;\n DestinationFieldName: string;\n DestinationFieldLabel?: string;\n IsKeyField?: boolean;\n IsRequired?: boolean;\n Direction?: 'SourceToDest' | 'DestToSource' | 'Both';\n TransformPipeline?: string | null;\n Priority?: number;\n }): Promise<MJCompanyIntegrationFieldMapEntity | null> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n fm.NewRecord();\n fm.EntityMapID = params.EntityMapID;\n fm.SourceFieldName = params.SourceFieldName;\n if (params.SourceFieldLabel) fm.SourceFieldLabel = params.SourceFieldLabel;\n fm.DestinationFieldName = params.DestinationFieldName;\n if (params.DestinationFieldLabel) fm.DestinationFieldLabel = params.DestinationFieldLabel;\n fm.IsKeyField = params.IsKeyField ?? false;\n fm.IsRequired = params.IsRequired ?? false;\n fm.Direction = params.Direction ?? 'SourceToDest';\n if (params.TransformPipeline !== undefined) fm.TransformPipeline = params.TransformPipeline;\n fm.Status = 'Active';\n fm.Priority = params.Priority ?? 0;\n\n const saved = await fm.Save();\n if (!saved) {\n console.error('[IntegrationDataService] Failed to create field map:', fm.LatestResult?.CompleteMessage);\n return null;\n }\n return fm;\n }\n\n async DeleteFieldMap(fieldMapID: string): Promise<boolean> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n await fm.Load(fieldMapID);\n return fm.Delete();\n }\n\n async UpdateFieldMap(fieldMapID: string, updates: {\n SourceFieldName?: string;\n DestinationFieldName?: string;\n IsKeyField?: boolean;\n IsRequired?: boolean;\n Direction?: 'SourceToDest' | 'DestToSource' | 'Both';\n Status?: 'Active' | 'Inactive';\n TransformPipeline?: string | null;\n }): Promise<boolean> {\n const md = new Metadata();\n const fm = await md.GetEntityObject<MJCompanyIntegrationFieldMapEntity>('MJ: Company Integration Field Maps');\n await fm.Load(fieldMapID);\n if (updates.SourceFieldName !== undefined) fm.SourceFieldName = updates.SourceFieldName;\n if (updates.DestinationFieldName !== undefined) fm.DestinationFieldName = updates.DestinationFieldName;\n if (updates.IsKeyField !== undefined) fm.IsKeyField = updates.IsKeyField;\n if (updates.IsRequired !== undefined) fm.IsRequired = updates.IsRequired;\n if (updates.Direction !== undefined) fm.Direction = updates.Direction;\n if (updates.Status !== undefined) fm.Status = updates.Status;\n if (updates.TransformPipeline !== undefined) fm.TransformPipeline = updates.TransformPipeline;\n return fm.Save();\n }\n\n /** Load available MJ entities for mapping target selection */\n async LoadMJEntities(_provider?: IRunViewProvider | null): Promise<Array<{ ID: string; Name: string }>> {\n const md = new Metadata();\n return md.Entities\n .map(e => ({ ID: e.ID, Name: e.Name }))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n }\n\n /** Load entity fields for a given entity (for field mapping destination picker) */\n async LoadEntityFields(entityID: string, _provider?: IRunViewProvider | null): Promise<Array<{ ID: string; Name: string; Type: string; IsRequired: boolean }>> {\n const md = new Metadata();\n const entity = md.Entities.find(e => UUIDsEqual(e.ID, entityID));\n if (!entity) return [];\n return entity.Fields\n .sort((a, b) => a.Sequence - b.Sequence)\n .map(f => ({ ID: f.ID, Name: f.Name, Type: f.Type, IsRequired: !f.AllowsNull }));\n }\n\n // --- Discovery (via GraphQL) ---\n\n /** Discover external objects available for a company integration */\n async DiscoverObjects(companyIntegrationID: string): Promise<DiscoveryResult<DiscoveredObjectResult[]>> {\n const client = this.getIntegrationClient();\n return client.DiscoverObjects(companyIntegrationID);\n }\n\n /** Discover fields on a specific external object */\n async DiscoverFields(companyIntegrationID: string, objectName: string): Promise<DiscoveryResult<DiscoveredFieldResult[]>> {\n const client = this.getIntegrationClient();\n return client.DiscoverFields(companyIntegrationID, objectName);\n }\n\n /** Generate DDL preview for creating tables from discovered objects */\n async SchemaPreview(\n companyIntegrationID: string,\n objects: SchemaPreviewObjectInput[],\n platform: string = 'sqlserver'\n ): Promise<SchemaPreviewResult> {\n const client = this.getIntegrationClient();\n return client.SchemaPreview(companyIntegrationID, objects, platform);\n }\n\n /** Get the connector's default configuration for quick setup */\n async GetDefaultConfig(companyIntegrationID: string): Promise<DefaultConfigResult> {\n const client = this.getIntegrationClient();\n return client.GetDefaultConfig(companyIntegrationID);\n }\n\n /** Test connection to the external system */\n async TestConnection(companyIntegrationID: string): Promise<ConnectionTestGraphQLResult> {\n const client = this.getIntegrationClient();\n return client.TestConnection(companyIntegrationID);\n }\n\n /** Preview source data from the external system via connector's FetchChanges */\n async PreviewSourceData(\n companyIntegrationID: string,\n objectName: string,\n limit: number = 5\n ): Promise<Array<Record<string, string | number | boolean | null>>> {\n const client = this.getIntegrationClient();\n const result = await client.PreviewData(companyIntegrationID, objectName, limit);\n if (!result.Success || !result.Records) {\n console.warn('[IntegrationDataService] PreviewSourceData failed:', result.Message);\n return [];\n }\n return result.Records.map(r => {\n try {\n return JSON.parse(r.Data) as Record<string, string | number | boolean | null>;\n } catch {\n return { _raw: r.Data } as Record<string, string | number | boolean | null>;\n }\n });\n }\n\n /** Preview destination data by loading a few records from the target entity */\n async PreviewDestinationData(\n entityID: string,\n limit: number = 5,\n provider?: IRunViewProvider | null\n ): Promise<Array<Record<string, string | number | boolean | null>>> {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => UUIDsEqual(e.ID, entityID));\n if (!entityInfo) return [];\n\n // Load first N fields (skip internal __mj fields) to keep preview compact\n const fields = entityInfo.Fields\n .filter(f => !f.Name.startsWith('__mj'))\n .slice(0, 8)\n .map(f => f.Name);\n\n const rv = this.createRunView(provider);\n const result = await rv.RunView<Record<string, string | number | boolean | null>>({\n EntityName: entityInfo.Name,\n ExtraFilter: '',\n OrderBy: `${fields[0]} ASC`,\n MaxRows: limit,\n Fields: fields,\n ResultType: 'simple'\n });\n return result.Results;\n }\n\n /** Get a count of records in the destination MJ entity */\n async GetDestinationRecordCount(\n entityID: string,\n provider?: IRunViewProvider | null\n ): Promise<number> {\n const md = new Metadata();\n const entityInfo = md.Entities.find(e => UUIDsEqual(e.ID, entityID));\n if (!entityInfo) return 0;\n\n const rv = this.createRunView(provider);\n const result = await rv.RunView<{ TotalCount: number }>({\n EntityName: entityInfo.Name,\n ExtraFilter: '',\n Fields: [entityInfo.FirstPrimaryKey?.Name ?? 'ID'],\n ResultType: 'simple'\n });\n return result.TotalRowCount ?? result.Results.length;\n }\n\n /** Get the most recent run that touched a given entity */\n async GetLastSyncForEntity(\n companyIntegrationID: string,\n entityID: string,\n provider?: IRunViewProvider | null\n ): Promise<{ StartedAt: string | null; EndedAt: string | null; Status: string; TotalRecords: number } | null> {\n const rv = this.createRunView(provider);\n // Get runs for this integration, most recent first\n const runsResult = await rv.RunView<IntegrationRunRow>({\n EntityName: 'MJ: Company Integration Runs',\n ExtraFilter: `CompanyIntegrationID='${companyIntegrationID}'`,\n OrderBy: 'StartedAt DESC',\n MaxRows: 5,\n Fields: ['ID', 'CompanyIntegrationID', 'StartedAt', 'EndedAt', 'TotalRecords', 'Status'],\n ResultType: 'simple'\n });\n if (runsResult.Results.length === 0) return null;\n\n // Check each run's details to find one that touched this entity\n for (const run of runsResult.Results) {\n const detailResult = await rv.RunView<{ EntityID: string }>({\n EntityName: 'MJ: Company Integration Run Details',\n ExtraFilter: `CompanyIntegrationRunID='${run.ID}' AND EntityID='${entityID}'`,\n MaxRows: 1,\n Fields: ['EntityID'],\n ResultType: 'simple'\n });\n if (detailResult.Results.length > 0) {\n return {\n StartedAt: run.StartedAt,\n EndedAt: run.EndedAt,\n Status: run.Status,\n TotalRecords: run.TotalRecords\n };\n }\n }\n // No run touched this entity — return the most recent run anyway as context\n const latest = runsResult.Results[0];\n return {\n StartedAt: latest.StartedAt,\n EndedAt: latest.EndedAt,\n Status: latest.Status,\n TotalRecords: latest.TotalRecords\n };\n }\n\n /** Run an integration sync via the \"Run Integration Sync\" action */\n async RunSync(companyIntegrationID: string): Promise<{ Success: boolean; Message: string }> {\n const actionID = await this.lookupActionID('Run Integration Sync');\n if (!actionID) {\n return {\n Success: false,\n Message: 'Action \"Run Integration Sync\" not found. Ensure the action is registered.'\n };\n }\n\n const provider = Metadata.Provider as GraphQLDataProvider;\n const actionClient = new GraphQLActionClient(provider);\n const result = await actionClient.RunAction(actionID, [\n { Name: 'CompanyIntegrationID', Value: companyIntegrationID, Type: 'Input' }\n ]);\n return { Success: result.Success, Message: result.Message ?? '' };\n }\n\n /** Load schedule data for all company integrations (includes new scheduling fields) */\n async LoadSchedules(_provider?: IRunViewProvider | null): Promise<MJCompanyIntegrationEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n return IntegrationEngineBase.Instance.CompanyIntegrations;\n }\n\n /** Load sync watermarks for a specific company integration's entity maps */\n async LoadWatermarks(companyIntegrationID: string, _provider?: IRunViewProvider | null): Promise<MJCompanyIntegrationSyncWatermarkEntity[]> {\n await IntegrationEngineBase.Instance.Config(false);\n const entityMaps = IntegrationEngineBase.Instance.GetEntityMapsForCompanyIntegration(companyIntegrationID);\n if (entityMaps.length === 0) return [];\n\n const mapIDSet = new Set(entityMaps.map(em => em.ID.toLowerCase()));\n return IntegrationEngineBase.Instance.Watermarks.filter(w => mapIDSet.has(w.EntityMapID.toLowerCase()));\n }\n\n /** Load entity map count per company integration (used by Overview cards) */\n async LoadEntityMapCounts(_provider?: IRunViewProvider | null): Promise<Map<string, number>> {\n await IntegrationEngineBase.Instance.Config(false);\n const counts = new Map<string, number>();\n for (const em of IntegrationEngineBase.Instance.EntityMaps) {\n if (em.SyncEnabled) {\n const key = em.CompanyIntegrationID.toLowerCase();\n counts.set(key, (counts.get(key) ?? 0) + 1);\n }\n }\n return counts;\n }\n\n private async lookupActionID(actionName: string): Promise<string | null> {\n const rv = new RunView();\n const result = await rv.RunView<{ ID: string }>({\n EntityName: 'MJ: Actions',\n ExtraFilter: `Name='${actionName}'`,\n Fields: ['ID'],\n MaxRows: 1,\n ResultType: 'simple'\n });\n return result.Results.length > 0 ? result.Results[0].ID : null;\n }\n\n private getIntegrationClient(): GraphQLIntegrationClient {\n const provider = Metadata.Provider as GraphQLDataProvider;\n return new GraphQLIntegrationClient(provider);\n }\n\n private createRunView(provider?: IRunViewProvider | null): RunView {\n return new RunView(provider ?? null);\n }\n\n private buildSummary(\n integration: MJCompanyIntegrationEntity,\n allRuns: IntegrationRunRow[],\n sourceTypes: MJIntegrationSourceTypeEntity[]\n ): IntegrationSummary {\n const integrationRuns = allRuns.filter(r => UUIDsEqual(r.CompanyIntegrationID, integration.ID));\n const latestRun = integrationRuns.length > 0 ? integrationRuns[0] : null;\n const recentRuns = integrationRuns.slice(0, 5);\n const statusColor = this.computeStatusColor(latestRun, integration.IsActive);\n const relativeTime = this.computeRelativeTime(latestRun?.StartedAt ?? null);\n const totalRecordsSyncedToday = this.computeRecordsSyncedToday(integrationRuns);\n const totalErrors = integrationRuns.filter(r => r.Status === 'Failed').length;\n const durationMs = this.computeDuration(latestRun);\n const sourceType = this.resolveSourceType(integration, sourceTypes);\n\n return {\n Integration: integration,\n SourceType: sourceType,\n LatestRun: latestRun,\n RecentRuns: recentRuns,\n StatusColor: statusColor,\n RelativeTime: relativeTime,\n TotalRecordsSyncedToday: totalRecordsSyncedToday,\n TotalErrors: totalErrors,\n DurationMs: durationMs\n };\n }\n\n private resolveSourceType(\n integration: MJCompanyIntegrationEntity,\n sourceTypes: MJIntegrationSourceTypeEntity[]\n ): MJIntegrationSourceTypeEntity | null {\n if (!integration.SourceTypeID) return null;\n return sourceTypes.find(st => UUIDsEqual(st.ID, integration.SourceTypeID)) ?? null;\n }\n\n private buildActivityFeedItem(run: IntegrationRunRow): ActivityFeedItem {\n return {\n RunID: run.ID,\n IntegrationName: run.Integration,\n Status: run.Status,\n StatusColor: this.runStatusColor(run),\n StartedAt: run.StartedAt,\n RelativeTime: this.computeRelativeTime(run.StartedAt),\n TotalRecords: run.TotalRecords,\n RunByUser: run.RunByUser\n };\n }\n\n private runStatusColor(run: IntegrationRunRow): 'amber' | 'green' | 'red' {\n if (run.Status === 'Failed') return 'red';\n if (run.Status === 'Success') return 'green';\n return 'amber';\n }\n\n private computeRecordsSyncedToday(runs: IntegrationRunRow[]): number {\n const todayStart = new Date();\n todayStart.setHours(0, 0, 0, 0);\n return runs\n .filter(r => r.StartedAt && new Date(r.StartedAt) >= todayStart)\n .reduce((acc, r) => acc + r.TotalRecords, 0);\n }\n\n private computeDuration(run: IntegrationRunRow | null): number | null {\n if (!run?.StartedAt || !run?.EndedAt) return null;\n return new Date(run.EndedAt).getTime() - new Date(run.StartedAt).getTime();\n }\n\n private aggregateDailyCounts(runs: IntegrationRunRow[], days: number): DailyRecordCount[] {\n const result: DailyRecordCount[] = [];\n const today = new Date();\n\n for (let i = days - 1; i >= 0; i--) {\n const date = new Date(today);\n date.setDate(date.getDate() - i);\n const dateStr = date.toISOString().split('T')[0];\n const label = date.toLocaleDateString(undefined, { weekday: 'short' });\n\n const dayRecords = runs\n .filter(r => r.StartedAt && r.StartedAt.startsWith(dateStr))\n .reduce((acc, r) => acc + r.TotalRecords, 0);\n\n result.push({ Date: dateStr, Label: label, Records: dayRecords });\n }\n return result;\n }\n\n private computeStatusColor(\n latestRun: IntegrationRunRow | null,\n isActive: boolean | null\n ): 'green' | 'amber' | 'red' | 'gray' {\n if (!isActive) return 'gray';\n if (!latestRun) return 'gray';\n if (latestRun.Status === 'Failed') return 'red';\n if (latestRun.Status === 'In Progress' || latestRun.Status === 'Pending') return 'amber';\n if (latestRun.Status === 'Success') {\n return this.isStale(latestRun.StartedAt) ? 'amber' : 'green';\n }\n return 'gray';\n }\n\n private isStale(startedAt: string | null): boolean {\n if (!startedAt) return true;\n const runDate = new Date(startedAt);\n const hoursAgo = (Date.now() - runDate.getTime()) / (1000 * 60 * 60);\n return hoursAgo > 24;\n }\n\n private computeRelativeTime(dateStr: string | null): string {\n if (!dateStr) return 'Never run';\n const date = new Date(dateStr);\n const diffMs = Date.now() - date.getTime();\n const diffMinutes = Math.floor(diffMs / (1000 * 60));\n\n if (diffMinutes < 1) return 'Just now';\n if (diffMinutes < 60) return `${diffMinutes}m ago`;\n const diffHours = Math.floor(diffMinutes / 60);\n if (diffHours < 24) return `${diffHours}h ago`;\n const diffDays = Math.floor(diffHours / 24);\n if (diffDays < 30) return `${diffDays}d ago`;\n return date.toLocaleDateString();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-data-service.test.js","sourceRoot":"","sources":["../../src/__tests__/integration-data-service.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for IntegrationDataService\n * Covers pure logic methods (KPI computation, formatting, status calculation)\n */\nimport { describe, it, expect } from 'vitest';\nimport { IntegrationDataService, IntegrationSummary, IntegrationRunRow } from '../Integration/services/integration-data.service';\n\nfunction createService(): IntegrationDataService {\n return new IntegrationDataService();\n}\n\nfunction createSummary(overrides: Partial<IntegrationSummary> = {}): IntegrationSummary {\n return {\n Integration: {\n ID: '1', Name: 'Test', IsActive: true, LastRunID: null,\n LastRunStartedAt: null, LastRunEndedAt: null, Company: 'TestCo',\n Integration: 'Test', DriverClassName: null\n },\n SourceType: null,\n LatestRun: null,\n RecentRuns: [],\n StatusColor: 'gray',\n RelativeTime: 'Never run',\n TotalRecordsSyncedToday: 0,\n TotalErrors: 0,\n DurationMs: null,\n ...overrides\n };\n}\n\nfunction createRun(overrides: Partial<IntegrationRunRow> = {}): IntegrationRunRow {\n return {\n ID: '1', CompanyIntegrationID: '1', StartedAt: null, EndedAt: null,\n TotalRecords: 0, Status: 'Success', ErrorLog: null,\n Integration: 'Test', Company: 'TestCo', RunByUser: 'Admin',\n ...overrides\n };\n}\n\ndescribe('IntegrationDataService', () => {\n describe('ComputeKPIs', () => {\n it('should return zeros for empty summaries', () => {\n const svc = createService();\n const kpis = svc.ComputeKPIs([]);\n expect(kpis.TotalIntegrations).toBe(0);\n expect(kpis.ActiveSyncs).toBe(0);\n expect(kpis.RecordsSyncedToday).toBe(0);\n expect(kpis.ErrorRate).toBe(0);\n expect(kpis.AverageSyncDurationMs).toBeNull();\n });\n\n it('should count total integrations', () => {\n const svc = createService();\n const summaries = [createSummary(), createSummary(), createSummary()];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.TotalIntegrations).toBe(3);\n });\n\n it('should count active syncs (In Progress and Pending)', () => {\n const svc = createService();\n const summaries = [\n createSummary({ LatestRun: createRun({ Status: 'In Progress' }) }),\n createSummary({ LatestRun: createRun({ Status: 'Pending' }) }),\n createSummary({ LatestRun: createRun({ Status: 'Success' }) }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.ActiveSyncs).toBe(2);\n });\n\n it('should sum records synced today', () => {\n const svc = createService();\n const summaries = [\n createSummary({ TotalRecordsSyncedToday: 100 }),\n createSummary({ TotalRecordsSyncedToday: 250 }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.RecordsSyncedToday).toBe(350);\n });\n\n it('should compute error rate from recent runs', () => {\n const svc = createService();\n const runs = [createRun(), createRun(), createRun(), createRun()];\n const summaries = [\n createSummary({ RecentRuns: runs, TotalErrors: 1 }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.ErrorRate).toBe(25);\n });\n\n it('should compute average sync duration', () => {\n const svc = createService();\n const summaries = [\n createSummary({ DurationMs: 1000 }),\n createSummary({ DurationMs: 3000 }),\n createSummary({ DurationMs: null }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.AverageSyncDurationMs).toBe(2000);\n });\n });\n\n describe('FormatDuration', () => {\n it('should return -- for null', () => {\n expect(createService().FormatDuration(null)).toBe('--');\n });\n\n it('should format seconds', () => {\n expect(createService().FormatDuration(45000)).toBe('45s');\n });\n\n it('should format minutes and seconds', () => {\n expect(createService().FormatDuration(125000)).toBe('2m 5s');\n });\n\n it('should format hours and minutes', () => {\n expect(createService().FormatDuration(3720000)).toBe('1h 2m');\n });\n\n it('should format zero seconds', () => {\n expect(createService().FormatDuration(0)).toBe('0s');\n });\n });\n\n describe('ComputeRelativeTime', () => {\n it('should return \"Never run\" for null', () => {\n expect(createService().ComputeRelativeTime(null)).toBe('Never run');\n });\n\n it('should return \"Just now\" for recent dates', () => {\n const now = new Date().toISOString();\n expect(createService().ComputeRelativeTime(now)).toBe('Just now');\n });\n\n it('should return minutes for recent past', () => {\n const fiveMinAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(fiveMinAgo)).toBe('5m ago');\n });\n\n it('should return hours for hours ago', () => {\n const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(threeHoursAgo)).toBe('3h ago');\n });\n\n it('should return days for days ago', () => {\n const twoDaysAgo = new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(twoDaysAgo)).toBe('2d ago');\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"integration-data-service.test.js","sourceRoot":"","sources":["../../src/__tests__/integration-data-service.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Tests for IntegrationDataService\n * Covers pure logic methods (KPI computation, formatting, status calculation)\n */\nimport { describe, it, expect } from 'vitest';\nimport { IntegrationDataService, IntegrationSummary, IntegrationRunRow } from '../Integration/services/integration-data.service';\nimport { MJCompanyIntegrationEntity } from '@memberjunction/core-entities';\n\nfunction createService(): IntegrationDataService {\n return new IntegrationDataService();\n}\n\nfunction createSummary(overrides: Partial<IntegrationSummary> = {}): IntegrationSummary {\n return {\n Integration: {\n ID: '1', Name: 'Test', IsActive: true, LastRunID: null,\n LastRunStartedAt: null, LastRunEndedAt: null, Company: 'TestCo',\n Integration: 'Test', DriverClassName: null\n } as unknown as MJCompanyIntegrationEntity,\n SourceType: null,\n LatestRun: null,\n RecentRuns: [],\n StatusColor: 'gray',\n RelativeTime: 'Never run',\n TotalRecordsSyncedToday: 0,\n TotalErrors: 0,\n DurationMs: null,\n ...overrides\n };\n}\n\nfunction createRun(overrides: Partial<IntegrationRunRow> = {}): IntegrationRunRow {\n return {\n ID: '1', CompanyIntegrationID: '1', StartedAt: null, EndedAt: null,\n TotalRecords: 0, Status: 'Success', ErrorLog: null,\n Integration: 'Test', Company: 'TestCo', RunByUser: 'Admin',\n ...overrides\n };\n}\n\ndescribe('IntegrationDataService', () => {\n describe('ComputeKPIs', () => {\n it('should return zeros for empty summaries', () => {\n const svc = createService();\n const kpis = svc.ComputeKPIs([]);\n expect(kpis.TotalIntegrations).toBe(0);\n expect(kpis.ActiveSyncs).toBe(0);\n expect(kpis.RecordsSyncedToday).toBe(0);\n expect(kpis.ErrorRate).toBe(0);\n expect(kpis.AverageSyncDurationMs).toBeNull();\n });\n\n it('should count total integrations', () => {\n const svc = createService();\n const summaries = [createSummary(), createSummary(), createSummary()];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.TotalIntegrations).toBe(3);\n });\n\n it('should count active syncs (In Progress and Pending)', () => {\n const svc = createService();\n const summaries = [\n createSummary({ LatestRun: createRun({ Status: 'In Progress' }) }),\n createSummary({ LatestRun: createRun({ Status: 'Pending' }) }),\n createSummary({ LatestRun: createRun({ Status: 'Success' }) }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.ActiveSyncs).toBe(2);\n });\n\n it('should sum records synced today', () => {\n const svc = createService();\n const summaries = [\n createSummary({ TotalRecordsSyncedToday: 100 }),\n createSummary({ TotalRecordsSyncedToday: 250 }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.RecordsSyncedToday).toBe(350);\n });\n\n it('should compute error rate from recent runs', () => {\n const svc = createService();\n const runs = [createRun(), createRun(), createRun(), createRun()];\n const summaries = [\n createSummary({ RecentRuns: runs, TotalErrors: 1 }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.ErrorRate).toBe(25);\n });\n\n it('should compute average sync duration', () => {\n const svc = createService();\n const summaries = [\n createSummary({ DurationMs: 1000 }),\n createSummary({ DurationMs: 3000 }),\n createSummary({ DurationMs: null }),\n ];\n const kpis = svc.ComputeKPIs(summaries);\n expect(kpis.AverageSyncDurationMs).toBe(2000);\n });\n });\n\n describe('FormatDuration', () => {\n it('should return -- for null', () => {\n expect(createService().FormatDuration(null)).toBe('--');\n });\n\n it('should format seconds', () => {\n expect(createService().FormatDuration(45000)).toBe('45s');\n });\n\n it('should format minutes and seconds', () => {\n expect(createService().FormatDuration(125000)).toBe('2m 5s');\n });\n\n it('should format hours and minutes', () => {\n expect(createService().FormatDuration(3720000)).toBe('1h 2m');\n });\n\n it('should format zero seconds', () => {\n expect(createService().FormatDuration(0)).toBe('0s');\n });\n });\n\n describe('ComputeRelativeTime', () => {\n it('should return \"Never run\" for null', () => {\n expect(createService().ComputeRelativeTime(null)).toBe('Never run');\n });\n\n it('should return \"Just now\" for recent dates', () => {\n const now = new Date().toISOString();\n expect(createService().ComputeRelativeTime(now)).toBe('Just now');\n });\n\n it('should return minutes for recent past', () => {\n const fiveMinAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(fiveMinAgo)).toBe('5m ago');\n });\n\n it('should return hours for hours ago', () => {\n const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(threeHoursAgo)).toBe('3h ago');\n });\n\n it('should return days for days ago', () => {\n const twoDaysAgo = new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString();\n expect(createService().ComputeRelativeTime(twoDaysAgo)).toBe('2d ago');\n });\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-dashboards",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.10.1",
|
|
4
4
|
"description": "MemberJunction Dashboards",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -34,45 +34,45 @@
|
|
|
34
34
|
"@codemirror/merge": "^6.11.2",
|
|
35
35
|
"@codemirror/state": "^6.5.4",
|
|
36
36
|
"@codemirror/view": "^6.39.12",
|
|
37
|
-
"@memberjunction/actions-base": "5.
|
|
38
|
-
"@memberjunction/ai-engine-base": "5.
|
|
39
|
-
"@memberjunction/api-keys-base": "5.
|
|
40
|
-
"@memberjunction/ai-core-plus": "5.
|
|
41
|
-
"@memberjunction/core": "5.
|
|
42
|
-
"@memberjunction/export-engine": "5.
|
|
43
|
-
"@memberjunction/ng-entity-relationship-diagram": "5.
|
|
44
|
-
"@memberjunction/core-entities": "5.
|
|
45
|
-
"@memberjunction/global": "5.
|
|
46
|
-
"@memberjunction/graphql-dataprovider": "5.
|
|
47
|
-
"@memberjunction/integration-engine-base": "5.
|
|
48
|
-
"@memberjunction/interactive-component-types": "5.
|
|
49
|
-
"@memberjunction/ng-action-gallery": "5.
|
|
50
|
-
"@memberjunction/ng-actions": "5.
|
|
51
|
-
"@memberjunction/ng-agents": "5.
|
|
52
|
-
"@memberjunction/ng-ai-test-harness": "5.
|
|
53
|
-
"@memberjunction/ng-base-application": "5.
|
|
54
|
-
"@memberjunction/ng-code-editor": "5.
|
|
55
|
-
"@memberjunction/ng-container-directives": "5.
|
|
56
|
-
"@memberjunction/ng-core-entity-forms": "5.
|
|
57
|
-
"@memberjunction/ng-credentials": "5.
|
|
58
|
-
"@memberjunction/ng-dashboard-viewer": "5.
|
|
59
|
-
"@memberjunction/ng-entity-viewer": "5.
|
|
60
|
-
"@memberjunction/ng-export-service": "5.
|
|
61
|
-
"@memberjunction/ng-filter-builder": "5.
|
|
62
|
-
"@memberjunction/ng-list-management": "5.
|
|
63
|
-
"@memberjunction/ng-explorer-settings": "5.
|
|
64
|
-
"@memberjunction/ng-notifications": "5.
|
|
65
|
-
"@memberjunction/ng-query-viewer": "5.
|
|
66
|
-
"@memberjunction/ng-react": "5.
|
|
67
|
-
"@memberjunction/ng-shared": "5.
|
|
68
|
-
"@memberjunction/ng-shared-generic": "5.
|
|
69
|
-
"@memberjunction/ng-trees": "5.
|
|
70
|
-
"@memberjunction/ng-versions": "5.
|
|
71
|
-
"@memberjunction/ng-testing": "5.
|
|
72
|
-
"@memberjunction/skip-types": "5.
|
|
73
|
-
"@memberjunction/templates-base-types": "5.
|
|
74
|
-
"@memberjunction/testing-engine-base": "5.
|
|
75
|
-
"@memberjunction/ng-markdown": "5.
|
|
37
|
+
"@memberjunction/actions-base": "5.10.1",
|
|
38
|
+
"@memberjunction/ai-engine-base": "5.10.1",
|
|
39
|
+
"@memberjunction/api-keys-base": "5.10.1",
|
|
40
|
+
"@memberjunction/ai-core-plus": "5.10.1",
|
|
41
|
+
"@memberjunction/core": "5.10.1",
|
|
42
|
+
"@memberjunction/export-engine": "5.10.1",
|
|
43
|
+
"@memberjunction/ng-entity-relationship-diagram": "5.10.1",
|
|
44
|
+
"@memberjunction/core-entities": "5.10.1",
|
|
45
|
+
"@memberjunction/global": "5.10.1",
|
|
46
|
+
"@memberjunction/graphql-dataprovider": "5.10.1",
|
|
47
|
+
"@memberjunction/integration-engine-base": "5.10.1",
|
|
48
|
+
"@memberjunction/interactive-component-types": "5.10.1",
|
|
49
|
+
"@memberjunction/ng-action-gallery": "5.10.1",
|
|
50
|
+
"@memberjunction/ng-actions": "5.10.1",
|
|
51
|
+
"@memberjunction/ng-agents": "5.10.1",
|
|
52
|
+
"@memberjunction/ng-ai-test-harness": "5.10.1",
|
|
53
|
+
"@memberjunction/ng-base-application": "5.10.1",
|
|
54
|
+
"@memberjunction/ng-code-editor": "5.10.1",
|
|
55
|
+
"@memberjunction/ng-container-directives": "5.10.1",
|
|
56
|
+
"@memberjunction/ng-core-entity-forms": "5.10.1",
|
|
57
|
+
"@memberjunction/ng-credentials": "5.10.1",
|
|
58
|
+
"@memberjunction/ng-dashboard-viewer": "5.10.1",
|
|
59
|
+
"@memberjunction/ng-entity-viewer": "5.10.1",
|
|
60
|
+
"@memberjunction/ng-export-service": "5.10.1",
|
|
61
|
+
"@memberjunction/ng-filter-builder": "5.10.1",
|
|
62
|
+
"@memberjunction/ng-list-management": "5.10.1",
|
|
63
|
+
"@memberjunction/ng-explorer-settings": "5.10.1",
|
|
64
|
+
"@memberjunction/ng-notifications": "5.10.1",
|
|
65
|
+
"@memberjunction/ng-query-viewer": "5.10.1",
|
|
66
|
+
"@memberjunction/ng-react": "5.10.1",
|
|
67
|
+
"@memberjunction/ng-shared": "5.10.1",
|
|
68
|
+
"@memberjunction/ng-shared-generic": "5.10.1",
|
|
69
|
+
"@memberjunction/ng-trees": "5.10.1",
|
|
70
|
+
"@memberjunction/ng-versions": "5.10.1",
|
|
71
|
+
"@memberjunction/ng-testing": "5.10.1",
|
|
72
|
+
"@memberjunction/skip-types": "5.10.1",
|
|
73
|
+
"@memberjunction/templates-base-types": "5.10.1",
|
|
74
|
+
"@memberjunction/testing-engine-base": "5.10.1",
|
|
75
|
+
"@memberjunction/ng-markdown": "5.10.1",
|
|
76
76
|
"@progress/kendo-angular-buttons": "22.0.1",
|
|
77
77
|
"@progress/kendo-angular-dateinputs": "22.0.1",
|
|
78
78
|
"@progress/kendo-angular-dialog": "22.0.1",
|