ngx-t-forms 2.0.29 → 2.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-t-forms-auto-complete-input-element.component-DCKuXHAW.mjs +104 -0
- package/fesm2022/ngx-t-forms-auto-complete-input-element.component-DCKuXHAW.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-basic-input-input-element.component-Ce4ipSUc.mjs +85 -0
- package/fesm2022/ngx-t-forms-basic-input-input-element.component-Ce4ipSUc.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-C5TPddVe.mjs +643 -0
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-C5TPddVe.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-CICQaqz6.mjs +97 -0
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-CICQaqz6.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-CzisLSIP.mjs +195 -0
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-CzisLSIP.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-data-source-picker.component-Dzz_o6fJ.mjs +261 -0
- package/fesm2022/ngx-t-forms-data-source-picker.component-Dzz_o6fJ.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-date-picker-input-element.component-CYUbVyzP.mjs +85 -0
- package/fesm2022/ngx-t-forms-date-picker-input-element.component-CYUbVyzP.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-date-range-picker-input-element.component-CmoquQGV.mjs +156 -0
- package/fesm2022/ngx-t-forms-date-range-picker-input-element.component-CmoquQGV.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CLUOXreG.mjs +368 -0
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-CLUOXreG.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-document-picker.component-qObjcqhE.mjs +704 -0
- package/fesm2022/ngx-t-forms-document-picker.component-qObjcqhE.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-editor-input-element.component-BLXlfb6F.mjs +294 -0
- package/fesm2022/ngx-t-forms-editor-input-element.component-BLXlfb6F.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-editor-js-input.component-BQL0AH7H.mjs +240 -0
- package/fesm2022/ngx-t-forms-editor-js-input.component-BQL0AH7H.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-file-upload-input-element.component-C7mMeEjF.mjs +205 -0
- package/fesm2022/ngx-t-forms-file-upload-input-element.component-C7mMeEjF.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-input-selector.component-C9u8zq9B.mjs +86 -0
- package/fesm2022/ngx-t-forms-form-input-selector.component-C9u8zq9B.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-json-view.component-856Hx1Bg.mjs +22 -0
- package/fesm2022/ngx-t-forms-form-json-view.component-856Hx1Bg.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-payload-projection.component-CDkTuX9S.mjs +179 -0
- package/fesm2022/ngx-t-forms-form-payload-projection.component-CDkTuX9S.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs +319 -0
- package/fesm2022/ngx-t-forms-form-section-stepper.component-Bs50-nEB.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-qrhM0jGL.mjs +379 -0
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-qrhM0jGL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-geo-location.component-Bosp1UzR.mjs +124 -0
- package/fesm2022/ngx-t-forms-geo-location.component-Bosp1UzR.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-getInputIcon-B4ADgevZ.mjs +31 -0
- package/fesm2022/ngx-t-forms-getInputIcon-B4ADgevZ.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-image-capture-input-element.component-C1g7Z0cK.mjs +180 -0
- package/fesm2022/ngx-t-forms-image-capture-input-element.component-C1g7Z0cK.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-index-dDSobs6A.mjs +2 -0
- package/fesm2022/ngx-t-forms-index-dDSobs6A.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-input-custom.component-BkbHFAyR.mjs +105 -0
- package/fesm2022/ngx-t-forms-input-custom.component-BkbHFAyR.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-input-editor.component-BPUOM9kQ.mjs +181 -0
- package/fesm2022/ngx-t-forms-input-editor.component-BPUOM9kQ.mjs.map +1 -0
- package/fesm2022/{ngx-t-forms-map-mat-options-keys-CbdW82su.mjs → ngx-t-forms-map-mat-options-keys-B6hJ7Io5.mjs} +12 -14
- package/fesm2022/ngx-t-forms-map-mat-options-keys-B6hJ7Io5.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-c7uZT1sr.mjs +66 -0
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-c7uZT1sr.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-CTSBrM-j.mjs +211 -0
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-CTSBrM-j.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-CcYiwx-8.mjs +165 -0
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-CcYiwx-8.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-missing-form-configs.component-DrnH8qdG.mjs +38 -0
- package/fesm2022/ngx-t-forms-missing-form-configs.component-DrnH8qdG.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-C_abEBQ5.mjs +38 -0
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-C_abEBQ5.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-99DpVSy7.mjs +126 -0
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-99DpVSy7.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C0qsMfsq.mjs +336 -0
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-C0qsMfsq.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-B1Z-IXSL.mjs +74 -0
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-B1Z-IXSL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-multiple-input-input-element.component-C7y1OGPx.mjs +905 -0
- package/fesm2022/ngx-t-forms-multiple-input-input-element.component-C7y1OGPx.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-ngx-t-forms-u_kigDid.mjs +19461 -0
- package/fesm2022/ngx-t-forms-ngx-t-forms-u_kigDid.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-paginated-selection-table-AQZSMmhr.mjs +555 -0
- package/fesm2022/ngx-t-forms-paginated-selection-table-AQZSMmhr.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DmNSc5aw.mjs +748 -0
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DmNSc5aw.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-record-list-manager.component-CUMMvMch.mjs +358 -0
- package/fesm2022/ngx-t-forms-record-list-manager.component-CUMMvMch.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs +272 -0
- package/fesm2022/ngx-t-forms-required-inputs.component-Ch2yNcIS.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-C_aFtdvW.mjs +398 -0
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-C_aFtdvW.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-search-field.component-B2ZO7lqO.mjs +38 -0
- package/fesm2022/ngx-t-forms-search-field.component-B2ZO7lqO.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-section-report.component-BxOhR6C0.mjs +98 -0
- package/fesm2022/ngx-t-forms-section-report.component-BxOhR6C0.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-select-input-element.component-DbgZdNoe.mjs +150 -0
- package/fesm2022/ngx-t-forms-select-input-element.component-DbgZdNoe.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Dhln81DL.mjs +169 -0
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Dhln81DL.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-leBokXvM.mjs +204 -0
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-leBokXvM.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-textarea-input-element.component-BEbXJjFA.mjs +95 -0
- package/fesm2022/ngx-t-forms-textarea-input-element.component-BEbXJjFA.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-toggle-input-element.component-DDErRUJd.mjs +82 -0
- package/fesm2022/ngx-t-forms-toggle-input-element.component-DDErRUJd.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-validators-config.component-oGjQVGE2.mjs +733 -0
- package/fesm2022/ngx-t-forms-validators-config.component-oGjQVGE2.mjs.map +1 -0
- package/fesm2022/ngx-t-forms-workflow-adjudication.component-CtU8dECN.mjs +1303 -0
- package/fesm2022/ngx-t-forms-workflow-adjudication.component-CtU8dECN.mjs.map +1 -0
- package/fesm2022/ngx-t-forms.mjs +2 -1
- package/fesm2022/ngx-t-forms.mjs.map +1 -1
- package/package.json +20 -18
- package/styles/_editor-mixins.scss +62 -0
- package/styles/_json-editor-syntax.scss +26 -0
- package/styles/_signature-pad.scss +26 -0
- package/styles/_tokens.scss +148 -0
- package/types/ngx-t-forms.d.ts +1767 -621
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-D-SBMdYg.mjs +0 -313
- package/fesm2022/ngx-t-forms-calculated-field-rules.component-D-SBMdYg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-1cpszpPN.mjs +0 -191
- package/fesm2022/ngx-t-forms-chip-options-creator-editor.component-1cpszpPN.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-DFdAVWTg.mjs +0 -207
- package/fesm2022/ngx-t-forms-config-mscoa-additional-inputs.component-DFdAVWTg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-data-source-picker.component-DxORinAD.mjs +0 -204
- package/fesm2022/ngx-t-forms-data-source-picker.component-DxORinAD.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-DcWS1txl.mjs +0 -289
- package/fesm2022/ngx-t-forms-document-list-label-config-editor.component-DcWS1txl.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-input-selector.component-B2QEnvkq.mjs +0 -134
- package/fesm2022/ngx-t-forms-form-input-selector.component-B2QEnvkq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-json-view.component-DePf44w6.mjs +0 -22
- package/fesm2022/ngx-t-forms-form-json-view.component-DePf44w6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-form-section-stepper.component-BTkcSjg7.mjs +0 -270
- package/fesm2022/ngx-t-forms-form-section-stepper.component-BTkcSjg7.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-Wamzf_sq.mjs +0 -345
- package/fesm2022/ngx-t-forms-forms-builder-menu.component-Wamzf_sq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-input-editor.component-D4xHO76K.mjs +0 -147
- package/fesm2022/ngx-t-forms-input-editor.component-D4xHO76K.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-map-mat-options-keys-CbdW82su.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DmTyO9Wi.mjs +0 -105
- package/fesm2022/ngx-t-forms-mat-chip-list-editor.component-DmTyO9Wi.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-DZ4TenrI.mjs +0 -109
- package/fesm2022/ngx-t-forms-mat-slider-editor.component-DZ4TenrI.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-DPyBYE4p.mjs +0 -155
- package/fesm2022/ngx-t-forms-mat-slider-toggle-editor.component-DPyBYE4p.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-missing-form-configs.component-BRmnwAK6.mjs +0 -28
- package/fesm2022/ngx-t-forms-missing-form-configs.component-BRmnwAK6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D_umeAPL.mjs +0 -43
- package/fesm2022/ngx-t-forms-mscoa-chart-toolbar.component-D_umeAPL.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-CSX2NCNU.mjs +0 -116
- package/fesm2022/ngx-t-forms-mscoa-error-display.component-CSX2NCNU.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B6IF8kGg.mjs +0 -296
- package/fesm2022/ngx-t-forms-mscoa-segment-config.component-B6IF8kGg.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-BPkjsRmH.mjs +0 -83
- package/fesm2022/ngx-t-forms-mscoa-temporary-hint.component-BPkjsRmH.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-ngx-t-forms-D9qmig6g.mjs +0 -16844
- package/fesm2022/ngx-t-forms-ngx-t-forms-D9qmig6g.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DBJEyCbd.mjs +0 -613
- package/fesm2022/ngx-t-forms-pipeline-generator.component-DBJEyCbd.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-record-list-manager.component-Dgs9lNSr.mjs +0 -269
- package/fesm2022/ngx-t-forms-record-list-manager.component-Dgs9lNSr.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-required-inputs.component-CSIJvSHq.mjs +0 -190
- package/fesm2022/ngx-t-forms-required-inputs.component-CSIJvSHq.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-CY-JSkGs.mjs +0 -291
- package/fesm2022/ngx-t-forms-rest-api-call-setup.component-CY-JSkGs.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-section-report.component-12-KdKT6.mjs +0 -156
- package/fesm2022/ngx-t-forms-section-report.component-12-KdKT6.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Be3QAG_L.mjs +0 -186
- package/fesm2022/ngx-t-forms-selection-options-editor.component-Be3QAG_L.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-a4f1r8gH.mjs +0 -187
- package/fesm2022/ngx-t-forms-t-workflow-picker.component-a4f1r8gH.mjs.map +0 -1
- package/fesm2022/ngx-t-forms-validators-config.component-B3j9Dmgu.mjs +0 -215
- package/fesm2022/ngx-t-forms-validators-config.component-B3j9Dmgu.mjs.map +0 -1
|
@@ -1,613 +0,0 @@
|
|
|
1
|
-
import * as i2$2 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-D9qmig6g.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 i3$1 from '@angular/material/icon';
|
|
15
|
-
import * as i3$2 from '@angular/material/select';
|
|
16
|
-
import * as i4$1 from '@angular/material/tooltip';
|
|
17
|
-
import { TWorkflowPickerComponent } from './ngx-t-forms-t-workflow-picker.component-a4f1r8gH.mjs';
|
|
18
|
-
import { MatFormFieldControl } from '@angular/material/form-field';
|
|
19
|
-
import { HttpClient } from '@angular/common/http';
|
|
20
|
-
import * as i10 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 i7$1 from '@angular/material/progress-spinner';
|
|
25
|
-
import * as i5$1 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
|
-
this.activeStage.valid = false;
|
|
80
|
-
return; // Early exit if validation fails
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
const valid = PipelineBuilder.validateStageConfig(stage, config);
|
|
84
|
-
this.activeStage.valid = valid;
|
|
85
|
-
// Set error message if config is invalid
|
|
86
|
-
if (!valid) {
|
|
87
|
-
this.configValidationError = undefined;
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
// Catch and handle errors from validation
|
|
93
|
-
this.configValidationError = error.message || JSON.stringify(error) || 'An unknown error occurred';
|
|
94
|
-
this.activeStage.valid = false;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
canSaveConfig() {
|
|
98
|
-
return !!this.activeStage && !this.configValidationError;
|
|
99
|
-
}
|
|
100
|
-
saveConfiguration() {
|
|
101
|
-
// Logic for saving the configuration
|
|
102
|
-
if (this.canSaveConfig()) {
|
|
103
|
-
this.saveStage.emit(this.activeStage);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
trackByStage(index, stage) {
|
|
107
|
-
return stage.stage;
|
|
108
|
-
}
|
|
109
|
-
get allowedStageNames() {
|
|
110
|
-
return this.allowedStages.map(stage => stage.stage);
|
|
111
|
-
}
|
|
112
|
-
get activeDescription() {
|
|
113
|
-
return this.allowedStages.find(stage => stage.stage === this.activeStage?.stage)?.description;
|
|
114
|
-
}
|
|
115
|
-
deleteActive() {
|
|
116
|
-
this.deleteStage.emit();
|
|
117
|
-
}
|
|
118
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AggregateStageEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
119
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.5", 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[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { 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: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3$2.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i3$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i3$2.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: i4$1.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: JsonEditorComponent, selector: "app-json-editor", inputs: ["value"], outputs: ["valueChange"] }] }); }
|
|
120
|
-
}
|
|
121
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: AggregateStageEditorComponent, decorators: [{
|
|
122
|
-
type: Component,
|
|
123
|
-
args: [{ selector: 'app-aggregate-stage-editor', standalone: true, imports: [
|
|
124
|
-
MatModulesModule,
|
|
125
|
-
CommonModule,
|
|
126
|
-
FormsModule,
|
|
127
|
-
JsonEditorComponent
|
|
128
|
-
], 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"] }]
|
|
129
|
-
}], ctorParameters: () => [], propDecorators: { selectedStage: [{
|
|
130
|
-
type: Input
|
|
131
|
-
}], isRunningPipeline: [{
|
|
132
|
-
type: Input
|
|
133
|
-
}], saveStage: [{
|
|
134
|
-
type: Output
|
|
135
|
-
}], deleteStage: [{
|
|
136
|
-
type: Output
|
|
137
|
-
}] } });
|
|
138
|
-
|
|
139
|
-
class PipelineService {
|
|
140
|
-
constructor() {
|
|
141
|
-
//LOADING INDICATORS
|
|
142
|
-
this.isRunningPipeline = false;
|
|
143
|
-
this.aiIsGeneratingPipeline = false;
|
|
144
|
-
this.isLoadingAllowedStages = false;
|
|
145
|
-
this.isLoadingWorkflowSchema = false;
|
|
146
|
-
//States
|
|
147
|
-
this.workflowId$ = new BehaviorSubject(undefined);
|
|
148
|
-
this.activeStage$ = new BehaviorSubject(undefined);
|
|
149
|
-
this.prompt$ = new BehaviorSubject(undefined);
|
|
150
|
-
this.schemaLoadError$ = new BehaviorSubject(undefined);
|
|
151
|
-
this.pipeline$ = new BehaviorSubject([]);
|
|
152
|
-
this.threadId$ = new BehaviorSubject(undefined);
|
|
153
|
-
this.schema$ = new BehaviorSubject(undefined);
|
|
154
|
-
this.allowedStages$ = new BehaviorSubject([]);
|
|
155
|
-
this.pipeLineResult$ = new BehaviorSubject([]);
|
|
156
|
-
this.chatHistory$ = new BehaviorSubject([]);
|
|
157
|
-
this.http = inject(HttpClient);
|
|
158
|
-
//Set local storage threadId
|
|
159
|
-
const threadId = localStorage.getItem('threadId');
|
|
160
|
-
if (threadId) {
|
|
161
|
-
this.threadId$.next(threadId);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
get config$() {
|
|
165
|
-
return this.workflowId$.pipe(switchMap(workflowId => this.pipeline$.pipe(switchMap(pipeline => this.pipeLineResult$.pipe(map(responseBody => ({ workflowId, pipeline, responseBody })))))));
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Fetch available pipeline stages for the user to select and generate pipelines.
|
|
169
|
-
* Ideally, this could be static or fetched from a backend.
|
|
170
|
-
*/
|
|
171
|
-
runPipeLine(pipeline, workflowId) {
|
|
172
|
-
const url = "http://localhost:5000/api/v1/pipelineBuilder/runPipeline";
|
|
173
|
-
// For now, returning a static list of pipeline stages. In a real application, you can fetch from an API.
|
|
174
|
-
this.isRunningPipeline = true;
|
|
175
|
-
return this.http.post(url, { pipeline, workflowId }).pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
|
|
176
|
-
finalize(() => this.isRunningPipeline = false));
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Generate a MongoDB pipeline based on the given user prompt.
|
|
180
|
-
*
|
|
181
|
-
* @param prompt The user's input or description of the desired pipeline.
|
|
182
|
-
*/
|
|
183
|
-
generatePipeline(query, schema, threadId, existingPipeline, previousError) {
|
|
184
|
-
if (!schema) {
|
|
185
|
-
throw new Error("Schema is required");
|
|
186
|
-
}
|
|
187
|
-
const payload = { query, schema, threadId, existingPipeline, previousError };
|
|
188
|
-
const url = "http://localhost:5000/api/v1/pipelineBuilder/generatePipeline";
|
|
189
|
-
this.aiIsGeneratingPipeline = true;
|
|
190
|
-
return this.http.post(`${url}`, payload)
|
|
191
|
-
.pipe(take(1), catchError(this.handleError), // Error handling for the HTTP request,
|
|
192
|
-
finalize(() => this.aiIsGeneratingPipeline = false));
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Handle any errors from the HTTP request.
|
|
196
|
-
*
|
|
197
|
-
* @param error The error response from the HTTP request
|
|
198
|
-
*/
|
|
199
|
-
handleError(error) {
|
|
200
|
-
// Return an observable with a user-facing error message
|
|
201
|
-
return throwError(() => new Error('Something went wrong with the pipeline generation; please try again later.'));
|
|
202
|
-
}
|
|
203
|
-
getSchema(workflowId) {
|
|
204
|
-
if (!workflowId) {
|
|
205
|
-
throw new Error("WorkflowId is required");
|
|
206
|
-
}
|
|
207
|
-
const url = "http://localhost:5000/api/v1/pipelineBuilder/getSchema";
|
|
208
|
-
return this.http.get(`${url}`, { params: { workflowId: workflowId } }).pipe(take(1), catchError(this.handleError) // Error handling for the HTTP request
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
/** OPERATIONS */
|
|
212
|
-
isSchemaEmpty(object) {
|
|
213
|
-
}
|
|
214
|
-
workflowChanged(event) {
|
|
215
|
-
this.workflowId$.next(event);
|
|
216
|
-
if (!event) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
this.getSchema(event).pipe(take(1), tap(({ schema }) => {
|
|
220
|
-
this.schema$.next(schema);
|
|
221
|
-
const isEmptySchema = Object.keys(schema)[0] === "" && Object.values(schema)[0] === "Array<>";
|
|
222
|
-
const error = isEmptySchema
|
|
223
|
-
? "Document schema is missing. Please ensure at least one document exists for the selected workflow."
|
|
224
|
-
: undefined;
|
|
225
|
-
this.schemaLoadError$.next(error);
|
|
226
|
-
this.runActivePipeline();
|
|
227
|
-
}), catchError((error) => {
|
|
228
|
-
this.schemaLoadError$.next("Error loading schema");
|
|
229
|
-
return this.handleError(error);
|
|
230
|
-
})).subscribe();
|
|
231
|
-
}
|
|
232
|
-
setActiveStage(i) {
|
|
233
|
-
const index = this.activeStage$.getValue();
|
|
234
|
-
if (index === i) {
|
|
235
|
-
this.activeStage$.next(undefined);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
this.activeStage$.next(i);
|
|
239
|
-
}
|
|
240
|
-
addStage() {
|
|
241
|
-
const newPipeline = this.pipeline$.getValue().concat({});
|
|
242
|
-
this.pipeline$.next(newPipeline);
|
|
243
|
-
}
|
|
244
|
-
onTextChange(event) {
|
|
245
|
-
this.prompt$.next(event);
|
|
246
|
-
}
|
|
247
|
-
promptSubmit() {
|
|
248
|
-
// Use combineLatest to fetch the latest values from multiple sources
|
|
249
|
-
combineLatest([this.schema$, this.threadId$, this.pipeline$, this.prompt$, this.chatHistory$])
|
|
250
|
-
.pipe(take(1), tap(() => { }), filter(([schema, , , prompt]) => !!schema && !!prompt), switchMap(([schema, threadId, pipeline, prompt, history]) => {
|
|
251
|
-
// Use a shallow copy of the pipeline
|
|
252
|
-
const previousError = history[history.length - 1]?.assistance?.error;
|
|
253
|
-
const pipelineCopy = pipeline.map(stage => JSON.parse(JSON.stringify(stage))) || [];
|
|
254
|
-
return this.generatePipeline(prompt, schema, threadId, pipelineCopy, previousError).pipe(map((response) => ({ ...response, history, prompt })));
|
|
255
|
-
}), tap((response) => {
|
|
256
|
-
const { pipeline, threadId, history, prompt } = response;
|
|
257
|
-
const historyRecord = {
|
|
258
|
-
user: prompt,
|
|
259
|
-
assistance: response,
|
|
260
|
-
date: new Date()
|
|
261
|
-
};
|
|
262
|
-
// Use next with a concatenated value for chat history
|
|
263
|
-
this.chatHistory$.next([...(history || []), historyRecord]);
|
|
264
|
-
this.pipeline$.next(pipeline);
|
|
265
|
-
this.threadId$.next(threadId);
|
|
266
|
-
// Store threadID locally
|
|
267
|
-
localStorage.setItem('threadId', threadId);
|
|
268
|
-
// Run the active pipeline after all state updates are complete
|
|
269
|
-
this.runActivePipeline();
|
|
270
|
-
}), catchError((error) => {
|
|
271
|
-
return this.handleError(error);
|
|
272
|
-
})).subscribe();
|
|
273
|
-
}
|
|
274
|
-
runActivePipeline() {
|
|
275
|
-
const pipeline = [...(this.pipeline$.getValue().map(stage => (JSON.parse(JSON.stringify(stage)))) || [])];
|
|
276
|
-
const someAreNotValid = pipeline.some(stage => Object.keys(stage).length === 0);
|
|
277
|
-
if (pipeline.length === 0 || someAreNotValid) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
try {
|
|
281
|
-
PipelineBuilder.validatePipeline(pipeline);
|
|
282
|
-
}
|
|
283
|
-
catch {
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
const workflowId = this.workflowId$.getValue();
|
|
287
|
-
if (!workflowId) {
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
this.runPipeLine(pipeline, workflowId).pipe(take(1), tap(({ results }) => {
|
|
291
|
-
this.pipeLineResult$.next(results);
|
|
292
|
-
}), catchError((error) => {
|
|
293
|
-
const err = JSON.parse(JSON.stringify(error));
|
|
294
|
-
const errorMessage = err.error;
|
|
295
|
-
if (errorMessage) {
|
|
296
|
-
this.pipelineErrorLogAndRetry(errorMessage);
|
|
297
|
-
}
|
|
298
|
-
return this.handleError(error);
|
|
299
|
-
})).subscribe();
|
|
300
|
-
}
|
|
301
|
-
pipelineErrorLogAndRetry(message) {
|
|
302
|
-
const history = this.chatHistory$.getValue();
|
|
303
|
-
const prompt = this.prompt$.getValue();
|
|
304
|
-
const historyRecord = {
|
|
305
|
-
user: prompt,
|
|
306
|
-
assistance: {
|
|
307
|
-
message
|
|
308
|
-
},
|
|
309
|
-
date: new Date()
|
|
310
|
-
};
|
|
311
|
-
this.chatHistory$.next([...(history || []), historyRecord]);
|
|
312
|
-
}
|
|
313
|
-
get activeStage() {
|
|
314
|
-
return this.pipeline$.asObservable().pipe(switchMap(pipeline => this.activeStage$.pipe(map(activeIndex => activeIndex === undefined ? undefined : {
|
|
315
|
-
name: Object.keys(pipeline[activeIndex] || {})[0] || '',
|
|
316
|
-
config: pipeline[activeIndex][Object.keys(pipeline[activeIndex] || {})?.[0] || '']
|
|
317
|
-
}))));
|
|
318
|
-
}
|
|
319
|
-
saveStage(index, stage) {
|
|
320
|
-
const pipeline = this.pipeline$.getValue();
|
|
321
|
-
if (index === undefined) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
const newPipeline = pipeline.map((s, i) => {
|
|
325
|
-
if (i === index) {
|
|
326
|
-
return stage ? {
|
|
327
|
-
[stage.stage]: stage.config
|
|
328
|
-
} : s;
|
|
329
|
-
}
|
|
330
|
-
return s;
|
|
331
|
-
});
|
|
332
|
-
this.pipeline$.next(newPipeline);
|
|
333
|
-
this.activeStage$.next(undefined);
|
|
334
|
-
this.runActivePipeline();
|
|
335
|
-
}
|
|
336
|
-
deleteStage(index) {
|
|
337
|
-
const pipeline = this.pipeline$.getValue();
|
|
338
|
-
if (index === undefined) {
|
|
339
|
-
return;
|
|
340
|
-
}
|
|
341
|
-
const newPipeline = pipeline.filter((s, i) => i !== index);
|
|
342
|
-
this.pipeline$.next(newPipeline);
|
|
343
|
-
this.activeStage$.next(undefined);
|
|
344
|
-
this.runActivePipeline();
|
|
345
|
-
}
|
|
346
|
-
get pipelineGeneralValid() {
|
|
347
|
-
return this.pipeline$.asObservable().pipe(map(pipeline => {
|
|
348
|
-
const allHaveTypes = pipeline.every(stage => Object.keys(stage).length === 1);
|
|
349
|
-
if (!allHaveTypes) {
|
|
350
|
-
return {
|
|
351
|
-
valid: false,
|
|
352
|
-
message: "All stages must be a valid pipeline stage"
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
const AllStagesMustHaveConfig = pipeline.every((stage) => stage[Object.keys(stage)?.[0] || ''] !== undefined);
|
|
356
|
-
if (!AllStagesMustHaveConfig) {
|
|
357
|
-
return {
|
|
358
|
-
valid: false,
|
|
359
|
-
message: "All stages must have a configuration"
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
return {
|
|
363
|
-
valid: true
|
|
364
|
-
};
|
|
365
|
-
}));
|
|
366
|
-
}
|
|
367
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PipelineService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
368
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PipelineService, providedIn: 'root' }); }
|
|
369
|
-
}
|
|
370
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PipelineService, decorators: [{
|
|
371
|
-
type: Injectable,
|
|
372
|
-
args: [{
|
|
373
|
-
providedIn: 'root'
|
|
374
|
-
}]
|
|
375
|
-
}], ctorParameters: () => [] });
|
|
376
|
-
|
|
377
|
-
class PipelineGeneratorComponent {
|
|
378
|
-
static { this.nextId = 0; }
|
|
379
|
-
constructor(ngControl, _elementRef) {
|
|
380
|
-
this.ngControl = ngControl;
|
|
381
|
-
this._elementRef = _elementRef;
|
|
382
|
-
this.stateChanges = new Subject();
|
|
383
|
-
this.NGX_T_FORMS_CONFIG = inject(NGX_T_FORMS_CONFIG_TOKEN);
|
|
384
|
-
this.id = `app-pipeline-generator-${PipelineGeneratorComponent.nextId++}`;
|
|
385
|
-
this.placeholder = '';
|
|
386
|
-
this.focused = false;
|
|
387
|
-
this.required = false;
|
|
388
|
-
this.disabled = false;
|
|
389
|
-
this.touched = false;
|
|
390
|
-
this.onTouched = () => { };
|
|
391
|
-
this.valueChanged = new EventEmitter();
|
|
392
|
-
this.errors = [];
|
|
393
|
-
this.destroy$ = new Subject();
|
|
394
|
-
this.pipeline = new PipelineService();
|
|
395
|
-
this.initiated = false;
|
|
396
|
-
this.initiateSubscription = () => {
|
|
397
|
-
this.pipeline.config$.pipe(takeUntil(this.destroy$), distinctUntilChanged((prev, curr) => JSON.stringify(prev) === JSON.stringify(curr))).subscribe(config => {
|
|
398
|
-
if (!this.initiated) {
|
|
399
|
-
this.initiated = true;
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
const newConfig = {
|
|
403
|
-
...this._value,
|
|
404
|
-
...config,
|
|
405
|
-
name: this._workflowName || 'Unnamed Pipeline',
|
|
406
|
-
"source": "mongoPipeline",
|
|
407
|
-
};
|
|
408
|
-
this.valueChanged.emit(newConfig);
|
|
409
|
-
});
|
|
410
|
-
};
|
|
411
|
-
this.cursorPosition = 0;
|
|
412
|
-
this.showSuggestions = false;
|
|
413
|
-
this.optionsSearch = '';
|
|
414
|
-
this.trackById = (index, stage) => index;
|
|
415
|
-
}
|
|
416
|
-
get empty() {
|
|
417
|
-
return !this.value;
|
|
418
|
-
}
|
|
419
|
-
get shouldLabelFloat() {
|
|
420
|
-
return this.focused || !this.empty;
|
|
421
|
-
}
|
|
422
|
-
get errorState() {
|
|
423
|
-
const hasError = !!this.ngControl?.control?.errors || (this.errors || []).length > 0 && this.touched;
|
|
424
|
-
return !this.value && !!this.required || hasError;
|
|
425
|
-
}
|
|
426
|
-
setDescribedByIds(ids) {
|
|
427
|
-
// Ensure the component view is initialized
|
|
428
|
-
if (this._elementRef && this._elementRef.nativeElement) {
|
|
429
|
-
const controlElement = this._elementRef.nativeElement.querySelector('.app-pipeline-generator');
|
|
430
|
-
// Check if the controlElement exists before attempting to set its attribute
|
|
431
|
-
if (controlElement) {
|
|
432
|
-
controlElement.setAttribute('aria-describedby', ids.join(' '));
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
onContainerClick(event) {
|
|
437
|
-
this.markAsTouched();
|
|
438
|
-
this.stateChanges.next();
|
|
439
|
-
}
|
|
440
|
-
markAsTouched() {
|
|
441
|
-
if (!this.touched) {
|
|
442
|
-
this.onTouched();
|
|
443
|
-
this.touched = true;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
set value(value) {
|
|
447
|
-
const workflowIdChanged = this._value?.workflowId !== value?.workflowId;
|
|
448
|
-
const pipelineLengthChanged = this._value?.pipeline?.length !== value?.pipeline?.length;
|
|
449
|
-
const pipeLineContentChanged = JSON.stringify(this._value?.pipeline) !== JSON.stringify(value?.pipeline);
|
|
450
|
-
if (workflowIdChanged || pipelineLengthChanged || pipeLineContentChanged) {
|
|
451
|
-
this._value = value;
|
|
452
|
-
if (value?.workflowId) {
|
|
453
|
-
this.workflowChanged(value?.workflowId);
|
|
454
|
-
}
|
|
455
|
-
if (value?.pipeline) {
|
|
456
|
-
this.pipeline.pipeline$.next(value?.pipeline || []);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
set getWorkflowOptions(options$) {
|
|
461
|
-
this.workflows$ = options$;
|
|
462
|
-
}
|
|
463
|
-
ngOnInit() {
|
|
464
|
-
this.initiateSubscription();
|
|
465
|
-
}
|
|
466
|
-
ngOnDestroy() {
|
|
467
|
-
this.destroy$.next();
|
|
468
|
-
this.destroy$.complete();
|
|
469
|
-
}
|
|
470
|
-
workflowChanged(event) {
|
|
471
|
-
this.pipeline.workflowChanged(event);
|
|
472
|
-
}
|
|
473
|
-
workflowNameChanged(event) {
|
|
474
|
-
this._workflowName = event;
|
|
475
|
-
}
|
|
476
|
-
get workflowId() {
|
|
477
|
-
return this.pipeline.workflowId$.asObservable();
|
|
478
|
-
}
|
|
479
|
-
get stages() {
|
|
480
|
-
return this.pipeline.pipeline$.asObservable().pipe(map(stages => stages.map(stage => ({
|
|
481
|
-
name: Object.keys(stage)[0],
|
|
482
|
-
stage: Object.keys(stage)[0],
|
|
483
|
-
config: stage[Object.keys(stage)?.[0] || ''],
|
|
484
|
-
valid: !!Object.keys(stage)[0] && !!stage[Object.keys(stage)?.[0] || '']
|
|
485
|
-
}))));
|
|
486
|
-
}
|
|
487
|
-
get pipeLineResults() {
|
|
488
|
-
return this.pipeline.pipeLineResult$.asObservable();
|
|
489
|
-
}
|
|
490
|
-
get prompt() {
|
|
491
|
-
return this.pipeline.prompt$.asObservable();
|
|
492
|
-
}
|
|
493
|
-
get aiIsGeneratingPipeline() {
|
|
494
|
-
return this.pipeline.aiIsGeneratingPipeline;
|
|
495
|
-
}
|
|
496
|
-
get activeStageIndex() {
|
|
497
|
-
return this.pipeline.activeStage$.asObservable();
|
|
498
|
-
}
|
|
499
|
-
get activeStage() {
|
|
500
|
-
return this.pipeline.activeStage;
|
|
501
|
-
}
|
|
502
|
-
get isRunningPipeline() {
|
|
503
|
-
return this.pipeline.isRunningPipeline;
|
|
504
|
-
}
|
|
505
|
-
get cannotAddStage() {
|
|
506
|
-
return this.pipeline.pipelineGeneralValid.pipe(map(valid => !valid));
|
|
507
|
-
}
|
|
508
|
-
get schemaLoadError$() {
|
|
509
|
-
return this.pipeline.schemaLoadError$.asObservable();
|
|
510
|
-
}
|
|
511
|
-
get chatHistory() {
|
|
512
|
-
return this.pipeline.chatHistory$.asObservable();
|
|
513
|
-
}
|
|
514
|
-
onTextChange(event) {
|
|
515
|
-
if (!this.textareaElementRef?.nativeElement) {
|
|
516
|
-
return;
|
|
517
|
-
}
|
|
518
|
-
const newValue = event.target.value;
|
|
519
|
-
const textarea = this.textareaElementRef.nativeElement;
|
|
520
|
-
this.cursorPosition = textarea.selectionStart || 0;
|
|
521
|
-
const lastChar = newValue[this.cursorPosition - 1];
|
|
522
|
-
const match = newValue.slice(0, this.cursorPosition).match(/\$(\w*)$/);
|
|
523
|
-
if (lastChar === '$' || (match && match[1] !== undefined)) {
|
|
524
|
-
this.showSuggestions = true;
|
|
525
|
-
this.optionsSearch = match ? match?.[1] || '' : '';
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
this.showSuggestions = false;
|
|
529
|
-
this.optionsSearch = '';
|
|
530
|
-
}
|
|
531
|
-
this.pipeline.onTextChange(newValue);
|
|
532
|
-
}
|
|
533
|
-
selectSuggestionInput(suggestion) {
|
|
534
|
-
this.pipeline.prompt$.asObservable().pipe(take(1), tap(prompt => {
|
|
535
|
-
const match = prompt?.slice(0, this.cursorPosition).match(/\$(\w*)$/);
|
|
536
|
-
const beforeCursor = prompt?.slice(0, match ? match.index : this.cursorPosition - 1);
|
|
537
|
-
const afterCursor = prompt?.slice(this.cursorPosition);
|
|
538
|
-
prompt = beforeCursor + suggestion + ' ' + afterCursor;
|
|
539
|
-
this.pipeline.prompt$.next(prompt);
|
|
540
|
-
this.applyNewValueToPrompt(suggestion);
|
|
541
|
-
})).subscribe();
|
|
542
|
-
}
|
|
543
|
-
applyNewValueToPrompt(suggestion) {
|
|
544
|
-
this.showSuggestions = false;
|
|
545
|
-
const textarea = this.textareaElementRef.nativeElement;
|
|
546
|
-
textarea.focus();
|
|
547
|
-
const newCursorPosition = this.cursorPosition + suggestion.length;
|
|
548
|
-
setTimeout(() => {
|
|
549
|
-
textarea.setSelectionRange(newCursorPosition, newCursorPosition);
|
|
550
|
-
}, 0);
|
|
551
|
-
}
|
|
552
|
-
onSearchChange(event) {
|
|
553
|
-
this.optionsSearch = event.detail.value;
|
|
554
|
-
}
|
|
555
|
-
promptSubmit() {
|
|
556
|
-
this.pipeline.promptSubmit();
|
|
557
|
-
}
|
|
558
|
-
setActiveStage(index) {
|
|
559
|
-
this.pipeline.setActiveStage(index);
|
|
560
|
-
}
|
|
561
|
-
addStage() {
|
|
562
|
-
this.pipeline.addStage();
|
|
563
|
-
}
|
|
564
|
-
get getSchemaProperties() {
|
|
565
|
-
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)));
|
|
566
|
-
}
|
|
567
|
-
deleteStage(index) {
|
|
568
|
-
this.pipeline.deleteStage(index);
|
|
569
|
-
}
|
|
570
|
-
saveStage(index, stage) {
|
|
571
|
-
this.pipeline.saveStage(index, stage);
|
|
572
|
-
this.setActiveStage(undefined);
|
|
573
|
-
}
|
|
574
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PipelineGeneratorComponent, deps: [{ token: i1.NgControl, optional: true, self: true }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
575
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", 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$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { 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[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatMiniFabButton, selector: "button[mat-mini-fab], a[mat-mini-fab], button[matMiniFab], a[matMiniFab]", exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { 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: i3$1.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: i7$1.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i5$1.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "directive", type: i10.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", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], 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: "ngmodule", type: OverlayModule }, { kind: "pipe", type: i2$2.AsyncPipe, name: "async" }, { kind: "pipe", type: i2$2.JsonPipe, name: "json" }, { kind: "pipe", type: i2$2.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: DaysAgoPipe, name: "daysAgo" }] }); }
|
|
576
|
-
}
|
|
577
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PipelineGeneratorComponent, decorators: [{
|
|
578
|
-
type: Component,
|
|
579
|
-
args: [{ selector: 'app-pipeline-generator', standalone: true, imports: [
|
|
580
|
-
CommonModule,
|
|
581
|
-
TWorkflowPickerComponent,
|
|
582
|
-
FormsModule,
|
|
583
|
-
TDynamicDataViewComponent,
|
|
584
|
-
MatModulesModule,
|
|
585
|
-
AggregateStageEditorComponent,
|
|
586
|
-
DaysAgoPipe,
|
|
587
|
-
OverlayModule
|
|
588
|
-
], 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"] }]
|
|
589
|
-
}], ctorParameters: () => [{ type: i1.NgControl, decorators: [{
|
|
590
|
-
type: Optional
|
|
591
|
-
}, {
|
|
592
|
-
type: Self
|
|
593
|
-
}] }, { type: i0.ElementRef }], propDecorators: { id: [{
|
|
594
|
-
type: HostBinding
|
|
595
|
-
}], disabled: [{
|
|
596
|
-
type: Input
|
|
597
|
-
}], textareaElementRef: [{
|
|
598
|
-
type: ViewChild,
|
|
599
|
-
args: ['textarea', { read: ElementRef, static: false }]
|
|
600
|
-
}], value: [{
|
|
601
|
-
type: Input
|
|
602
|
-
}], getWorkflowOptions: [{
|
|
603
|
-
type: Input
|
|
604
|
-
}], userName: [{
|
|
605
|
-
type: Input
|
|
606
|
-
}], valueChanged: [{
|
|
607
|
-
type: Output
|
|
608
|
-
}], errors: [{
|
|
609
|
-
type: Input
|
|
610
|
-
}] } });
|
|
611
|
-
|
|
612
|
-
export { PipelineGeneratorComponent };
|
|
613
|
-
//# sourceMappingURL=ngx-t-forms-pipeline-generator.component-DBJEyCbd.mjs.map
|