🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Book a DemoInstallSign in
Socket

angular-elastic-builder

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-elastic-builder - npm Package Compare versions

Comparing version

to
1.5.0

.eslintrc

213

dist/angular-elastic-builder.js

@@ -5,3 +5,3 @@ /**

*
* @version v1.4.0
* @version v1.5.0
* @link https://github.com/dncrews/angular-elastic-builder.git

@@ -25,2 +25,3 @@ * @license MIT

'RecursionHelper',
'ui.bootstrap',
]);

@@ -89,3 +90,3 @@

scope.$watch('data.needsUpdate', function(curr) {
if (! curr) return;
if (!curr) return;

@@ -100,9 +101,9 @@ scope.filters = elasticQueryService.toFilters(data.query, scope.data.fields);

scope.$watch('filters', function(curr) {
if (! curr) return;
if (!curr) return;
data.query = elasticQueryService.toQuery(scope.filters, scope.data.fields);
}, true);
}
},
};
}
},

@@ -143,3 +144,3 @@ ]);

return RH.compile(element, function(scope, el, attrs) {
var depth = scope.depth = (+ attrs.depth)
var depth = scope.depth = (+attrs.depth)
, item = scope.item;

@@ -154,5 +155,5 @@

});
}
},
};
}
},

@@ -191,3 +192,3 @@ ]);

return RH.compile(element, function(scope, el, attrs) {
var depth = scope.depth = (+ attrs.depth);
var depth = scope.depth = (+attrs.depth);
var group = scope.group;

@@ -214,5 +215,5 @@

});
}
},
};
}
},

@@ -251,3 +252,3 @@ ]);

if (! fields || ! field) return;
if (!fields || !field) return;

@@ -258,5 +259,5 @@ if (fields[field].subType === 'boolean') return 'boolean';

};
}
},
};
}
},

@@ -295,3 +296,3 @@ ]);

var type = scope.type;
if (! type) return;
if (!type) return;

@@ -320,5 +321,62 @@ type = type.charAt(0).toUpperCase() + type.slice(1);

};
scope.numberNeeded = function() {
var needs = [
'last',
'next',
];
return ~needs.indexOf(scope.rule.subType);
};
scope.today = function() {
scope.rule.date = new Date();
};
scope.today();
scope.clear = function() {
scope.rule.date = null;
};
scope.dateOptions = {
dateDisabled: disabled,
formatYear: 'yy',
maxDate: new Date(2018, 1, 13),
minDate: new Date(),
startingDay: 1,
};
// Disable weekend selection
function disabled(data) {
var date = data.date
, mode = data.mode;
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
}
scope.open1 = function() {
scope.popup1.opened = true;
};
scope.setDate = function(year, month, day) {
scope.rule.date = new Date(year, month - 1, day);
};
scope.formats = [
'yyyy-MM-ddTHH:mm:ss',
'yyyy-MM-ddTHH:mm:ssZ',
'yyyy-MM-dd',
'dd-MMMM-yyyy',
'yyyy/MM/dd',
'shortDate',
];
scope.rule.dateFormat = scope.formats[0];
scope.format = scope.rule.dateFormat;
scope.altInputFormats = ['M!/d!/yyyy'];
scope.popup1 = { opened: false };
},
};
}
},

@@ -371,9 +429,13 @@ ]);

.factory('elasticQueryService', [
function() {
'$filter',
function($filter) {
return {
toFilters: toFilters,
toQuery: toQuery,
toQuery: function(filters, fieldMap) {
return toQuery(filters, fieldMap, $filter);
},
};
}
},
]);

@@ -386,5 +448,5 @@

function toQuery(filters, fieldMap){
var query = filters.map(parseFilterGroup.bind(filters, fieldMap)).filter(function(item) {
return !! item;
function toQuery(filters, fieldMap, $filter){
var query = filters.map(parseFilterGroup.bind(filters, fieldMap, $filter)).filter(function(item) {
return !!item;
});

@@ -430,3 +492,3 @@ return query;

obj.values = fieldData.choices.reduce(function(prev, choice) {
prev[choice] = truthy === (group[key][obj.field].indexOf(choice) > -1);
prev[choice] = truthy === (~group[key][obj.field].indexOf(choice));
return prev;

@@ -444,6 +506,38 @@ }, {});

case 'range':
var date, parts;
obj.field = Object.keys(group[key])[0];
obj.subType = Object.keys(group[key][obj.field])[0];
obj.value = group[key][obj.field][obj.subType];
if (angular.isNumber(group[key][obj.field][obj.subType])) {
obj.value = group[key][obj.field][obj.subType];
break;
}
if (angular.isDefined(Object.keys(group[key][obj.field])[1])) {
date = group[key][obj.field].gte;
if (~date.indexOf('now-')) {
obj.subType = 'last';
obj.value = parseInt(date.split('now-')[1].split('d')[0]);
break;
}
if (~date.indexOf('now')) {
obj.subType = 'next';
date = group[key][obj.field].lte;
obj.value = parseInt(date.split('now+')[1].split('d')[0]);
break;
}
obj.subType = 'equals';
parts = date.split('T')[0].split('-');
obj.date = parts[2] + '/' + parts[1] + '/' + parts[0];
break;
}
date = group[key][obj.field][obj.subType];
parts = date.split('T')[0].split('-');
obj.date = parts[2] + '/' + parts[1] + '/' + parts[0];
break;
case 'not':

@@ -460,7 +554,7 @@ obj = parseQueryGroup(fieldMap, group[key].filter, false);

function parseFilterGroup(fieldMap, group) {
function parseFilterGroup(fieldMap, $filter, group) {
var obj = {};
if (group.type === 'group') {
obj[group.subType] = group.rules.map(parseFilterGroup.bind(group, fieldMap)).filter(function(item) {
return !! item;
obj[group.subType] = group.rules.map(parseFilterGroup.bind(group, fieldMap, $filter)).filter(function(item) {
return !!item;
});

@@ -474,3 +568,3 @@ return obj;

if (! fieldName) return;
if (!fieldName) return;

@@ -481,3 +575,3 @@ switch (fieldData.type) {

if (! group.subType) return;
if (!group.subType) return;
switch (group.subType) {

@@ -513,10 +607,47 @@ case 'equals':

case 'date':
if (group.subType === 'exists') {
obj.exists = { field: fieldName };
} else if (group.subType === 'notExists') {
obj.missing = { field: fieldName };
} else {
throw new Error('unexpected subtype');
if (!group.subType) return;
switch (group.subType) {
case 'equals':
if (!angular.isDate(group.date)) return;
obj.term = {};
obj.term[fieldName] = formatDate($filter, group.date, group.dateFormat);
break;
case 'lt':
case 'lte':
if (!angular.isDate(group.date)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName][group.subType] = formatDate($filter, group.date, group.dateFormat);
break;
case 'gt':
case 'gte':
if (!angular.isDate(group.date)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName][group.subType] = formatDate($filter, group.date, group.dateFormat);
break;
case 'last':
if (!angular.isNumber(group.value)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName].gte = 'now-' + group.value + 'd';
obj.range[fieldName].lte = 'now';
break;
case 'next':
if (!angular.isNumber(group.value)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName].gte = 'now';
obj.range[fieldName].lte = 'now+' + group.value + 'd';
break;
case 'exists':
obj.exists = { field: fieldName };
break;
case 'notExists':
obj.missing = { field: fieldName };
break;
default:
throw new Error('unexpected subtype ' + group.subType);
}
break;

@@ -556,3 +687,3 @@

value: null,
}
},
};

@@ -563,2 +694,8 @@

function formatDate($filter, date, dateFormat) {
if (!angular.isDate(date)) return false;
var fDate = $filter('date')(date, dateFormat);
return fDate;
}
})(window.angular);

@@ -571,5 +708,5 @@

$templateCache.put("angular-elastic-builder/types/Boolean.html","<span class=\"boolean-rule\">\n Equals\n\n <!-- This is a weird hack to make sure these are numbers -->\n <select\n data-ng-model=\"rule.value\"\n class=\"form-control\"\n data-ng-options=\"booleans.indexOf(choice) as choice for choice in booleansOrder\">\n </select>\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Date.html","<span class=\"date-rule\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Date.html","<span class=\"date-rule form-inline\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <optgroup label=\"Exact\">\n <option value=\"equals\">=</option>\n </optgroup>\n <optgroup label=\"Unbounded-range\">\n <option value=\"lt\">&lt;</option>\n <option value=\"lte\">&le;</option>\n <option value=\"gt\">&gt;</option>\n <option value=\"gte\">&ge;</option>\n </optgroup>\n <optgroup label=\"Bounded-range\">\n <option value=\"last\">In the last</option>\n <option value=\"next\">In the next</option>\n </optgroup>\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n <div class=\"form-group\">\n <div class=\"input-group\">\n <input data-ng-if=\"inputNeeded()\"\n type=\"text\"\n class=\"form-control\"\n data-uib-datepicker-popup=\"{{ rule.dateFormat }}\"\n data-ng-model=\"rule.date\"\n data-is-open=\"popup1.opened\"\n data-datepicker-options=\"dateOptions\"\n data-ng-required=\"true\"\n data-close-text=\"Close\" />\n <div class=\"input-group-btn\">\n <button type=\"button\" class=\"btn btn-default\" ng-click=\"open1()\" data-ng-if=\"inputNeeded()\">\n <i class=\"fa fa-calendar\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <span class=\"form-inline\">\n <div class=\"form-group\">\n <label data-ng-if=\"inputNeeded()\">Format</label>\n <select\n class=\"form-control\"\n data-ng-model=\"rule.dateFormat\"\n data-ng-if=\"inputNeeded()\"\n ng-options=\"f for f in formats\"></select>\n </div>\n </span>\n\n <span data-ng-if=\"numberNeeded()\">\n <input type=\"number\" class=\"form-control\" data-ng-model=\"rule.value\" min=0> days\n </span>\n\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Multi.html","<span class=\"multi-rule\">\n <span data-ng-repeat=\"choice in guide.choices\">\n <label class=\"checkbox\">\n <input type=\"checkbox\" data-ng-model=\"rule.values[choice]\">\n {{ choice }}\n </label>\n </span>\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Number.html","<span class=\"number-rule\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <optgroup label=\"Numeral\">\n <option value=\"equals\">=</option>\n <option value=\"gt\">&gt;</option>\n <option value=\"gte\">&ge;</option>\n <option value=\"lt\">&lt;</option>\n <option value=\"lte\">&le;</option>\n </optgroup>\n\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n <!-- Range Fields -->\n <input data-ng-if=\"inputNeeded()\"\n class=\"form-control\"\n data-ng-model=\"rule.value\"\n type=\"number\"\n min=\"{{ guide.minimum }}\"\n max=\"{{ guide.maximum }}\">\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Term.html","<span class=\"elastic-term\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <!-- Term Options -->\n <optgroup label=\"Text\">\n <option value=\"equals\">Equals</option>\n <option value=\"notEquals\">! Equals</option>\n </optgroup>\n\n <!-- Generic Options -->\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n\n </select>\n <input\n data-ng-if=\"inputNeeded()\"\n class=\"form-control\"\n data-ng-model=\"rule.value\"\n type=\"text\">\n</span>\n");}]);})(window.angular);

2

dist/angular-elastic-builder.min.js

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

!function(e){"use strict";e.module("angular-elastic-builder",["RecursionHelper"])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").directive("elasticBuilder",["elasticQueryService",function(e){return{scope:{data:"=elasticBuilder"},templateUrl:"angular-elastic-builder/BuilderDirective.html",link:function(t){var n=t.data;t.filters=[],t.removeChild=function(e){t.filters.splice(e,1)},t.addRule=function(){t.filters.push({})},t.addGroup=function(){t.filters.push({type:"group",subType:"and",rules:[]})},t.$watch("data.needsUpdate",function(a){a&&(t.filters=e.toFilters(n.query,t.data.fields),t.data.needsUpdate=!1)}),t.$watch("filters",function(a){a&&(n.query=e.toQuery(t.filters,t.data.fields))},!0)}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderChooser",["RecursionHelper","groupClassHelper",function(e,t){return{scope:{elasticFields:"=",item:"=elasticBuilderChooser",onRemove:"&"},templateUrl:"angular-elastic-builder/ChooserDirective.html",compile:function(n){return e.compile(n,function(e,n,a){var i=e.depth=+a.depth,l=e.item;e.getGroupClassName=function(){var e=i;return"group"===l.type&&e++,t(e)}})}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderGroup",["RecursionHelper","groupClassHelper",function(e,t){return{scope:{elasticFields:"=",group:"=elasticBuilderGroup",onRemove:"&"},templateUrl:"angular-elastic-builder/GroupDirective.html",compile:function(n){return e.compile(n,function(e,n,a){var i=e.depth=+a.depth,l=e.group;e.addRule=function(){l.rules.push({})},e.addGroup=function(){l.rules.push({type:"group",subType:"and",rules:[]})},e.removeChild=function(e){l.rules.splice(e,1)},e.getGroupClassName=function(){return t(i+1)}})}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderRule",[function(){return{scope:{elasticFields:"=",rule:"=elasticBuilderRule",onRemove:"&"},templateUrl:"angular-elastic-builder/RuleDirective.html",link:function(e){e.getType=function(){var t=e.elasticFields,n=e.rule.field;if(t&&n)return"boolean"===t[n].subType?"boolean":t[n].type}}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticType",[function(){return{scope:{type:"=elasticType",rule:"=",guide:"="},template:'<ng-include src="getTemplateUrl()" />',link:function(e){e.getTemplateUrl=function(){var t=e.type;if(t)return t=t.charAt(0).toUpperCase()+t.slice(1),"angular-elastic-builder/types/"+t+".html"},e.booleans=["False","True"],e.booleansOrder=["True","False"],e.inputNeeded=function(){var t=["equals","notEquals","gt","gte","lt","lte"];return~t.indexOf(e.rule.subType)}}}}])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").factory("groupClassHelper",function(){return function(e){var t=["","list-group-item-info","list-group-item-success","list-group-item-warning","list-group-item-danger"];return t[e%t.length]}})}(window.angular),function(e){"use strict";function t(e,t){var n=e.map(a.bind(e,t));return n}function n(e,t){var n=e.map(i.bind(e,t)).filter(function(e){return!!e});return n}function a(e,t,n){n!==!1&&(n=!0);var i=Object.keys(t)[0],s={or:"group",and:"group",range:"number"},r=s[i]||"item",u=l(r);switch(i){case"or":case"and":u.rules=t[i].map(a.bind(t,e)),u.subType=i;break;case"missing":case"exists":u.field=t[i].field,u.subType={exists:"exists",missing:"notExists"}[i],delete u.value;break;case"term":case"terms":u.field=Object.keys(t[i])[0];var o=e[Object.keys(t[i])[0]];if("multi"===o.type){var c=t[i][u.field];"string"==typeof c&&(c=[c]),u.values=o.choices.reduce(function(e,a){return e[a]=n===t[i][u.field].indexOf(a)>-1,e},{})}else u.subType=n?"equals":"notEquals",u.value=t[i][u.field],"number"==typeof u.value&&(u.subType="boolean");break;case"range":u.field=Object.keys(t[i])[0],u.subType=Object.keys(t[i][u.field])[0],u.value=t[i][u.field][u.subType];break;case"not":u=a(e,t[i].filter,!1);break;default:u.field=Object.keys(t[i])[0]}return u}function i(e,t){var n={};if("group"===t.type)return n[t.subType]=t.rules.map(i.bind(t,e)).filter(function(e){return!!e}),n;var a=t.field,l=e[a];if(a){switch(l.type){case"term":if("boolean"===l.subType&&(t.subType="boolean"),!t.subType)return;switch(t.subType){case"equals":case"boolean":if(void 0===t.value)return;n.term={},n.term[a]=t.value;break;case"notEquals":if(void 0===t.value)return;n.not={filter:{term:{}}},n.not.filter.term[a]=t.value;break;case"exists":n.exists={field:a};break;case"notExists":n.missing={field:a};break;default:throw new Error("unexpected subtype "+t.subType)}break;case"number":n.range={},n.range[a]={},n.range[a][t.subType]=t.value;break;case"date":if("exists"===t.subType)n.exists={field:a};else{if("notExists"!==t.subType)throw new Error("unexpected subtype");n.missing={field:a}}break;case"multi":n.terms={},n.terms[a]=Object.keys(t.values||{}).reduce(function(e,n){return t.values[n]&&e.push(n),e},[]);break;default:throw new Error("unexpected type")}return n}}function l(t){var n={group:{type:"group",subType:"",rules:[]},item:{field:"",subType:"",value:""},number:{field:"",subType:"",value:null}};return e.copy(n[t])}e.module("angular-elastic-builder").factory("elasticQueryService",[function(){return{toFilters:t,toQuery:n}}])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").run(["$templateCache",function(e){e.put("angular-elastic-builder/BuilderDirective.html",'<div class="elastic-builder">\n <div class="filter-panels">\n <div class="list-group form-inline">\n <div\n data-ng-repeat="filter in filters"\n data-elastic-builder-chooser="filter"\n data-elastic-fields="data.fields"\n data-on-remove="removeChild($index)"\n data-depth="0"></div>\n <div class="list-group-item actions">\n <a class="btn btn-xs btn-primary" title="Add Rule" data-ng-click="addRule()">\n <i class="fa fa-plus"></i>\n </a>\n <a class="btn btn-xs btn-primary" title="Add Group" data-ng-click="addGroup()">\n <i class="fa fa-list"></i>\n </a>\n </div>\n </div>\n </div>\n</div>\n'),e.put("angular-elastic-builder/ChooserDirective.html",'<div\n class="list-group-item elastic-builder-chooser"\n data-ng-class="getGroupClassName()">\n\n <div data-ng-if="item.type === \'group\'"\n data-elastic-builder-group="item"\n data-depth="{{ depth }}"\n data-elastic-fields="elasticFields"\n data-on-remove="onRemove()"></div>\n\n <div data-ng-if="item.type !== \'group\'"\n data-elastic-builder-rule="item"\n data-elastic-fields="elasticFields"\n data-on-remove="onRemove()"></div>\n\n</div>\n'),e.put("angular-elastic-builder/GroupDirective.html",'<div class="elastic-builder-group">\n <h5>If\n <select data-ng-model="group.subType" class="form-control">\n <option value="and">all</option>\n <option value="or">any</option>\n </select>\n of these conditions are met\n </h5>\n <div\n data-ng-repeat="rule in group.rules"\n data-elastic-builder-chooser="rule"\n data-elastic-fields="elasticFields"\n data-depth="{{ +depth + 1 }}"\n data-on-remove="removeChild($index)"></div>\n\n <div class="list-group-item actions" data-ng-class="getGroupClassName()">\n <a class="btn btn-xs btn-primary" title="Add Sub-Rule" data-ng-click="addRule()">\n <i class="fa fa-plus"></i>\n </a>\n <a class="btn btn-xs btn-primary" title="Add Sub-Group" data-ng-click="addGroup()">\n <i class="fa fa-list"></i>\n </a>\n </div>\n\n <a class="btn btn-xs btn-danger remover" data-ng-click="onRemove()">\n <i class="fa fa-minus"></i>\n </a>\n</div>\n'),e.put("angular-elastic-builder/RuleDirective.html",'<div class="elastic-builder-rule">\n <select class="form-control" data-ng-model="rule.field" data-ng-options="key as key for (key, value) in elasticFields"></select>\n\n <span data-elastic-type="getType()" data-rule="rule" data-guide="elasticFields[rule.field]"></span>\n\n <a class="btn btn-xs btn-danger remover" data-ng-click="onRemove()">\n <i class="fa fa-minus"></i>\n </a>\n\n</div>\n'),e.put("angular-elastic-builder/types/Boolean.html",'<span class="boolean-rule">\n Equals\n\n <!-- This is a weird hack to make sure these are numbers -->\n <select\n data-ng-model="rule.value"\n class="form-control"\n data-ng-options="booleans.indexOf(choice) as choice for choice in booleansOrder">\n </select>\n</span>\n'),e.put("angular-elastic-builder/types/Date.html",'<span class="date-rule">\n <select data-ng-model="rule.subType" class="form-control">\n\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n </select>\n\n</span>\n'),e.put("angular-elastic-builder/types/Multi.html",'<span class="multi-rule">\n <span data-ng-repeat="choice in guide.choices">\n <label class="checkbox">\n <input type="checkbox" data-ng-model="rule.values[choice]">\n {{ choice }}\n </label>\n </span>\n</span>\n'),e.put("angular-elastic-builder/types/Number.html",'<span class="number-rule">\n <select data-ng-model="rule.subType" class="form-control">\n <optgroup label="Numeral">\n <option value="equals">=</option>\n <option value="gt">&gt;</option>\n <option value="gte">&ge;</option>\n <option value="lt">&lt;</option>\n <option value="lte">&le;</option>\n </optgroup>\n\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n </select>\n\n <!-- Range Fields -->\n <input data-ng-if="inputNeeded()"\n class="form-control"\n data-ng-model="rule.value"\n type="number"\n min="{{ guide.minimum }}"\n max="{{ guide.maximum }}">\n</span>\n'),e.put("angular-elastic-builder/types/Term.html",'<span class="elastic-term">\n <select data-ng-model="rule.subType" class="form-control">\n <!-- Term Options -->\n <optgroup label="Text">\n <option value="equals">Equals</option>\n <option value="notEquals">! Equals</option>\n </optgroup>\n\n <!-- Generic Options -->\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n\n </select>\n <input\n data-ng-if="inputNeeded()"\n class="form-control"\n data-ng-model="rule.value"\n type="text">\n</span>\n')}])}(window.angular);
!function(e){"use strict";e.module("angular-elastic-builder",["RecursionHelper","ui.bootstrap"])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").directive("elasticBuilder",["elasticQueryService",function(e){return{scope:{data:"=elasticBuilder"},templateUrl:"angular-elastic-builder/BuilderDirective.html",link:function(t){var n=t.data;t.filters=[],t.removeChild=function(e){t.filters.splice(e,1)},t.addRule=function(){t.filters.push({})},t.addGroup=function(){t.filters.push({type:"group",subType:"and",rules:[]})},t.$watch("data.needsUpdate",function(a){a&&(t.filters=e.toFilters(n.query,t.data.fields),t.data.needsUpdate=!1)}),t.$watch("filters",function(a){a&&(n.query=e.toQuery(t.filters,t.data.fields))},!0)}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderChooser",["RecursionHelper","groupClassHelper",function(e,t){return{scope:{elasticFields:"=",item:"=elasticBuilderChooser",onRemove:"&"},templateUrl:"angular-elastic-builder/ChooserDirective.html",compile:function(n){return e.compile(n,function(e,n,a){var i=e.depth=+a.depth,l=e.item;e.getGroupClassName=function(){var e=i;return"group"===l.type&&e++,t(e)}})}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderGroup",["RecursionHelper","groupClassHelper",function(e,t){return{scope:{elasticFields:"=",group:"=elasticBuilderGroup",onRemove:"&"},templateUrl:"angular-elastic-builder/GroupDirective.html",compile:function(n){return e.compile(n,function(e,n,a){var i=e.depth=+a.depth,l=e.group;e.addRule=function(){l.rules.push({})},e.addGroup=function(){l.rules.push({type:"group",subType:"and",rules:[]})},e.removeChild=function(e){l.rules.splice(e,1)},e.getGroupClassName=function(){return t(i+1)}})}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticBuilderRule",[function(){return{scope:{elasticFields:"=",rule:"=elasticBuilderRule",onRemove:"&"},templateUrl:"angular-elastic-builder/RuleDirective.html",link:function(e){e.getType=function(){var t=e.elasticFields,n=e.rule.field;if(t&&n)return"boolean"===t[n].subType?"boolean":t[n].type}}}}])}(window.angular),function(e){"use strict";var t=e.module("angular-elastic-builder");t.directive("elasticType",[function(){return{scope:{type:"=elasticType",rule:"=",guide:"="},template:'<ng-include src="getTemplateUrl()" />',link:function(e){function t(e){var t=e.date,n=e.mode;return"day"===n&&(0===t.getDay()||6===t.getDay())}e.getTemplateUrl=function(){var t=e.type;if(t)return t=t.charAt(0).toUpperCase()+t.slice(1),"angular-elastic-builder/types/"+t+".html"},e.booleans=["False","True"],e.booleansOrder=["True","False"],e.inputNeeded=function(){var t=["equals","notEquals","gt","gte","lt","lte"];return~t.indexOf(e.rule.subType)},e.numberNeeded=function(){var t=["last","next"];return~t.indexOf(e.rule.subType)},e.today=function(){e.rule.date=new Date},e.today(),e.clear=function(){e.rule.date=null},e.dateOptions={dateDisabled:t,formatYear:"yy",maxDate:new Date(2018,1,13),minDate:new Date,startingDay:1},e.open1=function(){e.popup1.opened=!0},e.setDate=function(t,n,a){e.rule.date=new Date(t,n-1,a)},e.formats=["yyyy-MM-ddTHH:mm:ss","yyyy-MM-ddTHH:mm:ssZ","yyyy-MM-dd","dd-MMMM-yyyy","yyyy/MM/dd","shortDate"],e.rule.dateFormat=e.formats[0],e.format=e.rule.dateFormat,e.altInputFormats=["M!/d!/yyyy"],e.popup1={opened:!1}}}}])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").factory("groupClassHelper",function(){return function(e){var t=["","list-group-item-info","list-group-item-success","list-group-item-warning","list-group-item-danger"];return t[e%t.length]}})}(window.angular),function(e){"use strict";function t(e,t){var n=e.map(a.bind(e,t));return n}function n(e,t,n){var a=e.map(i.bind(e,t,n)).filter(function(e){return!!e});return a}function a(t,n,i){i!==!1&&(i=!0);var r=Object.keys(n)[0],s={or:"group",and:"group",range:"number"},u=s[r]||"item",o=l(u);switch(r){case"or":case"and":o.rules=n[r].map(a.bind(n,t)),o.subType=r;break;case"missing":case"exists":o.field=n[r].field,o.subType={exists:"exists",missing:"notExists"}[r],delete o.value;break;case"term":case"terms":o.field=Object.keys(n[r])[0];var d=t[Object.keys(n[r])[0]];if("multi"===d.type){var p=n[r][o.field];"string"==typeof p&&(p=[p]),o.values=d.choices.reduce(function(e,t){return e[t]=i===~n[r][o.field].indexOf(t),e},{})}else o.subType=i?"equals":"notEquals",o.value=n[r][o.field],"number"==typeof o.value&&(o.subType="boolean");break;case"range":var c,f;if(o.field=Object.keys(n[r])[0],o.subType=Object.keys(n[r][o.field])[0],e.isNumber(n[r][o.field][o.subType])){o.value=n[r][o.field][o.subType];break}if(e.isDefined(Object.keys(n[r][o.field])[1])){if(c=n[r][o.field].gte,~c.indexOf("now-")){o.subType="last",o.value=parseInt(c.split("now-")[1].split("d")[0]);break}if(~c.indexOf("now")){o.subType="next",c=n[r][o.field].lte,o.value=parseInt(c.split("now+")[1].split("d")[0]);break}o.subType="equals",f=c.split("T")[0].split("-"),o.date=f[2]+"/"+f[1]+"/"+f[0];break}c=n[r][o.field][o.subType],f=c.split("T")[0].split("-"),o.date=f[2]+"/"+f[1]+"/"+f[0];break;case"not":o=a(t,n[r].filter,!1);break;default:o.field=Object.keys(n[r])[0]}return o}function i(t,n,a){var l={};if("group"===a.type)return l[a.subType]=a.rules.map(i.bind(a,t,n)).filter(function(e){return!!e}),l;var s=a.field,u=t[s];if(s){switch(u.type){case"term":if("boolean"===u.subType&&(a.subType="boolean"),!a.subType)return;switch(a.subType){case"equals":case"boolean":if(void 0===a.value)return;l.term={},l.term[s]=a.value;break;case"notEquals":if(void 0===a.value)return;l.not={filter:{term:{}}},l.not.filter.term[s]=a.value;break;case"exists":l.exists={field:s};break;case"notExists":l.missing={field:s};break;default:throw new Error("unexpected subtype "+a.subType)}break;case"number":l.range={},l.range[s]={},l.range[s][a.subType]=a.value;break;case"date":if(!a.subType)return;switch(a.subType){case"equals":if(!e.isDate(a.date))return;l.term={},l.term[s]=r(n,a.date,a.dateFormat);break;case"lt":case"lte":if(!e.isDate(a.date))return;l.range={},l.range[s]={},l.range[s][a.subType]=r(n,a.date,a.dateFormat);break;case"gt":case"gte":if(!e.isDate(a.date))return;l.range={},l.range[s]={},l.range[s][a.subType]=r(n,a.date,a.dateFormat);break;case"last":if(!e.isNumber(a.value))return;l.range={},l.range[s]={},l.range[s].gte="now-"+a.value+"d",l.range[s].lte="now";break;case"next":if(!e.isNumber(a.value))return;l.range={},l.range[s]={},l.range[s].gte="now",l.range[s].lte="now+"+a.value+"d";break;case"exists":l.exists={field:s};break;case"notExists":l.missing={field:s};break;default:throw new Error("unexpected subtype "+a.subType)}break;case"multi":l.terms={},l.terms[s]=Object.keys(a.values||{}).reduce(function(e,t){return a.values[t]&&e.push(t),e},[]);break;default:throw new Error("unexpected type")}return l}}function l(t){var n={group:{type:"group",subType:"",rules:[]},item:{field:"",subType:"",value:""},number:{field:"",subType:"",value:null}};return e.copy(n[t])}function r(t,n,a){if(!e.isDate(n))return!1;var i=t("date")(n,a);return i}e.module("angular-elastic-builder").factory("elasticQueryService",["$filter",function(e){return{toFilters:t,toQuery:function(t,a){return n(t,a,e)}}}])}(window.angular),function(e){"use strict";e.module("angular-elastic-builder").run(["$templateCache",function(e){e.put("angular-elastic-builder/BuilderDirective.html",'<div class="elastic-builder">\n <div class="filter-panels">\n <div class="list-group form-inline">\n <div\n data-ng-repeat="filter in filters"\n data-elastic-builder-chooser="filter"\n data-elastic-fields="data.fields"\n data-on-remove="removeChild($index)"\n data-depth="0"></div>\n <div class="list-group-item actions">\n <a class="btn btn-xs btn-primary" title="Add Rule" data-ng-click="addRule()">\n <i class="fa fa-plus"></i>\n </a>\n <a class="btn btn-xs btn-primary" title="Add Group" data-ng-click="addGroup()">\n <i class="fa fa-list"></i>\n </a>\n </div>\n </div>\n </div>\n</div>\n'),e.put("angular-elastic-builder/ChooserDirective.html",'<div\n class="list-group-item elastic-builder-chooser"\n data-ng-class="getGroupClassName()">\n\n <div data-ng-if="item.type === \'group\'"\n data-elastic-builder-group="item"\n data-depth="{{ depth }}"\n data-elastic-fields="elasticFields"\n data-on-remove="onRemove()"></div>\n\n <div data-ng-if="item.type !== \'group\'"\n data-elastic-builder-rule="item"\n data-elastic-fields="elasticFields"\n data-on-remove="onRemove()"></div>\n\n</div>\n'),e.put("angular-elastic-builder/GroupDirective.html",'<div class="elastic-builder-group">\n <h5>If\n <select data-ng-model="group.subType" class="form-control">\n <option value="and">all</option>\n <option value="or">any</option>\n </select>\n of these conditions are met\n </h5>\n <div\n data-ng-repeat="rule in group.rules"\n data-elastic-builder-chooser="rule"\n data-elastic-fields="elasticFields"\n data-depth="{{ +depth + 1 }}"\n data-on-remove="removeChild($index)"></div>\n\n <div class="list-group-item actions" data-ng-class="getGroupClassName()">\n <a class="btn btn-xs btn-primary" title="Add Sub-Rule" data-ng-click="addRule()">\n <i class="fa fa-plus"></i>\n </a>\n <a class="btn btn-xs btn-primary" title="Add Sub-Group" data-ng-click="addGroup()">\n <i class="fa fa-list"></i>\n </a>\n </div>\n\n <a class="btn btn-xs btn-danger remover" data-ng-click="onRemove()">\n <i class="fa fa-minus"></i>\n </a>\n</div>\n'),e.put("angular-elastic-builder/RuleDirective.html",'<div class="elastic-builder-rule">\n <select class="form-control" data-ng-model="rule.field" data-ng-options="key as key for (key, value) in elasticFields"></select>\n\n <span data-elastic-type="getType()" data-rule="rule" data-guide="elasticFields[rule.field]"></span>\n\n <a class="btn btn-xs btn-danger remover" data-ng-click="onRemove()">\n <i class="fa fa-minus"></i>\n </a>\n\n</div>\n'),e.put("angular-elastic-builder/types/Boolean.html",'<span class="boolean-rule">\n Equals\n\n <!-- This is a weird hack to make sure these are numbers -->\n <select\n data-ng-model="rule.value"\n class="form-control"\n data-ng-options="booleans.indexOf(choice) as choice for choice in booleansOrder">\n </select>\n</span>\n'),e.put("angular-elastic-builder/types/Date.html",'<span class="date-rule form-inline">\n <select data-ng-model="rule.subType" class="form-control">\n <optgroup label="Exact">\n <option value="equals">=</option>\n </optgroup>\n <optgroup label="Unbounded-range">\n <option value="lt">&lt;</option>\n <option value="lte">&le;</option>\n <option value="gt">&gt;</option>\n <option value="gte">&ge;</option>\n </optgroup>\n <optgroup label="Bounded-range">\n <option value="last">In the last</option>\n <option value="next">In the next</option>\n </optgroup>\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n </select>\n\n <div class="form-group">\n <div class="input-group">\n <input data-ng-if="inputNeeded()"\n type="text"\n class="form-control"\n data-uib-datepicker-popup="{{ rule.dateFormat }}"\n data-ng-model="rule.date"\n data-is-open="popup1.opened"\n data-datepicker-options="dateOptions"\n data-ng-required="true"\n data-close-text="Close" />\n <div class="input-group-btn">\n <button type="button" class="btn btn-default" ng-click="open1()" data-ng-if="inputNeeded()">\n <i class="fa fa-calendar"></i>\n </button>\n </div>\n </div>\n </div>\n\n <span class="form-inline">\n <div class="form-group">\n <label data-ng-if="inputNeeded()">Format</label>\n <select\n class="form-control"\n data-ng-model="rule.dateFormat"\n data-ng-if="inputNeeded()"\n ng-options="f for f in formats"></select>\n </div>\n </span>\n\n <span data-ng-if="numberNeeded()">\n <input type="number" class="form-control" data-ng-model="rule.value" min=0> days\n </span>\n\n</span>\n'),e.put("angular-elastic-builder/types/Multi.html",'<span class="multi-rule">\n <span data-ng-repeat="choice in guide.choices">\n <label class="checkbox">\n <input type="checkbox" data-ng-model="rule.values[choice]">\n {{ choice }}\n </label>\n </span>\n</span>\n'),e.put("angular-elastic-builder/types/Number.html",'<span class="number-rule">\n <select data-ng-model="rule.subType" class="form-control">\n <optgroup label="Numeral">\n <option value="equals">=</option>\n <option value="gt">&gt;</option>\n <option value="gte">&ge;</option>\n <option value="lt">&lt;</option>\n <option value="lte">&le;</option>\n </optgroup>\n\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n </select>\n\n <!-- Range Fields -->\n <input data-ng-if="inputNeeded()"\n class="form-control"\n data-ng-model="rule.value"\n type="number"\n min="{{ guide.minimum }}"\n max="{{ guide.maximum }}">\n</span>\n'),e.put("angular-elastic-builder/types/Term.html",'<span class="elastic-term">\n <select data-ng-model="rule.subType" class="form-control">\n <!-- Term Options -->\n <optgroup label="Text">\n <option value="equals">Equals</option>\n <option value="notEquals">! Equals</option>\n </optgroup>\n\n <!-- Generic Options -->\n <optgroup label="Generic">\n <option value="exists">Exists</option>\n <option value="notExists">! Exists</option>\n </optgroup>\n\n </select>\n <input\n data-ng-if="inputNeeded()"\n class="form-control"\n data-ng-model="rule.value"\n type="text">\n</span>\n')}])}(window.angular);

@@ -8,3 +8,4 @@ var path = require('path');

app.use('/js', express.static(path.join(__dirname, '../dist')));
app.use('/angular', express.static(path.join(__dirname, '../node_modules/angular-recursion')));
app.use('/angular-recursion', express.static(path.join(__dirname, '../node_modules/angular-recursion')));
app.use('/angular-ui-bootstrap', express.static(path.join(__dirname, '../node_modules/angular-ui-bootstrap/dist')));

@@ -11,0 +12,0 @@ app.listen(process.env.PORT || 3000, function() {

@@ -15,2 +15,7 @@ (function(angular) {

{
'term': {
'test.date': '2016-04-08T09:16:48'
}
},
{
'range': {

@@ -54,2 +59,10 @@ 'test.number': {

}
},
{
'range': {
'test.otherdate': {
'gte': 'now',
'lte': 'now+7d'
}
}
}

@@ -62,3 +75,5 @@ ];

'test.boolean': { type: 'term', subType: 'boolean' },
'test.state.multi': { type: 'multi', choices: [ 'AZ', 'CA', 'CT' ]}
'test.state.multi': { type: 'multi', choices: [ 'AZ', 'CA', 'CT' ]},
'test.date': { type: 'date' },
'test.otherdate': { type: 'date' }
};

@@ -65,0 +80,0 @@

@@ -11,3 +11,4 @@ /**

, uglify = require('gulp-uglifyjs')
, util = require('util');
, util = require('util')
, eslint = require('gulp-eslint');

@@ -74,2 +75,12 @@ /**

gulp.task('lint', function() {
return gulp.src([
'src/**/**.js',
'!src/tmpl/ElasticBuilderTemplates.js',
])
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
gulp.task('watch', [ 'templatecache', 'build' ], function() {

@@ -79,1 +90,2 @@ gulp.watch('src/tmpl/**/*.html', [ 'templatecache', 'build' ]);

});
{
"name": "angular-elastic-builder",
"version": "1.4.0",
"version": "1.5.0",
"description": "Angular Module for building an Elasticsearch Query",

@@ -17,7 +17,10 @@ "author": "Dan Crews <crewsd@gmail.com>",

"angular-recursion": "^1.0.5",
"del": "^1.1.1",
"express": "^4.12.3",
"gulp": "^3.8.11",
"angular-ui-bootstrap": "^1.2.5",
"del": "^1.2.1",
"eslint": "^2.7.0",
"express": "^4.13.4",
"gulp": "^3.9.1",
"gulp-angular-templatecache": "^1.6.0",
"gulp-concat": "^2.5.2",
"gulp-concat": "^2.6.0",
"gulp-eslint": "^2.0.0",
"gulp-header": "^1.2.2",

@@ -29,4 +32,6 @@ "gulp-rename": "^1.2.2",

"example": "node examples",
"test": "echo \"Error: no test specified\" && exit 1"
}
"test": "echo \"Error: no test specified\" && exit 1",
"gulp": "gulp"
},
"dependencies": {}
}

@@ -19,3 +19,5 @@ # Angular Elasticsearch Query Builder

### Dependency
Notice: this plugin requires the [Angular Recursion](https://github.com/marklagendijk/angular-recursion) module.
Notice: this plugin requires:
- the [Angular Recursion](https://github.com/marklagendijk/angular-recursion) module.
- the [Angular directives for Bootstrap](https://github.com/angular-ui/bootstrap) module to display the Calendar (ui.bootstrap.datepicker)

@@ -25,4 +27,5 @@ ### Installation

```html
<script type="text/javascript" src="/angular-recursion.min.js"></script>
<script type="text/javascript" src="/angular-elastic-builder.min.js"></script>
<script type="text/javascript" src="angular-ui-bootstrap/ui-bootstrap-tpls.js"></script>
<script type="text/javascript" src="angular-recursion/angular-recursion.min.js"></script>
<script type="text/javascript" src="angular-elastic-builder/angular-elastic-builder.min.js"></script>
```

@@ -53,6 +56,8 @@

$scope.elasticBuilderData.fields = {
'some.number.field': { type: 'number' },
'some.term.field': { type: 'term' },
'some.boolean.field': { type: 'term', subType: 'boolean' },
'multi.selector': { type: 'multi', choices: [ 'AZ', 'CA', 'CT' ]}
'test.number': { type: 'number', minimum: 650 },
'test.term': { type: 'term' },
'test.boolean': { type: 'term', subType: 'boolean' },
'test.state.multi': { type: 'multi', choices: [ 'AZ', 'CA', 'CT' ]},
'test.date': { type: 'date' },
'test.otherdate': { type: 'date' }
};

@@ -72,19 +77,39 @@ ```

{
"terms": {
"multi.selector": [
"AZ",
"CT"
]
}
"and": [
{
"term": {
"test.date": "2016-04-08T10:44:06"
}
},
{
"range": {
"test.number": {
"gte": 650
}
}
},
{
"range": {
"test.number": {
"lt": 850
}
}
}
]
},
{
"term": {
"some.boolean.field": "0"
"test.boolean": 0
}
},
{
"terms": {
"test.state.multi": [ "AZ", "CT" ]
}
},
{
"not": {
"filter": {
"term": {
"some.term.field": "Hello World"
"test.term": "asdfasdf"
}

@@ -95,18 +120,13 @@ }

{
"and": [
{
"range": {
"some.number.field": {
"gte": 0
}
}
},
{
"range": {
"some.number.field": {
"lt": 100
}
}
"exists": {
"field": "test.term"
}
},
{
"range": {
"test.otherdate": {
"gte": "now",
"lte": "now+7d"
}
]
}
}

@@ -124,2 +144,3 @@ ]

- These are actually "equals 0" and "equals 1" for the database query
- `'date'`: in addition to Generic Options, gets "&gt;", "&ge;", "&lt;", "&le;", "="

@@ -147,2 +168,3 @@ Generic Options

[gratipay-url]: https://www.gratipay.com/dncrews/
[screenshot-image]: https://raw.githubusercontent.com/dncrews/angular-elastic-builder/master/screenshot.png
[screenshot-image]: ./screenshot.png

@@ -60,3 +60,3 @@ /**

scope.$watch('data.needsUpdate', function(curr) {
if (! curr) return;
if (!curr) return;

@@ -71,9 +71,9 @@ scope.filters = elasticQueryService.toFilters(data.query, scope.data.fields);

scope.$watch('filters', function(curr) {
if (! curr) return;
if (!curr) return;
data.query = elasticQueryService.toQuery(scope.filters, scope.data.fields);
}, true);
}
},
};
}
},

@@ -80,0 +80,0 @@ ]);

@@ -31,3 +31,3 @@ /**

return RH.compile(element, function(scope, el, attrs) {
var depth = scope.depth = (+ attrs.depth)
var depth = scope.depth = (+attrs.depth)
, item = scope.item;

@@ -42,5 +42,5 @@

});
}
},
};
}
},

@@ -47,0 +47,0 @@ ]);

@@ -29,3 +29,3 @@ /**

return RH.compile(element, function(scope, el, attrs) {
var depth = scope.depth = (+ attrs.depth);
var depth = scope.depth = (+attrs.depth);
var group = scope.group;

@@ -52,5 +52,5 @@

});
}
},
};
}
},

@@ -57,0 +57,0 @@ ]);

@@ -29,3 +29,3 @@ /**

if (! fields || ! field) return;
if (!fields || !field) return;

@@ -36,5 +36,5 @@ if (fields[field].subType === 'boolean') return 'boolean';

};
}
},
};
}
},

@@ -41,0 +41,0 @@ ]);

@@ -29,3 +29,3 @@ /**

var type = scope.type;
if (! type) return;
if (!type) return;

@@ -54,5 +54,62 @@ type = type.charAt(0).toUpperCase() + type.slice(1);

};
scope.numberNeeded = function() {
var needs = [
'last',
'next',
];
return ~needs.indexOf(scope.rule.subType);
};
scope.today = function() {
scope.rule.date = new Date();
};
scope.today();
scope.clear = function() {
scope.rule.date = null;
};
scope.dateOptions = {
dateDisabled: disabled,
formatYear: 'yy',
maxDate: new Date(2018, 1, 13),
minDate: new Date(),
startingDay: 1,
};
// Disable weekend selection
function disabled(data) {
var date = data.date
, mode = data.mode;
return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
}
scope.open1 = function() {
scope.popup1.opened = true;
};
scope.setDate = function(year, month, day) {
scope.rule.date = new Date(year, month - 1, day);
};
scope.formats = [
'yyyy-MM-ddTHH:mm:ss',
'yyyy-MM-ddTHH:mm:ssZ',
'yyyy-MM-dd',
'dd-MMMM-yyyy',
'yyyy/MM/dd',
'shortDate',
];
scope.rule.dateFormat = scope.formats[0];
scope.format = scope.rule.dateFormat;
scope.altInputFormats = ['M!/d!/yyyy'];
scope.popup1 = { opened: false };
},
};
}
},

@@ -59,0 +116,0 @@ ]);

@@ -14,4 +14,5 @@ /**

'RecursionHelper',
'ui.bootstrap',
]);
})(window.angular);

@@ -14,9 +14,13 @@ /**

.factory('elasticQueryService', [
function() {
'$filter',
function($filter) {
return {
toFilters: toFilters,
toQuery: toQuery,
toQuery: function(filters, fieldMap) {
return toQuery(filters, fieldMap, $filter);
},
};
}
},
]);

@@ -29,5 +33,5 @@

function toQuery(filters, fieldMap){
var query = filters.map(parseFilterGroup.bind(filters, fieldMap)).filter(function(item) {
return !! item;
function toQuery(filters, fieldMap, $filter){
var query = filters.map(parseFilterGroup.bind(filters, fieldMap, $filter)).filter(function(item) {
return !!item;
});

@@ -73,3 +77,3 @@ return query;

obj.values = fieldData.choices.reduce(function(prev, choice) {
prev[choice] = truthy === (group[key][obj.field].indexOf(choice) > -1);
prev[choice] = truthy === (~group[key][obj.field].indexOf(choice));
return prev;

@@ -87,6 +91,38 @@ }, {});

case 'range':
var date, parts;
obj.field = Object.keys(group[key])[0];
obj.subType = Object.keys(group[key][obj.field])[0];
obj.value = group[key][obj.field][obj.subType];
if (angular.isNumber(group[key][obj.field][obj.subType])) {
obj.value = group[key][obj.field][obj.subType];
break;
}
if (angular.isDefined(Object.keys(group[key][obj.field])[1])) {
date = group[key][obj.field].gte;
if (~date.indexOf('now-')) {
obj.subType = 'last';
obj.value = parseInt(date.split('now-')[1].split('d')[0]);
break;
}
if (~date.indexOf('now')) {
obj.subType = 'next';
date = group[key][obj.field].lte;
obj.value = parseInt(date.split('now+')[1].split('d')[0]);
break;
}
obj.subType = 'equals';
parts = date.split('T')[0].split('-');
obj.date = parts[2] + '/' + parts[1] + '/' + parts[0];
break;
}
date = group[key][obj.field][obj.subType];
parts = date.split('T')[0].split('-');
obj.date = parts[2] + '/' + parts[1] + '/' + parts[0];
break;
case 'not':

@@ -103,7 +139,7 @@ obj = parseQueryGroup(fieldMap, group[key].filter, false);

function parseFilterGroup(fieldMap, group) {
function parseFilterGroup(fieldMap, $filter, group) {
var obj = {};
if (group.type === 'group') {
obj[group.subType] = group.rules.map(parseFilterGroup.bind(group, fieldMap)).filter(function(item) {
return !! item;
obj[group.subType] = group.rules.map(parseFilterGroup.bind(group, fieldMap, $filter)).filter(function(item) {
return !!item;
});

@@ -117,3 +153,3 @@ return obj;

if (! fieldName) return;
if (!fieldName) return;

@@ -124,3 +160,3 @@ switch (fieldData.type) {

if (! group.subType) return;
if (!group.subType) return;
switch (group.subType) {

@@ -156,10 +192,47 @@ case 'equals':

case 'date':
if (group.subType === 'exists') {
obj.exists = { field: fieldName };
} else if (group.subType === 'notExists') {
obj.missing = { field: fieldName };
} else {
throw new Error('unexpected subtype');
if (!group.subType) return;
switch (group.subType) {
case 'equals':
if (!angular.isDate(group.date)) return;
obj.term = {};
obj.term[fieldName] = formatDate($filter, group.date, group.dateFormat);
break;
case 'lt':
case 'lte':
if (!angular.isDate(group.date)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName][group.subType] = formatDate($filter, group.date, group.dateFormat);
break;
case 'gt':
case 'gte':
if (!angular.isDate(group.date)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName][group.subType] = formatDate($filter, group.date, group.dateFormat);
break;
case 'last':
if (!angular.isNumber(group.value)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName].gte = 'now-' + group.value + 'd';
obj.range[fieldName].lte = 'now';
break;
case 'next':
if (!angular.isNumber(group.value)) return;
obj.range = {};
obj.range[fieldName] = {};
obj.range[fieldName].gte = 'now';
obj.range[fieldName].lte = 'now+' + group.value + 'd';
break;
case 'exists':
obj.exists = { field: fieldName };
break;
case 'notExists':
obj.missing = { field: fieldName };
break;
default:
throw new Error('unexpected subtype ' + group.subType);
}
break;

@@ -199,3 +272,3 @@

value: null,
}
},
};

@@ -206,2 +279,8 @@

function formatDate($filter, date, dateFormat) {
if (!angular.isDate(date)) return false;
var fDate = $filter('date')(date, dateFormat);
return fDate;
}
})(window.angular);

@@ -6,5 +6,5 @@ (function(angular) {"use strict"; angular.module("angular-elastic-builder").run(["$templateCache", function($templateCache) {$templateCache.put("angular-elastic-builder/BuilderDirective.html","<div class=\"elastic-builder\">\n <div class=\"filter-panels\">\n <div class=\"list-group form-inline\">\n <div\n data-ng-repeat=\"filter in filters\"\n data-elastic-builder-chooser=\"filter\"\n data-elastic-fields=\"data.fields\"\n data-on-remove=\"removeChild($index)\"\n data-depth=\"0\"></div>\n <div class=\"list-group-item actions\">\n <a class=\"btn btn-xs btn-primary\" title=\"Add Rule\" data-ng-click=\"addRule()\">\n <i class=\"fa fa-plus\"></i>\n </a>\n <a class=\"btn btn-xs btn-primary\" title=\"Add Group\" data-ng-click=\"addGroup()\">\n <i class=\"fa fa-list\"></i>\n </a>\n </div>\n </div>\n </div>\n</div>\n");

$templateCache.put("angular-elastic-builder/types/Boolean.html","<span class=\"boolean-rule\">\n Equals\n\n <!-- This is a weird hack to make sure these are numbers -->\n <select\n data-ng-model=\"rule.value\"\n class=\"form-control\"\n data-ng-options=\"booleans.indexOf(choice) as choice for choice in booleansOrder\">\n </select>\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Date.html","<span class=\"date-rule\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Date.html","<span class=\"date-rule form-inline\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <optgroup label=\"Exact\">\n <option value=\"equals\">=</option>\n </optgroup>\n <optgroup label=\"Unbounded-range\">\n <option value=\"lt\">&lt;</option>\n <option value=\"lte\">&le;</option>\n <option value=\"gt\">&gt;</option>\n <option value=\"gte\">&ge;</option>\n </optgroup>\n <optgroup label=\"Bounded-range\">\n <option value=\"last\">In the last</option>\n <option value=\"next\">In the next</option>\n </optgroup>\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n <div class=\"form-group\">\n <div class=\"input-group\">\n <input data-ng-if=\"inputNeeded()\"\n type=\"text\"\n class=\"form-control\"\n data-uib-datepicker-popup=\"{{ rule.dateFormat }}\"\n data-ng-model=\"rule.date\"\n data-is-open=\"popup1.opened\"\n data-datepicker-options=\"dateOptions\"\n data-ng-required=\"true\"\n data-close-text=\"Close\" />\n <div class=\"input-group-btn\">\n <button type=\"button\" class=\"btn btn-default\" ng-click=\"open1()\" data-ng-if=\"inputNeeded()\">\n <i class=\"fa fa-calendar\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <span class=\"form-inline\">\n <div class=\"form-group\">\n <label data-ng-if=\"inputNeeded()\">Format</label>\n <select\n class=\"form-control\"\n data-ng-model=\"rule.dateFormat\"\n data-ng-if=\"inputNeeded()\"\n ng-options=\"f for f in formats\"></select>\n </div>\n </span>\n\n <span data-ng-if=\"numberNeeded()\">\n <input type=\"number\" class=\"form-control\" data-ng-model=\"rule.value\" min=0> days\n </span>\n\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Multi.html","<span class=\"multi-rule\">\n <span data-ng-repeat=\"choice in guide.choices\">\n <label class=\"checkbox\">\n <input type=\"checkbox\" data-ng-model=\"rule.values[choice]\">\n {{ choice }}\n </label>\n </span>\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Number.html","<span class=\"number-rule\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <optgroup label=\"Numeral\">\n <option value=\"equals\">=</option>\n <option value=\"gt\">&gt;</option>\n <option value=\"gte\">&ge;</option>\n <option value=\"lt\">&lt;</option>\n <option value=\"lte\">&le;</option>\n </optgroup>\n\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n </select>\n\n <!-- Range Fields -->\n <input data-ng-if=\"inputNeeded()\"\n class=\"form-control\"\n data-ng-model=\"rule.value\"\n type=\"number\"\n min=\"{{ guide.minimum }}\"\n max=\"{{ guide.maximum }}\">\n</span>\n");
$templateCache.put("angular-elastic-builder/types/Term.html","<span class=\"elastic-term\">\n <select data-ng-model=\"rule.subType\" class=\"form-control\">\n <!-- Term Options -->\n <optgroup label=\"Text\">\n <option value=\"equals\">Equals</option>\n <option value=\"notEquals\">! Equals</option>\n </optgroup>\n\n <!-- Generic Options -->\n <optgroup label=\"Generic\">\n <option value=\"exists\">Exists</option>\n <option value=\"notExists\">! Exists</option>\n </optgroup>\n\n </select>\n <input\n data-ng-if=\"inputNeeded()\"\n class=\"form-control\"\n data-ng-model=\"rule.value\"\n type=\"text\">\n</span>\n");}]);})(window.angular);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet