github.com/grafana/pyroscope@v1.18.0/pkg/operations/v2/pages.go (about)

     1  package v2
     2  
     3  import (
     4  	_ "embed"
     5  	"fmt"
     6  	"html/template"
     7  )
     8  
     9  //go:embed tool.blocks.index.gohtml
    10  var indexPageHtml string
    11  
    12  //go:embed tool.blocks.list.gohtml
    13  var blocksPageHtml string
    14  
    15  //go:embed tool.blocks.detail.gohtml
    16  var blockDetailsPageHtml string
    17  
    18  //go:embed tool.blocks.dataset.gohtml
    19  var datasetDetailsPageHtml string
    20  
    21  //go:embed tool.blocks.dataset.profiles.gohtml
    22  var datasetProfilesPageHtml string
    23  
    24  //go:embed tool.blocks.profile.call.tree.gohtml
    25  var profileCallTreePageHtml string
    26  
    27  //go:embed tool.pagination.gohtml
    28  var paginationHtml string
    29  
    30  //go:embed tool.blocks.dataset.index.gohtml
    31  var datasetIndexPageHtml string
    32  
    33  //go:embed tool.blocks.dataset.symbols.gohtml
    34  var datasetSymbolsPageHtml string
    35  
    36  type indexPageContent struct {
    37  	Users []string
    38  	Now   string
    39  }
    40  
    41  type blockListPageContent struct {
    42  	User           string
    43  	SelectedBlocks *blockListResult
    44  	Query          *blockQuery
    45  	Now            string
    46  }
    47  
    48  type blockDetailsPageContent struct {
    49  	User        string
    50  	Block       *blockDetails
    51  	Shard       uint32
    52  	BlockTenant string
    53  	Now         string
    54  }
    55  
    56  type datasetDetailsPageContent struct {
    57  	User        string
    58  	BlockID     string
    59  	Shard       uint32
    60  	BlockTenant string
    61  	Dataset     *datasetDetails
    62  	Now         string
    63  }
    64  
    65  type datasetProfilesPageContent struct {
    66  	User        string
    67  	BlockID     string
    68  	Shard       uint32
    69  	BlockTenant string
    70  	Dataset     *datasetDetails
    71  	Profiles    []profileInfo
    72  	TotalCount  int
    73  	Page        int
    74  	PageSize    int
    75  	TotalPages  int
    76  	HasPrevPage bool
    77  	HasNextPage bool
    78  	Now         string
    79  }
    80  
    81  type templates struct {
    82  	indexTemplate           *template.Template
    83  	blocksTemplate          *template.Template
    84  	blockDetailsTemplate    *template.Template
    85  	datasetDetailsTemplate  *template.Template
    86  	datasetProfilesTemplate *template.Template
    87  	profileCallTreeTemplate *template.Template
    88  	datasetIndexTemplate    *template.Template
    89  	datasetSymbolsTemplate  *template.Template
    90  }
    91  
    92  var pageTemplates = initTemplates()
    93  
    94  func initTemplates() *templates {
    95  	indexTemplate := template.New("index")
    96  	template.Must(indexTemplate.Parse(indexPageHtml))
    97  	blocksTemplate := template.New("blocks").Funcs(template.FuncMap{
    98  		"mul":    mul,
    99  		"add":    add,
   100  		"addf":   addf,
   101  		"subf":   subf,
   102  		"mulf":   mulf,
   103  		"divf":   divf,
   104  		"format": format,
   105  		"float":  float,
   106  	})
   107  	template.Must(blocksTemplate.Parse(blocksPageHtml))
   108  	blockDetailsTemplate := template.New("block-details")
   109  	template.Must(blockDetailsTemplate.Parse(blockDetailsPageHtml))
   110  	datasetDetailsTemplate := template.New("dataset-details")
   111  	template.Must(datasetDetailsTemplate.Parse(datasetDetailsPageHtml))
   112  	datasetProfilesTemplate := template.New("dataset-profiles").Funcs(template.FuncMap{
   113  		"add":  add,
   114  		"mul":  mul,
   115  		"seq":  seq,
   116  		"dict": dict,
   117  	})
   118  	template.Must(datasetProfilesTemplate.Parse(paginationHtml))
   119  	template.Must(datasetProfilesTemplate.Parse(datasetProfilesPageHtml))
   120  	profileCallTreeTemplate := template.New("profile-call-tree").Funcs(template.FuncMap{
   121  		"add":  add,
   122  		"dict": dict,
   123  	})
   124  	template.Must(profileCallTreeTemplate.Parse(profileCallTreePageHtml))
   125  	datasetIndexTemplate := template.New("dataset-index")
   126  	template.Must(datasetIndexTemplate.Parse(datasetIndexPageHtml))
   127  	datasetSymbolsTemplate := template.New("dataset-symbols").Funcs(template.FuncMap{
   128  		"add":  add,
   129  		"mul":  mul,
   130  		"seq":  seq,
   131  		"dict": dict,
   132  	})
   133  	template.Must(datasetSymbolsTemplate.Parse(paginationHtml))
   134  	template.Must(datasetSymbolsTemplate.Parse(datasetSymbolsPageHtml))
   135  	t := &templates{
   136  		indexTemplate:           indexTemplate,
   137  		blocksTemplate:          blocksTemplate,
   138  		blockDetailsTemplate:    blockDetailsTemplate,
   139  		datasetDetailsTemplate:  datasetDetailsTemplate,
   140  		datasetProfilesTemplate: datasetProfilesTemplate,
   141  		profileCallTreeTemplate: profileCallTreeTemplate,
   142  		datasetIndexTemplate:    datasetIndexTemplate,
   143  		datasetSymbolsTemplate:  datasetSymbolsTemplate,
   144  	}
   145  	return t
   146  }
   147  
   148  func mul(param1, param2 int) int {
   149  	return param1 * param2
   150  }
   151  
   152  func mulf(param1, param2 float64) float64 {
   153  	return param1 * param2
   154  }
   155  
   156  func add(param1, param2 int) int {
   157  	return param1 + param2
   158  }
   159  
   160  func addf(param1, param2 float64) float64 {
   161  	return param1 + param2
   162  }
   163  
   164  func subf(param1, param2 float64) float64 {
   165  	return param1 - param2
   166  }
   167  
   168  func divf(param1, param2 int) float64 {
   169  	return float64(param1) / float64(param2)
   170  }
   171  
   172  func format(format string, value any) string {
   173  	return fmt.Sprintf(format, value)
   174  }
   175  
   176  func float(param int) float64 {
   177  	return float64(param)
   178  }
   179  
   180  // dict creates a map for passing multiple values to a template
   181  func dict(values ...interface{}) (map[string]interface{}, error) {
   182  	if len(values)%2 != 0 {
   183  		return nil, fmt.Errorf("dict requires an even number of arguments")
   184  	}
   185  	dict := make(map[string]interface{}, len(values)/2)
   186  	for i := 0; i < len(values); i += 2 {
   187  		key, ok := values[i].(string)
   188  		if !ok {
   189  			return nil, fmt.Errorf("dict keys must be strings")
   190  		}
   191  		dict[key] = values[i+1]
   192  	}
   193  	return dict, nil
   194  }
   195  
   196  // seq generates a sequence of integers from start to end (inclusive)
   197  func seq(start, end int) []int {
   198  	if start > end {
   199  		return []int{}
   200  	}
   201  	result := make([]int, end-start+1)
   202  	for i := range result {
   203  		result[i] = start + i
   204  	}
   205  	return result
   206  }