import * as i0 from '@angular/core';
import { inject, TemplateRef, Directive, input, contentChild, ChangeDetectorRef, PLATFORM_ID, viewChildren, contentChildren, output, Component } from '@angular/core';
import * as i1 from '@angular/common';
import { isPlatformServer, CommonModule } from '@angular/common';
import { Icon } from '@ngstarter-ui/components/icon';
import { MenuTrigger, Menu, MenuContent, MenuOptionGroupDirective, MenuItem } from '@ngstarter-ui/components/menu';
import * as i2 from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { Select, Option } from '@ngstarter-ui/components/select';
import { AutoFocusDirective, FocusElementDirective } from '@ngstarter-ui/components/core';
import { Input } from '@ngstarter-ui/components/input';
import { FormField } from '@ngstarter-ui/components/form-field';

class FilterBuilderOperationNameDirective {
    templateRef = inject(TemplateRef);
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationNameDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: FilterBuilderOperationNameDirective, isStandalone: true, selector: "[ngsFilterBuilderOperationName]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationNameDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsFilterBuilderOperationName]',
                    standalone: true
                }]
        }] });

class FilterBuilderOperationIconDirective {
    templateRef = inject(TemplateRef);
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: FilterBuilderOperationIconDirective, isStandalone: true, selector: "[ngsFilterBuilderOperationIcon]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationIconDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsFilterBuilderOperationIcon]',
                    standalone: true
                }]
        }] });

class FilterBuilderOperationDefDirective {
    id = input('', { ...(ngDevMode ? { debugName: "id" } : /* istanbul ignore next */ {}), alias: 'ngsFilterBuilderOperationDef' });
    allowedDataTypes = input([], ...(ngDevMode ? [{ debugName: "allowedDataTypes" }] : /* istanbul ignore next */ []));
    operationName = contentChild(FilterBuilderOperationNameDirective, ...(ngDevMode ? [{ debugName: "operationName" }] : /* istanbul ignore next */ []));
    operationIcon = contentChild(FilterBuilderOperationIconDirective, ...(ngDevMode ? [{ debugName: "operationIcon" }] : /* istanbul ignore next */ []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationDefDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.4", type: FilterBuilderOperationDefDirective, isStandalone: true, selector: "[ngsFilterBuilderOperationDef]", inputs: { id: { classPropertyName: "id", publicName: "ngsFilterBuilderOperationDef", isSignal: true, isRequired: false, transformFunction: null }, allowedDataTypes: { classPropertyName: "allowedDataTypes", publicName: "allowedDataTypes", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "operationName", first: true, predicate: FilterBuilderOperationNameDirective, descendants: true, isSignal: true }, { propertyName: "operationIcon", first: true, predicate: FilterBuilderOperationIconDirective, descendants: true, isSignal: true }], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilderOperationDefDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsFilterBuilderOperationDef]',
                    standalone: true
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngsFilterBuilderOperationDef", required: false }] }], allowedDataTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedDataTypes", required: false }] }], operationName: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FilterBuilderOperationNameDirective), { isSignal: true }] }], operationIcon: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FilterBuilderOperationIconDirective), { isSignal: true }] }] } });

class FilterBuilder {
    _cdr = inject(ChangeDetectorRef);
    _isServer = isPlatformServer(inject(PLATFORM_ID));
    _operationAllowedTypesMap = new Map();
    _resetMethodMap = {
        '_resetStringValue': this._resetStringValue,
        '_resetBooleanValue': this._resetBooleanValue,
        '_resetArrayValue': this._resetArrayValue,
        '_resetNumberValue': this._resetNumberValue,
    };
    value = input([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
    fieldDefs = input([], ...(ngDevMode ? [{ debugName: "fieldDefs" }] : /* istanbul ignore next */ []));
    categories = input([], ...(ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []));
    groupOperations = input([
        {
            id: 'and',
            name: 'And'
        },
        {
            id: 'or',
            name: 'Or'
        }
    ], ...(ngDevMode ? [{ debugName: "groupOperations" }] : /* istanbul ignore next */ []));
    customOperations = input([], ...(ngDevMode ? [{ debugName: "customOperations" }] : /* istanbul ignore next */ []));
    _logicalOperator = this.groupOperations()[0].id;
    _prebuiltOperationDefs = viewChildren(FilterBuilderOperationDefDirective, ...(ngDevMode ? [{ debugName: "_prebuiltOperationDefs" }] : /* istanbul ignore next */ []));
    _customOperationDefs = contentChildren(FilterBuilderOperationDefDirective, ...(ngDevMode ? [{ debugName: "_customOperationDefs" }] : /* istanbul ignore next */ []));
    _operationDefs = [];
    valueChanged = output();
    _value = [];
    _operations = [];
    editItem;
    _tempMultipleValue = [];
    ngOnInit() {
        if (this.value().length) {
            if (!this._isGroup(this.value()[0])) {
                throw new Error('Invalid filter value, first element should be a filter group');
            }
            this._logicalOperator = this.value()[0]['logicalOperator'];
            this._value = JSON.parse(JSON.stringify(this.value()[0]['value']));
        }
    }
    ngAfterViewInit() {
        this._operationDefs = [...this._prebuiltOperationDefs(), ...this._customOperationDefs()];
        this._operationDefs.forEach(operationDef => {
            this._operations.push({
                id: operationDef.id(),
                name: operationDef.operationName()?.templateRef
            });
            operationDef.allowedDataTypes().forEach((allowedType) => {
                if (!this._operationAllowedTypesMap.has(allowedType)) {
                    this._operationAllowedTypesMap.set(allowedType, []);
                }
                const allowedTypeValue = this._operationAllowedTypesMap.get(allowedType);
                allowedTypeValue.push(operationDef.id());
                this._operationAllowedTypesMap.set(allowedType, allowedTypeValue);
            });
        });
        this._cdr.detectChanges();
    }
    addCondition(targetGroup) {
        const value = !targetGroup ? this._value : targetGroup.value;
        value.push({
            value: [this.fieldDefs()[0].dataField, this._operations[0].id, '']
        });
    }
    addGroup(targetGroup) {
        const value = !targetGroup ? this._value : targetGroup.value;
        value.push({
            logicalOperator: this.groupOperations()[0].id,
            value: []
        });
    }
    getConditionField(dataField) {
        return this.fieldDefs().find(field => field.dataField === dataField);
    }
    getConditionOperation(id) {
        return this._operations.find(operation => operation.id === id);
    }
    getSelectedGroupOperationName(targetGroup) {
        const groupLogicalOperatorId = targetGroup ? targetGroup.logicalOperator : this._logicalOperator;
        return this.groupOperations().find(groupOperator => groupOperator.id === groupLogicalOperatorId)?.name || '';
    }
    selectConditionField(item, field) {
        let allowedTypes = this._operationAllowedTypesMap.get(field.dataType);
        item['value'][0] = field.dataField;
        item['value'][1] = allowedTypes[0];
        this._resetValue(field, item);
        this.editItem = undefined;
        this._emitChangeEvent();
    }
    operationChanged(item, operation) {
        const oldOperation = item['value'][1];
        if (oldOperation === 'equals' && operation === 'isAnyOf') {
            item['value'][2] = [];
        }
        else if (oldOperation === 'isAnyOf' && operation === 'equals') {
            item['value'][2] = null;
        }
        if (oldOperation === 'isBetween' && operation !== 'isBetween') {
            item['value'][2] = null;
        }
        else if (oldOperation !== 'isBetween' && operation === 'isBetween') {
            item['value'][2] = [];
        }
        if (['isNotBlank', 'isBlank'].includes(operation)) {
            item['value'][2] = null;
        }
        item['value'][1] = operation;
        this.editItem = undefined;
        this._emitChangeEvent();
    }
    removeCondition(index, items) {
        items.splice(index, 1);
        this._emitChangeEvent();
    }
    isOperationAllowedForCondition(dataField, operationId) {
        const fieldDef = this.fieldDefs().find(f => f.dataField === dataField);
        let allowedTypes = this._operationAllowedTypesMap.get(fieldDef.dataType);
        if (!allowedTypes) {
            throw new Error('There are not operations for the datatype: ' + fieldDef.dataType);
        }
        return allowedTypes.includes(operationId);
    }
    modifyValue(item) {
        this.editItem = item;
        if (this.getFieldType(item) === 'array' && item['value'][1] === 'isAnyOf') {
            this._tempMultipleValue = [...(item['value'][2] || [])];
        }
    }
    getFieldType(item) {
        return this.fieldDefs().find(f => f.dataField === item['value'][0]).dataType;
    }
    isValueNotEmpty(item) {
        if (this.getFieldType(item) === 'array') {
            if (item['value'][1] === 'equals') {
                return item['value'][2] !== null && item['value'][2] !== '';
            }
            else {
                return item['value'][2].length > 0;
            }
        }
        if (item['value'][1] === 'isBetween') {
            return item['value'][2].length === 2 && item['value'][2][0] !== null && item['value'][2][1] !== null;
        }
        return item['value'][2] !== null && item['value'][2] !== '';
    }
    cancelEdit(delay = 0) {
        setTimeout(() => {
            this.editItem = undefined;
            this._cdr.detectChanges();
        }, delay);
    }
    getOptions(item) {
        const fieldDef = this._getFieldDef(item);
        return fieldDef.lookup?.dataSource;
    }
    getDataSourceItemNameById(item, dataSourceItemId) {
        const fieldDef = this._getFieldDef(item);
        return (fieldDef.lookup?.dataSource).find(item => item.id === dataSourceItemId)?.name || '';
    }
    selectBlur(event) {
        if (this.editItem && this.getFieldType(this.editItem) === 'array' && this.editItem['value'][1] === 'isAnyOf') {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        const select = event.target;
        setTimeout(() => {
            const formField = select.closest('.ngs-form-field');
            if (formField) {
                this.cancelEdit();
            }
        }, 200);
    }
    selectClosed() {
        if (this.editItem && this.getFieldType(this.editItem) === 'array' && this.editItem['value'][1] === 'isAnyOf') {
            this.editItem['value'][2] = [...this._tempMultipleValue];
        }
        this.cancelEdit();
        setTimeout(() => {
            this._emitChangeEvent();
        });
    }
    operationIconTemplateRef(operation) {
        return operation.operationIcon()?.templateRef;
    }
    operationNameTemplateRef(operation) {
        return operation.operationName()?.templateRef;
    }
    _isGroup(item) {
        return 'logicalOperator' in item;
    }
    _isCondition(item) {
        return !('logicalOperator' in item);
    }
    _emitChangeEvent() {
        const value = this._normalizeValue(this._value);
        if (value.length > 0) {
            this.valueChanged.emit([
                {
                    logicalOperator: this._logicalOperator,
                    value: value
                }
            ]);
        }
        else {
            this.valueChanged.emit([]);
        }
    }
    _getFieldDef(condition) {
        return this.fieldDefs().find(f => f.dataField === condition['value'][0]);
    }
    _resetValue(field, condition) {
        const fieldDef = this.fieldDefs().find(f => f.dataField === field.dataField);
        const resetMethod = '_reset' + this._capitalizeFirstLetter(fieldDef.dataType) + 'Value';
        this._resetMethodMap[resetMethod](condition);
    }
    _resetStringValue(condition) {
        condition['value'][2] = '';
    }
    _resetNumberValue(condition) {
        condition['value'][2] = null;
    }
    _resetArrayValue(condition) {
        if (condition['value'][1] === 'equals') {
            condition['value'][2] = null;
        }
        else {
            condition['value'][2] = [];
        }
    }
    _resetBooleanValue(condition) {
        condition['value'][2] = false;
    }
    _capitalizeFirstLetter(value) {
        return value.charAt(0).toUpperCase() + value.slice(1);
    }
    _normalizeValue(value) {
        let result = [];
        value.forEach(item => {
            if (this._isGroup(item)) {
                const groupValue = this._normalizeValue(item.value);
                if (groupValue.length > 0) {
                    result = [...result, {
                            logicalOperator: item.logicalOperator,
                            value: groupValue
                        }];
                }
            }
            else {
                if (this.isValueNotEmpty(item)) {
                    result.push(item);
                }
            }
        });
        return result;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilder, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: FilterBuilder, isStandalone: true, selector: "ngs-filter-builder", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, fieldDefs: { classPropertyName: "fieldDefs", publicName: "fieldDefs", isSignal: true, isRequired: false, transformFunction: null }, categories: { classPropertyName: "categories", publicName: "categories", isSignal: true, isRequired: false, transformFunction: null }, groupOperations: { classPropertyName: "groupOperations", publicName: "groupOperations", isSignal: true, isRequired: false, transformFunction: null }, customOperations: { classPropertyName: "customOperations", publicName: "customOperations", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChanged: "valueChanged" }, host: { classAttribute: "ngs-filter-builder" }, queries: [{ propertyName: "_customOperationDefs", predicate: FilterBuilderOperationDefDirective, isSignal: true }], viewQueries: [{ propertyName: "_prebuiltOperationDefs", predicate: FilterBuilderOperationDefDirective, descendants: true, isSignal: true }], exportAs: ["ngsFilterBuilder"], ngImport: i0, template: "@if (_isServer) {\n  <ng-content/>\n}\n\n<ng-template #itemsTpl let-items>\n  <div class=\"group\">\n    @for (item of items; track item; let index = $index) {\n      @if (_isGroup(item)) {\n        <div class=\"flex items-center group-operations\">\n          <div class=\"remove\" (click)=\"removeCondition(index, items)\">\n            <ngs-icon name=\"fluent:dismiss-24-regular\" class=\"font-icon\"/>\n          </div>\n          <button [ngsMenuTriggerFor]=\"nestedGroupOperationsMenu\"\n                  #nestedGroupOperationsMenuTrigger=\"ngsMenuTrigger\"\n                  class=\"group-operation\">\n            {{ getSelectedGroupOperationName(item) }}\n          </button>\n          <div [ngsMenuTriggerFor]=\"addGroupMenu\" class=\"add\">\n            <ngs-icon name=\"fluent:add-24-regular\" class=\"font-icon\"/>\n          </div>\n          <ngs-menu #nestedGroupOperationsMenu=\"ngsMenu\">\n            <div ngsMenuOptionGroup [(ngModel)]=\"item['logicalOperator']\">\n              @for (groupOperation of groupOperations(); track groupOperation.id) {\n                <ngs-option [value]=\"groupOperation.id\"\n                            (click)=\"nestedGroupOperationsMenuTrigger.closeMenu('click')\">{{ groupOperation.name }}\n                </ngs-option>\n              }\n            </div>\n          </ngs-menu>\n          <ngs-menu #addGroupMenu=\"ngsMenu\">\n            <button ngs-menu-item (click)=\"addCondition(item)\">Add Condition</button>\n            <button ngs-menu-item (click)=\"addGroup(item)\">Add Group</button>\n          </ngs-menu>\n        </div>\n        @if (item['value'].length > 0) {\n          <ng-container [ngTemplateOutlet]=\"itemsTpl\" [ngTemplateOutletContext]=\"{ $implicit: item['value'] }\"/>\n        }\n      } @else if (_isCondition(item)) {\n        <div class=\"condition\">\n          <div class=\"remove\" (click)=\"removeCondition(index, items)\">\n            <ngs-icon name=\"fluent:dismiss-24-regular\" class=\"font-icon\"/>\n          </div>\n          <button class=\"condition-field\"\n                  #fieldsMenuTrigger=\"ngsMenuTrigger\"\n                  [ngsMenuTriggerFor]=\"fieldsMenu\">{{ getConditionField(item['value'][0])?.name }}\n          </button>\n          <button class=\"condition-operation\"\n                  #operationsMenuTrigger=\"ngsMenuTrigger\"\n                  [ngsMenuTriggerFor]=\"operationsMenu\">\n            <ng-template [ngTemplateOutlet]=\"getConditionOperation(item['value'][1])?.name\"/>\n          </button>\n          <div class=\"relative\">\n            @if (editItem && editItem === item) {\n              <div class=\"absolute start-0 top-0 -translate-y-1/2\">\n                @switch (getFieldType(editItem)) {\n                  @case ('array') {\n                    @switch (editItem['value'][1]) {\n                      @case ('equals') {\n                        <ngs-form-field class=\"form-field\">\n                          <ngs-select placeholder=\"Select...\"\n                                      ngsAutoFocus\n                                      (blur)=\"selectBlur($event)\"\n                                      [(ngModel)]=\"item['value'][2]\"\n                                      (ngModelChange)=\"_emitChangeEvent()\">\n                            @for (option of getOptions(editItem); track option.id) {\n                              <ngs-option [value]=\"option.id\">{{ option.name }}</ngs-option>\n                            }\n                          </ngs-select>\n                        </ngs-form-field>\n                      }\n                      @case ('isAnyOf') {\n                        <ngs-form-field class=\"form-field\">\n                          <ngs-select placeholder=\"Select...\" multiple\n                                      ngsAutoFocus\n                                      (blur)=\"selectBlur($event)\"\n                                      [(ngModel)]=\"_tempMultipleValue\"\n                                      (closed)=\"selectClosed()\">\n                            @for (option of getOptions(editItem); track option.id) {\n                              <ngs-option [value]=\"option.id\">{{ option.name }}</ngs-option>\n                            }\n                          </ngs-select>\n                        </ngs-form-field>\n                      }\n                    }\n                  }\n                  @case ('number') {\n                    @switch (editItem['value'][1]) {\n                      @case ('isBetween') {\n                        <div class=\"flex gap-2 items-center\"\n                             ngsFocusElement (elementBlurred)=\"cancelEdit()\">\n                          <ngs-form-field class=\"form-field-number\">\n                            <input type=\"number\" ngsInput ngsAutoFocus\n                                   [(ngModel)]=\"item['value'][2][0]\"\n                                   (ngModelChange)=\"_emitChangeEvent()\">\n                          </ngs-form-field>\n                          <div class=\"text-neutral-500\">&ndash;</div>\n                          <ngs-form-field class=\"form-field-number\">\n                            <input type=\"number\" ngsInput\n                                   [(ngModel)]=\"item['value'][2][1]\"\n                                   (ngModelChange)=\"_emitChangeEvent()\">\n                          </ngs-form-field>\n                        </div>\n                      }\n                      @default {\n                        <ngs-form-field class=\"form-field-number\">\n                          <input type=\"number\" ngsInput ngsAutoFocus\n                                 (blur)=\"cancelEdit()\"\n                                 [(ngModel)]=\"item['value'][2]\"\n                                 (ngModelChange)=\"_emitChangeEvent()\">\n                        </ngs-form-field>\n                      }\n                    }\n                  }\n                  @default {\n                    <ngs-form-field class=\"form-field\">\n                      <input type=\"text\" ngsInput ngsAutoFocus\n                             (blur)=\"cancelEdit()\"\n                             [(ngModel)]=\"item['value'][2]\"\n                             (ngModelChange)=\"_emitChangeEvent()\">\n                    </ngs-form-field>\n                  }\n                }\n              </div>\n            } @else {\n              @if (item['value'][1] !== 'isBlank' && item['value'][1] !== 'isNotBlank') {\n                @if (isValueNotEmpty(item)) {\n                  @if (getFieldType(item) === 'array') {\n                    @if (item['value'][1] === 'equals') {\n                      <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                        {{ getDataSourceItemNameById(item, item['value'][2]) }}\n                      </button>\n                    } @else {\n                      <button class=\"condition-value flex items-center gap-2\" (click)=\"modifyValue(item)\">\n                        @for (dataSourceItemId of item['value'][2]; track dataSourceItemId; let last = $last) {\n                          <span>{{ getDataSourceItemNameById(item, dataSourceItemId) }}</span>\n                          @if (!last) {\n                            <span class=\"text-neutral-500\">|</span>\n                          }\n                        }\n                      </button>\n                    }\n                  } @else {\n                    @if (item['value'][1] === 'isBetween') {\n                      <button class=\"condition-value flex items-center gap-2\" (click)=\"modifyValue(item)\">\n                        <span>{{ item['value'][2][0] }}</span>\n                        <span class=\"text-neutral-500\">&ndash;</span>\n                        <span>{{ item['value'][2][1] }}</span>\n                      </button>\n                    } @else {\n                      <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                        <span>{{ item['value'][2] }}</span>\n                      </button>\n                    }\n                  }\n                } @else {\n                  <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                    <span i18n>&lt;enter a value&gt;</span>\n                  </button>\n                }\n              }\n            }\n          </div>\n        </div>\n        <ngs-menu #fieldsMenu=\"ngsMenu\">\n          <ng-template ngsMenuContent>\n            <div ngsMenuOptionGroup [ngModel]=\"item['value'][0]\">\n              @for (fieldDef of fieldDefs(); track fieldDef) {\n                <ngs-option [value]=\"fieldDef.dataField\"\n                            (click)=\"selectConditionField(item, fieldDef); fieldsMenuTrigger.closeMenu('click')\">{{ fieldDef.name }}\n                </ngs-option>\n              }\n            </div>\n          </ng-template>\n        </ngs-menu>\n        <ngs-menu #operationsMenu=\"ngsMenu\">\n          <ng-template ngsMenuContent>\n            <div ngsMenuOptionGroup [ngModel]=\"item['value'][1]\">\n              @for (operation of _operationDefs; track operation.id()) {\n                <div [hidden]=\"!isOperationAllowedForCondition(item['value'][0], operation.id())\">\n                  <ngs-option [value]=\"operation.id()\"\n                              (click)=\"operationChanged(item, operation.id()); operationsMenuTrigger.closeMenu('click')\">\n                    <div class=\"flex items-center gap-3\">\n                      @if (operation.operationIcon()) {\n                        <ng-template [ngTemplateOutlet]=\"operationIconTemplateRef(operation)\"/>\n                      }\n                      <div>\n                        <ng-template [ngTemplateOutlet]=\"operationNameTemplateRef(operation)\"/>\n                      </div>\n                    </div>\n                  </ngs-option>\n                </div>\n              }\n            </div>\n          </ng-template>\n        </ngs-menu>\n      }\n    }\n  </div>\n</ng-template>\n\n<div class=\"group\">\n  <div class=\"flex items-center group-operations\">\n    <button [ngsMenuTriggerFor]=\"groupOperationsMenu\"\n            #groupOperationsMenuTrigger=\"ngsMenuTrigger\"\n            class=\"group-operation\">\n      {{ getSelectedGroupOperationName() }}\n    </button>\n    <div [ngsMenuTriggerFor]=\"addMenu\" class=\"add\">\n      <ngs-icon name=\"fluent:add-24-regular\" class=\"font-icon\"/>\n    </div>\n  </div>\n  <ng-container [ngTemplateOutlet]=\"itemsTpl\" [ngTemplateOutletContext]=\"{ $implicit: _value }\"/>\n</div>\n\n<ngs-menu #groupOperationsMenu=\"ngsMenu\">\n  <ng-template ngsMenuContent>\n    <div ngsMenuOptionGroup [(ngModel)]=\"_logicalOperator\" (ngModelChange)=\"_emitChangeEvent()\">\n      @for (operation of groupOperations(); track operation.id) {\n        <ngs-option [value]=\"operation.id\"\n                    (click)=\"groupOperationsMenuTrigger.closeMenu('click')\">{{ operation.name }}\n        </ngs-option>\n      }\n    </div>\n  </ng-template>\n</ngs-menu>\n<ngs-menu #addMenu=\"ngsMenu\">\n  <ng-template ngsMenuContent>\n    <button ngs-menu-item (click)=\"addCondition()\">Add Condition</button>\n    <button ngs-menu-item (click)=\"addGroup()\">Add Group</button>\n  </ng-template>\n</ngs-menu>\n\n<ng-container ngsFilterBuilderOperationDef=\"contains\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Contains</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"doesNotContain\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Does not contain</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"startsWith\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Starts with</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"endsWith\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Ends with</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"equals\" [allowedDataTypes]=\"['string', 'number', 'array', 'boolean']\">\n  <ng-template ngsFilterBuilderOperationName>Equals</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"notEquals\" [allowedDataTypes]=\"['string', 'number', 'boolean']\">\n  <ng-template ngsFilterBuilderOperationName>Not equals</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isLessThen\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is less then</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isLessThenOrEqual\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is less then or equal to</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isGreaterThen\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is greater then</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isGreaterThenOrEqual\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is greater then or equal to</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isBlank\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Is blank</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isNotBlank\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Is not blank</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isBetween\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is between</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isAnyOf\" [allowedDataTypes]=\"['array']\">\n  <ng-template ngsFilterBuilderOperationName>Is any of</ng-template>\n</ng-container>\n", styles: [":host{--ngs-filter-builder-group-operations-gap: calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-group-operation-font-size: var(--text-tiny);--ngs-filter-builder-group-operation-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-bg: var(--ngs-color-surface-container);--ngs-filter-builder-group-operation-font-weight: 400;--ngs-filter-builder-group-operation-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-group-operation-bpadding: 0 calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-group-operation-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-group-operation-hover-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-hover-bg: var(--ngs-color-surface-container-high);--ngs-filter-builder-group-operation-active-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-active-bg: var(--ngs-color-surface-container-highest);--ngs-filter-builder-group-operation-border: 1px solid var(--ngs-color-border);--ngs-filter-builder-group-add-color: var(--ngs-color-primary);--ngs-filter-builder-group-add-hover-color: var(--ngs-color-primary);--ngs-filter-builder-group-margin: 0;--ngs-filter-builder-group-padding: 0;--ngs-filter-builder-group-gap: calc(var(--spacing, .25rem) * 4);--ngs-filter-builder-condition-gap: calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-field-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-field-font-size: var(--text-tiny);--ngs-filter-builder-condition-field-color: var(--ngs-color-on-primary-container);--ngs-filter-builder-condition-field-bg: var(--ngs-color-primary-container);--ngs-filter-builder-condition-field-font-weight: 400;--ngs-filter-builder-condition-field-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-field-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-field-hover-color: var(--ngs-color-on-primary-container);--ngs-filter-builder-condition-field-hover-bg: var(--ngs-color-primary-400);--ngs-filter-builder-condition-field-active-color: var(--ngs-color-on-primary);--ngs-filter-builder-condition-field-active-bg: var(--ngs-color-primary);--ngs-filter-builder-condition-operation-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-operation-font-size: var(--text-tiny);--ngs-filter-builder-condition-operation-color: var(--ngs-color-on-secondary-container);--ngs-filter-builder-condition-operation-bg: var(--ngs-color-secondary-container);--ngs-filter-builder-condition-operation-font-weight: 400;--ngs-filter-builder-condition-operation-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-operation-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-operation-hover-color: var(--ngs-color-on-secondary-container);--ngs-filter-builder-condition-operation-hover-bg: var(--ngs-color-secondary-400);--ngs-filter-builder-condition-operation-active-color: var(--ngs-color-on-secondary);--ngs-filter-builder-condition-operation-active-bg: var(--ngs-color-secondary);--ngs-filter-builder-condition-value-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-value-font-size: var(--text-tiny);--ngs-filter-builder-condition-value-color: var(--ngs-color-on-surface);--ngs-filter-builder-condition-value-bg: var(--ngs-color-surface-container-high);--ngs-filter-builder-condition-value-font-weight: 400;--ngs-filter-builder-condition-value-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-value-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-value-hover-color: var(--ngs-color-on-surface);--ngs-filter-builder-condition-value-hover-bg: var(--ngs-color-surface-container-highest);--ngs-filter-builder-condition-remove-color: var(--ngs-color-danger);--ngs-filter-builder-condition-remove-hover-color: var(--ngs-color-danger);display:block}:host ::ng-deep .ngs-form-field-infix{--ngs-form-field-container-height: 46px !important;--ngs-form-field-container-vertical-padding: 12px !important}:host ::ng-deep .subscript-wrapper{display:none}:host .form-field{width:200px}:host .form-field-number{width:140px}:host .group-operations{gap:var(--ngs-filter-builder-group-operations-gap)}:host .group{margin:var(--ngs-filter-builder-group-margin);padding:var(--ngs-filter-builder-group-padding);display:flex;flex-direction:column;gap:var(--ngs-filter-builder-group-gap)}:host .group .group{margin-left:calc(var(--spacing, .25rem) * 4)}:host .icon:empty{display:none}:host .group-operation{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-group-operation-height);font-size:var(--ngs-filter-builder-group-operation-font-size);font-weight:var(--ngs-filter-builder-group-operation-font-weight);color:var(--ngs-filter-builder-group-operation-color);background:var(--ngs-filter-builder-group-operation-bg);border:var(--ngs-filter-builder-group-operation-border);border-radius:var(--ngs-filter-builder-group-operation-border-radius);padding:var(--ngs-filter-builder-group-operation-bpadding)}:host .group-operation:hover{color:var(--ngs-filter-builder-group-operation-hover-color);background:var(--ngs-filter-builder-group-operation-hover-bg)}:host .group-operation:active,:host .group-operation.active{color:var(--ngs-filter-builder-group-operation-active-color);background:var(--ngs-filter-builder-group-operation-active-bg)}:host .condition{display:flex;align-items:center;gap:var(--ngs-filter-builder-condition-gap)}:host .condition-field{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-field-height);font-size:var(--ngs-filter-builder-condition-field-font-size);font-weight:var(--ngs-filter-builder-condition-field-font-weight);color:var(--ngs-filter-builder-condition-field-color);background:var(--ngs-filter-builder-condition-field-bg);border-radius:var(--ngs-filter-builder-condition-field-border-radius);padding:var(--ngs-filter-builder-condition-field-bpadding)}:host .condition-field:hover{color:var(--ngs-filter-builder-condition-field-hover-color);background:var(--ngs-filter-builder-condition-field-hover-bg)}:host .add{line-height:0;color:var(--ngs-filter-builder-group-add-color);cursor:pointer}:host .add:hover{color:var(--ngs-filter-builder-group-add-hover-color)}:host .remove{line-height:0;color:var(--ngs-filter-builder-condition-remove-color);cursor:pointer}:host .remove:hover{color:var(--ngs-filter-builder-condition-remove-hover-color)}:host .condition-field:active,:host .condition-field.active{color:var(--ngs-filter-builder-condition-field-active-color);background:var(--ngs-filter-builder-condition-field-active-bg)}:host .condition-operation{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-operation-height);font-size:var(--ngs-filter-builder-condition-operation-font-size);font-weight:var(--ngs-filter-builder-condition-operation-font-weight);color:var(--ngs-filter-builder-condition-operation-color);background:var(--ngs-filter-builder-condition-operation-bg);border-radius:var(--ngs-filter-builder-condition-operation-border-radius);padding:var(--ngs-filter-builder-condition-operation-bpadding)}:host .condition-operation:hover{color:var(--ngs-filter-builder-condition-operation-hover-color);background:var(--ngs-filter-builder-condition-operation-hover-bg)}:host .condition-operation:active,:host .condition-operation.active{color:var(--ngs-filter-builder-condition-operation-active-color);background:var(--ngs-filter-builder-condition-operation-active-bg)}:host .condition-value{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-value-height);font-size:var(--ngs-filter-builder-condition-value-font-size);font-weight:var(--ngs-filter-builder-condition-value-font-weight);color:var(--ngs-filter-builder-condition-value-color);background:var(--ngs-filter-builder-condition-value-bg);border-radius:var(--ngs-filter-builder-condition-value-border-radius);padding:var(--ngs-filter-builder-condition-value-bpadding)}:host .condition-value:hover{color:var(--ngs-filter-builder-condition-value-hover-color);background:var(--ngs-filter-builder-condition-value-hover-bg)}:host-context(html.dark){--ngs-filter-builder-group-operation-color: var(--ngs-color-neutral-200);--ngs-filter-builder-group-operation-hover-bg: var(--ngs-color-neutral-600);--ngs-filter-builder-group-operation-active-bg: var(--ngs-color-neutral-650);--ngs-filter-builder-group-operation-hover-color: var(--ngs-color-neutral-100);--ngs-filter-builder-group-operation-active-color: var(--ngs-color-neutral-50)}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: Icon, selector: "ngs-icon", inputs: ["name"], exportAs: ["ngsIcon"] }, { kind: "directive", type: MenuTrigger, selector: "[ngsMenuTriggerFor]", inputs: ["ngsMenuTriggerFor", "ngsMenuTriggerData", "ngsMenuDisabled", "xPosition", "yPosition", "ngsMenuTriggerRestoreFocus"], outputs: ["menuOpened", "menuClosed"], exportAs: ["ngsMenuTrigger"] }, { kind: "component", type: Menu, selector: "ngs-menu", inputs: ["role", "classList", "xPosition", "yPosition"], outputs: ["closed"], exportAs: ["ngsMenu"] }, { kind: "directive", type: MenuContent, selector: "[ngsMenuContent]" }, { kind: "directive", type: MenuOptionGroupDirective, selector: "[ngsMenuOptionGroup]", inputs: ["multiple"], outputs: ["valueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: MenuItem, selector: "ngs-menu-item, [ngs-menu-item]", inputs: ["disabled", "role", "selected"], outputs: ["_triggered"], exportAs: ["ngsMenuItem"] }, { kind: "component", type: FormField, selector: "ngs-form-field", inputs: ["subscriptHiddenIfEmpty"], exportAs: ["ngsFormField"] }, { kind: "component", type: Select, selector: "ngs-select", inputs: ["id", "placeholder", "disabled", "required", "multiple", "hideCheckIcon", "ariaLabel", "tabIndex", "aria-describedby", "value"], outputs: ["selectionChange", "opened", "closed", "valueChange"], exportAs: ["ngsSelect"] }, { kind: "component", type: Option, selector: "ngs-option", inputs: ["value", "disabled", "selected"], outputs: ["onSelectionChange"], exportAs: ["ngsOption"] }, { kind: "directive", type: AutoFocusDirective, selector: "[ngsAutoFocus]", inputs: ["ngsAutoFocus"], exportAs: ["ngsAutoFocus"] }, { kind: "directive", type: FocusElementDirective, selector: "[ngsFocusElement]", inputs: ["checkChildren"], outputs: ["elementFocused", "elementBlurred"], exportAs: ["ngsFocusElement"] }, { kind: "directive", type: Input, selector: "input[ngsInput], textarea[ngsInput]", inputs: ["id", "placeholder", "required", "disabled", "readonly", "errorStateMatcher"], exportAs: ["ngsInput"] }, { kind: "directive", type: FilterBuilderOperationDefDirective, selector: "[ngsFilterBuilderOperationDef]", inputs: ["ngsFilterBuilderOperationDef", "allowedDataTypes"] }, { kind: "directive", type: FilterBuilderOperationNameDirective, selector: "[ngsFilterBuilderOperationName]" }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: FilterBuilder, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-filter-builder', exportAs: 'ngsFilterBuilder', imports: [
                        CommonModule,
                        Icon,
                        MenuTrigger,
                        Menu,
                        MenuContent,
                        MenuOptionGroupDirective,
                        FormsModule,
                        MenuItem,
                        FormField,
                        Select,
                        Option,
                        AutoFocusDirective,
                        FocusElementDirective,
                        Input,
                        FilterBuilderOperationDefDirective,
                        FilterBuilderOperationNameDirective
                    ], host: {
                        'class': 'ngs-filter-builder'
                    }, template: "@if (_isServer) {\n  <ng-content/>\n}\n\n<ng-template #itemsTpl let-items>\n  <div class=\"group\">\n    @for (item of items; track item; let index = $index) {\n      @if (_isGroup(item)) {\n        <div class=\"flex items-center group-operations\">\n          <div class=\"remove\" (click)=\"removeCondition(index, items)\">\n            <ngs-icon name=\"fluent:dismiss-24-regular\" class=\"font-icon\"/>\n          </div>\n          <button [ngsMenuTriggerFor]=\"nestedGroupOperationsMenu\"\n                  #nestedGroupOperationsMenuTrigger=\"ngsMenuTrigger\"\n                  class=\"group-operation\">\n            {{ getSelectedGroupOperationName(item) }}\n          </button>\n          <div [ngsMenuTriggerFor]=\"addGroupMenu\" class=\"add\">\n            <ngs-icon name=\"fluent:add-24-regular\" class=\"font-icon\"/>\n          </div>\n          <ngs-menu #nestedGroupOperationsMenu=\"ngsMenu\">\n            <div ngsMenuOptionGroup [(ngModel)]=\"item['logicalOperator']\">\n              @for (groupOperation of groupOperations(); track groupOperation.id) {\n                <ngs-option [value]=\"groupOperation.id\"\n                            (click)=\"nestedGroupOperationsMenuTrigger.closeMenu('click')\">{{ groupOperation.name }}\n                </ngs-option>\n              }\n            </div>\n          </ngs-menu>\n          <ngs-menu #addGroupMenu=\"ngsMenu\">\n            <button ngs-menu-item (click)=\"addCondition(item)\">Add Condition</button>\n            <button ngs-menu-item (click)=\"addGroup(item)\">Add Group</button>\n          </ngs-menu>\n        </div>\n        @if (item['value'].length > 0) {\n          <ng-container [ngTemplateOutlet]=\"itemsTpl\" [ngTemplateOutletContext]=\"{ $implicit: item['value'] }\"/>\n        }\n      } @else if (_isCondition(item)) {\n        <div class=\"condition\">\n          <div class=\"remove\" (click)=\"removeCondition(index, items)\">\n            <ngs-icon name=\"fluent:dismiss-24-regular\" class=\"font-icon\"/>\n          </div>\n          <button class=\"condition-field\"\n                  #fieldsMenuTrigger=\"ngsMenuTrigger\"\n                  [ngsMenuTriggerFor]=\"fieldsMenu\">{{ getConditionField(item['value'][0])?.name }}\n          </button>\n          <button class=\"condition-operation\"\n                  #operationsMenuTrigger=\"ngsMenuTrigger\"\n                  [ngsMenuTriggerFor]=\"operationsMenu\">\n            <ng-template [ngTemplateOutlet]=\"getConditionOperation(item['value'][1])?.name\"/>\n          </button>\n          <div class=\"relative\">\n            @if (editItem && editItem === item) {\n              <div class=\"absolute start-0 top-0 -translate-y-1/2\">\n                @switch (getFieldType(editItem)) {\n                  @case ('array') {\n                    @switch (editItem['value'][1]) {\n                      @case ('equals') {\n                        <ngs-form-field class=\"form-field\">\n                          <ngs-select placeholder=\"Select...\"\n                                      ngsAutoFocus\n                                      (blur)=\"selectBlur($event)\"\n                                      [(ngModel)]=\"item['value'][2]\"\n                                      (ngModelChange)=\"_emitChangeEvent()\">\n                            @for (option of getOptions(editItem); track option.id) {\n                              <ngs-option [value]=\"option.id\">{{ option.name }}</ngs-option>\n                            }\n                          </ngs-select>\n                        </ngs-form-field>\n                      }\n                      @case ('isAnyOf') {\n                        <ngs-form-field class=\"form-field\">\n                          <ngs-select placeholder=\"Select...\" multiple\n                                      ngsAutoFocus\n                                      (blur)=\"selectBlur($event)\"\n                                      [(ngModel)]=\"_tempMultipleValue\"\n                                      (closed)=\"selectClosed()\">\n                            @for (option of getOptions(editItem); track option.id) {\n                              <ngs-option [value]=\"option.id\">{{ option.name }}</ngs-option>\n                            }\n                          </ngs-select>\n                        </ngs-form-field>\n                      }\n                    }\n                  }\n                  @case ('number') {\n                    @switch (editItem['value'][1]) {\n                      @case ('isBetween') {\n                        <div class=\"flex gap-2 items-center\"\n                             ngsFocusElement (elementBlurred)=\"cancelEdit()\">\n                          <ngs-form-field class=\"form-field-number\">\n                            <input type=\"number\" ngsInput ngsAutoFocus\n                                   [(ngModel)]=\"item['value'][2][0]\"\n                                   (ngModelChange)=\"_emitChangeEvent()\">\n                          </ngs-form-field>\n                          <div class=\"text-neutral-500\">&ndash;</div>\n                          <ngs-form-field class=\"form-field-number\">\n                            <input type=\"number\" ngsInput\n                                   [(ngModel)]=\"item['value'][2][1]\"\n                                   (ngModelChange)=\"_emitChangeEvent()\">\n                          </ngs-form-field>\n                        </div>\n                      }\n                      @default {\n                        <ngs-form-field class=\"form-field-number\">\n                          <input type=\"number\" ngsInput ngsAutoFocus\n                                 (blur)=\"cancelEdit()\"\n                                 [(ngModel)]=\"item['value'][2]\"\n                                 (ngModelChange)=\"_emitChangeEvent()\">\n                        </ngs-form-field>\n                      }\n                    }\n                  }\n                  @default {\n                    <ngs-form-field class=\"form-field\">\n                      <input type=\"text\" ngsInput ngsAutoFocus\n                             (blur)=\"cancelEdit()\"\n                             [(ngModel)]=\"item['value'][2]\"\n                             (ngModelChange)=\"_emitChangeEvent()\">\n                    </ngs-form-field>\n                  }\n                }\n              </div>\n            } @else {\n              @if (item['value'][1] !== 'isBlank' && item['value'][1] !== 'isNotBlank') {\n                @if (isValueNotEmpty(item)) {\n                  @if (getFieldType(item) === 'array') {\n                    @if (item['value'][1] === 'equals') {\n                      <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                        {{ getDataSourceItemNameById(item, item['value'][2]) }}\n                      </button>\n                    } @else {\n                      <button class=\"condition-value flex items-center gap-2\" (click)=\"modifyValue(item)\">\n                        @for (dataSourceItemId of item['value'][2]; track dataSourceItemId; let last = $last) {\n                          <span>{{ getDataSourceItemNameById(item, dataSourceItemId) }}</span>\n                          @if (!last) {\n                            <span class=\"text-neutral-500\">|</span>\n                          }\n                        }\n                      </button>\n                    }\n                  } @else {\n                    @if (item['value'][1] === 'isBetween') {\n                      <button class=\"condition-value flex items-center gap-2\" (click)=\"modifyValue(item)\">\n                        <span>{{ item['value'][2][0] }}</span>\n                        <span class=\"text-neutral-500\">&ndash;</span>\n                        <span>{{ item['value'][2][1] }}</span>\n                      </button>\n                    } @else {\n                      <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                        <span>{{ item['value'][2] }}</span>\n                      </button>\n                    }\n                  }\n                } @else {\n                  <button class=\"condition-value\" (click)=\"modifyValue(item)\">\n                    <span i18n>&lt;enter a value&gt;</span>\n                  </button>\n                }\n              }\n            }\n          </div>\n        </div>\n        <ngs-menu #fieldsMenu=\"ngsMenu\">\n          <ng-template ngsMenuContent>\n            <div ngsMenuOptionGroup [ngModel]=\"item['value'][0]\">\n              @for (fieldDef of fieldDefs(); track fieldDef) {\n                <ngs-option [value]=\"fieldDef.dataField\"\n                            (click)=\"selectConditionField(item, fieldDef); fieldsMenuTrigger.closeMenu('click')\">{{ fieldDef.name }}\n                </ngs-option>\n              }\n            </div>\n          </ng-template>\n        </ngs-menu>\n        <ngs-menu #operationsMenu=\"ngsMenu\">\n          <ng-template ngsMenuContent>\n            <div ngsMenuOptionGroup [ngModel]=\"item['value'][1]\">\n              @for (operation of _operationDefs; track operation.id()) {\n                <div [hidden]=\"!isOperationAllowedForCondition(item['value'][0], operation.id())\">\n                  <ngs-option [value]=\"operation.id()\"\n                              (click)=\"operationChanged(item, operation.id()); operationsMenuTrigger.closeMenu('click')\">\n                    <div class=\"flex items-center gap-3\">\n                      @if (operation.operationIcon()) {\n                        <ng-template [ngTemplateOutlet]=\"operationIconTemplateRef(operation)\"/>\n                      }\n                      <div>\n                        <ng-template [ngTemplateOutlet]=\"operationNameTemplateRef(operation)\"/>\n                      </div>\n                    </div>\n                  </ngs-option>\n                </div>\n              }\n            </div>\n          </ng-template>\n        </ngs-menu>\n      }\n    }\n  </div>\n</ng-template>\n\n<div class=\"group\">\n  <div class=\"flex items-center group-operations\">\n    <button [ngsMenuTriggerFor]=\"groupOperationsMenu\"\n            #groupOperationsMenuTrigger=\"ngsMenuTrigger\"\n            class=\"group-operation\">\n      {{ getSelectedGroupOperationName() }}\n    </button>\n    <div [ngsMenuTriggerFor]=\"addMenu\" class=\"add\">\n      <ngs-icon name=\"fluent:add-24-regular\" class=\"font-icon\"/>\n    </div>\n  </div>\n  <ng-container [ngTemplateOutlet]=\"itemsTpl\" [ngTemplateOutletContext]=\"{ $implicit: _value }\"/>\n</div>\n\n<ngs-menu #groupOperationsMenu=\"ngsMenu\">\n  <ng-template ngsMenuContent>\n    <div ngsMenuOptionGroup [(ngModel)]=\"_logicalOperator\" (ngModelChange)=\"_emitChangeEvent()\">\n      @for (operation of groupOperations(); track operation.id) {\n        <ngs-option [value]=\"operation.id\"\n                    (click)=\"groupOperationsMenuTrigger.closeMenu('click')\">{{ operation.name }}\n        </ngs-option>\n      }\n    </div>\n  </ng-template>\n</ngs-menu>\n<ngs-menu #addMenu=\"ngsMenu\">\n  <ng-template ngsMenuContent>\n    <button ngs-menu-item (click)=\"addCondition()\">Add Condition</button>\n    <button ngs-menu-item (click)=\"addGroup()\">Add Group</button>\n  </ng-template>\n</ngs-menu>\n\n<ng-container ngsFilterBuilderOperationDef=\"contains\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Contains</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"doesNotContain\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Does not contain</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"startsWith\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Starts with</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"endsWith\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Ends with</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"equals\" [allowedDataTypes]=\"['string', 'number', 'array', 'boolean']\">\n  <ng-template ngsFilterBuilderOperationName>Equals</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"notEquals\" [allowedDataTypes]=\"['string', 'number', 'boolean']\">\n  <ng-template ngsFilterBuilderOperationName>Not equals</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isLessThen\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is less then</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isLessThenOrEqual\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is less then or equal to</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isGreaterThen\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is greater then</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isGreaterThenOrEqual\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is greater then or equal to</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isBlank\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Is blank</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isNotBlank\" [allowedDataTypes]=\"['string']\">\n  <ng-template ngsFilterBuilderOperationName>Is not blank</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isBetween\" [allowedDataTypes]=\"['number']\">\n  <ng-template ngsFilterBuilderOperationName>Is between</ng-template>\n</ng-container>\n<ng-container ngsFilterBuilderOperationDef=\"isAnyOf\" [allowedDataTypes]=\"['array']\">\n  <ng-template ngsFilterBuilderOperationName>Is any of</ng-template>\n</ng-container>\n", styles: [":host{--ngs-filter-builder-group-operations-gap: calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-group-operation-font-size: var(--text-tiny);--ngs-filter-builder-group-operation-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-bg: var(--ngs-color-surface-container);--ngs-filter-builder-group-operation-font-weight: 400;--ngs-filter-builder-group-operation-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-group-operation-bpadding: 0 calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-group-operation-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-group-operation-hover-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-hover-bg: var(--ngs-color-surface-container-high);--ngs-filter-builder-group-operation-active-color: var(--ngs-color-on-surface);--ngs-filter-builder-group-operation-active-bg: var(--ngs-color-surface-container-highest);--ngs-filter-builder-group-operation-border: 1px solid var(--ngs-color-border);--ngs-filter-builder-group-add-color: var(--ngs-color-primary);--ngs-filter-builder-group-add-hover-color: var(--ngs-color-primary);--ngs-filter-builder-group-margin: 0;--ngs-filter-builder-group-padding: 0;--ngs-filter-builder-group-gap: calc(var(--spacing, .25rem) * 4);--ngs-filter-builder-condition-gap: calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-field-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-field-font-size: var(--text-tiny);--ngs-filter-builder-condition-field-color: var(--ngs-color-on-primary-container);--ngs-filter-builder-condition-field-bg: var(--ngs-color-primary-container);--ngs-filter-builder-condition-field-font-weight: 400;--ngs-filter-builder-condition-field-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-field-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-field-hover-color: var(--ngs-color-on-primary-container);--ngs-filter-builder-condition-field-hover-bg: var(--ngs-color-primary-400);--ngs-filter-builder-condition-field-active-color: var(--ngs-color-on-primary);--ngs-filter-builder-condition-field-active-bg: var(--ngs-color-primary);--ngs-filter-builder-condition-operation-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-operation-font-size: var(--text-tiny);--ngs-filter-builder-condition-operation-color: var(--ngs-color-on-secondary-container);--ngs-filter-builder-condition-operation-bg: var(--ngs-color-secondary-container);--ngs-filter-builder-condition-operation-font-weight: 400;--ngs-filter-builder-condition-operation-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-operation-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-operation-hover-color: var(--ngs-color-on-secondary-container);--ngs-filter-builder-condition-operation-hover-bg: var(--ngs-color-secondary-400);--ngs-filter-builder-condition-operation-active-color: var(--ngs-color-on-secondary);--ngs-filter-builder-condition-operation-active-bg: var(--ngs-color-secondary);--ngs-filter-builder-condition-value-height: calc(var(--spacing, .25rem) * 7);--ngs-filter-builder-condition-value-font-size: var(--text-tiny);--ngs-filter-builder-condition-value-color: var(--ngs-color-on-surface);--ngs-filter-builder-condition-value-bg: var(--ngs-color-surface-container-high);--ngs-filter-builder-condition-value-font-weight: 400;--ngs-filter-builder-condition-value-border-radius: var(--ngs-radius-lg);--ngs-filter-builder-condition-value-bpadding: calc(var(--spacing, .25rem) * .5) calc(var(--spacing, .25rem) * 2);--ngs-filter-builder-condition-value-hover-color: var(--ngs-color-on-surface);--ngs-filter-builder-condition-value-hover-bg: var(--ngs-color-surface-container-highest);--ngs-filter-builder-condition-remove-color: var(--ngs-color-danger);--ngs-filter-builder-condition-remove-hover-color: var(--ngs-color-danger);display:block}:host ::ng-deep .ngs-form-field-infix{--ngs-form-field-container-height: 46px !important;--ngs-form-field-container-vertical-padding: 12px !important}:host ::ng-deep .subscript-wrapper{display:none}:host .form-field{width:200px}:host .form-field-number{width:140px}:host .group-operations{gap:var(--ngs-filter-builder-group-operations-gap)}:host .group{margin:var(--ngs-filter-builder-group-margin);padding:var(--ngs-filter-builder-group-padding);display:flex;flex-direction:column;gap:var(--ngs-filter-builder-group-gap)}:host .group .group{margin-left:calc(var(--spacing, .25rem) * 4)}:host .icon:empty{display:none}:host .group-operation{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-group-operation-height);font-size:var(--ngs-filter-builder-group-operation-font-size);font-weight:var(--ngs-filter-builder-group-operation-font-weight);color:var(--ngs-filter-builder-group-operation-color);background:var(--ngs-filter-builder-group-operation-bg);border:var(--ngs-filter-builder-group-operation-border);border-radius:var(--ngs-filter-builder-group-operation-border-radius);padding:var(--ngs-filter-builder-group-operation-bpadding)}:host .group-operation:hover{color:var(--ngs-filter-builder-group-operation-hover-color);background:var(--ngs-filter-builder-group-operation-hover-bg)}:host .group-operation:active,:host .group-operation.active{color:var(--ngs-filter-builder-group-operation-active-color);background:var(--ngs-filter-builder-group-operation-active-bg)}:host .condition{display:flex;align-items:center;gap:var(--ngs-filter-builder-condition-gap)}:host .condition-field{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-field-height);font-size:var(--ngs-filter-builder-condition-field-font-size);font-weight:var(--ngs-filter-builder-condition-field-font-weight);color:var(--ngs-filter-builder-condition-field-color);background:var(--ngs-filter-builder-condition-field-bg);border-radius:var(--ngs-filter-builder-condition-field-border-radius);padding:var(--ngs-filter-builder-condition-field-bpadding)}:host .condition-field:hover{color:var(--ngs-filter-builder-condition-field-hover-color);background:var(--ngs-filter-builder-condition-field-hover-bg)}:host .add{line-height:0;color:var(--ngs-filter-builder-group-add-color);cursor:pointer}:host .add:hover{color:var(--ngs-filter-builder-group-add-hover-color)}:host .remove{line-height:0;color:var(--ngs-filter-builder-condition-remove-color);cursor:pointer}:host .remove:hover{color:var(--ngs-filter-builder-condition-remove-hover-color)}:host .condition-field:active,:host .condition-field.active{color:var(--ngs-filter-builder-condition-field-active-color);background:var(--ngs-filter-builder-condition-field-active-bg)}:host .condition-operation{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-operation-height);font-size:var(--ngs-filter-builder-condition-operation-font-size);font-weight:var(--ngs-filter-builder-condition-operation-font-weight);color:var(--ngs-filter-builder-condition-operation-color);background:var(--ngs-filter-builder-condition-operation-bg);border-radius:var(--ngs-filter-builder-condition-operation-border-radius);padding:var(--ngs-filter-builder-condition-operation-bpadding)}:host .condition-operation:hover{color:var(--ngs-filter-builder-condition-operation-hover-color);background:var(--ngs-filter-builder-condition-operation-hover-bg)}:host .condition-operation:active,:host .condition-operation.active{color:var(--ngs-filter-builder-condition-operation-active-color);background:var(--ngs-filter-builder-condition-operation-active-bg)}:host .condition-value{display:flex;align-items:center;width:max-content;-webkit-user-select:none;user-select:none;cursor:pointer;height:var(--ngs-filter-builder-condition-value-height);font-size:var(--ngs-filter-builder-condition-value-font-size);font-weight:var(--ngs-filter-builder-condition-value-font-weight);color:var(--ngs-filter-builder-condition-value-color);background:var(--ngs-filter-builder-condition-value-bg);border-radius:var(--ngs-filter-builder-condition-value-border-radius);padding:var(--ngs-filter-builder-condition-value-bpadding)}:host .condition-value:hover{color:var(--ngs-filter-builder-condition-value-hover-color);background:var(--ngs-filter-builder-condition-value-hover-bg)}:host-context(html.dark){--ngs-filter-builder-group-operation-color: var(--ngs-color-neutral-200);--ngs-filter-builder-group-operation-hover-bg: var(--ngs-color-neutral-600);--ngs-filter-builder-group-operation-active-bg: var(--ngs-color-neutral-650);--ngs-filter-builder-group-operation-hover-color: var(--ngs-color-neutral-100);--ngs-filter-builder-group-operation-active-color: var(--ngs-color-neutral-50)}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], fieldDefs: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldDefs", required: false }] }], categories: [{ type: i0.Input, args: [{ isSignal: true, alias: "categories", required: false }] }], groupOperations: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupOperations", required: false }] }], customOperations: [{ type: i0.Input, args: [{ isSignal: true, alias: "customOperations", required: false }] }], _prebuiltOperationDefs: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => FilterBuilderOperationDefDirective), { isSignal: true }] }], _customOperationDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => FilterBuilderOperationDefDirective), { isSignal: true }] }], valueChanged: [{ type: i0.Output, args: ["valueChanged"] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { FilterBuilder, FilterBuilderOperationDefDirective, FilterBuilderOperationIconDirective, FilterBuilderOperationNameDirective };
//# sourceMappingURL=ngstarter-ui-components-filter-builder.mjs.map
