ngx-t-forms 2.0.23 → 2.0.25

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 (148) hide show
  1. package/README.md +177 -16
  2. package/fesm2022/ngx-t-forms-calculated-field-rules.component-DiNSTxsW.mjs +313 -0
  3. package/fesm2022/ngx-t-forms-calculated-field-rules.component-DiNSTxsW.mjs.map +1 -0
  4. package/fesm2022/{ngx-t-forms-chip-options-creator-editor.component-DVhV4izc.mjs → ngx-t-forms-chip-options-creator-editor.component-3FkGwVWB.mjs} +6 -6
  5. package/fesm2022/{ngx-t-forms-chip-options-creator-editor.component-DVhV4izc.mjs.map → ngx-t-forms-chip-options-creator-editor.component-3FkGwVWB.mjs.map} +1 -1
  6. package/fesm2022/{ngx-t-forms-config-mscoa-additional-inputs.component-BTUnZ1q1.mjs → ngx-t-forms-config-mscoa-additional-inputs.component-tHaWIt1o.mjs} +10 -10
  7. package/fesm2022/{ngx-t-forms-config-mscoa-additional-inputs.component-BTUnZ1q1.mjs.map → ngx-t-forms-config-mscoa-additional-inputs.component-tHaWIt1o.mjs.map} +1 -1
  8. package/fesm2022/{ngx-t-forms-data-source-picker.component-DcpGy7kq.mjs → ngx-t-forms-data-source-picker.component-CxG1tQfC.mjs} +10 -10
  9. package/fesm2022/{ngx-t-forms-data-source-picker.component-DcpGy7kq.mjs.map → ngx-t-forms-data-source-picker.component-CxG1tQfC.mjs.map} +1 -1
  10. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CsqYlgS6.mjs +291 -0
  11. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CsqYlgS6.mjs.map +1 -0
  12. package/fesm2022/{ngx-t-forms-form-input-selector.component-n88ExFxv.mjs → ngx-t-forms-form-input-selector.component-D-nVF7t7.mjs} +8 -8
  13. package/fesm2022/{ngx-t-forms-form-input-selector.component-n88ExFxv.mjs.map → ngx-t-forms-form-input-selector.component-D-nVF7t7.mjs.map} +1 -1
  14. package/fesm2022/{ngx-t-forms-form-json-view.component-Bm-k704L.mjs → ngx-t-forms-form-json-view.component-B01nOklu.mjs} +6 -6
  15. package/fesm2022/{ngx-t-forms-form-json-view.component-Bm-k704L.mjs.map → ngx-t-forms-form-json-view.component-B01nOklu.mjs.map} +1 -1
  16. package/fesm2022/ngx-t-forms-form-section-stepper.component-Bg9eGmgN.mjs +267 -0
  17. package/fesm2022/ngx-t-forms-form-section-stepper.component-Bg9eGmgN.mjs.map +1 -0
  18. package/fesm2022/{ngx-t-forms-forms-builder-menu.component-Brj72jZP.mjs → ngx-t-forms-forms-builder-menu.component-jn9-yVbI.mjs} +21 -21
  19. package/fesm2022/ngx-t-forms-forms-builder-menu.component-jn9-yVbI.mjs.map +1 -0
  20. package/fesm2022/{ngx-t-forms-input-editor.component-BqRBvrQe.mjs → ngx-t-forms-input-editor.component-DyQBfgio.mjs} +19 -19
  21. package/fesm2022/{ngx-t-forms-input-editor.component-BqRBvrQe.mjs.map → ngx-t-forms-input-editor.component-DyQBfgio.mjs.map} +1 -1
  22. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-BCoTHeK3.mjs +106 -0
  23. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-BCoTHeK3.mjs.map +1 -0
  24. package/fesm2022/{ngx-t-forms-mat-slider-editor.component-CnnC8-nJ.mjs → ngx-t-forms-mat-slider-editor.component-WDd5lc_2.mjs} +5 -5
  25. package/fesm2022/{ngx-t-forms-mat-slider-editor.component-CnnC8-nJ.mjs.map → ngx-t-forms-mat-slider-editor.component-WDd5lc_2.mjs.map} +1 -1
  26. package/fesm2022/{ngx-t-forms-mat-slider-toggle-editor.component-B8O9Xn4R.mjs → ngx-t-forms-mat-slider-toggle-editor.component-DGac4Eja.mjs} +5 -5
  27. package/fesm2022/{ngx-t-forms-mat-slider-toggle-editor.component-B8O9Xn4R.mjs.map → ngx-t-forms-mat-slider-toggle-editor.component-DGac4Eja.mjs.map} +1 -1
  28. package/fesm2022/{ngx-t-forms-missing-form-configs.component-CXIOm7OT.mjs → ngx-t-forms-missing-form-configs.component-sJVu5SkY.mjs} +8 -8
  29. package/fesm2022/{ngx-t-forms-missing-form-configs.component-CXIOm7OT.mjs.map → ngx-t-forms-missing-form-configs.component-sJVu5SkY.mjs.map} +1 -1
  30. package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-CF5DxLZG.mjs +43 -0
  31. package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-CF5DxLZG.mjs.map +1 -0
  32. package/fesm2022/ngx-t-forms-mscoa-error-display.component-D9zKeT7Z.mjs +116 -0
  33. package/fesm2022/ngx-t-forms-mscoa-error-display.component-D9zKeT7Z.mjs.map +1 -0
  34. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-BIr1g5cG.mjs +299 -0
  35. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-BIr1g5cG.mjs.map +1 -0
  36. package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-DgdZwE72.mjs +83 -0
  37. package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-DgdZwE72.mjs.map +1 -0
  38. package/fesm2022/{ngx-t-forms-ngx-t-forms-BYmto56R.mjs → ngx-t-forms-ngx-t-forms-A9_4GxP6.mjs} +3855 -980
  39. package/fesm2022/ngx-t-forms-ngx-t-forms-A9_4GxP6.mjs.map +1 -0
  40. package/fesm2022/ngx-t-forms-pipeline-generator.component-CwCwl53b.mjs +637 -0
  41. package/fesm2022/ngx-t-forms-pipeline-generator.component-CwCwl53b.mjs.map +1 -0
  42. package/fesm2022/ngx-t-forms-record-list-manager.component-BYyr0yzb.mjs +270 -0
  43. package/fesm2022/ngx-t-forms-record-list-manager.component-BYyr0yzb.mjs.map +1 -0
  44. package/fesm2022/{ngx-t-forms-required-inputs.component-C5iwMGil.mjs → ngx-t-forms-required-inputs.component-pv5pqFhh.mjs} +12 -12
  45. package/fesm2022/{ngx-t-forms-required-inputs.component-C5iwMGil.mjs.map → ngx-t-forms-required-inputs.component-pv5pqFhh.mjs.map} +1 -1
  46. package/fesm2022/{ngx-t-forms-rest-api-call-setup.component-C4zwQqzh.mjs → ngx-t-forms-rest-api-call-setup.component-CQeww1qM.mjs} +14 -14
  47. package/fesm2022/{ngx-t-forms-rest-api-call-setup.component-C4zwQqzh.mjs.map → ngx-t-forms-rest-api-call-setup.component-CQeww1qM.mjs.map} +1 -1
  48. package/fesm2022/{ngx-t-forms-section-report.component-B5TrrkeO.mjs → ngx-t-forms-section-report.component-DGwgq4QR.mjs} +10 -10
  49. package/fesm2022/{ngx-t-forms-section-report.component-B5TrrkeO.mjs.map → ngx-t-forms-section-report.component-DGwgq4QR.mjs.map} +1 -1
  50. package/fesm2022/{ngx-t-forms-selection-options-editor.component-ClzCcmlC.mjs → ngx-t-forms-selection-options-editor.component-CqAxZnEp.mjs} +10 -10
  51. package/fesm2022/{ngx-t-forms-selection-options-editor.component-ClzCcmlC.mjs.map → ngx-t-forms-selection-options-editor.component-CqAxZnEp.mjs.map} +1 -1
  52. package/fesm2022/ngx-t-forms-t-workflow-picker.component-Cz6YZMia.mjs +187 -0
  53. package/fesm2022/ngx-t-forms-t-workflow-picker.component-Cz6YZMia.mjs.map +1 -0
  54. package/fesm2022/{ngx-t-forms-validators-config.component-B9kfcaSm.mjs → ngx-t-forms-validators-config.component-CL73KUxw.mjs} +11 -11
  55. package/fesm2022/{ngx-t-forms-validators-config.component-B9kfcaSm.mjs.map → ngx-t-forms-validators-config.component-CL73KUxw.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/input-element-editor/input-element-editor.component.d.ts +6 -2
  59. package/lib/components/forms/forms.component.d.ts +2 -1
  60. package/lib/components/forms/store/Form-actions-formBuilder.d.ts +1 -0
  61. package/lib/components/forms/store/Form-selectors-FormBuilder.d.ts +3 -1
  62. package/lib/components/forms/store/Forms-Effects.d.ts +7 -1
  63. package/lib/components/forms/store/forms-store.service.d.ts +19 -53
  64. package/lib/components/index.d.ts +2 -1
  65. package/lib/components/t-dynamic-data-edit/elements/api-value-access-rules/api-value-access-rules.component.d.ts +40 -20
  66. package/lib/components/t-dynamic-data-edit/elements/calculated-field-rules/calculated-field-rules.component.d.ts +51 -63
  67. package/lib/components/t-dynamic-data-edit/elements/document-list-label-config-editor/document-list-label-config-editor.component.d.ts +8 -1
  68. package/lib/components/t-dynamic-data-edit/elements/json-editor/json-editor.component.d.ts +37 -9
  69. package/lib/components/t-dynamic-data-edit/elements/mat-chip-list-editor/mat-chip-list-editor.component.d.ts +5 -1
  70. package/lib/components/t-dynamic-data-edit/elements/mscoa-segment-config/mscoa-segment-config.component.d.ts +4 -1
  71. package/lib/components/t-dynamic-data-edit/elements/pipeline-generator/pipeline-generator.component.d.ts +2 -0
  72. package/lib/components/t-dynamic-data-edit/elements/record-list-manager/record-list-manager.component.d.ts +75 -0
  73. package/lib/components/t-dynamic-data-edit/elements/t-workflow-picker/t-workflow-picker.component.d.ts +7 -3
  74. package/lib/components/t-dynamic-data-edit/t-dynamic-data-edit.component.d.ts +1 -0
  75. package/lib/components/t-form-input/elements/Geo-location-form-input/geo-location.component.d.ts +1 -1
  76. package/lib/components/t-form-input/elements/auto-complete-input-element/auto-complete-input-element.component.d.ts +1 -1
  77. package/lib/components/t-form-input/elements/basic-input-input-element/basic-input-input-element.component.d.ts +2 -1
  78. package/lib/components/t-form-input/elements/basic-input-input-element/core/input-custom/input-custom.component.d.ts +2 -1
  79. package/lib/components/t-form-input/elements/date-picker-input-element/date-picker-input-element.component.d.ts +1 -1
  80. package/lib/components/t-form-input/elements/date-range-picker-input-element/date-range-picker-input-element.component.d.ts +1 -1
  81. package/lib/components/t-form-input/elements/document-picker/document-picker.component.d.ts +1 -1
  82. package/lib/components/t-form-input/elements/editor-input-element/editor-input-element.component.d.ts +1 -1
  83. package/lib/components/t-form-input/elements/file-upload-input-element/file-upload-input-element.component.d.ts +1 -1
  84. package/lib/components/t-form-input/elements/image-capture-input-element/image-capture-input-element.component.d.ts +1 -1
  85. package/lib/components/t-form-input/elements/mscoa-form-input/elements/account-value/account-value.component.d.ts +8 -0
  86. 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
  87. 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
  88. 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
  89. 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
  90. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/extractCols.d.ts +22 -0
  91. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/mscoa-chart.component.d.ts +299 -86
  92. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.constants.d.ts +47 -0
  93. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.helpers.d.ts +87 -0
  94. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-chart.types.d.ts +51 -0
  95. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-chart/utils/mscoa-message-formatter.d.ts +87 -0
  96. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-computation/mscoa-computation.component.d.ts +149 -22
  97. package/lib/components/t-form-input/elements/mscoa-form-input/elements/mscoa-reactive-form-field/mscoa-reactive-form-field.component.d.ts +11 -0
  98. package/lib/components/t-form-input/elements/mscoa-form-input/elements/scoa-account-table/scoa-account-table.component.d.ts +4 -0
  99. package/lib/components/t-form-input/elements/mscoa-form-input/mscoa-form-input.component.d.ts +1 -1
  100. package/lib/components/t-form-input/elements/mscoa-form-input/store/accountConstants.d.ts +7 -2
  101. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-actions.d.ts +13 -2
  102. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-component-store.service.d.ts +45 -8
  103. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-effects.d.ts +1 -0
  104. package/lib/components/t-form-input/elements/mscoa-form-input/store/mscoa-selectors.d.ts +33 -8
  105. package/lib/components/t-form-input/elements/multiple-input-input-element/multiple-input-input-element.component.d.ts +1 -1
  106. package/lib/components/t-form-input/elements/select-input-element/select-input-element.component.d.ts +1 -1
  107. package/lib/components/t-form-input/elements/signature-input-element/core/signature-pad-input/functions/getSignatureImage.d.ts +3 -0
  108. package/lib/components/t-form-input/elements/signature-input-element/signature-input-element.component.d.ts +1 -1
  109. package/lib/components/t-form-input/elements/textarea-input-element/core/text-area-reactive-input/text-area-reactive-input.component.d.ts +1 -2
  110. package/lib/components/t-form-input/elements/textarea-input-element/textarea-input-element.component.d.ts +1 -1
  111. package/lib/components/t-form-input/elements/toggle-input-element/toggle-input-element.component.d.ts +1 -1
  112. package/lib/components/t-form-input/elements/workflow-adjudication/elements/point-assignment/elements/point-assignment-dialog/point-assignment-dialog.component.d.ts +41 -0
  113. package/lib/components/t-form-input/elements/workflow-adjudication/elements/point-assignment/point-assignment.component.d.ts +40 -28
  114. package/lib/components/t-form-input/elements/workflow-adjudication/elements/submission-review/elements/submission-review-dialog/submission-review-dialog.component.d.ts +27 -0
  115. package/lib/components/t-form-input/elements/workflow-adjudication/elements/submission-review/submission-review.component.d.ts +6 -11
  116. package/lib/components/t-form-input/elements/workflow-adjudication/elements/supplier-selection/supplier-selection.component.d.ts +33 -0
  117. package/lib/components/t-form-input/elements/workflow-adjudication/workflow-adjudication.component.d.ts +1 -1
  118. package/lib/services/core/t-form-builder/functions/deleteSection.d.ts +1 -0
  119. package/lib/services/core/t-form-builder/functions/inputElementEditorConfigs.d.ts +9 -3
  120. package/lib/services/core/t-form-builder/functions/removeItem.d.ts +1 -0
  121. package/lib/services/core/t-form-builder/functions/stepTitleChangeStep.d.ts +1 -0
  122. package/lib/services/core/t-form-controller/function/calculateInputValue.d.ts +1 -1
  123. package/lib/services/core/t-form-controller/function/getInputSourcedValue.d.ts +4 -0
  124. package/lib/services/core/t-form-tower-controller/functions/runMultipleInputPrepopulationFunctions.d.ts +11 -0
  125. package/lib/services/core/t-form-tower-controller/functions/updateFormInputConfig.d.ts +7 -0
  126. package/lib/services/core/t-input-controller/functions/baseCustomInput.d.ts +4 -2
  127. package/lib/services/core/t-input-controller/functions/inputErrorMessage.d.ts +1 -1
  128. package/lib/shared/functions/convertElementEditorTypesToInputType.d.ts +3 -0
  129. package/lib/shared/functions/fuzzyTextSearch.d.ts +4 -0
  130. package/lib/shared/functions/getPipedValueFromDataType.d.ts +2 -0
  131. package/lib/shared/index.d.ts +2 -1
  132. package/package.json +2 -2
  133. package/fesm2022/ngx-t-forms-calculated-field-rules.component-BdDN7YwK.mjs +0 -316
  134. package/fesm2022/ngx-t-forms-calculated-field-rules.component-BdDN7YwK.mjs.map +0 -1
  135. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-Bdfd5ik4.mjs +0 -238
  136. package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-Bdfd5ik4.mjs.map +0 -1
  137. package/fesm2022/ngx-t-forms-form-section-stepper.component-BGu2CX3r.mjs +0 -261
  138. package/fesm2022/ngx-t-forms-form-section-stepper.component-BGu2CX3r.mjs.map +0 -1
  139. package/fesm2022/ngx-t-forms-forms-builder-menu.component-Brj72jZP.mjs.map +0 -1
  140. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DRMTdPwU.mjs +0 -95
  141. package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DRMTdPwU.mjs.map +0 -1
  142. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B0I2X92a.mjs +0 -281
  143. package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B0I2X92a.mjs.map +0 -1
  144. package/fesm2022/ngx-t-forms-ngx-t-forms-BYmto56R.mjs.map +0 -1
  145. package/fesm2022/ngx-t-forms-pipeline-generator.component-T4_0xqeE.mjs +0 -727
  146. package/fesm2022/ngx-t-forms-pipeline-generator.component-T4_0xqeE.mjs.map +0 -1
  147. package/fesm2022/ngx-t-forms-t-workflow-picker.component-C1t8oH9s.mjs +0 -171
  148. package/fesm2022/ngx-t-forms-t-workflow-picker.component-C1t8oH9s.mjs.map +0 -1
@@ -1,727 +0,0 @@
1
- import * as i2 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 { Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
7
- import { Subscription, debounceTime, 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, N as NGX_T_FORMS_CONFIG_TOKEN, b as TDynamicDataViewComponent, D as DaysAgoPipe } from './ngx-t-forms-ngx-t-forms-BYmto56R.mjs';
10
- import * as i5 from '@angular/material/icon';
11
- import * as i1$1 from '@angular/material/autocomplete';
12
- import * as i2$1 from '@angular/material/button';
13
- import * as i3 from '@angular/material/card';
14
- import * as i4 from '@angular/material/divider';
15
- import * as i3$1 from '@angular/material/select';
16
- import * as i8 from '@angular/material/tooltip';
17
- import { TWorkflowPickerComponent } from './ngx-t-forms-t-workflow-picker.component-C1t8oH9s.mjs';
18
- import { MatFormFieldControl } from '@angular/material/form-field';
19
- import { HttpClient } from '@angular/common/http';
20
- import * as i11 from '@angular/cdk/overlay';
21
- import { OverlayModule } from '@angular/cdk/overlay';
22
- import * as i5$1 from '@angular/material/expansion';
23
- import * as i6 from '@angular/material/list';
24
- import * as i7 from '@angular/material/progress-spinner';
25
- import * as i9 from '@angular/material/toolbar';
26
-
27
- class JsonEditorComponent {
28
- constructor(fb) {
29
- this.fb = fb;
30
- this.subscriptions = new Subscription();
31
- this.valueChange = new EventEmitter();
32
- this.jsonText = ''; // Placeholder for the JSON text
33
- this.errorMessage = null;
34
- this.jsonForm = this.fb.group({
35
- jsonText: ['', Validators.required]
36
- });
37
- this.init();
38
- }
39
- ngOnDestroy() {
40
- this.subscriptions.unsubscribe();
41
- }
42
- ngOnChanges(changes) {
43
- if (changes['value'] && changes['value'].currentValue !== this._value) {
44
- this._value = changes['value'].currentValue;
45
- this.parseAndBeautifyJson(this._value, true);
46
- }
47
- }
48
- init() {
49
- this.subscriptions.add(this.jsonForm.get('jsonText').valueChanges
50
- .pipe(debounceTime(1000))
51
- .subscribe(value => {
52
- this.parseAndBeautifyJson(value);
53
- }));
54
- }
55
- parseAndBeautifyJson(value, hardSet) {
56
- try {
57
- // Attempt to parse the JSON
58
- const parsedJson = typeof value === 'object' && value !== null ? value : JSON.parse(value);
59
- // If valid, beautify the JSON
60
- const beautifiedJson = JSON.stringify(parsedJson, null, 4);
61
- // Update form control value with beautified JSON
62
- const form = this.jsonForm.get('jsonText');
63
- if (!form) {
64
- this.errorMessage = 'Form control not found.';
65
- return;
66
- }
67
- // Set beautified JSON without emitting another change event
68
- form.setValue(beautifiedJson, { emitEvent: false });
69
- this.errorMessage = null;
70
- this.valueChange.emit({ value: parsedJson, valid: true });
71
- }
72
- catch (error) {
73
- if (error instanceof SyntaxError) {
74
- // Extract the position of the error from the error message
75
- const errorMessage = this.getDetailedJsonError(value, error.message);
76
- this.errorMessage = `JSON Syntax Error: ${errorMessage}`;
77
- }
78
- else {
79
- this.errorMessage = 'Unexpected error occurred while parsing JSON.';
80
- }
81
- if (hardSet) {
82
- console.log('hardset', value);
83
- this.jsonForm.get('jsonText')?.setValue(value, { emitEvent: false });
84
- }
85
- this.valueChange.emit({ value: value, valid: false });
86
- }
87
- }
88
- // Function to give detailed JSON error information
89
- getDetailedJsonError(value, message) {
90
- const positionMatch = message.match(/position (\d+)/);
91
- if (!!positionMatch?.[1]) {
92
- const position = parseInt(positionMatch[1], 10);
93
- const excerpt = this.getErrorExcerpt(value, position);
94
- return `at position ${position}: near "${excerpt}". Check for missing commas, brackets, or quotes.`;
95
- }
96
- return message;
97
- }
98
- // Helper function to extract a portion of the string around the error position
99
- getErrorExcerpt(value, position, excerptLength = 20) {
100
- const start = Math.max(0, position - excerptLength);
101
- const end = Math.min(value.length, position + excerptLength);
102
- return value.substring(start, end);
103
- }
104
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JsonEditorComponent, deps: [{ token: i1.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
105
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: JsonEditorComponent, isStandalone: true, selector: "app-json-editor", inputs: { value: "value" }, outputs: { valueChange: "valueChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"json-editor-container\">\n <div *ngIf=\"jsonForm.invalid\" \n style=\"margin-top: 16px;\"\n class=\"tree-instructions\">\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\n <span> Paste or type JSON below. The editor will auto-beautify the text.</span>\n </div>\n\n\n \n <!-- Error message if JSON is invalid -->\n <div *ngIf=\"errorMessage\" \n \n style=\"\" class=\"tree-instructions json-error \">\n <span> {{errorMessage}}</span>\n </div>\n \n <form [formGroup]=\"jsonForm\">\n <textarea\n formControlName=\"jsonText\"\n class=\"json-textarea\"\n [class.error-message]=\"errorMessage\"\n rows=\"15\"\n placeholder=\"Enter your JSON here...\"></textarea>\n </form>\n <!-- JSON Textarea -->\n\n</div>\n", styles: [".json-editor-container{max-width:800px;margin:0 auto;border-radius:5px}.json-editor-container h1{font-size:24px;color:#333}.json-editor-container .lead{font-size:.9 rem;margin-bottom:10px;padding-left:16px}.json-editor-container .json-textarea{width:calc(100% - 24px);padding:12px;font-size:14px;color:#333;background-color:#fff;border:1px solid #ccc;border-radius:5px;font-family:Courier New,Courier,monospace}.json-editor-container .json-textarea:focus{outline:none;border-color:var(--ion-color-primary)}.error-message{border:solid 1px #e74c3c!important}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;border-radius:4px;margin-bottom:0;background:azure}.json-error{background:inherit;color:#e74c3c;margin-bottom:4px}.info-icon{width:38px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatModulesModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
106
- }
107
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JsonEditorComponent, decorators: [{
108
- type: Component,
109
- args: [{ selector: 'app-json-editor', standalone: true, imports: [
110
- CommonModule,
111
- MatModulesModule,
112
- FormsModule,
113
- ReactiveFormsModule
114
- ], template: "<div class=\"json-editor-container\">\n <div *ngIf=\"jsonForm.invalid\" \n style=\"margin-top: 16px;\"\n class=\"tree-instructions\">\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\n <span> Paste or type JSON below. The editor will auto-beautify the text.</span>\n </div>\n\n\n \n <!-- Error message if JSON is invalid -->\n <div *ngIf=\"errorMessage\" \n \n style=\"\" class=\"tree-instructions json-error \">\n <span> {{errorMessage}}</span>\n </div>\n \n <form [formGroup]=\"jsonForm\">\n <textarea\n formControlName=\"jsonText\"\n class=\"json-textarea\"\n [class.error-message]=\"errorMessage\"\n rows=\"15\"\n placeholder=\"Enter your JSON here...\"></textarea>\n </form>\n <!-- JSON Textarea -->\n\n</div>\n", styles: [".json-editor-container{max-width:800px;margin:0 auto;border-radius:5px}.json-editor-container h1{font-size:24px;color:#333}.json-editor-container .lead{font-size:.9 rem;margin-bottom:10px;padding-left:16px}.json-editor-container .json-textarea{width:calc(100% - 24px);padding:12px;font-size:14px;color:#333;background-color:#fff;border:1px solid #ccc;border-radius:5px;font-family:Courier New,Courier,monospace}.json-editor-container .json-textarea:focus{outline:none;border-color:var(--ion-color-primary)}.error-message{border:solid 1px #e74c3c!important}.tree-instructions{display:flex;align-items:center;gap:8px;padding:12px;border-radius:4px;margin-bottom:0;background:azure}.json-error{background:inherit;color:#e74c3c;margin-bottom:4px}.info-icon{width:38px}\n"] }]
115
- }], ctorParameters: () => [{ type: i1.FormBuilder }], propDecorators: { value: [{
116
- type: Input
117
- }], valueChange: [{
118
- type: Output
119
- }] } });
120
-
121
- class AggregateStageEditorComponent {
122
- ngOnDestroy() {
123
- this.subscription.unsubscribe();
124
- }
125
- constructor() {
126
- this.subscription = new Subscription();
127
- this.isRunningPipeline = false;
128
- this.saveStage = new EventEmitter();
129
- this.deleteStage = new EventEmitter();
130
- this.activeStage = undefined; // Define the type appropriately if possible
131
- this.allowedStages = [];
132
- }
133
- ngOnInit() {
134
- // Debounce the config change to optimize performance
135
- this.allowedStages = PipelineBuilder.getViewOnlyStages();
136
- }
137
- handleChange(event) {
138
- const selectedStage = event.value;
139
- if (this.activeStage === undefined) {
140
- this.activeStage = {
141
- stage: selectedStage,
142
- ...this.selectedStage || {},
143
- };
144
- }
145
- else {
146
- this.activeStage = {
147
- config: this.activeStage?.config || this.selectedStage?.config,
148
- stage: selectedStage
149
- };
150
- }
151
- { }
152
- if (this.activeStage?.config && !!this.activeStage?.stage) {
153
- this.validateConfig();
154
- }
155
- }
156
- handleConfigChange(event) {
157
- if (!this.activeStage) {
158
- this.activeStage = {
159
- ...this.selectedStage || {},
160
- };
161
- }
162
- this.activeStage = {
163
- stage: this.activeStage?.stage || this.selectedStage?.name,
164
- config: event.value
165
- };
166
- this.validateConfig();
167
- }
168
- validateConfig() {
169
- this.configValidationError = undefined;
170
- const { config, stage } = this.activeStage || {};
171
- // Check if config and stage are defined
172
- if (!config && config !== 0 || !stage) {
173
- console.error('Config or stage is not defined', config, stage);
174
- this.activeStage.valid = false;
175
- return; // Early exit if validation fails
176
- }
177
- try {
178
- const valid = PipelineBuilder.validateStageConfig(stage, config);
179
- this.activeStage.valid = valid;
180
- // Set error message if config is invalid
181
- if (!valid) {
182
- this.configValidationError = undefined;
183
- return;
184
- }
185
- }
186
- catch (error) {
187
- // Catch and handle errors from validation
188
- this.configValidationError = error.message || JSON.stringify(error) || 'An unknown error occurred';
189
- this.activeStage.valid = false;
190
- console.error('Validation Error:', this.configValidationError);
191
- }
192
- }
193
- canSaveConfig() {
194
- return !!this.activeStage && !this.configValidationError;
195
- }
196
- saveConfiguration() {
197
- // Logic for saving the configuration
198
- if (this.canSaveConfig()) {
199
- this.saveStage.emit(this.activeStage);
200
- }
201
- }
202
- trackByStage(index, stage) {
203
- return stage.stage;
204
- }
205
- get allowedStageNames() {
206
- return this.allowedStages.map(stage => stage.stage);
207
- }
208
- get activeDescription() {
209
- return this.allowedStages.find(stage => stage.stage === this.activeStage?.stage)?.description;
210
- }
211
- deleteActive() {
212
- this.deleteStage.emit();
213
- }
214
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AggregateStageEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
215
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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: i1$1.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: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i3$1.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.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: JsonEditorComponent, selector: "app-json-editor", inputs: ["value"], outputs: ["valueChange"] }] }); }
216
- }
217
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AggregateStageEditorComponent, decorators: [{
218
- type: Component,
219
- args: [{ selector: 'app-aggregate-stage-editor', standalone: true, imports: [
220
- MatModulesModule,
221
- CommonModule,
222
- FormsModule,
223
- JsonEditorComponent
224
- ], 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"] }]
225
- }], ctorParameters: () => [], propDecorators: { selectedStage: [{
226
- type: Input
227
- }], isRunningPipeline: [{
228
- type: Input
229
- }], saveStage: [{
230
- type: Output
231
- }], deleteStage: [{
232
- type: Output
233
- }] } });
234
-
235
- class PipelineService {
236
- constructor() {
237
- //LOADING INDICATORS
238
- this.isRunningPipeline = false;
239
- this.aiIsGeneratingPipeline = false;
240
- this.isLoadingAllowedStages = false;
241
- this.isLoadingWorkflowSchema = false;
242
- //States
243
- this.workflowId$ = new BehaviorSubject(undefined);
244
- this.activeStage$ = new BehaviorSubject(undefined);
245
- this.prompt$ = new BehaviorSubject(undefined);
246
- this.schemaLoadError$ = new BehaviorSubject(undefined);
247
- this.pipeline$ = new BehaviorSubject([]);
248
- this.threadId$ = new BehaviorSubject(undefined);
249
- this.schema$ = new BehaviorSubject(undefined);
250
- this.allowedStages$ = new BehaviorSubject([]);
251
- this.pipeLineResult$ = new BehaviorSubject([]);
252
- this.chatHistory$ = new BehaviorSubject([]);
253
- this.http = inject(HttpClient);
254
- //Set local storage threadId
255
- const threadId = localStorage.getItem('threadId');
256
- if (threadId) {
257
- this.threadId$.next(threadId);
258
- }
259
- }
260
- get config$() {
261
- return this.workflowId$.pipe(switchMap(workflowId => this.pipeline$.pipe(switchMap(pipeline => this.pipeLineResult$.pipe(map(responseBody => ({ workflowId, pipeline, responseBody })))))));
262
- }
263
- /**
264
- * Fetch available pipeline stages for the user to select and generate pipelines.
265
- * Ideally, this could be static or fetched from a backend.
266
- */
267
- runPipeLine(pipeline, workflowId) {
268
- const url = "http://localhost:5000/api/v1/pipelineBuilder/runPipeline";
269
- // For now, returning a static list of pipeline stages. In a real application, you can fetch from an API.
270
- this.isRunningPipeline = true;
271
- return this.http.post(url, { pipeline, workflowId }).pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
272
- finalize(() => this.isRunningPipeline = false));
273
- }
274
- /**
275
- * Generate a MongoDB pipeline based on the given user prompt.
276
- *
277
- * @param prompt The user's input or description of the desired pipeline.
278
- */
279
- generatePipeline(query, schema, threadId, existingPipeline, previousError) {
280
- if (!schema) {
281
- throw new Error("Schema is required");
282
- }
283
- const payload = { query, schema, threadId, existingPipeline, previousError };
284
- const url = "http://localhost:5000/api/v1/pipelineBuilder/generatePipeline";
285
- this.aiIsGeneratingPipeline = true;
286
- return this.http.post(`${url}`, payload)
287
- .pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
288
- finalize(() => this.aiIsGeneratingPipeline = false));
289
- }
290
- /**
291
- * Handle any errors from the HTTP request.
292
- *
293
- * @param error The error response from the HTTP request
294
- */
295
- handleError(error) {
296
- console.error('An error occurred', error);
297
- // Return an observable with a user-facing error message
298
- return throwError(() => new Error('Something went wrong with the pipeline generation; please try again later.'));
299
- }
300
- getSchema(workflowId) {
301
- if (!workflowId) {
302
- throw new Error("WorkflowId is required");
303
- }
304
- const url = "http://localhost:5000/api/v1/pipelineBuilder/getSchema";
305
- return this.http.get(`${url}`, { params: { workflowId: workflowId } }).pipe(take(1), catchError(this.handleError) // Error handling for the HTTP request
306
- );
307
- }
308
- /** OPERATIONS */
309
- isSchemaEmpty(object) {
310
- }
311
- workflowChanged(event) {
312
- this.workflowId$.next(event);
313
- if (!event) {
314
- return;
315
- }
316
- this.getSchema(event).pipe(take(1), tap(({ schema }) => {
317
- this.schema$.next(schema);
318
- const isEmptySchema = Object.keys(schema)[0] === "" && Object.values(schema)[0] === "Array<>";
319
- const error = isEmptySchema
320
- ? "Document schema is missing. Please ensure at least one document exists for the selected workflow."
321
- : undefined;
322
- this.schemaLoadError$.next(error);
323
- console.log("Workflow schema loaded,run pipeline");
324
- this.runActivePipeline();
325
- }), catchError((error) => {
326
- this.schemaLoadError$.next("Error loading schema");
327
- return this.handleError(error);
328
- })).subscribe();
329
- }
330
- setActiveStage(i) {
331
- const index = this.activeStage$.getValue();
332
- if (index === i) {
333
- this.activeStage$.next(undefined);
334
- return;
335
- }
336
- this.activeStage$.next(i);
337
- }
338
- addStage() {
339
- const newPipeline = this.pipeline$.getValue().concat({});
340
- this.pipeline$.next(newPipeline);
341
- }
342
- onTextChange(event) {
343
- this.prompt$.next(event);
344
- console.log(event);
345
- }
346
- promptSubmit() {
347
- // Use combineLatest to fetch the latest values from multiple sources
348
- combineLatest([this.schema$, this.threadId$, this.pipeline$, this.prompt$, this.chatHistory$])
349
- .pipe(take(1), tap(([schema, threadId, pipeline, prompt, history]) => {
350
- if (!schema || !prompt) {
351
- console.warn(`Missing values: schema ${schema} prompt ${prompt}`);
352
- }
353
- }), filter(([schema, , , prompt]) => !!schema && !!prompt), switchMap(([schema, threadId, pipeline, prompt, history]) => {
354
- // Use a shallow copy of the pipeline
355
- const previousError = history[history.length - 1]?.assistance?.error;
356
- const pipelineCopy = pipeline.map(stage => JSON.parse(JSON.stringify(stage))) || [];
357
- console.info('Generating pipeline with prompt:', prompt, 'schema:', schema, 'threadId:', threadId, 'pipeline:', pipeline);
358
- return this.generatePipeline(prompt, schema, threadId, pipelineCopy, previousError).pipe(map((response) => ({ ...response, history, prompt })));
359
- }), tap((response) => {
360
- const { pipeline, threadId, history, prompt } = response;
361
- const historyRecord = {
362
- user: prompt,
363
- assistance: response,
364
- date: new Date()
365
- };
366
- // Use next with a concatenated value for chat history
367
- this.chatHistory$.next([...(history || []), historyRecord]);
368
- this.pipeline$.next(pipeline);
369
- this.threadId$.next(threadId);
370
- // Store threadID locally
371
- localStorage.setItem('threadId', threadId);
372
- // Run the active pipeline after all state updates are complete
373
- console.log("prompt submitted run pipeline");
374
- this.runActivePipeline();
375
- }), catchError((error) => {
376
- console.error('Error response:', error.message || error);
377
- return this.handleError(error);
378
- })).subscribe();
379
- }
380
- runActivePipeline() {
381
- const pipeline = [...(this.pipeline$.getValue().map(stage => (JSON.parse(JSON.stringify(stage)))) || [])];
382
- const someAreNotValid = pipeline.some(stage => Object.keys(stage).length === 0);
383
- if (pipeline.length === 0 || someAreNotValid) {
384
- return;
385
- }
386
- try {
387
- PipelineBuilder.validatePipeline(pipeline);
388
- }
389
- catch (error) {
390
- console.error(error, pipeline);
391
- return;
392
- }
393
- const workflowId = this.workflowId$.getValue();
394
- if (!workflowId) {
395
- return;
396
- }
397
- this.runPipeLine(pipeline, workflowId).pipe(take(1), tap(({ results }) => {
398
- this.pipeLineResult$.next(results);
399
- }), catchError((error) => {
400
- console.error('Error response:', error);
401
- const err = JSON.parse(JSON.stringify(error));
402
- const errorMessage = err.error;
403
- if (errorMessage) {
404
- this.pipelineErrorLogAndRetry(errorMessage);
405
- }
406
- return this.handleError(error);
407
- })).subscribe();
408
- }
409
- pipelineErrorLogAndRetry(message) {
410
- const history = this.chatHistory$.getValue();
411
- const prompt = this.prompt$.getValue();
412
- const historyRecord = {
413
- user: prompt,
414
- assistance: {
415
- message
416
- },
417
- date: new Date()
418
- };
419
- this.chatHistory$.next([...(history || []), historyRecord]);
420
- }
421
- get activeStage() {
422
- return this.pipeline$.asObservable().pipe(switchMap(pipeline => this.activeStage$.pipe(map(activeIndex => activeIndex === undefined ? undefined : {
423
- name: Object.keys(pipeline[activeIndex] || {})[0] || '',
424
- config: pipeline[activeIndex][Object.keys(pipeline[activeIndex] || {})?.[0] || '']
425
- }))));
426
- }
427
- saveStage(index, stage) {
428
- const pipeline = this.pipeline$.getValue();
429
- if (index === undefined) {
430
- return;
431
- }
432
- const newPipeline = pipeline.map((s, i) => {
433
- if (i === index) {
434
- return stage ? {
435
- [stage.stage]: stage.config
436
- } : s;
437
- }
438
- return s;
439
- });
440
- console.log("newPipeline", newPipeline);
441
- this.pipeline$.next(newPipeline);
442
- this.activeStage$.next(undefined);
443
- console.log("stage saved run pipeline");
444
- this.runActivePipeline();
445
- }
446
- deleteStage(index) {
447
- const pipeline = this.pipeline$.getValue();
448
- if (index === undefined) {
449
- return;
450
- }
451
- const newPipeline = pipeline.filter((s, i) => i !== index);
452
- console.log("newPipeline", newPipeline);
453
- this.pipeline$.next(newPipeline);
454
- this.activeStage$.next(undefined);
455
- console.log("stage deleted run pipeline");
456
- this.runActivePipeline();
457
- }
458
- get pipelineGeneralValid() {
459
- return this.pipeline$.asObservable().pipe(map(pipeline => {
460
- const allHaveTypes = pipeline.every(stage => Object.keys(stage).length === 1);
461
- if (!allHaveTypes) {
462
- return {
463
- valid: false,
464
- message: "All stages must be a valid pipeline stage"
465
- };
466
- }
467
- const AllStagesMustHaveConfig = pipeline.every((stage) => stage[Object.keys(stage)?.[0] || ''] !== undefined);
468
- if (!AllStagesMustHaveConfig) {
469
- return {
470
- valid: false,
471
- message: "All stages must have a configuration"
472
- };
473
- }
474
- return {
475
- valid: true
476
- };
477
- }));
478
- }
479
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PipelineService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
480
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PipelineService, providedIn: 'root' }); }
481
- }
482
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PipelineService, decorators: [{
483
- type: Injectable,
484
- args: [{
485
- providedIn: 'root'
486
- }]
487
- }], ctorParameters: () => [] });
488
-
489
- class PipelineGeneratorComponent {
490
- static { this.nextId = 0; }
491
- constructor(ngControl, _elementRef) {
492
- this.ngControl = ngControl;
493
- this._elementRef = _elementRef;
494
- this.stateChanges = new Subject();
495
- this.NGX_T_FORMS_CONFIG = inject(NGX_T_FORMS_CONFIG_TOKEN);
496
- this.id = `app-pipeline-generator-${PipelineGeneratorComponent.nextId++}`;
497
- this.placeholder = '';
498
- this.focused = false;
499
- this.required = false;
500
- this.disabled = false;
501
- this.touched = false;
502
- this.onTouched = () => { };
503
- this.valueChanged = new EventEmitter();
504
- this.errors = [];
505
- this.destroy$ = new Subject();
506
- this.pipeline = new PipelineService();
507
- this.initiated = false;
508
- this.initiateSubscription = () => {
509
- this.pipeline.config$.pipe(takeUntil(this.destroy$), distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr))).subscribe(config => {
510
- if (!this.initiated) {
511
- this.initiated = true;
512
- return;
513
- }
514
- const newConfig = {
515
- ...this._value,
516
- ...config,
517
- "source": "mongoPipeline",
518
- };
519
- console.log('Pipeline config changed', newConfig);
520
- this.valueChanged.emit(newConfig);
521
- });
522
- };
523
- this.cursorPosition = 0;
524
- this.showSuggestions = false;
525
- this.optionsSearch = '';
526
- this.trackById = (index, stage) => index;
527
- }
528
- get empty() {
529
- return !this.value;
530
- }
531
- get shouldLabelFloat() {
532
- return this.focused || !this.empty;
533
- }
534
- get errorState() {
535
- const hasError = !!this.ngControl?.control?.errors || (this.errors || []).length > 0 && this.touched;
536
- return !this.value && !!this.required || hasError;
537
- }
538
- setDescribedByIds(ids) {
539
- // Ensure the component view is initialized
540
- if (this._elementRef && this._elementRef.nativeElement) {
541
- const controlElement = this._elementRef.nativeElement.querySelector('.app-pipeline-generator');
542
- // Check if the controlElement exists before attempting to set its attribute
543
- if (controlElement) {
544
- controlElement.setAttribute('aria-describedby', ids.join(' '));
545
- }
546
- }
547
- }
548
- onContainerClick(event) {
549
- this.markAsTouched();
550
- this.stateChanges.next();
551
- }
552
- markAsTouched() {
553
- console.log('markAsTouched');
554
- if (!this.touched) {
555
- this.onTouched();
556
- this.touched = true;
557
- }
558
- }
559
- set value(value) {
560
- const workflowIdChanged = this._value?.workflowId !== value?.workflowId;
561
- const pipelineLengthChanged = this._value?.pipeline?.length !== value?.pipeline?.length;
562
- const pipeLineContentChanged = JSON.stringify(this._value?.pipeline) !== JSON.stringify(value?.pipeline);
563
- if (workflowIdChanged || pipelineLengthChanged || pipeLineContentChanged) {
564
- this._value = value;
565
- if (value?.workflowId) {
566
- this.workflowChanged(value?.workflowId);
567
- }
568
- console.log('Pipeline value changed', value, this.pipeline.pipeline$.value);
569
- if (value?.pipeline) {
570
- this.pipeline.pipeline$.next(value?.pipeline || []);
571
- }
572
- }
573
- }
574
- set getWorkflowOptions(options$) {
575
- this.workflows$ = options$;
576
- }
577
- ngOnInit() {
578
- this.initiateSubscription();
579
- }
580
- ngOnDestroy() {
581
- this.destroy$.next();
582
- this.destroy$.complete();
583
- }
584
- workflowChanged(event) {
585
- this.pipeline.workflowChanged(event);
586
- }
587
- get workflowId() {
588
- return this.pipeline.workflowId$.asObservable();
589
- }
590
- get stages() {
591
- return this.pipeline.pipeline$.asObservable().pipe(map(stages => stages.map(stage => ({
592
- name: Object.keys(stage)[0],
593
- stage: Object.keys(stage)[0],
594
- config: stage[Object.keys(stage)?.[0] || ''],
595
- valid: !!Object.keys(stage)[0] && !!stage[Object.keys(stage)?.[0] || '']
596
- }))));
597
- }
598
- get pipeLineResults() {
599
- return this.pipeline.pipeLineResult$.asObservable();
600
- }
601
- get prompt() {
602
- return this.pipeline.prompt$.asObservable();
603
- }
604
- get aiIsGeneratingPipeline() {
605
- return this.pipeline.aiIsGeneratingPipeline;
606
- }
607
- get activeStageIndex() {
608
- return this.pipeline.activeStage$.asObservable();
609
- }
610
- get activeStage() {
611
- console.log(this.pipeline.activeStage);
612
- return this.pipeline.activeStage;
613
- }
614
- get isRunningPipeline() {
615
- return this.pipeline.isRunningPipeline;
616
- }
617
- get cannotAddStage() {
618
- return this.pipeline.pipelineGeneralValid.pipe(map(valid => !valid));
619
- }
620
- get schemaLoadError$() {
621
- return this.pipeline.schemaLoadError$.asObservable();
622
- }
623
- get chatHistory() {
624
- return this.pipeline.chatHistory$.asObservable();
625
- }
626
- onTextChange(event) {
627
- if (!this.textareaElementRef?.nativeElement) {
628
- return;
629
- }
630
- console.log('onTextChange', event);
631
- const newValue = event.target.value;
632
- const textarea = this.textareaElementRef.nativeElement;
633
- this.cursorPosition = textarea.selectionStart || 0;
634
- const lastChar = newValue[this.cursorPosition - 1];
635
- const match = newValue.slice(0, this.cursorPosition).match(/\$(\w*)$/);
636
- if (lastChar === '$' || (match && match[1] !== undefined)) {
637
- this.showSuggestions = true;
638
- this.optionsSearch = match ? match?.[1] || '' : '';
639
- }
640
- else {
641
- this.showSuggestions = false;
642
- this.optionsSearch = '';
643
- }
644
- this.pipeline.onTextChange(newValue);
645
- }
646
- selectSuggestionInput(suggestion) {
647
- this.pipeline.prompt$.asObservable().pipe(take(1), tap(prompt => {
648
- const match = prompt?.slice(0, this.cursorPosition).match(/\$(\w*)$/);
649
- const beforeCursor = prompt?.slice(0, match ? match.index : this.cursorPosition - 1);
650
- const afterCursor = prompt?.slice(this.cursorPosition);
651
- prompt = beforeCursor + suggestion + ' ' + afterCursor;
652
- this.pipeline.prompt$.next(prompt);
653
- this.applyNewValueToPrompt(suggestion);
654
- })).subscribe();
655
- }
656
- applyNewValueToPrompt(suggestion) {
657
- this.showSuggestions = false;
658
- const textarea = this.textareaElementRef.nativeElement;
659
- textarea.focus();
660
- const newCursorPosition = this.cursorPosition + suggestion.length;
661
- setTimeout(() => {
662
- textarea.setSelectionRange(newCursorPosition, newCursorPosition);
663
- }, 0);
664
- }
665
- onSearchChange(event) {
666
- this.optionsSearch = event.detail.value;
667
- }
668
- promptSubmit() {
669
- this.pipeline.promptSubmit();
670
- console.log('promptSubmit');
671
- }
672
- setActiveStage(index) {
673
- this.pipeline.setActiveStage(index);
674
- }
675
- addStage() {
676
- this.pipeline.addStage();
677
- }
678
- get getSchemaProperties() {
679
- 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)));
680
- }
681
- deleteStage(index) {
682
- this.pipeline.deleteStage(index);
683
- }
684
- saveStage(index, stage) {
685
- this.pipeline.saveStage(index, stage);
686
- this.setActiveStage(undefined);
687
- }
688
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PipelineGeneratorComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
689
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", 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: "\n\n\n<section class=\"ion-margin\">\n <p>MongoDB aggregation pipeline builder for selected workflows. </p>\n</section>\n<lib-t-workflow-picker \n(valueChanged)=\"workflowChanged($event)\" \n[getWorkflowOptions]=\" workflows$\"\n [value]=\"(workflowId|async)||undefined\">\n</lib-t-workflow-picker>\n<mat-accordion multi *ngIf=\"workflowId|async\">\n <!-- Pipeline Accordion -->\n <mat-expansion-panel value=\"pipeline\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">\n dynamic_form\n </mat-icon>\n {{isRunningPipeline?'Executing current Data pipeline...':'Data retrieval pipeline'}}\n </mat-panel-title>\n\n </mat-expansion-panel-header>\n <div class=\"content\">\n <!-- Mongodb aggregate pipelione stages management and edit start-->\n <div *ngIf=\"((stages | async)?.length || 0) ===0\" class=\"tree-instructions\">\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\n <span>\n Add stages to the pipeline below.<br>\n Each stage processes input documents by filtering, grouping, or calculating values. The output documents from\n one stage are passed to the next stage in the pipeline.\n </span>\n </div>\n\n <mat-nav-list style=\" background: var(--mat-tree-container-background-color);padding:0px;border-radius:8px\">\n\n\n <ng-container *ngFor=\"let stage of stages | async; trackBy: trackById;index as $index;last as isLast\">\n <mat-list-item [style.margin-top]=\"(activeStageIndex|async) ===$index?'4px':'0px'\"\n [class.mat-elevation-z8]=\"(activeStageIndex|async) ===$index\" class=\"stage-item\"\n (click)=\"setActiveStage($index)\" [activated]=\" (activeStageIndex|async) ===$index\">\n <span class=\"stage-index\" matListItemAvatar>{{$index + 1}} </span>\n <div matListItemTitle>\n <div style=\"line-height: normal;\">\n {{ stage.name || 'Stage ' }}\n </div>\n <div class=\"stage-inner-message\" *ngIf=\"!stage.name && (activeStageIndex|async) !==$index \">\n Incomplete , click to edit\n </div>\n\n </div>\n\n <button *ngIf=\"(activeStageIndex|async) ===$index||!stage.valid && (activeStageIndex|async) !==$index\"\n mat-icon-button matListItemMeta>\n <mat-icon color=\"primary\" *ngIf=\"(activeStageIndex|async) ===$index\">check_circle</mat-icon>\n\n <mat-icon color=\"warn\" *ngIf=\"!stage.valid && (activeStageIndex|async) !==$index\">\n warning\n </mat-icon>\n </button>\n </mat-list-item>\n <mat-divider></mat-divider>\n\n <app-aggregate-stage-editor [selectedStage]=\"stage\" [isRunningPipeline]=\"isRunningPipeline\"\n (deleteStage)=\"deleteStage($index)\" (saveStage)=\"saveStage($index,$event)\"\n *ngIf=\"(activeStageIndex|async) ===$index\"></app-aggregate-stage-editor>\n\n\n </ng-container>\n\n <mat-toolbar style=\"padding: 0px;\">\n\n <span class=\"spacer\"></span>\n <button class=\"stage-button\" [disabled]=\"isRunningPipeline\" color=\"primary\" (click)=\"addStage()\"\n mat-raised-button>\n Add\n <mat-icon>add</mat-icon>\n </button>\n </mat-toolbar>\n </mat-nav-list>\n\n <!-- Mongodb aggregate pipelione stages management and edit end -->\n </div>\n </mat-expansion-panel>\n\n <!-- Results Accordion -->\n <mat-expansion-panel value=\"results\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">dataset</mat-icon>\n {{isRunningPipeline?'Running pipeline...':'Data Results'}}\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"content\">\n <ng-container *ngIf=\"pipeLineResults | async as results; else noResults\">\n\n <lib-t-dynamic-data-view *ngIf=\"results\" [data]=\"results\"></lib-t-dynamic-data-view>\n <p *ngIf=\"!results\" color=\"medium\">\n\n No results available\n\n </p>\n\n </ng-container>\n <ng-template #noResults>\n <p color=\"medium\">No results available</p>\n </ng-template>\n </div>\n </mat-expansion-panel>\n\n <!-- AI Agent Accordion -->\n <mat-expansion-panel value=\"ai\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner *ngIf=\" aiIsGeneratingPipeline \" style=\"position: absolute;\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">tips_and_updates</mat-icon>\n {{ aiIsGeneratingPipeline ? 'Agent busy ...' : 'AI AGENT prompt' }}\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <div class=\"content\">\n @if( schemaLoadError$ | async){\n <div class=\"tree-instructions\" style=\"background: antiquewhite !important;\">\n <mat-icon class=\"info-icon\" color=\"warn\">error</mat-icon>\n <span> {{ schemaLoadError$ | async }}</span>\n </div>\n \n }\n <mat-list *ngFor=\"let chat of chatHistory|async;\">\n\n <mat-list-item class=\"chatContent chatItem\">\n <div class=\"chat\" style=\"background:bisque;text-align:end;\n border-radius: 18px 18px 0px 18px;\" matListItemTitle>\n <div>\n {{chat.user}}\n </div>\n <div style=\"opacity:0.6;line-height: normal;display: flex;align-items: center;justify-content: flex-end;\">\n {{chat.date|daysAgo}}\n <mat-icon class=\"sent-icon\">\n done_all\n </mat-icon>\n </div>\n </div>\n </mat-list-item>\n\n <mat-list-item style=\"margin-top: 16px;\" class=\"chatContent chatItem\" color=\"light\" lines=\"full\">\n <mat-icon style=\" margin-left: 0px;\n margin-top: 16px;\n margin-bottom: auto;\" matListItemIcon>smart_toy</mat-icon>\n <div class=\"chat\" style=\"text-align: left; \n padding-left: 16px; \n background: azure;\n border-radius: 0px 18px 18px 18px;\" *ngIf=\"!chat.assistance?.error\" matListItemTitle>\n <pre>\n {{chat. assistance.pipeline |json}}\n </pre>\n </div>\n <div *ngIf=\"chat.assistance?.error\" matListItemTitle>\n {{chat.assistance.error}}\n </div>\n </mat-list-item>\n\n\n </mat-list>\n <mat-list>\n <mat-list-item class=\"chatContent chatItem\">\n <textarea matListItemTitle #textarea style=\" width: calc(100% - 13px);\n border-radius: 14px;\n padding-right: 3px;\n padding-left: 8px;\" class=\"chat\" [value]=\" prompt|async\" (input)=\"onTextChange($event)\"\n placeholder=\"Provide a pipeline generation prompt\"></textarea>\n <button matListItemMeta style=\" margin-left: 4px;\n margin-right: 0px;\" color=\"primary\" mat-mini-fab [disabled]=\"aiIsGeneratingPipeline\" (click)=\"promptSubmit()\">\n\n <mat-icon style=\"margin: 0px !important;color:white\">send</mat-icon>\n <mat-spinner color=\"accent\" *ngIf=\" aiIsGeneratingPipeline \" \n class=\"submit-spinner\" ></mat-spinner>\n </button>\n \n </mat-list-item>\n\n </mat-list>\n\n\n <section *ngIf=\"showSuggestions\" class=\"showSuggestionContainer\">\n <!-- <mat-toolbar class=\"search-container\" style=\"background: inherit;\">\n\n\n <input type=\"search\" placeholder=\"Search options\" class=\"search-field\" (change)=\"onSearchChange($event)\">\n\n <mat-icon>\n search\n </mat-icon>\n </mat-toolbar> -->\n <mat-divider></mat-divider>\n <div style=\"padding: 8px;\">\n <div class=\"suggestion-container\">\n <div class=\"suggestion-column\">\n <h5>Collection document properties</h5>\n <div class=\"button-container\">\n <button *ngFor=\"let method of getSchemaProperties | async;trackBy: trackById\"\n (click)=\"selectSuggestionInput(method.value)\" color=\"accent\" mat-flat-button\n class=\"suggestion-button\">\n {{ method.label | titlecase }}\n </button>\n </div>\n </div>\n\n </div>\n\n\n </div>\n </section>\n\n\n\n\n\n\n\n </div>\n </mat-expansion-panel>\n</mat-accordion>\n\n\n\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOpen]=\"disabled\"\n>\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5);\">\n\n\n</div>\n</ng-template>\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:14px;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:14px;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:14px;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.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2.JsonPipe, name: "json" }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }, { kind: "component", type: TWorkflowPickerComponent, selector: "lib-t-workflow-picker", inputs: ["disabled", "errors", "required", "value", "placeholder", "getWorkflowOptions"], outputs: ["valueChange", "valueChanged"] }, { 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$1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i5$1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i5$1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i5$1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i6.MatNavList, selector: "mat-nav-list", exportAs: ["matNavList"] }, { kind: "component", type: i6.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i6.MatListItemAvatar, selector: "[matListItemAvatar]" }, { kind: "directive", type: i6.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i6.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "directive", type: i6.MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "component", type: i7.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i11.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 }] }); }
690
- }
691
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: PipelineGeneratorComponent, decorators: [{
692
- type: Component,
693
- args: [{ selector: 'app-pipeline-generator', standalone: true, imports: [
694
- CommonModule,
695
- TWorkflowPickerComponent,
696
- FormsModule,
697
- TDynamicDataViewComponent,
698
- MatModulesModule,
699
- AggregateStageEditorComponent,
700
- DaysAgoPipe,
701
- OverlayModule
702
- ], providers: [{ provide: MatFormFieldControl, useExisting: PipelineGeneratorComponent }], template: "\n\n\n<section class=\"ion-margin\">\n <p>MongoDB aggregation pipeline builder for selected workflows. </p>\n</section>\n<lib-t-workflow-picker \n(valueChanged)=\"workflowChanged($event)\" \n[getWorkflowOptions]=\" workflows$\"\n [value]=\"(workflowId|async)||undefined\">\n</lib-t-workflow-picker>\n<mat-accordion multi *ngIf=\"workflowId|async\">\n <!-- Pipeline Accordion -->\n <mat-expansion-panel value=\"pipeline\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">\n dynamic_form\n </mat-icon>\n {{isRunningPipeline?'Executing current Data pipeline...':'Data retrieval pipeline'}}\n </mat-panel-title>\n\n </mat-expansion-panel-header>\n <div class=\"content\">\n <!-- Mongodb aggregate pipelione stages management and edit start-->\n <div *ngIf=\"((stages | async)?.length || 0) ===0\" class=\"tree-instructions\">\n <mat-icon class=\"info-icon\" color=\"primary\">info</mat-icon>\n <span>\n Add stages to the pipeline below.<br>\n Each stage processes input documents by filtering, grouping, or calculating values. The output documents from\n one stage are passed to the next stage in the pipeline.\n </span>\n </div>\n\n <mat-nav-list style=\" background: var(--mat-tree-container-background-color);padding:0px;border-radius:8px\">\n\n\n <ng-container *ngFor=\"let stage of stages | async; trackBy: trackById;index as $index;last as isLast\">\n <mat-list-item [style.margin-top]=\"(activeStageIndex|async) ===$index?'4px':'0px'\"\n [class.mat-elevation-z8]=\"(activeStageIndex|async) ===$index\" class=\"stage-item\"\n (click)=\"setActiveStage($index)\" [activated]=\" (activeStageIndex|async) ===$index\">\n <span class=\"stage-index\" matListItemAvatar>{{$index + 1}} </span>\n <div matListItemTitle>\n <div style=\"line-height: normal;\">\n {{ stage.name || 'Stage ' }}\n </div>\n <div class=\"stage-inner-message\" *ngIf=\"!stage.name && (activeStageIndex|async) !==$index \">\n Incomplete , click to edit\n </div>\n\n </div>\n\n <button *ngIf=\"(activeStageIndex|async) ===$index||!stage.valid && (activeStageIndex|async) !==$index\"\n mat-icon-button matListItemMeta>\n <mat-icon color=\"primary\" *ngIf=\"(activeStageIndex|async) ===$index\">check_circle</mat-icon>\n\n <mat-icon color=\"warn\" *ngIf=\"!stage.valid && (activeStageIndex|async) !==$index\">\n warning\n </mat-icon>\n </button>\n </mat-list-item>\n <mat-divider></mat-divider>\n\n <app-aggregate-stage-editor [selectedStage]=\"stage\" [isRunningPipeline]=\"isRunningPipeline\"\n (deleteStage)=\"deleteStage($index)\" (saveStage)=\"saveStage($index,$event)\"\n *ngIf=\"(activeStageIndex|async) ===$index\"></app-aggregate-stage-editor>\n\n\n </ng-container>\n\n <mat-toolbar style=\"padding: 0px;\">\n\n <span class=\"spacer\"></span>\n <button class=\"stage-button\" [disabled]=\"isRunningPipeline\" color=\"primary\" (click)=\"addStage()\"\n mat-raised-button>\n Add\n <mat-icon>add</mat-icon>\n </button>\n </mat-toolbar>\n </mat-nav-list>\n\n <!-- Mongodb aggregate pipelione stages management and edit end -->\n </div>\n </mat-expansion-panel>\n\n <!-- Results Accordion -->\n <mat-expansion-panel value=\"results\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner color=\"accent\" *ngIf=\"isRunningPipeline\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">dataset</mat-icon>\n {{isRunningPipeline?'Running pipeline...':'Data Results'}}\n </mat-panel-title>\n </mat-expansion-panel-header>\n <div class=\"content\">\n <ng-container *ngIf=\"pipeLineResults | async as results; else noResults\">\n\n <lib-t-dynamic-data-view *ngIf=\"results\" [data]=\"results\"></lib-t-dynamic-data-view>\n <p *ngIf=\"!results\" color=\"medium\">\n\n No results available\n\n </p>\n\n </ng-container>\n <ng-template #noResults>\n <p color=\"medium\">No results available</p>\n </ng-template>\n </div>\n </mat-expansion-panel>\n\n <!-- AI Agent Accordion -->\n <mat-expansion-panel value=\"ai\">\n <mat-expansion-panel-header>\n <mat-panel-title>\n <mat-spinner *ngIf=\" aiIsGeneratingPipeline \" style=\"position: absolute;\" class=\"header-spinner\"></mat-spinner>\n <mat-icon class=\"title-icon\">tips_and_updates</mat-icon>\n {{ aiIsGeneratingPipeline ? 'Agent busy ...' : 'AI AGENT prompt' }}\n </mat-panel-title>\n </mat-expansion-panel-header>\n\n <div class=\"content\">\n @if( schemaLoadError$ | async){\n <div class=\"tree-instructions\" style=\"background: antiquewhite !important;\">\n <mat-icon class=\"info-icon\" color=\"warn\">error</mat-icon>\n <span> {{ schemaLoadError$ | async }}</span>\n </div>\n \n }\n <mat-list *ngFor=\"let chat of chatHistory|async;\">\n\n <mat-list-item class=\"chatContent chatItem\">\n <div class=\"chat\" style=\"background:bisque;text-align:end;\n border-radius: 18px 18px 0px 18px;\" matListItemTitle>\n <div>\n {{chat.user}}\n </div>\n <div style=\"opacity:0.6;line-height: normal;display: flex;align-items: center;justify-content: flex-end;\">\n {{chat.date|daysAgo}}\n <mat-icon class=\"sent-icon\">\n done_all\n </mat-icon>\n </div>\n </div>\n </mat-list-item>\n\n <mat-list-item style=\"margin-top: 16px;\" class=\"chatContent chatItem\" color=\"light\" lines=\"full\">\n <mat-icon style=\" margin-left: 0px;\n margin-top: 16px;\n margin-bottom: auto;\" matListItemIcon>smart_toy</mat-icon>\n <div class=\"chat\" style=\"text-align: left; \n padding-left: 16px; \n background: azure;\n border-radius: 0px 18px 18px 18px;\" *ngIf=\"!chat.assistance?.error\" matListItemTitle>\n <pre>\n {{chat. assistance.pipeline |json}}\n </pre>\n </div>\n <div *ngIf=\"chat.assistance?.error\" matListItemTitle>\n {{chat.assistance.error}}\n </div>\n </mat-list-item>\n\n\n </mat-list>\n <mat-list>\n <mat-list-item class=\"chatContent chatItem\">\n <textarea matListItemTitle #textarea style=\" width: calc(100% - 13px);\n border-radius: 14px;\n padding-right: 3px;\n padding-left: 8px;\" class=\"chat\" [value]=\" prompt|async\" (input)=\"onTextChange($event)\"\n placeholder=\"Provide a pipeline generation prompt\"></textarea>\n <button matListItemMeta style=\" margin-left: 4px;\n margin-right: 0px;\" color=\"primary\" mat-mini-fab [disabled]=\"aiIsGeneratingPipeline\" (click)=\"promptSubmit()\">\n\n <mat-icon style=\"margin: 0px !important;color:white\">send</mat-icon>\n <mat-spinner color=\"accent\" *ngIf=\" aiIsGeneratingPipeline \" \n class=\"submit-spinner\" ></mat-spinner>\n </button>\n \n </mat-list-item>\n\n </mat-list>\n\n\n <section *ngIf=\"showSuggestions\" class=\"showSuggestionContainer\">\n <!-- <mat-toolbar class=\"search-container\" style=\"background: inherit;\">\n\n\n <input type=\"search\" placeholder=\"Search options\" class=\"search-field\" (change)=\"onSearchChange($event)\">\n\n <mat-icon>\n search\n </mat-icon>\n </mat-toolbar> -->\n <mat-divider></mat-divider>\n <div style=\"padding: 8px;\">\n <div class=\"suggestion-container\">\n <div class=\"suggestion-column\">\n <h5>Collection document properties</h5>\n <div class=\"button-container\">\n <button *ngFor=\"let method of getSchemaProperties | async;trackBy: trackById\"\n (click)=\"selectSuggestionInput(method.value)\" color=\"accent\" mat-flat-button\n class=\"suggestion-button\">\n {{ method.label | titlecase }}\n </button>\n </div>\n </div>\n\n </div>\n\n\n </div>\n </section>\n\n\n\n\n\n\n\n </div>\n </mat-expansion-panel>\n</mat-accordion>\n\n\n\n\n<ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOpen]=\"disabled\"\n>\n<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5);\">\n\n\n</div>\n</ng-template>\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:14px;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:14px;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:14px;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"] }]
703
- }], ctorParameters: () => [{ type: i1.NgControl, decorators: [{
704
- type: Optional
705
- }, {
706
- type: Self
707
- }] }, { type: i0.ElementRef }], propDecorators: { id: [{
708
- type: HostBinding
709
- }], disabled: [{
710
- type: Input
711
- }], textareaElementRef: [{
712
- type: ViewChild,
713
- args: ['textarea', { read: ElementRef, static: false }]
714
- }], value: [{
715
- type: Input
716
- }], getWorkflowOptions: [{
717
- type: Input
718
- }], userName: [{
719
- type: Input
720
- }], valueChanged: [{
721
- type: Output
722
- }], errors: [{
723
- type: Input
724
- }] } });
725
-
726
- export { PipelineGeneratorComponent };
727
- //# sourceMappingURL=ngx-t-forms-pipeline-generator.component-T4_0xqeE.mjs.map