@memberjunction/ng-dashboards 5.33.0 → 5.34.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/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/agents/agent-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js.map +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts +28 -8
- package/dist/ComponentStudio/services/component-studio-state.service.d.ts.map +1 -1
- package/dist/ComponentStudio/services/component-studio-state.service.js +45 -27
- package/dist/ComponentStudio/services/component-studio-state.service.js.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts +18 -3
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.d.ts.map +1 -1
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +51 -11
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts +134 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.d.ts.map +1 -1
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js +1227 -24
- package/dist/KnowledgeHub/components/config/knowledge-config-resource.component.js.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts +4 -0
- package/dist/SystemDiagnostics/system-diagnostics.component.d.ts.map +1 -1
- package/dist/SystemDiagnostics/system-diagnostics.component.js +106 -68
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +3 -3
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/package.json +52 -52
|
@@ -171,7 +171,7 @@ export class IntegrationCardComponent {
|
|
|
171
171
|
i0.ɵɵproperty("disabled", !ctx.Summary.Integration.IsActive);
|
|
172
172
|
i0.ɵɵadvance(4);
|
|
173
173
|
i0.ɵɵclassProp("fa-chevron-down", !ctx.Expanded)("fa-chevron-up", ctx.Expanded);
|
|
174
|
-
} }, dependencies: [i1.MJButtonDirective, i2.DecimalPipe], styles: [".integration-card[_ngcontent-%COMP%] {\n background: var(--
|
|
174
|
+
} }, dependencies: [i1.MJButtonDirective, i2.DecimalPipe], styles: [".integration-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n transition: box-shadow 0.2s;\n }\n .integration-card[_ngcontent-%COMP%]:hover { box-shadow: var(--mj-shadow-md); }\n .integration-card.inactive[_ngcontent-%COMP%] { opacity: 0.6; }\n\n .card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n .source-icon[_ngcontent-%COMP%] {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; color: var(--mj-brand-primary);\n }\n .card-title-area[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n .card-title[_ngcontent-%COMP%] {\n margin: 0; font-size: 14px; font-weight: 600;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .source-type-label[_ngcontent-%COMP%] { font-size: 12px; color: var(--mj-text-muted); }\n\n .status-area[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n .indicator-green[_ngcontent-%COMP%] { background: var(--mj-status-success); }\n .indicator-amber[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n .indicator-red[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n .indicator-gray[_ngcontent-%COMP%] { background: var(--mj-text-disabled); }\n\n .status-indicator.pulsing[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_pulse 1.5s ease-in-out infinite;\n }\n @keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.3); }\n }\n\n .status-chip[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 12px; text-transform: uppercase; white-space: nowrap;\n }\n .status-green[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .status-amber[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .status-red[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .status-gray[_ngcontent-%COMP%] { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n .card-body[_ngcontent-%COMP%] { margin-bottom: 12px; }\n .stat-row[_ngcontent-%COMP%] {\n display: flex; justify-content: space-between;\n padding: 4px 0; font-size: 13px;\n }\n .stat-label[_ngcontent-%COMP%] { color: var(--mj-text-secondary); }\n .stat-value[_ngcontent-%COMP%] { font-weight: 500; }\n .error-value[_ngcontent-%COMP%] { color: var(--mj-status-error-text); }\n .error-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 700;\n }\n\n \n\n .sparkline-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid var(--mj-border-subtle);\n margin-bottom: 4px;\n }\n .sparkline-label[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n }\n .sparkline[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-end;\n gap: 3px;\n height: 24px;\n flex: 1;\n }\n .spark-bar[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 2px;\n border-radius: 2px 2px 0 0;\n transition: height 0.3s ease;\n }\n .spark-success[_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n .spark-failed[_ngcontent-%COMP%] { background: var(--mj-status-error); }\n .spark-pending[_ngcontent-%COMP%] { background: var(--mj-status-warning); }\n\n .card-footer[_ngcontent-%COMP%] {\n display: flex; justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle); padding-top: 8px;\n }"] });
|
|
175
175
|
}
|
|
176
176
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(IntegrationCardComponent, [{
|
|
177
177
|
type: Component,
|
|
@@ -248,7 +248,7 @@ export class IntegrationCardComponent {
|
|
|
248
248
|
</button>
|
|
249
249
|
</div>
|
|
250
250
|
</div>
|
|
251
|
-
`, styles: ["\n .integration-card {\n background: var(--
|
|
251
|
+
`, styles: ["\n .integration-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n transition: box-shadow 0.2s;\n }\n .integration-card:hover { box-shadow: var(--mj-shadow-md); }\n .integration-card.inactive { opacity: 0.6; }\n\n .card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n .source-icon {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; color: var(--mj-brand-primary);\n }\n .card-title-area { flex: 1; min-width: 0; }\n .card-title {\n margin: 0; font-size: 14px; font-weight: 600;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .source-type-label { font-size: 12px; color: var(--mj-text-muted); }\n\n .status-area {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .status-indicator {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n .indicator-green { background: var(--mj-status-success); }\n .indicator-amber { background: var(--mj-status-warning); }\n .indicator-red { background: var(--mj-status-error); }\n .indicator-gray { background: var(--mj-text-disabled); }\n\n .status-indicator.pulsing {\n animation: pulse 1.5s ease-in-out infinite;\n }\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.3); }\n }\n\n .status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 12px; text-transform: uppercase; white-space: nowrap;\n }\n .status-green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .status-amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .status-red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .status-gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n .card-body { margin-bottom: 12px; }\n .stat-row {\n display: flex; justify-content: space-between;\n padding: 4px 0; font-size: 13px;\n }\n .stat-label { color: var(--mj-text-secondary); }\n .stat-value { font-weight: 500; }\n .error-value { color: var(--mj-status-error-text); }\n .error-badge {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 700;\n }\n\n /* Sparkline */\n .sparkline-row {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid var(--mj-border-subtle);\n margin-bottom: 4px;\n }\n .sparkline-label {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n }\n .sparkline {\n display: flex;\n align-items: flex-end;\n gap: 3px;\n height: 24px;\n flex: 1;\n }\n .spark-bar {\n flex: 1;\n min-height: 2px;\n border-radius: 2px 2px 0 0;\n transition: height 0.3s ease;\n }\n .spark-success { background: var(--mj-brand-primary); }\n .spark-failed { background: var(--mj-status-error); }\n .spark-pending { background: var(--mj-status-warning); }\n\n .card-footer {\n display: flex; justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle); padding-top: 8px;\n }\n "] }]
|
|
252
252
|
}], null, { Summary: [{
|
|
253
253
|
type: Input
|
|
254
254
|
}], Expanded: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-card.component.js","sourceRoot":"","sources":["../../../../src/Integration/components/widgets/integration-card.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { IRunViewProvider } from '@memberjunction/core';\nimport { IntegrationSummary, ResolveIntegrationIcon } from '../../services/integration-data.service';\n\n@Component({\n standalone: false,\n selector: 'app-integration-card',\n template: `\n <div class=\"integration-card\" [class.inactive]=\"!Summary.Integration.IsActive\">\n <div class=\"card-header\">\n <div class=\"source-icon\">\n <i [class]=\"SourceIconClass\"></i>\n </div>\n <div class=\"card-title-area\">\n <h3 class=\"card-title\">{{ Summary.Integration.Name }}</h3>\n <span class=\"source-type-label\">{{ Summary.SourceType?.Name ?? 'Unknown' }}</span>\n </div>\n <div class=\"status-area\">\n <span class=\"status-indicator\" [class]=\"'indicator-' + Summary.StatusColor\"\n [class.pulsing]=\"IsActivelySyncing\"></span>\n <span class=\"status-chip\" [class]=\"'status-' + Summary.StatusColor\">\n {{ StatusLabel }}\n </span>\n </div>\n </div>\n\n <div class=\"card-body\">\n <div class=\"stat-row\">\n <span class=\"stat-label\">Last Run</span>\n <span class=\"stat-value\">{{ Summary.RelativeTime }}</span>\n </div>\n @if (Summary.LatestRun) {\n <div class=\"stat-row\">\n <span class=\"stat-label\">Records Synced</span>\n <span class=\"stat-value\">{{ Summary.LatestRun.TotalRecords | number }}</span>\n </div>\n <div class=\"stat-row\">\n <span class=\"stat-label\">Duration</span>\n <span class=\"stat-value\">{{ FormattedDuration }}</span>\n </div>\n }\n @if (Summary.TotalErrors > 0) {\n <div class=\"stat-row\">\n <span class=\"stat-label\">Errors</span>\n <span class=\"stat-value error-value\">\n <span class=\"error-badge\">{{ Summary.TotalErrors }}</span>\n </span>\n </div>\n }\n </div>\n\n <!-- Sparkline: records synced for last 5 runs -->\n @if (Summary.RecentRuns.length > 1) {\n <div class=\"sparkline-row\">\n <span class=\"sparkline-label\">Recent syncs</span>\n <div class=\"sparkline\">\n @for (run of Summary.RecentRuns; track run.ID) {\n <div class=\"spark-bar\"\n [style.height.%]=\"SparkBarHeight(run.TotalRecords)\"\n [class.spark-success]=\"run.Status === 'Success'\"\n [class.spark-failed]=\"run.Status === 'Failed'\"\n [class.spark-pending]=\"run.Status !== 'Success' && run.Status !== 'Failed'\"\n [title]=\"run.TotalRecords + ' records - ' + run.Status\">\n </div>\n }\n </div>\n </div>\n }\n\n <div class=\"card-footer\">\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"OnRunNowClick()\" [disabled]=\"!Summary.Integration.IsActive\">\n <i class=\"fa-solid fa-play\"></i> Run Now\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnExpandToggle()\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!Expanded\" [class.fa-chevron-up]=\"Expanded\"></i>\n History\n </button>\n </div>\n </div>\n `,\n styles: [`\n .integration-card {\n background: var(--card-bg, #fff);\n border: 1px solid var(--border-color, #e0e0e0);\n border-radius: 8px;\n padding: 16px;\n transition: box-shadow 0.2s;\n }\n .integration-card:hover { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }\n .integration-card.inactive { opacity: 0.6; }\n\n .card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n .source-icon {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: var(--icon-bg, #f0f4ff);\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; color: var(--primary-color, #4a6cf7);\n }\n .card-title-area { flex: 1; min-width: 0; }\n .card-title {\n margin: 0; font-size: 14px; font-weight: 600;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .source-type-label { font-size: 12px; color: #888; }\n\n .status-area {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .status-indicator {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n .indicator-green { background: #1b7a3d; }\n .indicator-amber { background: #b5850a; }\n .indicator-red { background: #c62828; }\n .indicator-gray { background: #999; }\n\n .status-indicator.pulsing {\n animation: pulse 1.5s ease-in-out infinite;\n }\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.3); }\n }\n\n .status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 12px; text-transform: uppercase; white-space: nowrap;\n }\n .status-green { background: #e6f9ed; color: #1b7a3d; }\n .status-amber { background: #fff7e0; color: #b5850a; }\n .status-red { background: #fde8e8; color: #c62828; }\n .status-gray { background: #f0f0f0; color: #757575; }\n\n .card-body { margin-bottom: 12px; }\n .stat-row {\n display: flex; justify-content: space-between;\n padding: 4px 0; font-size: 13px;\n }\n .stat-label { color: #666; }\n .stat-value { font-weight: 500; }\n .error-value { color: #c62828; }\n .error-badge {\n background: #fde8e8;\n color: #c62828;\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 700;\n }\n\n /* Sparkline */\n .sparkline-row {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid #f0f0f0;\n margin-bottom: 4px;\n }\n .sparkline-label {\n font-size: 11px;\n color: #999;\n white-space: nowrap;\n }\n .sparkline {\n display: flex;\n align-items: flex-end;\n gap: 3px;\n height: 24px;\n flex: 1;\n }\n .spark-bar {\n flex: 1;\n min-height: 2px;\n border-radius: 2px 2px 0 0;\n transition: height 0.3s ease;\n }\n .spark-success { background: #4a6cf7; }\n .spark-failed { background: #c62828; }\n .spark-pending { background: #b5850a; }\n\n .card-footer {\n display: flex; justify-content: space-between;\n border-top: 1px solid #eee; padding-top: 8px;\n }\n `]\n})\nexport class IntegrationCardComponent {\n @Input() Summary!: IntegrationSummary;\n @Input() Expanded: boolean = false;\n @Input() ViewProvider: IRunViewProvider | null = null;\n @Output() RunNowClick = new EventEmitter<string>();\n @Output() ExpandToggle = new EventEmitter<string>();\n\n get SourceIconClass(): string {\n if (this.Summary.SourceType?.IconClass) {\n return this.Summary.SourceType.IconClass;\n }\n return ResolveIntegrationIcon(\n this.Summary.Integration.Integration ?? this.Summary.Integration.Name,\n this.Summary.Icon\n );\n }\n\n get StatusLabel(): string {\n const color = this.Summary.StatusColor;\n if (color === 'green') return 'Healthy';\n if (color === 'amber') return 'Warning';\n if (color === 'red') return 'Failed';\n return 'Inactive';\n }\n\n get IsActivelySyncing(): boolean {\n return this.Summary.LatestRun?.Status === 'In Progress'\n || this.Summary.LatestRun?.Status === 'Pending';\n }\n\n get FormattedDuration(): string {\n const ms = this.Summary.DurationMs;\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 return `${minutes}m ${seconds}s`;\n }\n\n get MaxSparkRecords(): number {\n const maxVal = Math.max(...this.Summary.RecentRuns.map(r => r.TotalRecords));\n return maxVal > 0 ? maxVal : 1;\n }\n\n SparkBarHeight(records: number): number {\n return Math.max((records / this.MaxSparkRecords) * 100, 8);\n }\n\n OnRunNowClick(): void {\n this.RunNowClick.emit(this.Summary.Integration.ID);\n }\n\n OnExpandToggle(): void {\n this.ExpandToggle.emit(this.Summary.Integration.ID);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"integration-card.component.js","sourceRoot":"","sources":["../../../../src/Integration/components/widgets/integration-card.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter } from '@angular/core';\nimport { IRunViewProvider } from '@memberjunction/core';\nimport { IntegrationSummary, ResolveIntegrationIcon } from '../../services/integration-data.service';\n\n@Component({\n standalone: false,\n selector: 'app-integration-card',\n template: `\n <div class=\"integration-card\" [class.inactive]=\"!Summary.Integration.IsActive\">\n <div class=\"card-header\">\n <div class=\"source-icon\">\n <i [class]=\"SourceIconClass\"></i>\n </div>\n <div class=\"card-title-area\">\n <h3 class=\"card-title\">{{ Summary.Integration.Name }}</h3>\n <span class=\"source-type-label\">{{ Summary.SourceType?.Name ?? 'Unknown' }}</span>\n </div>\n <div class=\"status-area\">\n <span class=\"status-indicator\" [class]=\"'indicator-' + Summary.StatusColor\"\n [class.pulsing]=\"IsActivelySyncing\"></span>\n <span class=\"status-chip\" [class]=\"'status-' + Summary.StatusColor\">\n {{ StatusLabel }}\n </span>\n </div>\n </div>\n\n <div class=\"card-body\">\n <div class=\"stat-row\">\n <span class=\"stat-label\">Last Run</span>\n <span class=\"stat-value\">{{ Summary.RelativeTime }}</span>\n </div>\n @if (Summary.LatestRun) {\n <div class=\"stat-row\">\n <span class=\"stat-label\">Records Synced</span>\n <span class=\"stat-value\">{{ Summary.LatestRun.TotalRecords | number }}</span>\n </div>\n <div class=\"stat-row\">\n <span class=\"stat-label\">Duration</span>\n <span class=\"stat-value\">{{ FormattedDuration }}</span>\n </div>\n }\n @if (Summary.TotalErrors > 0) {\n <div class=\"stat-row\">\n <span class=\"stat-label\">Errors</span>\n <span class=\"stat-value error-value\">\n <span class=\"error-badge\">{{ Summary.TotalErrors }}</span>\n </span>\n </div>\n }\n </div>\n\n <!-- Sparkline: records synced for last 5 runs -->\n @if (Summary.RecentRuns.length > 1) {\n <div class=\"sparkline-row\">\n <span class=\"sparkline-label\">Recent syncs</span>\n <div class=\"sparkline\">\n @for (run of Summary.RecentRuns; track run.ID) {\n <div class=\"spark-bar\"\n [style.height.%]=\"SparkBarHeight(run.TotalRecords)\"\n [class.spark-success]=\"run.Status === 'Success'\"\n [class.spark-failed]=\"run.Status === 'Failed'\"\n [class.spark-pending]=\"run.Status !== 'Success' && run.Status !== 'Failed'\"\n [title]=\"run.TotalRecords + ' records - ' + run.Status\">\n </div>\n }\n </div>\n </div>\n }\n\n <div class=\"card-footer\">\n <button mjButton variant=\"primary\" size=\"sm\"\n (click)=\"OnRunNowClick()\" [disabled]=\"!Summary.Integration.IsActive\">\n <i class=\"fa-solid fa-play\"></i> Run Now\n </button>\n <button mjButton variant=\"flat\" size=\"sm\" (click)=\"OnExpandToggle()\">\n <i class=\"fa-solid\" [class.fa-chevron-down]=\"!Expanded\" [class.fa-chevron-up]=\"Expanded\"></i>\n History\n </button>\n </div>\n </div>\n `,\n styles: [`\n .integration-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n padding: 16px;\n transition: box-shadow 0.2s;\n }\n .integration-card:hover { box-shadow: var(--mj-shadow-md); }\n .integration-card.inactive { opacity: 0.6; }\n\n .card-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 12px;\n }\n .source-icon {\n width: 40px; height: 40px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n display: flex; align-items: center; justify-content: center;\n font-size: 18px; color: var(--mj-brand-primary);\n }\n .card-title-area { flex: 1; min-width: 0; }\n .card-title {\n margin: 0; font-size: 14px; font-weight: 600;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n .source-type-label { font-size: 12px; color: var(--mj-text-muted); }\n\n .status-area {\n display: flex;\n align-items: center;\n gap: 6px;\n flex-shrink: 0;\n }\n\n .status-indicator {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n display: inline-block;\n }\n .indicator-green { background: var(--mj-status-success); }\n .indicator-amber { background: var(--mj-status-warning); }\n .indicator-red { background: var(--mj-status-error); }\n .indicator-gray { background: var(--mj-text-disabled); }\n\n .status-indicator.pulsing {\n animation: pulse 1.5s ease-in-out infinite;\n }\n @keyframes pulse {\n 0%, 100% { opacity: 1; transform: scale(1); }\n 50% { opacity: 0.5; transform: scale(1.3); }\n }\n\n .status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 12px; text-transform: uppercase; white-space: nowrap;\n }\n .status-green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .status-amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .status-red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .status-gray { background: var(--mj-bg-surface-sunken); color: var(--mj-text-muted); }\n\n .card-body { margin-bottom: 12px; }\n .stat-row {\n display: flex; justify-content: space-between;\n padding: 4px 0; font-size: 13px;\n }\n .stat-label { color: var(--mj-text-secondary); }\n .stat-value { font-weight: 500; }\n .error-value { color: var(--mj-status-error-text); }\n .error-badge {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n padding: 1px 8px;\n border-radius: 10px;\n font-size: 12px;\n font-weight: 700;\n }\n\n /* Sparkline */\n .sparkline-row {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid var(--mj-border-subtle);\n margin-bottom: 4px;\n }\n .sparkline-label {\n font-size: 11px;\n color: var(--mj-text-disabled);\n white-space: nowrap;\n }\n .sparkline {\n display: flex;\n align-items: flex-end;\n gap: 3px;\n height: 24px;\n flex: 1;\n }\n .spark-bar {\n flex: 1;\n min-height: 2px;\n border-radius: 2px 2px 0 0;\n transition: height 0.3s ease;\n }\n .spark-success { background: var(--mj-brand-primary); }\n .spark-failed { background: var(--mj-status-error); }\n .spark-pending { background: var(--mj-status-warning); }\n\n .card-footer {\n display: flex; justify-content: space-between;\n border-top: 1px solid var(--mj-border-subtle); padding-top: 8px;\n }\n `]\n})\nexport class IntegrationCardComponent {\n @Input() Summary!: IntegrationSummary;\n @Input() Expanded: boolean = false;\n @Input() ViewProvider: IRunViewProvider | null = null;\n @Output() RunNowClick = new EventEmitter<string>();\n @Output() ExpandToggle = new EventEmitter<string>();\n\n get SourceIconClass(): string {\n if (this.Summary.SourceType?.IconClass) {\n return this.Summary.SourceType.IconClass;\n }\n return ResolveIntegrationIcon(\n this.Summary.Integration.Integration ?? this.Summary.Integration.Name,\n this.Summary.Icon\n );\n }\n\n get StatusLabel(): string {\n const color = this.Summary.StatusColor;\n if (color === 'green') return 'Healthy';\n if (color === 'amber') return 'Warning';\n if (color === 'red') return 'Failed';\n return 'Inactive';\n }\n\n get IsActivelySyncing(): boolean {\n return this.Summary.LatestRun?.Status === 'In Progress'\n || this.Summary.LatestRun?.Status === 'Pending';\n }\n\n get FormattedDuration(): string {\n const ms = this.Summary.DurationMs;\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 return `${minutes}m ${seconds}s`;\n }\n\n get MaxSparkRecords(): number {\n const maxVal = Math.max(...this.Summary.RecentRuns.map(r => r.TotalRecords));\n return maxVal > 0 ? maxVal : 1;\n }\n\n SparkBarHeight(records: number): number {\n return Math.max((records / this.MaxSparkRecords) * 100, 8);\n }\n\n OnRunNowClick(): void {\n this.RunNowClick.emit(this.Summary.Integration.ID);\n }\n\n OnExpandToggle(): void {\n this.ExpandToggle.emit(this.Summary.Integration.ID);\n }\n}\n"]}
|
|
@@ -283,7 +283,7 @@ export class RunHistoryPanelComponent {
|
|
|
283
283
|
i0.ɵɵconditionalCreate(0, RunHistoryPanelComponent_Conditional_0_Template, 2, 0, "div", 0)(1, RunHistoryPanelComponent_Conditional_1_Template, 4, 0, "div", 1)(2, RunHistoryPanelComponent_Conditional_2_Template, 18, 0, "div", 2);
|
|
284
284
|
} if (rf & 2) {
|
|
285
285
|
i0.ɵɵconditional(ctx.IsLoading ? 0 : ctx.Runs.length === 0 ? 1 : 2);
|
|
286
|
-
} }, dependencies: [i1.LoadingComponent, i2.DecimalPipe], styles: [".history-loading[_ngcontent-%COMP%], .history-empty[_ngcontent-%COMP%] {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel[_ngcontent-%COMP%] { margin-top: 8px; }\n\n .history-table[_ngcontent-%COMP%] {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row[_ngcontent-%COMP%] { cursor: pointer; }\n .run-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n \n\n .run-status-chip[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green[_ngcontent-%COMP%] { background:
|
|
286
|
+
} }, dependencies: [i1.LoadingComponent, i2.DecimalPipe], styles: [".history-loading[_ngcontent-%COMP%], .history-empty[_ngcontent-%COMP%] {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel[_ngcontent-%COMP%] { margin-top: 8px; }\n\n .history-table[_ngcontent-%COMP%] {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row[_ngcontent-%COMP%] { cursor: pointer; }\n .run-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected[_ngcontent-%COMP%] { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n \n\n .run-status-chip[_ngcontent-%COMP%] {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green[_ngcontent-%COMP%] { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .chip-amber[_ngcontent-%COMP%] { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .chip-red[_ngcontent-%COMP%] { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n\n .duration-cell[_ngcontent-%COMP%] {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .detail-arrow[_ngcontent-%COMP%] { transition: transform 0.2s; font-size: 11px; color: var(--mj-text-muted); }\n .detail-arrow.rotated[_ngcontent-%COMP%] { transform: rotate(90deg); }\n\n .detail-row[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { padding: 0; }\n .detail-panel[_ngcontent-%COMP%] {\n padding: 12px 16px; background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n }\n .detail-panel[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] { margin: 0 0 8px 0; font-size: 13px; }\n\n .detail-table[_ngcontent-%COMP%] {\n width: 100%; border-collapse: collapse; font-size: 12px;\n }\n .detail-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left; padding: 4px 6px; color: var(--mj-text-muted); font-weight: 500;\n }\n .detail-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] { padding: 4px 6px; }\n .error-count[_ngcontent-%COMP%] { color: var(--mj-status-error-text); font-weight: 600; }\n\n \n\n .error-details-section[_ngcontent-%COMP%] {\n margin-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 8px;\n }\n .error-toggle[_ngcontent-%COMP%] {\n background: none; border: none; cursor: pointer;\n font-size: 12px; font-weight: 600; color: var(--mj-status-error-text);\n display: flex; align-items: center; gap: 6px;\n padding: 4px 0;\n }\n .error-toggle[_ngcontent-%COMP%]:hover { text-decoration: underline; }\n .toggle-icon[_ngcontent-%COMP%] {\n transition: transform 0.2s; font-size: 10px;\n }\n .toggle-icon.rotated[_ngcontent-%COMP%] { transform: rotate(180deg); }\n .error-log[_ngcontent-%COMP%] {\n margin: 8px 0 0 0; padding: 10px;\n background: var(--mj-status-error-bg); border: 1px solid var(--mj-status-error-border);\n border-radius: 4px; font-size: 11px;\n white-space: pre-wrap; word-break: break-word;\n max-height: 200px; overflow-y: auto;\n color: var(--mj-status-error-text);\n }"] });
|
|
287
287
|
}
|
|
288
288
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RunHistoryPanelComponent, [{
|
|
289
289
|
type: Component,
|
|
@@ -389,7 +389,7 @@ export class RunHistoryPanelComponent {
|
|
|
389
389
|
</table>
|
|
390
390
|
</div>
|
|
391
391
|
}
|
|
392
|
-
`, styles: ["\n .history-loading, .history-empty {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty i { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel { margin-top: 8px; }\n\n .history-table {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table th {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row { cursor: pointer; }\n .run-row:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row td { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n /* Status Chips with icon */\n .run-status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green { background:
|
|
392
|
+
`, styles: ["\n .history-loading, .history-empty {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty i { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel { margin-top: 8px; }\n\n .history-table {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table th {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row { cursor: pointer; }\n .run-row:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row td { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n /* Status Chips with icon */\n .run-status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .chip-amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .chip-red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n\n .duration-cell {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .detail-arrow { transition: transform 0.2s; font-size: 11px; color: var(--mj-text-muted); }\n .detail-arrow.rotated { transform: rotate(90deg); }\n\n .detail-row td { padding: 0; }\n .detail-panel {\n padding: 12px 16px; background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n }\n .detail-panel h4 { margin: 0 0 8px 0; font-size: 13px; }\n\n .detail-table {\n width: 100%; border-collapse: collapse; font-size: 12px;\n }\n .detail-table th {\n text-align: left; padding: 4px 6px; color: var(--mj-text-muted); font-weight: 500;\n }\n .detail-table td { padding: 4px 6px; }\n .error-count { color: var(--mj-status-error-text); font-weight: 600; }\n\n /* Error Details */\n .error-details-section {\n margin-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 8px;\n }\n .error-toggle {\n background: none; border: none; cursor: pointer;\n font-size: 12px; font-weight: 600; color: var(--mj-status-error-text);\n display: flex; align-items: center; gap: 6px;\n padding: 4px 0;\n }\n .error-toggle:hover { text-decoration: underline; }\n .toggle-icon {\n transition: transform 0.2s; font-size: 10px;\n }\n .toggle-icon.rotated { transform: rotate(180deg); }\n .error-log {\n margin: 8px 0 0 0; padding: 10px;\n background: var(--mj-status-error-bg); border: 1px solid var(--mj-status-error-border);\n border-radius: 4px; font-size: 11px;\n white-space: pre-wrap; word-break: break-word;\n max-height: 200px; overflow-y: auto;\n color: var(--mj-status-error-text);\n }\n "] }]
|
|
393
393
|
}], null, { CompanyIntegrationID: [{
|
|
394
394
|
type: Input
|
|
395
395
|
}], ViewProvider: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-history-panel.component.js","sourceRoot":"","sources":["../../../../src/Integration/components/widgets/run-history-panel.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnChanges, SimpleChanges, inject } from '@angular/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { IRunViewProvider } from '@memberjunction/core';\nimport { IntegrationDataService, IntegrationRunRow, RunDetailRow } from '../../services/integration-data.service';\n\ntype RunStatusColorType = 'amber' | 'green' | 'red';\n\n@Component({\n standalone: false,\n selector: 'app-run-history-panel',\n template: `\n @if (IsLoading) {\n <div class=\"history-loading\">\n <mj-loading text=\"Loading run history...\" size=\"small\"></mj-loading>\n </div>\n } @else if (Runs.length === 0) {\n <div class=\"history-empty\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <p>No runs recorded yet</p>\n </div>\n } @else {\n <div class=\"history-panel\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Started</th>\n <th>Status</th>\n <th>Duration</th>\n <th>Records</th>\n <th>Run By</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (run of Runs; track run.ID) {\n <tr class=\"run-row\" [class.selected]=\"IsSelectedRun(run.ID)\"\n (click)=\"OnRunClick(run)\">\n <td>{{ FormatDate(run.StartedAt) }}</td>\n <td>\n <span class=\"run-status-chip\" [class]=\"'chip-' + StatusColor(run)\">\n <i [class]=\"StatusIcon(run)\"></i>\n {{ run.Status }}\n </span>\n </td>\n <td class=\"duration-cell\">{{ FormatDuration(run) }}</td>\n <td>{{ run.TotalRecords | number }}</td>\n <td>{{ run.RunByUser }}</td>\n <td>\n <i class=\"fa-solid fa-chevron-right detail-arrow\"\n [class.rotated]=\"IsSelectedRun(run.ID)\"></i>\n </td>\n </tr>\n @if (IsSelectedRun(run.ID) && IsLoadingDetails) {\n <tr class=\"detail-row\">\n <td colspan=\"6\">\n <mj-loading text=\"Loading details...\" size=\"small\"></mj-loading>\n </td>\n </tr>\n }\n @if (IsSelectedRun(run.ID) && !IsLoadingDetails && RunDetails.length > 0) {\n <tr class=\"detail-row\">\n <td colspan=\"6\">\n <div class=\"detail-panel\">\n <h4>Entity Breakdown</h4>\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th>Processed</th>\n <th>Created</th>\n <th>Updated</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetails; track detail.EntityID) {\n <tr>\n <td>{{ detail.Entity }}</td>\n <td>{{ detail.RecordsProcessed | number }}</td>\n <td>{{ detail.RecordsCreated | number }}</td>\n <td>{{ detail.RecordsUpdated | number }}</td>\n <td [class.error-count]=\"detail.RecordsErrored > 0\">\n {{ detail.RecordsErrored | number }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <!-- Error details expandable -->\n @if (run.ErrorLog) {\n <div class=\"error-details-section\">\n <button class=\"error-toggle\" (click)=\"ToggleErrorLog($event)\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n Error Details\n <i class=\"fa-solid fa-chevron-down toggle-icon\"\n [class.rotated]=\"ShowErrorLog\"></i>\n </button>\n @if (ShowErrorLog) {\n <pre class=\"error-log\">{{ run.ErrorLog }}</pre>\n }\n </div>\n }\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n }\n `,\n styles: [`\n .history-loading, .history-empty {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty i { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel { margin-top: 8px; }\n\n .history-table {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table th {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row { cursor: pointer; }\n .run-row:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row td { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n /* Status Chips with icon */\n .run-status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green { background: #e6f9ed; color: #1b7a3d; }\n .chip-amber { background: #fff7e0; color: #b5850a; }\n .chip-red { background: #fde8e8; color: #c62828; }\n\n .duration-cell {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .detail-arrow { transition: transform 0.2s; font-size: 11px; color: var(--mj-text-muted); }\n .detail-arrow.rotated { transform: rotate(90deg); }\n\n .detail-row td { padding: 0; }\n .detail-panel {\n padding: 12px 16px; background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n }\n .detail-panel h4 { margin: 0 0 8px 0; font-size: 13px; }\n\n .detail-table {\n width: 100%; border-collapse: collapse; font-size: 12px;\n }\n .detail-table th {\n text-align: left; padding: 4px 6px; color: var(--mj-text-muted); font-weight: 500;\n }\n .detail-table td { padding: 4px 6px; }\n .error-count { color: #c62828; font-weight: 600; }\n\n /* Error Details */\n .error-details-section {\n margin-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 8px;\n }\n .error-toggle {\n background: none; border: none; cursor: pointer;\n font-size: 12px; font-weight: 600; color: #c62828;\n display: flex; align-items: center; gap: 6px;\n padding: 4px 0;\n }\n .error-toggle:hover { text-decoration: underline; }\n .toggle-icon {\n transition: transform 0.2s; font-size: 10px;\n }\n .toggle-icon.rotated { transform: rotate(180deg); }\n .error-log {\n margin: 8px 0 0 0; padding: 10px;\n background: #fff0f0; border: 1px solid #fdd;\n border-radius: 4px; font-size: 11px;\n white-space: pre-wrap; word-break: break-word;\n max-height: 200px; overflow-y: auto;\n color: #7a1111;\n }\n `]\n})\nexport class RunHistoryPanelComponent implements OnChanges {\n @Input() CompanyIntegrationID: string | null = null;\n @Input() ViewProvider: IRunViewProvider | null = null;\n\n Runs: IntegrationRunRow[] = [];\n RunDetails: RunDetailRow[] = [];\n SelectedRunID: string | null = null;\n IsLoading = false;\n IsLoadingDetails = false;\n ShowErrorLog = false;\n\n private dataService = inject(IntegrationDataService);\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['CompanyIntegrationID'] && this.CompanyIntegrationID) {\n this.LoadRuns();\n }\n }\n\n async LoadRuns(): Promise<void> {\n if (!this.CompanyIntegrationID) return;\n this.IsLoading = true;\n this.SelectedRunID = null;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n try {\n this.Runs = await this.dataService.LoadRunHistory(\n this.CompanyIntegrationID, 10, this.ViewProvider\n );\n } finally {\n this.IsLoading = false;\n }\n }\n\n async OnRunClick(run: IntegrationRunRow): Promise<void> {\n if (UUIDsEqual(this.SelectedRunID, run.ID)) {\n this.SelectedRunID = null;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n return;\n }\n this.SelectedRunID = run.ID;\n this.IsLoadingDetails = true;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n try {\n this.RunDetails = await this.dataService.LoadRunDetails(run.ID, this.ViewProvider);\n } finally {\n this.IsLoadingDetails = false;\n }\n }\n\n IsSelectedRun(id: string): boolean {\n return UUIDsEqual(this.SelectedRunID, id);\n }\n\n StatusColor(run: IntegrationRunRow): RunStatusColorType {\n if (run.Status === 'Success') return 'green';\n if (run.Status === 'Failed') return 'red';\n return 'amber';\n }\n\n StatusIcon(run: IntegrationRunRow): string {\n if (run.Status === 'Success') return 'fa-solid fa-circle-check';\n if (run.Status === 'Failed') return 'fa-solid fa-circle-xmark';\n if (run.Status === 'In Progress') return 'fa-solid fa-spinner fa-spin';\n return 'fa-solid fa-clock';\n }\n\n FormatDate(dateStr: string | null): string {\n if (!dateStr) return '--';\n const d = new Date(dateStr);\n return d.toLocaleString(undefined, {\n month: 'short', day: 'numeric',\n hour: '2-digit', minute: '2-digit'\n });\n }\n\n FormatDuration(run: IntegrationRunRow): string {\n if (!run.StartedAt || !run.EndedAt) return '--';\n const ms = new Date(run.EndedAt).getTime() - new Date(run.StartedAt).getTime();\n return this.dataService.FormatDuration(ms);\n }\n\n ToggleErrorLog(event: Event): void {\n event.stopPropagation();\n this.ShowErrorLog = !this.ShowErrorLog;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run-history-panel.component.js","sourceRoot":"","sources":["../../../../src/Integration/components/widgets/run-history-panel.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, OnChanges, SimpleChanges, inject } from '@angular/core';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { IRunViewProvider } from '@memberjunction/core';\nimport { IntegrationDataService, IntegrationRunRow, RunDetailRow } from '../../services/integration-data.service';\n\ntype RunStatusColorType = 'amber' | 'green' | 'red';\n\n@Component({\n standalone: false,\n selector: 'app-run-history-panel',\n template: `\n @if (IsLoading) {\n <div class=\"history-loading\">\n <mj-loading text=\"Loading run history...\" size=\"small\"></mj-loading>\n </div>\n } @else if (Runs.length === 0) {\n <div class=\"history-empty\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n <p>No runs recorded yet</p>\n </div>\n } @else {\n <div class=\"history-panel\">\n <table class=\"history-table\">\n <thead>\n <tr>\n <th>Started</th>\n <th>Status</th>\n <th>Duration</th>\n <th>Records</th>\n <th>Run By</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n @for (run of Runs; track run.ID) {\n <tr class=\"run-row\" [class.selected]=\"IsSelectedRun(run.ID)\"\n (click)=\"OnRunClick(run)\">\n <td>{{ FormatDate(run.StartedAt) }}</td>\n <td>\n <span class=\"run-status-chip\" [class]=\"'chip-' + StatusColor(run)\">\n <i [class]=\"StatusIcon(run)\"></i>\n {{ run.Status }}\n </span>\n </td>\n <td class=\"duration-cell\">{{ FormatDuration(run) }}</td>\n <td>{{ run.TotalRecords | number }}</td>\n <td>{{ run.RunByUser }}</td>\n <td>\n <i class=\"fa-solid fa-chevron-right detail-arrow\"\n [class.rotated]=\"IsSelectedRun(run.ID)\"></i>\n </td>\n </tr>\n @if (IsSelectedRun(run.ID) && IsLoadingDetails) {\n <tr class=\"detail-row\">\n <td colspan=\"6\">\n <mj-loading text=\"Loading details...\" size=\"small\"></mj-loading>\n </td>\n </tr>\n }\n @if (IsSelectedRun(run.ID) && !IsLoadingDetails && RunDetails.length > 0) {\n <tr class=\"detail-row\">\n <td colspan=\"6\">\n <div class=\"detail-panel\">\n <h4>Entity Breakdown</h4>\n <table class=\"detail-table\">\n <thead>\n <tr>\n <th>Entity</th>\n <th>Processed</th>\n <th>Created</th>\n <th>Updated</th>\n <th>Errors</th>\n </tr>\n </thead>\n <tbody>\n @for (detail of RunDetails; track detail.EntityID) {\n <tr>\n <td>{{ detail.Entity }}</td>\n <td>{{ detail.RecordsProcessed | number }}</td>\n <td>{{ detail.RecordsCreated | number }}</td>\n <td>{{ detail.RecordsUpdated | number }}</td>\n <td [class.error-count]=\"detail.RecordsErrored > 0\">\n {{ detail.RecordsErrored | number }}\n </td>\n </tr>\n }\n </tbody>\n </table>\n\n <!-- Error details expandable -->\n @if (run.ErrorLog) {\n <div class=\"error-details-section\">\n <button class=\"error-toggle\" (click)=\"ToggleErrorLog($event)\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n Error Details\n <i class=\"fa-solid fa-chevron-down toggle-icon\"\n [class.rotated]=\"ShowErrorLog\"></i>\n </button>\n @if (ShowErrorLog) {\n <pre class=\"error-log\">{{ run.ErrorLog }}</pre>\n }\n </div>\n }\n </div>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n </div>\n }\n `,\n styles: [`\n .history-loading, .history-empty {\n padding: 24px; text-align: center; color: var(--mj-text-muted);\n }\n .history-empty i { font-size: 24px; margin-bottom: 8px; display: block; }\n\n .history-panel { margin-top: 8px; }\n\n .history-table {\n width: 100%; border-collapse: collapse; font-size: 13px;\n }\n .history-table th {\n text-align: left; padding: 6px 8px;\n border-bottom: 2px solid var(--mj-border-default); color: var(--mj-text-secondary); font-weight: 600;\n }\n .run-row { cursor: pointer; }\n .run-row:hover { background: var(--mj-bg-surface-sunken); }\n .run-row.selected { background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); }\n .run-row td { padding: 6px 8px; border-bottom: 1px solid var(--mj-border-default); }\n\n /* Status Chips with icon */\n .run-status-chip {\n font-size: 11px; font-weight: 600; padding: 3px 8px;\n border-radius: 10px; display: inline-flex; align-items: center; gap: 4px;\n white-space: nowrap;\n }\n .chip-green { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .chip-amber { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .chip-red { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n\n .duration-cell {\n font-variant-numeric: tabular-nums;\n color: var(--mj-text-secondary);\n }\n\n .detail-arrow { transition: transform 0.2s; font-size: 11px; color: var(--mj-text-muted); }\n .detail-arrow.rotated { transform: rotate(90deg); }\n\n .detail-row td { padding: 0; }\n .detail-panel {\n padding: 12px 16px; background: var(--mj-bg-surface-sunken);\n border-left: 3px solid var(--mj-brand-primary);\n }\n .detail-panel h4 { margin: 0 0 8px 0; font-size: 13px; }\n\n .detail-table {\n width: 100%; border-collapse: collapse; font-size: 12px;\n }\n .detail-table th {\n text-align: left; padding: 4px 6px; color: var(--mj-text-muted); font-weight: 500;\n }\n .detail-table td { padding: 4px 6px; }\n .error-count { color: var(--mj-status-error-text); font-weight: 600; }\n\n /* Error Details */\n .error-details-section {\n margin-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n padding-top: 8px;\n }\n .error-toggle {\n background: none; border: none; cursor: pointer;\n font-size: 12px; font-weight: 600; color: var(--mj-status-error-text);\n display: flex; align-items: center; gap: 6px;\n padding: 4px 0;\n }\n .error-toggle:hover { text-decoration: underline; }\n .toggle-icon {\n transition: transform 0.2s; font-size: 10px;\n }\n .toggle-icon.rotated { transform: rotate(180deg); }\n .error-log {\n margin: 8px 0 0 0; padding: 10px;\n background: var(--mj-status-error-bg); border: 1px solid var(--mj-status-error-border);\n border-radius: 4px; font-size: 11px;\n white-space: pre-wrap; word-break: break-word;\n max-height: 200px; overflow-y: auto;\n color: var(--mj-status-error-text);\n }\n `]\n})\nexport class RunHistoryPanelComponent implements OnChanges {\n @Input() CompanyIntegrationID: string | null = null;\n @Input() ViewProvider: IRunViewProvider | null = null;\n\n Runs: IntegrationRunRow[] = [];\n RunDetails: RunDetailRow[] = [];\n SelectedRunID: string | null = null;\n IsLoading = false;\n IsLoadingDetails = false;\n ShowErrorLog = false;\n\n private dataService = inject(IntegrationDataService);\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['CompanyIntegrationID'] && this.CompanyIntegrationID) {\n this.LoadRuns();\n }\n }\n\n async LoadRuns(): Promise<void> {\n if (!this.CompanyIntegrationID) return;\n this.IsLoading = true;\n this.SelectedRunID = null;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n try {\n this.Runs = await this.dataService.LoadRunHistory(\n this.CompanyIntegrationID, 10, this.ViewProvider\n );\n } finally {\n this.IsLoading = false;\n }\n }\n\n async OnRunClick(run: IntegrationRunRow): Promise<void> {\n if (UUIDsEqual(this.SelectedRunID, run.ID)) {\n this.SelectedRunID = null;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n return;\n }\n this.SelectedRunID = run.ID;\n this.IsLoadingDetails = true;\n this.RunDetails = [];\n this.ShowErrorLog = false;\n try {\n this.RunDetails = await this.dataService.LoadRunDetails(run.ID, this.ViewProvider);\n } finally {\n this.IsLoadingDetails = false;\n }\n }\n\n IsSelectedRun(id: string): boolean {\n return UUIDsEqual(this.SelectedRunID, id);\n }\n\n StatusColor(run: IntegrationRunRow): RunStatusColorType {\n if (run.Status === 'Success') return 'green';\n if (run.Status === 'Failed') return 'red';\n return 'amber';\n }\n\n StatusIcon(run: IntegrationRunRow): string {\n if (run.Status === 'Success') return 'fa-solid fa-circle-check';\n if (run.Status === 'Failed') return 'fa-solid fa-circle-xmark';\n if (run.Status === 'In Progress') return 'fa-solid fa-spinner fa-spin';\n return 'fa-solid fa-clock';\n }\n\n FormatDate(dateStr: string | null): string {\n if (!dateStr) return '--';\n const d = new Date(dateStr);\n return d.toLocaleString(undefined, {\n month: 'short', day: 'numeric',\n hour: '2-digit', minute: '2-digit'\n });\n }\n\n FormatDuration(run: IntegrationRunRow): string {\n if (!run.StartedAt || !run.EndedAt) return '--';\n const ms = new Date(run.EndedAt).getTime() - new Date(run.StartedAt).getTime();\n return this.dataService.FormatDuration(ms);\n }\n\n ToggleErrorLog(event: Event): void {\n event.stopPropagation();\n this.ShowErrorLog = !this.ShowErrorLog;\n }\n}\n"]}
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { OnDestroy, AfterViewInit } from '@angular/core';
|
|
9
9
|
import { Subject } from 'rxjs';
|
|
10
|
-
import { ResourceData } from '@memberjunction/core-entities';
|
|
10
|
+
import { ResourceData, MJSearchScopeEntity } from '@memberjunction/core-entities';
|
|
11
11
|
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
|
|
12
|
+
import { SearchScopeChildGridColumn } from '@memberjunction/ng-search';
|
|
12
13
|
import * as i0 from "@angular/core";
|
|
13
14
|
/** Configuration section definition */
|
|
14
15
|
interface ConfigSection {
|
|
@@ -100,9 +101,141 @@ export declare class KnowledgeConfigResourceComponent extends BaseResourceCompon
|
|
|
100
101
|
NewIndexName: string;
|
|
101
102
|
NewIndexVectorDBID: string;
|
|
102
103
|
NewIndexEmbeddingModelID: string;
|
|
104
|
+
/** All SearchScope rows the current user can manage. */
|
|
105
|
+
SearchScopes: MJSearchScopeEntity[];
|
|
106
|
+
/** Currently-selected scope ID — drives child-grid loading. */
|
|
107
|
+
ActiveScopeID: string | null;
|
|
108
|
+
IsLoadingScopes: boolean;
|
|
109
|
+
/** Which sub-tab of the selected scope is open. */
|
|
110
|
+
ActiveScopeTab: 'definition' | 'providers' | 'indexes' | 'entities' | 'storage' | 'permissions';
|
|
111
|
+
/** Column spec for the Providers child grid. */
|
|
112
|
+
readonly ScopeProviderColumns: SearchScopeChildGridColumn[];
|
|
113
|
+
/** Column spec for the External Indexes child grid. */
|
|
114
|
+
readonly ScopeExternalIndexColumns: SearchScopeChildGridColumn[];
|
|
115
|
+
/** Column spec for the Entities child grid. */
|
|
116
|
+
readonly ScopeEntityColumns: SearchScopeChildGridColumn[];
|
|
117
|
+
/** Column spec for the Storage Accounts child grid. */
|
|
118
|
+
readonly ScopeStorageColumns: SearchScopeChildGridColumn[];
|
|
119
|
+
/**
|
|
120
|
+
* Column spec for the SearchScopePermission child grid (Phase 2A).
|
|
121
|
+
* Editable surface — admins author per-user / per-role grants here.
|
|
122
|
+
* Each row binds either a User or a Role (XOR enforced by the DB CHECK
|
|
123
|
+
* constraint, surfaced as a save-time error for now). Resolution order
|
|
124
|
+
* lives in SearchScopePermissionResolver.
|
|
125
|
+
*/
|
|
126
|
+
readonly ScopePermissionColumns: SearchScopeChildGridColumn[];
|
|
103
127
|
ngAfterViewInit(): void;
|
|
104
128
|
ngOnDestroy(): void;
|
|
105
129
|
SelectSection(sectionId: string): void;
|
|
130
|
+
AnalyticsLoaded: boolean;
|
|
131
|
+
AnalyticsLoading: boolean;
|
|
132
|
+
AnalyticsTotalRuns: number;
|
|
133
|
+
AnalyticsSuccessRate: number;
|
|
134
|
+
AnalyticsAvgLatencyMs: number;
|
|
135
|
+
AnalyticsP95LatencyMs: number;
|
|
136
|
+
AnalyticsTotalRerankerCostCents: number;
|
|
137
|
+
AnalyticsHitRate: number;
|
|
138
|
+
AnalyticsTopScopes: Array<{
|
|
139
|
+
ScopeID: string;
|
|
140
|
+
Name: string;
|
|
141
|
+
Count: number;
|
|
142
|
+
AvgLatencyMs: number;
|
|
143
|
+
}>;
|
|
144
|
+
AnalyticsTopFailures: Array<{
|
|
145
|
+
Reason: string;
|
|
146
|
+
Count: number;
|
|
147
|
+
}>;
|
|
148
|
+
AnalyticsRerankerSpend: Array<{
|
|
149
|
+
Reranker: string;
|
|
150
|
+
Count: number;
|
|
151
|
+
TotalCents: number;
|
|
152
|
+
}>;
|
|
153
|
+
LoadSearchAnalytics(): Promise<void>;
|
|
154
|
+
/** Fetch the raw SearchExecutionLog rows. Returns null on RunView failure (already logged). */
|
|
155
|
+
private fetchSearchExecutionRows;
|
|
156
|
+
/** Total runs, success rate, hit rate, avg + p95 latency, total reranker spend. */
|
|
157
|
+
private computeAnalyticsKpis;
|
|
158
|
+
/**
|
|
159
|
+
* Per-scope volume rollup → top 10 by Count. Fetches scope names from
|
|
160
|
+
* `this.SearchScopes` when already loaded, otherwise loads them on demand
|
|
161
|
+
* so the unscoped audit-only path still gets human-readable labels.
|
|
162
|
+
*/
|
|
163
|
+
private computeAnalyticsTopScopes;
|
|
164
|
+
/** Top 5 failure reasons across non-Success rows. */
|
|
165
|
+
private computeAnalyticsTopFailures;
|
|
166
|
+
/** Per-reranker spend rollup, sorted descending by total cost. */
|
|
167
|
+
private computeAnalyticsRerankerSpend;
|
|
168
|
+
PermissionsLoaded: boolean;
|
|
169
|
+
PermissionsLoading: boolean;
|
|
170
|
+
PermissionsRows: Array<{
|
|
171
|
+
ID: string;
|
|
172
|
+
SearchScopeID: string;
|
|
173
|
+
SearchScopeName: string;
|
|
174
|
+
UserID: string | null;
|
|
175
|
+
UserName: string | null;
|
|
176
|
+
UserEmail: string | null;
|
|
177
|
+
RoleID: string | null;
|
|
178
|
+
RoleName: string | null;
|
|
179
|
+
PermissionLevel: string;
|
|
180
|
+
}>;
|
|
181
|
+
PermissionsFilterScope: string;
|
|
182
|
+
PermissionsFilterPrincipal: string;
|
|
183
|
+
PermissionsFilterLevel: string;
|
|
184
|
+
LoadPermissionsAudit(): Promise<void>;
|
|
185
|
+
get FilteredPermissionsRows(): typeof this.PermissionsRows;
|
|
186
|
+
RefreshPermissionsAudit(): void;
|
|
187
|
+
/**
|
|
188
|
+
* Pull permissions, scopes, users, roles in one batched call.
|
|
189
|
+
* `BypassCache: true` on every view — this is an audit dashboard, so we
|
|
190
|
+
* want SQL-truth even when permission/scope rows have been written
|
|
191
|
+
* outside the normal `BaseEntity.Save()` path (test harnesses,
|
|
192
|
+
* direct-SQL maintenance, recovery scripts). Without this, scope names
|
|
193
|
+
* can render as "(unknown)" if the cache was populated before the
|
|
194
|
+
* underlying row was inserted.
|
|
195
|
+
*
|
|
196
|
+
* Returns null on RunView failure (already logged).
|
|
197
|
+
*/
|
|
198
|
+
private fetchPermissionsAuditData;
|
|
199
|
+
/**
|
|
200
|
+
* Shape the raw fetched data into the audit-table rows. Drops
|
|
201
|
+
* permission rows whose SearchScope is not visible to the current user
|
|
202
|
+
* (MJ's row-level filtering hides scopes from non-Owner callers).
|
|
203
|
+
* Surfacing the permission row with "(unknown)" leaks the row's
|
|
204
|
+
* existence without giving the auditor anything useful — the underlying
|
|
205
|
+
* API already enforces visibility, so this is a UX call, not a security
|
|
206
|
+
* one.
|
|
207
|
+
*/
|
|
208
|
+
private shapePermissionsAuditRows;
|
|
209
|
+
LoadSearchScopes(): Promise<void>;
|
|
210
|
+
SelectScope(scopeID: string): void;
|
|
211
|
+
SelectScopeTab(tab: 'definition' | 'providers' | 'indexes' | 'entities' | 'storage' | 'permissions'): void;
|
|
212
|
+
get ActiveScope(): MJSearchScopeEntity | null;
|
|
213
|
+
CreateNewScope(): Promise<void>;
|
|
214
|
+
/**
|
|
215
|
+
* Pick a placeholder Name that doesn't collide with an existing scope.
|
|
216
|
+
* `__mj.SearchScope.Name` is UNIQUE, so reusing the literal string
|
|
217
|
+
* "New Search Scope" twice in a row throws SQL Server's UQ violation.
|
|
218
|
+
* Walk an incrementing suffix until we find one the in-memory list
|
|
219
|
+
* doesn't already use ("New Search Scope", "New Search Scope 2",
|
|
220
|
+
* "New Search Scope 3", ...). Existing scopes table is small and
|
|
221
|
+
* already loaded, so the linear scan is trivially cheap.
|
|
222
|
+
*/
|
|
223
|
+
private pickUniqueNewScopeName;
|
|
224
|
+
/**
|
|
225
|
+
* Open the active scope in its full custom form (a new MJExplorer tab).
|
|
226
|
+
* The dashboard view exposes a quick-edit subset; the full form has the
|
|
227
|
+
* Phase 2D / Phase 4 surfaces (Fusion Weights sliders, Reranker dropdown,
|
|
228
|
+
* Reranker Budget Cents, Live Preview, Search Scope Test Queries panel,
|
|
229
|
+
* Search Execution Logs panel, etc.). No-ops for the built-in Global
|
|
230
|
+
* scope (no detail to author) and any scope without an ID yet.
|
|
231
|
+
*/
|
|
232
|
+
OpenActiveScopeFullForm(): void;
|
|
233
|
+
SaveActiveScope(): Promise<void>;
|
|
234
|
+
/** Format a scope Date field as the string expected by <input type="datetime-local">. */
|
|
235
|
+
FormatScopeDate(value: Date | string | null | undefined): string;
|
|
236
|
+
/** Write a datetime-local input value back to the scope entity. Empty clears to null. */
|
|
237
|
+
SetScopeDate(scope: MJSearchScopeEntity, field: 'StartAt' | 'EndAt', value: string): void;
|
|
238
|
+
DeleteActiveScope(): Promise<void>;
|
|
106
239
|
OnSettingChanged(): void;
|
|
107
240
|
SaveConfiguration(): Promise<void>;
|
|
108
241
|
ResetConfiguration(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge-config-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/config/knowledge-config-resource.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgC,SAAS,EAAE,aAAa,EAAU,MAAM,eAAe,CAAC;AAC/F,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAuH,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge-config-resource.component.d.ts","sourceRoot":"","sources":["../../../../src/KnowledgeHub/components/config/knowledge-config-resource.component.ts"],"names":[],"mappings":"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"}
|