github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/static/js/dashboard-logs-results-grid.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 18 'use strict'; 19 20 let panelGridDiv = null; 21 22 function getGridPanelRows() { 23 // initial dataset 24 let panelLogsRowData = []; 25 return panelLogsRowData; 26 } 27 function getGridPanelCols(){ 28 // initial columns 29 let panelLogsColumnDefs = [ 30 { 31 field: "timestamp", 32 headerName: "timestamp", 33 editable: true, 34 cellEditor: ReadOnlyCellEditor, 35 cellEditorPopup: true, 36 cellEditorPopupPosition: 'under', 37 cellRenderer: (params) => { 38 return moment(params.value).format(timestampDateFmt); 39 }, 40 cellEditorParams: cellEditorParams, 41 maxWidth: 250, 42 minWidth: 250, 43 sort: "desc" 44 }, 45 { 46 field: "logs", 47 headerName: "logs", 48 cellRenderer: (params) => { 49 let logString = ''; 50 let counter = 0; 51 52 _.forEach(params.data, (value, key) => { 53 let colSep = counter > 0 ? '<span class="col-sep"> | </span>' : ''; 54 55 logString += `<span class="cname-hide-${string2Hex(key)}">${colSep}${key}=` + JSON.stringify(JSON.unflatten(value), null, 2) + `</span>`; 56 counter++; 57 }) 58 return logString; 59 }, 60 } 61 ]; 62 return panelLogsColumnDefs; 63 } 64 65 // let the grid know which columns and what data to use 66 function getPanelGridOptions() { 67 const panelGridOptions = { 68 columnDefs: getGridPanelCols(), 69 rowData: getGridPanelRows(), 70 animateRows: true, 71 readOnlyEdit: true, 72 singleClickEdit: true, 73 rowHeight: 35, 74 defaultColDef: { 75 initialWidth: 100, 76 sortable: true, 77 resizable: true, 78 minWidth: 200, 79 icons: { 80 sortAscending: '<i class="fa fa-sort-alpha-up"/>', 81 sortDescending: '<i class="fa fa-sort-alpha-down"/>', 82 }, 83 }, 84 icons: { 85 sortAscending: '<i class="fa fa-sort-alpha-up"/>', 86 sortDescending: '<i class="fa fa-sort-alpha-down"/>', 87 }, 88 enableCellTextSelection: true, 89 suppressScrollOnNewData: true, 90 suppressAnimationFrame: true, 91 suppressFieldDotNotation: true, 92 onBodyScroll(evt) { 93 if (evt.direction === 'vertical' && canScrollMore == true) { 94 let diff = getGridPanelRows().length - evt.api.getLastDisplayedRow(); 95 // if we're less than 1 items from the end...fetch more data 96 if (diff <= 5) { 97 let scrollingTrigger = true; 98 data = getQueryParamsData(scrollingTrigger); 99 runPanelLogsQuery(data); 100 } 101 } 102 }, 103 }; 104 return panelGridOptions; 105 } 106 107 108 function renderPanelLogsGrid(columnOrder, hits, panelId,logLinesViewType) { 109 $(`.panelDisplay .big-number-display-container`).hide(); 110 let panelLogsRowData = getGridPanelRows(); 111 let panelLogsColumnDefs = getGridPanelCols(); 112 let panelGridOptions = getPanelGridOptions(); 113 114 if(panelId == -1) // for panel on the editPanelScreen page 115 panelGridDiv = document.querySelector('.panelDisplay #panelLogResultsGrid'); 116 else // for panels on the dashboard page 117 panelGridDiv = document.querySelector(`#panel${panelId} #panelLogResultsGrid`); 118 119 new agGrid.Grid(panelGridDiv, panelGridOptions); 120 121 let cols = columnOrder.map((colName, index) => { 122 let hideCol = false; 123 if (index >= defaultColumnCount) { 124 hideCol = true; 125 } 126 127 if (logLinesViewType != 'single-line' && colName == 'logs') { 128 hideCol = true; 129 } 130 131 if (index > 1) { 132 if (selectedFieldsList.indexOf(colName) != -1) { 133 hideCol = true; 134 } else { 135 hideCol = false; 136 } 137 } 138 return { 139 field: colName, 140 hide: hideCol, 141 headerName: colName, 142 cellRenderer: myCellRenderer, 143 cellRendererParams: { 144 colName: colName 145 } 146 }; 147 }); 148 panelLogsRowData = _.concat(panelLogsRowData, hits); 149 panelLogsColumnDefs = _.chain(panelLogsColumnDefs).concat(cols).uniqBy('field').value(); 150 151 const allColumnIds = []; 152 panelGridOptions.columnApi.getColumns().forEach((column) => { 153 allColumnIds.push(column.getId()); 154 }); 155 panelGridOptions.columnApi.autoSizeColumns(allColumnIds, false); 156 panelGridOptions.api.setRowData(panelLogsRowData); 157 158 switch (logLinesViewType){ 159 case 'Single line display view': 160 panelLogOptionSingleHandler(panelGridOptions,panelLogsColumnDefs); 161 break; 162 case 'Multi line display view': 163 panelLogOptionMultiHandler(panelGridOptions,panelLogsColumnDefs,panelLogsRowData); 164 break; 165 case 'Table view': 166 panelLogOptionTableHandler(panelGridOptions,panelLogsColumnDefs); 167 break; 168 } 169 $(`#panel${panelId} .panel-body #panel-loading`).hide(); 170 } 171 172 function panelLogOptionSingleHandler(panelGridOptions,panelLogsColumnDefs){ 173 panelLogsColumnDefs.forEach(function (colDef, index) { 174 if (colDef.field === "logs"){ 175 colDef.cellStyle = null; 176 colDef.autoHeight = null; 177 } 178 }); 179 panelGridOptions.api.setColumnDefs(panelLogsColumnDefs); 180 panelGridOptions.api.resetRowHeights() 181 panelLogsColumnDefs.forEach((colDef, index) => { 182 panelGridOptions.columnApi.setColumnVisible(colDef.field, false); 183 }); 184 panelGridOptions.columnApi.setColumnVisible("logs", true); 185 panelGridOptions.columnApi.setColumnVisible("timestamp", true); 186 187 panelGridOptions.columnApi.autoSizeColumn(panelGridOptions.columnApi.getColumn("logs"), false); 188 } 189 190 function panelLogOptionMultiHandler(panelGridOptions,panelLogsColumnDefs,panelLogsRowData) { 191 192 panelLogsColumnDefs.forEach(function (colDef, index) { 193 if (colDef.field === "logs"){ 194 colDef.cellStyle = {'white-space': 'normal'}; 195 colDef.autoHeight = true; 196 } 197 }); 198 panelGridOptions.api.setColumnDefs(panelLogsColumnDefs); 199 200 panelLogsColumnDefs.forEach((colDef, index) => { 201 panelGridOptions.columnApi.setColumnVisible(colDef.field, false); 202 }); 203 panelGridOptions.columnApi.setColumnVisible("logs", true); 204 panelGridOptions.columnApi.setColumnVisible("timestamp", true); 205 206 panelGridOptions.columnApi.autoSizeColumn(panelGridOptions.columnApi.getColumn("logs"), false); 207 panelGridOptions.api.setRowData(panelLogsRowData); 208 panelGridOptions.api.sizeColumnsToFit(); 209 } 210 211 function panelLogOptionTableHandler(panelGridOptions,panelLogsColumnDefs) { 212 213 panelLogsColumnDefs.forEach(function (colDef, index) { 214 if (colDef.field === "logs") { 215 colDef.cellStyle = null; 216 colDef.autoHeight = null; 217 } 218 }); 219 panelGridOptions.api.setColumnDefs(panelLogsColumnDefs); 220 panelGridOptions.api.resetRowHeights(); 221 // Always show timestamp 222 panelGridOptions.columnApi.setColumnVisible("timestamp", true); 223 panelGridOptions.columnApi.setColumnVisible("logs", false); 224 } 225 226 227 function renderPanelAggsGrid(columnOrder, hits,panelId) { 228 let aggsColumnDefs = []; 229 let segStatsRowData=[]; 230 const aggGridOptions = { 231 columnDefs: aggsColumnDefs, 232 rowData: [], 233 animateRows: true, 234 defaultColDef: { 235 flex: 1, 236 minWidth: 100, 237 resizable: true, 238 sortable: true, 239 icons: { 240 sortAscending: '<i class="fa fa-sort-alpha-up"/>', 241 sortDescending: '<i class="fa fa-sort-alpha-down"/>', 242 }, 243 cellRenderer: params => params.value ? params.value : 'null', 244 }, 245 icons: { 246 sortAscending: '<i class="fa fa-sort-alpha-up"/>', 247 sortDescending: '<i class="fa fa-sort-alpha-down"/>', 248 } 249 }; 250 $(`.panelDisplay .big-number-display-container`).hide(); 251 if(panelId == -1) 252 panelGridDiv = document.querySelector('.panelDisplay #panelLogResultsGrid'); 253 else 254 panelGridDiv = document.querySelector(`#panel${panelId} #panelLogResultsGrid`); 255 256 new agGrid.Grid(panelGridDiv, aggGridOptions); 257 258 let colDefs = aggGridOptions.api.getColumnDefs(); 259 colDefs.length = 0; 260 colDefs = columnOrder.map((colName, index) => { 261 let title = colName; 262 let resize = index + 1 == columnOrder.length ? false : true; 263 let maxWidth = Math.max(displayTextWidth(colName, "italic 19pt DINpro "), 200) //200 is approx width of 1trillion number 264 return { 265 field: title, 266 headerName: title, 267 resizable: resize, 268 minWidth: maxWidth, 269 }; 270 }); 271 aggsColumnDefs = _.chain(aggsColumnDefs).concat(colDefs).uniqBy('field').value(); 272 aggGridOptions.api.setColumnDefs(aggsColumnDefs); 273 let newRow = new Map() 274 $.each(hits, function (key, resMap) { 275 newRow.set("id", 0) 276 columnOrder.map((colName, index) => { 277 if (resMap.GroupByValues!=null && resMap.GroupByValues[index]!="*" && index< (resMap.GroupByValues).length){ 278 newRow.set(colName, resMap.GroupByValues[index]) 279 }else{ 280 newRow.set(colName, resMap.MeasureVal[colName]) 281 } 282 }) 283 segStatsRowData = _.concat(segStatsRowData, Object.fromEntries(newRow)); 284 }) 285 aggGridOptions.api.setRowData(segStatsRowData); 286 $(`#panel${panelId} .panel-body #panel-loading`).hide(); 287 }