data lake
This commit is contained in:
		
							parent
							
								
									251bc56428
								
							
						
					
					
						commit
						7f80ea6330
					
				| @ -55,11 +55,13 @@ | ||||
|       <clr-dg-column [clrDgField]="'sure_connect_id'"> <ng-container *clrDgHideableColumn="{hidden: false}"> SureConnect | ||||
|         </ng-container></clr-dg-column> | ||||
| 
 | ||||
|       <clr-dg-column [clrDgField]="'calculated_field_json'"> <ng-container *clrDgHideableColumn="{hidden: false}"> Calculated Fields | ||||
|       <clr-dg-column [clrDgField]="'calculated_field_json'"> <ng-container *clrDgHideableColumn="{hidden: false}"> | ||||
|           Calculated Fields | ||||
|         </ng-container></clr-dg-column> | ||||
| 
 | ||||
|       <!-- who column --> | ||||
|       <clr-dg-column> <ng-container *clrDgHideableColumn="{hidden: false}"> | ||||
|       <clr-dg-column> | ||||
|         <ng-container *clrDgHideableColumn="{hidden: false}"> | ||||
|           <clr-icon shape="bars"></clr-icon> Action | ||||
|         </ng-container></clr-dg-column> | ||||
|       <!-- end --> | ||||
| @ -99,8 +101,9 @@ | ||||
| 
 | ||||
|         <clr-dg-cell>{{user.sureconnect_name}}</clr-dg-cell> | ||||
| 
 | ||||
|         <clr-dg-cell (click)="goToReplaceStringjson(user.calculated_field_json)" style="cursor: pointer; align-items: center;"><clr-icon | ||||
|             shape="details" *ngIf="user.calculated_field_json"></clr-icon></clr-dg-cell> | ||||
|         <clr-dg-cell (click)="goToReplaceStringjson(user.calculated_field_json)" | ||||
|           style="cursor: pointer; align-items: center;"><clr-icon shape="details" | ||||
|             *ngIf="user.calculated_field_json"></clr-icon></clr-dg-cell> | ||||
| 
 | ||||
|         <!-- who column --> | ||||
|         <clr-dg-cell> | ||||
| @ -165,7 +168,9 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </ng-template><ng-container *ngIf="isCardview"> | ||||
|   </ng-template> | ||||
| 
 | ||||
|   <ng-container *ngIf="isCardview"> | ||||
|     <div *ngIf="product; else showInfo" class="clr-row clr-align-items-start clr-justify-content-start"> | ||||
|       <div *ngFor="let app of product| filter:search; let index = i" class="clr-col-auto"> | ||||
|         <div class="clr-row"> | ||||
| @ -227,6 +232,7 @@ | ||||
|                       {{afterText(item.fieldtext)}} | ||||
|                     </div> | ||||
| 
 | ||||
|                     | ||||
|                     <div *ngIf="item.name === 'Line'" class="title-card card-title" | ||||
|                       [style.text-align]="item.alignment !== '' ? item.alignment : 'left'" | ||||
|                       [style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'" | ||||
| @ -240,7 +246,6 @@ | ||||
|                       <hr> | ||||
|                     </div> | ||||
| 
 | ||||
| 
 | ||||
|  <div *ngIf="item.name === 'Icon'" class="icon-card" | ||||
|                       [style.text-align]="item.alignment !== '' ? item.alignment : 'left'" | ||||
|                       [style.line-height]="item.textlineheight !== '' ? item.textlineheight : '1'" | ||||
| @ -282,16 +287,6 @@ | ||||
| </div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <clr-modal [(clrModalOpen)]="rsModaljson" [clrModalSize]="'xl'" [clrModalStaticBackdrop]="true"> | ||||
|   <div class="modal-body"> | ||||
|     <textarea class="form-control" style="width:100%; height: 400px;" readonly>{{rowSelected}}</textarea> | ||||
| @ -522,21 +517,27 @@ | ||||
|   <div class="modal-body"> | ||||
|     <form [formGroup]="calculatedFieldForm"> | ||||
|       <div class="clr-row"> | ||||
|         <div class="clr-col-12"> | ||||
|           <h4>Available Keys from API:</h4> | ||||
|           <ul> | ||||
|             <li *ngFor="let key of availableKeys">{{ key }}</li> | ||||
|           </ul> | ||||
|         <div class="clr-col-12 calculated-section"> | ||||
|           <h4 class="section-title"> | ||||
|             <clr-icon shape="key" class="section-icon"></clr-icon> | ||||
|             Available Keys from API | ||||
|           </h4> | ||||
|           <div class="field-container"> | ||||
|             <span *ngFor="let key of availableKeys" class="field-tag" (click)="addFieldToEquation(key)"> | ||||
|               <clr-icon shape="data-field" class="field-icon"></clr-icon> | ||||
|               {{ key }} | ||||
|             </span> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="clr-col-12"> | ||||
|           <label>Calculated Field Name</label> | ||||
|           <input class="clr-input" type="text" formControlName="fieldName" placeholder="Enter field name" /> | ||||
|         <div class="clr-col-12 calculated-section"> | ||||
|           <label class="field-label">Calculated Field Name</label> | ||||
|           <input class="clr-input field-input" type="text" formControlName="fieldName" placeholder="Enter field name" /> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="clr-col-12"> | ||||
|           <label>Operation</label> | ||||
|           <select formControlName="operation"> | ||||
|         <div class="clr-col-12 calculated-section"> | ||||
|           <label class="field-label">Operation</label> | ||||
|           <select class="field-input" formControlName="operation"> | ||||
|             <option value="">Select Operation</option> | ||||
|             <option value="add">Addition (+)</option> | ||||
|             <option value="subtract">Subtraction (-)</option> | ||||
| @ -544,47 +545,128 @@ | ||||
|             <option value="divide">Division (/)</option> | ||||
|             <option value="percentage">Percentage (%)</option> | ||||
|             <option value="concat">Concatenation (||)</option> | ||||
|             <option value="complex">Complex Equation</option> | ||||
|           </select> | ||||
|         </div> | ||||
| 
 | ||||
|         <!-- Complex Equation Section --> | ||||
|         <div class="clr-col-12 calculated-section" *ngIf="calculatedFieldForm.get('operation')?.value === 'complex'"> | ||||
|           <label class="field-label">Complex Equation</label> | ||||
|           <textarea class="clr-textarea equation-input" formControlName="complexEquation" | ||||
|             placeholder="Enter complex equation using actual field names" rows="3"></textarea> | ||||
|           <small class="clr-subtext equation-hint"> | ||||
|             Use actual field names from the available keys list above, or predefined constants (constant_X). | ||||
|             Example: (field1 + field2) * constant_1 - (field3 / field4) | ||||
|           </small> | ||||
| 
 | ||||
|           <!-- Available Operators --> | ||||
|           <div class="operators-container"> | ||||
|             <h5 class="subsection-title"> | ||||
|               <clr-icon shape="calculator" class="subsection-icon"></clr-icon> | ||||
|               Available Operators | ||||
|             </h5> | ||||
|             <div class="operator-tags"> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('+')">+</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('-')">-</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('*')">×</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('/')">÷</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('(')">(</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation(')')">)</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('[')">[</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation(']')">]</span> | ||||
|               <!-- <span class="operator-tag" (click)="addOperatorToEquation('{')">{</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('}')">}</span> --> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('^')">^</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('%')">%</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('=')">=</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('>')">></span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('<')"><</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('>=')">>=</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('<=')"><=</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('!=')">!=</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('&&')">&&</span> | ||||
|               <span class="operator-tag" (click)="addOperatorToEquation('||')">||</span> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
|           <!-- Available Fields --> | ||||
|           <div class="fields-container"> | ||||
|             <h5 class="subsection-title"> | ||||
|               <clr-icon shape="data-field" class="subsection-icon"></clr-icon> | ||||
|               Available Fields | ||||
|             </h5> | ||||
|             <div class="field-tags"> | ||||
|               <span *ngFor="let key of availableKeys" class="field-tag" (click)="addFieldToEquation(key)"> | ||||
|                 <clr-icon shape="data-field" class="field-icon"></clr-icon> | ||||
|                 {{ key }} | ||||
|               </span> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
|           <!-- Defined Constants --> | ||||
|           <div class="constants-container" *ngIf="getDefinedConstants().length > 0"> | ||||
|             <h5 class="subsection-title"> | ||||
|               <clr-icon shape="pin" class="subsection-icon"></clr-icon> | ||||
|               Defined Constants | ||||
|             </h5> | ||||
|             <div class="constant-tags"> | ||||
|               <span *ngFor="let constant of getDefinedConstants()" class="constant-tag" | ||||
|                 (click)="addFieldToEquation(constant)"> | ||||
|                 <clr-icon shape="pin" class="constant-icon"></clr-icon> | ||||
|                 {{ constant }} | ||||
|               </span> | ||||
|             </div> | ||||
|           </div> | ||||
| 
 | ||||
|           <!-- Add New Constant --> | ||||
|           <div class="new-constant-container"> | ||||
|             <button class="btn btn-sm btn-secondary add-constant-btn" (click)="addNewConstantToEquation()"> | ||||
|               <clr-icon shape="plus"></clr-icon> Add New Constant | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
| 
 | ||||
|         <!-- Multiple Fields Section --> | ||||
|         <div class="clr-col-12" *ngIf="calculatedFieldForm.get('operation')?.value"> | ||||
|           <label>Fields and Constants</label> | ||||
|           <div class="clr-row"> | ||||
|             <div class="clr-col-12"> | ||||
|         <div class="clr-col-12 calculated-section" | ||||
|           *ngIf="calculatedFieldForm.get('operation')?.value && calculatedFieldForm.get('operation')?.value !== 'complex'"> | ||||
|           <label class="field-label">Fields and Constants</label> | ||||
|           <div class="field-components-container"> | ||||
|             <div formArrayName="fieldComponents"> | ||||
|                 <div *ngFor="let fieldComponent of getFieldComponents().controls; let i = index"  | ||||
|                      [formGroupName]="i" class="clr-row field-component-row"> | ||||
|                   <div class="clr-col-5"> | ||||
|                     <select formControlName="field"> | ||||
|               <div *ngFor="let fieldComponent of getFieldComponents().controls; let i = index" [formGroupName]="i" | ||||
|                 class="field-component-row"> | ||||
|                 <div class="field-select-container"> | ||||
|                   <select class="field-select" formControlName="field"> | ||||
|                     <option value="">Select Field</option> | ||||
|                     <option *ngFor="let key of availableKeys" [value]="key">{{ key }}</option> | ||||
|                   </select> | ||||
|                 </div> | ||||
|                   <div class="clr-col-5"> | ||||
|                     <input type="text" formControlName="constant" placeholder="Or enter constant value" /> | ||||
|                 <div class="constant-input-container"> | ||||
|                   <input type="text" class="constant-input" formControlName="constant" placeholder="Or enter constant value" /> | ||||
|                 </div> | ||||
|                   <div class="clr-col-2"> | ||||
|                     <button type="button" class="btn btn-icon btn-danger" (click)="removeFieldComponent(i)"  | ||||
|                 <div class="remove-btn-container"> | ||||
|                   <button type="button" class="btn btn-icon btn-danger remove-field-btn" (click)="removeFieldComponent(i)" | ||||
|                     *ngIf="getFieldComponents().length > 1"> | ||||
|                     <clr-icon shape="trash"></clr-icon> | ||||
|                   </button> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|               <button type="button" class="btn btn-sm" (click)="addFieldComponent()"> | ||||
|             <button type="button" class="btn btn-sm add-field-btn" (click)="addFieldComponent()"> | ||||
|               <clr-icon shape="plus"></clr-icon> Add Field/Constant | ||||
|             </button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       </div> | ||||
|     </form> | ||||
| 
 | ||||
|     <div class="clr-row" style="margin-top: 20px;"> | ||||
|     <div class="clr-row created-fields-section"> | ||||
|       <div class="clr-col-12"> | ||||
|         <h4>Created Calculated Fields:</h4> | ||||
|         <table class="table"> | ||||
|         <h4 class="section-title"> | ||||
|           <clr-icon shape="list" class="section-icon"></clr-icon> | ||||
|           Created Calculated Fields | ||||
|         </h4> | ||||
|         <div class="table-container"> | ||||
|           <table class="table calculated-fields-table"> | ||||
|             <thead> | ||||
|               <tr> | ||||
|                 <th>Field Name</th> | ||||
| @ -595,18 +677,21 @@ | ||||
|             </thead> | ||||
|             <tbody> | ||||
|               <tr *ngFor="let field of calculatedFields"> | ||||
|               <td>{{ field.fieldName }}</td> | ||||
|               <td>{{ field.operation }}</td> | ||||
|               <td> | ||||
|                 <td class="field-name-cell">{{ field.fieldName }}</td> | ||||
|                 <td class="operation-cell">{{ field.operation }}</td> | ||||
|                 <td class="expression-cell"> | ||||
|                   <span *ngIf="field.operation === 'complex'">{{ field.complexEquation }}</span> | ||||
|                   <span *ngIf="field.operation !== 'complex'"> | ||||
|                     <span *ngFor="let component of field.fieldComponents; let last = last"> | ||||
|                       <span *ngIf="component.field && !component.isConstant">{{ component.field }}</span> | ||||
|                       <span *ngIf="component.isConstant">"{{ component.constant }}"</span> | ||||
|                       <span *ngIf="!component.field && component.constant">"{{ component.constant }}"</span> | ||||
|                       <span *ngIf="!last"> {{ getOperationSymbol(field.operation) }} </span> | ||||
|                     </span> | ||||
|                   </span> | ||||
|                 </td> | ||||
|               <td> | ||||
|                 <button class="btn btn-icon btn-danger" (click)="deleteCalculatedField(field.id)"> | ||||
|                 <td class="actions-cell"> | ||||
|                   <button class="btn btn-icon btn-danger delete-field-btn" (click)="deleteCalculatedField(field.id)"> | ||||
|                     <clr-icon shape="trash"></clr-icon> | ||||
|                   </button> | ||||
|                 </td> | ||||
| @ -616,6 +701,7 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="modal-footer"> | ||||
|     <button type="button" class="btn btn-outline" (click)="calculatedFieldModalOpen = false">Cancel</button> | ||||
|     <button type="button" class="btn btn-primary" (click)="addCalculatedField()">Add Field</button> | ||||
| @ -626,6 +712,26 @@ | ||||
|   </div> | ||||
| </clr-modal> | ||||
| 
 | ||||
| <!-- Constant Value Modal --> | ||||
| <clr-modal [(clrModalOpen)]="constantValueModalOpen" [clrModalSize]="'sm'" [clrModalStaticBackdrop]="true"> | ||||
|   <h3 class="modal-title">Define Constant Value</h3> | ||||
|   <div class="modal-body"> | ||||
|     <div class="clr-row"> | ||||
|       <div class="clr-col-12"> | ||||
|         <p>Enter a value for constant: <strong>{{ currentConstantName }}</strong></p> | ||||
|       </div> | ||||
|       <div class="clr-col-12"> | ||||
|         <label>Constant Value</label> | ||||
|         <input class="clr-input" type="text" [(ngModel)]="currentConstantValue" placeholder="Enter constant value" /> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="modal-footer"> | ||||
|     <button type="button" class="btn btn-outline" (click)="cancelConstantValue()">Cancel</button> | ||||
|     <button type="button" class="btn btn-primary" (click)="saveConstantValue()">Save</button> | ||||
|   </div> | ||||
| </clr-modal> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -1,85 +1,297 @@ | ||||
| //@import "../../../../assets/scss/var"; | ||||
| .s-info-bar { | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
|   justify-content: space-between; | ||||
|   button { | ||||
|     outline: none; | ||||
|   } | ||||
| } | ||||
| .delete,.heading{ | ||||
|   text-align: center; | ||||
|   color: red; | ||||
| } | ||||
| .entry-pg { | ||||
|   width: 750px; | ||||
| /* Calculated Fields Modal Styles */ | ||||
| 
 | ||||
| .calculated-section { | ||||
|   margin-bottom: 20px; | ||||
|   padding: 15px; | ||||
|   border-radius: 8px; | ||||
|   background-color: #f9f9f9; | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.05); | ||||
| } | ||||
| 
 | ||||
| .button1::after { | ||||
|   content: none; | ||||
| } | ||||
| .button1:hover::after { | ||||
|   content: "ADD ROWS"; | ||||
| } | ||||
| 
 | ||||
| .section { | ||||
|   background-color: #dddddd; | ||||
|   height: 40px; | ||||
| } | ||||
| 
 | ||||
| .section p { | ||||
|   //color: white; | ||||
|   padding: 10px; | ||||
|   font-size: 18px; | ||||
| } | ||||
| 
 | ||||
| .clr-input { | ||||
|   color: #212529; | ||||
|   border: 1px solid #ced4da; | ||||
|   border-radius: 0.25rem; | ||||
|   padding: 0.75rem 0.75rem; | ||||
|   margin-top: 3px; | ||||
|   width: 100%; | ||||
|   margin-bottom: 10px; | ||||
| } | ||||
| 
 | ||||
| .clr-file { | ||||
|   color: #212529; | ||||
|   border: 1px solid #ced4da; | ||||
|   border-radius: 0.25rem; | ||||
|   //padding: 0.6rem 0.75rem; | ||||
|   margin-top: 3px; | ||||
|   width: 100%; | ||||
|   margin-bottom: 10px; | ||||
| } | ||||
| 
 | ||||
| .center { | ||||
|   text-align: center; | ||||
| } | ||||
| select{ | ||||
|   width: 100%; | ||||
|   margin-top: 3px; | ||||
|   padding: 5px 5px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 4px; | ||||
| } | ||||
| input[type=text],[type=date],[type=number],textarea { | ||||
|   width: 100%; | ||||
|   padding: 15px 15px; | ||||
|   background-color:rgb(255, 255, 255); | ||||
|  // margin: 8px 0; | ||||
|   display: inline-block; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 4px; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| .error_mess { | ||||
|   color: red; | ||||
| } | ||||
| .universal-section-header { | ||||
|   margin: 24px 0 10px 0; | ||||
| .section-title { | ||||
|   color: #0072a0; | ||||
|   font-weight: 600; | ||||
|   color: #1a237e; | ||||
|   letter-spacing: 0.5px; | ||||
|   font-size: 1.25rem; | ||||
|   margin-bottom: 15px; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
| 
 | ||||
| .section-icon { | ||||
|   margin-right: 10px; | ||||
| } | ||||
| 
 | ||||
| .field-label { | ||||
|   display: block; | ||||
|   margin-bottom: 8px; | ||||
|   font-weight: 500; | ||||
|   color: #333; | ||||
| } | ||||
| 
 | ||||
| .field-input { | ||||
|   width: 100%; | ||||
|   padding: 10px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 4px; | ||||
|   font-size: 14px; | ||||
|   transition: border-color 0.3s; | ||||
| } | ||||
| 
 | ||||
| .field-input:focus { | ||||
|   border-color: #0072a0; | ||||
|   outline: none; | ||||
|   box-shadow: 0 0 0 2px rgba(0, 114, 160, 0.2); | ||||
| } | ||||
| 
 | ||||
| .field-container { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 8px; | ||||
|   margin-top: 10px; | ||||
| } | ||||
| 
 | ||||
| .field-tag { | ||||
|   display: inline-flex; | ||||
|   align-items: center; | ||||
|   background-color: #e3f2fd; | ||||
|   border: 1px solid #bbdefb; | ||||
|   border-radius: 20px; | ||||
|   padding: 6px 12px; | ||||
|   margin: 4px; | ||||
|   font-size: 13px; | ||||
|   font-family: monospace; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.2s; | ||||
| } | ||||
| 
 | ||||
| .field-tag:hover { | ||||
|   background-color: #bbdefb; | ||||
|   transform: translateY(-2px); | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
| } | ||||
| 
 | ||||
| .field-icon { | ||||
|   margin-right: 5px; | ||||
|   color: #1976d2; | ||||
| } | ||||
| 
 | ||||
| .equation-input { | ||||
|   width: 100%; | ||||
|   padding: 12px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 6px; | ||||
|   font-family: monospace; | ||||
|   font-size: 14px; | ||||
|   margin-bottom: 8px; | ||||
| } | ||||
| 
 | ||||
| .equation-hint { | ||||
|   display: block; | ||||
|   margin-bottom: 15px; | ||||
|   color: #666; | ||||
|   font-style: italic; | ||||
| } | ||||
| 
 | ||||
| .operators-container, | ||||
| .fields-container, | ||||
| .constants-container, | ||||
| .new-constant-container { | ||||
|   margin-bottom: 20px; | ||||
| } | ||||
| 
 | ||||
| .subsection-title { | ||||
|   color: #555; | ||||
|   font-weight: 500; | ||||
|   margin-bottom: 10px; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
| 
 | ||||
| .subsection-icon { | ||||
|   margin-right: 8px; | ||||
|   color: #0072a0; | ||||
| } | ||||
| 
 | ||||
| .operator-tags { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 6px; | ||||
| } | ||||
| 
 | ||||
| .operator-tag { | ||||
|   display: inline-flex; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   background-color: #0072a0; | ||||
|   color: white; | ||||
|   border: 1px solid #005a80; | ||||
|   border-radius: 4px; | ||||
|   padding: 6px 10px; | ||||
|   font-size: 14px; | ||||
|   font-family: monospace; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.2s; | ||||
|   min-width: 36px; | ||||
| } | ||||
| 
 | ||||
| .operator-tag:hover { | ||||
|   background-color: #005a80; | ||||
|   transform: scale(1.1); | ||||
| } | ||||
| 
 | ||||
| .field-tags { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 6px; | ||||
| } | ||||
| 
 | ||||
| .constant-tags { | ||||
|   display: flex; | ||||
|   flex-wrap: wrap; | ||||
|   gap: 6px; | ||||
| } | ||||
| 
 | ||||
| .constant-tag { | ||||
|   display: inline-flex; | ||||
|   align-items: center; | ||||
|   background-color: #4caf50; | ||||
|   color: white; | ||||
|   border: 1px solid #388e3c; | ||||
|   border-radius: 20px; | ||||
|   padding: 6px 12px; | ||||
|   margin: 4px; | ||||
|   font-size: 13px; | ||||
|   font-family: monospace; | ||||
|   cursor: pointer; | ||||
|   transition: all 0.2s; | ||||
| } | ||||
| 
 | ||||
| .constant-tag:hover { | ||||
|   background-color: #388e3c; | ||||
|   transform: translateY(-2px); | ||||
|   box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||
| } | ||||
| 
 | ||||
| .constant-icon { | ||||
|   margin-right: 5px; | ||||
| } | ||||
| 
 | ||||
| .add-constant-btn { | ||||
|   background-color: #ff9800; | ||||
|   border-color: #f57c00; | ||||
| } | ||||
| 
 | ||||
| .add-constant-btn:hover { | ||||
|   background-color: #f57c00; | ||||
| } | ||||
| 
 | ||||
| .field-components-container { | ||||
|   background-color: white; | ||||
|   border: 1px solid #e0e0e0; | ||||
|   border-radius: 6px; | ||||
|   padding: 15px; | ||||
| } | ||||
| 
 | ||||
| .field-component-row { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   margin-bottom: 10px; | ||||
|   gap: 10px; | ||||
| } | ||||
| 
 | ||||
| .field-select-container, | ||||
| .constant-input-container { | ||||
|   flex: 1; | ||||
| } | ||||
| 
 | ||||
| .field-select, | ||||
| .constant-input { | ||||
|   width: 100%; | ||||
|   padding: 8px; | ||||
|   border: 1px solid #ccc; | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .remove-field-btn { | ||||
|   padding: 6px; | ||||
| } | ||||
| 
 | ||||
| .add-field-btn { | ||||
|   margin-top: 10px; | ||||
|   background-color: #1976d2; | ||||
|   border-color: #1976d2; | ||||
|   color: white; | ||||
| } | ||||
| 
 | ||||
| .add-field-btn:hover { | ||||
|   background-color: #1565c0; | ||||
| } | ||||
| 
 | ||||
| .created-fields-section { | ||||
|   margin-top: 25px; | ||||
|   padding-top: 20px; | ||||
|   border-top: 1px solid #eee; | ||||
| } | ||||
| 
 | ||||
| .table-container { | ||||
|   overflow-x: auto; | ||||
| } | ||||
| 
 | ||||
| .calculated-fields-table { | ||||
|   width: 100%; | ||||
|   border-collapse: collapse; | ||||
|   box-shadow: 0 1px 3px rgba(0,0,0,0.1); | ||||
|   border-radius: 6px; | ||||
|   overflow: hidden; | ||||
| } | ||||
| 
 | ||||
| .calculated-fields-table th { | ||||
|   background-color: #f5f5f5; | ||||
|   padding: 12px 15px; | ||||
|   text-align: left; | ||||
|   font-weight: 600; | ||||
|   color: #333; | ||||
| } | ||||
| 
 | ||||
| .calculated-fields-table td { | ||||
|   padding: 12px 15px; | ||||
|   border-bottom: 1px solid #eee; | ||||
| } | ||||
| 
 | ||||
| .field-name-cell { | ||||
|   font-weight: 500; | ||||
|   color: #0072a0; | ||||
| } | ||||
| 
 | ||||
| .operation-cell { | ||||
|   font-family: monospace; | ||||
|   background-color: #e3f2fd; | ||||
|   border-radius: 4px; | ||||
|   padding: 4px 8px; | ||||
|   display: inline-block; | ||||
| } | ||||
| 
 | ||||
| .expression-cell { | ||||
|   font-family: monospace; | ||||
|   font-size: 13px; | ||||
| } | ||||
| 
 | ||||
| .actions-cell { | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| .delete-field-btn { | ||||
|   padding: 6px; | ||||
| } | ||||
| 
 | ||||
| /* Responsive adjustments */ | ||||
| @media (max-width: 768px) { | ||||
|   .field-component-row { | ||||
|     flex-direction: column; | ||||
|     align-items: stretch; | ||||
|   } | ||||
|    | ||||
|   .field-select-container, | ||||
|   .constant-input-container { | ||||
|     margin-bottom: 8px; | ||||
|   } | ||||
| } | ||||
| @ -70,6 +70,12 @@ export class Data_lakeComponent implements OnInit { | ||||
|   calculatedFields: any[] = []; | ||||
|   constantCounter = 1; // Persistent counter for unique constant names
 | ||||
| 
 | ||||
|   // New properties for constant value input
 | ||||
|   constantValueModalOpen = false; | ||||
|   currentConstantName = ''; | ||||
|   currentConstantValue = ''; | ||||
|   pendingEquationUpdate = ''; | ||||
|    | ||||
|   constructor( | ||||
|     private extensionService: ExtensionService, | ||||
|     private userInfoService: UserInfoService, | ||||
| @ -136,8 +142,16 @@ export class Data_lakeComponent implements OnInit { | ||||
|     this.calculatedFieldForm = this._fb.group({ | ||||
|       fieldName: [''], | ||||
|       operation: [''], | ||||
|       complexEquation: [''], // Add complex equation field
 | ||||
|       fieldComponents: this._fb.array([this.createFieldComponent()]) | ||||
|     }); | ||||
|      | ||||
|     // Add real-time validation for complex equation
 | ||||
|     this.calculatedFieldForm.get('complexEquation')?.valueChanges.subscribe(value => { | ||||
|       if (this.calculatedFieldForm.get('operation')?.value === 'complex' && value) { | ||||
|         this.analyzeComplexEquation(value); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|    | ||||
|   // Helper method to create a field component group
 | ||||
| @ -241,6 +255,7 @@ export class Data_lakeComponent implements OnInit { | ||||
|     this.calculatedFieldForm.reset({ | ||||
|       fieldName: '', | ||||
|       operation: '', | ||||
|       complexEquation: '', | ||||
|       fieldComponents: [{}] // Start with one empty field component
 | ||||
|     }); | ||||
|      | ||||
| @ -257,11 +272,73 @@ export class Data_lakeComponent implements OnInit { | ||||
|   addCalculatedField() { | ||||
|     const formData = this.calculatedFieldForm.value; | ||||
| 
 | ||||
|     if (!formData.fieldName || !formData.operation) { | ||||
|     if (!formData.fieldName || (!formData.operation && formData.operation !== 'complex')) { | ||||
|       this.toastr.error('Field name and operation are required'); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     // Handle complex equation separately
 | ||||
|     if (formData.operation === 'complex') { | ||||
|       if (!formData.complexEquation || formData.complexEquation.trim() === '') { | ||||
|         this.toastr.error('Complex equation is required'); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       // Validate complex equation format
 | ||||
|       if (!this.validateComplexEquation(formData.complexEquation)) { | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       // Extract constants used in the equation
 | ||||
|       const fieldRefs = this.extractFieldReferences(formData.complexEquation); | ||||
|       const equationConstants: any[] = []; | ||||
|        | ||||
|       for (const fieldRef of fieldRefs) { | ||||
|         // Check if it's a constant (constant_X format)
 | ||||
|         if (fieldRef.startsWith('constant_') && /^\d+$/.test(fieldRef.substring(9))) { | ||||
|           // Find the constant value from existing calculated fields
 | ||||
|           let constantValue = ''; | ||||
|           for (const field of this.calculatedFields) { | ||||
|             if (field.operation === 'constant' && field.fieldName === fieldRef) { | ||||
|               if (field.fieldComponents && field.fieldComponents.length > 0) { | ||||
|                 constantValue = field.fieldComponents[0].constant; | ||||
|                 break; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|            | ||||
|           if (constantValue) { | ||||
|             equationConstants.push({ | ||||
|               field: fieldRef, | ||||
|               constant: constantValue, | ||||
|               isConstant: true | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       // Create calculated field object for complex equation
 | ||||
|       const calculatedField = { | ||||
|         id: Date.now(), | ||||
|         fieldName: formData.fieldName, | ||||
|         operation: 'complex', | ||||
|         complexEquation: formData.complexEquation, | ||||
|         fieldComponents: equationConstants // Include constants used in the equation
 | ||||
|       }; | ||||
| 
 | ||||
|       this.calculatedFields.push(calculatedField); | ||||
|       this.toastr.success('Complex calculated field added successfully'); | ||||
| 
 | ||||
|       // Reset form but keep one empty field component
 | ||||
|       this.calculatedFieldForm.reset({ | ||||
|         fieldName: '', | ||||
|         operation: '', | ||||
|         complexEquation: '', | ||||
|         fieldComponents: [{}] | ||||
|       }); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     // Filter out empty field components
 | ||||
|     const validFieldComponents = formData.fieldComponents.filter(component =>  | ||||
|       component.field || component.constant | ||||
| @ -328,10 +405,187 @@ export class Data_lakeComponent implements OnInit { | ||||
|     this.calculatedFieldForm.reset({ | ||||
|       fieldName: '', | ||||
|       operation: '', | ||||
|       complexEquation: '', | ||||
|       fieldComponents: [{}] | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   // Validate complex equation format
 | ||||
|   validateComplexEquation(equation: string): boolean { | ||||
|     // Updated validation to include additional operators
 | ||||
|     const validPattern = /^[a-zA-Z0-9_+\-*/().\[\]{}^%>=<!&|\s]+$/; | ||||
|     if (!validPattern.test(equation)) { | ||||
|       this.toastr.error('Invalid complex equation format. Only alphanumeric characters, underscores, and operators (+, -, *, /, (, ), [, ], {, }, ^, %, =, >, <, !, &, |) are allowed.'); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     // Check for empty equation
 | ||||
|     if (!equation || equation.trim() === '') { | ||||
|       this.toastr.error('Complex equation cannot be empty'); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     // Extract all field/constant references from the equation
 | ||||
|     const fieldRefs = this.extractFieldReferences(equation); | ||||
|      | ||||
|     // Validate each reference
 | ||||
|     const invalidReferences: string[] = []; | ||||
|     for (const fieldRef of fieldRefs) { | ||||
|       // Skip if it's a direct numeric value
 | ||||
|       if (!isNaN(Number(fieldRef))) { | ||||
|         continue; | ||||
|       } | ||||
|        | ||||
|       // Check if it's a predefined constant (constant_X format)
 | ||||
|       if (fieldRef.startsWith('constant_') && /^\d+$/.test(fieldRef.substring(9))) { | ||||
|         // Check if this constant has been defined in previous calculated fields
 | ||||
|         let constantFound = false; | ||||
|         for (const field of this.calculatedFields) { | ||||
|           if (field.operation === 'constant' && field.fieldName === fieldRef) { | ||||
|             constantFound = true; | ||||
|             break; | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         if (!constantFound) { | ||||
|           invalidReferences.push(`Referenced constant '${fieldRef}' has not been defined`); | ||||
|         } | ||||
|         continue; | ||||
|       } | ||||
|        | ||||
|       // Check if field exists in available keys
 | ||||
|       if (!this.availableKeys.includes(fieldRef)) { | ||||
|         invalidReferences.push(`Field '${fieldRef}' not found in available keys`); | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     // Show all validation errors
 | ||||
|     if (invalidReferences.length > 0) { | ||||
|       invalidReferences.forEach(error => this.toastr.error(error)); | ||||
|       return false; | ||||
|     } | ||||
|      | ||||
|     // Try to parse the equation to check for basic syntax errors
 | ||||
|     try { | ||||
|       this.parseEquation(equation); | ||||
|     } catch (error) { | ||||
|       this.toastr.error(`Invalid equation syntax: ${error.message}`); | ||||
|       return false; | ||||
|     } | ||||
|      | ||||
|     // Additional validation for complex expressions
 | ||||
|     this.analyzeComplexEquation(equation); | ||||
|      | ||||
|     return true; | ||||
|   } | ||||
|    | ||||
|   // Analyze complex equation and provide warnings
 | ||||
|   analyzeComplexEquation(equation: string): void { | ||||
|     // Check for potentially problematic patterns
 | ||||
|     if (/[+\-*/]{3,}/.test(equation)) { | ||||
|       this.toastr.warning('Equation contains multiple consecutive operators which may cause unexpected results'); | ||||
|     } | ||||
|      | ||||
|     // Check for unbalanced expressions
 | ||||
|     const operators = equation.match(/[+\-*/]/g) || []; | ||||
|     const operands = equation.match(/[a-zA-Z0-9_]+/g) || []; | ||||
|      | ||||
|     if (operators.length > 0 && operands.length === 0) { | ||||
|       this.toastr.warning('Equation contains operators but no operands (fields or constants)'); | ||||
|     } | ||||
|      | ||||
|     // Check for division by zero patterns
 | ||||
|     if (/\/\s*0(?!\d)/.test(equation)) { | ||||
|       this.toastr.warning('Equation may contain division by zero'); | ||||
|     } | ||||
|      | ||||
|     // Check for excessive nesting
 | ||||
|     let parenDepth = 0; | ||||
|     let maxParenDepth = 0; | ||||
|     for (const char of equation) { | ||||
|       if (char === '(') { | ||||
|         parenDepth++; | ||||
|         maxParenDepth = Math.max(maxParenDepth, parenDepth); | ||||
|       } else if (char === ')') { | ||||
|         parenDepth--; | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     if (maxParenDepth > 10) { | ||||
|       this.toastr.warning('Equation has deep nesting which may affect performance'); | ||||
|     } | ||||
|      | ||||
|     // Check for repeated field usage
 | ||||
|     const fieldRefs = this.extractFieldReferences(equation); | ||||
|     const fieldCounts: {[key: string]: number} = {}; | ||||
|     fieldRefs.forEach(field => { | ||||
|       if (!isNaN(Number(field))) return; // Skip numbers
 | ||||
|       fieldCounts[field] = (fieldCounts[field] || 0) + 1; | ||||
|     }); | ||||
|      | ||||
|     Object.keys(fieldCounts).forEach(field => { | ||||
|       if (fieldCounts[field] > 3) { | ||||
|         this.toastr.warning(`Field '${field}' is used ${fieldCounts[field]} times in the equation`); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|    | ||||
|   // Extract field references from equation
 | ||||
|   extractFieldReferences(equation: string): string[] { | ||||
|     // Remove all operators and parentheses to isolate field names
 | ||||
|     const cleanEquation = equation.replace(/[+\-*/()[\]{}^%>=<!&|\s]+/g, ' '); | ||||
|     // Split by whitespace and filter out empty strings and numbers
 | ||||
|     return cleanEquation.split(/\s+/).filter(token => token.length > 0); | ||||
|   } | ||||
|    | ||||
|   // Simple equation parser to check syntax (basic implementation)
 | ||||
|   parseEquation(equation: string): void { | ||||
|     // Remove spaces
 | ||||
|     const cleanEquation = equation.replace(/\s/g, ''); | ||||
|      | ||||
|     // Check for balanced parentheses
 | ||||
|     let parenCount = 0; | ||||
|     for (const char of cleanEquation) { | ||||
|       if (char === '(') parenCount++; | ||||
|       if (char === ')') parenCount--; | ||||
|       if (parenCount < 0) throw new Error('Mismatched parentheses'); | ||||
|     } | ||||
|     if (parenCount !== 0) throw new Error('Mismatched parentheses'); | ||||
|      | ||||
|     // Check for balanced square brackets
 | ||||
|     let bracketCount = 0; | ||||
|     for (const char of cleanEquation) { | ||||
|       if (char === '[') bracketCount++; | ||||
|       if (char === ']') bracketCount--; | ||||
|       if (bracketCount < 0) throw new Error('Mismatched square brackets'); | ||||
|     } | ||||
|     if (bracketCount !== 0) throw new Error('Mismatched square brackets'); | ||||
|      | ||||
|     // Check for balanced curly braces
 | ||||
|     let braceCount = 0; | ||||
|     for (const char of cleanEquation) { | ||||
|       if (char === '{') braceCount++; | ||||
|       if (char === '}') braceCount--; | ||||
|       if (braceCount < 0) throw new Error('Mismatched curly braces'); | ||||
|     } | ||||
|     if (braceCount !== 0) throw new Error('Mismatched curly braces'); | ||||
|      | ||||
|     // Check for invalid sequences
 | ||||
|     if (/[+\-*/]{2,}/.test(cleanEquation)) { | ||||
|       throw new Error('Invalid operator sequence'); | ||||
|     } | ||||
|      | ||||
|     // Check that equation doesn't start or end with an operator (except minus for negative numbers)
 | ||||
|     if (/^[+*/^%=<>|&]/.test(cleanEquation) || /[+\-*/^%=<>|&]$/.test(cleanEquation)) { | ||||
|       throw new Error('Equation cannot start or end with an operator'); | ||||
|     } | ||||
|      | ||||
|     // Check for empty parentheses
 | ||||
|     if (/\(\)/.test(cleanEquation)) { | ||||
|       throw new Error('Empty parentheses are not allowed'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // Delete calculated field
 | ||||
|   deleteCalculatedField(id: number) { | ||||
|     this.calculatedFields = this.calculatedFields.filter(field => field.id !== id); | ||||
| @ -562,4 +816,156 @@ export class Data_lakeComponent implements OnInit { | ||||
|       } | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   // Add operator to complex equation
 | ||||
|   addOperatorToEquation(operator: string) { | ||||
|     const equationControl = this.calculatedFieldForm.get('complexEquation'); | ||||
|     if (equationControl) { | ||||
|       const currentValue = equationControl.value || ''; | ||||
|       equationControl.setValue(currentValue + operator); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   // Add field or constant to complex equation
 | ||||
|   addFieldToEquation(field: string) { | ||||
|     const equationControl = this.calculatedFieldForm.get('complexEquation'); | ||||
|     if (equationControl) { | ||||
|       const currentValue = equationControl.value || ''; | ||||
|       // Add space before and after if needed
 | ||||
|       const newValue = currentValue ? `${currentValue} ${field} ` : `${field} `; | ||||
|       equationControl.setValue(newValue); | ||||
|        | ||||
|       // Validate after adding field
 | ||||
|       if (this.calculatedFieldForm.get('operation')?.value === 'complex') { | ||||
|         this.analyzeComplexEquation(equationControl.value); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   // Get all defined constants from existing calculated fields
 | ||||
|   getDefinedConstants(): string[] { | ||||
|     const constants: string[] = []; | ||||
|     this.calculatedFields.forEach(field => { | ||||
|       // Check for actual constant operations
 | ||||
|       if (field.operation === 'constant' && field.fieldName) { | ||||
|         constants.push(field.fieldName); | ||||
|       } | ||||
|     }); | ||||
|     return constants; | ||||
|   } | ||||
|    | ||||
|   // Add a new constant to the equation
 | ||||
|   addNewConstantToEquation() { | ||||
|     // Generate a new constant name
 | ||||
|     this.currentConstantName = `constant_${this.constantCounter}`; | ||||
|      | ||||
|     // Open the constant value modal
 | ||||
|     this.currentConstantValue = ''; | ||||
|     this.constantValueModalOpen = true; | ||||
|   } | ||||
|    | ||||
|   // Save constant value and update equation
 | ||||
|   saveConstantValue() { | ||||
|     if (this.currentConstantValue === '') { | ||||
|       this.toastr.error('Constant value is required'); | ||||
|       return; | ||||
|     } | ||||
|      | ||||
|     // Validate constant value based on operation type
 | ||||
|     const operation = this.calculatedFieldForm.get('operation')?.value; | ||||
|     if (operation !== 'concat' && operation !== 'complex') { | ||||
|       const numericValue = Number(this.currentConstantValue); | ||||
|       if (isNaN(numericValue)) { | ||||
|         this.toastr.error('Constant values must be numeric for this operation'); | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     // For non-complex operations, add to field components directly
 | ||||
|     if (operation && operation !== 'complex') { | ||||
|       const fieldComponents = this.getFieldComponents(); | ||||
|       fieldComponents.push(this._fb.group({ | ||||
|         field: [this.currentConstantName], | ||||
|         constant: [this.currentConstantValue] | ||||
|       })); | ||||
|     } else if (operation === 'complex') { | ||||
|       // For complex equations, add to the equation and create a constant field
 | ||||
|       const equationControl = this.calculatedFieldForm.get('complexEquation'); | ||||
|       if (equationControl) { | ||||
|         const currentValue = equationControl.value || ''; | ||||
|         const newValue = currentValue ? `${currentValue} ${this.currentConstantName} ` : `${this.currentConstantName} `; | ||||
|         equationControl.setValue(newValue); | ||||
|       } | ||||
|        | ||||
|       // Also create a constant field that can be referenced
 | ||||
|       const constantField = { | ||||
|         id: Date.now(), | ||||
|         fieldName: this.currentConstantName, | ||||
|         operation: 'constant', | ||||
|         fieldComponents: [{ | ||||
|           field: this.currentConstantName, | ||||
|           constant: this.currentConstantValue, | ||||
|           isConstant: true | ||||
|         }] | ||||
|       }; | ||||
|        | ||||
|       this.calculatedFields.push(constantField); | ||||
|     } else { | ||||
|       // If no operation is selected, just create the constant field
 | ||||
|       const constantField = { | ||||
|         id: Date.now(), | ||||
|         fieldName: this.currentConstantName, | ||||
|         operation: 'constant', | ||||
|         fieldComponents: [{ | ||||
|           field: this.currentConstantName, | ||||
|           constant: this.currentConstantValue, | ||||
|           isConstant: true | ||||
|         }] | ||||
|       }; | ||||
|        | ||||
|       this.calculatedFields.push(constantField); | ||||
|     } | ||||
|      | ||||
|     // Increment the counter for next constant
 | ||||
|     this.constantCounter++; | ||||
|      | ||||
|     // Close modal and show success message
 | ||||
|     this.constantValueModalOpen = false; | ||||
|     this.toastr.success(`Constant ${this.currentConstantName} added with value ${this.currentConstantValue}`); | ||||
|   } | ||||
|    | ||||
|   // Cancel constant value input
 | ||||
|   cancelConstantValue() { | ||||
|     this.constantValueModalOpen = false; | ||||
|     this.currentConstantName = ''; | ||||
|     this.currentConstantValue = ''; | ||||
|   } | ||||
|    | ||||
|   // Test method to verify constant validation
 | ||||
|   testConstantFunctionality() { | ||||
|     // Clear existing calculated fields for testing
 | ||||
|     this.calculatedFields = []; | ||||
|      | ||||
|     // Add a test constant
 | ||||
|     const testConstant = { | ||||
|       id: Date.now(), | ||||
|       fieldName: 'constant_1', | ||||
|       operation: 'constant', | ||||
|       fieldComponents: [{ | ||||
|         field: 'constant_1', | ||||
|         constant: '15', | ||||
|         isConstant: true | ||||
|       }] | ||||
|     }; | ||||
|      | ||||
|     this.calculatedFields.push(testConstant); | ||||
|      | ||||
|     // Test validation
 | ||||
|     const testEquation = 'pincode + mobno * constant_1'; | ||||
|     const isValid = this.validateComplexEquation(testEquation); | ||||
|      | ||||
|     console.log('Test equation:', testEquation); | ||||
|     console.log('Validation result:', isValid); | ||||
|     console.log('Defined constants:', this.getDefinedConstants()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
|     <div class="clr-col-4" style="text-align: right;"> | ||||
| 
 | ||||
|       <button id="add" class="btn btn-primary" *ngIf="mcreate == 'true'"  (click)="goToAdd()"> | ||||
|       <button id="add" class="btn btn-primary"  (click)="goToAdd()"> | ||||
|         <clr-icon shape="plus"></clr-icon>ADD | ||||
|       </button> | ||||
| 
 | ||||
|  | ||||
| @ -31,12 +31,12 @@ export class SureconnectComponent implements OnInit { | ||||
|   ngOnInit(): void { | ||||
|     this.showdata = this.menuGroupService.getdata(); | ||||
|     console.log(this.showdata); | ||||
|     this.mcreate = this.showdata.mcreate; | ||||
|     console.log(this.mcreate); | ||||
|     this.mdelete = this.showdata.mdelete | ||||
|     console.log(this.mdelete); | ||||
|     this.medit = this.showdata.medit | ||||
|     console.log(this.medit); | ||||
|     // this.mcreate = this.showdata.mcreate;
 | ||||
|     // console.log(this.mcreate);
 | ||||
|     // this.mdelete = this.showdata.mdelete
 | ||||
|     // console.log(this.mdelete);
 | ||||
|     // this.medit = this.showdata.medit
 | ||||
|     // console.log(this.medit);
 | ||||
|     this.getall(); | ||||
|   } | ||||
|   getall() { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user