Socket
Socket
Sign inDemoInstall

@momsfriendlydevco/angular-ui-query-builder

Package Overview
Dependencies
Maintainers
3
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@momsfriendlydevco/angular-ui-query-builder - npm Package Compare versions

Comparing version 1.1.7 to 1.1.8

2

dist/angular-ui-query-builder.js

@@ -46,3 +46,3 @@ 'use strict';

},
template: '\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t<!-- Root branch display {{{ -->\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<!-- }}} -->\n\t\t\t<!-- Path component {{{ -->\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t({{leaf.id ? \'HASID\' : \'NOID\'}})\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query type component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query operand component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t</div>\n\t\t<!-- Add button {{{ -->\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t<!-- }}} -->\n\t',
template: '\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t<!-- Root branch display {{{ -->\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<!-- }}} -->\n\t\t\t<!-- Path component {{{ -->\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query type component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query operand component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t</div>\n\t\t<!-- Add button {{{ -->\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t<!-- }}} -->\n\t',
controller: ['$element', '$scope', function controller($element, $scope) {

@@ -49,0 +49,0 @@ var $ctrl = this;

@@ -1,1 +0,1 @@

"use strict";function _defineProperty(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}angular.module("angular-ui-query-builder",[]).component("uiQueryBuilder",{bindings:{query:"=",spec:"<"},template:'\n\t\t<div class="ui-query-builder">\n\t\t\t<ui-query-builder-branch\n\t\t\t\tbranch="$ctrl.query"\n\t\t\t\tspec="$ctrl.spec"\n\t\t\t></ui-query-builder-branch>\n\t\t</div>\n\t',controller:["$scope",function(t){var e=this;t.$watch("$ctrl.spec",function(){_.forEach(e.spec,function(t,e){t.title||(t.title=_.startCase(e)),t.enum&&_.isArray(t.enum)&&(t.enum=_(t.enum).map(function(t){return _.isString(t)?{id:t,title:_.startCase(t)}:t}).sortBy("title").value())})})}]}).component("uiQueryBuilderBranch",{bindings:{branch:"=",spec:"<"},template:'\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t\x3c!-- Root branch display {{{ --\x3e\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t\x3c!-- Path component {{{ --\x3e\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t({{leaf.id ? \'HASID\' : \'NOID\'}})\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query type component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query operand component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t</div>\n\t\t\x3c!-- Add button {{{ --\x3e\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t\x3c!-- }}} --\x3e\n\t',controller:["$element","$scope",function(t,e){var n=this;n.operands=[{id:"$eq",setter:function(t){return{$eq:t}},export:function(t){return t.valueEdit},base:{title:"Is",type:"string"},boolean:{title:"Is",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$ne",setter:function(t){return{$ne:t}},export:function(t){return t.valueEdit},base:{title:"Is not",type:"string"},boolean:{title:"Is not",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$in",setter:function(t){return{$in:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$in:t.value.$in}},base:{title:"One of",type:"array"}},{id:"$nin",setter:function(t){return{$nin:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$nin:t.value.$nin}},base:{title:"Not one of",type:"array"}},{id:"$gt",setter:function(t){return{$gt:t}},export:function(t){return{$gt:t.value.$gt}},base:{title:"Above",type:"number"}},{id:"$gte",setter:function(t){return{$gte:t}},export:function(t){return{$gte:t.value.$gte}},base:{title:"Above or equals",type:"number"}},{id:"$lt",setter:function(t){return{$lt:t}},export:function(t){return{$lt:t.value.$lt}},base:{title:"Below",type:"number"}},{id:"$lte",setter:function(t){return{$lt:t}},export:function(t){return{$lte:t.value.$lte}},base:{title:"Below or equals",type:"number"}},{id:"$exists",setter:function(t){return{$exists:!!t}},export:function(t){return{$exists:t.value.$exists}},base:{title:"Has a value",type:"boolean",textTrue:"Has a value",textFalse:"Has no value"}},{id:"$regexp",setter:function(t){return{$regexp:t}},export:function(t){return{$regexp:t.value.$regexp}},base:{title:"Matches",type:"string"}}],n.operandsByID=_.mapKeys(n.operands,"id"),n.getSpec=function(t,e,a){return n.spec[a]?n.spec[a]:"$and"==t||"$or"==t?_defineProperty({type:"group"},"type",t):_.isString(e)?{type:"string"}:_.isNumber(e)?{type:"number"}:{type:"string"}},n.translateBranch=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return _(n.branch).map(function(t,a){var r=_.isObject(t)?_(t).keys().first():"$eq";return{id:a,value:t,valueEdit:(_.isObject(t)&&_.size(t)>0?_(t).map().first():void 0)||t,valueOperand:r,isMeta:a.startsWith("$"),spec:n.getSpec(a,t,a),path:e.concat([a])}}).sortBy(function(t){return t.isMeta?"Z"+t.id:"A"+t.id}).value()},n.exportBranch=function(){n.branch=_(n.properties).mapKeys(function(t){return t.id}).mapValues(function(t){return n.operandsByID[t.valueOperand].export(t)}).value()},n.properties,e.$watchGroup(["$ctrl.branch","$ctrl.spec"],function(){n.branch&&n.spec&&(n.properties=n.translateBranch(n.branch))}),n.setField=function(t,e){t.id=e,t.path=[e],t.value=void 0,t.valueEdit=void 0,t.valueOperand="$eq",t.spec=n.spec[e],n.setValue(t)},n.setWrapper=function(t,e){var a={};_.isObject(t.value)&&1==_.size(t.value)?a[e]=_(t.value).values().first():a[e]=t.valueEdit,t.valueOperand=e,t.value=a,t.valueEdit=_.isObject(a[e])&&_.size(a[e])?a[e]:a,n.setValue(t)},n.setValue=function(t,e){var a=_.isUndefined(e)?t.valueEdit:e;t.value=n.operandsByID[t.valueOperand].setter(a),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value,n.exportBranch()},n.setValueIncluded=function(t,e,n){var a=_(t.value).keys().first();if(!a)throw new Error("Tried to set array inclusion on non wrapped key: "+t.value);var r=t.value[a].includes(e);n&&!r?t.value[a].push(e):!n&&r&&(t.value[a]=t.value[a].filter(function(t){return t!=e})),t.value[a].sort(),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value},n.add=function(){if(!n.properties.some(function(t){return!t.id})){n.properties.push({});e.$on("uiQueryQueryRepaint",function(){t.find(".query-block > .new").addClass("open")})}},n.remove=function(t){n.properties=n.properties.filter(function(e){return e.id!=t}),n.exportBranch()}}]}).filter("uiQueryBuilderFilterSelected",function(){return function(t,e,n){if(t)return t.filter(function(t){var a=e.valueEdit.includes(t.id);return n?!a:a})}}).directive("ngRepeatEmit",["$rootScope","$timeout",function(t,e){return{restrict:"A",link:function(t,n,a){!0===t.$last&&e(function(){return t.$emit(a.ngRepeatEmit)})}}}]);
"use strict";function _defineProperty(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}angular.module("angular-ui-query-builder",[]).component("uiQueryBuilder",{bindings:{query:"=",spec:"<"},template:'\n\t\t<div class="ui-query-builder">\n\t\t\t<ui-query-builder-branch\n\t\t\t\tbranch="$ctrl.query"\n\t\t\t\tspec="$ctrl.spec"\n\t\t\t></ui-query-builder-branch>\n\t\t</div>\n\t',controller:["$scope",function(t){var e=this;t.$watch("$ctrl.spec",function(){_.forEach(e.spec,function(t,e){t.title||(t.title=_.startCase(e)),t.enum&&_.isArray(t.enum)&&(t.enum=_(t.enum).map(function(t){return _.isString(t)?{id:t,title:_.startCase(t)}:t}).sortBy("title").value())})})}]}).component("uiQueryBuilderBranch",{bindings:{branch:"=",spec:"<"},template:'\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t\x3c!-- Root branch display {{{ --\x3e\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t\x3c!-- Path component {{{ --\x3e\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query type component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query operand component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t</div>\n\t\t\x3c!-- Add button {{{ --\x3e\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t\x3c!-- }}} --\x3e\n\t',controller:["$element","$scope",function(t,e){var n=this;n.operands=[{id:"$eq",setter:function(t){return{$eq:t}},export:function(t){return t.valueEdit},base:{title:"Is",type:"string"},boolean:{title:"Is",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$ne",setter:function(t){return{$ne:t}},export:function(t){return t.valueEdit},base:{title:"Is not",type:"string"},boolean:{title:"Is not",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$in",setter:function(t){return{$in:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$in:t.value.$in}},base:{title:"One of",type:"array"}},{id:"$nin",setter:function(t){return{$nin:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$nin:t.value.$nin}},base:{title:"Not one of",type:"array"}},{id:"$gt",setter:function(t){return{$gt:t}},export:function(t){return{$gt:t.value.$gt}},base:{title:"Above",type:"number"}},{id:"$gte",setter:function(t){return{$gte:t}},export:function(t){return{$gte:t.value.$gte}},base:{title:"Above or equals",type:"number"}},{id:"$lt",setter:function(t){return{$lt:t}},export:function(t){return{$lt:t.value.$lt}},base:{title:"Below",type:"number"}},{id:"$lte",setter:function(t){return{$lt:t}},export:function(t){return{$lte:t.value.$lte}},base:{title:"Below or equals",type:"number"}},{id:"$exists",setter:function(t){return{$exists:!!t}},export:function(t){return{$exists:t.value.$exists}},base:{title:"Has a value",type:"boolean",textTrue:"Has a value",textFalse:"Has no value"}},{id:"$regexp",setter:function(t){return{$regexp:t}},export:function(t){return{$regexp:t.value.$regexp}},base:{title:"Matches",type:"string"}}],n.operandsByID=_.mapKeys(n.operands,"id"),n.getSpec=function(t,e,a){return n.spec[a]?n.spec[a]:"$and"==t||"$or"==t?_defineProperty({type:"group"},"type",t):_.isString(e)?{type:"string"}:_.isNumber(e)?{type:"number"}:{type:"string"}},n.translateBranch=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return _(n.branch).map(function(t,a){var r=_.isObject(t)?_(t).keys().first():"$eq";return{id:a,value:t,valueEdit:(_.isObject(t)&&_.size(t)>0?_(t).map().first():void 0)||t,valueOperand:r,isMeta:a.startsWith("$"),spec:n.getSpec(a,t,a),path:e.concat([a])}}).sortBy(function(t){return t.isMeta?"Z"+t.id:"A"+t.id}).value()},n.exportBranch=function(){n.branch=_(n.properties).mapKeys(function(t){return t.id}).mapValues(function(t){return n.operandsByID[t.valueOperand].export(t)}).value()},n.properties,e.$watchGroup(["$ctrl.branch","$ctrl.spec"],function(){n.branch&&n.spec&&(n.properties=n.translateBranch(n.branch))}),n.setField=function(t,e){t.id=e,t.path=[e],t.value=void 0,t.valueEdit=void 0,t.valueOperand="$eq",t.spec=n.spec[e],n.setValue(t)},n.setWrapper=function(t,e){var a={};_.isObject(t.value)&&1==_.size(t.value)?a[e]=_(t.value).values().first():a[e]=t.valueEdit,t.valueOperand=e,t.value=a,t.valueEdit=_.isObject(a[e])&&_.size(a[e])?a[e]:a,n.setValue(t)},n.setValue=function(t,e){var a=_.isUndefined(e)?t.valueEdit:e;t.value=n.operandsByID[t.valueOperand].setter(a),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value,n.exportBranch()},n.setValueIncluded=function(t,e,n){var a=_(t.value).keys().first();if(!a)throw new Error("Tried to set array inclusion on non wrapped key: "+t.value);var r=t.value[a].includes(e);n&&!r?t.value[a].push(e):!n&&r&&(t.value[a]=t.value[a].filter(function(t){return t!=e})),t.value[a].sort(),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value},n.add=function(){if(!n.properties.some(function(t){return!t.id})){n.properties.push({});e.$on("uiQueryQueryRepaint",function(){t.find(".query-block > .new").addClass("open")})}},n.remove=function(t){n.properties=n.properties.filter(function(e){return e.id!=t}),n.exportBranch()}}]}).filter("uiQueryBuilderFilterSelected",function(){return function(t,e,n){if(t)return t.filter(function(t){var a=e.valueEdit.includes(t.id);return n?!a:a})}}).directive("ngRepeatEmit",["$rootScope","$timeout",function(t,e){return{restrict:"A",link:function(t,n,a){!0===t.$last&&e(function(){return t.$emit(a.ngRepeatEmit)})}}}]);

@@ -14,3 +14,3 @@ 'use strict';

template: '\n\t\t<div class="ui-query-builder">\n\t\t\t<ui-query-builder-branch\n\t\t\t\tbranch="$ctrl.query"\n\t\t\t\tspec="$ctrl.spec"\n\t\t\t></ui-query-builder-branch>\n\t\t</div>\n\t',
controller: ["$scope", function controller($scope) {
controller: ['$scope', function controller($scope) {
var $ctrl = this;

@@ -47,4 +47,4 @@

},
template: '\n\t\t<div class="query-container-leadin"></div>\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" class="query-container">\n\t\t\t<!-- Root branch display {{{ -->\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<!-- }}} -->\n\t\t\t<!-- Path component {{{ -->\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query type component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query operand component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t</div>\n\t\t<!-- Add button {{{ -->\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class="query-container-leadout"></div>\n\t\t<!-- }}} -->\n\t',
controller: ["$scope", function controller($scope) {
template: '\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t<!-- Root branch display {{{ -->\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<!-- }}} -->\n\t\t\t<!-- Path component {{{ -->\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query type component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t<!-- Query operand component {{{ -->\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- }}} -->\n\t\t</div>\n\t\t<!-- Add button {{{ -->\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t<!-- }}} -->\n\t',
controller: ['$element', '$scope', function controller($element, $scope) {
var $ctrl = this;

@@ -328,2 +328,3 @@

// Utility functions {{{
/**

@@ -352,10 +353,24 @@ * Set whether the specified value is included in the leaf array of values

};
// }}}
// New branches {{{
// Branch CRUD {{{
$ctrl.add = function () {
if ($ctrl.properties.every(function (p) {
return p.id;
})) // Check there are no new items currently in the process of being added
$ctrl.properties.push({});
if ($ctrl.properties.some(function (p) {
return !p.id;
})) return; // Check there are no new items currently in the process of being added
$ctrl.properties.push({});
// Wait for the page to redraw then force the dropdown to open
// Yes I know this is a weird work around but we have to wait for the DOM to settle for some reason before we can add the `open` class - MC 2017-10-03
var eventUnbind = $scope.$on('uiQueryQueryRepaint', function () {
$element.find('.query-block > .new').addClass('open');
});
};
$ctrl.remove = function (id) {
$ctrl.properties = $ctrl.properties.filter(function (p) {
return p.id != id;
});
$ctrl.exportBranch();
};
// }}}

@@ -382,3 +397,20 @@ }]

};
});
})
/**
* Fire a $scope.$emit() with the given message when an ng-repeat render finishes
* @param {string} message The message to emit to this element scope upwards
* @example
* <div ng-repeat="widget in widgets" ng-repeat-emit="finished"></div>
*/
.directive('ngRepeatEmit', ['$rootScope', '$timeout', function ($rootScope, $timeout) {
return {
restrict: 'A',
link: function link(scope, elem, attr) {
if (scope.$last === true) $timeout(function () {
return scope.$emit(attr.ngRepeatEmit);
});
}
};
}]);
// }}}

@@ -1,1 +0,1 @@

"use strict";function _defineProperty(obj,key,value){return key in obj?Object.defineProperty(obj,key,{value:value,enumerable:!0,configurable:!0,writable:!0}):obj[key]=value,obj}angular.module("angular-ui-query-builder",[]).component("uiQueryBuilder",{bindings:{query:"=",spec:"<"},template:'\n\t\t<div class="ui-query-builder">\n\t\t\t<ui-query-builder-branch\n\t\t\t\tbranch="$ctrl.query"\n\t\t\t\tspec="$ctrl.spec"\n\t\t\t></ui-query-builder-branch>\n\t\t</div>\n\t',controller:["$scope",function($scope){var $ctrl=this;$scope.$watch("$ctrl.spec",function(){_.forEach($ctrl.spec,function(v,k){v.title||(v.title=_.startCase(k)),v.enum&&_.isArray(v.enum)&&(v.enum=_(v.enum).map(function(e){return _.isString(e)?{id:e,title:_.startCase(e)}:e}).sortBy("title").value())})})}]}).component("uiQueryBuilderBranch",{bindings:{branch:"=",spec:"<"},template:'\n\t\t<div class="query-container-leadin"></div>\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" class="query-container">\n\t\t\t\x3c!-- Root branch display {{{ --\x3e\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t\x3c!-- Path component {{{ --\x3e\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query type component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query operand component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t</div>\n\t\t\x3c!-- Add button {{{ --\x3e\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class="query-container-leadout"></div>\n\t\t\x3c!-- }}} --\x3e\n\t',controller:["$scope",function($scope){var $ctrl=this;$ctrl.operands=[{id:"$eq",setter:function(v){return{$eq:v}},export:function(leaf){return leaf.valueEdit},base:{title:"Is",type:"string"},boolean:{title:"Is",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$ne",setter:function(v){return{$ne:v}},export:function(leaf){return leaf.valueEdit},base:{title:"Is not",type:"string"},boolean:{title:"Is not",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$in",setter:function(v){return{$in:_.isArray(v)?v.split(/\s*,\s*/):[v]}},export:function(leaf){return{$in:leaf.value.$in}},base:{title:"One of",type:"array"}},{id:"$nin",setter:function(v){return{$nin:_.isArray(v)?v.split(/\s*,\s*/):[v]}},export:function(leaf){return{$nin:leaf.value.$nin}},base:{title:"Not one of",type:"array"}},{id:"$gt",setter:function(v){return{$gt:v}},export:function(leaf){return{$gt:leaf.value.$gt}},base:{title:"Above",type:"number"}},{id:"$gte",setter:function(v){return{$gte:v}},export:function(leaf){return{$gte:leaf.value.$gte}},base:{title:"Above or equals",type:"number"}},{id:"$lt",setter:function(v){return{$lt:v}},export:function(leaf){return{$lt:leaf.value.$lt}},base:{title:"Below",type:"number"}},{id:"$lte",setter:function(v){return{$lt:v}},export:function(leaf){return{$lte:leaf.value.$lte}},base:{title:"Below or equals",type:"number"}},{id:"$exists",setter:function(v){return{$exists:!!v}},export:function(leaf){return{$exists:leaf.value.$exists}},base:{title:"Has a value",type:"boolean",textTrue:"Has a value",textFalse:"Has no value"}},{id:"$regexp",setter:function(v){return{$regexp:v}},export:function(leaf){return{$regexp:leaf.value.$regexp}},base:{title:"Matches",type:"string"}}],$ctrl.operandsByID=_.mapKeys($ctrl.operands,"id"),$ctrl.getSpec=function(key,val,path){return $ctrl.spec[path]?$ctrl.spec[path]:"$and"==key||"$or"==key?_defineProperty({type:"group"},"type",key):_.isString(val)?{type:"string"}:_.isNumber(val)?{type:"number"}:{type:"string"}},$ctrl.translateBranch=function(branch){var pathSegments=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return _($ctrl.branch).map(function(v,k){var wrappingKey=_.isObject(v)?_(v).keys().first():"$eq";return{id:k,value:v,valueEdit:(_.isObject(v)&&_.size(v)>0?_(v).map().first():void 0)||v,valueOperand:wrappingKey,isMeta:k.startsWith("$"),spec:$ctrl.getSpec(k,v,k),path:pathSegments.concat([k])}}).sortBy(function(p){return p.isMeta?"Z"+p.id:"A"+p.id}).value()},$ctrl.exportBranch=function(){$ctrl.branch=_($ctrl.properties).mapKeys(function(b){return b.id}).mapValues(function(b){return $ctrl.operandsByID[b.valueOperand].export(b)}).value()},$ctrl.properties,$scope.$watchGroup(["$ctrl.branch","$ctrl.spec"],function(){$ctrl.branch&&$ctrl.spec&&($ctrl.properties=$ctrl.translateBranch($ctrl.branch))}),$ctrl.setField=function(leaf,field){leaf.id=field,leaf.path=[field],leaf.value=void 0,leaf.valueEdit=void 0,leaf.valueOperand="$eq",leaf.spec=$ctrl.spec[field],$ctrl.setValue(leaf)},$ctrl.setWrapper=function(leaf,type){var newValue={};_.isObject(leaf.value)&&1==_.size(leaf.value)?newValue[type]=_(leaf.value).values().first():newValue[type]=leaf.valueEdit,leaf.valueOperand=type,leaf.value=newValue,leaf.valueEdit=_.isObject(newValue[type])&&_.size(newValue[type])?newValue[type]:newValue,$ctrl.setValue(leaf)},$ctrl.setValue=function(leaf,value){var newValue=_.isUndefined(value)?leaf.valueEdit:value;leaf.value=$ctrl.operandsByID[leaf.valueOperand].setter(newValue),leaf.valueEdit=_.isObject(leaf.value)&&_.size(leaf.value)?_(leaf.value).map().first():leaf.value,$ctrl.exportBranch()},$ctrl.setValueIncluded=function(leaf,value,included){var wrapperKey=_(leaf.value).keys().first();if(!wrapperKey)throw new Error("Tried to set array inclusion on non wrapped key: "+leaf.value);var isIncluded=leaf.value[wrapperKey].includes(value);included&&!isIncluded?leaf.value[wrapperKey].push(value):!included&&isIncluded&&(leaf.value[wrapperKey]=leaf.value[wrapperKey].filter(function(i){return i!=value})),leaf.value[wrapperKey].sort(),leaf.valueEdit=_.isObject(leaf.value)&&_.size(leaf.value)?_(leaf.value).map().first():leaf.value},$ctrl.add=function(){$ctrl.properties.every(function(p){return p.id})&&$ctrl.properties.push({})}}]}).filter("uiQueryBuilderFilterSelected",function(){return function(items,leaf,invert){if(items)return items.filter(function(i){var doesInclude=leaf.valueEdit.includes(i.id);return invert?!doesInclude:doesInclude})}});
"use strict";function _defineProperty(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}angular.module("angular-ui-query-builder",[]).component("uiQueryBuilder",{bindings:{query:"=",spec:"<"},template:'\n\t\t<div class="ui-query-builder">\n\t\t\t<ui-query-builder-branch\n\t\t\t\tbranch="$ctrl.query"\n\t\t\t\tspec="$ctrl.spec"\n\t\t\t></ui-query-builder-branch>\n\t\t</div>\n\t',controller:["$scope",function(t){var e=this;t.$watch("$ctrl.spec",function(){_.forEach(e.spec,function(t,e){t.title||(t.title=_.startCase(e)),t.enum&&_.isArray(t.enum)&&(t.enum=_(t.enum).map(function(t){return _.isString(t)?{id:t,title:_.startCase(t)}:t}).sortBy("title").value())})})}]}).component("uiQueryBuilderBranch",{bindings:{branch:"=",spec:"<"},template:'\n\t\t<div ng-repeat="leaf in $ctrl.properties track by leaf.id" ng-switch="leaf.spec.type" ng-repeat-emit="uiQueryQueryRepaint" class="query-container">\n\t\t\t\x3c!-- Root branch display {{{ --\x3e\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t\x3c!-- Path component {{{ --\x3e\n\t\t\t<div class="query-block">\n\t\t\t\t<div class="btn-group btn-block" ng-class="{new: !leaf.id}">\n\t\t\t\t\t<a class="btn btn-1 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<div ng-click="$ctrl.remove(leaf.id); $event.stopPropagation()" class="btn btn-trash btn-danger btn-xs pull-left">\n\t\t\t\t\t\t\t<i class="fa fa-times"></i>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{{$ctrl.spec[leaf.id].title || \'Select...\'}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="(key, val) in $ctrl.spec track by key" ng-class="key == leaf.id && \'active\'">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setField(leaf, key)">\n\t\t\t\t\t\t\t\t{{$ctrl.spec[key].title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query type component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block">\n\t\t\t\t<div class="btn-group btn-block">\n\t\t\t\t\t<a class="btn btn-2 btn-block dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t{{($ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).title}}\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</a>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$eq\')">Is</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$ne\')">Is not</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$in\')">One of</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$nin\')">Not one of</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">Above</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'number\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Below</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$gt\')">After</a></li>\n\t\t\t\t\t\t<li ng-if="leaf.spec.type == \'date\'"><a ng-click="$ctrl.setWrapper(leaf, \'$lt\')">Before</a></li>\n\t\t\t\t\t\t<li><a ng-click="$ctrl.setWrapper(leaf, \'$exists\')">Has a value</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-stem"><div></div></div>\n\t\t\t\x3c!-- Query operand component {{{ --\x3e\n\t\t\t<div ng-show="leaf.valueOperand" class="query-block btn-group" ng-switch="(operandConfig = $ctrl.operandsByID[leaf.valueOperand][leaf.spec.type] || $ctrl.operandsByID[leaf.valueOperand].base).type">\n\t\t\t\t<div ng-switch-when="string" class="btn btn-block btn-3">\n\t\t\t\t\t<input ng-model="leaf.valueEdit" ng-change="$ctrl.setValue(leaf)" type="text" class="form-control"/>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="array" class="btn btn-block btn-3 btn-group">\n\t\t\t\t\t<div class="btn-fill text-left dropdown-toggle" data-toggle="dropdown">\n\t\t\t\t\t\t<span class="pill" ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf track by item.id">\n\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<span ng-if="!leaf.valueEdit.length">...</span>\n\t\t\t\t\t\t<i class="fa fa-caret-down"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<ul class="dropdown-menu pull-right">\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:false track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, false)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-check-square text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li ng-repeat="item in $ctrl.spec[leaf.id].enum | uiQueryBuilderFilterSelected:leaf:true track by item.id">\n\t\t\t\t\t\t\t<a ng-click="$ctrl.setValueIncluded(leaf, item.id, true)">\n\t\t\t\t\t\t\t\t<i class="fa fa-fw fa-square-o text-primary"></i>\n\t\t\t\t\t\t\t\t{{item.title}}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-when="boolean" class="btn btn-block btn-3" ng-click="$ctrl.setValue(leaf, !leaf.valueEdit)">\n\t\t\t\t\t<i class="fa" ng-class="leaf.valueEdit ? \'fa-check-square-o\' : \'fa-square-o\'"></i>\n\t\t\t\t\t{{leaf.valueEdit ? operandConfig.textTrue : operandConfig.textFalse}}\n\t\t\t\t</div>\n\t\t\t\t<div ng-switch-default class="btn btn-block btn-3">\n\t\t\t\t\tUnknown operand: <code>{{leaf.valueOperand}}</code>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t\x3c!-- }}} --\x3e\n\t\t</div>\n\t\t\x3c!-- Add button {{{ --\x3e\n\t\t<div class="query-container">\n\t\t\t<div class="query-stem"><div></div></div>\n\t\t\t<div class="query-block btn-group">\n\t\t\t\t<a ng-click="$ctrl.add()" class="btn btn-lg btn-add btn-default">\n\t\t\t\t\t<i class="fa fa-fw fa-plus fa-lg"></i>\n\t\t\t\t</a>\n\t\t\t</div>\n\t\t</div>\n\t\t\x3c!-- }}} --\x3e\n\t',controller:["$element","$scope",function(t,e){var n=this;n.operands=[{id:"$eq",setter:function(t){return{$eq:t}},export:function(t){return t.valueEdit},base:{title:"Is",type:"string"},boolean:{title:"Is",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$ne",setter:function(t){return{$ne:t}},export:function(t){return t.valueEdit},base:{title:"Is not",type:"string"},boolean:{title:"Is not",type:"boolean",textTrue:"Enabled",textFalse:"Disabled"}},{id:"$in",setter:function(t){return{$in:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$in:t.value.$in}},base:{title:"One of",type:"array"}},{id:"$nin",setter:function(t){return{$nin:_.isArray(t)?t.split(/\s*,\s*/):[t]}},export:function(t){return{$nin:t.value.$nin}},base:{title:"Not one of",type:"array"}},{id:"$gt",setter:function(t){return{$gt:t}},export:function(t){return{$gt:t.value.$gt}},base:{title:"Above",type:"number"}},{id:"$gte",setter:function(t){return{$gte:t}},export:function(t){return{$gte:t.value.$gte}},base:{title:"Above or equals",type:"number"}},{id:"$lt",setter:function(t){return{$lt:t}},export:function(t){return{$lt:t.value.$lt}},base:{title:"Below",type:"number"}},{id:"$lte",setter:function(t){return{$lt:t}},export:function(t){return{$lte:t.value.$lte}},base:{title:"Below or equals",type:"number"}},{id:"$exists",setter:function(t){return{$exists:!!t}},export:function(t){return{$exists:t.value.$exists}},base:{title:"Has a value",type:"boolean",textTrue:"Has a value",textFalse:"Has no value"}},{id:"$regexp",setter:function(t){return{$regexp:t}},export:function(t){return{$regexp:t.value.$regexp}},base:{title:"Matches",type:"string"}}],n.operandsByID=_.mapKeys(n.operands,"id"),n.getSpec=function(t,e,a){return n.spec[a]?n.spec[a]:"$and"==t||"$or"==t?_defineProperty({type:"group"},"type",t):_.isString(e)?{type:"string"}:_.isNumber(e)?{type:"number"}:{type:"string"}},n.translateBranch=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];return _(n.branch).map(function(t,a){var r=_.isObject(t)?_(t).keys().first():"$eq";return{id:a,value:t,valueEdit:(_.isObject(t)&&_.size(t)>0?_(t).map().first():void 0)||t,valueOperand:r,isMeta:a.startsWith("$"),spec:n.getSpec(a,t,a),path:e.concat([a])}}).sortBy(function(t){return t.isMeta?"Z"+t.id:"A"+t.id}).value()},n.exportBranch=function(){n.branch=_(n.properties).mapKeys(function(t){return t.id}).mapValues(function(t){return n.operandsByID[t.valueOperand].export(t)}).value()},n.properties,e.$watchGroup(["$ctrl.branch","$ctrl.spec"],function(){n.branch&&n.spec&&(n.properties=n.translateBranch(n.branch))}),n.setField=function(t,e){t.id=e,t.path=[e],t.value=void 0,t.valueEdit=void 0,t.valueOperand="$eq",t.spec=n.spec[e],n.setValue(t)},n.setWrapper=function(t,e){var a={};_.isObject(t.value)&&1==_.size(t.value)?a[e]=_(t.value).values().first():a[e]=t.valueEdit,t.valueOperand=e,t.value=a,t.valueEdit=_.isObject(a[e])&&_.size(a[e])?a[e]:a,n.setValue(t)},n.setValue=function(t,e){var a=_.isUndefined(e)?t.valueEdit:e;t.value=n.operandsByID[t.valueOperand].setter(a),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value,n.exportBranch()},n.setValueIncluded=function(t,e,n){var a=_(t.value).keys().first();if(!a)throw new Error("Tried to set array inclusion on non wrapped key: "+t.value);var r=t.value[a].includes(e);n&&!r?t.value[a].push(e):!n&&r&&(t.value[a]=t.value[a].filter(function(t){return t!=e})),t.value[a].sort(),t.valueEdit=_.isObject(t.value)&&_.size(t.value)?_(t.value).map().first():t.value},n.add=function(){if(!n.properties.some(function(t){return!t.id})){n.properties.push({});e.$on("uiQueryQueryRepaint",function(){t.find(".query-block > .new").addClass("open")})}},n.remove=function(t){n.properties=n.properties.filter(function(e){return e.id!=t}),n.exportBranch()}}]}).filter("uiQueryBuilderFilterSelected",function(){return function(t,e,n){if(t)return t.filter(function(t){var a=e.valueEdit.includes(t.id);return n?!a:a})}}).directive("ngRepeatEmit",["$rootScope","$timeout",function(t,e){return{restrict:"A",link:function(t,n,a){!0===t.$last&&e(function(){return t.$emit(a.ngRepeatEmit)})}}}]);
{
"name": "@momsfriendlydevco/angular-ui-query-builder",
"version": "1.1.7",
"version": "1.1.8",
"description": "MongoDB format query-builder UI component for Angular",

@@ -5,0 +5,0 @@ "main": "dist/angular-ui-query-builder.js",

@@ -62,3 +62,2 @@ angular.module('angular-ui-query-builder',[])

{{$ctrl.spec[leaf.id].title || 'Select...'}}
({{leaf.id ? 'HASID' : 'NOID'}})
<i class="fa fa-caret-down"></i>

@@ -65,0 +64,0 @@ </a>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc