in pkg/api/v1/state.go [158:220]
func (s *Server) ListRows(ctx context.Context, req *apipb.ListRowsRequest) (*apipb.ListRowsResponse, error) {
ctx, cancel := context.WithTimeout(ctx, s.Timeout)
defer cancel()
// this should be factored out of this function
cfg, err := s.getConfig(ctx, logrus.WithContext(ctx), req.GetScope())
if err != nil {
return nil, err
}
cfg.Mutex.RLock()
defer cfg.Mutex.RUnlock()
dashboardName, tabName, testGroupName, err := findDashboardTab(cfg, req.GetDashboard(), req.GetTab())
if err != nil {
return nil, err
}
grid, err := s.Grid(ctx, req.GetScope(), dashboardName, tabName, testGroupName)
if err != nil {
return nil, fmt.Errorf("Dashboard {%q} or tab {%q} not found", req.GetDashboard(), req.GetTab())
}
if grid == nil {
return nil, errors.New("grid not found")
}
dashboardTabResponse := apipb.ListRowsResponse{
Rows: make([]*apipb.ListRowsResponse_Row, 0, len(grid.Rows)),
}
for _, gRow := range grid.Rows {
gRowDecodedResults := decodeRLE(gRow.Results)
cellsCount := len(gRowDecodedResults)
row := apipb.ListRowsResponse_Row{
Name: gRow.Name,
Issues: gRow.Issues,
Alert: gRow.AlertInfo,
Cells: make([]*apipb.ListRowsResponse_Cell, 0, cellsCount),
}
var filledIdx int
// loop through CellIds, Messages, Icons slices and build cell struct objects
for cellIdx := 0; cellIdx < cellsCount; cellIdx++ {
// Cell IDs, messages, and icons are only listed for non-blank cells.
cell := apipb.ListRowsResponse_Cell{
Result: gRowDecodedResults[cellIdx],
}
if gRowDecodedResults[cellIdx] != 0 {
// Cell IDs may be omitted for subrows.
if len(gRow.CellIds) != 0 {
cell.CellId = gRow.CellIds[filledIdx]
}
if len(gRow.Messages) != 0 {
cell.Message = gRow.Messages[filledIdx]
}
if len(gRow.Icons) != 0 {
cell.Icon = gRow.Icons[filledIdx]
}
filledIdx++
}
row.Cells = append(row.Cells, &cell)
}
dashboardTabResponse.Rows = append(dashboardTabResponse.Rows, &row)
}
return &dashboardTabResponse, nil
}