Socket
Socket
Sign inDemoInstall

angular-elastic-builder

Package Overview
Dependencies
0
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.4.0 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

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc