@memberjunction/ng-core-entity-forms 5.30.0 → 5.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/lib/__tests__/content-source-form.test.d.ts +2 -0
  2. package/dist/lib/__tests__/content-source-form.test.d.ts.map +1 -0
  3. package/dist/lib/__tests__/content-source-form.test.js +183 -0
  4. package/dist/lib/__tests__/content-source-form.test.js.map +1 -0
  5. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts +2 -1
  6. package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
  7. package/dist/lib/custom/AIAgents/add-action-dialog.component.js +6 -4
  8. package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
  9. package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js +2 -2
  10. package/dist/lib/custom/AIAgents/agent-advanced-settings-dialog.component.js.map +1 -1
  11. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts +2 -1
  12. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
  13. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +6 -4
  14. package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
  15. package/dist/lib/custom/AIAgents/ai-agent-form.component.js +15 -15
  16. package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
  17. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts +2 -1
  18. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
  19. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +9 -7
  20. package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
  21. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts +2 -1
  22. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
  23. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +11 -9
  24. package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
  25. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts +2 -1
  26. package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts.map +1 -1
  27. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +6 -5
  28. package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
  29. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts +2 -1
  30. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
  31. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +6 -4
  32. package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
  33. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts +2 -1
  34. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
  35. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +6 -4
  36. package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
  37. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +2 -1
  38. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
  39. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +6 -4
  40. package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
  41. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +3 -3
  42. package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
  43. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +1 -1
  44. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
  45. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +6 -6
  46. package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
  47. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts +2 -1
  48. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
  49. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +7 -5
  50. package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
  51. package/dist/lib/custom/Actions/action-execution-log-form.component.js +3 -3
  52. package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
  53. package/dist/lib/custom/Actions/action-form.component.js +12 -12
  54. package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
  55. package/dist/lib/custom/ContentSources/content-source-form.component.d.ts +59 -5
  56. package/dist/lib/custom/ContentSources/content-source-form.component.d.ts.map +1 -1
  57. package/dist/lib/custom/ContentSources/content-source-form.component.js +379 -34
  58. package/dist/lib/custom/ContentSources/content-source-form.component.js.map +1 -1
  59. package/dist/lib/custom/Entities/entity-form.component.d.ts +1 -1
  60. package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
  61. package/dist/lib/custom/Entities/entity-form.component.js +5 -5
  62. package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
  63. package/dist/lib/custom/Lists/list-form.component.d.ts +1 -1
  64. package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
  65. package/dist/lib/custom/Lists/list-form.component.js +10 -10
  66. package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
  67. package/dist/lib/custom/Queries/query-category-dialog.component.d.ts +2 -1
  68. package/dist/lib/custom/Queries/query-category-dialog.component.d.ts.map +1 -1
  69. package/dist/lib/custom/Queries/query-category-dialog.component.js +9 -7
  70. package/dist/lib/custom/Queries/query-category-dialog.component.js.map +1 -1
  71. package/dist/lib/custom/Queries/query-form.component.js +17 -17
  72. package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
  73. package/dist/lib/custom/Queries/query-run-dialog.component.d.ts +2 -1
  74. package/dist/lib/custom/Queries/query-run-dialog.component.d.ts.map +1 -1
  75. package/dist/lib/custom/Queries/query-run-dialog.component.js +7 -6
  76. package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
  77. package/dist/lib/custom/Templates/template-param-dialog.component.d.ts +2 -1
  78. package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
  79. package/dist/lib/custom/Templates/template-param-dialog.component.js +10 -8
  80. package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
  81. package/dist/lib/custom/Templates/template-params-grid.component.d.ts +2 -1
  82. package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
  83. package/dist/lib/custom/Templates/template-params-grid.component.js +9 -7
  84. package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
  85. package/dist/lib/custom/Templates/templates-form.component.js +8 -8
  86. package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
  87. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts +3 -2
  88. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -1
  89. package/dist/lib/custom/Tests/entity-link-pill.component.js +8 -6
  90. package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -1
  91. package/dist/lib/custom/Tests/test-form.component.d.ts +1 -1
  92. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  93. package/dist/lib/custom/Tests/test-form.component.js +7 -7
  94. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  95. package/dist/lib/custom/Tests/test-run-form.component.js +5 -5
  96. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  97. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +1 -1
  98. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  99. package/dist/lib/custom/Tests/test-suite-form.component.js +8 -8
  100. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  101. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +1 -1
  102. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
  103. package/dist/lib/custom/Tests/test-suite-run-form.component.js +6 -6
  104. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  105. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +2 -1
  106. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
  107. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +8 -6
  108. package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
  109. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts +9 -0
  110. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
  111. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +15 -3
  112. package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
  113. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +3 -2
  114. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
  115. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +10 -5
  116. package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
  117. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +2 -2
  118. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  119. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -1
  120. package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
  121. package/dist/lib/custom/shared/entity-selector-dialog.component.js +6 -4
  122. package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
  123. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.d.ts.map +1 -1
  124. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js +46 -28
  125. package/dist/lib/generated/Entities/MJAIModel/mjaimodel.form.component.js.map +1 -1
  126. package/dist/lib/generated/Entities/MJCompanyIntegrationEntityMap/mjcompanyintegrationentitymap.form.component.js +10 -10
  127. package/dist/lib/generated/Entities/MJCompanyIntegrationEntityMap/mjcompanyintegrationentitymap.form.component.js.map +1 -1
  128. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.d.ts.map +1 -1
  129. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js +25 -7
  130. package/dist/lib/generated/Entities/MJContentItem/mjcontentitem.form.component.js.map +1 -1
  131. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.d.ts.map +1 -1
  132. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js +25 -7
  133. package/dist/lib/generated/Entities/MJContentSource/mjcontentsource.form.component.js.map +1 -1
  134. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
  135. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +106 -88
  136. package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
  137. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.d.ts.map +1 -1
  138. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js +181 -61
  139. package/dist/lib/generated/Entities/MJTag/mjtag.form.component.js.map +1 -1
  140. package/dist/lib/generated/Entities/MJTagScope/mjtagscope.form.component.d.ts +10 -0
  141. package/dist/lib/generated/Entities/MJTagScope/mjtagscope.form.component.d.ts.map +1 -0
  142. package/dist/lib/generated/Entities/MJTagScope/mjtagscope.form.component.js +63 -0
  143. package/dist/lib/generated/Entities/MJTagScope/mjtagscope.form.component.js.map +1 -0
  144. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.d.ts +10 -0
  145. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.d.ts.map +1 -0
  146. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.js +95 -0
  147. package/dist/lib/generated/Entities/MJTagSuggestion/mjtagsuggestion.form.component.js.map +1 -0
  148. package/dist/lib/generated/Entities/MJTagSynonym/mjtagsynonym.form.component.d.ts +10 -0
  149. package/dist/lib/generated/Entities/MJTagSynonym/mjtagsynonym.form.component.d.ts.map +1 -0
  150. package/dist/lib/generated/Entities/MJTagSynonym/mjtagsynonym.form.component.js +63 -0
  151. package/dist/lib/generated/Entities/MJTagSynonym/mjtagsynonym.form.component.js.map +1 -0
  152. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
  153. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +199 -181
  154. package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
  155. package/dist/lib/generated/generated-forms.module.d.ts +51 -48
  156. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  157. package/dist/lib/generated/generated-forms.module.js +27 -18
  158. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  159. package/dist/lib/shared/components/template-editor.component.d.ts +3 -2
  160. package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
  161. package/dist/lib/shared/components/template-editor.component.js +8 -6
  162. package/dist/lib/shared/components/template-editor.component.js.map +1 -1
  163. package/package.json +37 -35
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=content-source-form.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-source-form.test.d.ts","sourceRoot":"","sources":["../../../src/lib/__tests__/content-source-form.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Tests for the Tag Pipeline Configuration extras on the custom ContentSource form.
3
+ *
4
+ * The form's typed accessors (Mode / Threshold / Budget) round-trip through the
5
+ * `ConfigurationObject` typed JSON accessor on the entity. We mock the entity
6
+ * with a stand-in object that records its current Configuration so each setter
7
+ * can be observed end-to-end.
8
+ */
9
+ import { describe, it, expect, vi } from 'vitest';
10
+ vi.mock('@angular/core', () => ({
11
+ Component: () => (target) => target,
12
+ }));
13
+ vi.mock('@memberjunction/global', () => ({
14
+ RegisterClass: () => (t) => t,
15
+ }));
16
+ vi.mock('@memberjunction/ng-base-forms', () => ({
17
+ BaseFormComponent: class {
18
+ constructor() {
19
+ this.EditMode = true;
20
+ this.formContext = {};
21
+ }
22
+ },
23
+ }));
24
+ vi.mock('@memberjunction/core-entities', () => ({}));
25
+ vi.mock('../../generated/Entities/MJContentSource/mjcontentsource.form.component', () => ({
26
+ MJContentSourceFormComponent: class {
27
+ constructor() {
28
+ this.EditMode = true;
29
+ this.formContext = {};
30
+ }
31
+ },
32
+ }));
33
+ import { MJContentSourceFormComponentExtended } from '../custom/ContentSources/content-source-form.component';
34
+ function makeForm(initial) {
35
+ const form = new MJContentSourceFormComponentExtended();
36
+ let cfg = { ...(initial ?? {}) };
37
+ let contentSourceType = '';
38
+ form.record = {
39
+ get ConfigurationObject() { return cfg; },
40
+ set ConfigurationObject(value) { cfg = value; },
41
+ get ContentSourceType() { return contentSourceType; },
42
+ set ContentSourceType(v) { contentSourceType = v; },
43
+ EmbeddingModelID: 'embed-model-1',
44
+ };
45
+ return form;
46
+ }
47
+ describe('MJContentSourceFormComponentExtended', () => {
48
+ describe('IsEntitySourceType', () => {
49
+ it('returns false when no record is loaded', () => {
50
+ const f = new MJContentSourceFormComponentExtended();
51
+ f.record = null;
52
+ expect(f.IsEntitySourceType).toBe(false);
53
+ });
54
+ it('returns true when ContentSourceType is "Entity" (case-insensitive)', () => {
55
+ const f = makeForm();
56
+ f.record.ContentSourceType = 'entity';
57
+ expect(f.IsEntitySourceType).toBe(true);
58
+ f.record.ContentSourceType = 'Entity';
59
+ expect(f.IsEntitySourceType).toBe(true);
60
+ });
61
+ it('returns false for non-entity sources', () => {
62
+ const f = makeForm();
63
+ f.record.ContentSourceType = 'HubSpot';
64
+ expect(f.IsEntitySourceType).toBe(false);
65
+ });
66
+ });
67
+ describe('Taxonomy mode', () => {
68
+ it('defaults to auto-grow when nothing in config', () => {
69
+ const f = makeForm();
70
+ expect(f.CurrentMode).toBe('auto-grow');
71
+ });
72
+ it('reads the mode set in config', () => {
73
+ const f = makeForm({ TagTaxonomyMode: 'constrained' });
74
+ expect(f.CurrentMode).toBe('constrained');
75
+ });
76
+ it('SetMode persists through ConfigurationObject', () => {
77
+ const f = makeForm();
78
+ f.SetMode('free-flow');
79
+ expect(f.CurrentMode).toBe('free-flow');
80
+ });
81
+ });
82
+ describe('Thresholds', () => {
83
+ it('defaults MatchThreshold to 0.85', () => {
84
+ const f = makeForm();
85
+ expect(f.MatchThresholdValue).toBe(0.85);
86
+ });
87
+ it('clamps MatchThreshold setter to [0, 1]', () => {
88
+ const f = makeForm();
89
+ f.MatchThresholdValue = 1.5;
90
+ expect(f.MatchThresholdValue).toBe(1);
91
+ f.MatchThresholdValue = -0.5;
92
+ expect(f.MatchThresholdValue).toBe(0);
93
+ });
94
+ it('pulls SuggestThreshold below MatchThreshold when MatchThreshold drops', () => {
95
+ const f = makeForm({ TagMatchThreshold: 0.85, SuggestThreshold: 0.80 });
96
+ f.MatchThresholdValue = 0.70;
97
+ // SuggestThreshold should drop to <= 0.70 (auto-pinned 0.05 below)
98
+ expect(f.SuggestThresholdValue).toBeLessThanOrEqual(0.70);
99
+ });
100
+ it('clamps SuggestThreshold to <= MatchThreshold', () => {
101
+ const f = makeForm({ TagMatchThreshold: 0.80 });
102
+ f.SuggestThresholdValue = 0.95;
103
+ expect(f.SuggestThresholdValue).toBeLessThanOrEqual(0.80);
104
+ });
105
+ it('flags validation message when SuggestThreshold >= MatchThreshold', () => {
106
+ const f = makeForm();
107
+ // Force an invalid pair via the JSON object directly to bypass setter clamping
108
+ f.setConfig({ TagMatchThreshold: 0.80, SuggestThreshold: 0.90 });
109
+ expect(f.ThresholdValidationMessage).toMatch(/lower than/);
110
+ });
111
+ it('returns null validation message when SuggestThreshold < MatchThreshold', () => {
112
+ const f = makeForm();
113
+ f.setConfig({ TagMatchThreshold: 0.85, SuggestThreshold: 0.70 });
114
+ expect(f.ThresholdValidationMessage).toBeNull();
115
+ });
116
+ });
117
+ describe('Boolean toggles', () => {
118
+ it('ShareTaxonomyWithLLM defaults to true', () => {
119
+ const f = makeForm();
120
+ expect(f.ShareTaxonomyValue).toBe(true);
121
+ });
122
+ it('ShareTaxonomyWithLLM is honored when explicitly false', () => {
123
+ const f = makeForm({ ShareTaxonomyWithLLM: false });
124
+ expect(f.ShareTaxonomyValue).toBe(false);
125
+ });
126
+ it('EnableVectorization defaults to true', () => {
127
+ const f = makeForm();
128
+ expect(f.EnableVectorizationValue).toBe(true);
129
+ });
130
+ });
131
+ describe('Budget setters', () => {
132
+ it('return null when unset', () => {
133
+ const f = makeForm();
134
+ expect(f.MaxNewTagsPerRunValue).toBeNull();
135
+ expect(f.MaxCostPerRunValue).toBeNull();
136
+ });
137
+ it('persist numeric values through Configuration', () => {
138
+ const f = makeForm();
139
+ f.MaxNewTagsPerRunValue = 50;
140
+ f.MaxCostPerRunValue = 12.5;
141
+ expect(f.MaxNewTagsPerRunValue).toBe(50);
142
+ expect(f.MaxCostPerRunValue).toBe(12.5);
143
+ });
144
+ it('strip the field when blank string is supplied (ngModel quirk)', () => {
145
+ const f = makeForm({ MaxNewTagsPerRun: 50 });
146
+ f.MaxNewTagsPerRunValue = '';
147
+ expect(f.MaxNewTagsPerRunValue).toBeNull();
148
+ });
149
+ it('strip the field when null is supplied', () => {
150
+ const f = makeForm({ MaxTokensPerRun: 1000 });
151
+ f.MaxTokensPerRunValue = null;
152
+ expect(f.MaxTokensPerRunValue).toBeNull();
153
+ });
154
+ it('coerce string numbers from form inputs', () => {
155
+ const f = makeForm();
156
+ f.MaxNewTagsPerItemValue = '7';
157
+ expect(f.MaxNewTagsPerItemValue).toBe(7);
158
+ });
159
+ it('reject NaN gracefully', () => {
160
+ const f = makeForm();
161
+ f.MaxNewTagsPerRunValue = 'abc';
162
+ expect(f.MaxNewTagsPerRunValue).toBeNull();
163
+ });
164
+ });
165
+ describe('Tag root + Configuration round-trip', () => {
166
+ it('writes TagRootID through the typed accessor', () => {
167
+ const f = makeForm();
168
+ f.TagRootIDValue = 'root-123';
169
+ expect(f.TagRootIDValue).toBe('root-123');
170
+ expect(f.Config.TagRootID).toBe('root-123');
171
+ });
172
+ it('preserves SourceSpecificConfiguration when other knobs change', () => {
173
+ const f = makeForm({
174
+ TagTaxonomyMode: 'auto-grow',
175
+ SourceSpecificConfiguration: { workspaceId: 'abc' }
176
+ });
177
+ f.SetMode('free-flow');
178
+ expect(f.Config.SourceSpecificConfiguration).toEqual({ workspaceId: 'abc' });
179
+ expect(f.Config.TagTaxonomyMode).toBe('free-flow');
180
+ });
181
+ });
182
+ });
183
+ //# sourceMappingURL=content-source-form.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-source-form.test.js","sourceRoot":"","sources":["../../../src/lib/__tests__/content-source-form.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAc,MAAM,QAAQ,CAAC;AAE9D,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5B,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,MAAgB,EAAE,EAAE,CAAC,MAAM;CAChD,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC;CACzC,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,iBAAiB,EAAE;QAAA;YACR,aAAQ,GAAG,IAAI,CAAC;YAChB,gBAAW,GAAG,EAAE,CAAC;QAC5B,CAAC;KAAA;CACJ,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAErD,EAAE,CAAC,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE,CAAC,CAAC;IACtF,4BAA4B,EAAE;QAAA;YACnB,aAAQ,GAAG,IAAI,CAAC;YAChB,gBAAW,GAAG,EAAE,CAAC;QAC5B,CAAC;KAAA;CACJ,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,oCAAoC,EAAE,MAAM,wDAAwD,CAAC;AAgB9G,SAAS,QAAQ,CAAC,OAAwB;IACtC,MAAM,IAAI,GAAG,IAAI,oCAAoC,EAAE,CAAC;IACxD,IAAI,GAAG,GAAmB,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;IACjD,IAAI,iBAAiB,GAAG,EAAE,CAAC;IAC1B,IAAuC,CAAC,MAAM,GAAG;QAC9C,IAAI,mBAAmB,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,mBAAmB,CAAC,KAAqB,IAAI,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC;QAC/D,IAAI,iBAAiB,KAAK,OAAO,iBAAiB,CAAC,CAAC,CAAC;QACrD,IAAI,iBAAiB,CAAC,CAAS,IAAI,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC;QAC3D,gBAAgB,EAAE,eAAe;KACpC,CAAC;IACF,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAElD,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,GAAG,IAAI,oCAAoC,EAAE,CAAC;YACpD,CAAoC,CAAC,MAAM,GAAG,IAAI,CAAC;YACpD,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;YAC1E,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACpB,CAAC,CAAC,MAAmD,CAAC,iBAAiB,GAAG,QAAQ,CAAC;YACpF,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC,CAAC,MAAmD,CAAC,iBAAiB,GAAG,QAAQ,CAAC;YACpF,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACpB,CAAC,CAAC,MAAmD,CAAC,iBAAiB,GAAG,SAAS,CAAC;YACrF,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC,CAAC;YACvD,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YACvB,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,mBAAmB,GAAG,GAAG,CAAC;YAC5B,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC,CAAC,mBAAmB,GAAG,CAAC,GAAG,CAAC;YAC7B,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;YAC7E,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,mBAAmB,GAAG,IAAI,CAAC;YAC7B,mEAAmE;YACnE,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,CAAC,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAC/B,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;YACxE,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,+EAA+E;YAC/E,CAAC,CAAC,SAAS,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAC9E,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,SAAS,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;YAC7D,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC,CAAC;YACpD,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAC9B,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,qBAAqB,GAAG,EAAE,CAAC;YAC7B,CAAC,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAC5B,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACrE,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAC7C,CAAC,CAAC,qBAAqB,GAAG,EAAW,CAAC;YACtC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC7C,MAAM,CAAC,GAAG,QAAQ,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,CAAC,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAC9B,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,sBAAsB,GAAG,GAAY,CAAC;YACxC,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,qBAAqB,GAAG,KAAc,CAAC;YACzC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qCAAqC,EAAE,GAAG,EAAE;QACjD,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACnD,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC;YACrB,CAAC,CAAC,cAAc,GAAG,UAAU,CAAC;YAC9B,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC1C,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACrE,MAAM,CAAC,GAAG,QAAQ,CAAC;gBACf,eAAe,EAAE,WAAW;gBAC5B,2BAA2B,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;aACtD,CAAC,CAAC;YACH,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YACvB,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7E,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC","sourcesContent":["/**\n * Tests for the Tag Pipeline Configuration extras on the custom ContentSource form.\n *\n * The form's typed accessors (Mode / Threshold / Budget) round-trip through the\n * `ConfigurationObject` typed JSON accessor on the entity. We mock the entity\n * with a stand-in object that records its current Configuration so each setter\n * can be observed end-to-end.\n */\nimport { describe, it, expect, vi, beforeEach } from 'vitest';\n\nvi.mock('@angular/core', () => ({\n Component: () => (target: Function) => target,\n}));\n\nvi.mock('@memberjunction/global', () => ({\n RegisterClass: () => (t: unknown) => t,\n}));\n\nvi.mock('@memberjunction/ng-base-forms', () => ({\n BaseFormComponent: class {\n public EditMode = true;\n public formContext = {};\n },\n}));\n\nvi.mock('@memberjunction/core-entities', () => ({}));\n\nvi.mock('../../generated/Entities/MJContentSource/mjcontentsource.form.component', () => ({\n MJContentSourceFormComponent: class {\n public EditMode = true;\n public formContext = {};\n },\n}));\n\nimport { MJContentSourceFormComponentExtended } from '../custom/ContentSources/content-source-form.component';\n\ninterface TestableConfig {\n TagTaxonomyMode?: string;\n TagRootID?: string | null;\n TagMatchThreshold?: number;\n SuggestThreshold?: number;\n ShareTaxonomyWithLLM?: boolean;\n EnableVectorization?: boolean;\n MaxNewTagsPerRun?: number;\n MaxNewTagsPerItem?: number;\n MaxTokensPerRun?: number;\n MaxCostPerRun?: number;\n SourceSpecificConfiguration?: Record<string, unknown>;\n}\n\nfunction makeForm(initial?: TestableConfig): MJContentSourceFormComponentExtended {\n const form = new MJContentSourceFormComponentExtended();\n let cfg: TestableConfig = { ...(initial ?? {}) };\n let contentSourceType = '';\n (form as unknown as { record: unknown }).record = {\n get ConfigurationObject() { return cfg; },\n set ConfigurationObject(value: TestableConfig) { cfg = value; },\n get ContentSourceType() { return contentSourceType; },\n set ContentSourceType(v: string) { contentSourceType = v; },\n EmbeddingModelID: 'embed-model-1',\n };\n return form;\n}\n\ndescribe('MJContentSourceFormComponentExtended', () => {\n\n describe('IsEntitySourceType', () => {\n it('returns false when no record is loaded', () => {\n const f = new MJContentSourceFormComponentExtended();\n (f as unknown as { record: unknown }).record = null;\n expect(f.IsEntitySourceType).toBe(false);\n });\n it('returns true when ContentSourceType is \"Entity\" (case-insensitive)', () => {\n const f = makeForm();\n (f.record as unknown as { ContentSourceType: string }).ContentSourceType = 'entity';\n expect(f.IsEntitySourceType).toBe(true);\n (f.record as unknown as { ContentSourceType: string }).ContentSourceType = 'Entity';\n expect(f.IsEntitySourceType).toBe(true);\n });\n it('returns false for non-entity sources', () => {\n const f = makeForm();\n (f.record as unknown as { ContentSourceType: string }).ContentSourceType = 'HubSpot';\n expect(f.IsEntitySourceType).toBe(false);\n });\n });\n\n describe('Taxonomy mode', () => {\n it('defaults to auto-grow when nothing in config', () => {\n const f = makeForm();\n expect(f.CurrentMode).toBe('auto-grow');\n });\n it('reads the mode set in config', () => {\n const f = makeForm({ TagTaxonomyMode: 'constrained' });\n expect(f.CurrentMode).toBe('constrained');\n });\n it('SetMode persists through ConfigurationObject', () => {\n const f = makeForm();\n f.SetMode('free-flow');\n expect(f.CurrentMode).toBe('free-flow');\n });\n });\n\n describe('Thresholds', () => {\n it('defaults MatchThreshold to 0.85', () => {\n const f = makeForm();\n expect(f.MatchThresholdValue).toBe(0.85);\n });\n it('clamps MatchThreshold setter to [0, 1]', () => {\n const f = makeForm();\n f.MatchThresholdValue = 1.5;\n expect(f.MatchThresholdValue).toBe(1);\n f.MatchThresholdValue = -0.5;\n expect(f.MatchThresholdValue).toBe(0);\n });\n it('pulls SuggestThreshold below MatchThreshold when MatchThreshold drops', () => {\n const f = makeForm({ TagMatchThreshold: 0.85, SuggestThreshold: 0.80 });\n f.MatchThresholdValue = 0.70;\n // SuggestThreshold should drop to <= 0.70 (auto-pinned 0.05 below)\n expect(f.SuggestThresholdValue).toBeLessThanOrEqual(0.70);\n });\n it('clamps SuggestThreshold to <= MatchThreshold', () => {\n const f = makeForm({ TagMatchThreshold: 0.80 });\n f.SuggestThresholdValue = 0.95;\n expect(f.SuggestThresholdValue).toBeLessThanOrEqual(0.80);\n });\n it('flags validation message when SuggestThreshold >= MatchThreshold', () => {\n const f = makeForm();\n // Force an invalid pair via the JSON object directly to bypass setter clamping\n f.setConfig({ TagMatchThreshold: 0.80, SuggestThreshold: 0.90 });\n expect(f.ThresholdValidationMessage).toMatch(/lower than/);\n });\n it('returns null validation message when SuggestThreshold < MatchThreshold', () => {\n const f = makeForm();\n f.setConfig({ TagMatchThreshold: 0.85, SuggestThreshold: 0.70 });\n expect(f.ThresholdValidationMessage).toBeNull();\n });\n });\n\n describe('Boolean toggles', () => {\n it('ShareTaxonomyWithLLM defaults to true', () => {\n const f = makeForm();\n expect(f.ShareTaxonomyValue).toBe(true);\n });\n it('ShareTaxonomyWithLLM is honored when explicitly false', () => {\n const f = makeForm({ ShareTaxonomyWithLLM: false });\n expect(f.ShareTaxonomyValue).toBe(false);\n });\n it('EnableVectorization defaults to true', () => {\n const f = makeForm();\n expect(f.EnableVectorizationValue).toBe(true);\n });\n });\n\n describe('Budget setters', () => {\n it('return null when unset', () => {\n const f = makeForm();\n expect(f.MaxNewTagsPerRunValue).toBeNull();\n expect(f.MaxCostPerRunValue).toBeNull();\n });\n it('persist numeric values through Configuration', () => {\n const f = makeForm();\n f.MaxNewTagsPerRunValue = 50;\n f.MaxCostPerRunValue = 12.5;\n expect(f.MaxNewTagsPerRunValue).toBe(50);\n expect(f.MaxCostPerRunValue).toBe(12.5);\n });\n it('strip the field when blank string is supplied (ngModel quirk)', () => {\n const f = makeForm({ MaxNewTagsPerRun: 50 });\n f.MaxNewTagsPerRunValue = '' as never;\n expect(f.MaxNewTagsPerRunValue).toBeNull();\n });\n it('strip the field when null is supplied', () => {\n const f = makeForm({ MaxTokensPerRun: 1000 });\n f.MaxTokensPerRunValue = null;\n expect(f.MaxTokensPerRunValue).toBeNull();\n });\n it('coerce string numbers from form inputs', () => {\n const f = makeForm();\n f.MaxNewTagsPerItemValue = '7' as never;\n expect(f.MaxNewTagsPerItemValue).toBe(7);\n });\n it('reject NaN gracefully', () => {\n const f = makeForm();\n f.MaxNewTagsPerRunValue = 'abc' as never;\n expect(f.MaxNewTagsPerRunValue).toBeNull();\n });\n });\n\n describe('Tag root + Configuration round-trip', () => {\n it('writes TagRootID through the typed accessor', () => {\n const f = makeForm();\n f.TagRootIDValue = 'root-123';\n expect(f.TagRootIDValue).toBe('root-123');\n expect(f.Config.TagRootID).toBe('root-123');\n });\n it('preserves SourceSpecificConfiguration when other knobs change', () => {\n const f = makeForm({\n TagTaxonomyMode: 'auto-grow',\n SourceSpecificConfiguration: { workspaceId: 'abc' }\n });\n f.SetMode('free-flow');\n expect(f.Config.SourceSpecificConfiguration).toEqual({ workspaceId: 'abc' });\n expect(f.Config.TagTaxonomyMode).toBe('free-flow');\n });\n });\n});\n"]}
@@ -2,6 +2,7 @@ import { OnInit, OnDestroy, ChangeDetectorRef, EventEmitter } from '@angular/cor
2
2
  import { FormControl } from '@angular/forms';
3
3
  import { Subject, BehaviorSubject } from 'rxjs';
4
4
  import { MJActionEntity, MJActionCategoryEntity } from '@memberjunction/core-entities';
5
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
5
6
  import * as i0 from "@angular/core";
6
7
  export interface CategoryTreeNode {
7
8
  id: string;
@@ -19,7 +20,7 @@ export interface ActionDisplayItem extends MJActionEntity {
19
20
  * Modern, clean dialog for selecting actions to add to an AI Agent.
20
21
  * Features searchable action list, category filtering, and multi-select capability.
21
22
  */
22
- export declare class AddActionDialogComponent implements OnInit, OnDestroy {
23
+ export declare class AddActionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy {
23
24
  private cdr;
24
25
  agentId: string;
25
26
  agentName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"add-action-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/add-action-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,eAAe,EAA2E,MAAM,MAAM,CAAC;AAEzH,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;;AAGvF,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAMa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IAyC9D,OAAO,CAAC,GAAG;IAtCb,OAAO,EAAE,MAAM,CAAM;IACrB,SAAS,EAAE,MAAM,CAAM;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAM;IAGjC,OAAO,CAAC,QAAQ,CAAuB;IAChC,MAAM,4BAAmC;IAGhD,WAAW,uCAAgD;IAC3D,WAAW,4CAAqD;IAChE,gBAAgB,uCAAgD;IAChE,aAAa,sCAA+C;IAC5D,gBAAgB,+BAA+C;IAC/D,UAAU,2BAAuC;IAGjD,aAAa,6BAAuB;IACpC,mBAAmB,0BAAsC;IACzD,SAAS,mCAAgD;IACzD,kBAAkB,cAAqB;IAGvC,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAES,WAAW,qBAA4B;gBAGvC,GAAG,EAAE,iBAAiB;IAGhC,QAAQ;IAMR,WAAW;YAKG,cAAc;YAad,wBAAwB;IAmCtC,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,wBAAwB;IAgBhC,cAAc,CAAC,UAAU,EAAE,MAAM;IAIjC,cAAc;IAKd,qBAAqB,CAAC,MAAM,EAAE,iBAAiB;IA4B/C,WAAW;IAIX,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;IAsBhD,MAAM;IAKN,kBAAkB;yCA1SP,wBAAwB;2CAAxB,wBAAwB;CAwTpC"}
1
+ {"version":3,"file":"add-action-dialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/add-action-dialog.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAU,YAAY,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,eAAe,EAA2E,MAAM,MAAM,CAAC;AAEzH,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAGvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,qBAMa,wBAAyB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAyC3F,OAAO,CAAC,GAAG;IAtCb,OAAO,EAAE,MAAM,CAAM;IACrB,SAAS,EAAE,MAAM,CAAM;IACvB,iBAAiB,EAAE,MAAM,EAAE,CAAM;IAGjC,OAAO,CAAC,QAAQ,CAAuB;IAChC,MAAM,4BAAmC;IAGhD,WAAW,uCAAgD;IAC3D,WAAW,4CAAqD;IAChE,gBAAgB,uCAAgD;IAChE,aAAa,sCAA+C;IAC5D,gBAAgB,+BAA+C;IAC/D,UAAU,2BAAuC;IAGjD,aAAa,6BAAuB;IACpC,mBAAmB,0BAAsC;IACzD,SAAS,mCAAgD;IACzD,kBAAkB,cAAqB;IAGvC,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,aAAa,IAAI,MAAM,CAE1B;IAES,WAAW,qBAA4B;gBAGvC,GAAG,EAAE,iBAAiB;IAIhC,QAAQ;IAMR,WAAW;YAKG,cAAc;YAad,wBAAwB;IAmCtC,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,wBAAwB;IAgBhC,cAAc,CAAC,UAAU,EAAE,MAAM;IAIjC,cAAc;IAKd,qBAAqB,CAAC,MAAM,EAAE,iBAAiB;IA4B/C,WAAW;IAIX,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;IAsBhD,MAAM;IAKN,kBAAkB;yCA3SP,wBAAwB;2CAAxB,wBAAwB;CAyTpC"}
@@ -3,6 +3,7 @@ import { FormControl } from '@angular/forms';
3
3
  import { Subject, BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, takeUntil, startWith } from 'rxjs';
4
4
  import { RunView } from '@memberjunction/core';
5
5
  import { UUIDsEqual } from '@memberjunction/global';
6
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
6
7
  import * as i0 from "@angular/core";
7
8
  import * as i1 from "@angular/forms";
8
9
  import * as i2 from "@memberjunction/ng-ui-components";
@@ -227,7 +228,7 @@ function AddActionDialogComponent_Conditional_37_Template(rf, ctx) { if (rf & 1)
227
228
  * Modern, clean dialog for selecting actions to add to an AI Agent.
228
229
  * Features searchable action list, category filtering, and multi-select capability.
229
230
  */
230
- export class AddActionDialogComponent {
231
+ export class AddActionDialogComponent extends BaseAngularComponent {
231
232
  // Computed values
232
233
  get selectedCount() {
233
234
  return this.selectedActions$.value.size;
@@ -239,6 +240,7 @@ export class AddActionDialogComponent {
239
240
  return this.filteredActions$.value.length;
240
241
  }
241
242
  constructor(cdr) {
243
+ super();
242
244
  this.cdr = cdr;
243
245
  // Input properties set by service
244
246
  this.agentId = '';
@@ -284,7 +286,7 @@ export class AddActionDialogComponent {
284
286
  }
285
287
  }
286
288
  async loadActionsAndCategories() {
287
- const rv = new RunView();
289
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
288
290
  const [actionsResult, categoriesResult] = await rv.RunViews([
289
291
  {
290
292
  EntityName: 'MJ: Actions',
@@ -494,7 +496,7 @@ export class AddActionDialogComponent {
494
496
  this.DialogClose.emit();
495
497
  }
496
498
  static { this.ɵfac = function AddActionDialogComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AddActionDialogComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
497
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AddActionDialogComponent, selectors: [["mj-add-action-dialog"]], outputs: { DialogClose: "DialogClose" }, standalone: false, decls: 44, vars: 35, consts: [[1, "add-action-dialog"], [1, "dialog-header"], [1, "search-section"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-prefix-icon"], ["placeholder", "Search actions by name, description, or category...", 1, "mj-input", "search-input", 3, "formControl"], [1, "header-actions"], ["mjButton", "", "variant", "flat", 3, "click", "title"], [1, "fa-solid"], [1, "stats"], [1, "stat-item"], [1, "fa-solid", "fa-bolt"], [1, "dialog-content"], [1, "category-sidebar"], [1, "sidebar-header"], [1, "fa-solid", "fa-folder-tree"], [1, "category-list"], [1, "category-item", 3, "selected"], [1, "actions-container"], [1, "loading-state"], [1, "empty-state"], [1, "actions-grid"], [1, "actions-list"], [1, "selection-summary"], [1, "dialog-footer"], ["mjButton", "", "variant", "flat", 3, "click"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "category-item", 3, "click"], [1, "category-name"], [1, "category-count"], [1, "loading-spinner"], [1, "fa-solid", "fa-spinner", "fa-spin", "fa-2x"], [1, "fa-solid", "fa-search-minus"], ["mjButton", "", 3, "click"], [1, "action-card", 3, "selected", "existing"], [1, "action-card", 3, "click"], [1, "selection-indicator"], [1, "card-header"], [1, "action-icon"], [1, "action-name"], [1, "card-body"], [1, "action-description"], [1, "category-badge"], [1, "type-badge"], [1, "existing-overlay"], [1, "fa-solid", "fa-folder"], [1, "fa-solid", "fa-tag"], [1, "fa-solid", "fa-check"], [1, "list-header"], [1, "col-select"], [1, "col-name"], [1, "col-category"], [1, "col-type"], [1, "col-description"], [1, "col-status"], [1, "list-item", 3, "selected", "existing"], [1, "list-item", 3, "click"], [1, "status-badge", "existing"], [1, "status-badge", "available"], [1, "summary-content"], [1, "fa-solid", "fa-check-circle"]], template: function AddActionDialogComponent_Template(rf, ctx) { if (rf & 1) {
499
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AddActionDialogComponent, selectors: [["mj-add-action-dialog"]], outputs: { DialogClose: "DialogClose" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 44, vars: 35, consts: [[1, "add-action-dialog"], [1, "dialog-header"], [1, "search-section"], [1, "search-input-wrapper"], [1, "fa-solid", "fa-search", "search-prefix-icon"], ["placeholder", "Search actions by name, description, or category...", 1, "mj-input", "search-input", 3, "formControl"], [1, "header-actions"], ["mjButton", "", "variant", "flat", 3, "click", "title"], [1, "fa-solid"], [1, "stats"], [1, "stat-item"], [1, "fa-solid", "fa-bolt"], [1, "dialog-content"], [1, "category-sidebar"], [1, "sidebar-header"], [1, "fa-solid", "fa-folder-tree"], [1, "category-list"], [1, "category-item", 3, "selected"], [1, "actions-container"], [1, "loading-state"], [1, "empty-state"], [1, "actions-grid"], [1, "actions-list"], [1, "selection-summary"], [1, "dialog-footer"], ["mjButton", "", "variant", "flat", 3, "click"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "category-item", 3, "click"], [1, "category-name"], [1, "category-count"], [1, "loading-spinner"], [1, "fa-solid", "fa-spinner", "fa-spin", "fa-2x"], [1, "fa-solid", "fa-search-minus"], ["mjButton", "", 3, "click"], [1, "action-card", 3, "selected", "existing"], [1, "action-card", 3, "click"], [1, "selection-indicator"], [1, "card-header"], [1, "action-icon"], [1, "action-name"], [1, "card-body"], [1, "action-description"], [1, "category-badge"], [1, "type-badge"], [1, "existing-overlay"], [1, "fa-solid", "fa-folder"], [1, "fa-solid", "fa-tag"], [1, "fa-solid", "fa-check"], [1, "list-header"], [1, "col-select"], [1, "col-name"], [1, "col-category"], [1, "col-type"], [1, "col-description"], [1, "col-status"], [1, "list-item", 3, "selected", "existing"], [1, "list-item", 3, "click"], [1, "status-badge", "existing"], [1, "status-badge", "available"], [1, "summary-content"], [1, "fa-solid", "fa-check-circle"]], template: function AddActionDialogComponent_Template(rf, ctx) { if (rf & 1) {
498
500
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "div", 3);
499
501
  i0.ɵɵelement(4, "i", 4)(5, "input", 5);
500
502
  i0.ɵɵelementEnd()();
@@ -572,5 +574,5 @@ export class AddActionDialogComponent {
572
574
  }], () => [{ type: i0.ChangeDetectorRef }], { DialogClose: [{
573
575
  type: Output
574
576
  }] }); })();
575
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AddActionDialogComponent, { className: "AddActionDialogComponent", filePath: "src/lib/custom/AIAgents/add-action-dialog.component.ts", lineNumber: 32 }); })();
577
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AddActionDialogComponent, { className: "AddActionDialogComponent", filePath: "src/lib/custom/AIAgents/add-action-dialog.component.ts", lineNumber: 33 }); })();
576
578
  //# sourceMappingURL=add-action-dialog.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-action-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/add-action-dialog.component.ts","../../../../src/lib/custom/AIAgents/add-action-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { FormControl } from '@angular/forms';\nimport { Subject, BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, takeUntil, startWith } from 'rxjs';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJActionEntity, MJActionCategoryEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nexport interface CategoryTreeNode {\n id: string;\n name: string;\n count: number;\n icon: string;\n children?: CategoryTreeNode[];\n expanded?: boolean;\n}\n\nexport interface ActionDisplayItem extends MJActionEntity {\n selected: boolean;\n categoryName?: string;\n}\n\n/**\n * Modern, clean dialog for selecting actions to add to an AI Agent.\n * Features searchable action list, category filtering, and multi-select capability.\n */\n@Component({\n standalone: false,\n selector: 'mj-add-action-dialog',\n templateUrl: './add-action-dialog.component.html',\n styleUrls: ['./add-action-dialog.component.css']\n})\nexport class AddActionDialogComponent implements OnInit, OnDestroy {\n \n // Input properties set by service\n agentId: string = '';\n agentName: string = '';\n existingActionIds: string[] = [];\n\n // Reactive state management\n private destroy$ = new Subject<void>();\n public result = new Subject<MJActionEntity[]>();\n \n // Data streams\n allActions$ = new BehaviorSubject<ActionDisplayItem[]>([]);\n categories$ = new BehaviorSubject<MJActionCategoryEntity[]>([]);\n filteredActions$ = new BehaviorSubject<ActionDisplayItem[]>([]);\n categoryTree$ = new BehaviorSubject<CategoryTreeNode[]>([]);\n selectedActions$ = new BehaviorSubject<Set<string>>(new Set());\n isLoading$ = new BehaviorSubject<boolean>(false);\n \n // UI state\n searchControl = new FormControl('');\n selectedCategoryId$ = new BehaviorSubject<string>('all');\n viewMode$ = new BehaviorSubject<'grid' | 'list'>('grid');\n expandedCategories = new Set<string>();\n\n // Computed values\n get selectedCount(): number {\n return this.selectedActions$.value.size;\n }\n\n get totalActionCount(): number {\n return this.allActions$.value.length;\n }\n\n get filteredCount(): number {\n return this.filteredActions$.value.length;\n }\n\n @Output() DialogClose = new EventEmitter<void>();\n\n constructor(\n private cdr: ChangeDetectorRef\n ) {}\n\n ngOnInit() {\n this.initializeData();\n this.setupFiltering();\n this.preselectExistingActions();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private async initializeData() {\n this.isLoading$.next(true);\n \n try {\n await this.loadActionsAndCategories();\n this.buildCategoryTree();\n } catch (error) {\n console.error('Error loading dialog data:', error);\n } finally {\n this.isLoading$.next(false);\n }\n }\n\n private async loadActionsAndCategories() {\n const rv = new RunView();\n \n const [actionsResult, categoriesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Actions',\n ExtraFilter: 'Status = \\'Active\\'',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object',\n MaxRows: 5000\n },\n {\n EntityName: 'MJ: Action Categories',\n ExtraFilter: 'Status = \\'Active\\'',\n OrderBy: 'Name',\n ResultType: 'entity_object',\n MaxRows: 1000\n }\n ]);\n\n if (actionsResult.Success) {\n const actions = (actionsResult.Results as MJActionEntity[] || []).map(action => ({\n ...action.GetAll(),\n selected: false,\n categoryName: action.Category || 'Uncategorized'\n } as ActionDisplayItem));\n \n this.allActions$.next(actions);\n }\n\n if (categoriesResult.Success) {\n this.categories$.next(categoriesResult.Results as MJActionCategoryEntity[] || []);\n }\n }\n\n private buildCategoryTree() {\n const actions = this.allActions$.value;\n const categories = this.categories$.value;\n \n // Count actions per category\n const categoryCounts = new Map<string, number>();\n actions.forEach(action => {\n const categoryName = action.categoryName || 'Uncategorized';\n categoryCounts.set(categoryName, (categoryCounts.get(categoryName) || 0) + 1);\n });\n\n // Build tree nodes\n const treeNodes: CategoryTreeNode[] = [\n {\n id: 'all',\n name: 'All Actions',\n count: actions.length,\n icon: 'fa-th'\n }\n ];\n\n // Add category nodes\n categories.forEach(category => {\n const count = categoryCounts.get(category.Name) || 0;\n if (count > 0) {\n treeNodes.push({\n id: category.ID,\n name: category.Name,\n count,\n icon: this.getCategoryIcon(category.Name)\n });\n }\n });\n\n // Add uncategorized if needed\n const uncategorizedCount = categoryCounts.get('Uncategorized') || 0;\n if (uncategorizedCount > 0) {\n treeNodes.push({\n id: 'uncategorized',\n name: 'Uncategorized',\n count: uncategorizedCount,\n icon: 'fa-question-circle'\n });\n }\n\n this.categoryTree$.next(treeNodes);\n }\n\n private getCategoryIcon(categoryName: string): string {\n const iconMap: { [key: string]: string } = {\n 'Data': 'fa-database',\n 'Communication': 'fa-envelope',\n 'Integration': 'fa-plug',\n 'Security': 'fa-shield-alt',\n 'Workflow': 'fa-project-diagram',\n 'AI': 'fa-brain',\n 'Files': 'fa-file-alt',\n 'Utilities': 'fa-tools',\n 'System': 'fa-cog',\n 'Analytics': 'fa-chart-line'\n };\n return iconMap[categoryName] || 'fa-folder';\n }\n\n private setupFiltering() {\n combineLatest([\n this.allActions$,\n this.searchControl.valueChanges.pipe(\n debounceTime(300),\n distinctUntilChanged(),\n startWith('') // Emit initial empty value\n ),\n this.selectedCategoryId$\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(([actions, searchTerm, categoryId]) => {\n this.filterActions(actions, searchTerm || '', categoryId);\n });\n }\n\n private filterActions(actions: ActionDisplayItem[], searchTerm: string, categoryId: string) {\n let filtered = [...actions];\n\n // Category filter\n if (categoryId !== 'all') {\n if (categoryId === 'uncategorized') {\n filtered = filtered.filter(action => !action.Category);\n } else {\n const categoryName = this.getCategoryNameById(categoryId);\n filtered = filtered.filter(action => action.categoryName === categoryName);\n }\n }\n\n // Search filter\n if (searchTerm) {\n const term = searchTerm.toLowerCase();\n filtered = filtered.filter(action =>\n action.Name.toLowerCase().includes(term) ||\n (action.Description && action.Description.toLowerCase().includes(term)) ||\n (action.categoryName && action.categoryName.toLowerCase().includes(term))\n );\n }\n\n this.filteredActions$.next(filtered);\n }\n\n private getCategoryNameById(categoryId: string): string {\n const category = this.categories$.value.find(c => UUIDsEqual(c.ID, categoryId));\n return category?.Name || '';\n }\n\n private preselectExistingActions() {\n if (this.existingActionIds.length > 0) {\n const selected = new Set(this.existingActionIds);\n this.selectedActions$.next(selected);\n \n // Update action selection state\n const actions = this.allActions$.value;\n actions.forEach(action => {\n action.selected = selected.has(action.ID);\n });\n this.allActions$.next(actions);\n }\n }\n\n // === UI Event Handlers ===\n\n selectCategory(categoryId: string) {\n this.selectedCategoryId$.next(categoryId);\n }\n\n toggleViewMode() {\n const currentMode = this.viewMode$.value;\n this.viewMode$.next(currentMode === 'grid' ? 'list' : 'grid');\n }\n\n toggleActionSelection(action: ActionDisplayItem) {\n const selected = this.selectedActions$.value;\n const actions = this.allActions$.value;\n \n // Find the action and toggle its selection\n const actionToUpdate = actions.find(a => UUIDsEqual(a.ID, action.ID));\n if (actionToUpdate) {\n actionToUpdate.selected = !actionToUpdate.selected;\n \n if (actionToUpdate.selected) {\n selected.add(action.ID);\n } else {\n selected.delete(action.ID);\n }\n \n this.selectedActions$.next(new Set(selected));\n this.allActions$.next(actions);\n \n // Update filtered actions to reflect selection state\n const filtered = this.filteredActions$.value;\n const filteredAction = filtered.find(a => UUIDsEqual(a.ID, action.ID));\n if (filteredAction) {\n filteredAction.selected = actionToUpdate.selected;\n this.filteredActions$.next(filtered);\n }\n }\n }\n\n clearSearch() {\n this.searchControl.reset();\n }\n\n getActionIcon(action: ActionDisplayItem): string {\n // Return custom icon if set\n if (action.IconClass) {\n return action.IconClass;\n }\n\n // Fallback icon mapping based on action name/type\n const name = action.Name.toLowerCase();\n if (name.includes('create') || name.includes('add')) return 'fa-plus-circle';\n if (name.includes('update') || name.includes('edit')) return 'fa-edit';\n if (name.includes('delete') || name.includes('remove')) return 'fa-trash';\n if (name.includes('email') || name.includes('send')) return 'fa-envelope';\n if (name.includes('export')) return 'fa-file-export';\n if (name.includes('import')) return 'fa-file-import';\n if (name.includes('report')) return 'fa-file-alt';\n if (name.includes('api')) return 'fa-plug';\n \n return 'fa-bolt'; // Default action icon\n }\n\n // === Dialog Actions ===\n\n cancel() {\n this.result.next([]);\n this.DialogClose.emit();\n }\n\n addSelectedActions() {\n const selectedIds = this.selectedActions$.value;\n const allActions = this.allActions$.value;\n\n // Get the selected action display items (excluding existing ones)\n const selectedDisplayItems = allActions\n .filter(action => selectedIds.has(action.ID) && !this.existingActionIds.some(id => UUIDsEqual(id, action.ID)));\n\n // Convert ActionDisplayItem to MJActionEntity by casting (they have the same structure)\n const selectedActions: MJActionEntity[] = selectedDisplayItems.map(item => item as MJActionEntity);\n\n this.result.next(selectedActions);\n this.DialogClose.emit();\n }\n}","<!-- Add Action Dialog -->\n<div class=\"add-action-dialog\">\n \n <!-- Dialog Header -->\n <div class=\"dialog-header\">\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search search-prefix-icon\"></i>\n <input\n class=\"mj-input search-input\"\n [formControl]=\"searchControl\"\n placeholder=\"Search actions by name, description, or category...\">\n </div>\n </div>\n \n <div class=\"header-actions\">\n <!-- View Toggle -->\n <button mjButton\n variant=\"flat\"\n (click)=\"toggleViewMode()\"\n [title]=\"(viewMode$ | async) === 'grid' ? 'Switch to list view' : 'Switch to grid view'\">\n <i class=\"fa-solid\"\n [class.fa-th]=\"(viewMode$ | async) === 'grid'\"\n [class.fa-list]=\"(viewMode$ | async) === 'list'\"></i>\n </button>\n \n <!-- Stats -->\n <div class=\"stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-bolt\"></i>\n {{ filteredCount }} of {{ totalActionCount }} actions\n </span>\n </div>\n </div>\n </div>\n\n <!-- Main Content -->\n <div class=\"dialog-content\">\n \n <!-- Category Sidebar -->\n <div class=\"category-sidebar\">\n <div class=\"sidebar-header\">\n <h4><i class=\"fa-solid fa-folder-tree\"></i> Categories</h4>\n </div>\n \n <div class=\"category-list\">\n @for (category of categoryTree$ | async; track category.id) {\n <div class=\"category-item\" \n [class.selected]=\"(selectedCategoryId$ | async) === category.id\"\n (click)=\"selectCategory(category.id)\">\n <i class=\"fa-solid {{ category.icon }} category-icon\"></i>\n <span class=\"category-name\">{{ category.name }}</span>\n <span class=\"category-count\">{{ category.count }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Actions Display -->\n <div class=\"actions-container\">\n \n <!-- Loading State -->\n @if (isLoading$ | async) {\n <div class=\"loading-state\">\n <div class=\"loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin fa-2x\"></i>\n </div>\n <p>Loading actions...</p>\n </div>\n }\n\n <!-- Empty State -->\n @if (!(isLoading$ | async) && filteredCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search-minus\"></i>\n <h3>No actions found</h3>\n <p>Try adjusting your search criteria or selecting a different category</p>\n <button mjButton (click)=\"clearSearch()\">Clear Search</button>\n </div>\n }\n\n <!-- Grid View -->\n @if (!(isLoading$ | async) && (viewMode$ | async) === 'grid' && filteredCount > 0) {\n <div class=\"actions-grid\">\n @for (action of filteredActions$ | async; track action.ID) {\n <div class=\"action-card\" \n [class.selected]=\"action.selected\"\n [class.existing]=\"existingActionIds.includes(action.ID)\"\n (click)=\"toggleActionSelection(action)\">\n \n <!-- Selection Indicator -->\n <div class=\"selection-indicator\">\n <i class=\"fa-solid\" \n [class.fa-check-circle]=\"action.selected\" \n [class.fa-circle]=\"!action.selected\"></i>\n </div>\n \n <!-- Card Content -->\n <div class=\"card-header\">\n <div class=\"action-icon\">\n <i class=\"fa-solid {{ getActionIcon(action) }}\"></i>\n </div>\n <h3 class=\"action-name\">{{ action.Name }}</h3>\n </div>\n \n <div class=\"card-body\">\n <p class=\"action-description\">{{ action.Description || 'No description available' }}</p>\n \n @if (action.categoryName) {\n <div class=\"category-badge\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ action.categoryName }}\n </div>\n }\n \n @if (action.Type) {\n <div class=\"type-badge\">\n <i class=\"fa-solid fa-tag\"></i>\n {{ action.Type }}\n </div>\n }\n </div>\n \n <!-- Existing Action Overlay -->\n @if (existingActionIds.includes(action.ID)) {\n <div class=\"existing-overlay\">\n <i class=\"fa-solid fa-check\"></i>\n <span>Already Added</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- List View -->\n @if (!(isLoading$ | async) && (viewMode$ | async) === 'list' && filteredCount > 0) {\n <div class=\"actions-list\">\n \n <!-- List Header -->\n <div class=\"list-header\">\n <span class=\"col-select\"></span>\n <span class=\"col-name\">Name</span>\n <span class=\"col-category\">Category</span>\n <span class=\"col-type\">Type</span>\n <span class=\"col-description\">Description</span>\n <span class=\"col-status\">Status</span>\n </div>\n \n <!-- List Items -->\n @for (action of filteredActions$ | async; track action.ID) {\n <div class=\"list-item\" \n [class.selected]=\"action.selected\"\n [class.existing]=\"existingActionIds.includes(action.ID)\"\n (click)=\"toggleActionSelection(action)\">\n \n <span class=\"col-select\">\n <i class=\"fa-solid\" \n [class.fa-check-circle]=\"action.selected\" \n [class.fa-circle]=\"!action.selected\"></i>\n </span>\n \n <span class=\"col-name\">\n <i class=\"fa-solid {{ getActionIcon(action) }} action-icon\"></i>\n {{ action.Name }}\n </span>\n \n <span class=\"col-category\">{{ action.categoryName || '-' }}</span>\n <span class=\"col-type\">{{ action.Type || '-' }}</span>\n <span class=\"col-description\">{{ action.Description || '-' }}</span>\n \n <span class=\"col-status\">\n @if (existingActionIds.includes(action.ID)) {\n <span class=\"status-badge existing\">\n <i class=\"fa-solid fa-check\"></i>\n Added\n </span>\n } @else {\n <span class=\"status-badge available\">\n <i class=\"fa-solid fa-plus\"></i>\n Available\n </span>\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Actions Summary -->\n @if (selectedCount > 0) {\n <div class=\"selection-summary\">\n <div class=\"summary-content\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>{{ selectedCount }} action{{ selectedCount === 1 ? '' : 's' }} selected</span>\n </div>\n </div>\n }\n\n <!-- Dialog Footer -->\n <div class=\"dialog-footer\">\n <button mjButton\n variant=\"flat\"\n (click)=\"cancel()\">\n Cancel\n </button>\n\n <button mjButton\n variant=\"primary\"\n [disabled]=\"selectedCount === 0\"\n (click)=\"addSelectedActions()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Selected ({{ selectedCount }})\n </button>\n </div>\n</div>"]}
1
+ {"version":3,"file":"add-action-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/add-action-dialog.component.ts","../../../../src/lib/custom/AIAgents/add-action-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, OnDestroy, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';\nimport { FormControl } from '@angular/forms';\nimport { Subject, BehaviorSubject, combineLatest, debounceTime, distinctUntilChanged, takeUntil, startWith } from 'rxjs';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJActionEntity, MJActionCategoryEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface CategoryTreeNode {\n id: string;\n name: string;\n count: number;\n icon: string;\n children?: CategoryTreeNode[];\n expanded?: boolean;\n}\n\nexport interface ActionDisplayItem extends MJActionEntity {\n selected: boolean;\n categoryName?: string;\n}\n\n/**\n * Modern, clean dialog for selecting actions to add to an AI Agent.\n * Features searchable action list, category filtering, and multi-select capability.\n */\n@Component({\n standalone: false,\n selector: 'mj-add-action-dialog',\n templateUrl: './add-action-dialog.component.html',\n styleUrls: ['./add-action-dialog.component.css']\n})\nexport class AddActionDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n \n // Input properties set by service\n agentId: string = '';\n agentName: string = '';\n existingActionIds: string[] = [];\n\n // Reactive state management\n private destroy$ = new Subject<void>();\n public result = new Subject<MJActionEntity[]>();\n \n // Data streams\n allActions$ = new BehaviorSubject<ActionDisplayItem[]>([]);\n categories$ = new BehaviorSubject<MJActionCategoryEntity[]>([]);\n filteredActions$ = new BehaviorSubject<ActionDisplayItem[]>([]);\n categoryTree$ = new BehaviorSubject<CategoryTreeNode[]>([]);\n selectedActions$ = new BehaviorSubject<Set<string>>(new Set());\n isLoading$ = new BehaviorSubject<boolean>(false);\n \n // UI state\n searchControl = new FormControl('');\n selectedCategoryId$ = new BehaviorSubject<string>('all');\n viewMode$ = new BehaviorSubject<'grid' | 'list'>('grid');\n expandedCategories = new Set<string>();\n\n // Computed values\n get selectedCount(): number {\n return this.selectedActions$.value.size;\n }\n\n get totalActionCount(): number {\n return this.allActions$.value.length;\n }\n\n get filteredCount(): number {\n return this.filteredActions$.value.length;\n }\n\n @Output() DialogClose = new EventEmitter<void>();\n\n constructor(\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n ngOnInit() {\n this.initializeData();\n this.setupFiltering();\n this.preselectExistingActions();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n private async initializeData() {\n this.isLoading$.next(true);\n \n try {\n await this.loadActionsAndCategories();\n this.buildCategoryTree();\n } catch (error) {\n console.error('Error loading dialog data:', error);\n } finally {\n this.isLoading$.next(false);\n }\n }\n\n private async loadActionsAndCategories() {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n \n const [actionsResult, categoriesResult] = await rv.RunViews([\n {\n EntityName: 'MJ: Actions',\n ExtraFilter: 'Status = \\'Active\\'',\n OrderBy: 'Category, Name',\n ResultType: 'entity_object',\n MaxRows: 5000\n },\n {\n EntityName: 'MJ: Action Categories',\n ExtraFilter: 'Status = \\'Active\\'',\n OrderBy: 'Name',\n ResultType: 'entity_object',\n MaxRows: 1000\n }\n ]);\n\n if (actionsResult.Success) {\n const actions = (actionsResult.Results as MJActionEntity[] || []).map(action => ({\n ...action.GetAll(),\n selected: false,\n categoryName: action.Category || 'Uncategorized'\n } as ActionDisplayItem));\n \n this.allActions$.next(actions);\n }\n\n if (categoriesResult.Success) {\n this.categories$.next(categoriesResult.Results as MJActionCategoryEntity[] || []);\n }\n }\n\n private buildCategoryTree() {\n const actions = this.allActions$.value;\n const categories = this.categories$.value;\n \n // Count actions per category\n const categoryCounts = new Map<string, number>();\n actions.forEach(action => {\n const categoryName = action.categoryName || 'Uncategorized';\n categoryCounts.set(categoryName, (categoryCounts.get(categoryName) || 0) + 1);\n });\n\n // Build tree nodes\n const treeNodes: CategoryTreeNode[] = [\n {\n id: 'all',\n name: 'All Actions',\n count: actions.length,\n icon: 'fa-th'\n }\n ];\n\n // Add category nodes\n categories.forEach(category => {\n const count = categoryCounts.get(category.Name) || 0;\n if (count > 0) {\n treeNodes.push({\n id: category.ID,\n name: category.Name,\n count,\n icon: this.getCategoryIcon(category.Name)\n });\n }\n });\n\n // Add uncategorized if needed\n const uncategorizedCount = categoryCounts.get('Uncategorized') || 0;\n if (uncategorizedCount > 0) {\n treeNodes.push({\n id: 'uncategorized',\n name: 'Uncategorized',\n count: uncategorizedCount,\n icon: 'fa-question-circle'\n });\n }\n\n this.categoryTree$.next(treeNodes);\n }\n\n private getCategoryIcon(categoryName: string): string {\n const iconMap: { [key: string]: string } = {\n 'Data': 'fa-database',\n 'Communication': 'fa-envelope',\n 'Integration': 'fa-plug',\n 'Security': 'fa-shield-alt',\n 'Workflow': 'fa-project-diagram',\n 'AI': 'fa-brain',\n 'Files': 'fa-file-alt',\n 'Utilities': 'fa-tools',\n 'System': 'fa-cog',\n 'Analytics': 'fa-chart-line'\n };\n return iconMap[categoryName] || 'fa-folder';\n }\n\n private setupFiltering() {\n combineLatest([\n this.allActions$,\n this.searchControl.valueChanges.pipe(\n debounceTime(300),\n distinctUntilChanged(),\n startWith('') // Emit initial empty value\n ),\n this.selectedCategoryId$\n ]).pipe(\n takeUntil(this.destroy$)\n ).subscribe(([actions, searchTerm, categoryId]) => {\n this.filterActions(actions, searchTerm || '', categoryId);\n });\n }\n\n private filterActions(actions: ActionDisplayItem[], searchTerm: string, categoryId: string) {\n let filtered = [...actions];\n\n // Category filter\n if (categoryId !== 'all') {\n if (categoryId === 'uncategorized') {\n filtered = filtered.filter(action => !action.Category);\n } else {\n const categoryName = this.getCategoryNameById(categoryId);\n filtered = filtered.filter(action => action.categoryName === categoryName);\n }\n }\n\n // Search filter\n if (searchTerm) {\n const term = searchTerm.toLowerCase();\n filtered = filtered.filter(action =>\n action.Name.toLowerCase().includes(term) ||\n (action.Description && action.Description.toLowerCase().includes(term)) ||\n (action.categoryName && action.categoryName.toLowerCase().includes(term))\n );\n }\n\n this.filteredActions$.next(filtered);\n }\n\n private getCategoryNameById(categoryId: string): string {\n const category = this.categories$.value.find(c => UUIDsEqual(c.ID, categoryId));\n return category?.Name || '';\n }\n\n private preselectExistingActions() {\n if (this.existingActionIds.length > 0) {\n const selected = new Set(this.existingActionIds);\n this.selectedActions$.next(selected);\n \n // Update action selection state\n const actions = this.allActions$.value;\n actions.forEach(action => {\n action.selected = selected.has(action.ID);\n });\n this.allActions$.next(actions);\n }\n }\n\n // === UI Event Handlers ===\n\n selectCategory(categoryId: string) {\n this.selectedCategoryId$.next(categoryId);\n }\n\n toggleViewMode() {\n const currentMode = this.viewMode$.value;\n this.viewMode$.next(currentMode === 'grid' ? 'list' : 'grid');\n }\n\n toggleActionSelection(action: ActionDisplayItem) {\n const selected = this.selectedActions$.value;\n const actions = this.allActions$.value;\n \n // Find the action and toggle its selection\n const actionToUpdate = actions.find(a => UUIDsEqual(a.ID, action.ID));\n if (actionToUpdate) {\n actionToUpdate.selected = !actionToUpdate.selected;\n \n if (actionToUpdate.selected) {\n selected.add(action.ID);\n } else {\n selected.delete(action.ID);\n }\n \n this.selectedActions$.next(new Set(selected));\n this.allActions$.next(actions);\n \n // Update filtered actions to reflect selection state\n const filtered = this.filteredActions$.value;\n const filteredAction = filtered.find(a => UUIDsEqual(a.ID, action.ID));\n if (filteredAction) {\n filteredAction.selected = actionToUpdate.selected;\n this.filteredActions$.next(filtered);\n }\n }\n }\n\n clearSearch() {\n this.searchControl.reset();\n }\n\n getActionIcon(action: ActionDisplayItem): string {\n // Return custom icon if set\n if (action.IconClass) {\n return action.IconClass;\n }\n\n // Fallback icon mapping based on action name/type\n const name = action.Name.toLowerCase();\n if (name.includes('create') || name.includes('add')) return 'fa-plus-circle';\n if (name.includes('update') || name.includes('edit')) return 'fa-edit';\n if (name.includes('delete') || name.includes('remove')) return 'fa-trash';\n if (name.includes('email') || name.includes('send')) return 'fa-envelope';\n if (name.includes('export')) return 'fa-file-export';\n if (name.includes('import')) return 'fa-file-import';\n if (name.includes('report')) return 'fa-file-alt';\n if (name.includes('api')) return 'fa-plug';\n \n return 'fa-bolt'; // Default action icon\n }\n\n // === Dialog Actions ===\n\n cancel() {\n this.result.next([]);\n this.DialogClose.emit();\n }\n\n addSelectedActions() {\n const selectedIds = this.selectedActions$.value;\n const allActions = this.allActions$.value;\n\n // Get the selected action display items (excluding existing ones)\n const selectedDisplayItems = allActions\n .filter(action => selectedIds.has(action.ID) && !this.existingActionIds.some(id => UUIDsEqual(id, action.ID)));\n\n // Convert ActionDisplayItem to MJActionEntity by casting (they have the same structure)\n const selectedActions: MJActionEntity[] = selectedDisplayItems.map(item => item as MJActionEntity);\n\n this.result.next(selectedActions);\n this.DialogClose.emit();\n }\n}","<!-- Add Action Dialog -->\n<div class=\"add-action-dialog\">\n \n <!-- Dialog Header -->\n <div class=\"dialog-header\">\n <div class=\"search-section\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-search search-prefix-icon\"></i>\n <input\n class=\"mj-input search-input\"\n [formControl]=\"searchControl\"\n placeholder=\"Search actions by name, description, or category...\">\n </div>\n </div>\n \n <div class=\"header-actions\">\n <!-- View Toggle -->\n <button mjButton\n variant=\"flat\"\n (click)=\"toggleViewMode()\"\n [title]=\"(viewMode$ | async) === 'grid' ? 'Switch to list view' : 'Switch to grid view'\">\n <i class=\"fa-solid\"\n [class.fa-th]=\"(viewMode$ | async) === 'grid'\"\n [class.fa-list]=\"(viewMode$ | async) === 'list'\"></i>\n </button>\n \n <!-- Stats -->\n <div class=\"stats\">\n <span class=\"stat-item\">\n <i class=\"fa-solid fa-bolt\"></i>\n {{ filteredCount }} of {{ totalActionCount }} actions\n </span>\n </div>\n </div>\n </div>\n\n <!-- Main Content -->\n <div class=\"dialog-content\">\n \n <!-- Category Sidebar -->\n <div class=\"category-sidebar\">\n <div class=\"sidebar-header\">\n <h4><i class=\"fa-solid fa-folder-tree\"></i> Categories</h4>\n </div>\n \n <div class=\"category-list\">\n @for (category of categoryTree$ | async; track category.id) {\n <div class=\"category-item\" \n [class.selected]=\"(selectedCategoryId$ | async) === category.id\"\n (click)=\"selectCategory(category.id)\">\n <i class=\"fa-solid {{ category.icon }} category-icon\"></i>\n <span class=\"category-name\">{{ category.name }}</span>\n <span class=\"category-count\">{{ category.count }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Actions Display -->\n <div class=\"actions-container\">\n \n <!-- Loading State -->\n @if (isLoading$ | async) {\n <div class=\"loading-state\">\n <div class=\"loading-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin fa-2x\"></i>\n </div>\n <p>Loading actions...</p>\n </div>\n }\n\n <!-- Empty State -->\n @if (!(isLoading$ | async) && filteredCount === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search-minus\"></i>\n <h3>No actions found</h3>\n <p>Try adjusting your search criteria or selecting a different category</p>\n <button mjButton (click)=\"clearSearch()\">Clear Search</button>\n </div>\n }\n\n <!-- Grid View -->\n @if (!(isLoading$ | async) && (viewMode$ | async) === 'grid' && filteredCount > 0) {\n <div class=\"actions-grid\">\n @for (action of filteredActions$ | async; track action.ID) {\n <div class=\"action-card\" \n [class.selected]=\"action.selected\"\n [class.existing]=\"existingActionIds.includes(action.ID)\"\n (click)=\"toggleActionSelection(action)\">\n \n <!-- Selection Indicator -->\n <div class=\"selection-indicator\">\n <i class=\"fa-solid\" \n [class.fa-check-circle]=\"action.selected\" \n [class.fa-circle]=\"!action.selected\"></i>\n </div>\n \n <!-- Card Content -->\n <div class=\"card-header\">\n <div class=\"action-icon\">\n <i class=\"fa-solid {{ getActionIcon(action) }}\"></i>\n </div>\n <h3 class=\"action-name\">{{ action.Name }}</h3>\n </div>\n \n <div class=\"card-body\">\n <p class=\"action-description\">{{ action.Description || 'No description available' }}</p>\n \n @if (action.categoryName) {\n <div class=\"category-badge\">\n <i class=\"fa-solid fa-folder\"></i>\n {{ action.categoryName }}\n </div>\n }\n \n @if (action.Type) {\n <div class=\"type-badge\">\n <i class=\"fa-solid fa-tag\"></i>\n {{ action.Type }}\n </div>\n }\n </div>\n \n <!-- Existing Action Overlay -->\n @if (existingActionIds.includes(action.ID)) {\n <div class=\"existing-overlay\">\n <i class=\"fa-solid fa-check\"></i>\n <span>Already Added</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- List View -->\n @if (!(isLoading$ | async) && (viewMode$ | async) === 'list' && filteredCount > 0) {\n <div class=\"actions-list\">\n \n <!-- List Header -->\n <div class=\"list-header\">\n <span class=\"col-select\"></span>\n <span class=\"col-name\">Name</span>\n <span class=\"col-category\">Category</span>\n <span class=\"col-type\">Type</span>\n <span class=\"col-description\">Description</span>\n <span class=\"col-status\">Status</span>\n </div>\n \n <!-- List Items -->\n @for (action of filteredActions$ | async; track action.ID) {\n <div class=\"list-item\" \n [class.selected]=\"action.selected\"\n [class.existing]=\"existingActionIds.includes(action.ID)\"\n (click)=\"toggleActionSelection(action)\">\n \n <span class=\"col-select\">\n <i class=\"fa-solid\" \n [class.fa-check-circle]=\"action.selected\" \n [class.fa-circle]=\"!action.selected\"></i>\n </span>\n \n <span class=\"col-name\">\n <i class=\"fa-solid {{ getActionIcon(action) }} action-icon\"></i>\n {{ action.Name }}\n </span>\n \n <span class=\"col-category\">{{ action.categoryName || '-' }}</span>\n <span class=\"col-type\">{{ action.Type || '-' }}</span>\n <span class=\"col-description\">{{ action.Description || '-' }}</span>\n \n <span class=\"col-status\">\n @if (existingActionIds.includes(action.ID)) {\n <span class=\"status-badge existing\">\n <i class=\"fa-solid fa-check\"></i>\n Added\n </span>\n } @else {\n <span class=\"status-badge available\">\n <i class=\"fa-solid fa-plus\"></i>\n Available\n </span>\n }\n </span>\n </div>\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Actions Summary -->\n @if (selectedCount > 0) {\n <div class=\"selection-summary\">\n <div class=\"summary-content\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>{{ selectedCount }} action{{ selectedCount === 1 ? '' : 's' }} selected</span>\n </div>\n </div>\n }\n\n <!-- Dialog Footer -->\n <div class=\"dialog-footer\">\n <button mjButton\n variant=\"flat\"\n (click)=\"cancel()\">\n Cancel\n </button>\n\n <button mjButton\n variant=\"primary\"\n [disabled]=\"selectedCount === 0\"\n (click)=\"addSelectedActions()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add Selected ({{ selectedCount }})\n </button>\n </div>\n</div>"]}
@@ -132,7 +132,7 @@
132
132
  // private async loadDropdownData() {
133
133
  // this.isLoading$.next(true);
134
134
  // try {
135
- // const rv = new RunView();
135
+ // const rv = RunView.FromMetadataProvider(this.ProviderToUse);
136
136
  // const agentTypesResult = await rv.RunView<MJAIAgentTypeEntity>({
137
137
  // EntityName: 'MJ: AI Agent Types',
138
138
  // ExtraFilter: 'IsActive = 1',
@@ -157,7 +157,7 @@
157
157
  // private async loadSelectedCompressionPrompt() {
158
158
  // if (this.agent.ContextCompressionPromptID) {
159
159
  // try {
160
- // const rv = new RunView();
160
+ // const rv = RunView.FromMetadataProvider(this.ProviderToUse);
161
161
  // const result = await rv.RunView<MJAIPromptEntityExtended>({
162
162
  // EntityName: 'MJ: AI Prompts',
163
163
  // ExtraFilter: `ID = '${this.agent.ContextCompressionPromptID}'`,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-advanced-settings-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/agent-advanced-settings-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["// import { Component, OnInit, OnDestroy, ChangeDetectorRef, ViewContainerRef } from '@angular/core';\n// import { FormGroup, FormBuilder, Validators } from '@angular/forms';\n// import { Subject, BehaviorSubject, takeUntil } from 'rxjs';\n// import { RunView, Metadata } from '@memberjunction/core';\n// import { MJAIAgentEntityExtended, MJAIAgentTypeEntity, MJAIPromptEntityExtended } from '@memberjunction/core-entities';\n// import { MJNotificationService } from '@memberjunction/ng-notifications';\n// import { Router } from '@angular/router';\n// import { AIAgentManagementService } from './ai-agent-management.service';\n\n// export interface AdvancedSettingsFormData {\n// // Identity & Behavior\n// logoURL: string | null;\n// iconClass: string | null;\n// driverClass: string | null;\n \n// // System Configuration \n// exposeAsAction: boolean;\n// typeID: string | null;\n// status: string | null;\n \n// // Context Compression\n// enableContextCompression: boolean;\n// contextCompressionMessageThreshold: number | null;\n// contextCompressionPromptID: string | null;\n// contextCompressionMessageRetentionCount: number | null;\n \n// // Payload Control\n// payloadDownstreamPaths: string;\n// payloadUpstreamPaths: string;\n// payloadSelfReadPaths: string | null;\n// payloadSelfWritePaths: string | null;\n// }\n\n// /**\n// * Advanced Settings dialog for AI Agents.\n// * Provides access to all advanced configuration options not available in the main UI.\n// */\n// @Component({\n// standalone: false,\n// selector: 'mj-agent-advanced-settings-dialog',\n// templateUrl: './agent-advanced-settings-dialog.component.html',\n// styleUrls: ['./agent-advanced-settings-dialog.component.css']\n// })\n// export class AgentAdvancedSettingsDialogComponent implements OnInit, OnDestroy {\n \n// // Input properties set by service\n// agent!: MJAIAgentEntityExtended;\n \n// // Reactive state management\n// private destroy$ = new Subject<void>();\n// public result = new Subject<AdvancedSettingsFormData | null>();\n \n// // Form and data\n// advancedForm!: FormGroup;\n// isLoading$ = new BehaviorSubject<boolean>(false);\n// isSaving$ = new BehaviorSubject<boolean>(false);\n \n// // Dropdown data\n// agentTypes$ = new BehaviorSubject<MJAIAgentTypeEntity[]>([]);\n \n// // Selected compression prompt\n// selectedCompressionPrompt: MJAIPromptEntityExtended | null = null;\n \n// // Available options\n// statusOptions = [\n// { text: 'Active', value: 'Active' },\n// { text: 'Disabled', value: 'Disabled' },\n// { text: 'Pending', value: 'Pending' }\n// ];\n\n// constructor(\n// private dialogRef: DialogRef,\n// private fb: FormBuilder,\n// private cdr: ChangeDetectorRef,\n// private router: Router,\n// private agentManagementService: AIAgentManagementService,\n// private viewContainerRef: ViewContainerRef\n// ) {}\n\n// ngOnInit() {\n// this.initializeForm();\n// this.loadDropdownData();\n// this.loadSelectedCompressionPrompt();\n// }\n\n// ngOnDestroy() {\n// this.destroy$.next();\n// this.destroy$.complete();\n// }\n\n// private initializeForm() {\n// this.advancedForm = this.fb.group({\n// // Identity & Behavior\n// logoURL: [this.agent.LogoURL],\n// iconClass: [this.agent.IconClass],\n// driverClass: [this.agent.DriverClass],\n \n// // System Configuration\n// exposeAsAction: [this.agent.ExposeAsAction],\n// typeID: [this.agent.TypeID],\n// status: [this.agent.Status],\n \n// // Context Compression\n// enableContextCompression: [this.agent.EnableContextCompression],\n// contextCompressionMessageThreshold: [this.agent.ContextCompressionMessageThreshold, [Validators.min(1)]],\n// contextCompressionPromptID: [this.agent.ContextCompressionPromptID],\n// contextCompressionMessageRetentionCount: [this.agent.ContextCompressionMessageRetentionCount, [Validators.min(1)]],\n \n// // Payload Control\n// payloadDownstreamPaths: [this.agent.PayloadDownstreamPaths, [Validators.required]],\n// payloadUpstreamPaths: [this.agent.PayloadUpstreamPaths, [Validators.required]],\n// payloadSelfReadPaths: [this.agent.PayloadSelfReadPaths],\n// payloadSelfWritePaths: [this.agent.PayloadSelfWritePaths]\n// });\n\n// // Set up validation dependencies\n// this.setupValidationLogic();\n// }\n\n// private setupValidationLogic() {\n// // Context compression validation\n// const enableCompressionControl = this.advancedForm.get('enableContextCompression');\n// const thresholdControl = this.advancedForm.get('contextCompressionMessageThreshold');\n// const promptControl = this.advancedForm.get('contextCompressionPromptID');\n// const retentionControl = this.advancedForm.get('contextCompressionMessageRetentionCount');\n\n// enableCompressionControl?.valueChanges.pipe(\n// takeUntil(this.destroy$)\n// ).subscribe(enabled => {\n// if (enabled) {\n// thresholdControl?.setValidators([Validators.required, Validators.min(1)]);\n// promptControl?.setValidators([Validators.required]);\n// retentionControl?.setValidators([Validators.required, Validators.min(1)]);\n// } else {\n// // Clear validators and reset values to null when disabled\n// thresholdControl?.clearValidators();\n// promptControl?.clearValidators();\n// retentionControl?.clearValidators();\n \n// // Reset field values to null\n// thresholdControl?.setValue(null);\n// promptControl?.setValue(null);\n// retentionControl?.setValue(null);\n \n// // Clear the selected compression prompt display\n// this.selectedCompressionPrompt = null;\n// }\n// thresholdControl?.updateValueAndValidity();\n// promptControl?.updateValueAndValidity();\n// retentionControl?.updateValueAndValidity();\n// });\n\n// // Note: ParentID vs ExposeAsAction validation is now handled in the sub-agents section\n// }\n\n// private async loadDropdownData() {\n// this.isLoading$.next(true);\n \n// try {\n// const rv = new RunView();\n \n// const agentTypesResult = await rv.RunView<MJAIAgentTypeEntity>({\n// EntityName: 'MJ: AI Agent Types',\n// ExtraFilter: 'IsActive = 1',\n// OrderBy: 'Name',\n// ResultType: 'entity_object',\n// MaxRows: 1000\n// });\n\n// if (agentTypesResult.Success) {\n// this.agentTypes$.next(agentTypesResult.Results || []);\n// }\n\n// } catch (error) {\n// console.error('Error loading dropdown data:', error);\n// MJNotificationService.Instance.CreateSimpleNotification(\n// 'Error loading form data. Please try again.',\n// 'error',\n// 3000\n// );\n// } finally {\n// this.isLoading$.next(false);\n// }\n// }\n\n// private async loadSelectedCompressionPrompt() {\n// if (this.agent.ContextCompressionPromptID) {\n// try {\n// const rv = new RunView();\n// const result = await rv.RunView<MJAIPromptEntityExtended>({\n// EntityName: 'MJ: AI Prompts',\n// ExtraFilter: `ID = '${this.agent.ContextCompressionPromptID}'`,\n// ResultType: 'entity_object',\n// MaxRows: 1\n// });\n\n// if (result.Success && result.Results && result.Results.length > 0) {\n// this.selectedCompressionPrompt = result.Results[0];\n// }\n// } catch (error) {\n// console.error('Error loading compression prompt:', error);\n// }\n// }\n// }\n\n// // === Validation Helpers ===\n\n// isFieldInvalid(fieldName: string): boolean {\n// const field = this.advancedForm.get(fieldName);\n// return !!(field && field.invalid && (field.dirty || field.touched));\n// }\n\n// getFieldError(fieldName: string): string {\n// const field = this.advancedForm.get(fieldName);\n// if (field?.errors) {\n// if (field.errors['required']) return 'This field is required';\n// if (field.errors['min']) return `Minimum value is ${field.errors['min'].min}`;\n// }\n// return '';\n// }\n\n// // === JSON Helpers ===\n\n// isValidJSON(value: string): boolean {\n// try {\n// JSON.parse(value);\n// return true;\n// } catch {\n// return false;\n// }\n// }\n\n// formatJSON(fieldName: string) {\n// const control = this.advancedForm.get(fieldName);\n// if (control?.value) {\n// try {\n// const parsed = JSON.parse(control.value);\n// const formatted = JSON.stringify(parsed, null, 2);\n// control.setValue(formatted);\n// } catch {\n// // Invalid JSON, leave as is\n// }\n// }\n// }\n\n// resetToDefault(fieldName: string) {\n// const control = this.advancedForm.get(fieldName);\n// if (fieldName === 'payloadDownstreamPaths' || fieldName === 'payloadUpstreamPaths') {\n// control?.setValue('[\"*\"]');\n// } else {\n// control?.setValue(null);\n// }\n// }\n\n// selectCompressionPrompt() {\n// this.agentManagementService.openContextCompressionPromptSelector({\n// currentPromptId: this.selectedCompressionPrompt?.ID,\n// viewContainerRef: this.viewContainerRef\n// }).subscribe(selectedPrompt => {\n// if (selectedPrompt) {\n// this.selectedCompressionPrompt = selectedPrompt;\n// this.advancedForm.get('contextCompressionPromptID')?.setValue(selectedPrompt.ID);\n// }\n// });\n// }\n\n// clearCompressionPrompt() {\n// this.selectedCompressionPrompt = null;\n// this.advancedForm.get('contextCompressionPromptID')?.setValue(null);\n// }\n\n// viewContextCompressionPrompt() {\n// if (this.selectedCompressionPrompt?.ID) {\n// // Navigate to the AI Prompt form\n// this.router.navigate(['/form', 'MJ: AI Prompts', this.selectedCompressionPrompt.ID]);\n// }\n// }\n\n// // === Dialog Actions ===\n\n// cancel() {\n// this.result.next(null);\n// this.dialogRef.close();\n// }\n\n// async save() {\n// if (this.advancedForm.invalid) {\n// // Mark all fields as touched to show validation errors\n// Object.keys(this.advancedForm.controls).forEach(key => {\n// this.advancedForm.get(key)?.markAsTouched();\n// });\n// return;\n// }\n\n// this.isSaving$.next(true);\n \n// try {\n// const formData: AdvancedSettingsFormData = this.advancedForm.value;\n \n// // Validate JSON fields\n// const jsonFields = ['payloadDownstreamPaths', 'payloadUpstreamPaths', 'payloadSelfReadPaths', 'payloadSelfWritePaths'];\n// for (const field of jsonFields) {\n// const value = formData[field as keyof AdvancedSettingsFormData];\n// if (value && typeof value === 'string' && !this.isValidJSON(value)) {\n// MJNotificationService.Instance.CreateSimpleNotification(\n// `Invalid JSON in ${field.replace(/([A-Z])/g, ' $1').toLowerCase()}`,\n// 'error',\n// 3000\n// );\n// this.isSaving$.next(false);\n// return;\n// }\n// }\n\n// this.result.next(formData);\n// this.dialogRef.close();\n \n// } catch (error) {\n// console.error('Error saving advanced settings:', error);\n// MJNotificationService.Instance.CreateSimpleNotification(\n// 'Error saving settings. Please try again.',\n// 'error',\n// 3000\n// );\n// } finally {\n// this.isSaving$.next(false);\n// }\n// }\n// }"]}
1
+ {"version":3,"file":"agent-advanced-settings-dialog.component.js","sourceRoot":"","sources":["../../../../src/lib/custom/AIAgents/agent-advanced-settings-dialog.component.ts"],"names":[],"mappings":"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","sourcesContent":["// import { Component, OnInit, OnDestroy, ChangeDetectorRef, ViewContainerRef } from '@angular/core';\n// import { FormGroup, FormBuilder, Validators } from '@angular/forms';\n// import { Subject, BehaviorSubject, takeUntil } from 'rxjs';\n// import { RunView, Metadata } from '@memberjunction/core';\n// import { MJAIAgentEntityExtended, MJAIAgentTypeEntity, MJAIPromptEntityExtended } from '@memberjunction/core-entities';\n// import { MJNotificationService } from '@memberjunction/ng-notifications';\n// import { Router } from '@angular/router';\n// import { AIAgentManagementService } from './ai-agent-management.service';\n\n// export interface AdvancedSettingsFormData {\n// // Identity & Behavior\n// logoURL: string | null;\n// iconClass: string | null;\n// driverClass: string | null;\n \n// // System Configuration \n// exposeAsAction: boolean;\n// typeID: string | null;\n// status: string | null;\n \n// // Context Compression\n// enableContextCompression: boolean;\n// contextCompressionMessageThreshold: number | null;\n// contextCompressionPromptID: string | null;\n// contextCompressionMessageRetentionCount: number | null;\n \n// // Payload Control\n// payloadDownstreamPaths: string;\n// payloadUpstreamPaths: string;\n// payloadSelfReadPaths: string | null;\n// payloadSelfWritePaths: string | null;\n// }\n\n// /**\n// * Advanced Settings dialog for AI Agents.\n// * Provides access to all advanced configuration options not available in the main UI.\n// */\n// @Component({\n// standalone: false,\n// selector: 'mj-agent-advanced-settings-dialog',\n// templateUrl: './agent-advanced-settings-dialog.component.html',\n// styleUrls: ['./agent-advanced-settings-dialog.component.css']\n// })\n// export class AgentAdvancedSettingsDialogComponent implements OnInit, OnDestroy {\n \n// // Input properties set by service\n// agent!: MJAIAgentEntityExtended;\n \n// // Reactive state management\n// private destroy$ = new Subject<void>();\n// public result = new Subject<AdvancedSettingsFormData | null>();\n \n// // Form and data\n// advancedForm!: FormGroup;\n// isLoading$ = new BehaviorSubject<boolean>(false);\n// isSaving$ = new BehaviorSubject<boolean>(false);\n \n// // Dropdown data\n// agentTypes$ = new BehaviorSubject<MJAIAgentTypeEntity[]>([]);\n \n// // Selected compression prompt\n// selectedCompressionPrompt: MJAIPromptEntityExtended | null = null;\n \n// // Available options\n// statusOptions = [\n// { text: 'Active', value: 'Active' },\n// { text: 'Disabled', value: 'Disabled' },\n// { text: 'Pending', value: 'Pending' }\n// ];\n\n// constructor(\n// private dialogRef: DialogRef,\n// private fb: FormBuilder,\n// private cdr: ChangeDetectorRef,\n// private router: Router,\n// private agentManagementService: AIAgentManagementService,\n// private viewContainerRef: ViewContainerRef\n// ) {}\n\n// ngOnInit() {\n// this.initializeForm();\n// this.loadDropdownData();\n// this.loadSelectedCompressionPrompt();\n// }\n\n// ngOnDestroy() {\n// this.destroy$.next();\n// this.destroy$.complete();\n// }\n\n// private initializeForm() {\n// this.advancedForm = this.fb.group({\n// // Identity & Behavior\n// logoURL: [this.agent.LogoURL],\n// iconClass: [this.agent.IconClass],\n// driverClass: [this.agent.DriverClass],\n \n// // System Configuration\n// exposeAsAction: [this.agent.ExposeAsAction],\n// typeID: [this.agent.TypeID],\n// status: [this.agent.Status],\n \n// // Context Compression\n// enableContextCompression: [this.agent.EnableContextCompression],\n// contextCompressionMessageThreshold: [this.agent.ContextCompressionMessageThreshold, [Validators.min(1)]],\n// contextCompressionPromptID: [this.agent.ContextCompressionPromptID],\n// contextCompressionMessageRetentionCount: [this.agent.ContextCompressionMessageRetentionCount, [Validators.min(1)]],\n \n// // Payload Control\n// payloadDownstreamPaths: [this.agent.PayloadDownstreamPaths, [Validators.required]],\n// payloadUpstreamPaths: [this.agent.PayloadUpstreamPaths, [Validators.required]],\n// payloadSelfReadPaths: [this.agent.PayloadSelfReadPaths],\n// payloadSelfWritePaths: [this.agent.PayloadSelfWritePaths]\n// });\n\n// // Set up validation dependencies\n// this.setupValidationLogic();\n// }\n\n// private setupValidationLogic() {\n// // Context compression validation\n// const enableCompressionControl = this.advancedForm.get('enableContextCompression');\n// const thresholdControl = this.advancedForm.get('contextCompressionMessageThreshold');\n// const promptControl = this.advancedForm.get('contextCompressionPromptID');\n// const retentionControl = this.advancedForm.get('contextCompressionMessageRetentionCount');\n\n// enableCompressionControl?.valueChanges.pipe(\n// takeUntil(this.destroy$)\n// ).subscribe(enabled => {\n// if (enabled) {\n// thresholdControl?.setValidators([Validators.required, Validators.min(1)]);\n// promptControl?.setValidators([Validators.required]);\n// retentionControl?.setValidators([Validators.required, Validators.min(1)]);\n// } else {\n// // Clear validators and reset values to null when disabled\n// thresholdControl?.clearValidators();\n// promptControl?.clearValidators();\n// retentionControl?.clearValidators();\n \n// // Reset field values to null\n// thresholdControl?.setValue(null);\n// promptControl?.setValue(null);\n// retentionControl?.setValue(null);\n \n// // Clear the selected compression prompt display\n// this.selectedCompressionPrompt = null;\n// }\n// thresholdControl?.updateValueAndValidity();\n// promptControl?.updateValueAndValidity();\n// retentionControl?.updateValueAndValidity();\n// });\n\n// // Note: ParentID vs ExposeAsAction validation is now handled in the sub-agents section\n// }\n\n// private async loadDropdownData() {\n// this.isLoading$.next(true);\n \n// try {\n// const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n \n// const agentTypesResult = await rv.RunView<MJAIAgentTypeEntity>({\n// EntityName: 'MJ: AI Agent Types',\n// ExtraFilter: 'IsActive = 1',\n// OrderBy: 'Name',\n// ResultType: 'entity_object',\n// MaxRows: 1000\n// });\n\n// if (agentTypesResult.Success) {\n// this.agentTypes$.next(agentTypesResult.Results || []);\n// }\n\n// } catch (error) {\n// console.error('Error loading dropdown data:', error);\n// MJNotificationService.Instance.CreateSimpleNotification(\n// 'Error loading form data. Please try again.',\n// 'error',\n// 3000\n// );\n// } finally {\n// this.isLoading$.next(false);\n// }\n// }\n\n// private async loadSelectedCompressionPrompt() {\n// if (this.agent.ContextCompressionPromptID) {\n// try {\n// const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n// const result = await rv.RunView<MJAIPromptEntityExtended>({\n// EntityName: 'MJ: AI Prompts',\n// ExtraFilter: `ID = '${this.agent.ContextCompressionPromptID}'`,\n// ResultType: 'entity_object',\n// MaxRows: 1\n// });\n\n// if (result.Success && result.Results && result.Results.length > 0) {\n// this.selectedCompressionPrompt = result.Results[0];\n// }\n// } catch (error) {\n// console.error('Error loading compression prompt:', error);\n// }\n// }\n// }\n\n// // === Validation Helpers ===\n\n// isFieldInvalid(fieldName: string): boolean {\n// const field = this.advancedForm.get(fieldName);\n// return !!(field && field.invalid && (field.dirty || field.touched));\n// }\n\n// getFieldError(fieldName: string): string {\n// const field = this.advancedForm.get(fieldName);\n// if (field?.errors) {\n// if (field.errors['required']) return 'This field is required';\n// if (field.errors['min']) return `Minimum value is ${field.errors['min'].min}`;\n// }\n// return '';\n// }\n\n// // === JSON Helpers ===\n\n// isValidJSON(value: string): boolean {\n// try {\n// JSON.parse(value);\n// return true;\n// } catch {\n// return false;\n// }\n// }\n\n// formatJSON(fieldName: string) {\n// const control = this.advancedForm.get(fieldName);\n// if (control?.value) {\n// try {\n// const parsed = JSON.parse(control.value);\n// const formatted = JSON.stringify(parsed, null, 2);\n// control.setValue(formatted);\n// } catch {\n// // Invalid JSON, leave as is\n// }\n// }\n// }\n\n// resetToDefault(fieldName: string) {\n// const control = this.advancedForm.get(fieldName);\n// if (fieldName === 'payloadDownstreamPaths' || fieldName === 'payloadUpstreamPaths') {\n// control?.setValue('[\"*\"]');\n// } else {\n// control?.setValue(null);\n// }\n// }\n\n// selectCompressionPrompt() {\n// this.agentManagementService.openContextCompressionPromptSelector({\n// currentPromptId: this.selectedCompressionPrompt?.ID,\n// viewContainerRef: this.viewContainerRef\n// }).subscribe(selectedPrompt => {\n// if (selectedPrompt) {\n// this.selectedCompressionPrompt = selectedPrompt;\n// this.advancedForm.get('contextCompressionPromptID')?.setValue(selectedPrompt.ID);\n// }\n// });\n// }\n\n// clearCompressionPrompt() {\n// this.selectedCompressionPrompt = null;\n// this.advancedForm.get('contextCompressionPromptID')?.setValue(null);\n// }\n\n// viewContextCompressionPrompt() {\n// if (this.selectedCompressionPrompt?.ID) {\n// // Navigate to the AI Prompt form\n// this.router.navigate(['/form', 'MJ: AI Prompts', this.selectedCompressionPrompt.ID]);\n// }\n// }\n\n// // === Dialog Actions ===\n\n// cancel() {\n// this.result.next(null);\n// this.dialogRef.close();\n// }\n\n// async save() {\n// if (this.advancedForm.invalid) {\n// // Mark all fields as touched to show validation errors\n// Object.keys(this.advancedForm.controls).forEach(key => {\n// this.advancedForm.get(key)?.markAsTouched();\n// });\n// return;\n// }\n\n// this.isSaving$.next(true);\n \n// try {\n// const formData: AdvancedSettingsFormData = this.advancedForm.value;\n \n// // Validate JSON fields\n// const jsonFields = ['payloadDownstreamPaths', 'payloadUpstreamPaths', 'payloadSelfReadPaths', 'payloadSelfWritePaths'];\n// for (const field of jsonFields) {\n// const value = formData[field as keyof AdvancedSettingsFormData];\n// if (value && typeof value === 'string' && !this.isValidJSON(value)) {\n// MJNotificationService.Instance.CreateSimpleNotification(\n// `Invalid JSON in ${field.replace(/([A-Z])/g, ' $1').toLowerCase()}`,\n// 'error',\n// 3000\n// );\n// this.isSaving$.next(false);\n// return;\n// }\n// }\n\n// this.result.next(formData);\n// this.dialogRef.close();\n \n// } catch (error) {\n// console.error('Error saving advanced settings:', error);\n// MJNotificationService.Instance.CreateSimpleNotification(\n// 'Error saving settings. Please try again.',\n// 'error',\n// 3000\n// );\n// } finally {\n// this.isSaving$.next(false);\n// }\n// }\n// }"]}
@@ -2,6 +2,7 @@ import { OnInit, OnDestroy, ChangeDetectorRef, EventEmitter } from '@angular/cor
2
2
  import { FormGroup, FormBuilder } from '@angular/forms';
3
3
  import { Subject, BehaviorSubject } from 'rxjs';
4
4
  import { MJAIAgentPromptEntity, MJAIConfigurationEntity } from '@memberjunction/core-entities';
5
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
5
6
  import * as i0 from "@angular/core";
6
7
  export interface AgentPromptAdvancedSettingsFormData {
7
8
  executionOrder: number;
@@ -15,7 +16,7 @@ export interface AgentPromptAdvancedSettingsFormData {
15
16
  * Advanced Settings dialog for AI Agent Prompts.
16
17
  * Manages execution order, context behavior, and other advanced prompt configurations.
17
18
  */
18
- export declare class AgentPromptAdvancedSettingsDialogComponent implements OnInit, OnDestroy {
19
+ export declare class AgentPromptAdvancedSettingsDialogComponent extends BaseAngularComponent implements OnInit, OnDestroy {
19
20
  private fb;
20
21
  private cdr;
21
22
  agentPrompt: MJAIAgentPromptEntity;