github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/static/js/saved-query.js (about) 1 /* 2 Copyright 2023. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 'use strict'; 18 19 20 let sqgridDiv = null; 21 let sqRowData = []; 22 let delNodeId = '' 23 24 25 function setSaveQueriesDialog() { 26 let dialog = null; 27 let form = null; 28 let qname = $("#qname"); 29 let description = $("#description"); 30 let allFields = $([]).add(qname).add(description); 31 let tips = $(".validateTips"); 32 33 function updateTips(t) { 34 tips.addClass("active"); 35 $(".validateTips").show(); 36 tips 37 .text(t) 38 .addClass("ui-state-highlight"); 39 } 40 41 function checkLength(o, n, min, max) { 42 if (o.val().length > max || o.val().length < min) { 43 o.addClass("ui-state-error"); 44 updateTips("Length of " + n + " must be between " + 45 min + " and " + max + "."); 46 return false; 47 } else { 48 return true; 49 } 50 } 51 52 function checkRegexp(o, regexp, n) { 53 if (!(regexp.test(o.val()))) { 54 o.addClass("ui-state-error"); 55 updateTips(n); 56 return false; 57 } else { 58 return true; 59 } 60 } 61 62 function saveQuery() { 63 let valid = true; 64 allFields.removeClass("ui-state-error"); 65 tips.removeClass("ui-state-highlight"); 66 tips.text(''); 67 valid = valid && checkLength(qname, "query name", 3, 30); 68 valid = valid && checkRegexp(qname, /^[a-zA-Z0-9_-]+$/i, "queryname may consist of a-z, 0-9, dash, underscores."); 69 70 if (valid) { 71 //post to save api 72 let data = getSearchFilterForSave(qname.val(), description.val()); 73 $.ajax({ 74 method: 'post', 75 url: 'api/usersavedqueries/save', 76 headers: { 77 'Content-Type': 'application/json; charset=utf-8', 78 'Accept': '*/*' 79 }, 80 crossDomain: true, 81 dataType: 'json', 82 data: JSON.stringify(data) 83 }) 84 .then(function () { 85 dialog.dialog("close"); 86 }) 87 .catch(function (err) { 88 if (err.status !== 200) { 89 showError(`Message: ${err.statusText}`); 90 } 91 dialog.dialog("close"); 92 }) 93 } 94 95 } 96 97 dialog = $('#save-queries').dialog({ 98 autoOpen: false, 99 resizable: false, 100 maxHeight: 307, 101 height: 307, 102 width: 464, 103 modal: true, 104 position: { 105 my: "center", 106 at: "center", 107 of: window 108 }, 109 buttons: { 110 Cancel: { 111 class: 'cancelqButton', 112 text: 'Cancel', 113 click : function (){ 114 dialog.dialog("close"); 115 } 116 }, 117 Save: { 118 class: 'saveqButton', 119 text: 'Save', 120 click : saveQuery, 121 }, 122 }, 123 close: function () { 124 form[0].reset(); 125 allFields.removeClass("ui-state-error"); 126 } 127 }); 128 129 form = dialog.find("form").on("submit", function (event) { 130 event.preventDefault(); 131 saveQuery(); 132 }); 133 134 $('#saveq-btn').on("click",function () { 135 $(".validateTips").hide(); 136 $('#save-queries').dialog('open'); 137 $('.ui-widget-overlay').addClass('opacity-75'); 138 return false; 139 }); 140 } 141 142 function getSavedQueries() { 143 $.ajax({ 144 method: 'get', 145 url: 'api/usersavedqueries/getall', 146 headers: { 147 'Content-Type': 'application/json; charset=utf-8', 148 'Accept': '*/*' 149 }, 150 crossDomain: true, 151 dataType: 'json', 152 }) 153 .then(displaySavedQueries); 154 } 155 156 class linkCellRenderer { 157 // init method gets the details of the cell to be renderer 158 init(params) { 159 this.eGui = document.createElement('span'); 160 let href = "index.html?searchText=" + 161 encodeURIComponent(params.data.searchText) + 162 "&indexName=" + 163 encodeURIComponent(params.data.indexName) + 164 "&filterTab=" + 165 encodeURIComponent(params.data.filterTab) + 166 "&queryLanguage=" + 167 encodeURIComponent(params.data.queryLanguage); 168 this.eGui.innerHTML = '<a class="query-link" href=' + href + 169 '" title="' + 170 params.data.description + 171 '"style="display:block;">' + 172 params.data.qname + 173 "</a>"; 174 } 175 176 getGui() { 177 return this.eGui; 178 } 179 refresh(params) { 180 return false; 181 } 182 } 183 184 class btnCellRenderer { 185 // init method gets the details of the cell to be renderer 186 init(params) { 187 this.eGui = document.createElement('div'); 188 this.eGui.innerHTML = `<input type="button" class="btn-simple" id="delbutton" />`; 189 190 // get references to the elements we want 191 this.eButton = this.eGui.querySelector('.btn-simple'); 192 this.eventListener = () => { 193 $('.popupOverlay, .popupContent').addClass('active'); 194 $('#delete-btn').data('params', params); 195 } 196 this.eButton.addEventListener('click', this.eventListener); 197 } 198 199 getGui() { 200 return this.eGui; 201 } 202 203 // gets called when the cell is removed from the grid 204 destroy() { 205 // do cleanup, remove event listener from button 206 if (this.eButton) { 207 // check that the button element exists as destroy() can be called before getGui() 208 this.eButton.removeEventListener('click', this.eventListener); 209 } 210 } 211 212 refresh(params) { 213 return false; 214 } 215 } 216 217 // Delete confirmation popup 218 $(document).ready(function () { 219 $('#cancel-btn, .popupOverlay, #delete-btn').click(function () { 220 $('.popupOverlay, .popupContent').removeClass('active'); 221 }); 222 223 // delete function 224 $('#delete-btn').click(function () { 225 let params= $('#delete-btn').data('params'); 226 $.ajax({ 227 method: 'get', 228 url: 'api/usersavedqueries/deleteone/' + params.data.qname, 229 headers: { 230 'Content-Type': 'application/json; charset=utf-8', 231 Accept: '*/*', 232 }, 233 crossDomain: true, 234 }).then(function () { 235 let deletedRowID = params.data.rowId; 236 sqgridOptions.api.applyTransaction({ 237 remove: [{ rowId: deletedRowID }], 238 }); 239 }); 240 }); 241 242 $(document).keypress(function(event){ 243 if(event.keyCode == '13'){ 244 $('.popupOverlay, .popupContent').removeClass('active'); 245 } 246 }) 247 248 $('#sq-filter-input').keyup(function(event){ 249 if (event.keyCode == '13'){ 250 searchSavedQueryHandler(event); 251 }else{ 252 displayOriginalSavedQueries(); 253 } 254 }) 255 }); 256 257 let queriesColumnDefs = [ 258 { 259 field: "rowId", 260 hide: true, 261 }, 262 { 263 field: "qname", 264 headerName: "Query Name", 265 cellRenderer: linkCellRenderer, 266 resizable: true, 267 }, 268 { 269 field: "qdescription", 270 headerName: "Description", 271 resizable: true, 272 }, 273 { 274 field: "queryLanguage", 275 headerName: "QueryLanguage", 276 resizable: true, 277 }, 278 { 279 field: "filterTab", 280 headerName: "FilterTab", 281 hide: true, 282 }, 283 { 284 field: "qdelete", 285 headerName: "Delete", 286 cellRenderer: btnCellRenderer, 287 resizable: false, 288 }, 289 ]; 290 291 292 // let the grid know which columns and what data to use 293 const sqgridOptions = { 294 columnDefs: queriesColumnDefs, 295 rowData: sqRowData, 296 animateRows: true, 297 headerHeight:32, 298 defaultColDef: { 299 initialWidth: 200, 300 sortable: true, 301 }, 302 enableCellTextSelection: true, 303 suppressScrollOnNewData: true, 304 suppressAnimationFrame: true, 305 getRowId: (params) => params.data.rowId, 306 onGridReady(params) { 307 this.gridApi = params.api; // To access the grids API 308 }, 309 localeText: { 310 noRowsToShow: 'No Saved Query Found' 311 } 312 // domLayout: 'autoHeight', 313 }; 314 315 function displaySavedQueries(res,flag) { 316 // loop through res and add data to savedQueries 317 if (flag === -1){ 318 //for search 319 let sqFilteredRowData = []; 320 if (sqgridDiv === null) { 321 sqgridDiv = document.querySelector('#queries-grid'); 322 new agGrid.Grid(sqgridDiv, sqgridOptions); 323 } 324 sqgridOptions.api.setColumnDefs(queriesColumnDefs); 325 let idx = 0; 326 let newRow = new Map() 327 $.each(res, function (key, value) { 328 newRow.set("rowId", idx) 329 newRow.set("qdescription", res[key].description) 330 newRow.set("searchText", value.searchText) 331 newRow.set("indexName", value.indexName) 332 newRow.set("qname", key) 333 newRow.set("queryLanguage", value.queryLanguage) 334 newRow.set("filterTab", value.filterTab) 335 sqFilteredRowData = _.concat(sqFilteredRowData, Object.fromEntries(newRow)); 336 idx = idx + 1 337 }) 338 sqgridOptions.api.setRowData(sqFilteredRowData); 339 sqgridOptions.api.sizeColumnsToFit(); 340 }else{ 341 if (sqgridDiv === null) { 342 sqgridDiv = document.querySelector('#queries-grid'); 343 new agGrid.Grid(sqgridDiv, sqgridOptions); 344 } 345 sqgridOptions.api.setColumnDefs(queriesColumnDefs); 346 let idx = 0; 347 let newRow = new Map() 348 $.each(res, function (key, value) { 349 newRow.set("rowId", idx) 350 newRow.set("qdescription", res[key].description) 351 newRow.set("searchText", value.searchText) 352 newRow.set("indexName", value.indexName) 353 newRow.set("qname", key) 354 newRow.set("queryLanguage", value.queryLanguage) 355 newRow.set("filterTab", value.filterTab) 356 sqRowData = _.concat(sqRowData, Object.fromEntries(newRow)); 357 idx = idx + 1 358 }) 359 sqgridOptions.api.setRowData(sqRowData); 360 sqgridOptions.api.sizeColumnsToFit(); 361 }} 362 363 function displayOriginalSavedQueries(){ 364 let searchText = $('#sq-filter-input').val() 365 if (searchText.length === 0){ 366 if (sqgridDiv === null) { 367 sqgridDiv = document.querySelector('#queries-grid'); 368 new agGrid.Grid(sqgridDiv, sqgridOptions); 369 } 370 $("#queries-grid-container").show() 371 $('#empty-qsearch-response').hide() 372 sqgridOptions.api.setColumnDefs(queriesColumnDefs); 373 sqgridOptions.api.setRowData(sqRowData); 374 sqgridOptions.api.sizeColumnsToFit(); 375 } 376 } 377 378 function getSearchedQuery() { 379 let searchText = $('#sq-filter-input').val(); 380 $.ajax({ 381 method: 'get', 382 url: 'api/usersavedqueries/' + searchText, 383 headers: { 384 'Content-Type': 'application/json; charset=utf-8', 385 'Accept': '*/*' 386 }, 387 crossDomain: true, 388 dataType: 'json', 389 }) 390 .then((res)=>{ 391 $("#queries-grid-container").show() 392 displaySavedQueries(res, -1); 393 }) 394 .catch(function (err) { 395 396 if (err.status !== 200) { 397 showError(`Message: ${err.statusText}`); 398 } 399 $("#queries-grid-container").hide(); 400 let el = $('#empty-qsearch-response'); 401 el.empty(); 402 el.append('<span>Query not found.</span>') 403 el.show(); 404 }) 405 406 }