ATLAS-3900: UI: Allow user to select the date range for date attribute in basic search
diff --git a/dashboardv2/package-lock.json b/dashboardv2/package-lock.json
index afc9fb3..b0afc0b 100644
--- a/dashboardv2/package-lock.json
+++ b/dashboardv2/package-lock.json
@@ -357,9 +357,9 @@
"integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E="
},
"bootstrap-daterangepicker": {
- "version": "2.1.25",
- "resolved": "https://registry.npmjs.org/bootstrap-daterangepicker/-/bootstrap-daterangepicker-2.1.25.tgz",
- "integrity": "sha1-/Ni6C3VaBU0zDXo7fE3Yu4Vc/7c=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bootstrap-daterangepicker/-/bootstrap-daterangepicker-3.1.0.tgz",
+ "integrity": "sha512-oaQZx6ZBDo/dZNyXGVi2rx5GmFXThyQLAxdtIqjtLlYVaQUfQALl5JZMJJZzyDIX7blfy4ppZPAJ10g8Ma4d/g==",
"requires": {
"jquery": ">=1.10",
"moment": "^2.9.0"
diff --git a/dashboardv2/package.json b/dashboardv2/package.json
index e0809d3..1c17c67 100644
--- a/dashboardv2/package.json
+++ b/dashboardv2/package.json
@@ -29,7 +29,7 @@
"backgrid-select-all": "0.3.5",
"backgrid-sizeable-columns": "0.1.1",
"bootstrap": "3.3.7",
- "bootstrap-daterangepicker": "2.1.25",
+ "bootstrap-daterangepicker": "3.1.0",
"d3": "3.5.17",
"d3-tip": "0.6.8",
"dagre-d3": "0.6.4",
diff --git a/dashboardv2/public/css/scss/override.scss b/dashboardv2/public/css/scss/override.scss
index 2bcfde9..de5462c 100644
--- a/dashboardv2/public/css/scss/override.scss
+++ b/dashboardv2/public/css/scss/override.scss
@@ -300,7 +300,7 @@
}
.rule-operator-container {
- width: 105px;
+ width: 150px;
.form-control {
width: 100% !important;
@@ -507,4 +507,26 @@
overflow: hidden;
text-overflow: ellipsis;
}
+}
+
+.daterangepicker {
+ max-height: 400px;
+ overflow-y: scroll;
+
+ .ranges {
+ max-height: 328px;
+ overflow: auto;
+ }
+
+ .ranges li.active,
+ td.active {
+ background-color: $color_havelock_blue_approx;
+ }
+
+ .drp-buttons {
+ .applyBtn {
+ background-color: $color_havelock_blue_approx;
+ border-color: $color_havelock_blue_approx;
+ }
+ }
}
\ No newline at end of file
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index a1c5ad3..4d10fa6 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums', 'moment', 'utils/Globals'], function(require, Utils, Modal, Messages, Enums, moment, Globals) {
+define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums', 'moment', 'utils/Globals', 'moment-timezone'], function(require, Utils, Modal, Messages, Enums, moment, Globals) {
'use strict';
var CommonViewFunction = {};
@@ -387,9 +387,13 @@
function objToString(filterObj) {
var generatedQuery = _.map(filterObj.rules, function(obj, key) {
+ var obj = $.extend(true, {}, obj); // not to update the timezone abbr on original obj , copy of obj is used
if (_.has(obj, 'condition')) {
return ' <span class="operator">' + obj.condition + '</span> ' + '(' + objToString(obj) + ')';
} else {
+ if (obj.type === "date") {
+ obj.value = obj.value + " (" + moment.tz(moment.tz.guess()).zoneAbbr() + ")";
+ }
return '<span class="key">' + (Enums.systemAttributes[obj.id] ? Enums.systemAttributes[obj.id] : _.escape(obj.id)) + '</span> <span class="operator">' + _.escape(obj.operator) + '</span> <span class="value">' + (Enums[obj.id] ? Enums[obj.id][obj.value] : _.escape(obj.value)) + "</span>";
}
});
@@ -487,6 +491,9 @@
if (Globals[value[skey].typeName]) {
attributeDefs = Globals[value[skey].typeName].attributeDefs;
}
+ if (Globals._ALL_CLASSIFICATION_TYPES && Globals._ALL_CLASSIFICATION_TYPES.attributeDefs) {
+ attributeDefs = attributeDefs.concat(Globals._ALL_CLASSIFICATION_TYPES.attributeDefs);
+ }
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (k == "entityFilters") {
@@ -503,6 +510,9 @@
if (Globals[value[skey].typeName]) {
attributeDefs = Globals[value[skey].typeName].attributeDefs;
}
+ if (Globals._ALL_ENTITY_TYPES && Globals._ALL_ENTITY_TYPES.attributeDefs) {
+ attributeDefs = attributeDefs.concat(Globals._ALL_ENTITY_TYPES.attributeDefs);
+ }
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
@@ -544,7 +554,18 @@
var type = (obj.type || obj.attributeType),
//obj.value will come as an object when selected type is Date and operator is isNull or not_null;
value = ((_.isString(obj.value) && _.contains(["is_null", "not_null"], obj.operator) && type === 'date') || _.isObject(obj.value) ? "" : _.trim(obj.value || obj.attributeValue)),
- url = [(obj.id || obj.attributeName), mapApiOperatorToUI(obj.operator), (type === 'date' && formatedDateToLong && value.length ? Date.parse(value) : value)];
+ url = [(obj.id || obj.attributeName), mapApiOperatorToUI(obj.operator), value];
+ if (obj.operator === "TIME_RANGE") {
+ if (value.indexOf("-") > -1) {
+ url[2] = value.split('-').map(function(udKey) {
+ return Date.parse(udKey.trim()).toString()
+ }).join(",")
+ } else {
+ url[2] = Enums.queryBuilderDateRangeUIValueToAPI[_.trim(value)] || value;
+ }
+ } else if (value.length && type === 'date' && formatedDateToLong) {
+ url[2] = Date.parse(value);
+ }
if (type) {
url.push(type);
}
@@ -561,30 +582,8 @@
}
function mapApiOperatorToUI(oper) {
- if (oper == "eq") {
- return "=";
- } else if (oper == "neq") {
- return "!=";
- } else if (oper == "lt") {
- return "<";
- } else if (oper == "lte") {
- return "<=";
- } else if (oper == "gt") {
- return ">";
- } else if (oper == "gte") {
- return ">=";
- } else if (oper == "startsWith") {
- return "begins_with";
- } else if (oper == "endsWith") {
- return "ends_with";
- } else if (oper == "contains") {
- return "contains";
- } else if (oper == "notNull") {
- return "not_null";
- } else if (oper == "isNull") {
- return "is_null";
- }
- return oper;
+ // Enum will be in effect once we click on save search.
+ return Enums.queryBuilderApiOperatorToUI[oper] || oper;
}
},
extractUrl: function(options) {
@@ -594,30 +593,7 @@
spliter = 1,
apiObj = options.apiObj,
mapUiOperatorToAPI = function(oper) {
- if (oper == "=") {
- return "eq";
- } else if (oper == "!=") {
- return "neq";
- } else if (oper == "<") {
- return "lt";
- } else if (oper == "<=") {
- return "lte";
- } else if (oper == ">") {
- return "gt";
- } else if (oper == ">=") {
- return "gte";
- } else if (oper == "begins_with") {
- return "startsWith";
- } else if (oper == "ends_with") {
- return "endsWith";
- } else if (oper == "contains") {
- return "contains";
- } else if (oper == "not_null") {
- return "notNull";
- } else if (oper == "is_null") {
- return "isNull";
- }
- return oper;
+ return Enums.queryBuilderUIOperatorToAPI[oper] || oper;
},
createObject = function(urlObj) {
var finalObj = {};
@@ -636,13 +612,24 @@
rule = {};
if (apiObj) {
rule = { attributeName: temp[0], operator: mapUiOperatorToAPI(temp[1]), attributeValue: _.trim(temp[2]) }
+
rule.attributeValue = rule.type === 'date' && formatDate && rule.attributeValue.length ? moment(parseInt(rule.attributeValue)).format(Globals.dateTimeFormat) : rule.attributeValue;
} else {
rule = { id: temp[0], operator: temp[1], value: _.trim(temp[2]) }
if (temp[3]) {
rule['type'] = temp[3];
}
- rule.value = rule.type === 'date' && formatDate && rule.value.length ? moment(parseInt(rule.value)).format(Globals.dateTimeFormat) : rule.value;
+ if (rule.operator === "TIME_RANGE") {
+ if (temp[2].indexOf(",") > -1) {
+ rule.value = temp[2].split(",").map(function(udKey) {
+ return moment(parseInt(udKey.trim())).format(Globals.dateTimeFormat)
+ }).join(" - ")
+ } else {
+ rule.value = Enums.queryBuilderDateRangeAPIValueToUI[_.trim(rule.value)] || rule.value;
+ }
+ } else if (rule.type === 'date' && formatDate && rule.value.length) {
+ rule.value = moment(parseInt(rule.value)).format(Globals.dateTimeFormat)
+ }
}
return rule;
}
diff --git a/dashboardv2/public/js/utils/Enums.js b/dashboardv2/public/js/utils/Enums.js
index 24ec36b..131a08f 100644
--- a/dashboardv2/public/js/utils/Enums.js
+++ b/dashboardv2/public/js/utils/Enums.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require'], function(require) {
+define(["require", "backbone"], function(require) {
'use strict';
var Enums = {};
@@ -219,5 +219,40 @@
0: "false",
1: "true"
};
+
+ Enums.queryBuilderUIOperatorToAPI = {
+ "=": "eq",
+ "!=": "neq",
+ "<": "lt",
+ "<=": "lte",
+ ">": "gt",
+ ">=": "gte",
+ "begins_with": "startsWith",
+ "ends_with": "endsWith",
+ "not_null": "notNull",
+ "is_null": "isNull",
+ "TIME_RANGE": "timerange"
+ };
+
+ Enums.queryBuilderApiOperatorToUI = _.invert(Enums.queryBuilderUIOperatorToAPI);
+
+ Enums.queryBuilderDateRangeUIValueToAPI = {
+ "Today": "TODAY",
+ "Yesterday": "YESTERDAY",
+ "Last 7 Days": "LAST_7_DAYS",
+ "Last 30 Days": "LAST_30_DAYS",
+ "This Month": "THIS_MONTH",
+ "Last Month": "LAST_MONTH",
+ "This Quarter": "THIS_QUARTER",
+ "Last Quarter":"LAST_QUARTER",
+ "This Year": "THIS_YEAR",
+ "Last Year": "LAST_YEAR",
+ "Last 3 Months": "LAST_3_MONTHS",
+ "Last 6 Months": "LAST_6_MONTHS",
+ "Last 12 Months": "LAST_12_MONTHS"
+ };
+
+ Enums.queryBuilderDateRangeAPIValueToUI = _.invert(Enums.queryBuilderDateRangeUIValueToAPI);
+
return Enums;
});
\ No newline at end of file
diff --git a/dashboardv2/public/js/views/search/QueryBuilderView.js b/dashboardv2/public/js/views/search/QueryBuilderView.js
index dc36ffe..ba6cf0d 100644
--- a/dashboardv2/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv2/public/js/views/search/QueryBuilderView.js
@@ -24,9 +24,10 @@
'utils/CommonViewFunction',
'utils/Enums',
'utils/Globals',
+ 'moment',
'query-builder',
'daterangepicker'
-], function(require, Backbone, QueryBuilderTmpl, UserDefineTmpl, Utils, CommonViewFunction, Enums, Globals) {
+], function(require, Backbone, QueryBuilderTmpl, UserDefineTmpl, Utils, CommonViewFunction, Enums, Globals, moment) {
var QueryBuilderView = Backbone.Marionette.LayoutView.extend(
/** @lends QueryBuilderView */
@@ -58,6 +59,22 @@
_.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters'));
this.attrObj = _.sortBy(this.attrObj, 'name');
this.filterType = this.tag ? 'tagFilters' : 'entityFilters';
+ this.defaultRange = "Last 7 Days";
+ this.dateRangesMap = {
+ 'Today': [moment(), moment()],
+ 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+ 'Last 7 Days': [moment().subtract(6, 'days'), moment()],
+ 'Last 30 Days': [moment().subtract(29, 'days'), moment()],
+ 'This Month': [moment().startOf('month'), moment().endOf('month')],
+ 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 3 Months': [moment().subtract(3, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 6 Months': [moment().subtract(6, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 12 Months': [moment().subtract(12, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'This Quarter': [moment().startOf('quarter'), moment().endOf('quarter')],
+ 'Last Quarter': [moment().subtract(1, 'quarter').startOf('quarter'), moment().subtract(1, 'quarter').endOf('quarter')],
+ 'This Year': [moment().startOf('year'), moment().endOf('year')],
+ 'Last Year': [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')]
+ }
},
bindEvents: function() {},
getOperator: function(type, skipDefault) {
@@ -71,7 +88,7 @@
}
}
if (type === "date") {
- obj.operators = ['>', '<'];
+ obj.operators = ['=', '!=', '>', '<', '>=', '<=', 'TIME_RANGE'];
}
if (type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double") {
obj.operators = ['=', '!=', '>', '<', '>=', '<='];
@@ -266,20 +283,7 @@
}
if (obj.type === "date") {
obj['plugin'] = 'daterangepicker';
- obj['plugin_config'] = {
- "singleDatePicker": true,
- "showDropdowns": true,
- "timePicker": true,
- locale: {
- format: Globals.dateTimeFormat
- }
- };
- if (rules) {
- var valueObj = _.find(rules, { id: obj.id });
- if (valueObj) {
- obj.plugin_config["startDate"] = valueObj.value;
- }
- }
+ obj['plugin_config'] = this.getDateConfig(rules, obj.id);
_.extend(obj, this.getOperator(obj.type));
return obj;
}
@@ -316,6 +320,86 @@
return obj;
}
},
+ getDateConfig: function(ruleObj, id, operator) {
+ var valueObj = ruleObj ? (_.find(ruleObj.rules, { id: id }) || {}) : {},
+ isTimeRange = (valueObj.operator && valueObj.operator === "TIME_RANGE" && operator === "TIME_RANGE") || (operator === "TIME_RANGE"),
+ obj = {
+ opens: "center",
+ autoApply: true,
+ autoUpdateInput: false,
+ timePickerSeconds: true,
+ timePicker: true,
+ locale: {
+ format: Globals.dateTimeFormat
+ }
+ };
+
+ if (isTimeRange) {
+ var defaultRangeDate = this.dateRangesMap[this.defaultRange];
+ obj.startDate = defaultRangeDate[0];
+ obj.endDate = defaultRangeDate[1];
+ obj.singleDatePicker = false;
+ obj.ranges = this.dateRangesMap;
+ } else {
+ obj.singleDatePicker = true;
+ obj.startDate = moment();
+ obj.endDate = obj.startDate;
+ }
+
+ if (!_.isEmpty(valueObj) && operator === valueObj.operator) {
+ if (isTimeRange) {
+ if (valueObj.value.indexOf("-") > -1) {
+ var dates = valueObj.value.split("-");
+ obj.startDate = dates[0].trim();
+ obj.endDate = dates[1].trim();
+ } else {
+ var dates = this.dateRangesMap[valueObj.value]
+ obj.startDate = dates[0];
+ obj.endDate = dates[1];
+ }
+ obj.singleDatePicker = false;
+ } else {
+ obj.startDate = moment(valueObj.value);
+ obj.endDate = moment(valueObj.value);
+ obj.singleDatePicker = true;
+ }
+ }
+
+ return obj;
+ },
+ setDateValue: function(rule, rules_widgets) {
+ if (rule.filter.type === "date" && rule.operator.nb_inputs) {
+ var inputEl = rule.$el.find(".rule-value-container").find("input"),
+ datepickerEl = rule.$el.find(".rule-value-container").find("input").data("daterangepicker")
+ inputEl.attr('readonly', true);
+ if (datepickerEl) {
+ datepickerEl.remove();
+ var configObj = this.getDateConfig(rules_widgets, rule.filter.id, rule.operator.type)
+ inputEl.daterangepicker(configObj);
+ if (rule.operator.type === "TIME_RANGE") {
+ rule.value = this.defaultRange;
+ } else {
+ rule.value = configObj.startDate.format(Globals.dateTimeFormat);
+ }
+ inputEl.on('apply.daterangepicker', function(ev, picker) {
+ picker.setStartDate(picker.startDate);
+ picker.setEndDate(picker.endDate);
+ var valueString = "";
+ if (picker.chosenLabel) {
+ if (picker.chosenLabel === "Custom Range") {
+ valueString = picker.startDate.format(Globals.dateTimeFormat) + " - " + picker.endDate.format(Globals.dateTimeFormat);
+ } else {
+ valueString = picker.chosenLabel;
+ }
+ } else {
+ valueString = picker.startDate.format(Globals.dateTimeFormat);
+ }
+ picker.element.val(valueString);
+ rule.value = valueString;
+ });
+ }
+ }
+ },
onRender: function() {
var that = this,
filters = [],
@@ -339,7 +423,7 @@
rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters ? this.searchTableFilters["adminAttrFilters"] : null, "formatDate": true });;
} else {
if (this.value) {
- var rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
+ rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
}
_.each(this.attrObj, function(obj) {
var type = that.tag ? that.value.tag : that.value.type;
@@ -415,16 +499,20 @@
}
filters = _.uniq(filters, 'id');
if (filters && !_.isEmpty(filters)) {
- this.ui.builder.queryBuilder({
- plugins: ['bt-tooltip-errors'],
- filters: filters,
- select_placeholder: placeHolder,
- allow_empty: true,
- conditions: ['AND', 'OR'],
- allow_groups: true,
- allow_empty: true,
- templates: {
- rule: '<div id="{{= it.rule_id }}" class="rule-container"> \
+ this.ui.builder.off()
+ .on("afterUpdateRuleOperator.queryBuilder", function(e, rule) {
+ that.setDateValue(rule, rules_widgets);
+ })
+ .queryBuilder({
+ plugins: ['bt-tooltip-errors'],
+ filters: filters,
+ select_placeholder: placeHolder,
+ allow_empty: true,
+ conditions: ['AND', 'OR'],
+ allow_groups: true,
+ allow_empty: true,
+ templates: {
+ rule: '<div id="{{= it.rule_id }}" class="rule-container"> \
<div class="values-box"><div class="rule-filter-container"></div> \
<div class="rule-operator-container"></div> \
<div class="rule-value-container"></div></div> \
@@ -439,50 +527,58 @@
<div class="error-container"><i class="{{= it.icons.error }}"></i> <span></span></div> \
{{?}} \
</div>'
- },
- operators: [
- { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'like', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'in', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'is_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: 'not_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] }
- ],
- lang: {
- add_rule: 'Add filter',
- add_group: 'Add filter group',
- operators: {
- not_null: 'is not null'
+ },
+ operators: [
+ { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'like', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'in', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'is_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: 'not_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: 'TIME_RANGE', nb_inputs: 1, multiple: false, apply_to: ['date'] }
+ ],
+ lang: {
+ add_rule: 'Add filter',
+ add_group: 'Add filter group',
+ operators: {
+ not_null: 'is not null',
+ TIME_RANGE: "Time Range"
+ }
+ },
+ icons: {
+ add_rule: 'fa fa-plus',
+ remove_rule: 'fa fa-times',
+ error: 'fa fa-exclamation-triangle'
+ },
+ rules: rules_widgets
+ })
+ .on("afterCreateRuleInput.queryBuilder", function(e, rule) {
+ rule.error = null;
+ if (rule.operator.nb_inputs && rule.filter.id === "__customAttributes") {
+ rule.$el.addClass("user-define");
+ } else if (rule.$el.hasClass("user-define")) {
+ rule.$el.removeClass("user-define");
}
- },
- icons: {
- add_rule: 'fa fa-plus',
- remove_rule: 'fa fa-times',
- error: 'fa fa-exclamation-triangle'
- },
- rules: rules_widgets
- }).on("afterCreateRuleInput.queryBuilder", function(e, rule) {
- rule.error = null;
- if (rule.operator.nb_inputs && rule.filter.id === "__customAttributes") {
- rule.$el.addClass("user-define");
- } else if (rule.$el.hasClass("user-define")) {
- rule.$el.removeClass("user-define");
- }
- }).on('validationError.queryBuilder', function(e, rule, error, value) {
- // never display error for my custom filter
- var errorMsg = error[0];
- if (that.queryBuilderLang && that.queryBuilderLang.errors && that.queryBuilderLang.errors[errorMsg]) {
- errorMsg = that.queryBuilderLang.errors[errorMsg];
- }
- rule.$el.find(".error-container span").html(errorMsg);
- });
+ if (rule.filter.type === "date") {
+ rule.$el.find('.rule-value-container >input').attr('readonly', true)
+ }
+ that.setDateValue(rule, rules_widgets);
+ })
+ .on('validationError.queryBuilder', function(e, rule, error, value) {
+ // never display error for my custom filter
+ var errorMsg = error[0];
+ if (that.queryBuilderLang && that.queryBuilderLang.errors && that.queryBuilderLang.errors[errorMsg]) {
+ errorMsg = that.queryBuilderLang.errors[errorMsg];
+ }
+ rule.$el.find(".error-container span").html(errorMsg);
+ });
var queryBuilderEl = that.ui.builder.data("queryBuilder");
if (queryBuilderEl && queryBuilderEl.lang) {
this.queryBuilderLang = queryBuilderEl.lang;
diff --git a/dashboardv3/package-lock.json b/dashboardv3/package-lock.json
index a9c0764..9721967 100644
--- a/dashboardv3/package-lock.json
+++ b/dashboardv3/package-lock.json
@@ -357,9 +357,9 @@
"integrity": "sha1-WjiTlFSfIzMIdaOxUGVldPip63E="
},
"bootstrap-daterangepicker": {
- "version": "2.1.25",
- "resolved": "https://registry.npmjs.org/bootstrap-daterangepicker/-/bootstrap-daterangepicker-2.1.25.tgz",
- "integrity": "sha1-/Ni6C3VaBU0zDXo7fE3Yu4Vc/7c=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bootstrap-daterangepicker/-/bootstrap-daterangepicker-3.1.0.tgz",
+ "integrity": "sha512-oaQZx6ZBDo/dZNyXGVi2rx5GmFXThyQLAxdtIqjtLlYVaQUfQALl5JZMJJZzyDIX7blfy4ppZPAJ10g8Ma4d/g==",
"requires": {
"jquery": ">=1.10",
"moment": "^2.9.0"
diff --git a/dashboardv3/package.json b/dashboardv3/package.json
index cab875d..43ae1bb 100644
--- a/dashboardv3/package.json
+++ b/dashboardv3/package.json
@@ -29,7 +29,7 @@
"backgrid-select-all": "0.3.5",
"backgrid-sizeable-columns": "0.1.1",
"bootstrap": "3.3.7",
- "bootstrap-daterangepicker": "2.1.25",
+ "bootstrap-daterangepicker": "3.1.0",
"d3": "3.5.17",
"d3-tip": "0.6.8",
"dagre-d3": "0.6.4",
diff --git a/dashboardv3/public/css/scss/override.scss b/dashboardv3/public/css/scss/override.scss
index 7499894..1c8fcfc 100644
--- a/dashboardv3/public/css/scss/override.scss
+++ b/dashboardv3/public/css/scss/override.scss
@@ -304,7 +304,7 @@
}
.rule-operator-container {
- width: 105px;
+ width: 150px;
.form-control {
width: 100% !important;
@@ -511,4 +511,24 @@
overflow: hidden;
text-overflow: ellipsis;
}
+}
+
+.daterangepicker {
+
+ .ranges {
+ max-height: 328px;
+ overflow: auto;
+ }
+
+ .ranges li.active,
+ td.active {
+ background-color: $color_havelock_blue_approx;
+ }
+
+ .drp-buttons {
+ .applyBtn {
+ background-color: $color_havelock_blue_approx;
+ border-color: $color_havelock_blue_approx;
+ }
+ }
}
\ No newline at end of file
diff --git a/dashboardv3/public/js/main.js b/dashboardv3/public/js/main.js
index d5c6787..9f9747f 100644
--- a/dashboardv3/public/js/main.js
+++ b/dashboardv3/public/js/main.js
@@ -348,7 +348,6 @@
startApp();
}
});
-
this.businessMetadataDefCollection.fetch({
complete: function() {
that.businessMetadataDefCollection.fullCollection.comparator = function(model) {
diff --git a/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html b/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
index 23ad9a8..1ce1218 100644
--- a/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
+++ b/dashboardv3/public/js/templates/search/SearchDefaultLayoutView_tmpl.html
@@ -30,7 +30,7 @@
<button class="btn-action btn-sm attribute-filter-text" data-id='attrFilter'> <i class="fa fa-angle-right"></i> Filters</button>
<button class='btn-action btn-sm' data-id='clearQuerySearch'>Clear</button>
<div class="attribute-filter-container hide">
- <div class="panel panel-default expand_collapse_panel-icon" data-id="includeExclude">
+ <div class="panel panel-default expand_collapse_panel-icon" data-id="includeExclude" style="margin-bottom: 0px;">
<div class="panel-heading" data-toggle="collapse" href="#collapseIncludeExclude" aria-expanded="true">
<h4 class="panel-title">
<a>Include/Exclude</a>
@@ -40,8 +40,8 @@
</div>
</div>
<div id="collapseIncludeExclude" class="panel-collapse collapse in">
- <div class="panel-body">
- <div class="form-group filter-box">
+ <div class="panel-body" style="padding: 4px 15px;">
+ <div class="form-group filter-box" style="margin: 0;">
<div class="entity-detail-table-toggle">
<div class="pretty p-switch p-fill">
<input type="checkbox" data-id="checkDeletedEntity" data-value="includeDE" id="historicalentities" />
diff --git a/dashboardv3/public/js/utils/CommonViewFunction.js b/dashboardv3/public/js/utils/CommonViewFunction.js
index dd3818b..670e509 100644
--- a/dashboardv3/public/js/utils/CommonViewFunction.js
+++ b/dashboardv3/public/js/utils/CommonViewFunction.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums', 'moment', 'utils/Globals'], function(require, Utils, Modal, Messages, Enums, moment, Globals) {
+define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums', 'moment', 'utils/Globals', 'moment-timezone'], function(require, Utils, Modal, Messages, Enums, moment, Globals) {
'use strict';
var CommonViewFunction = {};
@@ -387,10 +387,14 @@
function objToString(filterObj, type) {
var generatedQuery = _.map(filterObj.rules, function(obj, key) {
+ var obj = $.extend(true, {}, obj); // not to update the timezone abbr on original obj , copy of obj is used
if (_.has(obj, 'condition')) {
return '<span class="operator">' + obj.condition + '</span>' + '(' + objToString(obj).join("") + ')';
} else {
if (isCapsuleView) {
+ if (obj.type === "date") {
+ obj.value = obj.value + " (" + moment.tz(moment.tz.guess()).zoneAbbr() + ")";
+ }
return '<div class="capsuleView"><span class="key">' + (Enums.systemAttributes[obj.id] ? Enums.systemAttributes[obj.id] : _.escape(obj.id)) + '</span><span class="operator">' + _.escape(obj.operator) + '</span><span class="value">' + (Enums[obj.id] ? Enums[obj.id][obj.value] : _.escape(obj.value)) + "</span><div class='fa fa-close clear-attr' data-type=" + type + " data-id=" + _.escape(obj.id) + "></div></div>";
}
return '<span class="key">' + (Enums.systemAttributes[obj.id] ? Enums.systemAttributes[obj.id] : _.escape(obj.id)) + '</span><span class="operator">' + _.escape(obj.operator) + '</span><span class="value">' + (Enums[obj.id] ? Enums[obj.id][obj.value] : _.escape(obj.value)) + "</span>";
@@ -507,6 +511,9 @@
if (Globals[value[skey].typeName]) {
attributeDefs = Globals[value[skey].typeName].attributeDefs;
}
+ if (Globals._ALL_CLASSIFICATION_TYPES && Globals._ALL_CLASSIFICATION_TYPES.attributeDefs) {
+ attributeDefs = attributeDefs.concat(Globals._ALL_CLASSIFICATION_TYPES.attributeDefs);
+ }
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (k == "entityFilters") {
@@ -523,6 +530,9 @@
if (Globals[value[skey].typeName]) {
attributeDefs = Globals[value[skey].typeName].attributeDefs;
}
+ if (Globals._ALL_ENTITY_TYPES && Globals._ALL_ENTITY_TYPES.attributeDefs) {
+ attributeDefs = attributeDefs.concat(Globals._ALL_ENTITY_TYPES.attributeDefs);
+ }
}
val = CommonViewFunction.attributeFilter.generateUrl({ "value": val, "attributeDefs": attributeDefs });
} else if (_.contains(["includeDE", "excludeST", "excludeSC"], k)) {
@@ -564,7 +574,18 @@
var type = (obj.type || obj.attributeType),
//obj.value will come as an object when selected type is Date and operator is isNull or not_null;
value = ((_.isString(obj.value) && _.contains(["is_null", "not_null"], obj.operator) && type === 'date') || _.isObject(obj.value) ? "" : _.trim(obj.value || obj.attributeValue)),
- url = [(obj.id || obj.attributeName), mapApiOperatorToUI(obj.operator), (type === 'date' && formatedDateToLong && value.length ? Date.parse(value) : value)];
+ url = [(obj.id || obj.attributeName), mapApiOperatorToUI(obj.operator), value];
+ if (obj.operator === "TIME_RANGE") {
+ if (value.indexOf("-") > -1) {
+ url[2] = value.split('-').map(function(udKey) {
+ return Date.parse(udKey.trim()).toString()
+ }).join(",")
+ } else {
+ url[2] = Enums.queryBuilderDateRangeUIValueToAPI[_.trim(value)] || value;
+ }
+ } else if (value.length && type === 'date' && formatedDateToLong) {
+ url[2] = Date.parse(value);
+ }
if (type) {
url.push(type);
}
@@ -581,30 +602,8 @@
}
function mapApiOperatorToUI(oper) {
- if (oper == "eq") {
- return "=";
- } else if (oper == "neq") {
- return "!=";
- } else if (oper == "lt") {
- return "<";
- } else if (oper == "lte") {
- return "<=";
- } else if (oper == "gt") {
- return ">";
- } else if (oper == "gte") {
- return ">=";
- } else if (oper == "startsWith") {
- return "begins_with";
- } else if (oper == "endsWith") {
- return "ends_with";
- } else if (oper == "contains") {
- return "contains";
- } else if (oper == "notNull") {
- return "not_null";
- } else if (oper == "isNull") {
- return "is_null";
- }
- return oper;
+ // Enum will be in effect once we click on save search.
+ return Enums.queryBuilderApiOperatorToUI[oper] || oper;
}
},
extractUrl: function(options) {
@@ -614,30 +613,7 @@
spliter = 1,
apiObj = options.apiObj,
mapUiOperatorToAPI = function(oper) {
- if (oper == "=") {
- return "eq";
- } else if (oper == "!=") {
- return "neq";
- } else if (oper == "<") {
- return "lt";
- } else if (oper == "<=") {
- return "lte";
- } else if (oper == ">") {
- return "gt";
- } else if (oper == ">=") {
- return "gte";
- } else if (oper == "begins_with") {
- return "startsWith";
- } else if (oper == "ends_with") {
- return "endsWith";
- } else if (oper == "contains") {
- return "contains";
- } else if (oper == "not_null") {
- return "notNull";
- } else if (oper == "is_null") {
- return "isNull";
- }
- return oper;
+ return Enums.queryBuilderUIOperatorToAPI[oper] || oper;
},
createObject = function(urlObj) {
var finalObj = {};
@@ -662,7 +638,17 @@
if (temp[3]) {
rule['type'] = temp[3];
}
- rule.value = rule.type === 'date' && formatDate && rule.value.length ? moment(parseInt(rule.value)).format(Globals.dateTimeFormat) : rule.value;
+ if (rule.operator === "TIME_RANGE") {
+ if (temp[2].indexOf(",") > -1) {
+ rule.value = temp[2].split(",").map(function(udKey) {
+ return moment(parseInt(udKey.trim())).format(Globals.dateTimeFormat)
+ }).join(" - ")
+ } else {
+ rule.value = Enums.queryBuilderDateRangeAPIValueToUI[_.trim(rule.value)] || rule.value;
+ }
+ } else if (rule.type === 'date' && formatDate && rule.value.length) {
+ rule.value = moment(parseInt(rule.value)).format(Globals.dateTimeFormat)
+ }
}
return rule;
}
diff --git a/dashboardv3/public/js/utils/Enums.js b/dashboardv3/public/js/utils/Enums.js
index 24ec36b..131a08f 100644
--- a/dashboardv3/public/js/utils/Enums.js
+++ b/dashboardv3/public/js/utils/Enums.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require'], function(require) {
+define(["require", "backbone"], function(require) {
'use strict';
var Enums = {};
@@ -219,5 +219,40 @@
0: "false",
1: "true"
};
+
+ Enums.queryBuilderUIOperatorToAPI = {
+ "=": "eq",
+ "!=": "neq",
+ "<": "lt",
+ "<=": "lte",
+ ">": "gt",
+ ">=": "gte",
+ "begins_with": "startsWith",
+ "ends_with": "endsWith",
+ "not_null": "notNull",
+ "is_null": "isNull",
+ "TIME_RANGE": "timerange"
+ };
+
+ Enums.queryBuilderApiOperatorToUI = _.invert(Enums.queryBuilderUIOperatorToAPI);
+
+ Enums.queryBuilderDateRangeUIValueToAPI = {
+ "Today": "TODAY",
+ "Yesterday": "YESTERDAY",
+ "Last 7 Days": "LAST_7_DAYS",
+ "Last 30 Days": "LAST_30_DAYS",
+ "This Month": "THIS_MONTH",
+ "Last Month": "LAST_MONTH",
+ "This Quarter": "THIS_QUARTER",
+ "Last Quarter":"LAST_QUARTER",
+ "This Year": "THIS_YEAR",
+ "Last Year": "LAST_YEAR",
+ "Last 3 Months": "LAST_3_MONTHS",
+ "Last 6 Months": "LAST_6_MONTHS",
+ "Last 12 Months": "LAST_12_MONTHS"
+ };
+
+ Enums.queryBuilderDateRangeAPIValueToUI = _.invert(Enums.queryBuilderDateRangeUIValueToAPI);
+
return Enums;
});
\ No newline at end of file
diff --git a/dashboardv3/public/js/views/search/QueryBuilderView.js b/dashboardv3/public/js/views/search/QueryBuilderView.js
index dc36ffe..06ecd01 100644
--- a/dashboardv3/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv3/public/js/views/search/QueryBuilderView.js
@@ -24,9 +24,10 @@
'utils/CommonViewFunction',
'utils/Enums',
'utils/Globals',
+ 'moment',
'query-builder',
'daterangepicker'
-], function(require, Backbone, QueryBuilderTmpl, UserDefineTmpl, Utils, CommonViewFunction, Enums, Globals) {
+], function(require, Backbone, QueryBuilderTmpl, UserDefineTmpl, Utils, CommonViewFunction, Enums, Globals, moment) {
var QueryBuilderView = Backbone.Marionette.LayoutView.extend(
/** @lends QueryBuilderView */
@@ -58,6 +59,22 @@
_.extend(this, _.pick(options, 'attrObj', 'value', 'typeHeaders', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'businessMetadataDefCollection', 'tag', 'type', 'searchTableFilters', 'systemAttrArr', 'adminAttrFilters'));
this.attrObj = _.sortBy(this.attrObj, 'name');
this.filterType = this.tag ? 'tagFilters' : 'entityFilters';
+ this.defaultRange = "Last 7 Days";
+ this.dateRangesMap = {
+ 'Today': [moment(), moment()],
+ 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
+ 'Last 7 Days': [moment().subtract(6, 'days'), moment()],
+ 'Last 30 Days': [moment().subtract(29, 'days'), moment()],
+ 'This Month': [moment().startOf('month'), moment().endOf('month')],
+ 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 3 Months': [moment().subtract(3, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 6 Months': [moment().subtract(6, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'Last 12 Months': [moment().subtract(12, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
+ 'This Quarter': [moment().startOf('quarter'), moment().endOf('quarter')],
+ 'Last Quarter': [moment().subtract(1, 'quarter').startOf('quarter'), moment().subtract(1, 'quarter').endOf('quarter')],
+ 'This Year': [moment().startOf('year'), moment().endOf('year')],
+ 'Last Year': [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')]
+ }
},
bindEvents: function() {},
getOperator: function(type, skipDefault) {
@@ -71,7 +88,7 @@
}
}
if (type === "date") {
- obj.operators = ['>', '<'];
+ obj.operators = ['=', '!=', '>', '<', '>=', '<=', 'TIME_RANGE'];
}
if (type === "int" || type === "byte" || type === "short" || type === "long" || type === "float" || type === "double") {
obj.operators = ['=', '!=', '>', '<', '>=', '<='];
@@ -266,20 +283,7 @@
}
if (obj.type === "date") {
obj['plugin'] = 'daterangepicker';
- obj['plugin_config'] = {
- "singleDatePicker": true,
- "showDropdowns": true,
- "timePicker": true,
- locale: {
- format: Globals.dateTimeFormat
- }
- };
- if (rules) {
- var valueObj = _.find(rules, { id: obj.id });
- if (valueObj) {
- obj.plugin_config["startDate"] = valueObj.value;
- }
- }
+ obj['plugin_config'] = this.getDateConfig(rules, obj.id);
_.extend(obj, this.getOperator(obj.type));
return obj;
}
@@ -316,6 +320,86 @@
return obj;
}
},
+ getDateConfig: function(ruleObj, id, operator) {
+ var valueObj = ruleObj ? (_.find(ruleObj.rules, { id: id }) || {}) : {},
+ isTimeRange = (valueObj.operator && valueObj.operator === "TIME_RANGE" && operator === "TIME_RANGE") || (operator === "TIME_RANGE"),
+ obj = {
+ opens: "center",
+ autoApply: true,
+ autoUpdateInput: false,
+ timePickerSeconds: true,
+ timePicker: true,
+ locale: {
+ format: Globals.dateTimeFormat
+ }
+ };
+
+ if (isTimeRange) {
+ var defaultRangeDate = this.dateRangesMap[this.defaultRange];
+ obj.startDate = defaultRangeDate[0];
+ obj.endDate = defaultRangeDate[1];
+ obj.singleDatePicker = false;
+ obj.ranges = this.dateRangesMap;
+ } else {
+ obj.singleDatePicker = true;
+ obj.startDate = moment();
+ obj.endDate = obj.startDate;
+ }
+
+ if (!_.isEmpty(valueObj) && operator === valueObj.operator) {
+ if (isTimeRange) {
+ if (valueObj.value.indexOf("-") > -1) {
+ var dates = valueObj.value.split("-");
+ obj.startDate = dates[0].trim();
+ obj.endDate = dates[1].trim();
+ } else {
+ var dates = this.dateRangesMap[valueObj.value]
+ obj.startDate = dates[0];
+ obj.endDate = dates[1];
+ }
+ obj.singleDatePicker = false;
+ } else {
+ obj.startDate = moment(valueObj.value);
+ obj.endDate = moment(valueObj.value);
+ obj.singleDatePicker = true;
+ }
+ }
+
+ return obj;
+ },
+ setDateValue: function(rule, rules_widgets) {
+ if (rule.filter.type === "date" && rule.operator.nb_inputs) {
+ var inputEl = rule.$el.find(".rule-value-container").find("input"),
+ datepickerEl = rule.$el.find(".rule-value-container").find("input").data("daterangepicker")
+ inputEl.attr('readonly', true);
+ if (datepickerEl) {
+ datepickerEl.remove();
+ var configObj = this.getDateConfig(rules_widgets, rule.filter.id, rule.operator.type)
+ inputEl.daterangepicker(configObj);
+ if (rule.operator.type === "TIME_RANGE") {
+ rule.value = this.defaultRange;
+ } else {
+ rule.value = configObj.startDate.format(Globals.dateTimeFormat);
+ }
+ inputEl.on('apply.daterangepicker', function(ev, picker) {
+ picker.setStartDate(picker.startDate);
+ picker.setEndDate(picker.endDate);
+ var valueString = "";
+ if (picker.chosenLabel) {
+ if (picker.chosenLabel === "Custom Range") {
+ valueString = picker.startDate.format(Globals.dateTimeFormat) + " - " + picker.endDate.format(Globals.dateTimeFormat);
+ } else {
+ valueString = picker.chosenLabel;
+ }
+ } else {
+ valueString = picker.startDate.format(Globals.dateTimeFormat);
+ }
+ picker.element.val(valueString);
+ rule.value = valueString;
+ });
+ }
+ }
+ },
onRender: function() {
var that = this,
filters = [],
@@ -339,7 +423,7 @@
rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters ? this.searchTableFilters["adminAttrFilters"] : null, "formatDate": true });;
} else {
if (this.value) {
- var rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
+ rules_widgets = CommonViewFunction.attributeFilter.extractUrl({ "value": this.searchTableFilters[this.filterType][(this.tag ? this.value.tag : this.value.type)], "formatDate": true });
}
_.each(this.attrObj, function(obj) {
var type = that.tag ? that.value.tag : that.value.type;
@@ -415,16 +499,20 @@
}
filters = _.uniq(filters, 'id');
if (filters && !_.isEmpty(filters)) {
- this.ui.builder.queryBuilder({
- plugins: ['bt-tooltip-errors'],
- filters: filters,
- select_placeholder: placeHolder,
- allow_empty: true,
- conditions: ['AND', 'OR'],
- allow_groups: true,
- allow_empty: true,
- templates: {
- rule: '<div id="{{= it.rule_id }}" class="rule-container"> \
+ this.ui.builder.off()
+ .on("afterUpdateRuleOperator.queryBuilder", function(e, rule) {
+ that.setDateValue(rule, rules_widgets);
+ })
+ .queryBuilder({
+ plugins: ['bt-tooltip-errors'],
+ filters: filters,
+ select_placeholder: placeHolder,
+ allow_empty: true,
+ conditions: ['AND', 'OR'],
+ allow_groups: true,
+ allow_empty: true,
+ templates: {
+ rule: '<div id="{{= it.rule_id }}" class="rule-container"> \
<div class="values-box"><div class="rule-filter-container"></div> \
<div class="rule-operator-container"></div> \
<div class="rule-value-container"></div></div> \
@@ -439,50 +527,58 @@
<div class="error-container"><i class="{{= it.icons.error }}"></i> <span></span></div> \
{{?}} \
</div>'
- },
- operators: [
- { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'like', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'in', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
- { type: 'is_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
- { type: 'not_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] }
- ],
- lang: {
- add_rule: 'Add filter',
- add_group: 'Add filter group',
- operators: {
- not_null: 'is not null'
+ },
+ operators: [
+ { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '<=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: 'contains', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'like', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'in', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'begins_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'ends_with', nb_inputs: 1, multiple: false, apply_to: ['string'] },
+ { type: 'is_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: 'not_null', nb_inputs: false, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: 'TIME_RANGE', nb_inputs: 1, multiple: false, apply_to: ['date'] }
+ ],
+ lang: {
+ add_rule: 'Add filter',
+ add_group: 'Add filter group',
+ operators: {
+ not_null: 'is not null',
+ TIME_RANGE: "Time Range"
+ }
+ },
+ icons: {
+ add_rule: 'fa fa-plus',
+ remove_rule: 'fa fa-times',
+ error: 'fa fa-exclamation-triangle'
+ },
+ rules: rules_widgets
+ })
+ .on("afterCreateRuleInput.queryBuilder", function(e, rule) {
+ rule.error = null;
+ if (rule.operator.nb_inputs && rule.filter.id === "__customAttributes") {
+ rule.$el.addClass("user-define");
+ } else if (rule.$el.hasClass("user-define")) {
+ rule.$el.removeClass("user-define");
}
- },
- icons: {
- add_rule: 'fa fa-plus',
- remove_rule: 'fa fa-times',
- error: 'fa fa-exclamation-triangle'
- },
- rules: rules_widgets
- }).on("afterCreateRuleInput.queryBuilder", function(e, rule) {
- rule.error = null;
- if (rule.operator.nb_inputs && rule.filter.id === "__customAttributes") {
- rule.$el.addClass("user-define");
- } else if (rule.$el.hasClass("user-define")) {
- rule.$el.removeClass("user-define");
- }
- }).on('validationError.queryBuilder', function(e, rule, error, value) {
- // never display error for my custom filter
- var errorMsg = error[0];
- if (that.queryBuilderLang && that.queryBuilderLang.errors && that.queryBuilderLang.errors[errorMsg]) {
- errorMsg = that.queryBuilderLang.errors[errorMsg];
- }
- rule.$el.find(".error-container span").html(errorMsg);
- });
+ if (rule.filter.type === "date") {
+ rule.$el.find('.rule-value-container >input').attr('readonly', true);
+ }
+ that.setDateValue(rule, rules_widgets);
+ })
+ .on('validationError.queryBuilder', function(e, rule, error, value) {
+ // never display error for my custom filter
+ var errorMsg = error[0];
+ if (that.queryBuilderLang && that.queryBuilderLang.errors && that.queryBuilderLang.errors[errorMsg]) {
+ errorMsg = that.queryBuilderLang.errors[errorMsg];
+ }
+ rule.$el.find(".error-container span").html(errorMsg);
+ });
var queryBuilderEl = that.ui.builder.data("queryBuilder");
if (queryBuilderEl && queryBuilderEl.lang) {
this.queryBuilderLang = queryBuilderEl.lang;
diff --git a/dashboardv3/public/js/views/search/tree/EntityTreeLayoutView.js b/dashboardv3/public/js/views/search/tree/EntityTreeLayoutView.js
index f2111ca..a859ea0 100644
--- a/dashboardv3/public/js/views/search/tree/EntityTreeLayoutView.js
+++ b/dashboardv3/public/js/views/search/tree/EntityTreeLayoutView.js
@@ -242,7 +242,8 @@
params["entityFilters"] = null;
}
}
-
+ var getUrl = Utils.getUrlState.isSearchTab();
+ if (!getUrl) { that.typeId = null; }
if (that.typeId != selectedNodeId) {
that.typeId = selectedNodeId;
typeValue = name;