@memberjunction/ng-dashboards 6.2.0-edge.2 → 6.2.0-edge.4
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/analytics/realtime/realtime-transcripts-data.d.ts +4 -3
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.d.ts.map +1 -1
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js +8 -5
- package/dist/AI/components/analytics/realtime/realtime-transcripts-data.js.map +1 -1
- package/dist/AI/components/duplicates/compare-value.component.d.ts +67 -0
- package/dist/AI/components/duplicates/compare-value.component.d.ts.map +1 -0
- package/dist/AI/components/duplicates/compare-value.component.js +168 -0
- package/dist/AI/components/duplicates/compare-value.component.js.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts +49 -3
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.d.ts.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js +287 -169
- package/dist/AI/components/duplicates/duplicate-detection-resource.component.js.map +1 -1
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts +77 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.d.ts.map +1 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js +116 -0
- package/dist/AI/components/duplicates/duplicate-detection-run-scope.js.map +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts +1 -0
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.d.ts.map +1 -1
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +16 -4
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.d.ts +2 -0
- package/dist/AI/components/tags/tags-resource.component.d.ts.map +1 -1
- package/dist/AI/components/tags/tags-resource.component.js +12 -6
- package/dist/AI/components/tags/tags-resource.component.js.map +1 -1
- package/dist/AI/components/vectors/vector-index-auto.d.ts +29 -0
- package/dist/AI/components/vectors/vector-index-auto.d.ts.map +1 -0
- package/dist/AI/components/vectors/vector-index-auto.js +59 -0
- package/dist/AI/components/vectors/vector-index-auto.js.map +1 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts +9 -0
- package/dist/AI/components/vectors/vector-management-resource.component.d.ts.map +1 -1
- package/dist/AI/components/vectors/vector-management-resource.component.js +65 -20
- package/dist/AI/components/vectors/vector-management-resource.component.js.map +1 -1
- package/dist/Actions/components/actions-overview.component.d.ts.map +1 -1
- package/dist/Actions/components/actions-overview.component.js +7 -3
- package/dist/Actions/components/actions-overview.component.js.map +1 -1
- package/dist/Actions/components/categories-list-view.component.d.ts.map +1 -1
- package/dist/Actions/components/categories-list-view.component.js +3 -2
- package/dist/Actions/components/categories-list-view.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.d.ts.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +1 -0
- package/dist/ComponentStudio/component-studio-dashboard.component.js.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts +0 -3
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +5 -14
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +1 -0
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.d.ts +12 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.d.ts.map +1 -1
- package/dist/ComponentStudio/components/form-override-dialog.component.js +128 -81
- package/dist/ComponentStudio/components/form-override-dialog.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.d.ts +2 -0
- package/dist/Credentials/components/credentials-list-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +12 -10
- package/dist/Credentials/components/credentials-list-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts +14 -43
- package/dist/DashboardBrowser/dashboard-browser-agent-context.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js +6 -29
- package/dist/DashboardBrowser/dashboard-browser-agent-context.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts +174 -321
- package/dist/DashboardBrowser/dashboard-browser-resource.component.d.ts.map +1 -1
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +522 -1195
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts +116 -0
- package/dist/DashboardBrowser/dashboard-library-filter.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js +277 -0
- package/dist/DashboardBrowser/dashboard-library-filter.js.map +1 -0
- package/dist/DashboardBrowser/dashboard-share-dialog.component.d.ts +1 -1
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js.map +1 -1
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts +26 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js +32 -0
- package/dist/DashboardBrowser/dashboards-agent-tools.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts +58 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js +391 -0
- package/dist/DashboardBrowser/dashboards-categories-resource.component.js.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts +37 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.d.ts.map +1 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js +68 -0
- package/dist/DashboardBrowser/dashboards-categories.helpers.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts +295 -0
- package/dist/DashboardEditor/dashboard-editor.component.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.component.js +1022 -0
- package/dist/DashboardEditor/dashboard-editor.component.js.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts +23 -0
- package/dist/DashboardEditor/dashboard-editor.types.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-editor.types.js +3 -0
- package/dist/DashboardEditor/dashboard-editor.types.js.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts +11 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.d.ts.map +1 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js +17 -0
- package/dist/DashboardEditor/dashboard-viewer-factory.js.map +1 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +30 -0
- package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
- package/dist/DataExplorer/data-explorer-dashboard.component.js +349 -232
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/DataExplorer/services/explorer-state.service.d.ts +1 -1
- package/dist/DataExplorer/services/explorer-state.service.js +2 -5
- package/dist/DataExplorer/services/explorer-state.service.js.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.d.ts +0 -14
- package/dist/FormBuilder/form-builder-resource.component.d.ts.map +1 -1
- package/dist/FormBuilder/form-builder-resource.component.js +7 -29
- package/dist/FormBuilder/form-builder-resource.component.js.map +1 -1
- package/dist/Home/home-agent-context.d.ts +29 -10
- package/dist/Home/home-agent-context.d.ts.map +1 -1
- package/dist/Home/home-agent-context.js +50 -24
- package/dist/Home/home-agent-context.js.map +1 -1
- package/dist/Home/home-dashboard-switcher.component.d.ts +95 -0
- package/dist/Home/home-dashboard-switcher.component.d.ts.map +1 -0
- package/dist/Home/home-dashboard-switcher.component.js +442 -0
- package/dist/Home/home-dashboard-switcher.component.js.map +1 -0
- package/dist/Home/home-dashboard.component.d.ts +330 -17
- package/dist/Home/home-dashboard.component.d.ts.map +1 -1
- package/dist/Home/home-dashboard.component.js +1702 -1014
- package/dist/Home/home-dashboard.component.js.map +1 -1
- package/dist/Home/home-menus.d.ts +38 -0
- package/dist/Home/home-menus.d.ts.map +1 -0
- package/dist/Home/home-menus.js +53 -0
- package/dist/Home/home-menus.js.map +1 -0
- package/dist/Home/home-pinned-dashboards.d.ts +33 -0
- package/dist/Home/home-pinned-dashboards.d.ts.map +1 -0
- package/dist/Home/home-pinned-dashboards.js +76 -0
- package/dist/Home/home-pinned-dashboards.js.map +1 -0
- package/dist/PredictiveStudio/components/ps-production.component.d.ts +5 -1
- package/dist/PredictiveStudio/components/ps-production.component.d.ts.map +1 -1
- package/dist/PredictiveStudio/components/ps-production.component.js +64 -41
- package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
- package/dist/QueryBrowser/query-browser-resource.component.js +3 -2
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js +2 -2
- package/dist/RealtimeRecordings/realtime-recordings-dashboard.component.js.map +1 -1
- package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts +107 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.d.ts.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.js +216 -0
- package/dist/TelephonyOperations/telephony-operations-agent-context.js.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts +58 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.d.ts.map +1 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js +812 -0
- package/dist/TelephonyOperations/telephony-operations-dashboard.component.js.map +1 -0
- package/dist/Testing/components/testing-explorer.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +7 -7
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/WorkQueue/components/work-queue-bindings.component.d.ts +37 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.js +210 -0
- package/dist/WorkQueue/components/work-queue-bindings.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts +70 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.js +496 -0
- package/dist/WorkQueue/components/work-queue-dead-letters.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts +22 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.js +99 -0
- package/dist/WorkQueue/components/work-queue-discard-dialog.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-overview.component.d.ts +29 -0
- package/dist/WorkQueue/components/work-queue-overview.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-overview.component.js +278 -0
- package/dist/WorkQueue/components/work-queue-overview.component.js.map +1 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.d.ts +59 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.d.ts.map +1 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.js +359 -0
- package/dist/WorkQueue/components/work-queue-partitions.component.js.map +1 -0
- package/dist/WorkQueue/services/work-queue-operator.service.d.ts +22 -0
- package/dist/WorkQueue/services/work-queue-operator.service.d.ts.map +1 -0
- package/dist/WorkQueue/services/work-queue-operator.service.js +44 -0
- package/dist/WorkQueue/services/work-queue-operator.service.js.map +1 -0
- package/dist/WorkQueue/work-queue-agent-context.d.ts +67 -0
- package/dist/WorkQueue/work-queue-agent-context.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-agent-context.js +119 -0
- package/dist/WorkQueue/work-queue-agent-context.js.map +1 -0
- package/dist/WorkQueue/work-queue-dashboard.component.d.ts +94 -0
- package/dist/WorkQueue/work-queue-dashboard.component.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-dashboard.component.js +545 -0
- package/dist/WorkQueue/work-queue-dashboard.component.js.map +1 -0
- package/dist/WorkQueue/work-queue-types.d.ts +40 -0
- package/dist/WorkQueue/work-queue-types.d.ts.map +1 -0
- package/dist/WorkQueue/work-queue-types.js +2 -0
- package/dist/WorkQueue/work-queue-types.js.map +1 -0
- package/dist/ai-dashboards.module.d.ts +21 -20
- package/dist/ai-dashboards.module.d.ts.map +1 -1
- package/dist/ai-dashboards.module.js +4 -1
- package/dist/ai-dashboards.module.js.map +1 -1
- package/dist/core-dashboards.module.d.ts +69 -61
- package/dist/core-dashboards.module.d.ts.map +1 -1
- package/dist/core-dashboards.module.js +29 -2
- package/dist/core-dashboards.module.js.map +1 -1
- package/dist/data-explorer-dashboards.module.d.ts +1 -1
- package/dist/data-explorer-dashboards.module.d.ts.map +1 -1
- package/dist/data-explorer-dashboards.module.js +3 -1
- package/dist/data-explorer-dashboards.module.js.map +1 -1
- package/dist/module.d.ts +14 -13
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +7 -0
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +6 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +9 -0
- package/dist/public-api.js.map +1 -1
- package/dist/shared/dashboard-library-changes.d.ts +23 -0
- package/dist/shared/dashboard-library-changes.d.ts.map +1 -0
- package/dist/shared/dashboard-library-changes.js +26 -0
- package/dist/shared/dashboard-library-changes.js.map +1 -0
- package/dist/shared/dashboard-owner-names.d.ts +17 -0
- package/dist/shared/dashboard-owner-names.d.ts.map +1 -0
- package/dist/shared/dashboard-owner-names.js +65 -0
- package/dist/shared/dashboard-owner-names.js.map +1 -0
- package/dist/shared/dashboard-recents.d.ts +34 -0
- package/dist/shared/dashboard-recents.d.ts.map +1 -0
- package/dist/shared/dashboard-recents.js +87 -0
- package/dist/shared/dashboard-recents.js.map +1 -0
- package/dist/shared/dashboards-app-install.d.ts +59 -0
- package/dist/shared/dashboards-app-install.d.ts.map +1 -0
- package/dist/shared/dashboards-app-install.js +97 -0
- package/dist/shared/dashboards-app-install.js.map +1 -0
- package/dist/shared/dashboards-app.helpers.d.ts +42 -0
- package/dist/shared/dashboards-app.helpers.d.ts.map +1 -0
- package/dist/shared/dashboards-app.helpers.js +143 -0
- package/dist/shared/dashboards-app.helpers.js.map +1 -0
- package/dist/work-queue-dashboards.module.d.ts +23 -0
- package/dist/work-queue-dashboards.module.d.ts.map +1 -0
- package/dist/work-queue-dashboards.module.js +92 -0
- package/dist/work-queue-dashboards.module.js.map +1 -0
- package/package.json +73 -66
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { WORK_QUEUE_PARTITION_CONDITIONS } from '../work-queue-agent-context';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "../services/work-queue-operator.service";
|
|
5
|
+
import * as i2 from "@angular/common";
|
|
6
|
+
import * as i3 from "@angular/forms";
|
|
7
|
+
import * as i4 from "@memberjunction/ng-ui-components";
|
|
8
|
+
import * as i5 from "@memberjunction/ng-shared-generic";
|
|
9
|
+
import * as i6 from "./work-queue-discard-dialog.component";
|
|
10
|
+
const _forTrack0 = ($index, $item) => $item.ID;
|
|
11
|
+
const _forTrack1 = ($index, $item) => $item.PartitionKey;
|
|
12
|
+
function WorkQueuePartitionsComponent_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
13
|
+
i0.ɵɵelementStart(0, "option", 5);
|
|
14
|
+
i0.ɵɵtext(1);
|
|
15
|
+
i0.ɵɵelementEnd();
|
|
16
|
+
} if (rf & 2) {
|
|
17
|
+
const s_r1 = ctx.$implicit;
|
|
18
|
+
i0.ɵɵproperty("value", s_r1.Name);
|
|
19
|
+
i0.ɵɵadvance();
|
|
20
|
+
i0.ɵɵtextInterpolate3("", s_r1.Name, " \u2014 ", s_r1.Topic, " (", s_r1.Transport, ")");
|
|
21
|
+
} }
|
|
22
|
+
function WorkQueuePartitionsComponent_For_11_Template(rf, ctx) { if (rf & 1) {
|
|
23
|
+
const _r2 = i0.ɵɵgetCurrentView();
|
|
24
|
+
i0.ɵɵelementStart(0, "mj-filter-chip", 17);
|
|
25
|
+
i0.ɵɵlistener("Clicked", function WorkQueuePartitionsComponent_For_11_Template_mj_filter_chip_Clicked_0_listener() { const c_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.ToggleCondition(c_r3)); });
|
|
26
|
+
i0.ɵɵelementEnd();
|
|
27
|
+
} if (rf & 2) {
|
|
28
|
+
const c_r3 = ctx.$implicit;
|
|
29
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
30
|
+
i0.ɵɵproperty("Label", c_r3)("Active", ctx_r3.Condition === c_r3);
|
|
31
|
+
} }
|
|
32
|
+
function WorkQueuePartitionsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
+
i0.ɵɵelement(0, "mj-alert", 8);
|
|
34
|
+
} if (rf & 2) {
|
|
35
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
36
|
+
i0.ɵɵproperty("Variant", ctx_r3.LastOutcome.Ok ? "success" : "error")("Message", ctx_r3.LastOutcome.Message);
|
|
37
|
+
} }
|
|
38
|
+
function WorkQueuePartitionsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
39
|
+
i0.ɵɵelement(0, "mj-empty-state", 9);
|
|
40
|
+
} }
|
|
41
|
+
function WorkQueuePartitionsComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
42
|
+
i0.ɵɵelement(0, "mj-empty-state", 10);
|
|
43
|
+
} }
|
|
44
|
+
function WorkQueuePartitionsComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
45
|
+
i0.ɵɵelementStart(0, "div", 11);
|
|
46
|
+
i0.ɵɵelement(1, "mj-loading", 18);
|
|
47
|
+
i0.ɵɵelementEnd();
|
|
48
|
+
} }
|
|
49
|
+
function WorkQueuePartitionsComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
|
|
50
|
+
i0.ɵɵelement(0, "mj-alert", 12);
|
|
51
|
+
} if (rf & 2) {
|
|
52
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
53
|
+
i0.ɵɵproperty("Message", ctx_r3.LoadError);
|
|
54
|
+
} }
|
|
55
|
+
function WorkQueuePartitionsComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
|
|
56
|
+
i0.ɵɵelement(0, "mj-alert", 13);
|
|
57
|
+
} }
|
|
58
|
+
function WorkQueuePartitionsComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
59
|
+
i0.ɵɵelement(0, "mj-empty-state", 14);
|
|
60
|
+
} if (rf & 2) {
|
|
61
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
62
|
+
i0.ɵɵproperty("Message", ctx_r3.Condition ? "No keys are currently " + ctx_r3.Condition + "." : "No partition keys have open work on this subscription.");
|
|
63
|
+
} }
|
|
64
|
+
function WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
65
|
+
i0.ɵɵelementStart(0, "code", 25);
|
|
66
|
+
i0.ɵɵtext(1);
|
|
67
|
+
i0.ɵɵelementEnd();
|
|
68
|
+
} if (rf & 2) {
|
|
69
|
+
const row_r5 = i0.ɵɵnextContext().$implicit;
|
|
70
|
+
i0.ɵɵadvance();
|
|
71
|
+
i0.ɵɵtextInterpolate(row_r5.HeadDeliveryID);
|
|
72
|
+
} }
|
|
73
|
+
function WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
74
|
+
i0.ɵɵelementStart(0, "span", 26);
|
|
75
|
+
i0.ɵɵtext(1, "\u2014");
|
|
76
|
+
i0.ɵɵelementEnd();
|
|
77
|
+
} }
|
|
78
|
+
function WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
80
|
+
i0.ɵɵelementStart(0, "button", 28);
|
|
81
|
+
i0.ɵɵlistener("click", function WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_12_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r6); const row_r5 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.RequestReplay(row_r5, $event)); });
|
|
82
|
+
i0.ɵɵelement(1, "i", 29);
|
|
83
|
+
i0.ɵɵtext(2, " Replay head ");
|
|
84
|
+
i0.ɵɵelementEnd();
|
|
85
|
+
i0.ɵɵelementStart(3, "button", 30);
|
|
86
|
+
i0.ɵɵlistener("click", function WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_12_Template_button_click_3_listener($event) { i0.ɵɵrestoreView(_r6); const row_r5 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.RequestDiscard(row_r5, $event)); });
|
|
87
|
+
i0.ɵɵelement(4, "i", 31);
|
|
88
|
+
i0.ɵɵtext(5, " Discard head ");
|
|
89
|
+
i0.ɵɵelementEnd();
|
|
90
|
+
} if (rf & 2) {
|
|
91
|
+
const ctx_r3 = i0.ɵɵnextContext(3);
|
|
92
|
+
i0.ɵɵproperty("disabled", !ctx_r3.CanOperate || ctx_r3.ActionInProgress);
|
|
93
|
+
i0.ɵɵadvance(3);
|
|
94
|
+
i0.ɵɵproperty("disabled", !ctx_r3.CanOperate || ctx_r3.ActionInProgress);
|
|
95
|
+
} }
|
|
96
|
+
function WorkQueuePartitionsComponent_Conditional_19_For_15_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
i0.ɵɵelementStart(0, "tr")(1, "td", 23);
|
|
98
|
+
i0.ɵɵtext(2);
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
i0.ɵɵelementStart(3, "td")(4, "span", 24);
|
|
101
|
+
i0.ɵɵtext(5);
|
|
102
|
+
i0.ɵɵelementEnd()();
|
|
103
|
+
i0.ɵɵelementStart(6, "td");
|
|
104
|
+
i0.ɵɵconditionalCreate(7, WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_7_Template, 2, 1, "code", 25)(8, WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_8_Template, 2, 0, "span", 26);
|
|
105
|
+
i0.ɵɵelementEnd();
|
|
106
|
+
i0.ɵɵelementStart(9, "td", 20);
|
|
107
|
+
i0.ɵɵtext(10);
|
|
108
|
+
i0.ɵɵelementEnd();
|
|
109
|
+
i0.ɵɵelementStart(11, "td", 27);
|
|
110
|
+
i0.ɵɵconditionalCreate(12, WorkQueuePartitionsComponent_Conditional_19_For_15_Conditional_12_Template, 6, 2);
|
|
111
|
+
i0.ɵɵelementEnd()();
|
|
112
|
+
} if (rf & 2) {
|
|
113
|
+
const row_r5 = ctx.$implicit;
|
|
114
|
+
const ctx_r3 = i0.ɵɵnextContext(2);
|
|
115
|
+
i0.ɵɵclassProp("wq-row-blocked", row_r5.Condition === "Blocked");
|
|
116
|
+
i0.ɵɵadvance(2);
|
|
117
|
+
i0.ɵɵtextInterpolate(row_r5.PartitionKey);
|
|
118
|
+
i0.ɵɵadvance(2);
|
|
119
|
+
i0.ɵɵproperty("ngClass", ctx_r3.ConditionClass(row_r5.Condition));
|
|
120
|
+
i0.ɵɵadvance();
|
|
121
|
+
i0.ɵɵtextInterpolate(row_r5.Condition);
|
|
122
|
+
i0.ɵɵadvance(2);
|
|
123
|
+
i0.ɵɵconditional(row_r5.HeadDeliveryID ? 7 : 8);
|
|
124
|
+
i0.ɵɵadvance(3);
|
|
125
|
+
i0.ɵɵtextInterpolate(row_r5.WaitingItems);
|
|
126
|
+
i0.ɵɵadvance(2);
|
|
127
|
+
i0.ɵɵconditional(row_r5.Condition === "Blocked" && row_r5.HeadDeliveryID ? 12 : -1);
|
|
128
|
+
} }
|
|
129
|
+
function WorkQueuePartitionsComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
|
|
130
|
+
i0.ɵɵelementStart(0, "table", 19)(1, "thead")(2, "tr")(3, "th");
|
|
131
|
+
i0.ɵɵtext(4, "Partition key");
|
|
132
|
+
i0.ɵɵelementEnd();
|
|
133
|
+
i0.ɵɵelementStart(5, "th");
|
|
134
|
+
i0.ɵɵtext(6, "Condition");
|
|
135
|
+
i0.ɵɵelementEnd();
|
|
136
|
+
i0.ɵɵelementStart(7, "th");
|
|
137
|
+
i0.ɵɵtext(8, "Head delivery");
|
|
138
|
+
i0.ɵɵelementEnd();
|
|
139
|
+
i0.ɵɵelementStart(9, "th", 20);
|
|
140
|
+
i0.ɵɵtext(10, "Waiting");
|
|
141
|
+
i0.ɵɵelementEnd();
|
|
142
|
+
i0.ɵɵelementStart(11, "th", 20);
|
|
143
|
+
i0.ɵɵtext(12, "Actions");
|
|
144
|
+
i0.ɵɵelementEnd()()();
|
|
145
|
+
i0.ɵɵelementStart(13, "tbody");
|
|
146
|
+
i0.ɵɵrepeaterCreate(14, WorkQueuePartitionsComponent_Conditional_19_For_15_Template, 13, 8, "tr", 21, _forTrack1);
|
|
147
|
+
i0.ɵɵelementEnd()();
|
|
148
|
+
i0.ɵɵelementStart(16, "p", 22);
|
|
149
|
+
i0.ɵɵtext(17, "Blocked = the head of the key is dead-lettered, so everything behind it waits. Replaying or discarding the head releases the key.");
|
|
150
|
+
i0.ɵɵelementEnd();
|
|
151
|
+
} if (rf & 2) {
|
|
152
|
+
const ctx_r3 = i0.ɵɵnextContext();
|
|
153
|
+
i0.ɵɵadvance(14);
|
|
154
|
+
i0.ɵɵrepeater(ctx_r3.Rows);
|
|
155
|
+
} }
|
|
156
|
+
/**
|
|
157
|
+
* Partition-key state for one Ordered subscription: which keys are Blocked (a dead-lettered head holds the key),
|
|
158
|
+
* InFlight or Idle, and how much waits behind each head. Replay / discard act on the blocking head delivery.
|
|
159
|
+
*/
|
|
160
|
+
export class WorkQueuePartitionsComponent {
|
|
161
|
+
operator;
|
|
162
|
+
cdr;
|
|
163
|
+
Provider;
|
|
164
|
+
Subscriptions = [];
|
|
165
|
+
SelectedSubscription = null;
|
|
166
|
+
Condition = null;
|
|
167
|
+
CanOperate = false;
|
|
168
|
+
SelectedSubscriptionChange = new EventEmitter();
|
|
169
|
+
ConditionChange = new EventEmitter();
|
|
170
|
+
Changed = new EventEmitter();
|
|
171
|
+
Loaded = new EventEmitter();
|
|
172
|
+
Conditions = WORK_QUEUE_PARTITION_CONDITIONS;
|
|
173
|
+
Rows = [];
|
|
174
|
+
Supported = true;
|
|
175
|
+
IsLoading = false;
|
|
176
|
+
LoadError = null;
|
|
177
|
+
PendingHead = null;
|
|
178
|
+
ConfirmReplayVisible = false;
|
|
179
|
+
DiscardVisible = false;
|
|
180
|
+
ActionInProgress = false;
|
|
181
|
+
LastOutcome = null;
|
|
182
|
+
constructor(operator, cdr) {
|
|
183
|
+
this.operator = operator;
|
|
184
|
+
this.cdr = cdr;
|
|
185
|
+
}
|
|
186
|
+
ngOnChanges(changes) {
|
|
187
|
+
if (changes['SelectedSubscription'] || changes['Condition'] || changes['Provider']) {
|
|
188
|
+
void this.Refresh();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/** Only Ordered subscriptions have partitions; the picker lists just those. */
|
|
192
|
+
get OrderedSubscriptions() {
|
|
193
|
+
return this.Subscriptions.filter((s) => s.PartitionMode === 'Ordered');
|
|
194
|
+
}
|
|
195
|
+
get BlockedCount() {
|
|
196
|
+
return this.Rows.filter((r) => r.Condition === 'Blocked').length;
|
|
197
|
+
}
|
|
198
|
+
OnSubscriptionChange(name) {
|
|
199
|
+
this.SelectedSubscriptionChange.emit(name === '' ? null : name);
|
|
200
|
+
}
|
|
201
|
+
ToggleCondition(condition) {
|
|
202
|
+
this.ConditionChange.emit(this.Condition === condition ? null : condition);
|
|
203
|
+
}
|
|
204
|
+
async Refresh() {
|
|
205
|
+
this.LastOutcome = null;
|
|
206
|
+
if (!this.SelectedSubscription || !this.Provider) {
|
|
207
|
+
this.Rows = [];
|
|
208
|
+
this.emitLoaded();
|
|
209
|
+
this.cdr.markForCheck();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
this.IsLoading = true;
|
|
213
|
+
this.LoadError = null;
|
|
214
|
+
this.cdr.markForCheck();
|
|
215
|
+
try {
|
|
216
|
+
const output = await this.operator.ListPartitions(this.Provider, this.SelectedSubscription, this.Condition ?? undefined);
|
|
217
|
+
this.Supported = output.supported;
|
|
218
|
+
this.Rows = output.items;
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
this.Rows = [];
|
|
222
|
+
this.LoadError = error instanceof Error ? error.message : String(error);
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
this.IsLoading = false;
|
|
226
|
+
this.emitLoaded();
|
|
227
|
+
this.cdr.markForCheck();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
ConditionClass(condition) {
|
|
231
|
+
switch (condition) {
|
|
232
|
+
case 'Blocked': return 'wq-chip-error';
|
|
233
|
+
case 'InFlight': return 'wq-chip-info';
|
|
234
|
+
default: return 'wq-chip-neutral';
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
RequestReplay(row, event) {
|
|
238
|
+
event.stopPropagation();
|
|
239
|
+
if (row.HeadDeliveryID && this.CanOperate) {
|
|
240
|
+
this.PendingHead = row;
|
|
241
|
+
this.ConfirmReplayVisible = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
RequestDiscard(row, event) {
|
|
245
|
+
event.stopPropagation();
|
|
246
|
+
if (row.HeadDeliveryID && this.CanOperate) {
|
|
247
|
+
this.PendingHead = row;
|
|
248
|
+
this.DiscardVisible = true;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
get DiscardMessage() {
|
|
252
|
+
const head = this.PendingHead;
|
|
253
|
+
if (!head)
|
|
254
|
+
return '';
|
|
255
|
+
return `The head delivery of key "${head.PartitionKey}" will be discarded permanently, releasing the ${head.WaitingItems} item${head.WaitingItems === 1 ? '' : 's'} waiting behind it.`;
|
|
256
|
+
}
|
|
257
|
+
async ReplayHead() {
|
|
258
|
+
this.ConfirmReplayVisible = false;
|
|
259
|
+
const head = this.PendingHead;
|
|
260
|
+
if (!head?.HeadDeliveryID)
|
|
261
|
+
return;
|
|
262
|
+
await this.runAction(() => this.operator.Replay(this.Provider, this.SelectedSubscription ?? '', head.HeadDeliveryID ?? '', `Replayed head of key ${head.PartitionKey} from the Work Queue dashboard`)
|
|
263
|
+
.then((r) => (r.supported ? (r.replayed ? `Replayed the head of key "${head.PartitionKey}".` : 'Nothing replayed (the head was already resolved).') : 'Replay is not supported on this transport.')));
|
|
264
|
+
}
|
|
265
|
+
async DiscardHead(reason) {
|
|
266
|
+
const head = this.PendingHead;
|
|
267
|
+
if (!head?.HeadDeliveryID)
|
|
268
|
+
return;
|
|
269
|
+
await this.runAction(() => this.operator.Discard(this.Provider, this.SelectedSubscription ?? '', head.HeadDeliveryID ?? '', reason)
|
|
270
|
+
.then((r) => (r.supported ? (r.discarded ? `Discarded the head of key "${head.PartitionKey}".` : 'Nothing discarded (the head was already resolved).') : 'Discard is not supported on this transport.')));
|
|
271
|
+
this.DiscardVisible = false;
|
|
272
|
+
this.cdr.markForCheck();
|
|
273
|
+
}
|
|
274
|
+
async runAction(action) {
|
|
275
|
+
this.ActionInProgress = true;
|
|
276
|
+
this.cdr.markForCheck();
|
|
277
|
+
let outcome;
|
|
278
|
+
try {
|
|
279
|
+
outcome = { Ok: true, Message: await action() };
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
outcome = { Ok: false, Message: error instanceof Error ? error.message : String(error) };
|
|
283
|
+
}
|
|
284
|
+
this.ActionInProgress = false;
|
|
285
|
+
this.PendingHead = null;
|
|
286
|
+
await this.Refresh();
|
|
287
|
+
this.LastOutcome = outcome;
|
|
288
|
+
if (outcome.Ok)
|
|
289
|
+
this.Changed.emit();
|
|
290
|
+
this.cdr.markForCheck();
|
|
291
|
+
}
|
|
292
|
+
emitLoaded() {
|
|
293
|
+
this.Loaded.emit({ Count: this.Rows.length, Blocked: this.BlockedCount });
|
|
294
|
+
}
|
|
295
|
+
static ɵfac = function WorkQueuePartitionsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || WorkQueuePartitionsComponent)(i0.ɵɵdirectiveInject(i1.WorkQueueOperatorService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
|
|
296
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: WorkQueuePartitionsComponent, selectors: [["mj-work-queue-partitions"]], inputs: { Provider: "Provider", Subscriptions: "Subscriptions", SelectedSubscription: "SelectedSubscription", Condition: "Condition", CanOperate: "CanOperate" }, outputs: { SelectedSubscriptionChange: "SelectedSubscriptionChange", ConditionChange: "ConditionChange", Changed: "Changed", Loaded: "Loaded" }, standalone: false, features: [i0.ɵɵNgOnChangesFeature], decls: 22, vars: 8, consts: [[1, "wq-panel"], [1, "wq-picker-row"], ["for", "wq-pt-subscription", 1, "wq-label"], ["id", "wq-pt-subscription", 1, "wq-select", 3, "ngModelChange", "ngModel"], ["value", ""], [3, "value"], [1, "wq-chips"], [3, "Label", "Active"], ["Size", "sm", 3, "Variant", "Message"], ["Icon", "fa-solid fa-list-ol", "Title", "No Ordered subscriptions", "Message", "Partition state only exists for subscriptions with PartitionMode = Ordered."], ["Icon", "fa-solid fa-list-ol", "Title", "Pick a subscription", "Message", "Partition keys are listed per Ordered subscription."], [1, "wq-loading"], ["Variant", "error", "Title", "Could not list partitions", 3, "Message"], ["Variant", "info", "Title", "Not supported", "Message", "This transport does not expose partition state to MemberJunction."], ["Variant", "empty", "Icon", "fa-solid fa-circle-check", "Title", "No partitions", 3, "Message"], ["Title", "Replay blocked head", "Type", "warning", "ConfirmText", "Replay", "Icon", "fa-solid fa-rotate-left", "DetailMessage", "If it succeeds, the items waiting behind it run in order. If it fails again it returns to the dead-letter set.", 3, "Confirmed", "Cancelled", "Visible", "Message"], ["Title", "Discard blocked head", 3, "VisibleChange", "Confirmed", "Visible", "Message", "Busy"], [3, "Clicked", "Label", "Active"], ["text", "Loading partitions...", "size", "medium"], [1, "wq-table"], [1, "wq-num"], [3, "wq-row-blocked"], [1, "wq-footnote"], [1, "wq-key"], [1, "wq-chip", 3, "ngClass"], [1, "wq-id"], [1, "wq-muted"], [1, "wq-num", "wq-actions"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Replay the dead-lettered head", 3, "click", "disabled"], [1, "fa-solid", "fa-rotate-left"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Discard the dead-lettered head and release the key", 3, "click", "disabled"], [1, "fa-solid", "fa-trash"]], template: function WorkQueuePartitionsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
297
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "label", 2);
|
|
298
|
+
i0.ɵɵtext(3, "Ordered subscription");
|
|
299
|
+
i0.ɵɵelementEnd();
|
|
300
|
+
i0.ɵɵelementStart(4, "select", 3);
|
|
301
|
+
i0.ɵɵlistener("ngModelChange", function WorkQueuePartitionsComponent_Template_select_ngModelChange_4_listener($event) { return ctx.OnSubscriptionChange($event); });
|
|
302
|
+
i0.ɵɵelementStart(5, "option", 4);
|
|
303
|
+
i0.ɵɵtext(6, "Choose a subscription\u2026");
|
|
304
|
+
i0.ɵɵelementEnd();
|
|
305
|
+
i0.ɵɵrepeaterCreate(7, WorkQueuePartitionsComponent_For_8_Template, 2, 4, "option", 5, _forTrack0);
|
|
306
|
+
i0.ɵɵelementEnd();
|
|
307
|
+
i0.ɵɵelementStart(9, "div", 6);
|
|
308
|
+
i0.ɵɵrepeaterCreate(10, WorkQueuePartitionsComponent_For_11_Template, 1, 2, "mj-filter-chip", 7, i0.ɵɵrepeaterTrackByIdentity);
|
|
309
|
+
i0.ɵɵelementEnd()();
|
|
310
|
+
i0.ɵɵconditionalCreate(12, WorkQueuePartitionsComponent_Conditional_12_Template, 1, 2, "mj-alert", 8);
|
|
311
|
+
i0.ɵɵconditionalCreate(13, WorkQueuePartitionsComponent_Conditional_13_Template, 1, 0, "mj-empty-state", 9)(14, WorkQueuePartitionsComponent_Conditional_14_Template, 1, 0, "mj-empty-state", 10)(15, WorkQueuePartitionsComponent_Conditional_15_Template, 2, 0, "div", 11)(16, WorkQueuePartitionsComponent_Conditional_16_Template, 1, 1, "mj-alert", 12)(17, WorkQueuePartitionsComponent_Conditional_17_Template, 1, 0, "mj-alert", 13)(18, WorkQueuePartitionsComponent_Conditional_18_Template, 1, 1, "mj-empty-state", 14)(19, WorkQueuePartitionsComponent_Conditional_19_Template, 18, 0);
|
|
312
|
+
i0.ɵɵelementEnd();
|
|
313
|
+
i0.ɵɵelementStart(20, "mj-confirm-dialog", 15);
|
|
314
|
+
i0.ɵɵlistener("Confirmed", function WorkQueuePartitionsComponent_Template_mj_confirm_dialog_Confirmed_20_listener() { return ctx.ReplayHead(); })("Cancelled", function WorkQueuePartitionsComponent_Template_mj_confirm_dialog_Cancelled_20_listener() { ctx.ConfirmReplayVisible = false; return ctx.PendingHead = null; });
|
|
315
|
+
i0.ɵɵelementEnd();
|
|
316
|
+
i0.ɵɵelementStart(21, "mj-work-queue-discard-dialog", 16);
|
|
317
|
+
i0.ɵɵlistener("VisibleChange", function WorkQueuePartitionsComponent_Template_mj_work_queue_discard_dialog_VisibleChange_21_listener($event) { ctx.DiscardVisible = $event; return ctx.PendingHead = $event ? ctx.PendingHead : null; })("Confirmed", function WorkQueuePartitionsComponent_Template_mj_work_queue_discard_dialog_Confirmed_21_listener($event) { return ctx.DiscardHead($event); });
|
|
318
|
+
i0.ɵɵelementEnd();
|
|
319
|
+
} if (rf & 2) {
|
|
320
|
+
i0.ɵɵadvance(4);
|
|
321
|
+
i0.ɵɵproperty("ngModel", ctx.SelectedSubscription ?? "");
|
|
322
|
+
i0.ɵɵadvance(3);
|
|
323
|
+
i0.ɵɵrepeater(ctx.OrderedSubscriptions);
|
|
324
|
+
i0.ɵɵadvance(3);
|
|
325
|
+
i0.ɵɵrepeater(ctx.Conditions);
|
|
326
|
+
i0.ɵɵadvance(2);
|
|
327
|
+
i0.ɵɵconditional(ctx.LastOutcome ? 12 : -1);
|
|
328
|
+
i0.ɵɵadvance();
|
|
329
|
+
i0.ɵɵconditional(ctx.OrderedSubscriptions.length === 0 ? 13 : !ctx.SelectedSubscription ? 14 : ctx.IsLoading ? 15 : ctx.LoadError ? 16 : !ctx.Supported ? 17 : ctx.Rows.length === 0 ? 18 : 19);
|
|
330
|
+
i0.ɵɵadvance(7);
|
|
331
|
+
i0.ɵɵproperty("Visible", ctx.ConfirmReplayVisible)("Message", "The head delivery of key \"" + ((ctx.PendingHead == null ? null : ctx.PendingHead.PartitionKey) ?? "") + "\" will be queued again.");
|
|
332
|
+
i0.ɵɵadvance();
|
|
333
|
+
i0.ɵɵproperty("Visible", ctx.DiscardVisible)("Message", ctx.DiscardMessage)("Busy", ctx.ActionInProgress);
|
|
334
|
+
} }, dependencies: [i2.NgClass, i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJAlertComponent, i4.MJButtonDirective, i4.MJConfirmDialogComponent, i4.MJEmptyStateComponent, i4.MJFilterChipComponent, i5.LoadingComponent, i6.WorkQueueDiscardDialogComponent], styles: [".wq-panel[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.wq-picker-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.wq-label[_ngcontent-%COMP%] {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-select[_ngcontent-%COMP%] {\n min-width: 320px;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.wq-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}\n\n.wq-chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.wq-loading[_ngcontent-%COMP%] {\n padding: 40px 0;\n}\n\n.wq-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.wq-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n text-align: left;\n padding: 8px 12px;\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.wq-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: middle;\n}\n\n.wq-row-blocked[_ngcontent-%COMP%] td[_ngcontent-%COMP%]:first-child {\n box-shadow: inset 3px 0 0 var(--mj-status-error);\n}\n\n.wq-key[_ngcontent-%COMP%] {\n font-family: var(--mj-font-family-mono);\n font-size: 0.8rem;\n}\n\n.wq-id[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-num[_ngcontent-%COMP%] {\n text-align: right;\n white-space: nowrap;\n}\n\n.wq-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n}\n\n.wq-muted[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.wq-chip[_ngcontent-%COMP%] {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.wq-chip-neutral[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.wq-chip-info[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info-text);\n}\n\n.wq-chip-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 14%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n}\n\n.wq-footnote[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 800px) {\n .wq-select[_ngcontent-%COMP%] {\n min-width: 0;\n width: 100%;\n }\n}"], changeDetection: 0 });
|
|
335
|
+
}
|
|
336
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WorkQueuePartitionsComponent, [{
|
|
337
|
+
type: Component,
|
|
338
|
+
args: [{ standalone: false, selector: 'mj-work-queue-partitions', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"wq-panel\">\n <div class=\"wq-picker-row\">\n <label class=\"wq-label\" for=\"wq-pt-subscription\">Ordered subscription</label>\n <select id=\"wq-pt-subscription\" class=\"wq-select\" [ngModel]=\"SelectedSubscription ?? ''\" (ngModelChange)=\"OnSubscriptionChange($event)\">\n <option value=\"\">Choose a subscription\u2026</option>\n @for (s of OrderedSubscriptions; track s.ID) {\n <option [value]=\"s.Name\">{{ s.Name }} \u2014 {{ s.Topic }} ({{ s.Transport }})</option>\n }\n </select>\n <div class=\"wq-chips\">\n @for (c of Conditions; track c) {\n <mj-filter-chip [Label]=\"c\" [Active]=\"Condition === c\" (Clicked)=\"ToggleCondition(c)\"></mj-filter-chip>\n }\n </div>\n </div>\n\n @if (LastOutcome) {\n <mj-alert [Variant]=\"LastOutcome.Ok ? 'success' : 'error'\" Size=\"sm\" [Message]=\"LastOutcome.Message\"></mj-alert>\n }\n\n @if (OrderedSubscriptions.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-list-ol\" Title=\"No Ordered subscriptions\" Message=\"Partition state only exists for subscriptions with PartitionMode = Ordered.\" />\n } @else if (!SelectedSubscription) {\n <mj-empty-state Icon=\"fa-solid fa-list-ol\" Title=\"Pick a subscription\" Message=\"Partition keys are listed per Ordered subscription.\" />\n } @else if (IsLoading) {\n <div class=\"wq-loading\"><mj-loading text=\"Loading partitions...\" size=\"medium\"></mj-loading></div>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" Title=\"Could not list partitions\" [Message]=\"LoadError\"></mj-alert>\n } @else if (!Supported) {\n <mj-alert Variant=\"info\" Title=\"Not supported\" Message=\"This transport does not expose partition state to MemberJunction.\"></mj-alert>\n } @else if (Rows.length === 0) {\n <mj-empty-state Variant=\"empty\" Icon=\"fa-solid fa-circle-check\" Title=\"No partitions\" [Message]=\"Condition ? 'No keys are currently ' + Condition + '.' : 'No partition keys have open work on this subscription.'\" />\n } @else {\n <table class=\"wq-table\">\n <thead>\n <tr>\n <th>Partition key</th>\n <th>Condition</th>\n <th>Head delivery</th>\n <th class=\"wq-num\">Waiting</th>\n <th class=\"wq-num\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of Rows; track row.PartitionKey) {\n <tr [class.wq-row-blocked]=\"row.Condition === 'Blocked'\">\n <td class=\"wq-key\">{{ row.PartitionKey }}</td>\n <td><span class=\"wq-chip\" [ngClass]=\"ConditionClass(row.Condition)\">{{ row.Condition }}</span></td>\n <td>@if (row.HeadDeliveryID) { <code class=\"wq-id\">{{ row.HeadDeliveryID }}</code> } @else { <span class=\"wq-muted\">\u2014</span> }</td>\n <td class=\"wq-num\">{{ row.WaitingItems }}</td>\n <td class=\"wq-num wq-actions\">\n @if (row.Condition === 'Blocked' && row.HeadDeliveryID) {\n <button mjButton variant=\"outline\" size=\"sm\" [disabled]=\"!CanOperate || ActionInProgress\" title=\"Replay the dead-lettered head\" (click)=\"RequestReplay(row, $event)\">\n <i class=\"fa-solid fa-rotate-left\"></i> Replay head\n </button>\n <button mjButton variant=\"outline\" size=\"sm\" [disabled]=\"!CanOperate || ActionInProgress\" title=\"Discard the dead-lettered head and release the key\" (click)=\"RequestDiscard(row, $event)\">\n <i class=\"fa-solid fa-trash\"></i> Discard head\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n <p class=\"wq-footnote\">Blocked = the head of the key is dead-lettered, so everything behind it waits. Replaying or discarding the head releases the key.</p>\n }\n</div>\n\n<mj-confirm-dialog [Visible]=\"ConfirmReplayVisible\" Title=\"Replay blocked head\" Type=\"warning\" ConfirmText=\"Replay\" Icon=\"fa-solid fa-rotate-left\"\n [Message]=\"'The head delivery of key "' + (PendingHead?.PartitionKey ?? '') + '" will be queued again.'\"\n DetailMessage=\"If it succeeds, the items waiting behind it run in order. If it fails again it returns to the dead-letter set.\"\n (Confirmed)=\"ReplayHead()\" (Cancelled)=\"ConfirmReplayVisible = false; PendingHead = null\"></mj-confirm-dialog>\n\n<mj-work-queue-discard-dialog [Visible]=\"DiscardVisible\" Title=\"Discard blocked head\" [Message]=\"DiscardMessage\" [Busy]=\"ActionInProgress\"\n (VisibleChange)=\"DiscardVisible = $event; PendingHead = $event ? PendingHead : null\" (Confirmed)=\"DiscardHead($event)\"></mj-work-queue-discard-dialog>\n", styles: [".wq-panel {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.wq-picker-row {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.wq-label {\n font-size: 0.8rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-select {\n min-width: 320px;\n padding: 8px 10px;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n font: inherit;\n}\n\n.wq-select:focus {\n outline: none;\n border-color: var(--mj-border-focus);\n}\n\n.wq-chips {\n display: flex;\n gap: 6px;\n}\n\n.wq-loading {\n padding: 40px 0;\n}\n\n.wq-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.875rem;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 12px;\n overflow: hidden;\n}\n\n.wq-table th {\n text-align: left;\n padding: 8px 12px;\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n color: var(--mj-text-secondary);\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.wq-table td {\n padding: 10px 12px;\n border-bottom: 1px solid var(--mj-border-subtle);\n color: var(--mj-text-primary);\n vertical-align: middle;\n}\n\n.wq-row-blocked td:first-child {\n box-shadow: inset 3px 0 0 var(--mj-status-error);\n}\n\n.wq-key {\n font-family: var(--mj-font-family-mono);\n font-size: 0.8rem;\n}\n\n.wq-id {\n font-size: 0.75rem;\n color: var(--mj-text-secondary);\n}\n\n.wq-num {\n text-align: right;\n white-space: nowrap;\n}\n\n.wq-actions {\n display: flex;\n gap: 6px;\n justify-content: flex-end;\n}\n\n.wq-muted {\n color: var(--mj-text-muted);\n}\n\n.wq-chip {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 999px;\n font-size: 0.7rem;\n font-weight: 600;\n}\n\n.wq-chip-neutral {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.wq-chip-info {\n background: color-mix(in srgb, var(--mj-status-info) 14%, var(--mj-bg-surface));\n color: var(--mj-status-info-text);\n}\n\n.wq-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 14%, var(--mj-bg-surface));\n color: var(--mj-status-error-text);\n}\n\n.wq-footnote {\n margin: 0;\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n@media (max-width: 800px) {\n .wq-select {\n min-width: 0;\n width: 100%;\n }\n}\n"] }]
|
|
339
|
+
}], () => [{ type: i1.WorkQueueOperatorService }, { type: i0.ChangeDetectorRef }], { Provider: [{
|
|
340
|
+
type: Input
|
|
341
|
+
}], Subscriptions: [{
|
|
342
|
+
type: Input
|
|
343
|
+
}], SelectedSubscription: [{
|
|
344
|
+
type: Input
|
|
345
|
+
}], Condition: [{
|
|
346
|
+
type: Input
|
|
347
|
+
}], CanOperate: [{
|
|
348
|
+
type: Input
|
|
349
|
+
}], SelectedSubscriptionChange: [{
|
|
350
|
+
type: Output
|
|
351
|
+
}], ConditionChange: [{
|
|
352
|
+
type: Output
|
|
353
|
+
}], Changed: [{
|
|
354
|
+
type: Output
|
|
355
|
+
}], Loaded: [{
|
|
356
|
+
type: Output
|
|
357
|
+
}] }); })();
|
|
358
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(WorkQueuePartitionsComponent, { className: "WorkQueuePartitionsComponent", filePath: "src/WorkQueue/components/work-queue-partitions.component.ts", lineNumber: 19 }); })();
|
|
359
|
+
//# sourceMappingURL=work-queue-partitions.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-queue-partitions.component.js","sourceRoot":"","sources":["../../../src/WorkQueue/components/work-queue-partitions.component.ts","../../../src/WorkQueue/components/work-queue-partitions.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';\nimport type { IMetadataProvider } from '@memberjunction/core';\nimport type { WorkQueuePartitionStateRow } from '@memberjunction/core-entities';\nimport { WorkQueueOperatorService } from '../services/work-queue-operator.service';\nimport { WORK_QUEUE_PARTITION_CONDITIONS, WorkQueuePartitionCondition } from '../work-queue-agent-context';\nimport type { WorkQueueSubscriptionOption } from '../work-queue-types';\n\n/**\n * Partition-key state for one Ordered subscription: which keys are Blocked (a dead-lettered head holds the key),\n * InFlight or Idle, and how much waits behind each head. Replay / discard act on the blocking head delivery.\n */\n@Component({\n standalone: false,\n selector: 'mj-work-queue-partitions',\n templateUrl: './work-queue-partitions.component.html',\n styleUrls: ['./work-queue-partitions.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class WorkQueuePartitionsComponent implements OnChanges {\n @Input() Provider!: IMetadataProvider;\n @Input() Subscriptions: WorkQueueSubscriptionOption[] = [];\n @Input() SelectedSubscription: string | null = null;\n @Input() Condition: WorkQueuePartitionCondition | null = null;\n @Input() CanOperate = false;\n @Output() SelectedSubscriptionChange = new EventEmitter<string | null>();\n @Output() ConditionChange = new EventEmitter<WorkQueuePartitionCondition | null>();\n @Output() Changed = new EventEmitter<void>();\n @Output() Loaded = new EventEmitter<{ Count: number; Blocked: number }>();\n\n public readonly Conditions = WORK_QUEUE_PARTITION_CONDITIONS;\n public Rows: WorkQueuePartitionStateRow[] = [];\n public Supported = true;\n public IsLoading = false;\n public LoadError: string | null = null;\n public PendingHead: WorkQueuePartitionStateRow | null = null;\n public ConfirmReplayVisible = false;\n public DiscardVisible = false;\n public ActionInProgress = false;\n public LastOutcome: { Ok: boolean; Message: string } | null = null;\n\n constructor(private readonly operator: WorkQueueOperatorService, private readonly cdr: ChangeDetectorRef) {}\n\n public ngOnChanges(changes: SimpleChanges): void {\n if (changes['SelectedSubscription'] || changes['Condition'] || changes['Provider']) {\n void this.Refresh();\n }\n }\n\n /** Only Ordered subscriptions have partitions; the picker lists just those. */\n public get OrderedSubscriptions(): WorkQueueSubscriptionOption[] {\n return this.Subscriptions.filter((s) => s.PartitionMode === 'Ordered');\n }\n\n public get BlockedCount(): number {\n return this.Rows.filter((r) => r.Condition === 'Blocked').length;\n }\n\n public OnSubscriptionChange(name: string): void {\n this.SelectedSubscriptionChange.emit(name === '' ? null : name);\n }\n\n public ToggleCondition(condition: WorkQueuePartitionCondition): void {\n this.ConditionChange.emit(this.Condition === condition ? null : condition);\n }\n\n public async Refresh(): Promise<void> {\n this.LastOutcome = null;\n if (!this.SelectedSubscription || !this.Provider) {\n this.Rows = [];\n this.emitLoaded();\n this.cdr.markForCheck();\n return;\n }\n this.IsLoading = true;\n this.LoadError = null;\n this.cdr.markForCheck();\n try {\n const output = await this.operator.ListPartitions(this.Provider, this.SelectedSubscription, this.Condition ?? undefined);\n this.Supported = output.supported;\n this.Rows = output.items;\n } catch (error) {\n this.Rows = [];\n this.LoadError = error instanceof Error ? error.message : String(error);\n } finally {\n this.IsLoading = false;\n this.emitLoaded();\n this.cdr.markForCheck();\n }\n }\n\n public ConditionClass(condition: WorkQueuePartitionStateRow['Condition']): string {\n switch (condition) {\n case 'Blocked': return 'wq-chip-error';\n case 'InFlight': return 'wq-chip-info';\n default: return 'wq-chip-neutral';\n }\n }\n\n public RequestReplay(row: WorkQueuePartitionStateRow, event: Event): void {\n event.stopPropagation();\n if (row.HeadDeliveryID && this.CanOperate) {\n this.PendingHead = row;\n this.ConfirmReplayVisible = true;\n }\n }\n\n public RequestDiscard(row: WorkQueuePartitionStateRow, event: Event): void {\n event.stopPropagation();\n if (row.HeadDeliveryID && this.CanOperate) {\n this.PendingHead = row;\n this.DiscardVisible = true;\n }\n }\n\n public get DiscardMessage(): string {\n const head = this.PendingHead;\n if (!head) return '';\n return `The head delivery of key \"${head.PartitionKey}\" will be discarded permanently, releasing the ${head.WaitingItems} item${head.WaitingItems === 1 ? '' : 's'} waiting behind it.`;\n }\n\n public async ReplayHead(): Promise<void> {\n this.ConfirmReplayVisible = false;\n const head = this.PendingHead;\n if (!head?.HeadDeliveryID) return;\n await this.runAction(() => this.operator.Replay(this.Provider, this.SelectedSubscription ?? '', head.HeadDeliveryID ?? '', `Replayed head of key ${head.PartitionKey} from the Work Queue dashboard`)\n .then((r) => (r.supported ? (r.replayed ? `Replayed the head of key \"${head.PartitionKey}\".` : 'Nothing replayed (the head was already resolved).') : 'Replay is not supported on this transport.')));\n }\n\n public async DiscardHead(reason: string): Promise<void> {\n const head = this.PendingHead;\n if (!head?.HeadDeliveryID) return;\n await this.runAction(() => this.operator.Discard(this.Provider, this.SelectedSubscription ?? '', head.HeadDeliveryID ?? '', reason)\n .then((r) => (r.supported ? (r.discarded ? `Discarded the head of key \"${head.PartitionKey}\".` : 'Nothing discarded (the head was already resolved).') : 'Discard is not supported on this transport.')));\n this.DiscardVisible = false;\n this.cdr.markForCheck();\n }\n\n private async runAction(action: () => Promise<string>): Promise<void> {\n this.ActionInProgress = true;\n this.cdr.markForCheck();\n let outcome: { Ok: boolean; Message: string };\n try {\n outcome = { Ok: true, Message: await action() };\n } catch (error) {\n outcome = { Ok: false, Message: error instanceof Error ? error.message : String(error) };\n }\n this.ActionInProgress = false;\n this.PendingHead = null;\n await this.Refresh();\n this.LastOutcome = outcome;\n if (outcome.Ok) this.Changed.emit();\n this.cdr.markForCheck();\n }\n\n private emitLoaded(): void {\n this.Loaded.emit({ Count: this.Rows.length, Blocked: this.BlockedCount });\n }\n}\n","<div class=\"wq-panel\">\n <div class=\"wq-picker-row\">\n <label class=\"wq-label\" for=\"wq-pt-subscription\">Ordered subscription</label>\n <select id=\"wq-pt-subscription\" class=\"wq-select\" [ngModel]=\"SelectedSubscription ?? ''\" (ngModelChange)=\"OnSubscriptionChange($event)\">\n <option value=\"\">Choose a subscription…</option>\n @for (s of OrderedSubscriptions; track s.ID) {\n <option [value]=\"s.Name\">{{ s.Name }} — {{ s.Topic }} ({{ s.Transport }})</option>\n }\n </select>\n <div class=\"wq-chips\">\n @for (c of Conditions; track c) {\n <mj-filter-chip [Label]=\"c\" [Active]=\"Condition === c\" (Clicked)=\"ToggleCondition(c)\"></mj-filter-chip>\n }\n </div>\n </div>\n\n @if (LastOutcome) {\n <mj-alert [Variant]=\"LastOutcome.Ok ? 'success' : 'error'\" Size=\"sm\" [Message]=\"LastOutcome.Message\"></mj-alert>\n }\n\n @if (OrderedSubscriptions.length === 0) {\n <mj-empty-state Icon=\"fa-solid fa-list-ol\" Title=\"No Ordered subscriptions\" Message=\"Partition state only exists for subscriptions with PartitionMode = Ordered.\" />\n } @else if (!SelectedSubscription) {\n <mj-empty-state Icon=\"fa-solid fa-list-ol\" Title=\"Pick a subscription\" Message=\"Partition keys are listed per Ordered subscription.\" />\n } @else if (IsLoading) {\n <div class=\"wq-loading\"><mj-loading text=\"Loading partitions...\" size=\"medium\"></mj-loading></div>\n } @else if (LoadError) {\n <mj-alert Variant=\"error\" Title=\"Could not list partitions\" [Message]=\"LoadError\"></mj-alert>\n } @else if (!Supported) {\n <mj-alert Variant=\"info\" Title=\"Not supported\" Message=\"This transport does not expose partition state to MemberJunction.\"></mj-alert>\n } @else if (Rows.length === 0) {\n <mj-empty-state Variant=\"empty\" Icon=\"fa-solid fa-circle-check\" Title=\"No partitions\" [Message]=\"Condition ? 'No keys are currently ' + Condition + '.' : 'No partition keys have open work on this subscription.'\" />\n } @else {\n <table class=\"wq-table\">\n <thead>\n <tr>\n <th>Partition key</th>\n <th>Condition</th>\n <th>Head delivery</th>\n <th class=\"wq-num\">Waiting</th>\n <th class=\"wq-num\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (row of Rows; track row.PartitionKey) {\n <tr [class.wq-row-blocked]=\"row.Condition === 'Blocked'\">\n <td class=\"wq-key\">{{ row.PartitionKey }}</td>\n <td><span class=\"wq-chip\" [ngClass]=\"ConditionClass(row.Condition)\">{{ row.Condition }}</span></td>\n <td>@if (row.HeadDeliveryID) { <code class=\"wq-id\">{{ row.HeadDeliveryID }}</code> } @else { <span class=\"wq-muted\">—</span> }</td>\n <td class=\"wq-num\">{{ row.WaitingItems }}</td>\n <td class=\"wq-num wq-actions\">\n @if (row.Condition === 'Blocked' && row.HeadDeliveryID) {\n <button mjButton variant=\"outline\" size=\"sm\" [disabled]=\"!CanOperate || ActionInProgress\" title=\"Replay the dead-lettered head\" (click)=\"RequestReplay(row, $event)\">\n <i class=\"fa-solid fa-rotate-left\"></i> Replay head\n </button>\n <button mjButton variant=\"outline\" size=\"sm\" [disabled]=\"!CanOperate || ActionInProgress\" title=\"Discard the dead-lettered head and release the key\" (click)=\"RequestDiscard(row, $event)\">\n <i class=\"fa-solid fa-trash\"></i> Discard head\n </button>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n <p class=\"wq-footnote\">Blocked = the head of the key is dead-lettered, so everything behind it waits. Replaying or discarding the head releases the key.</p>\n }\n</div>\n\n<mj-confirm-dialog [Visible]=\"ConfirmReplayVisible\" Title=\"Replay blocked head\" Type=\"warning\" ConfirmText=\"Replay\" Icon=\"fa-solid fa-rotate-left\"\n [Message]=\"'The head delivery of key "' + (PendingHead?.PartitionKey ?? '') + '" will be queued again.'\"\n DetailMessage=\"If it succeeds, the items waiting behind it run in order. If it fails again it returns to the dead-letter set.\"\n (Confirmed)=\"ReplayHead()\" (Cancelled)=\"ConfirmReplayVisible = false; PendingHead = null\"></mj-confirm-dialog>\n\n<mj-work-queue-discard-dialog [Visible]=\"DiscardVisible\" Title=\"Discard blocked head\" [Message]=\"DiscardMessage\" [Busy]=\"ActionInProgress\"\n (VisibleChange)=\"DiscardVisible = $event; PendingHead = $event ? PendingHead : null\" (Confirmed)=\"DiscardHead($event)\"></mj-work-queue-discard-dialog>\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { IMetadataProvider } from '@memberjunction/core';
|
|
2
|
+
import { type WorkQueueDiscardDeliveryOutput, type WorkQueueGetBacklogOutput, type WorkQueueGetSubscriptionStatsOutput, type WorkQueueListDeadLettersOutput, type WorkQueueListPartitionsOutput, type WorkQueueReplayDeadLetterOutput, type WorkQueueValidateBindingsOutput } from '@memberjunction/core-entities';
|
|
3
|
+
import type { WorkQueuePartitionCondition } from '../work-queue-agent-context';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Thin, provider-scoped wrapper over the seven WorkQueue.* Remote Operations (03 §8). Every call takes the
|
|
7
|
+
* caller's provider so the dashboard stays multi-provider safe; a failed operation throws an Error carrying the
|
|
8
|
+
* ResultCode (FORBIDDEN, EXECUTION_ERROR, …) and the server's message.
|
|
9
|
+
*/
|
|
10
|
+
export declare class WorkQueueOperatorService {
|
|
11
|
+
GetStats(provider: IMetadataProvider, subscriptionName?: string): Promise<WorkQueueGetSubscriptionStatsOutput>;
|
|
12
|
+
ListDeadLetters(provider: IMetadataProvider, subscriptionName: string, pageSize?: number, cursor?: string): Promise<WorkQueueListDeadLettersOutput>;
|
|
13
|
+
ListPartitions(provider: IMetadataProvider, subscriptionName: string, condition?: WorkQueuePartitionCondition, pageSize?: number, cursor?: string): Promise<WorkQueueListPartitionsOutput>;
|
|
14
|
+
Replay(provider: IMetadataProvider, subscriptionName: string, deliveryID: string, note?: string): Promise<WorkQueueReplayDeadLetterOutput>;
|
|
15
|
+
Discard(provider: IMetadataProvider, subscriptionName: string, deliveryID: string, reason: string): Promise<WorkQueueDiscardDeliveryOutput>;
|
|
16
|
+
GetBacklog(provider: IMetadataProvider, subscriptionName: string): Promise<WorkQueueGetBacklogOutput>;
|
|
17
|
+
ValidateBindings(provider: IMetadataProvider, transportName?: string): Promise<WorkQueueValidateBindingsOutput>;
|
|
18
|
+
private run;
|
|
19
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<WorkQueueOperatorService, never>;
|
|
20
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<WorkQueueOperatorService>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=work-queue-operator.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-queue-operator.service.d.ts","sourceRoot":"","sources":["../../../src/WorkQueue/services/work-queue-operator.service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAkB,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAIH,KAAK,8BAA8B,EAAE,KAAK,yBAAyB,EAAE,KAAK,mCAAmC,EAC7G,KAAK,8BAA8B,EAAE,KAAK,6BAA6B,EAAE,KAAK,+BAA+B,EAC7G,KAAK,+BAA+B,EACvC,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;;AAE/E;;;;GAIG;AACH,qBACa,wBAAwB;IAC1B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mCAAmC,CAAC;IAI9G,eAAe,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,SAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAIhJ,cAAc,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,2BAA2B,EAAE,QAAQ,SAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAIvL,MAAM,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,+BAA+B,CAAC;IAI1I,OAAO,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAI3I,UAAU,CAAC,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC;IAIrG,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,+BAA+B,CAAC;YAIxG,GAAG;yCA7BR,wBAAwB;6CAAxB,wBAAwB;CAoCpC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { WorkQueueDiscardDeliveryOperation, WorkQueueGetBacklogOperation, WorkQueueGetSubscriptionStatsOperation, WorkQueueListDeadLettersOperation, WorkQueueListPartitionsOperation, WorkQueueReplayDeadLetterOperation, WorkQueueValidateBindingsOperation, } from '@memberjunction/core-entities';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Thin, provider-scoped wrapper over the seven WorkQueue.* Remote Operations (03 §8). Every call takes the
|
|
6
|
+
* caller's provider so the dashboard stays multi-provider safe; a failed operation throws an Error carrying the
|
|
7
|
+
* ResultCode (FORBIDDEN, EXECUTION_ERROR, …) and the server's message.
|
|
8
|
+
*/
|
|
9
|
+
export class WorkQueueOperatorService {
|
|
10
|
+
GetStats(provider, subscriptionName) {
|
|
11
|
+
return this.run(new WorkQueueGetSubscriptionStatsOperation().Execute({ subscriptionName }, { provider }), 'WorkQueue.GetSubscriptionStats');
|
|
12
|
+
}
|
|
13
|
+
ListDeadLetters(provider, subscriptionName, pageSize = 100, cursor) {
|
|
14
|
+
return this.run(new WorkQueueListDeadLettersOperation().Execute({ subscriptionName, pageSize, cursor }, { provider }), 'WorkQueue.ListDeadLetters');
|
|
15
|
+
}
|
|
16
|
+
ListPartitions(provider, subscriptionName, condition, pageSize = 100, cursor) {
|
|
17
|
+
return this.run(new WorkQueueListPartitionsOperation().Execute({ subscriptionName, condition, pageSize, cursor }, { provider }), 'WorkQueue.ListPartitions');
|
|
18
|
+
}
|
|
19
|
+
Replay(provider, subscriptionName, deliveryID, note) {
|
|
20
|
+
return this.run(new WorkQueueReplayDeadLetterOperation().Execute({ subscriptionName, deliveryID, note }, { provider }), 'WorkQueue.ReplayDeadLetter');
|
|
21
|
+
}
|
|
22
|
+
Discard(provider, subscriptionName, deliveryID, reason) {
|
|
23
|
+
return this.run(new WorkQueueDiscardDeliveryOperation().Execute({ subscriptionName, deliveryID, reason }, { provider }), 'WorkQueue.DiscardDelivery');
|
|
24
|
+
}
|
|
25
|
+
GetBacklog(provider, subscriptionName) {
|
|
26
|
+
return this.run(new WorkQueueGetBacklogOperation().Execute({ subscriptionName }, { provider }), 'WorkQueue.GetBacklog');
|
|
27
|
+
}
|
|
28
|
+
ValidateBindings(provider, transportName) {
|
|
29
|
+
return this.run(new WorkQueueValidateBindingsOperation().Execute({ transportName }, { provider }), 'WorkQueue.ValidateBindings');
|
|
30
|
+
}
|
|
31
|
+
async run(pending, key) {
|
|
32
|
+
const result = await pending;
|
|
33
|
+
if (!result.Success || result.Output === undefined) {
|
|
34
|
+
throw new Error(`${key} failed (${result.ResultCode ?? 'UNKNOWN'}): ${result.ErrorMessage ?? 'no details'}`);
|
|
35
|
+
}
|
|
36
|
+
return result.Output;
|
|
37
|
+
}
|
|
38
|
+
static ɵfac = function WorkQueueOperatorService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || WorkQueueOperatorService)(); };
|
|
39
|
+
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: WorkQueueOperatorService, factory: WorkQueueOperatorService.ɵfac });
|
|
40
|
+
}
|
|
41
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(WorkQueueOperatorService, [{
|
|
42
|
+
type: Injectable
|
|
43
|
+
}], null, null); })();
|
|
44
|
+
//# sourceMappingURL=work-queue-operator.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-queue-operator.service.js","sourceRoot":"","sources":["../../../src/WorkQueue/services/work-queue-operator.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EACH,iCAAiC,EAAE,4BAA4B,EAAE,sCAAsC,EACvG,iCAAiC,EAAE,gCAAgC,EAAE,kCAAkC,EACvG,kCAAkC,GAIrC,MAAM,+BAA+B,CAAC;;AAGvC;;;;GAIG;AAEH,MAAM,OAAO,wBAAwB;IAC1B,QAAQ,CAAC,QAA2B,EAAE,gBAAyB;QAClE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,sCAAsC,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,gCAAgC,CAAC,CAAC;IAChJ,CAAC;IAEM,eAAe,CAAC,QAA2B,EAAE,gBAAwB,EAAE,QAAQ,GAAG,GAAG,EAAE,MAAe;QACzG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,iCAAiC,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,2BAA2B,CAAC,CAAC;IACxJ,CAAC;IAEM,cAAc,CAAC,QAA2B,EAAE,gBAAwB,EAAE,SAAuC,EAAE,QAAQ,GAAG,GAAG,EAAE,MAAe;QACjJ,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,gCAAgC,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,0BAA0B,CAAC,CAAC;IACjK,CAAC;IAEM,MAAM,CAAC,QAA2B,EAAE,gBAAwB,EAAE,UAAkB,EAAE,IAAa;QAClG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,kCAAkC,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,4BAA4B,CAAC,CAAC;IAC1J,CAAC;IAEM,OAAO,CAAC,QAA2B,EAAE,gBAAwB,EAAE,UAAkB,EAAE,MAAc;QACpG,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,iCAAiC,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAC1J,CAAC;IAEM,UAAU,CAAC,QAA2B,EAAE,gBAAwB;QACnE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,4BAA4B,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC5H,CAAC;IAEM,gBAAgB,CAAC,QAA2B,EAAE,aAAsB;QACvE,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,kCAAkC,EAAE,CAAC,OAAO,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,4BAA4B,CAAC,CAAC;IACrI,CAAC;IAEO,KAAK,CAAC,GAAG,CAAI,OAAmC,EAAE,GAAW;QACjE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,YAAY,MAAM,CAAC,UAAU,IAAI,SAAS,MAAM,MAAM,CAAC,YAAY,IAAI,YAAY,EAAE,CAAC,CAAC;QACjH,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;kHAnCQ,wBAAwB;gEAAxB,wBAAwB,WAAxB,wBAAwB;;iFAAxB,wBAAwB;cADpC,UAAU","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { IMetadataProvider, RemoteOpResult } from '@memberjunction/core';\nimport {\n WorkQueueDiscardDeliveryOperation, WorkQueueGetBacklogOperation, WorkQueueGetSubscriptionStatsOperation,\n WorkQueueListDeadLettersOperation, WorkQueueListPartitionsOperation, WorkQueueReplayDeadLetterOperation,\n WorkQueueValidateBindingsOperation,\n type WorkQueueDiscardDeliveryOutput, type WorkQueueGetBacklogOutput, type WorkQueueGetSubscriptionStatsOutput,\n type WorkQueueListDeadLettersOutput, type WorkQueueListPartitionsOutput, type WorkQueueReplayDeadLetterOutput,\n type WorkQueueValidateBindingsOutput,\n} from '@memberjunction/core-entities';\nimport type { WorkQueuePartitionCondition } from '../work-queue-agent-context';\n\n/**\n * Thin, provider-scoped wrapper over the seven WorkQueue.* Remote Operations (03 §8). Every call takes the\n * caller's provider so the dashboard stays multi-provider safe; a failed operation throws an Error carrying the\n * ResultCode (FORBIDDEN, EXECUTION_ERROR, …) and the server's message.\n */\n@Injectable()\nexport class WorkQueueOperatorService {\n public GetStats(provider: IMetadataProvider, subscriptionName?: string): Promise<WorkQueueGetSubscriptionStatsOutput> {\n return this.run(new WorkQueueGetSubscriptionStatsOperation().Execute({ subscriptionName }, { provider }), 'WorkQueue.GetSubscriptionStats');\n }\n\n public ListDeadLetters(provider: IMetadataProvider, subscriptionName: string, pageSize = 100, cursor?: string): Promise<WorkQueueListDeadLettersOutput> {\n return this.run(new WorkQueueListDeadLettersOperation().Execute({ subscriptionName, pageSize, cursor }, { provider }), 'WorkQueue.ListDeadLetters');\n }\n\n public ListPartitions(provider: IMetadataProvider, subscriptionName: string, condition?: WorkQueuePartitionCondition, pageSize = 100, cursor?: string): Promise<WorkQueueListPartitionsOutput> {\n return this.run(new WorkQueueListPartitionsOperation().Execute({ subscriptionName, condition, pageSize, cursor }, { provider }), 'WorkQueue.ListPartitions');\n }\n\n public Replay(provider: IMetadataProvider, subscriptionName: string, deliveryID: string, note?: string): Promise<WorkQueueReplayDeadLetterOutput> {\n return this.run(new WorkQueueReplayDeadLetterOperation().Execute({ subscriptionName, deliveryID, note }, { provider }), 'WorkQueue.ReplayDeadLetter');\n }\n\n public Discard(provider: IMetadataProvider, subscriptionName: string, deliveryID: string, reason: string): Promise<WorkQueueDiscardDeliveryOutput> {\n return this.run(new WorkQueueDiscardDeliveryOperation().Execute({ subscriptionName, deliveryID, reason }, { provider }), 'WorkQueue.DiscardDelivery');\n }\n\n public GetBacklog(provider: IMetadataProvider, subscriptionName: string): Promise<WorkQueueGetBacklogOutput> {\n return this.run(new WorkQueueGetBacklogOperation().Execute({ subscriptionName }, { provider }), 'WorkQueue.GetBacklog');\n }\n\n public ValidateBindings(provider: IMetadataProvider, transportName?: string): Promise<WorkQueueValidateBindingsOutput> {\n return this.run(new WorkQueueValidateBindingsOperation().Execute({ transportName }, { provider }), 'WorkQueue.ValidateBindings');\n }\n\n private async run<T>(pending: Promise<RemoteOpResult<T>>, key: string): Promise<T> {\n const result = await pending;\n if (!result.Success || result.Output === undefined) {\n throw new Error(`${key} failed (${result.ResultCode ?? 'UNKNOWN'}): ${result.ErrorMessage ?? 'no details'}`);\n }\n return result.Output;\n }\n}\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export declare const WORK_QUEUE_TABS: readonly ["overview", "dead-letters", "partitions", "bindings"];
|
|
2
|
+
export type WorkQueueTab = (typeof WORK_QUEUE_TABS)[number];
|
|
3
|
+
export declare const WORK_QUEUE_TAB_LABELS: Record<WorkQueueTab, string>;
|
|
4
|
+
/** The partition conditions WorkQueue.ListPartitions accepts (03 §5.2). */
|
|
5
|
+
export declare const WORK_QUEUE_PARTITION_CONDITIONS: readonly ["Blocked", "InFlight", "Idle"];
|
|
6
|
+
export type WorkQueuePartitionCondition = (typeof WORK_QUEUE_PARTITION_CONDITIONS)[number];
|
|
7
|
+
/** Upper bound on any list published in the agent context; a companion count reports the true total. */
|
|
8
|
+
export declare const WORK_QUEUE_CONTEXT_LIST_CAP = 25;
|
|
9
|
+
export declare function IsValidWorkQueueTab(value: unknown): value is WorkQueueTab;
|
|
10
|
+
export declare function IsValidPartitionCondition(value: unknown): value is WorkQueuePartitionCondition;
|
|
11
|
+
/** One subscription as the dashboard reports it to the agent: topology plus the last stats read (null until loaded). */
|
|
12
|
+
export interface WorkQueueSubscriptionSnapshot {
|
|
13
|
+
ID: string;
|
|
14
|
+
Name: string;
|
|
15
|
+
Topic: string;
|
|
16
|
+
Transport: string;
|
|
17
|
+
PartitionMode: string;
|
|
18
|
+
Status: string;
|
|
19
|
+
Pending: number | null;
|
|
20
|
+
InFlight: number | null;
|
|
21
|
+
DeadLettered: number | null;
|
|
22
|
+
BlockedKeys: number | null;
|
|
23
|
+
OldestPendingAgeSeconds: number | null;
|
|
24
|
+
}
|
|
25
|
+
/** A subscription needs an operator when it holds dead letters or a blocked Ordered key. */
|
|
26
|
+
export declare function NeedsAttention(snapshot: Pick<WorkQueueSubscriptionSnapshot, 'DeadLettered' | 'BlockedKeys'>): boolean;
|
|
27
|
+
/** Attention first, then by name; returns a new array. */
|
|
28
|
+
export declare function SortByAttention<T extends Pick<WorkQueueSubscriptionSnapshot, 'DeadLettered' | 'BlockedKeys' | 'Name'>>(items: readonly T[]): T[];
|
|
29
|
+
/** '—' for null, then s / m / h m / d h at the coarsest useful unit. */
|
|
30
|
+
export declare function FormatAge(seconds: number | null | undefined): string;
|
|
31
|
+
export interface SubscriptionCandidate {
|
|
32
|
+
ID: string;
|
|
33
|
+
Name: string;
|
|
34
|
+
}
|
|
35
|
+
export type SubscriptionResolution<T extends SubscriptionCandidate> = {
|
|
36
|
+
Kind: 'Match';
|
|
37
|
+
Item: T;
|
|
38
|
+
} | {
|
|
39
|
+
Kind: 'Ambiguous';
|
|
40
|
+
Matches: T[];
|
|
41
|
+
} | {
|
|
42
|
+
Kind: 'NotFound';
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Resolves an agent-supplied id or name tolerantly: exact id, then exact name (case-insensitive), then a unique
|
|
46
|
+
* case-insensitive substring of the name. Several substring matches are reported as Ambiguous, never guessed.
|
|
47
|
+
*/
|
|
48
|
+
export declare function ResolveSubscription<T extends SubscriptionCandidate>(candidates: readonly T[], query: string): SubscriptionResolution<T>;
|
|
49
|
+
export interface WorkQueueAgentContextInput {
|
|
50
|
+
ActiveTab: string;
|
|
51
|
+
Subscriptions: WorkQueueSubscriptionSnapshot[];
|
|
52
|
+
StatsFailures: string[];
|
|
53
|
+
StatsLoaded: boolean;
|
|
54
|
+
SelectedSubscription: string | null;
|
|
55
|
+
PartitionCondition: WorkQueuePartitionCondition | null;
|
|
56
|
+
DeadLetterCount: number | null;
|
|
57
|
+
SelectedDeadLetterCount: number;
|
|
58
|
+
BindingErrorCount: number | null;
|
|
59
|
+
BindingWarningCount: number | null;
|
|
60
|
+
LastRefreshedAt: string | null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Shapes the dashboard state for NavigationService.SetAgentContext. Counts come only from loaded stats: before the
|
|
64
|
+
* first stats read the aggregate fields are null rather than fabricated zeros.
|
|
65
|
+
*/
|
|
66
|
+
export declare function BuildWorkQueueAgentContext(input: WorkQueueAgentContextInput): Record<string, unknown>;
|
|
67
|
+
//# sourceMappingURL=work-queue-agent-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"work-queue-agent-context.d.ts","sourceRoot":"","sources":["../../src/WorkQueue/work-queue-agent-context.ts"],"names":[],"mappings":"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"}
|