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  }