ngx-t-forms 2.0.24 → 2.0.26

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 (149) hide show
  1. package/README.md +177 -16
  2. package/fesm2022/ngx-t-forms-calculated-field-rules.component-Cs_Lhz_D.mjs +313 -0
  3. package/fesm2022/ngx-t-forms-calculated-field-rules.component-Cs_Lhz_D.mjs.map +1 -0
  4. package/fesm2022/{ngx-t-forms-chip-options-creator-editor.component-C00n6tFs.mjs → ngx-t-forms-chip-options-creator-editor.component-DkTpG5yQ.mjs} +6 -6
  5. package/fesm2022/{ngx-t-forms-chip-options-creator-editor.component-C00n6tFs.mjs.map → ngx-t-forms-chip-options-creator-editor.component-DkTpG5yQ.mjs.map} +1 -1
  6. package/fesm2022/{ngx-t-forms-config-mscoa-additional-inputs.component-DtfUKZL-.mjs → ngx-t-forms-config-mscoa-additional-inputs.component-DJ9d3Oy9.mjs} +9 -9
  7. package/fesm2022/{ngx-t-forms-config-mscoa-additional-inputs.component-DtfUKZL-.mjs.map → ngx-t-forms-config-mscoa-additional-inputs.component-DJ9d3Oy9.mjs.map} +1 -1
  8. package/fesm2022/{ngx-t-forms-data-source-picker.component-BBEQuzn2.mjs → ngx-t-forms-data-source-picker.component-CFQ_GVPG.mjs} +11 -11
  9. package/fesm2022/{ngx-t-forms-data-source-picker.component-BBEQuzn2.mjs.map → ngx-t-forms-data-source-picker.component-CFQ_GVPG.mjs.map} +1 -1
  10. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CPF_BLRA.mjs +291 -0
  11. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CPF_BLRA.mjs.map +1 -0
  12. package/fesm2022/{ngx-t-forms-form-input-selector.component-CniLZN1h.mjs → ngx-t-forms-form-input-selector.component-C38FXT55.mjs} +8 -8
  13. package/fesm2022/{ngx-t-forms-form-input-selector.component-CniLZN1h.mjs.map → ngx-t-forms-form-input-selector.component-C38FXT55.mjs.map} +1 -1
  14. package/fesm2022/{ngx-t-forms-form-json-view.component-bnjkxqgV.mjs → ngx-t-forms-form-json-view.component-C7i6JZ-l.mjs} +6 -6
  15. package/fesm2022/{ngx-t-forms-form-json-view.component-bnjkxqgV.mjs.map → ngx-t-forms-form-json-view.component-C7i6JZ-l.mjs.map} +1 -1
  16. package/fesm2022/ngx-t-forms-form-section-stepper.component-CJz0yr78.mjs +264 -0
  17. package/fesm2022/ngx-t-forms-form-section-stepper.component-CJz0yr78.mjs.map +1 -0
  18. package/fesm2022/ngx-t-forms-forms-builder-menu.component-G3Agd-vE.mjs +349 -0
  19. package/fesm2022/ngx-t-forms-forms-builder-menu.component-G3Agd-vE.mjs.map +1 -0
  20. package/fesm2022/{ngx-t-forms-input-editor.component-BBP90B_e.mjs → ngx-t-forms-input-editor.component-B12zbXE1.mjs} +19 -19
  21. package/fesm2022/{ngx-t-forms-input-editor.component-BBP90B_e.mjs.map → ngx-t-forms-input-editor.component-B12zbXE1.mjs.map} +1 -1
  22. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-dIY3BX1u.mjs +106 -0
  23. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-dIY3BX1u.mjs.map +1 -0
  24. package/fesm2022/{ngx-t-forms-mat-slider-editor.component-CIiYyxkb.mjs → ngx-t-forms-mat-slider-editor.component-yMRCg8fo.mjs} +5 -5
  25. package/fesm2022/{ngx-t-forms-mat-slider-editor.component-CIiYyxkb.mjs.map → ngx-t-forms-mat-slider-editor.component-yMRCg8fo.mjs.map} +1 -1
  26. package/fesm2022/{ngx-t-forms-mat-slider-toggle-editor.component-DDR2JurF.mjs → ngx-t-forms-mat-slider-toggle-editor.component-0aUVP9A6.mjs} +7 -7
  27. package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-0aUVP9A6.mjs.map +1 -0
  28. package/fesm2022/{ngx-t-forms-missing-form-configs.component-CYN9mVz9.mjs → ngx-t-forms-missing-form-configs.component-CsPMQZqg.mjs} +9 -9
  29. package/fesm2022/{ngx-t-forms-missing-form-configs.component-CYN9mVz9.mjs.map → ngx-t-forms-missing-form-configs.component-CsPMQZqg.mjs.map} +1 -1
  30. package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D8a9-6lt.mjs +43 -0
  31. package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D8a9-6lt.mjs.map +1 -0
  32. package/fesm2022/ngx-t-forms-mscoa-error-display.component-DwbyXd_D.mjs +116 -0
  33. package/fesm2022/ngx-t-forms-mscoa-error-display.component-DwbyXd_D.mjs.map +1 -0
  34. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-BXPghOuH.mjs +299 -0
  35. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-BXPghOuH.mjs.map +1 -0
  36. package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-CBRfWvfD.mjs +83 -0
  37. package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-CBRfWvfD.mjs.map +1 -0
  38. package/fesm2022/{ngx-t-forms-ngx-t-forms-DwsbmVlY.mjs → ngx-t-forms-ngx-t-forms-CD9InaXz.mjs} +3364 -931
  39. package/fesm2022/ngx-t-forms-ngx-t-forms-CD9InaXz.mjs.map +1 -0
  40. package/fesm2022/ngx-t-forms-pipeline-generator.component-QE-I58e4.mjs +637 -0
  41. package/fesm2022/ngx-t-forms-pipeline-generator.component-QE-I58e4.mjs.map +1 -0
  42. package/fesm2022/ngx-t-forms-record-list-manager.component-D4wlLtdc.mjs +270 -0
  43. package/fesm2022/ngx-t-forms-record-list-manager.component-D4wlLtdc.mjs.map +1 -0
  44. package/fesm2022/ngx-t-forms-required-inputs.component-BoqmVDp2.mjs +192 -0
  45. package/fesm2022/ngx-t-forms-required-inputs.component-BoqmVDp2.mjs.map +1 -0
  46. package/fesm2022/{ngx-t-forms-rest-api-call-setup.component-BcItch1n.mjs → ngx-t-forms-rest-api-call-setup.component-CtfudSGT.mjs} +15 -15
  47. package/fesm2022/{ngx-t-forms-rest-api-call-setup.component-BcItch1n.mjs.map → ngx-t-forms-rest-api-call-setup.component-CtfudSGT.mjs.map} +1 -1
  48. package/fesm2022/{ngx-t-forms-section-report.component-Cn_oWXBX.mjs → ngx-t-forms-section-report.component-Dntm1m5b.mjs} +10 -10
  49. package/fesm2022/{ngx-t-forms-section-report.component-Cn_oWXBX.mjs.map → ngx-t-forms-section-report.component-Dntm1m5b.mjs.map} +1 -1
  50. package/fesm2022/{ngx-t-forms-selection-options-editor.component-Cc41XG4s.mjs → ngx-t-forms-selection-options-editor.component-Cc_qCtW2.mjs} +11 -11
  51. package/fesm2022/{ngx-t-forms-selection-options-editor.component-Cc41XG4s.mjs.map → ngx-t-forms-selection-options-editor.component-Cc_qCtW2.mjs.map} +1 -1
  52. package/fesm2022/ngx-t-forms-t-workflow-picker.component-xvX8t0pu.mjs +187 -0
  53. package/fesm2022/ngx-t-forms-t-workflow-picker.component-xvX8t0pu.mjs.map +1 -0
  54. package/fesm2022/{ngx-t-forms-validators-config.component-4Iy5uJj3.mjs → ngx-t-forms-validators-config.component-D6JG1p81.mjs} +13 -13
  55. package/fesm2022/{ngx-t-forms-validators-config.component-4Iy5uJj3.mjs.map → ngx-t-forms-validators-config.component-D6JG1p81.mjs.map} +1 -1
  56. package/fesm2022/ngx-t-forms.mjs +1 -1
  57. package/lib/components/form-builder/elements/form-section-stepper/form-section-stepper.component.d.ts +4 -1
  58. package/lib/components/form-builder/elements/form-submissions-config/form-submissions-config.component.d.ts +1 -1
  59. package/lib/components/form-builder/elements/input-element-editor/input-element-editor.component.d.ts +6 -2
  60. package/lib/components/forms/forms.component.d.ts +8 -0
  61. package/lib/components/forms/store/Form-actions-formBuilder.d.ts +1 -0
  62. package/lib/components/forms/store/Form-selectors-FormBuilder.d.ts +3 -1
  63. package/lib/components/forms/store/Forms-Effects.d.ts +7 -1
  64. package/lib/components/forms/store/forms-store.service.d.ts +19 -53
  65. package/lib/components/index.d.ts +2 -1
  66. package/lib/components/t-dynamic-data-edit/elements/api-value-access-rules/api-value-access-rules.component.d.ts +40 -20
  67. package/lib/components/t-dynamic-data-edit/elements/calculated-field-rules/calculated-field-rules.component.d.ts +51 -63
  68. package/lib/components/t-dynamic-data-edit/elements/document-list-label-config-editor/document-list-label-config-editor.component.d.ts +8 -1
  69. package/lib/components/t-dynamic-data-edit/elements/json-editor/json-editor.component.d.ts +37 -9
  70. package/lib/components/t-dynamic-data-edit/elements/mat-chip-list-editor/mat-chip-list-editor.component.d.ts +2 -1
  71. package/lib/components/t-dynamic-data-edit/elements/mscoa-segment-config/mscoa-segment-config.component.d.ts +4 -1
  72. package/lib/components/t-dynamic-data-edit/elements/pipeline-generator/pipeline-generator.component.d.ts +2 -0
  73. package/lib/components/t-dynamic-data-edit/elements/record-list-manager/record-list-manager.component.d.ts +75 -0
  74. package/lib/components/t-dynamic-data-edit/elements/required-inputs/required-inputs.component.d.ts +1 -0
  75. package/lib/components/t-dynamic-data-edit/elements/t-workflow-picker/t-workflow-picker.component.d.ts +7 -3
  76. package/lib/components/t-dynamic-data-edit/t-dynamic-data-edit.component.d.ts +1 -0
  77. package/lib/components/t-form-input/elements/Geo-location-form-input/geo-location.component.d.ts +1 -1
  78. package/lib/components/t-form-input/elements/auto-complete-input-element/auto-complete-input-element.component.d.ts +1 -1
  79. package/lib/components/t-form-input/elements/basic-input-input-element/basic-input-input-element.component.d.ts +2 -1
  80. package/lib/components/t-form-input/elements/basic-input-input-element/core/input-custom/input-custom.component.d.ts +2 -1
  81. package/lib/components/t-form-input/elements/date-picker-input-element/date-picker-input-element.component.d.ts +1 -1
  82. package/lib/components/t-form-input/elements/date-range-picker-input-element/date-range-picker-input-element.component.d.ts +1 -1
  83. package/lib/components/t-form-input/elements/document-picker/document-picker.component.d.ts +1 -1
  84. package/lib/components/t-form-input/elements/editor-input-element/editor-input-element.component.d.ts +1 -1
  85. package/lib/components/t-form-input/elements/file-upload-input-element/file-upload-input-element.component.d.ts +1 -1
  86. package/lib/components/t-form-input/elements/image-capture-input-element/image-capture-input-element.component.d.ts +1 -1
  87. package/lib/components/t-form-input/elements/mscoa-form-input/elements/account-value/account-value.component.d.ts +8 -0
  88. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/components/mscoa-chart-input-menu/mscoa-chart-input-menu.component.d.ts +23 -0
  89. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/components/mscoa-chart-toolbar/mscoa-chart-toolbar.component.d.ts +22 -0
  90. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/components/mscoa-error-display/mscoa-error-display.component.d.ts +34 -0
  91. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/components/mscoa-temporary-hint/mscoa-temporary-hint.component.d.ts +21 -0
  92. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/extractCols.d.ts +22 -0
  93. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/mscoa-chart.component.d.ts +299 -86
  94. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.constants.d.ts +47 -0
  95. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.helpers.d.ts +87 -0
  96. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.types.d.ts +51 -0
  97. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-message-formatter.d.ts +87 -0
  98. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-computation/mscoa-computation.component.d.ts +149 -22
  99. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-reactive-form-field/mscoa-reactive-form-field.component.d.ts +11 -0
  100. package/lib/components/t-form-input/elements/mscoa-form-input/elements/scoa-account-table/scoa-account-table.component.d.ts +4 -0
  101. package/lib/components/t-form-input/elements/mscoa-form-input/mscoa-form-input.component.d.ts +1 -1
  102. package/lib/components/t-form-input/elements/mscoa-form-input/store/accountConstants.d.ts +7 -2
  103. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-actions.d.ts +13 -2
  104. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-component-store.service.d.ts +45 -8
  105. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-effects.d.ts +1 -0
  106. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-selectors.d.ts +33 -8
  107. package/lib/components/t-form-input/elements/multiple-input-input-element/multiple-input-input-element.component.d.ts +1 -1
  108. package/lib/components/t-form-input/elements/select-input-element/select-input-element.component.d.ts +1 -1
  109. package/lib/components/t-form-input/elements/signature-input-element/core/signature-pad-input/functions/getSignatureImage.d.ts +3 -0
  110. package/lib/components/t-form-input/elements/signature-input-element/signature-input-element.component.d.ts +1 -1
  111. package/lib/components/t-form-input/elements/textarea-input-element/core/text-area-reactive-input/text-area-reactive-input.component.d.ts +1 -2
  112. package/lib/components/t-form-input/elements/textarea-input-element/textarea-input-element.component.d.ts +1 -1
  113. package/lib/components/t-form-input/elements/toggle-input-element/toggle-input-element.component.d.ts +1 -1
  114. package/lib/components/t-form-input/elements/workflow-adjudication/workflow-adjudication.component.d.ts +1 -1
  115. package/lib/services/core/t-form-builder/functions/deleteSection.d.ts +1 -0
  116. package/lib/services/core/t-form-builder/functions/inputElementEditorConfigs.d.ts +9 -3
  117. package/lib/services/core/t-form-builder/functions/removeItem.d.ts +1 -0
  118. package/lib/services/core/t-form-builder/functions/stepTitleChangeStep.d.ts +1 -0
  119. package/lib/services/core/t-form-controller/function/calculateInputValue.d.ts +1 -1
  120. package/lib/services/core/t-form-controller/function/getInputSourcedValue.d.ts +4 -0
  121. package/lib/services/core/t-form-tower-controller/functions/runMultipleInputPrepopulationFunctions.d.ts +11 -0
  122. package/lib/services/core/t-form-tower-controller/functions/updateFormInputConfig.d.ts +7 -0
  123. package/lib/services/core/t-input-controller/functions/baseCustomInput.d.ts +4 -2
  124. package/lib/services/core/t-input-controller/functions/inputErrorMessage.d.ts +1 -1
  125. package/lib/shared/functions/convertElementEditorTypesToInputType.d.ts +3 -0
  126. package/lib/shared/functions/fuzzyTextSearch.d.ts +4 -0
  127. package/lib/shared/functions/getPipedValueFromDataType.d.ts +2 -0
  128. package/lib/shared/index.d.ts +2 -1
  129. package/package.json +2 -2
  130. package/fesm2022/ngx-t-forms-calculated-field-rules.component-BUKzXsXn.mjs +0 -316
  131. package/fesm2022/ngx-t-forms-calculated-field-rules.component-BUKzXsXn.mjs.map +0 -1
  132. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-D6kwe89h.mjs +0 -238
  133. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-D6kwe89h.mjs.map +0 -1
  134. package/fesm2022/ngx-t-forms-form-section-stepper.component-DFbYNeAi.mjs +0 -261
  135. package/fesm2022/ngx-t-forms-form-section-stepper.component-DFbYNeAi.mjs.map +0 -1
  136. package/fesm2022/ngx-t-forms-forms-builder-menu.component-DBEgmcSi.mjs +0 -348
  137. package/fesm2022/ngx-t-forms-forms-builder-menu.component-DBEgmcSi.mjs.map +0 -1
  138. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-CQ76110I.mjs +0 -103
  139. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-CQ76110I.mjs.map +0 -1
  140. package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-DDR2JurF.mjs.map +0 -1
  141. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C9zKzzzX.mjs +0 -281
  142. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C9zKzzzX.mjs.map +0 -1
  143. package/fesm2022/ngx-t-forms-ngx-t-forms-DwsbmVlY.mjs.map +0 -1
  144. package/fesm2022/ngx-t-forms-pipeline-generator.component-CGKxfvvC.mjs +0 -727
  145. package/fesm2022/ngx-t-forms-pipeline-generator.component-CGKxfvvC.mjs.map +0 -1
  146. package/fesm2022/ngx-t-forms-required-inputs.component-Bktx1QGr.mjs +0 -188
  147. package/fesm2022/ngx-t-forms-required-inputs.component-Bktx1QGr.mjs.map +0 -1
  148. package/fesm2022/ngx-t-forms-t-workflow-picker.component-CezFgp2z.mjs +0 -171
  149. package/fesm2022/ngx-t-forms-t-workflow-picker.component-CezFgp2z.mjs.map +0 -1
@@ -0,0 +1,637 @@
1
+ import * as i2$4 from '@angular/common';
2
+ import { CommonModule } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { EventEmitter, Output, Input, Component, inject, Injectable, ElementRef, ViewChild, HostBinding, Optional, Self } from '@angular/core';
5
+ import * as i1 from '@angular/forms';
6
+ import { FormsModule } from '@angular/forms';
7
+ import { Subscription, BehaviorSubject, switchMap, map, take, catchError, finalize, throwError, tap, combineLatest, filter, Subject, takeUntil, distinctUntilChanged } from 'rxjs';
8
+ import PipelineBuilder from 'db-aggregation-pipeline-builder';
9
+ import { M as MatModulesModule, J as JsonEditorComponent, N as NGX_T_FORMS_CONFIG_TOKEN, b as TDynamicDataViewComponent, D as DaysAgoPipe } from './ngx-t-forms-ngx-t-forms-CD9InaXz.mjs';
10
+ import * as i2 from '@angular/material/autocomplete';
11
+ import * as i2$1 from '@angular/material/button';
12
+ import * as i3 from '@angular/material/card';
13
+ import * as i4 from '@angular/material/divider';
14
+ import * as i2$2 from '@angular/material/icon';
15
+ import * as i2$3 from '@angular/material/select';
16
+ import * as i8 from '@angular/material/tooltip';
17
+ import { TWorkflowPickerComponent } from './ngx-t-forms-t-workflow-picker.component-xvX8t0pu.mjs';
18
+ import { MatFormFieldControl } from '@angular/material/form-field';
19
+ import { HttpClient } from '@angular/common/http';
20
+ import * as i10$1 from '@angular/cdk/overlay';
21
+ import { OverlayModule } from '@angular/cdk/overlay';
22
+ import * as i5 from '@angular/material/expansion';
23
+ import * as i7 from '@angular/material/list';
24
+ import * as i3$1 from '@angular/material/progress-spinner';
25
+ import * as i10 from '@angular/material/toolbar';
26
+
27
+ class AggregateStageEditorComponent {
28
+ ngOnDestroy() {
29
+ this.subscription.unsubscribe();
30
+ }
31
+ constructor() {
32
+ this.subscription = new Subscription();
33
+ this.isRunningPipeline = false;
34
+ this.saveStage = new EventEmitter();
35
+ this.deleteStage = new EventEmitter();
36
+ this.activeStage = undefined; // Define the type appropriately if possible
37
+ this.allowedStages = [];
38
+ }
39
+ ngOnInit() {
40
+ // Debounce the config change to optimize performance
41
+ this.allowedStages = PipelineBuilder.getViewOnlyStages();
42
+ }
43
+ handleChange(event) {
44
+ const selectedStage = event.value;
45
+ if (this.activeStage === undefined) {
46
+ this.activeStage = {
47
+ stage: selectedStage,
48
+ ...this.selectedStage || {},
49
+ };
50
+ }
51
+ else {
52
+ this.activeStage = {
53
+ config: this.activeStage?.config || this.selectedStage?.config,
54
+ stage: selectedStage
55
+ };
56
+ }
57
+ { }
58
+ if (this.activeStage?.config && !!this.activeStage?.stage) {
59
+ this.validateConfig();
60
+ }
61
+ }
62
+ handleConfigChange(event) {
63
+ if (!this.activeStage) {
64
+ this.activeStage = {
65
+ ...this.selectedStage || {},
66
+ };
67
+ }
68
+ this.activeStage = {
69
+ stage: this.activeStage?.stage || this.selectedStage?.name,
70
+ config: event.value
71
+ };
72
+ this.validateConfig();
73
+ }
74
+ validateConfig() {
75
+ this.configValidationError = undefined;
76
+ const { config, stage } = this.activeStage || {};
77
+ // Check if config and stage are defined
78
+ if (!config && config !== 0 || !stage) {
79
+ console.error('Config or stage is not defined', config, stage);
80
+ this.activeStage.valid = false;
81
+ return; // Early exit if validation fails
82
+ }
83
+ try {
84
+ const valid = PipelineBuilder.validateStageConfig(stage, config);
85
+ this.activeStage.valid = valid;
86
+ // Set error message if config is invalid
87
+ if (!valid) {
88
+ this.configValidationError = undefined;
89
+ return;
90
+ }
91
+ }
92
+ catch (error) {
93
+ // Catch and handle errors from validation
94
+ this.configValidationError = error.message || JSON.stringify(error) || 'An unknown error occurred';
95
+ this.activeStage.valid = false;
96
+ console.error('Validation Error:', this.configValidationError);
97
+ }
98
+ }
99
+ canSaveConfig() {
100
+ return !!this.activeStage && !this.configValidationError;
101
+ }
102
+ saveConfiguration() {
103
+ // Logic for saving the configuration
104
+ if (this.canSaveConfig()) {
105
+ this.saveStage.emit(this.activeStage);
106
+ }
107
+ }
108
+ trackByStage(index, stage) {
109
+ return stage.stage;
110
+ }
111
+ get allowedStageNames() {
112
+ return this.allowedStages.map(stage => stage.stage);
113
+ }
114
+ get activeDescription() {
115
+ return this.allowedStages.find(stage => stage.stage === this.activeStage?.stage)?.description;
116
+ }
117
+ deleteActive() {
118
+ this.deleteStage.emit();
119
+ }
120
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AggregateStageEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
121
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: AggregateStageEditorComponent, isStandalone: true, selector: "app-aggregate-stage-editor", inputs: { selectedStage: "selectedStage", isRunningPipeline: "isRunningPipeline" }, outputs: { saveStage: "saveStage", deleteStage: "deleteStage" }, ngImport: i0, template: "<mat-card style=\"margin-bottom:8px\">\n <mat-card-content>\n\n <h5>\n Aggregate Pipeline Stage Configuration\n </h5>\n\n\n\n <mat-form-field style=\" margin-bottom: 8px;\" appearance=\"outline\" subscriptSizing=\"dynamic\" >\n <mat-label>Select Aggregate Stage</mat-label>\n <mat-select matNativeControl [value]=\"selectedStage?.name\" (selectionChange)=\"handleChange($event)\"\n placeholder=\"ChooseFunctionToRun\">\n <mat-option *ngFor=\"let stage of allowedStages; trackBy: trackByStage\" [value]=\"stage.stage\">\n {{stage.stage}}</mat-option>\n\n\n\n </mat-select>\n <mat-hint>\n {{activeDescription ?\n 'Hover over the info icon to view stage details .'\n : 'Please select an aggregation function from the list.'}}\n </mat-hint>\n <mat-hint *ngIf=\"activeDescription\" align=\"end\">\n <mat-icon matTooltipHideDelay=\"1000\" [matTooltip]=\"activeDescription\" matSuffix>info</mat-icon>\n </mat-hint>\n </mat-form-field>\n\n\n\n <div class=\"tree-instructions\" style=\"background: cornsilk;\" *ngIf=\"configValidationError\">\n <mat-icon style=\"margin-top: 4px;margin-bottom:auto\" class=\"info-icon\" color=\"warn\">warning</mat-icon>\n <span>{{ configValidationError }}</span>\n </div>\n\n\n\n\n\n <div class=\"config-container\" *ngIf=\"activeStage ||selectedStage?.config\">\n <app-json-editor [value]=\"selectedStage?.config\" (valueChange)=\"handleConfigChange($event)\"></app-json-editor>\n </div>\n\n <br>\n\n\n\n </mat-card-content>\n <mat-divider>\n </mat-divider>\n <mat-card-actions>\n\n <span class=\"spacer\"></span>\n <button color=\"warn\" [disabled]=\"isRunningPipeline\" mat-button (click)=\"deleteActive()\">\n Delete\n <mat-icon >delete</mat-icon>\n </button>\n <button style=\"margin-left:8px;\" color=\"primary\" mat-flat-button (click)=\"saveConfiguration()\"\n [disabled]=\"isRunningPipeline ||!activeStage?.valid \">\n Save\n <mat-icon> save</mat-icon>\n </button>\n </mat-card-actions>\n</mat-card>", styles: [".title-icon{margin-right:8px;vertical-align:middle}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:var(--mdc-elevated-card-container-color, var(--mat-app-surface-container-low));border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px!important;display:block}mat-form-field{min-width:100%;background:azure}.stageDescription{background:azure}.stage-button-container{display:flex;gap:4px;width:fit-content;align-items:center}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:azure;border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px;margin:8px auto auto}\n"], dependencies: [{ kind: "ngmodule", type: MatModulesModule }, { kind: "component", type: i2.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i2$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i3.MatCardActions, selector: "mat-card-actions", inputs: ["align"], exportAs: ["matCardActions"] }, { kind: "directive", type: i3.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i4.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: i2$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i2$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$3.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i2$3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: JsonEditorComponent, selector: "app-json-editor", inputs: ["value"], outputs: ["valueChange"] }] }); }
122
+ }
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AggregateStageEditorComponent, decorators: [{
124
+ type: Component,
125
+ args: [{ selector: 'app-aggregate-stage-editor', standalone: true, imports: [
126
+ MatModulesModule,
127
+ CommonModule,
128
+ FormsModule,
129
+ JsonEditorComponent
130
+ ], template: "<mat-card style=\"margin-bottom:8px\">\n <mat-card-content>\n\n <h5>\n Aggregate Pipeline Stage Configuration\n </h5>\n\n\n\n <mat-form-field style=\" margin-bottom: 8px;\" appearance=\"outline\" subscriptSizing=\"dynamic\" >\n <mat-label>Select Aggregate Stage</mat-label>\n <mat-select matNativeControl [value]=\"selectedStage?.name\" (selectionChange)=\"handleChange($event)\"\n placeholder=\"ChooseFunctionToRun\">\n <mat-option *ngFor=\"let stage of allowedStages; trackBy: trackByStage\" [value]=\"stage.stage\">\n {{stage.stage}}</mat-option>\n\n\n\n </mat-select>\n <mat-hint>\n {{activeDescription ?\n 'Hover over the info icon to view stage details .'\n : 'Please select an aggregation function from the list.'}}\n </mat-hint>\n <mat-hint *ngIf=\"activeDescription\" align=\"end\">\n <mat-icon matTooltipHideDelay=\"1000\" [matTooltip]=\"activeDescription\" matSuffix>info</mat-icon>\n </mat-hint>\n </mat-form-field>\n\n\n\n <div class=\"tree-instructions\" style=\"background: cornsilk;\" *ngIf=\"configValidationError\">\n <mat-icon style=\"margin-top: 4px;margin-bottom:auto\" class=\"info-icon\" color=\"warn\">warning</mat-icon>\n <span>{{ configValidationError }}</span>\n </div>\n\n\n\n\n\n <div class=\"config-container\" *ngIf=\"activeStage ||selectedStage?.config\">\n <app-json-editor [value]=\"selectedStage?.config\" (valueChange)=\"handleConfigChange($event)\"></app-json-editor>\n </div>\n\n <br>\n\n\n\n </mat-card-content>\n <mat-divider>\n </mat-divider>\n <mat-card-actions>\n\n <span class=\"spacer\"></span>\n <button color=\"warn\" [disabled]=\"isRunningPipeline\" mat-button (click)=\"deleteActive()\">\n Delete\n <mat-icon >delete</mat-icon>\n </button>\n <button style=\"margin-left:8px;\" color=\"primary\" mat-flat-button (click)=\"saveConfiguration()\"\n [disabled]=\"isRunningPipeline ||!activeStage?.valid \">\n Save\n <mat-icon> save</mat-icon>\n </button>\n </mat-card-actions>\n</mat-card>", styles: [".title-icon{margin-right:8px;vertical-align:middle}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:var(--mdc-elevated-card-container-color, var(--mat-app-surface-container-low));border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px!important;display:block}mat-form-field{min-width:100%;background:azure}.stageDescription{background:azure}.stage-button-container{display:flex;gap:4px;width:fit-content;align-items:center}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:azure;border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px;margin:8px auto auto}\n"] }]
131
+ }], ctorParameters: () => [], propDecorators: { selectedStage: [{
132
+ type: Input
133
+ }], isRunningPipeline: [{
134
+ type: Input
135
+ }], saveStage: [{
136
+ type: Output
137
+ }], deleteStage: [{
138
+ type: Output
139
+ }] } });
140
+
141
+ class PipelineService {
142
+ constructor() {
143
+ //LOADING INDICATORS
144
+ this.isRunningPipeline = false;
145
+ this.aiIsGeneratingPipeline = false;
146
+ this.isLoadingAllowedStages = false;
147
+ this.isLoadingWorkflowSchema = false;
148
+ //States
149
+ this.workflowId$ = new BehaviorSubject(undefined);
150
+ this.activeStage$ = new BehaviorSubject(undefined);
151
+ this.prompt$ = new BehaviorSubject(undefined);
152
+ this.schemaLoadError$ = new BehaviorSubject(undefined);
153
+ this.pipeline$ = new BehaviorSubject([]);
154
+ this.threadId$ = new BehaviorSubject(undefined);
155
+ this.schema$ = new BehaviorSubject(undefined);
156
+ this.allowedStages$ = new BehaviorSubject([]);
157
+ this.pipeLineResult$ = new BehaviorSubject([]);
158
+ this.chatHistory$ = new BehaviorSubject([]);
159
+ this.http = inject(HttpClient);
160
+ //Set local storage threadId
161
+ const threadId = localStorage.getItem('threadId');
162
+ if (threadId) {
163
+ this.threadId$.next(threadId);
164
+ }
165
+ }
166
+ get config$() {
167
+ return this.workflowId$.pipe(switchMap(workflowId => this.pipeline$.pipe(switchMap(pipeline => this.pipeLineResult$.pipe(map(responseBody => ({ workflowId, pipeline, responseBody })))))));
168
+ }
169
+ /**
170
+ * Fetch available pipeline stages for the user to select and generate pipelines.
171
+ * Ideally, this could be static or fetched from a backend.
172
+ */
173
+ runPipeLine(pipeline, workflowId) {
174
+ const url = "http://localhost:5000/api/v1/pipelineBuilder/runPipeline";
175
+ // For now, returning a static list of pipeline stages. In a real application, you can fetch from an API.
176
+ this.isRunningPipeline = true;
177
+ return this.http.post(url, { pipeline, workflowId }).pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
178
+ finalize(() => this.isRunningPipeline = false));
179
+ }
180
+ /**
181
+ * Generate a MongoDB pipeline based on the given user prompt.
182
+ *
183
+ * @param prompt The user's input or description of the desired pipeline.
184
+ */
185
+ generatePipeline(query, schema, threadId, existingPipeline, previousError) {
186
+ if (!schema) {
187
+ throw new Error("Schema is required");
188
+ }
189
+ const payload = { query, schema, threadId, existingPipeline, previousError };
190
+ const url = "http://localhost:5000/api/v1/pipelineBuilder/generatePipeline";
191
+ this.aiIsGeneratingPipeline = true;
192
+ return this.http.post(`${url}`, payload)
193
+ .pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
194
+ finalize(() => this.aiIsGeneratingPipeline = false));
195
+ }
196
+ /**
197
+ * Handle any errors from the HTTP request.
198
+ *
199
+ * @param error The error response from the HTTP request
200
+ */
201
+ handleError(error) {
202
+ console.error('An error occurred', error);
203
+ // Return an observable with a user-facing error message
204
+ return throwError(() => new Error('Something went wrong with the pipeline generation; please try again later.'));
205
+ }
206
+ getSchema(workflowId) {
207
+ if (!workflowId) {
208
+ throw new Error("WorkflowId is required");
209
+ }
210
+ const url = "http://localhost:5000/api/v1/pipelineBuilder/getSchema";
211
+ return this.http.get(`${url}`, { params: { workflowId: workflowId } }).pipe(take(1), catchError(this.handleError) // Error handling for the HTTP request
212
+ );
213
+ }
214
+ /** OPERATIONS */
215
+ isSchemaEmpty(object) {
216
+ }
217
+ workflowChanged(event) {
218
+ this.workflowId$.next(event);
219
+ if (!event) {
220
+ return;
221
+ }
222
+ this.getSchema(event).pipe(take(1), tap(({ schema }) => {
223
+ this.schema$.next(schema);
224
+ const isEmptySchema = Object.keys(schema)[0] === "" && Object.values(schema)[0] === "Array<>";
225
+ const error = isEmptySchema
226
+ ? "Document schema is missing. Please ensure at least one document exists for the selected workflow."
227
+ : undefined;
228
+ this.schemaLoadError$.next(error);
229
+ console.log("Workflow schema loaded,run pipeline");
230
+ this.runActivePipeline();
231
+ }), catchError((error) => {
232
+ this.schemaLoadError$.next("Error loading schema");
233
+ return this.handleError(error);
234
+ })).subscribe();
235
+ }
236
+ setActiveStage(i) {
237
+ const index = this.activeStage$.getValue();
238
+ if (index === i) {
239
+ this.activeStage$.next(undefined);
240
+ return;
241
+ }
242
+ this.activeStage$.next(i);
243
+ }
244
+ addStage() {
245
+ const newPipeline = this.pipeline$.getValue().concat({});
246
+ this.pipeline$.next(newPipeline);
247
+ }
248
+ onTextChange(event) {
249
+ this.prompt$.next(event);
250
+ console.log(event);
251
+ }
252
+ promptSubmit() {
253
+ // Use combineLatest to fetch the latest values from multiple sources
254
+ combineLatest([this.schema$, this.threadId$, this.pipeline$, this.prompt$, this.chatHistory$])
255
+ .pipe(take(1), tap(([schema, threadId, pipeline, prompt, history]) => {
256
+ if (!schema || !prompt) {
257
+ console.warn(`Missing values: schema ${schema} prompt ${prompt}`);
258
+ }
259
+ }), filter(([schema, , , prompt]) => !!schema && !!prompt), switchMap(([schema, threadId, pipeline, prompt, history]) => {
260
+ // Use a shallow copy of the pipeline
261
+ const previousError = history[history.length - 1]?.assistance?.error;
262
+ const pipelineCopy = pipeline.map(stage => JSON.parse(JSON.stringify(stage))) || [];
263
+ console.info('Generating pipeline with prompt:', prompt, 'schema:', schema, 'threadId:', threadId, 'pipeline:', pipeline);
264
+ return this.generatePipeline(prompt, schema, threadId, pipelineCopy, previousError).pipe(map((response) => ({ ...response, history, prompt })));
265
+ }), tap((response) => {
266
+ const { pipeline, threadId, history, prompt } = response;
267
+ const historyRecord = {
268
+ user: prompt,
269
+ assistance: response,
270
+ date: new Date()
271
+ };
272
+ // Use next with a concatenated value for chat history
273
+ this.chatHistory$.next([...(history || []), historyRecord]);
274
+ this.pipeline$.next(pipeline);
275
+ this.threadId$.next(threadId);
276
+ // Store threadID locally
277
+ localStorage.setItem('threadId', threadId);
278
+ // Run the active pipeline after all state updates are complete
279
+ console.log("prompt submitted run pipeline");
280
+ this.runActivePipeline();
281
+ }), catchError((error) => {
282
+ console.error('Error response:', error.message || error);
283
+ return this.handleError(error);
284
+ })).subscribe();
285
+ }
286
+ runActivePipeline() {
287
+ const pipeline = [...(this.pipeline$.getValue().map(stage => (JSON.parse(JSON.stringify(stage)))) || [])];
288
+ const someAreNotValid = pipeline.some(stage => Object.keys(stage).length === 0);
289
+ if (pipeline.length === 0 || someAreNotValid) {
290
+ return;
291
+ }
292
+ try {
293
+ PipelineBuilder.validatePipeline(pipeline);
294
+ }
295
+ catch (error) {
296
+ console.error(error, pipeline);
297
+ return;
298
+ }
299
+ const workflowId = this.workflowId$.getValue();
300
+ if (!workflowId) {
301
+ return;
302
+ }
303
+ this.runPipeLine(pipeline, workflowId).pipe(take(1), tap(({ results }) => {
304
+ this.pipeLineResult$.next(results);
305
+ }), catchError((error) => {
306
+ console.error('Error response:', error);
307
+ const err = JSON.parse(JSON.stringify(error));
308
+ const errorMessage = err.error;
309
+ if (errorMessage) {
310
+ this.pipelineErrorLogAndRetry(errorMessage);
311
+ }
312
+ return this.handleError(error);
313
+ })).subscribe();
314
+ }
315
+ pipelineErrorLogAndRetry(message) {
316
+ const history = this.chatHistory$.getValue();
317
+ const prompt = this.prompt$.getValue();
318
+ const historyRecord = {
319
+ user: prompt,
320
+ assistance: {
321
+ message
322
+ },
323
+ date: new Date()
324
+ };
325
+ this.chatHistory$.next([...(history || []), historyRecord]);
326
+ }
327
+ get activeStage() {
328
+ return this.pipeline$.asObservable().pipe(switchMap(pipeline => this.activeStage$.pipe(map(activeIndex => activeIndex === undefined ? undefined : {
329
+ name: Object.keys(pipeline[activeIndex] || {})[0] || '',
330
+ config: pipeline[activeIndex][Object.keys(pipeline[activeIndex] || {})?.[0] || '']
331
+ }))));
332
+ }
333
+ saveStage(index, stage) {
334
+ const pipeline = this.pipeline$.getValue();
335
+ if (index === undefined) {
336
+ return;
337
+ }
338
+ const newPipeline = pipeline.map((s, i) => {
339
+ if (i === index) {
340
+ return stage ? {
341
+ [stage.stage]: stage.config
342
+ } : s;
343
+ }
344
+ return s;
345
+ });
346
+ console.log("newPipeline", newPipeline);
347
+ this.pipeline$.next(newPipeline);
348
+ this.activeStage$.next(undefined);
349
+ console.log("stage saved run pipeline");
350
+ this.runActivePipeline();
351
+ }
352
+ deleteStage(index) {
353
+ const pipeline = this.pipeline$.getValue();
354
+ if (index === undefined) {
355
+ return;
356
+ }
357
+ const newPipeline = pipeline.filter((s, i) => i !== index);
358
+ console.log("newPipeline", newPipeline);
359
+ this.pipeline$.next(newPipeline);
360
+ this.activeStage$.next(undefined);
361
+ console.log("stage deleted run pipeline");
362
+ this.runActivePipeline();
363
+ }
364
+ get pipelineGeneralValid() {
365
+ return this.pipeline$.asObservable().pipe(map(pipeline => {
366
+ const allHaveTypes = pipeline.every(stage => Object.keys(stage).length === 1);
367
+ if (!allHaveTypes) {
368
+ return {
369
+ valid: false,
370
+ message: "All stages must be a valid pipeline stage"
371
+ };
372
+ }
373
+ const AllStagesMustHaveConfig = pipeline.every((stage) => stage[Object.keys(stage)?.[0] || ''] !== undefined);
374
+ if (!AllStagesMustHaveConfig) {
375
+ return {
376
+ valid: false,
377
+ message: "All stages must have a configuration"
378
+ };
379
+ }
380
+ return {
381
+ valid: true
382
+ };
383
+ }));
384
+ }
385
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PipelineService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
386
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PipelineService, providedIn: 'root' }); }
387
+ }
388
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PipelineService, decorators: [{
389
+ type: Injectable,
390
+ args: [{
391
+ providedIn: 'root'
392
+ }]
393
+ }], ctorParameters: () => [] });
394
+
395
+ class PipelineGeneratorComponent {
396
+ static { this.nextId = 0; }
397
+ constructor(ngControl, _elementRef) {
398
+ this.ngControl = ngControl;
399
+ this._elementRef = _elementRef;
400
+ this.stateChanges = new Subject();
401
+ this.NGX_T_FORMS_CONFIG = inject(NGX_T_FORMS_CONFIG_TOKEN);
402
+ this.id = `app-pipeline-generator-${PipelineGeneratorComponent.nextId++}`;
403
+ this.placeholder = '';
404
+ this.focused = false;
405
+ this.required = false;
406
+ this.disabled = false;
407
+ this.touched = false;
408
+ this.onTouched = () => { };
409
+ this.valueChanged = new EventEmitter();
410
+ this.errors = [];
411
+ this.destroy$ = new Subject();
412
+ this.pipeline = new PipelineService();
413
+ this.initiated = false;
414
+ this.initiateSubscription = () => {
415
+ this.pipeline.config$.pipe(takeUntil(this.destroy$), distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr))).subscribe(config => {
416
+ if (!this.initiated) {
417
+ this.initiated = true;
418
+ return;
419
+ }
420
+ const newConfig = {
421
+ ...this._value,
422
+ ...config,
423
+ name: this._workflowName || 'Unnamed Pipeline',
424
+ "source": "mongoPipeline",
425
+ };
426
+ console.log('Pipeline config changed', newConfig);
427
+ this.valueChanged.emit(newConfig);
428
+ });
429
+ };
430
+ this.cursorPosition = 0;
431
+ this.showSuggestions = false;
432
+ this.optionsSearch = '';
433
+ this.trackById = (index, stage) => index;
434
+ }
435
+ get empty() {
436
+ return !this.value;
437
+ }
438
+ get shouldLabelFloat() {
439
+ return this.focused || !this.empty;
440
+ }
441
+ get errorState() {
442
+ const hasError = !!this.ngControl?.control?.errors || (this.errors || []).length > 0 && this.touched;
443
+ return !this.value && !!this.required || hasError;
444
+ }
445
+ setDescribedByIds(ids) {
446
+ // Ensure the component view is initialized
447
+ if (this._elementRef && this._elementRef.nativeElement) {
448
+ const controlElement = this._elementRef.nativeElement.querySelector('.app-pipeline-generator');
449
+ // Check if the controlElement exists before attempting to set its attribute
450
+ if (controlElement) {
451
+ controlElement.setAttribute('aria-describedby', ids.join(' '));
452
+ }
453
+ }
454
+ }
455
+ onContainerClick(event) {
456
+ this.markAsTouched();
457
+ this.stateChanges.next();
458
+ }
459
+ markAsTouched() {
460
+ console.log('markAsTouched');
461
+ if (!this.touched) {
462
+ this.onTouched();
463
+ this.touched = true;
464
+ }
465
+ }
466
+ set value(value) {
467
+ const workflowIdChanged = this._value?.workflowId !== value?.workflowId;
468
+ const pipelineLengthChanged = this._value?.pipeline?.length !== value?.pipeline?.length;
469
+ const pipeLineContentChanged = JSON.stringify(this._value?.pipeline) !== JSON.stringify(value?.pipeline);
470
+ if (workflowIdChanged || pipelineLengthChanged || pipeLineContentChanged) {
471
+ this._value = value;
472
+ if (value?.workflowId) {
473
+ this.workflowChanged(value?.workflowId);
474
+ }
475
+ console.log('Pipeline value changed', value, this.pipeline.pipeline$.value);
476
+ if (value?.pipeline) {
477
+ this.pipeline.pipeline$.next(value?.pipeline || []);
478
+ }
479
+ }
480
+ }
481
+ set getWorkflowOptions(options$) {
482
+ this.workflows$ = options$;
483
+ }
484
+ ngOnInit() {
485
+ this.initiateSubscription();
486
+ }
487
+ ngOnDestroy() {
488
+ this.destroy$.next();
489
+ this.destroy$.complete();
490
+ }
491
+ workflowChanged(event) {
492
+ this.pipeline.workflowChanged(event);
493
+ }
494
+ workflowNameChanged(event) {
495
+ this._workflowName = event;
496
+ }
497
+ get workflowId() {
498
+ return this.pipeline.workflowId$.asObservable();
499
+ }
500
+ get stages() {
501
+ return this.pipeline.pipeline$.asObservable().pipe(map(stages => stages.map(stage => ({
502
+ name: Object.keys(stage)[0],
503
+ stage: Object.keys(stage)[0],
504
+ config: stage[Object.keys(stage)?.[0] || ''],
505
+ valid: !!Object.keys(stage)[0] && !!stage[Object.keys(stage)?.[0] || '']
506
+ }))));
507
+ }
508
+ get pipeLineResults() {
509
+ return this.pipeline.pipeLineResult$.asObservable();
510
+ }
511
+ get prompt() {
512
+ return this.pipeline.prompt$.asObservable();
513
+ }
514
+ get aiIsGeneratingPipeline() {
515
+ return this.pipeline.aiIsGeneratingPipeline;
516
+ }
517
+ get activeStageIndex() {
518
+ return this.pipeline.activeStage$.asObservable();
519
+ }
520
+ get activeStage() {
521
+ console.log(this.pipeline.activeStage);
522
+ return this.pipeline.activeStage;
523
+ }
524
+ get isRunningPipeline() {
525
+ return this.pipeline.isRunningPipeline;
526
+ }
527
+ get cannotAddStage() {
528
+ return this.pipeline.pipelineGeneralValid.pipe(map(valid => !valid));
529
+ }
530
+ get schemaLoadError$() {
531
+ return this.pipeline.schemaLoadError$.asObservable();
532
+ }
533
+ get chatHistory() {
534
+ return this.pipeline.chatHistory$.asObservable();
535
+ }
536
+ onTextChange(event) {
537
+ if (!this.textareaElementRef?.nativeElement) {
538
+ return;
539
+ }
540
+ console.log('onTextChange', event);
541
+ const newValue = event.target.value;
542
+ const textarea = this.textareaElementRef.nativeElement;
543
+ this.cursorPosition = textarea.selectionStart || 0;
544
+ const lastChar = newValue[this.cursorPosition - 1];
545
+ const match = newValue.slice(0, this.cursorPosition).match(/\$(\w*)$/);
546
+ if (lastChar === '$' || (match && match[1] !== undefined)) {
547
+ this.showSuggestions = true;
548
+ this.optionsSearch = match ? match?.[1] || '' : '';
549
+ }
550
+ else {
551
+ this.showSuggestions = false;
552
+ this.optionsSearch = '';
553
+ }
554
+ this.pipeline.onTextChange(newValue);
555
+ }
556
+ selectSuggestionInput(suggestion) {
557
+ this.pipeline.prompt$.asObservable().pipe(take(1), tap(prompt => {
558
+ const match = prompt?.slice(0, this.cursorPosition).match(/\$(\w*)$/);
559
+ const beforeCursor = prompt?.slice(0, match ? match.index : this.cursorPosition - 1);
560
+ const afterCursor = prompt?.slice(this.cursorPosition);
561
+ prompt = beforeCursor + suggestion + ' ' + afterCursor;
562
+ this.pipeline.prompt$.next(prompt);
563
+ this.applyNewValueToPrompt(suggestion);
564
+ })).subscribe();
565
+ }
566
+ applyNewValueToPrompt(suggestion) {
567
+ this.showSuggestions = false;
568
+ const textarea = this.textareaElementRef.nativeElement;
569
+ textarea.focus();
570
+ const newCursorPosition = this.cursorPosition + suggestion.length;
571
+ setTimeout(() => {
572
+ textarea.setSelectionRange(newCursorPosition, newCursorPosition);
573
+ }, 0);
574
+ }
575
+ onSearchChange(event) {
576
+ this.optionsSearch = event.detail.value;
577
+ }
578
+ promptSubmit() {
579
+ this.pipeline.promptSubmit();
580
+ console.log('promptSubmit');
581
+ }
582
+ setActiveStage(index) {
583
+ this.pipeline.setActiveStage(index);
584
+ }
585
+ addStage() {
586
+ this.pipeline.addStage();
587
+ }
588
+ get getSchemaProperties() {
589
+ return this.pipeline.schema$.asObservable().pipe(map(schema => Object.keys(schema || {}).map(key => ({ label: key, value: key, })).filter(key => this.optionsSearch ? key.label.toLowerCase().includes(this.optionsSearch.toLowerCase()) : true)));
590
+ }
591
+ deleteStage(index) {
592
+ this.pipeline.deleteStage(index);
593
+ }
594
+ saveStage(index, stage) {
595
+ this.pipeline.saveStage(index, stage);
596
+ this.setActiveStage(undefined);
597
+ }
598
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PipelineGeneratorComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
599
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: PipelineGeneratorComponent, isStandalone: true, selector: "app-pipeline-generator", inputs: { disabled: "disabled", value: "value", getWorkflowOptions: "getWorkflowOptions", userName: "userName", errors: "errors" }, outputs: { valueChanged: "valueChanged" }, host: { properties: { "id": "this.id" } }, providers: [{ provide: MatFormFieldControl, useExisting: PipelineGeneratorComponent }], viewQueries: [{ propertyName: "textareaElementRef", first: true, predicate: ["textarea"], descendants: true, read: ElementRef }], ngImport: i0, template: "\r\n\r\n\r\n<section class=\"ion-margin\">\r\n <p>MongoDB aggregation pipeline builder for selected workflows. </p>\r\n</section>\r\n<lib-t-workflow-picker \r\n(valueChanged)=\"workflowChanged($event)\"\r\n(workflowNameChanged)=\"workflowNameChanged($event)\" \r\n[getWorkflowOptions]=\" workflows$\"\r\n [value]=\"(workflowId|async)||undefined\">\r\n</lib-t-workflow-picker>\r\n<mat-accordion multi *ngIf=\"workflowId|async\">\r\n <!-- Pipeline Accordion -->\r\n <mat-expansion-panel value=\"pipeline\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">\r\n dynamic_form\r\n </mat-icon>\r\n {{isRunningPipeline?'Executing current Data pipeline...':'Data retrieval pipeline'}}\r\n </mat-panel-title>\r\n\r\n </mat-expansion-panel-header>\r\n <div class=\"content\">\r\n <!-- Mongodb aggregate pipelione stages management and edit start-->\r\n <div *ngIf=\"((stages | async)?.length || 0) ===0\" class=\"tree-instructions\">\r\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\r\n <span>\r\n Add stages to the pipeline below.<br>\r\n Each stage processes input documents by filtering, grouping, or calculating values. The output documents from\r\n one stage are passed to the next stage in the pipeline.\r\n </span>\r\n </div>\r\n\r\n <mat-nav-list style=\" background: var(--mat-tree-container-background-color);padding:0px;border-radius:8px\">\r\n\r\n\r\n <ng-container *ngFor=\"let stage of stages | async; trackBy: trackById;index as $index;last as isLast\">\r\n <mat-list-item [style.margin-top]=\"(activeStageIndex|async) ===$index?'4px':'0px'\"\r\n [class.mat-elevation-z8]=\"(activeStageIndex|async) ===$index\" class=\"stage-item\"\r\n (click)=\"setActiveStage($index)\" [activated]=\" (activeStageIndex|async) ===$index\">\r\n <span class=\"stage-index\" matListItemAvatar>{{$index + 1}} </span>\r\n <div matListItemTitle>\r\n <div style=\"line-height: normal;\">\r\n {{ stage.name || 'Stage ' }}\r\n </div>\r\n <div class=\"stage-inner-message\" *ngIf=\"!stage.name && (activeStageIndex|async) !==$index \">\r\n Incomplete , click to edit\r\n </div>\r\n\r\n </div>\r\n\r\n <button *ngIf=\"(activeStageIndex|async) ===$index||!stage.valid && (activeStageIndex|async) !==$index\"\r\n mat-icon-button matListItemMeta>\r\n <mat-icon color=\"primary\" *ngIf=\"(activeStageIndex|async) ===$index\">check_circle</mat-icon>\r\n\r\n <mat-icon color=\"warn\" *ngIf=\"!stage.valid && (activeStageIndex|async) !==$index\">\r\n warning\r\n </mat-icon>\r\n </button>\r\n </mat-list-item>\r\n <mat-divider></mat-divider>\r\n\r\n <app-aggregate-stage-editor [selectedStage]=\"stage\" [isRunningPipeline]=\"isRunningPipeline\"\r\n (deleteStage)=\"deleteStage($index)\" (saveStage)=\"saveStage($index,$event)\"\r\n *ngIf=\"(activeStageIndex|async) ===$index\"></app-aggregate-stage-editor>\r\n\r\n\r\n </ng-container>\r\n\r\n <mat-toolbar style=\"padding: 0px;\">\r\n\r\n <span class=\"spacer\"></span>\r\n <button class=\"stage-button\" [disabled]=\"isRunningPipeline\" color=\"primary\" (click)=\"addStage()\"\r\n mat-raised-button>\r\n Add\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n </mat-toolbar>\r\n </mat-nav-list>\r\n\r\n <!-- Mongodb aggregate pipelione stages management and edit end -->\r\n </div>\r\n </mat-expansion-panel>\r\n\r\n <!-- Results Accordion -->\r\n <mat-expansion-panel value=\"results\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">dataset</mat-icon>\r\n {{isRunningPipeline?'Running pipeline...':'Data Results'}}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"content\">\r\n <ng-container *ngIf=\"pipeLineResults | async as results; else noResults\">\r\n\r\n <lib-t-dynamic-data-view *ngIf=\"results\" [data]=\"results\"></lib-t-dynamic-data-view>\r\n <p *ngIf=\"!results\" color=\"medium\">\r\n\r\n No results available\r\n\r\n </p>\r\n\r\n </ng-container>\r\n <ng-template #noResults>\r\n <p color=\"medium\">No results available</p>\r\n </ng-template>\r\n </div>\r\n </mat-expansion-panel>\r\n\r\n <!-- AI Agent Accordion -->\r\n <mat-expansion-panel value=\"ai\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner *ngIf=\" aiIsGeneratingPipeline \" style=\"position: absolute;\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">tips_and_updates</mat-icon>\r\n {{ aiIsGeneratingPipeline ? 'Agent busy ...' : 'AI AGENT prompt' }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div class=\"content\">\r\n @if( schemaLoadError$ | async){\r\n <div class=\"tree-instructions\" style=\"background: antiquewhite !important;\">\r\n <mat-icon class=\"info-icon\" color=\"warn\">error</mat-icon>\r\n <span> {{ schemaLoadError$ | async }}</span>\r\n </div>\r\n \r\n }\r\n <mat-list *ngFor=\"let chat of chatHistory|async;\">\r\n\r\n <mat-list-item class=\"chatContent chatItem\">\r\n <div class=\"chat\" style=\"background:bisque;text-align:end;\r\n border-radius: 18px 18px 0px 18px;\" matListItemTitle>\r\n <div>\r\n {{chat.user}}\r\n </div>\r\n <div style=\"opacity:0.6;line-height: normal;display: flex;align-items: center;justify-content: flex-end;\">\r\n {{chat.date|daysAgo}}\r\n <mat-icon class=\"sent-icon\">\r\n done_all\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </mat-list-item>\r\n\r\n <mat-list-item style=\"margin-top: 16px;\" class=\"chatContent chatItem\" color=\"light\" lines=\"full\">\r\n <mat-icon style=\" margin-left: 0px;\r\n margin-top: 16px;\r\n margin-bottom: auto;\" matListItemIcon>smart_toy</mat-icon>\r\n <div class=\"chat\" style=\"text-align: left; \r\n padding-left: 16px; \r\n background: azure;\r\n border-radius: 0px 18px 18px 18px;\" *ngIf=\"!chat.assistance?.error\" matListItemTitle>\r\n <pre>\r\n {{chat. assistance.pipeline |json}}\r\n </pre>\r\n </div>\r\n <div *ngIf=\"chat.assistance?.error\" matListItemTitle>\r\n {{chat.assistance.error}}\r\n </div>\r\n </mat-list-item>\r\n\r\n\r\n </mat-list>\r\n <mat-list>\r\n <mat-list-item class=\"chatContent chatItem\">\r\n <textarea matListItemTitle #textarea style=\" width: calc(100% - 13px);\r\n border-radius: 14px;\r\n padding-right: 3px;\r\n padding-left: 8px;\" class=\"chat\" [value]=\" prompt|async\" (input)=\"onTextChange($event)\"\r\n placeholder=\"Provide a pipeline generation prompt\"></textarea>\r\n <button matListItemMeta style=\" margin-left: 4px;\r\n margin-right: 0px;\" color=\"primary\" mat-mini-fab [disabled]=\"aiIsGeneratingPipeline\" (click)=\"promptSubmit()\">\r\n\r\n <mat-icon style=\"margin: 0px !important;color:white\">send</mat-icon>\r\n <mat-spinner color=\"accent\" *ngIf=\" aiIsGeneratingPipeline \" \r\n class=\"submit-spinner\" ></mat-spinner>\r\n </button>\r\n \r\n </mat-list-item>\r\n\r\n </mat-list>\r\n\r\n\r\n <section *ngIf=\"showSuggestions\" class=\"showSuggestionContainer\">\r\n <!-- <mat-toolbar class=\"search-container\" style=\"background: inherit;\">\r\n\r\n\r\n <input type=\"search\" placeholder=\"Search options\" class=\"search-field\" (change)=\"onSearchChange($event)\">\r\n\r\n <mat-icon>\r\n search\r\n </mat-icon>\r\n </mat-toolbar> -->\r\n <mat-divider></mat-divider>\r\n <div style=\"padding: 8px;\">\r\n <div class=\"suggestion-container\">\r\n <div class=\"suggestion-column\">\r\n <h5>Collection document properties</h5>\r\n <div class=\"button-container\">\r\n <button *ngFor=\"let method of getSchemaProperties | async;trackBy: trackById\"\r\n (click)=\"selectSuggestionInput(method.value)\" color=\"accent\" mat-flat-button\r\n class=\"suggestion-button\">\r\n {{ method.label | titlecase }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n </section>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n </div>\r\n </mat-expansion-panel>\r\n</mat-accordion>\r\n\r\n\r\n\r\n\r\n<ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOpen]=\"disabled\"\r\n>\r\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5);\">\r\n\r\n\r\n</div>\r\n</ng-template>\r\n", styles: ["ion-card{margin:0 auto}.head{font-weight:500;font-size:.9rem;padding-left:8px}.chat{margin-top:0;padding-bottom:8px;padding-top:9px;padding-right:16px;white-space:normal;font-size:.8rem}.icon{margin-top:auto;margin-bottom:auto;margin-right:16px}.container{max-width:600px;margin:0 auto}ion-accordion-group{margin:16px}ion-icon{margin-right:16PX}.suggestion-container{display:flex;width:100%;gap:14px}.suggestion-column{flex:1;min-width:0}.button-container{display:flex;flex-wrap:wrap}.suggestion-button{height:auto;text-transform:capitalize;margin:2px;padding:8px;line-height:normal;text-align:left;font-size:.8em}h5{margin-bottom:8px;font-size:1em}mat-expansion-panel-header{padding-left:16px;padding-right:16px}mat-expansion-panel{background:var(--mat-sys-surface-container, var(--mat-app-surface))}mat-form-field{width:100%;background:azure}.chatItem{padding:0}.chatItem mat-icon{margin-left:16px;margin-right:16px}.chatContent{height:fit-content!important}.stage-button{margin:4px}.stage-index{font-size:.875em;display:flex;width:28px;height:28px;justify-content:center;background:azure;align-items:center;border:solid var(--mat-divider-color, var(--mat-app-outline)) 1px}.stage-inner-message{font-size:.875em;display:flex;line-height:normal;opacity:.6}.stage-item{height:54px!important}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:azure;border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px!important;display:block}.title-icon{margin-right:8px;vertical-align:middle}.header-spinner{position:absolute;width:24px!important;height:24px!important}.sent-icon{font-size:.875em;height:14px;margin-right:0!important;margin-left:0!important}.submit-spinner{position:absolute;width:40px!important;right:-8px;top:-20px;height:40px!important;--mdc-circular-progress-size: 40px !important;--mdc-circular-progress-active-indicator-width: 40px !important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2$4.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$4.JsonPipe, name: "json" }, { kind: "pipe", type: i2$4.TitleCasePipe, name: "titlecase" }, { kind: "component", type: TWorkflowPickerComponent, selector: "lib-t-workflow-picker", inputs: ["disabled", "errors", "required", "value", "placeholder", "getWorkflowOptions"], outputs: ["valueChange", "valueChanged", "workflowNameChanged"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: TDynamicDataViewComponent, selector: "lib-t-dynamic-data-view", inputs: ["data"] }, { kind: "ngmodule", type: MatModulesModule }, { kind: "component", type: i2$1.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab]", exportAs: ["matButton"] }, { kind: "component", type: i4.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "directive", type: i5.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i5.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: i2$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i7.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i7.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i7.MatListItemAvatar, selector: "[matListItemAvatar]" }, { kind: "directive", type: i7.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i7.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: i7.MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "component", type: i3$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i10.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i10$1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: AggregateStageEditorComponent, selector: "app-aggregate-stage-editor", inputs: ["selectedStage", "isRunningPipeline"], outputs: ["saveStage", "deleteStage"] }, { kind: "pipe", type: DaysAgoPipe, name: "daysAgo" }, { kind: "ngmodule", type: OverlayModule }] }); }
600
+ }
601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: PipelineGeneratorComponent, decorators: [{
602
+ type: Component,
603
+ args: [{ selector: 'app-pipeline-generator', standalone: true, imports: [
604
+ CommonModule,
605
+ TWorkflowPickerComponent,
606
+ FormsModule,
607
+ TDynamicDataViewComponent,
608
+ MatModulesModule,
609
+ AggregateStageEditorComponent,
610
+ DaysAgoPipe,
611
+ OverlayModule
612
+ ], providers: [{ provide: MatFormFieldControl, useExisting: PipelineGeneratorComponent }], template: "\r\n\r\n\r\n<section class=\"ion-margin\">\r\n <p>MongoDB aggregation pipeline builder for selected workflows. </p>\r\n</section>\r\n<lib-t-workflow-picker \r\n(valueChanged)=\"workflowChanged($event)\"\r\n(workflowNameChanged)=\"workflowNameChanged($event)\" \r\n[getWorkflowOptions]=\" workflows$\"\r\n [value]=\"(workflowId|async)||undefined\">\r\n</lib-t-workflow-picker>\r\n<mat-accordion multi *ngIf=\"workflowId|async\">\r\n <!-- Pipeline Accordion -->\r\n <mat-expansion-panel value=\"pipeline\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">\r\n dynamic_form\r\n </mat-icon>\r\n {{isRunningPipeline?'Executing current Data pipeline...':'Data retrieval pipeline'}}\r\n </mat-panel-title>\r\n\r\n </mat-expansion-panel-header>\r\n <div class=\"content\">\r\n <!-- Mongodb aggregate pipelione stages management and edit start-->\r\n <div *ngIf=\"((stages | async)?.length || 0) ===0\" class=\"tree-instructions\">\r\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\r\n <span>\r\n Add stages to the pipeline below.<br>\r\n Each stage processes input documents by filtering, grouping, or calculating values. The output documents from\r\n one stage are passed to the next stage in the pipeline.\r\n </span>\r\n </div>\r\n\r\n <mat-nav-list style=\" background: var(--mat-tree-container-background-color);padding:0px;border-radius:8px\">\r\n\r\n\r\n <ng-container *ngFor=\"let stage of stages | async; trackBy: trackById;index as $index;last as isLast\">\r\n <mat-list-item [style.margin-top]=\"(activeStageIndex|async) ===$index?'4px':'0px'\"\r\n [class.mat-elevation-z8]=\"(activeStageIndex|async) ===$index\" class=\"stage-item\"\r\n (click)=\"setActiveStage($index)\" [activated]=\" (activeStageIndex|async) ===$index\">\r\n <span class=\"stage-index\" matListItemAvatar>{{$index + 1}} </span>\r\n <div matListItemTitle>\r\n <div style=\"line-height: normal;\">\r\n {{ stage.name || 'Stage ' }}\r\n </div>\r\n <div class=\"stage-inner-message\" *ngIf=\"!stage.name && (activeStageIndex|async) !==$index \">\r\n Incomplete , click to edit\r\n </div>\r\n\r\n </div>\r\n\r\n <button *ngIf=\"(activeStageIndex|async) ===$index||!stage.valid && (activeStageIndex|async) !==$index\"\r\n mat-icon-button matListItemMeta>\r\n <mat-icon color=\"primary\" *ngIf=\"(activeStageIndex|async) ===$index\">check_circle</mat-icon>\r\n\r\n <mat-icon color=\"warn\" *ngIf=\"!stage.valid && (activeStageIndex|async) !==$index\">\r\n warning\r\n </mat-icon>\r\n </button>\r\n </mat-list-item>\r\n <mat-divider></mat-divider>\r\n\r\n <app-aggregate-stage-editor [selectedStage]=\"stage\" [isRunningPipeline]=\"isRunningPipeline\"\r\n (deleteStage)=\"deleteStage($index)\" (saveStage)=\"saveStage($index,$event)\"\r\n *ngIf=\"(activeStageIndex|async) ===$index\"></app-aggregate-stage-editor>\r\n\r\n\r\n </ng-container>\r\n\r\n <mat-toolbar style=\"padding: 0px;\">\r\n\r\n <span class=\"spacer\"></span>\r\n <button class=\"stage-button\" [disabled]=\"isRunningPipeline\" color=\"primary\" (click)=\"addStage()\"\r\n mat-raised-button>\r\n Add\r\n <mat-icon>add</mat-icon>\r\n </button>\r\n </mat-toolbar>\r\n </mat-nav-list>\r\n\r\n <!-- Mongodb aggregate pipelione stages management and edit end -->\r\n </div>\r\n </mat-expansion-panel>\r\n\r\n <!-- Results Accordion -->\r\n <mat-expansion-panel value=\"results\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">dataset</mat-icon>\r\n {{isRunningPipeline?'Running pipeline...':'Data Results'}}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div class=\"content\">\r\n <ng-container *ngIf=\"pipeLineResults | async as results; else noResults\">\r\n\r\n <lib-t-dynamic-data-view *ngIf=\"results\" [data]=\"results\"></lib-t-dynamic-data-view>\r\n <p *ngIf=\"!results\" color=\"medium\">\r\n\r\n No results available\r\n\r\n </p>\r\n\r\n </ng-container>\r\n <ng-template #noResults>\r\n <p color=\"medium\">No results available</p>\r\n </ng-template>\r\n </div>\r\n </mat-expansion-panel>\r\n\r\n <!-- AI Agent Accordion -->\r\n <mat-expansion-panel value=\"ai\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n <mat-spinner *ngIf=\" aiIsGeneratingPipeline \" style=\"position: absolute;\" class=\"header-spinner\"></mat-spinner>\r\n <mat-icon class=\"title-icon\">tips_and_updates</mat-icon>\r\n {{ aiIsGeneratingPipeline ? 'Agent busy ...' : 'AI AGENT prompt' }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n\r\n <div class=\"content\">\r\n @if( schemaLoadError$ | async){\r\n <div class=\"tree-instructions\" style=\"background: antiquewhite !important;\">\r\n <mat-icon class=\"info-icon\" color=\"warn\">error</mat-icon>\r\n <span> {{ schemaLoadError$ | async }}</span>\r\n </div>\r\n \r\n }\r\n <mat-list *ngFor=\"let chat of chatHistory|async;\">\r\n\r\n <mat-list-item class=\"chatContent chatItem\">\r\n <div class=\"chat\" style=\"background:bisque;text-align:end;\r\n border-radius: 18px 18px 0px 18px;\" matListItemTitle>\r\n <div>\r\n {{chat.user}}\r\n </div>\r\n <div style=\"opacity:0.6;line-height: normal;display: flex;align-items: center;justify-content: flex-end;\">\r\n {{chat.date|daysAgo}}\r\n <mat-icon class=\"sent-icon\">\r\n done_all\r\n </mat-icon>\r\n </div>\r\n </div>\r\n </mat-list-item>\r\n\r\n <mat-list-item style=\"margin-top: 16px;\" class=\"chatContent chatItem\" color=\"light\" lines=\"full\">\r\n <mat-icon style=\" margin-left: 0px;\r\n margin-top: 16px;\r\n margin-bottom: auto;\" matListItemIcon>smart_toy</mat-icon>\r\n <div class=\"chat\" style=\"text-align: left; \r\n padding-left: 16px; \r\n background: azure;\r\n border-radius: 0px 18px 18px 18px;\" *ngIf=\"!chat.assistance?.error\" matListItemTitle>\r\n <pre>\r\n {{chat. assistance.pipeline |json}}\r\n </pre>\r\n </div>\r\n <div *ngIf=\"chat.assistance?.error\" matListItemTitle>\r\n {{chat.assistance.error}}\r\n </div>\r\n </mat-list-item>\r\n\r\n\r\n </mat-list>\r\n <mat-list>\r\n <mat-list-item class=\"chatContent chatItem\">\r\n <textarea matListItemTitle #textarea style=\" width: calc(100% - 13px);\r\n border-radius: 14px;\r\n padding-right: 3px;\r\n padding-left: 8px;\" class=\"chat\" [value]=\" prompt|async\" (input)=\"onTextChange($event)\"\r\n placeholder=\"Provide a pipeline generation prompt\"></textarea>\r\n <button matListItemMeta style=\" margin-left: 4px;\r\n margin-right: 0px;\" color=\"primary\" mat-mini-fab [disabled]=\"aiIsGeneratingPipeline\" (click)=\"promptSubmit()\">\r\n\r\n <mat-icon style=\"margin: 0px !important;color:white\">send</mat-icon>\r\n <mat-spinner color=\"accent\" *ngIf=\" aiIsGeneratingPipeline \" \r\n class=\"submit-spinner\" ></mat-spinner>\r\n </button>\r\n \r\n </mat-list-item>\r\n\r\n </mat-list>\r\n\r\n\r\n <section *ngIf=\"showSuggestions\" class=\"showSuggestionContainer\">\r\n <!-- <mat-toolbar class=\"search-container\" style=\"background: inherit;\">\r\n\r\n\r\n <input type=\"search\" placeholder=\"Search options\" class=\"search-field\" (change)=\"onSearchChange($event)\">\r\n\r\n <mat-icon>\r\n search\r\n </mat-icon>\r\n </mat-toolbar> -->\r\n <mat-divider></mat-divider>\r\n <div style=\"padding: 8px;\">\r\n <div class=\"suggestion-container\">\r\n <div class=\"suggestion-column\">\r\n <h5>Collection document properties</h5>\r\n <div class=\"button-container\">\r\n <button *ngFor=\"let method of getSchemaProperties | async;trackBy: trackById\"\r\n (click)=\"selectSuggestionInput(method.value)\" color=\"accent\" mat-flat-button\r\n class=\"suggestion-button\">\r\n {{ method.label | titlecase }}\r\n </button>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n\r\n\r\n </div>\r\n </section>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n </div>\r\n </mat-expansion-panel>\r\n</mat-accordion>\r\n\r\n\r\n\r\n\r\n<ng-template\r\n cdkConnectedOverlay\r\n [cdkConnectedOverlayOpen]=\"disabled\"\r\n>\r\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5);\">\r\n\r\n\r\n</div>\r\n</ng-template>\r\n", styles: ["ion-card{margin:0 auto}.head{font-weight:500;font-size:.9rem;padding-left:8px}.chat{margin-top:0;padding-bottom:8px;padding-top:9px;padding-right:16px;white-space:normal;font-size:.8rem}.icon{margin-top:auto;margin-bottom:auto;margin-right:16px}.container{max-width:600px;margin:0 auto}ion-accordion-group{margin:16px}ion-icon{margin-right:16PX}.suggestion-container{display:flex;width:100%;gap:14px}.suggestion-column{flex:1;min-width:0}.button-container{display:flex;flex-wrap:wrap}.suggestion-button{height:auto;text-transform:capitalize;margin:2px;padding:8px;line-height:normal;text-align:left;font-size:.8em}h5{margin-bottom:8px;font-size:1em}mat-expansion-panel-header{padding-left:16px;padding-right:16px}mat-expansion-panel{background:var(--mat-sys-surface-container, var(--mat-app-surface))}mat-form-field{width:100%;background:azure}.chatItem{padding:0}.chatItem mat-icon{margin-left:16px;margin-right:16px}.chatContent{height:fit-content!important}.stage-button{margin:4px}.stage-index{font-size:.875em;display:flex;width:28px;height:28px;justify-content:center;background:azure;align-items:center;border:solid var(--mat-divider-color, var(--mat-app-outline)) 1px}.stage-inner-message{font-size:.875em;display:flex;line-height:normal;opacity:.6}.stage-item{height:54px!important}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;background:azure;border-radius:4px;margin-bottom:16px}.info-icon{min-width:38px!important;display:block}.title-icon{margin-right:8px;vertical-align:middle}.header-spinner{position:absolute;width:24px!important;height:24px!important}.sent-icon{font-size:.875em;height:14px;margin-right:0!important;margin-left:0!important}.submit-spinner{position:absolute;width:40px!important;right:-8px;top:-20px;height:40px!important;--mdc-circular-progress-size: 40px !important;--mdc-circular-progress-active-indicator-width: 40px !important}\n"] }]
613
+ }], ctorParameters: () => [{ type: i1.NgControl, decorators: [{
614
+ type: Optional
615
+ }, {
616
+ type: Self
617
+ }] }, { type: i0.ElementRef }], propDecorators: { id: [{
618
+ type: HostBinding
619
+ }], disabled: [{
620
+ type: Input
621
+ }], textareaElementRef: [{
622
+ type: ViewChild,
623
+ args: ['textarea', { read: ElementRef, static: false }]
624
+ }], value: [{
625
+ type: Input
626
+ }], getWorkflowOptions: [{
627
+ type: Input
628
+ }], userName: [{
629
+ type: Input
630
+ }], valueChanged: [{
631
+ type: Output
632
+ }], errors: [{
633
+ type: Input
634
+ }] } });
635
+
636
+ export { PipelineGeneratorComponent };
637
+ //# sourceMappingURL=ngx-t-forms-pipeline-generator.component-QE-I58e4.mjs.map