QueryBuilderView.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. define([ "require", "backbone", "hbs!tmpl/search/QueryBuilder_tmpl", "hbs!tmpl/search/UserDefine_tmpl", "utils/Utils", "utils/CommonViewFunction", "utils/Enums", "utils/Globals", "moment", "query-builder", "daterangepicker" ], function(require, Backbone, QueryBuilderTmpl, UserDefineTmpl, Utils, CommonViewFunction, Enums, Globals, moment) {
  2. var QueryBuilderView = Backbone.Marionette.LayoutView.extend({
  3. _viewName: "QueryBuilderView",
  4. template: QueryBuilderTmpl,
  5. regions: {},
  6. ui: {
  7. builder: "#builder"
  8. },
  9. events: function() {
  10. var events = {};
  11. return events;
  12. },
  13. initialize: function(options) {
  14. _.extend(this, _.pick(options, "attrObj", "value", "typeHeaders", "entityDefCollection", "enumDefCollection", "classificationDefCollection", "businessMetadataDefCollection", "tag", "type", "searchTableFilters", "systemAttrArr", "adminAttrFilters")),
  15. this.attrObj = _.sortBy(this.attrObj, "name"), this.filterType = this.tag ? "tagFilters" : "entityFilters",
  16. this.defaultRange = "Last 7 Days", this.dateRangesMap = {
  17. Today: [ moment(), moment() ],
  18. Yesterday: [ moment().subtract(1, "days"), moment().subtract(1, "days") ],
  19. "Last 7 Days": [ moment().subtract(6, "days"), moment() ],
  20. "Last 30 Days": [ moment().subtract(29, "days"), moment() ],
  21. "This Month": [ moment().startOf("month"), moment().endOf("month") ],
  22. "Last Month": [ moment().subtract(1, "month").startOf("month"), moment().subtract(1, "month").endOf("month") ],
  23. "Last 3 Months": [ moment().subtract(3, "month").startOf("month"), moment().subtract(1, "month").endOf("month") ],
  24. "Last 6 Months": [ moment().subtract(6, "month").startOf("month"), moment().subtract(1, "month").endOf("month") ],
  25. "Last 12 Months": [ moment().subtract(12, "month").startOf("month"), moment().subtract(1, "month").endOf("month") ],
  26. "This Quarter": [ moment().startOf("quarter"), moment().endOf("quarter") ],
  27. "Last Quarter": [ moment().subtract(1, "quarter").startOf("quarter"), moment().subtract(1, "quarter").endOf("quarter") ],
  28. "This Year": [ moment().startOf("year"), moment().endOf("year") ],
  29. "Last Year": [ moment().subtract(1, "year").startOf("year"), moment().subtract(1, "year").endOf("year") ]
  30. };
  31. },
  32. bindEvents: function() {},
  33. getOperator: function(type, skipDefault) {
  34. var obj = {
  35. operators: null
  36. };
  37. return "string" === type && (obj.operators = [ "=", "!=", "contains", "begins_with", "ends_with" ],
  38. this.adminAttrFilters && (obj.operators = obj.operators.concat([ "like", "in" ]))),
  39. "date" === type && (obj.operators = [ "=", "!=", ">", "<", ">=", "<=", "TIME_RANGE" ]),
  40. "int" !== type && "byte" !== type && "short" !== type && "long" !== type && "float" !== type && "double" !== type || (obj.operators = [ "=", "!=", ">", "<", ">=", "<=" ]),
  41. "enum" !== type && "boolean" !== type || (obj.operators = [ "=", "!=" ]), _.isEmpty(skipDefault) && obj.operators && (obj.operators = obj.operators.concat([ "is_null", "not_null" ])),
  42. obj;
  43. },
  44. isPrimitive: function(type) {
  45. return "int" === type || "byte" === type || "short" === type || "long" === type || "float" === type || "double" === type || "string" === type || "boolean" === type || "date" === type;
  46. },
  47. getUserDefineInput: function() {
  48. return UserDefineTmpl();
  49. },
  50. getObjDef: function(attrObj, rules, isGroup, groupType, isSystemAttr) {
  51. var that = this;
  52. if ("__classificationsText" !== attrObj.name && "__historicalGuids" !== attrObj.name) {
  53. var getLableWithType = function(label, name) {
  54. return "__classificationNames" === name || "__customAttributes" === name || "__labels" === name || "__propagatedClassificationNames" === name ? label : label + " (" + attrObj.typeName + ")";
  55. }, label = Enums.systemAttributes[attrObj.name] ? Enums.systemAttributes[attrObj.name] : _.escape(attrObj.name.capitalize()), obj = {
  56. id: attrObj.name,
  57. label: getLableWithType(label, attrObj.name),
  58. plainLabel: label,
  59. type: _.escape(attrObj.typeName),
  60. validation: {
  61. callback: function(value, rule) {
  62. return rule.operator.nb_inputs === !1 || !_.isEmpty(value) || !value instanceof Error || (value instanceof Error ? value.message : rule.filter.plainLabel + " is required");
  63. }
  64. }
  65. };
  66. if (isGroup && (obj.optgroup = groupType), isSystemAttr && "__isIncomplete" === attrObj.name || isSystemAttr && "IsIncomplete" === attrObj.name) return obj.type = "boolean",
  67. obj.label = (Enums.systemAttributes[attrObj.name] ? Enums.systemAttributes[attrObj.name] : _.escape(attrObj.name.capitalize())) + " (boolean)",
  68. obj.input = "select", obj.values = [ {
  69. 1: "true"
  70. }, {
  71. 0: "false"
  72. } ], _.extend(obj, this.getOperator("boolean")), obj;
  73. if (isSystemAttr && "Status" === attrObj.name || isSystemAttr && "__state" === attrObj.name || isSystemAttr && "__entityStatus" === attrObj.name) return obj.label = (Enums.systemAttributes[attrObj.name] ? Enums.systemAttributes[attrObj.name] : _.escape(attrObj.name.capitalize())) + " (enum)",
  74. obj.input = "select", obj.values = [ "ACTIVE", "DELETED" ], _.extend(obj, this.getOperator("boolean", !0)),
  75. obj;
  76. if (isSystemAttr && "__classificationNames" === attrObj.name || "__propagatedClassificationNames" === attrObj.name) return obj.plugin = "select2",
  77. obj.input = "select", obj.plugin_config = {
  78. placeholder: "Select classfication",
  79. tags: !0,
  80. multiple: !1,
  81. data: this.classificationDefCollection.fullCollection.models.map(function(o) {
  82. return {
  83. id: o.get("name"),
  84. text: o.get("name")
  85. };
  86. })
  87. }, obj.valueSetter = function(rule) {
  88. if (rule && !_.isEmpty(rule.value)) {
  89. var selectEl = rule.$el.find(".rule-value-container select"), valFound = that.classificationDefCollection.fullCollection.find(function(o) {
  90. return o.get("name") === rule.value;
  91. });
  92. if (valFound) selectEl.val(rule.value).trigger("change"); else {
  93. var newOption = new Option(rule.value, rule.value, !1, !1);
  94. selectEl.append(newOption).val(rule.value);
  95. }
  96. }
  97. }, _.extend(obj, this.getOperator("string")), obj;
  98. if (isSystemAttr && "__customAttributes" === attrObj.name) return obj.input = function(rule) {
  99. return rule && rule.operator && rule.operator.nb_inputs ? that.getUserDefineInput() : null;
  100. }, obj.valueGetter = function(rule) {
  101. if (rule && rule.operator && "contains" === rule.operator.type) {
  102. var $el = rule.$el.find(".rule-value-container"), key = $el.find("[data-type='key']").val(), val = $el.find("[data-type='value']").val();
  103. return _.isEmpty(key) || _.isEmpty(val) ? new Error("Key & Value is Required") : key + "=" + val;
  104. }
  105. return [];
  106. }, obj.valueSetter = function(rule) {
  107. if (rule && !rule.$el.hasClass("user-define") && rule.$el.addClass("user-define"),
  108. rule && rule.value && rule.value.length && !(rule.value instanceof Error)) {
  109. var $el = rule.$el.find(".rule-value-container"), value = rule.value.split("=");
  110. value && ($el.find("[data-type='key']").val(value[0]), $el.find("[data-type='value']").val(value[1]));
  111. }
  112. }, obj.operators = [ "contains", "is_null", "not_null" ], obj;
  113. if (isSystemAttr && "__typeName" === attrObj.name) {
  114. var entityType = [];
  115. return that.typeHeaders.fullCollection.each(function(model) {
  116. (1 == that.type && "ENTITY" == model.get("category") || 1 == that.tag && "CLASSIFICATION" == model.get("category")) && entityType.push({
  117. id: model.get("name"),
  118. text: model.get("name")
  119. });
  120. }), obj.plugin = "select2", obj.input = "select", obj.plugin_config = {
  121. placeholder: "请选择类型",
  122. tags: !0,
  123. multiple: !1,
  124. data: entityType
  125. }, obj.valueSetter = function(rule) {
  126. if (rule && !_.isEmpty(rule.value)) {
  127. var selectEl = rule.$el.find(".rule-value-container select"), valFound = that.typeHeaders.fullCollection.find(function(o) {
  128. return o.get("name") === rule.value;
  129. });
  130. if (valFound) selectEl.val(rule.value).trigger("change"); else {
  131. var newOption = new Option(rule.value, rule.value, !1, !1);
  132. selectEl.append(newOption).val(rule.value);
  133. }
  134. }
  135. }, _.extend(obj, this.getOperator("string")), obj;
  136. }
  137. if ("date" === obj.type) return obj.plugin = "daterangepicker", obj.plugin_config = this.getDateConfig(rules, obj.id),
  138. _.extend(obj, this.getOperator(obj.type)), obj;
  139. if (this.isPrimitive(obj.type)) return "boolean" === obj.type && (obj.input = "select",
  140. obj.values = [ "true", "false" ]), _.extend(obj, this.getOperator(obj.type, !1)),
  141. _.has(Enums.regex.RANGE_CHECK, obj.type) && (obj.validation = {
  142. min: Enums.regex.RANGE_CHECK[obj.type].min,
  143. max: Enums.regex.RANGE_CHECK[obj.type].max
  144. }, "double" === obj.type || "float" === obj.type ? obj.type = "double" : "int" !== obj.type && "byte" !== obj.type && "short" !== obj.type && "long" !== obj.type || (obj.type = "integer")),
  145. obj;
  146. var enumObj = this.enumDefCollection.fullCollection.find({
  147. name: obj.type
  148. });
  149. if (enumObj) {
  150. obj.type = "string", obj.input = "select";
  151. var value = [];
  152. return _.each(enumObj.get("elementDefs"), function(o) {
  153. value.push(o.value);
  154. }), obj.values = value, _.extend(obj, this.getOperator("enum")), obj;
  155. }
  156. }
  157. },
  158. getDateConfig: function(ruleObj, id, operator) {
  159. var valueObj = ruleObj ? _.find(ruleObj.rules, {
  160. id: id
  161. }) || {} : {}, isTimeRange = valueObj.operator && "TIME_RANGE" === valueObj.operator && "TIME_RANGE" === operator || "TIME_RANGE" === operator, obj = {
  162. opens: "center",
  163. autoApply: !0,
  164. autoUpdateInput: !1,
  165. timePickerSeconds: !0,
  166. timePicker: !0,
  167. locale: {
  168. format: Globals.dateTimeFormat
  169. }
  170. };
  171. if (isTimeRange) {
  172. var defaultRangeDate = this.dateRangesMap[this.defaultRange];
  173. obj.startDate = defaultRangeDate[0], obj.endDate = defaultRangeDate[1], obj.singleDatePicker = !1,
  174. obj.ranges = this.dateRangesMap;
  175. } else obj.singleDatePicker = !0, obj.startDate = moment(), obj.endDate = obj.startDate;
  176. if (!_.isEmpty(valueObj) && operator === valueObj.operator) if (isTimeRange) {
  177. if (valueObj.value.indexOf("-") > -1) {
  178. var dates = valueObj.value.split("-");
  179. obj.startDate = dates[0].trim(), obj.endDate = dates[1].trim();
  180. } else {
  181. var dates = this.dateRangesMap[valueObj.value];
  182. obj.startDate = dates[0], obj.endDate = dates[1];
  183. }
  184. obj.singleDatePicker = !1;
  185. } else obj.startDate = moment(Date.parse(valueObj.value)), obj.endDate = obj.startDate,
  186. obj.singleDatePicker = !0;
  187. return obj;
  188. },
  189. setDateValue: function(rule, rules_widgets) {
  190. if ("date" === rule.filter.type && rule.operator.nb_inputs) {
  191. var inputEl = rule.$el.find(".rule-value-container").find("input"), datepickerEl = rule.$el.find(".rule-value-container").find("input").data("daterangepicker");
  192. if (inputEl.attr("readonly", !0), datepickerEl) {
  193. datepickerEl.remove();
  194. var configObj = this.getDateConfig(rules_widgets, rule.filter.id, rule.operator.type);
  195. inputEl.daterangepicker(configObj), "TIME_RANGE" === rule.operator.type ? rule.value = this.defaultRange : rule.value = configObj.startDate.format(Globals.dateTimeFormat),
  196. inputEl.on("apply.daterangepicker", function(ev, picker) {
  197. picker.setStartDate(picker.startDate), picker.setEndDate(picker.endDate);
  198. var valueString = "";
  199. valueString = picker.chosenLabel ? "Custom Range" === picker.chosenLabel ? picker.startDate.format(Globals.dateTimeFormat) + " - " + picker.endDate.format(Globals.dateTimeFormat) : picker.chosenLabel : picker.startDate.format(Globals.dateTimeFormat),
  200. picker.element.val(valueString), rule.value = valueString;
  201. });
  202. }
  203. }
  204. },
  205. onRender: function() {
  206. var that = this, filters = [], isGroupView = !0, placeHolder = "--Select Attribute--", rules_widgets = null;
  207. if (this.adminAttrFilters) {
  208. var entityDef = this.entityDefCollection.fullCollection.find({
  209. name: "__AtlasAuditEntry"
  210. }), auditEntryAttributeDefs = null;
  211. entityDef && (auditEntryAttributeDefs = $.extend(!0, {}, entityDef.get("attributeDefs")) || null),
  212. auditEntryAttributeDefs && _.each(auditEntryAttributeDefs, function(attributes) {
  213. var returnObj = that.getObjDef(attributes, rules_widgets);
  214. returnObj && filters.push(returnObj);
  215. }), rules_widgets = CommonViewFunction.attributeFilter.extractUrl({
  216. value: this.searchTableFilters ? this.searchTableFilters.adminAttrFilters : null,
  217. formatDate: !0
  218. });
  219. } else {
  220. this.value && (rules_widgets = CommonViewFunction.attributeFilter.extractUrl({
  221. value: this.searchTableFilters[this.filterType][this.tag ? this.value.tag : this.value.type],
  222. formatDate: !0
  223. })), _.each(this.attrObj, function(obj) {
  224. var type = that.tag ? that.value.tag : that.value.type, returnObj = that.getObjDef(obj, rules_widgets, isGroupView, type + " Attribute");
  225. returnObj && filters.push(returnObj);
  226. });
  227. var sortMap = {
  228. __guid: 1,
  229. __typeName: 2,
  230. __timestamp: 3,
  231. __modificationTimestamp: 4,
  232. __createdBy: 5,
  233. __modifiedBy: 6,
  234. __isIncomplete: 7,
  235. __classificationNames: 9,
  236. __propagatedClassificationNames: 10,
  237. __labels: 11,
  238. __customAttributes: 12
  239. };
  240. if (that.type ? sortMap.__state = 8 : sortMap.__entityStatus = 8, this.systemAttrArr = _.sortBy(this.systemAttrArr, function(obj) {
  241. return sortMap[obj.name];
  242. }), _.each(this.systemAttrArr, function(obj) {
  243. var returnObj = that.getObjDef(obj, rules_widgets, isGroupView, "System Attribute", !0);
  244. returnObj && filters.push(returnObj);
  245. }), this.type) {
  246. var pushBusinessMetadataFilter = function(sortedAttributes, businessMetadataKey) {
  247. _.each(sortedAttributes, function(attrDetails) {
  248. var returnObj = that.getObjDef(attrDetails, rules_widgets, isGroupView, "Business Attributes: " + businessMetadataKey);
  249. returnObj && (returnObj.id = businessMetadataKey + "." + returnObj.id, returnObj.label = returnObj.label,
  250. returnObj.data = {
  251. entityType: "businessMetadata"
  252. }, filters.push(returnObj));
  253. });
  254. };
  255. if ("_ALL_ENTITY_TYPES" == this.value.type) this.businessMetadataDefCollection.each(function(model) {
  256. var sortedAttributes = model.get("attributeDefs");
  257. sortedAttributes = _.sortBy(sortedAttributes, function(obj) {
  258. return obj.name;
  259. }), pushBusinessMetadataFilter(sortedAttributes, model.get("name"));
  260. }); else {
  261. var entityDef = this.entityDefCollection.fullCollection.find({
  262. name: this.value.type
  263. }), businessMetadataAttributeDefs = null;
  264. entityDef && (businessMetadataAttributeDefs = entityDef.get("businessAttributeDefs")),
  265. businessMetadataAttributeDefs && _.each(businessMetadataAttributeDefs, function(attributes, key) {
  266. var sortedAttributes = _.sortBy(attributes, function(obj) {
  267. return obj.name;
  268. });
  269. pushBusinessMetadataFilter(sortedAttributes, key);
  270. });
  271. }
  272. }
  273. }
  274. if (filters = _.uniq(filters, "id"), filters && !_.isEmpty(filters)) {
  275. this.ui.builder.off().on("afterUpdateRuleOperator.queryBuilder", function(e, rule) {
  276. that.setDateValue(rule, rules_widgets);
  277. }).queryBuilder({
  278. plugins: [ "bt-tooltip-errors" ],
  279. filters: filters,
  280. select_placeholder: placeHolder,
  281. allow_empty: !0,
  282. conditions: [ "AND", "OR" ],
  283. allow_groups: !0,
  284. allow_empty: !0,
  285. templates: {
  286. 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> <div class="action-box"><div class="rule-header"> <div class="btn-group rule-actions"> <button type="button" class="btn btn-xs btn-danger" data-delete="rule"> <i class="{{= it.icons.remove_rule }}"></i> </button> </div> </div> </div> {{? it.settings.display_errors }} <div class="error-container"><i class="{{= it.icons.error }}"></i>&nbsp;<span></span></div> {{?}} </div>'
  287. },
  288. operators: [ {
  289. type: "=",
  290. nb_inputs: 1,
  291. multiple: !1,
  292. apply_to: [ "number", "string", "boolean", "enum" ]
  293. }, {
  294. type: "!=",
  295. nb_inputs: 1,
  296. multiple: !1,
  297. apply_to: [ "number", "string", "boolean", "enum" ]
  298. }, {
  299. type: ">",
  300. nb_inputs: 1,
  301. multiple: !1,
  302. apply_to: [ "number", "string", "boolean" ]
  303. }, {
  304. type: "<",
  305. nb_inputs: 1,
  306. multiple: !1,
  307. apply_to: [ "number", "string", "boolean" ]
  308. }, {
  309. type: ">=",
  310. nb_inputs: 1,
  311. multiple: !1,
  312. apply_to: [ "number", "string", "boolean" ]
  313. }, {
  314. type: "<=",
  315. nb_inputs: 1,
  316. multiple: !1,
  317. apply_to: [ "number", "string", "boolean" ]
  318. }, {
  319. type: "contains",
  320. nb_inputs: 1,
  321. multiple: !1,
  322. apply_to: [ "string" ]
  323. }, {
  324. type: "like",
  325. nb_inputs: 1,
  326. multiple: !1,
  327. apply_to: [ "string" ]
  328. }, {
  329. type: "in",
  330. nb_inputs: 1,
  331. multiple: !1,
  332. apply_to: [ "string" ]
  333. }, {
  334. type: "begins_with",
  335. nb_inputs: 1,
  336. multiple: !1,
  337. apply_to: [ "string" ]
  338. }, {
  339. type: "ends_with",
  340. nb_inputs: 1,
  341. multiple: !1,
  342. apply_to: [ "string" ]
  343. }, {
  344. type: "is_null",
  345. nb_inputs: !1,
  346. multiple: !1,
  347. apply_to: [ "number", "string", "boolean", "enum" ]
  348. }, {
  349. type: "not_null",
  350. nb_inputs: !1,
  351. multiple: !1,
  352. apply_to: [ "number", "string", "boolean", "enum" ]
  353. }, {
  354. type: "TIME_RANGE",
  355. nb_inputs: 1,
  356. multiple: !1,
  357. apply_to: [ "date" ]
  358. } ],
  359. lang: {
  360. add_rule: "Add filter",
  361. add_group: "Add filter group",
  362. operators: {
  363. not_null: "is not null",
  364. TIME_RANGE: "Time Range"
  365. }
  366. },
  367. icons: {
  368. add_rule: "fa fa-plus",
  369. remove_rule: "fa fa-times",
  370. error: "fa fa-exclamation-triangle"
  371. },
  372. rules: rules_widgets
  373. }).on("afterCreateRuleInput.queryBuilder", function(e, rule) {
  374. rule.error = null, rule.operator.nb_inputs && "__customAttributes" === rule.filter.id ? rule.$el.addClass("user-define") : rule.$el.hasClass("user-define") && rule.$el.removeClass("user-define"),
  375. "date" === rule.filter.type && rule.$el.find(".rule-value-container >input").attr("readonly", !0),
  376. that.setDateValue(rule, rules_widgets);
  377. }).on("validationError.queryBuilder", function(e, rule, error, value) {
  378. var errorMsg = error[0];
  379. that.queryBuilderLang && that.queryBuilderLang.errors && that.queryBuilderLang.errors[errorMsg] && (errorMsg = that.queryBuilderLang.errors[errorMsg]),
  380. rule.$el.find(".error-container span").html(errorMsg);
  381. });
  382. var queryBuilderEl = that.ui.builder.data("queryBuilder");
  383. queryBuilderEl && queryBuilderEl.lang && (this.queryBuilderLang = queryBuilderEl.lang),
  384. this.$(".rules-group-header .btn-group.pull-right.group-actions").toggleClass("pull-left");
  385. } else this.ui.builder.html("<h4>No Attributes are available !</h4>");
  386. }
  387. });
  388. return QueryBuilderView;
  389. });