novo-elements 12.0.1-next.2 → 12.1.0-next.1

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.
@@ -312,6 +312,7 @@ declare class ConditionBuilderComponent implements OnInit, OnChanges, AfterConte
312
312
  groupIndex: number;
313
313
  addressConfig: AddressCriteriaConfig;
314
314
  dateConfig: DateCriteriaConfig;
315
+ allowEmptyField: boolean;
315
316
  hideOperator: i0.InputSignal<boolean>;
316
317
  conditionType: i0.InputSignal<unknown>;
317
318
  inputConfig: i0.InputSignal<QueryBuilderConfig>;
@@ -343,15 +344,32 @@ declare class ConditionBuilderComponent implements OnInit, OnChanges, AfterConte
343
344
  */
344
345
  changeFieldOptions(fieldConfig: FieldConfig<BaseFieldDef>): void;
345
346
  /**
346
- * Resets the input and operator view containers, regenerates the field templates,
347
- * and marks the component for change detection.
347
+ * Resets the input and operator view containers and marks the component for change detection.
348
348
  *
349
349
  * Use this method after updating form controls to reinitialize the input and
350
350
  * operator fields so that the view reflects the latest form control changes.
351
351
  *
352
+ * @param recreateTemplates - If true (default), regenerates the field templates.
353
+ * If false, only clears the outlets without recreating templates.
352
354
  * @returns void
353
355
  */
354
- resetInputAndOperator(): void;
356
+ resetInputAndOperator(recreateTemplates?: boolean): void;
357
+ /**
358
+ * Clears the entire condition (field, operator, value) and resets the condition builder UI.
359
+ *
360
+ * This method performs a complete reset of the condition builder:
361
+ * - Clears all form values (field, operator, value, supportingValue)
362
+ * - Allows empty field selection (prevents auto-restoration to default)
363
+ * - Resets the field search term
364
+ * - Clears internal state (_lastContext) to force re-detection of field changes
365
+ * - Updates field selection and clears UI outlets
366
+ *
367
+ * Use this method when you need to completely clear a condition and start fresh,
368
+ * such as when toggling a filter off or resetting a form group.
369
+ *
370
+ * @returns void
371
+ */
372
+ clearCondition(): void;
355
373
  getField(): BaseFieldDef;
356
374
  getDefaultField(): string;
357
375
  updateFieldSelection(): void;
@@ -362,7 +380,7 @@ declare class ConditionBuilderComponent implements OnInit, OnChanges, AfterConte
362
380
  private createFieldOperators;
363
381
  private createFieldInput;
364
382
  static ɵfac: i0.ɵɵFactoryDeclaration<ConditionBuilderComponent, never>;
365
- static ɵcmp: i0.ɵɵComponentDeclaration<ConditionBuilderComponent, "novo-condition-builder", never, { "label": { "alias": "label"; "required": false; }; "scope": { "alias": "scope"; "required": false; }; "andIndex": { "alias": "andIndex"; "required": false; }; "groupIndex": { "alias": "groupIndex"; "required": false; }; "addressConfig": { "alias": "addressConfig"; "required": false; }; "dateConfig": { "alias": "dateConfig"; "required": false; }; "hideOperator": { "alias": "hideOperator"; "required": false; "isSignal": true; }; "conditionType": { "alias": "conditionType"; "required": false; "isSignal": true; }; "inputConfig": { "alias": "config"; "required": false; "isSignal": true; }; "inputEditTypeFn": { "alias": "editTypeFn"; "required": false; "isSignal": true; }; }, {}, never, ["*"], false, never>;
383
+ static ɵcmp: i0.ɵɵComponentDeclaration<ConditionBuilderComponent, "novo-condition-builder", never, { "label": { "alias": "label"; "required": false; }; "scope": { "alias": "scope"; "required": false; }; "andIndex": { "alias": "andIndex"; "required": false; }; "groupIndex": { "alias": "groupIndex"; "required": false; }; "addressConfig": { "alias": "addressConfig"; "required": false; }; "dateConfig": { "alias": "dateConfig"; "required": false; }; "allowEmptyField": { "alias": "allowEmptyField"; "required": false; }; "hideOperator": { "alias": "hideOperator"; "required": false; "isSignal": true; }; "conditionType": { "alias": "conditionType"; "required": false; "isSignal": true; }; "inputConfig": { "alias": "config"; "required": false; "isSignal": true; }; "inputEditTypeFn": { "alias": "editTypeFn"; "required": false; "isSignal": true; }; }, {}, never, ["*"], false, never>;
366
384
  }
367
385
 
368
386
  declare abstract class AbstractConditionFieldDef implements OnDestroy, OnInit, AfterViewInit {
@@ -6,7 +6,7 @@ import * as i1 from 'novo-elements/services';
6
6
  import { NovoLabelService } from 'novo-elements/services';
7
7
  import { Subject, Subscription, merge, interval } from 'rxjs';
8
8
  import { debounceTime, distinctUntilChanged, takeUntil, startWith, filter, debounce } from 'rxjs/operators';
9
- import { Helpers } from 'novo-elements/utils';
9
+ import { Helpers, BooleanInput } from 'novo-elements/utils';
10
10
  import * as i2 from '@angular/common';
11
11
  import { CommonModule } from '@angular/common';
12
12
  import * as i5 from 'novo-elements/elements/common';
@@ -1347,12 +1347,12 @@ class NovoDefaultPickerConditionDef extends AbstractConditionFieldDef {
1347
1347
  <novo-select-search #filterInput allowDeselectDuringFilter></novo-select-search>
1348
1348
  </novo-option>
1349
1349
  <!-- What about optionUrl/optionType -->
1350
- @for (option of meta?.options; track optionTracker) {
1350
+ @for (option of meta?.options; track optionTracker(option)) {
1351
1351
  <novo-option [hidden]="hideOption(option, filterInput?.value)" [value]="option.value" [attr.data-automation-value]="option.label">
1352
1352
  {{ option.label}}
1353
1353
  </novo-option>
1354
1354
  }
1355
- @for (option of customOptions(meta?.options, select); track optionTracker) {
1355
+ @for (option of customOptions(meta?.options, select); track optionTracker(option)) {
1356
1356
  <novo-option [hidden]="hideOption(option, filterInput?.value)" [value]="option.value" [attr.data-automation-value]="option.label">
1357
1357
  {{ option.label}}
1358
1358
  </novo-option>
@@ -1394,12 +1394,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1394
1394
  <novo-select-search #filterInput allowDeselectDuringFilter></novo-select-search>
1395
1395
  </novo-option>
1396
1396
  <!-- What about optionUrl/optionType -->
1397
- @for (option of meta?.options; track optionTracker) {
1397
+ @for (option of meta?.options; track optionTracker(option)) {
1398
1398
  <novo-option [hidden]="hideOption(option, filterInput?.value)" [value]="option.value" [attr.data-automation-value]="option.label">
1399
1399
  {{ option.label}}
1400
1400
  </novo-option>
1401
1401
  }
1402
- @for (option of customOptions(meta?.options, select); track optionTracker) {
1402
+ @for (option of customOptions(meta?.options, select); track optionTracker(option)) {
1403
1403
  <novo-option [hidden]="hideOption(option, filterInput?.value)" [value]="option.value" [attr.data-automation-value]="option.label">
1404
1404
  {{ option.label}}
1405
1405
  </novo-option>
@@ -1438,6 +1438,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1438
1438
  type: Input
1439
1439
  }] } });
1440
1440
 
1441
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
1442
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1443
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1444
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1445
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1446
+ };
1447
+ var __metadata = (this && this.__metadata) || function (k, v) {
1448
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1449
+ };
1441
1450
  /**
1442
1451
  * Provides a handle for the table to grab the view container's ng-container to insert data rows.
1443
1452
  * @docs-private
@@ -1482,6 +1491,7 @@ class ConditionBuilderComponent {
1482
1491
  this.cdr = cdr;
1483
1492
  this.queryBuilderService = queryBuilderService;
1484
1493
  this.controlContainer = controlContainer;
1494
+ this.allowEmptyField = false;
1485
1495
  this.hideOperator = input(true, ...(ngDevMode ? [{ debugName: "hideOperator" }] : []));
1486
1496
  this.conditionType = input(...(ngDevMode ? [undefined, { debugName: "conditionType" }] : []));
1487
1497
  // This component can either be directly hosted as a host to a condition, or it can be part of a condition group within a criteria builder.
@@ -1568,20 +1578,52 @@ class ConditionBuilderComponent {
1568
1578
  this.results$ = Promise.resolve(this.fieldConfig.options);
1569
1579
  }
1570
1580
  /**
1571
- * Resets the input and operator view containers, regenerates the field templates,
1572
- * and marks the component for change detection.
1581
+ * Resets the input and operator view containers and marks the component for change detection.
1573
1582
  *
1574
1583
  * Use this method after updating form controls to reinitialize the input and
1575
1584
  * operator fields so that the view reflects the latest form control changes.
1576
1585
  *
1586
+ * @param recreateTemplates - If true (default), regenerates the field templates.
1587
+ * If false, only clears the outlets without recreating templates.
1577
1588
  * @returns void
1578
1589
  */
1579
- resetInputAndOperator() {
1590
+ resetInputAndOperator(recreateTemplates = true) {
1580
1591
  this._inputOutlet.viewContainer.clear();
1581
1592
  this._operatorOutlet.viewContainer.clear();
1582
- this.createFieldTemplates();
1593
+ if (recreateTemplates) {
1594
+ this.createFieldTemplates();
1595
+ }
1583
1596
  this.cdr.markForCheck();
1584
1597
  }
1598
+ /**
1599
+ * Clears the entire condition (field, operator, value) and resets the condition builder UI.
1600
+ *
1601
+ * This method performs a complete reset of the condition builder:
1602
+ * - Clears all form values (field, operator, value, supportingValue)
1603
+ * - Allows empty field selection (prevents auto-restoration to default)
1604
+ * - Resets the field search term
1605
+ * - Clears internal state (_lastContext) to force re-detection of field changes
1606
+ * - Updates field selection and clears UI outlets
1607
+ *
1608
+ * Use this method when you need to completely clear a condition and start fresh,
1609
+ * such as when toggling a filter off or resetting a form group.
1610
+ *
1611
+ * @returns void
1612
+ */
1613
+ clearCondition() {
1614
+ // Clear all form values
1615
+ this.parentForm?.get('field')?.setValue(null);
1616
+ this.parentForm?.get('operator')?.setValue(null);
1617
+ this.parentForm?.get('value')?.setValue(null);
1618
+ this.parentForm?.get('supportingValue')?.setValue(null);
1619
+ // Reset the field search term
1620
+ this.searchTerm?.setValue('');
1621
+ // Reset internal state so updateFieldSelection detects the change
1622
+ this._lastContext = {};
1623
+ // Update field selection and clear UI
1624
+ this.updateFieldSelection();
1625
+ this.resetInputAndOperator(false);
1626
+ }
1585
1627
  getField() {
1586
1628
  const field = this.parentForm?.value?.field;
1587
1629
  if (!field) {
@@ -1599,7 +1641,9 @@ class ConditionBuilderComponent {
1599
1641
  updateFieldSelection() {
1600
1642
  const fieldConf = this.getField();
1601
1643
  if (!fieldConf) {
1602
- this.parentForm.get('field').setValue(this.getDefaultField());
1644
+ if (!this.allowEmptyField) {
1645
+ this.parentForm.get('field').setValue(this.getDefaultField());
1646
+ }
1603
1647
  return;
1604
1648
  }
1605
1649
  else {
@@ -1651,7 +1695,7 @@ class ConditionBuilderComponent {
1651
1695
  }
1652
1696
  createFieldTemplates() {
1653
1697
  const definition = this.findDefinitionForField(this.getField());
1654
- if (!this.parentForm.get('operator').value) {
1698
+ if (!this.parentForm.get('operator').value && definition) {
1655
1699
  this.parentForm.get('operator').setValue(definition.defaultOperator);
1656
1700
  }
1657
1701
  this.createFieldOperators(definition);
@@ -1674,7 +1718,7 @@ class ConditionBuilderComponent {
1674
1718
  this.cdr.markForCheck();
1675
1719
  }
1676
1720
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConditionBuilderComponent, deps: [{ token: i1.NovoLabelService }, { token: i0.ChangeDetectorRef }, { token: QueryBuilderService }, { token: i3.ControlContainer }], target: i0.ɵɵFactoryTarget.Component }); }
1677
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.17", type: ConditionBuilderComponent, isStandalone: false, selector: "novo-condition-builder", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, scope: { classPropertyName: "scope", publicName: "scope", isSignal: false, isRequired: false, transformFunction: null }, andIndex: { classPropertyName: "andIndex", publicName: "andIndex", isSignal: false, isRequired: false, transformFunction: null }, groupIndex: { classPropertyName: "groupIndex", publicName: "groupIndex", isSignal: false, isRequired: false, transformFunction: null }, addressConfig: { classPropertyName: "addressConfig", publicName: "addressConfig", isSignal: false, isRequired: false, transformFunction: null }, dateConfig: { classPropertyName: "dateConfig", publicName: "dateConfig", isSignal: false, isRequired: false, transformFunction: null }, hideOperator: { classPropertyName: "hideOperator", publicName: "hideOperator", isSignal: true, isRequired: false, transformFunction: null }, conditionType: { classPropertyName: "conditionType", publicName: "conditionType", isSignal: true, isRequired: false, transformFunction: null }, inputConfig: { classPropertyName: "inputConfig", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, inputEditTypeFn: { classPropertyName: "inputEditTypeFn", publicName: "editTypeFn", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.condition-host": "this.isConditionHost" } }, providers: [{ provide: NOVO_CONDITION_BUILDER, useExisting: ConditionBuilderComponent },
1721
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.17", type: ConditionBuilderComponent, isStandalone: false, selector: "novo-condition-builder", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, scope: { classPropertyName: "scope", publicName: "scope", isSignal: false, isRequired: false, transformFunction: null }, andIndex: { classPropertyName: "andIndex", publicName: "andIndex", isSignal: false, isRequired: false, transformFunction: null }, groupIndex: { classPropertyName: "groupIndex", publicName: "groupIndex", isSignal: false, isRequired: false, transformFunction: null }, addressConfig: { classPropertyName: "addressConfig", publicName: "addressConfig", isSignal: false, isRequired: false, transformFunction: null }, dateConfig: { classPropertyName: "dateConfig", publicName: "dateConfig", isSignal: false, isRequired: false, transformFunction: null }, allowEmptyField: { classPropertyName: "allowEmptyField", publicName: "allowEmptyField", isSignal: false, isRequired: false, transformFunction: null }, hideOperator: { classPropertyName: "hideOperator", publicName: "hideOperator", isSignal: true, isRequired: false, transformFunction: null }, conditionType: { classPropertyName: "conditionType", publicName: "conditionType", isSignal: true, isRequired: false, transformFunction: null }, inputConfig: { classPropertyName: "inputConfig", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, inputEditTypeFn: { classPropertyName: "inputEditTypeFn", publicName: "editTypeFn", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.condition-host": "this.isConditionHost" } }, providers: [{ provide: NOVO_CONDITION_BUILDER, useExisting: ConditionBuilderComponent },
1678
1722
  {
1679
1723
  provide: QueryBuilderService,
1680
1724
  deps: [NovoLabelService, [new SkipSelf(), new Optional(), QueryBuilderService]],
@@ -1687,6 +1731,10 @@ class ConditionBuilderComponent {
1687
1731
  },
1688
1732
  ], viewQueries: [{ propertyName: "_operatorOutlet", first: true, predicate: ConditionOperatorOutlet, descendants: true, static: true }, { propertyName: "_inputOutlet", first: true, predicate: ConditionInputOutlet, descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"parentForm\">\n <novo-grid gap=\"1rem\" [columns]=\"gridColumns()\" align=\"end\">\n <novo-field class=\"condition-field\" *ngIf=\"!staticFieldSelection()\">\n <novo-select\n [placeholder]=\"labels.chooseAField\"\n formControlName=\"field\"\n (onSelect)=\"updateFieldSelection()\"\n overlayWidth=\"24rem\"\n overlayHeight=\"20rem\"\n [displayWith]=\"fieldDisplayWith\"\n [style.minWidth.px]=\"160\"\n [style.maxWidth.px]=\"(hideOperator() || isConditionHost) ? 200 : 160\"\n [displayIcon]=\"displayIcon\">\n <novo-optgroup class=\"filter-search-results\">\n <novo-option>\n <novo-select-search [formControl]=\"searchTerm\" [clearSearchInput]=\"false\"></novo-select-search>\n </novo-option>\n <ng-container *ngIf=\"results$ | async as results; else loading\">\n <ng-container *ngIf=\"results.length\">\n <novo-option *ngFor=\"let field of results\" value=\"{{ field.name }}\"\n [attr.data-automation-id]=\"field.name\">\n {{ field.label || field.name }}\n </novo-option>\n </ng-container>\n </ng-container>\n </novo-optgroup>\n </novo-select>\n </novo-field>\n\n <div class=\"condition-operator\">\n <ng-container conditionOperatorOutlet></ng-container>\n </div>\n\n <div class=\"condition-input\">\n <ng-container conditionInputOutlet></ng-container>\n </div>\n </novo-grid>\n <ng-content></ng-content>\n</form>\n\n<novo-condition-templates *ngIf=\"isConditionHost\" [addressConfig]=\"addressConfig\" [dateConfig]=\"dateConfig\"/>\n\n<!-- LOADING TEMPLATE -->\n<ng-template #loading>\n <novo-loading></novo-loading>\n</ng-template>\n", styles: [":host{position:relative;display:block;width:100%}:host.condition-host{padding:var(--spacing-md);margin-bottom:1rem}:host .condition-field{grid-template-columns:minmax(fit-content,1fr);width:100%;width:-webkit-fill-available}:host .condition-operator::ng-deep .novo-select{min-width:13rem}:host .condition-input::ng-deep novo-field.novo-field-layout-vertical{grid-template-columns:minmax(fit-content,1fr);width:-webkit-fill-available}:host .condition-input::ng-deep novo-field.novo-field-layout-vertical .novo-input-element{width:100%}:host .condition-input::ng-deep novo-field{width:fit-content}:host .condition-input::ng-deep novo-field.address-radius{width:100px;min-width:100px;max-width:100px;margin-right:1rem}:host .condition-input::ng-deep novo-field.address-radius novo-select{min-width:70px}:host .condition-input::ng-deep novo-field.address-location .novo-field-suffix{align-self:flex-end}:host .condition-input::ng-deep .novo-field-infix{white-space:nowrap;overflow:hidden}:host .condition-input::ng-deep novo-chip-list{flex-grow:1}:host .condition-input::ng-deep novo-chip-list novo-chip{max-width:min(33rem,100% - 9px)}:host .condition-input::ng-deep novo-chips{border-bottom:none!important}:host .condition-input::ng-deep novo-chips input{padding-left:0!important}:host .condition-input::ng-deep novo-radio-group{padding:0!important}:host .and-or-filter-button{box-sizing:border-box;background:#fff;border:1px solid #ddd;color:#5691f5;display:inline-block;position:relative;cursor:pointer;margin:.4rem auto;align-items:center;text-align:center;-webkit-user-select:none;user-select:none;outline:none;white-space:nowrap;text-transform:uppercase;overflow:hidden;transition:box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i5.GapDirective, selector: "[gap]", inputs: ["gap"] }, { kind: "component", type: i5$1.NovoSelectElement, selector: "novo-select", inputs: ["disabled", "required", "tabIndex", "id", "name", "placeholder", "readonly", "headerConfig", "position", "overlayWidth", "overlayHeight", "displayIcon", "displayWith", "compareWith", "hideLegacyOptions", "value", "multiple", "options"], outputs: ["onSelect", "selectionChange", "valueChange", "openedChange", "opened", "closed"] }, { kind: "component", type: i6.NovoFieldElement, selector: "novo-field", inputs: ["layout", "appearance", "customOverlayOrigin", "width"], outputs: ["valueChanges", "stateChanges"] }, { kind: "component", type: i5.NovoOption, selector: "novo-option", inputs: ["selected", "keepOpen", "novoInert", "value", "disabled"], exportAs: ["novoOption"] }, { kind: "component", type: i5.NovoOptgroup, selector: "novo-optgroup", inputs: ["disabled", "label"], exportAs: ["novoOptgroup"] }, { kind: "component", type: i8.NovoGridElement, selector: "novo-grid", inputs: ["direction", "align", "justify", "columns"] }, { kind: "component", type: i9$3.NovoLoadingElement, selector: "novo-loading", inputs: ["theme", "color", "size"] }, { kind: "component", type: i9$2.NovoSelectSearchComponent, selector: "novo-select-search", inputs: ["name", "placeholderLabel", "type", "noEntriesFoundLabel", "indexAndLengthScreenReaderText", "clearSearchInput", "searching", "disableInitialFocus", "enableClearOnEscapePressed", "allowDeselectDuringFilter", "preventHomeEndKeyPropagation", "disableScrollToActiveOnOptionsChanged", "ariaLabel", "showToggleAllCheckbox", "toggleAllCheckboxChecked", "toggleAllCheckboxIndeterminate", "toggleAllCheckboxTooltipMessage", "toogleAllCheckboxTooltipPosition", "hideClearSearchButton", "alwaysRestoreSelectedOptionsMulti"], outputs: ["toggleAll"] }, { kind: "directive", type: ConditionInputOutlet, selector: "[conditionInputOutlet]" }, { kind: "directive", type: ConditionOperatorOutlet, selector: "[conditionOperatorOutlet]" }, { kind: "component", type: NovoConditionTemplatesComponent, selector: "novo-condition-templates", inputs: ["addressConfig", "dateConfig"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1689
1733
  }
1734
+ __decorate([
1735
+ BooleanInput(),
1736
+ __metadata("design:type", Boolean)
1737
+ ], ConditionBuilderComponent.prototype, "allowEmptyField", void 0);
1690
1738
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConditionBuilderComponent, decorators: [{
1691
1739
  type: Component,
1692
1740
  args: [{ selector: 'novo-condition-builder', providers: [{ provide: NOVO_CONDITION_BUILDER, useExisting: ConditionBuilderComponent },
@@ -1719,6 +1767,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
1719
1767
  type: Input
1720
1768
  }], dateConfig: [{
1721
1769
  type: Input
1770
+ }], allowEmptyField: [{
1771
+ type: Input
1722
1772
  }], hideOperator: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideOperator", required: false }] }], conditionType: [{ type: i0.Input, args: [{ isSignal: true, alias: "conditionType", required: false }] }], inputConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], inputEditTypeFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTypeFn", required: false }] }], isConditionHost: [{
1723
1773
  type: HostBinding,
1724
1774
  args: ['class.condition-host']
@@ -1843,7 +1893,7 @@ class ConditionGroupComponent {
1843
1893
  return this.root.length <= 1;
1844
1894
  }
1845
1895
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConditionGroupComponent, deps: [{ token: QueryBuilderService }, { token: i1.NovoLabelService }, { token: i3.ControlContainer }, { token: i3.FormBuilder }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1846
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ConditionGroupComponent, isStandalone: false, selector: "novo-condition-group", inputs: { controlName: "controlName", groupIndex: "groupIndex", hideFirstOperator: "hideFirstOperator", canBeEmpty: "canBeEmpty", formGroupName: "formGroupName" }, host: { classAttribute: "novo-condition-group" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ConditionGroupComponent), multi: true }], usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"parentForm\" class=\"condition-group-container\">\n <novo-stack [formArrayName]=\"controlName\" gap=\"md\">\n <ng-container\n *ngFor=\"let andGroup of root.controls; let andIndex = index; let isFirst = first;let isLast = last;\">\n <ng-container [formGroupName]=\"andIndex\">\n <novo-flex class=\"condition-row\" [ngClass]=\"{ isFirst: andIndex === 0 }\" [class]=\"entity || scope\" align=\"end\" gap=\"sm\" #flex>\n <novo-dropdown *ngIf=\"(!isFirst || !hideFirstOperator) && qbs.allowedGroupings.length > 1; else labeledGroup\" data-automation-id=\"groupings-dropdown\">\n <button theme=\"dialogue\" icon=\"collapse\" size=\"sm\">{{qbs.getConjunctionLabel(controlName)}}</button>\n <novo-optgroup>\n <novo-option *ngFor=\"let c of qbs.allowedGroupings\" (click)=\"updateControlName(c)\" [attr.data-automation-id]=\"c\">\n {{qbs.getConjunctionLabel(c)}}</novo-option>\n </novo-optgroup>\n </novo-dropdown>\n <ng-template #labeledGroup>\n <novo-label *ngIf=\"!isFirst || !hideFirstOperator\" color=\"ash\" size=\"xs\" uppercase padding=\"sm\">\n {{qbs.getConjunctionLabel(controlName)}}</novo-label>\n </ng-template>\n <novo-condition-builder [groupIndex]=\"groupIndex\" [andIndex]=\"andIndex\" [hideOperator]=\"isFirst && hideFirstOperator\" [scope]=\"scope\" [conditionType]=\"controlName\"></novo-condition-builder>\n <novo-button class=\"delete-btn\" theme=\"icon\" icon=\"delete-o\" color=\"negative\" (click)=\"removeCondition(andIndex)\" data-automation-id=\"delete-filter-button\">\n </novo-button>\n </novo-flex>\n </ng-container>\n </ng-container>\n <button\n *ngIf=\"!qbs.hasMultipleScopes()\"\n theme=\"dialogue\"\n data-automation-id=\"add-advanced-search-condition\"\n icon=\"add-thin\"\n side=\"left\"\n size=\"sm\"\n uppercase\n (click)=\"addCondition()\">\n {{ labels.addCondition }}</button>\n </novo-stack>\n</div>\n", styles: [":host{position:relative;display:block;border:1px solid var(--border);border-radius:var(--border-radius-round);padding:var(--spacing-md);width:100%}:host .condition-row{width:100%}:host .delete-btn{margin-bottom:1px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i5$2.NovoButtonElement, selector: "novo-button,button[theme]", inputs: ["color", "side", "size", "theme", "loading", "icon", "secondIcon", "disabled"] }, { kind: "component", type: i5.NovoLabel, selector: "novo-label,[novo-label]", inputs: ["id"] }, { kind: "directive", type: i5.PaddingDirective, selector: "[p],[padding],[paddingTop],[paddingRight],[paddingBottom],[paddingLeft],[paddingX],[paddingY],[pt],[pr],[pb],[pl],[px],[py]", inputs: ["padding", "p", "paddingLeft", "pl", "paddingRight", "pr", "paddingTop", "pt", "paddingBottom", "pb", "paddingX", "px", "paddingY", "py"] }, { kind: "directive", type: i5.GapDirective, selector: "[gap]", inputs: ["gap"] }, { kind: "directive", type: i5.ThemeColorDirective, selector: "[theme]", inputs: ["theme"] }, { kind: "component", type: i5.NovoOption, selector: "novo-option", inputs: ["selected", "keepOpen", "novoInert", "value", "disabled"], exportAs: ["novoOption"] }, { kind: "component", type: i5.NovoOptgroup, selector: "novo-optgroup", inputs: ["disabled", "label"], exportAs: ["novoOptgroup"] }, { kind: "component", type: i8.NovoFlexElement, selector: "novo-flex,novo-row", inputs: ["direction", "align", "justify", "wrap", "gap"] }, { kind: "component", type: i8.NovoStackElement, selector: "novo-stack,novo-column", inputs: ["direction", "align"] }, { kind: "component", type: i8$3.NovoDropdownElement, selector: "novo-dropdown", inputs: ["parentScrollSelector", "parentScrollAction", "containerClass", "side", "scrollStrategy", "keepOpen", "height", "width", "appendToBody", "multiple", "scrollToActiveItemOnOpen"], outputs: ["toggled"] }, { kind: "component", type: ConditionBuilderComponent, selector: "novo-condition-builder", inputs: ["label", "scope", "andIndex", "groupIndex", "addressConfig", "dateConfig", "hideOperator", "conditionType", "config", "editTypeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1896
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.17", type: ConditionGroupComponent, isStandalone: false, selector: "novo-condition-group", inputs: { controlName: "controlName", groupIndex: "groupIndex", hideFirstOperator: "hideFirstOperator", canBeEmpty: "canBeEmpty", formGroupName: "formGroupName" }, host: { classAttribute: "novo-condition-group" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ConditionGroupComponent), multi: true }], usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"parentForm\" class=\"condition-group-container\">\n <novo-stack [formArrayName]=\"controlName\" gap=\"md\">\n <ng-container\n *ngFor=\"let andGroup of root.controls; let andIndex = index; let isFirst = first;let isLast = last;\">\n <ng-container [formGroupName]=\"andIndex\">\n <novo-flex class=\"condition-row\" [ngClass]=\"{ isFirst: andIndex === 0 }\" [class]=\"entity || scope\" align=\"end\" gap=\"sm\" #flex>\n <novo-dropdown *ngIf=\"(!isFirst || !hideFirstOperator) && qbs.allowedGroupings.length > 1; else labeledGroup\" data-automation-id=\"groupings-dropdown\">\n <button theme=\"dialogue\" icon=\"collapse\" size=\"sm\">{{qbs.getConjunctionLabel(controlName)}}</button>\n <novo-optgroup>\n <novo-option *ngFor=\"let c of qbs.allowedGroupings\" (click)=\"updateControlName(c)\" [attr.data-automation-id]=\"c\">\n {{qbs.getConjunctionLabel(c)}}</novo-option>\n </novo-optgroup>\n </novo-dropdown>\n <ng-template #labeledGroup>\n <novo-label *ngIf=\"!isFirst || !hideFirstOperator\" color=\"ash\" size=\"xs\" uppercase padding=\"sm\">\n {{qbs.getConjunctionLabel(controlName)}}</novo-label>\n </ng-template>\n <novo-condition-builder [groupIndex]=\"groupIndex\" [andIndex]=\"andIndex\" [hideOperator]=\"isFirst && hideFirstOperator\" [scope]=\"scope\" [conditionType]=\"controlName\"></novo-condition-builder>\n <novo-button class=\"delete-btn\" theme=\"icon\" icon=\"delete-o\" color=\"negative\" (click)=\"removeCondition(andIndex)\" data-automation-id=\"delete-filter-button\">\n </novo-button>\n </novo-flex>\n </ng-container>\n </ng-container>\n <button\n *ngIf=\"!qbs.hasMultipleScopes()\"\n theme=\"dialogue\"\n data-automation-id=\"add-advanced-search-condition\"\n icon=\"add-thin\"\n side=\"left\"\n size=\"sm\"\n uppercase\n (click)=\"addCondition()\">\n {{ labels.addCondition }}</button>\n </novo-stack>\n</div>\n", styles: [":host{position:relative;display:block;border:1px solid var(--border);border-radius:var(--border-radius-round);padding:var(--spacing-md);width:100%}:host .condition-row{width:100%}:host .delete-btn{margin-bottom:1px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i3.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "component", type: i5$2.NovoButtonElement, selector: "novo-button,button[theme]", inputs: ["color", "side", "size", "theme", "loading", "icon", "secondIcon", "disabled"] }, { kind: "component", type: i5.NovoLabel, selector: "novo-label,[novo-label]", inputs: ["id"] }, { kind: "directive", type: i5.PaddingDirective, selector: "[p],[padding],[paddingTop],[paddingRight],[paddingBottom],[paddingLeft],[paddingX],[paddingY],[pt],[pr],[pb],[pl],[px],[py]", inputs: ["padding", "p", "paddingLeft", "pl", "paddingRight", "pr", "paddingTop", "pt", "paddingBottom", "pb", "paddingX", "px", "paddingY", "py"] }, { kind: "directive", type: i5.GapDirective, selector: "[gap]", inputs: ["gap"] }, { kind: "directive", type: i5.ThemeColorDirective, selector: "[theme]", inputs: ["theme"] }, { kind: "component", type: i5.NovoOption, selector: "novo-option", inputs: ["selected", "keepOpen", "novoInert", "value", "disabled"], exportAs: ["novoOption"] }, { kind: "component", type: i5.NovoOptgroup, selector: "novo-optgroup", inputs: ["disabled", "label"], exportAs: ["novoOptgroup"] }, { kind: "component", type: i8.NovoFlexElement, selector: "novo-flex,novo-row", inputs: ["direction", "align", "justify", "wrap", "gap"] }, { kind: "component", type: i8.NovoStackElement, selector: "novo-stack,novo-column", inputs: ["direction", "align"] }, { kind: "component", type: i8$3.NovoDropdownElement, selector: "novo-dropdown", inputs: ["parentScrollSelector", "parentScrollAction", "containerClass", "side", "scrollStrategy", "keepOpen", "height", "width", "appendToBody", "multiple", "scrollToActiveItemOnOpen"], outputs: ["toggled"] }, { kind: "component", type: ConditionBuilderComponent, selector: "novo-condition-builder", inputs: ["label", "scope", "andIndex", "groupIndex", "addressConfig", "dateConfig", "allowEmptyField", "hideOperator", "conditionType", "config", "editTypeFn"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1847
1897
  }
1848
1898
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: ConditionGroupComponent, decorators: [{
1849
1899
  type: Component,