/config: Added Copy to clipboard button for /config (#4410)

* added `Copy to clipboard` button

Signed-off-by: Stafford Williams <stafford.williams@gmail.com>

* generate vsfdata

Signed-off-by: Stafford Williams <stafford.williams@gmail.com>

* new lines

Signed-off-by: Stafford Williams <stafford.williams@gmail.com>

* single newline

Signed-off-by: Stafford Williams <stafford.williams@gmail.com>
This commit is contained in:
Stafford Williams 2018-11-27 19:05:26 +11:00 committed by Julius Volz
parent e329cbf673
commit 328d81999a
4 changed files with 73 additions and 5 deletions

View file

@ -38,6 +38,11 @@ var Assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8f\xd1\x4a\x03\x41\x0c\x45\xdf\xe7\x2b\x02\x3e\xcf\x52\x7d\x90\x3a\xfd\x18\xc9\xce\xc4\x6e\xe8\x34\x19\x32\xd9\x8a\x8a\xff\x2e\xdd\x5d\x11\xc1\xfa\x7a\x39\x37\xf7\x64\xc0\x4a\xe6\xcf\x13\x61\x21\x83\x8f\x00\x90\x67\xeb\x6a\x09\x9a\xb2\x38\xd9\x21\x7c\x86\xb0\x51\x85\x1c\xb9\xf6\x05\x2b\xdc\x5b\xc5\xb7\x04\xa2\x42\x0b\x54\xf8\x32\xf4\x49\x5f\x23\x8a\xa8\xa3\xb3\xca\x8a\xbe\xa8\x78\xec\xfc\x4e\x09\x76\xc3\x9e\xce\x87\x00\xd0\xb0\x14\x96\x63\x74\x6d\x09\xee\x7f\x67\xa3\xba\xeb\x79\x8b\x6f\x1c\x4e\x93\x5e\xfe\x11\xfe\xd3\x65\x9c\xdd\x55\x96\xce\x88\xf9\x74\x34\x9d\xa5\xc4\xac\xf5\xda\x76\x43\xe9\x0d\x8d\xc4\xaf\x2e\xa3\x5a\x21\xfb\xfe\x0e\x40\x67\xaf\x2c\xf4\x13\x6c\xb2\x09\x76\x37\x07\x07\xee\x31\x4f\x94\x4f\x54\x56\xd1\x75\xe9\xee\x61\xff\xb8\x7b\x5a\x6b\x5f\x01\x00\x00\xff\xff\x02\xa7\x24\xdc\x7f\x01\x00\x00"),
},
"/static/css/config.css": &vfsgen۰FileInfo{
name: "config.css",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
content: []byte("\x2e\x62\x74\x6e\x20\x7b\x0a\x20\x20\x20\x20\x62\x6f\x72\x64\x65\x72\x2d\x72\x61\x64\x69\x75\x73\x3a\x20\x30\x3b\x0a\x7d\x0a"),
},
"/static/css/graph.css": &vfsgen۰CompressedFileInfo{
name: "graph.css",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
@ -102,6 +107,13 @@ var Assets = func() http.FileSystem {
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x54\x4d\xca\xdb\x30\x10\xdd\xfb\x14\x53\x13\xb0\xb4\xb0\xe8\x3e\x64\x55\xba\xe8\x29\x8a\x90\x26\x96\xf8\xd4\x91\x91\x14\x27\xa5\xf8\xee\xc5\xff\x36\xb1\x43\xb2\xf1\x46\x6f\xde\xbc\x9f\xc1\xd7\x1b\xa9\x64\x3d\x81\x25\x9b\x18\x87\x7f\x19\xc0\x89\xe5\x42\x3a\x0c\xe9\xb7\x41\xa9\x31\xe4\x5c\x28\x67\xd5\x17\x9b\xc0\x23\x0e\xa0\x91\x01\xf0\x51\x4b\xd2\x18\x7e\x29\x4f\x70\x81\x13\x4b\xc6\x46\x2e\xae\x96\x34\xcb\xad\xb0\xca\x53\xa9\x0c\x36\xc1\x53\xa9\xfd\x9d\x72\x7e\xee\x67\xed\x15\xd8\x7a\x56\x38\xa4\x2a\x19\xf8\x76\xb9\xc0\xf7\x69\x01\x6c\xe8\x45\xc0\x3f\xbe\xc1\x1f\x4e\xc6\xc8\xf2\x1d\x66\x21\xb5\xde\x7b\xbd\xd5\xd3\xd6\x16\xd0\x45\x9c\xd9\x3b\x03\xca\x3b\x27\xeb\xf8\x9e\x83\x85\x09\xb6\x83\x2f\xb4\x75\x33\x47\xca\xd6\x89\xb4\xfd\x77\x5a\x4f\xf8\x48\x8c\x8b\xe4\xab\xca\x21\xeb\x21\x2d\x3f\x67\x43\x3f\xda\x36\x22\x1a\x7f\x2f\x25\x91\x4f\xb2\x2b\x25\x1e\xd7\xa4\x3c\xc5\x04\x49\x86\x0a\xd3\x4f\xd7\x5b\x2c\xf6\x18\x8a\x51\xc8\x80\xb7\x73\x1c\xe3\x20\x17\xca\x58\xa7\x03\x12\x2b\x6c\x31\x68\x19\x7a\xec\xa0\xc2\xc8\x38\x38\x2c\x2a\xf7\xb7\x36\xbd\xcd\x1b\x29\x83\xea\x0b\x75\xc1\x97\x4a\xd7\x17\xb6\xd5\xdf\x09\x62\x73\xbe\x07\xb8\xe5\x2a\x9f\xe1\x07\x52\x37\xe5\xec\xcb\x5b\x0a\x5a\xbd\xf7\xaf\xc5\x6a\xc3\xc4\xbf\x42\xdb\x58\xce\x24\x9b\x1b\x7b\x19\xcc\xc8\xfc\x4e\x28\xc6\x6a\xfc\x20\x94\x67\xf8\x87\xa1\x8c\xd2\x76\x03\x59\x05\xb6\x13\xca\x86\x70\x27\x97\xf1\x84\xdb\x2c\x3b\xb1\xee\x7f\xc3\xcf\xd9\xff\x00\x00\x00\xff\xff\x96\xfe\x01\x29\x80\x04\x00\x00"),
},
"/static/js/config.js": &vfsgen۰CompressedFileInfo{
name: "config.js",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
uncompressedSize: 363,
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x90\xb1\x4a\x04\x31\x10\x86\xfb\x3c\xc5\x10\xaf\x98\x80\xec\x0b\x2c\x36\x1e\x16\x36\x16\x6a\x2f\x71\x32\xb7\x04\x93\x99\x65\xcd\x79\x06\xb9\x77\x97\x44\x08\xd7\xc9\xa5\x0a\xc3\xf7\xff\xf3\x31\x87\xa3\x50\x89\x2a\x10\x25\x16\x74\xf0\x63\x00\x00\x76\x68\x6f\x48\xd7\xfa\xaa\xfb\x14\xd7\x77\xf5\x5b\xb0\x6e\x52\x41\x4b\x29\xd2\x87\xbd\x85\x91\x1b\x99\xf6\xbe\xfc\x06\x9b\x97\x85\xe1\x0e\x82\xd2\x31\xb3\x94\x89\x36\xf6\x85\x9f\xdb\x18\xdd\x3c\xd8\xce\x4d\x9f\x9c\x98\xca\x93\x06\xc6\x11\x58\xb8\x3c\x24\x6e\xdf\xfb\xfa\x18\xd0\x92\xca\x21\x2e\x6f\xd5\xe7\x64\xdd\x45\xc3\x29\x4a\xd0\x53\xc3\x5f\x7a\x4b\x54\x41\x37\x71\x5e\x4b\xc5\x7f\x31\x1f\xc2\x9f\x52\xf7\xb8\xc0\x87\x06\x7f\x33\xed\x35\x67\x2f\xdd\x61\xad\xf6\xba\xdd\x67\x37\x9b\xb3\x31\x3b\x6c\xa7\x75\xb3\xf9\x0d\x00\x00\xff\xff\xce\xe7\x15\x39\x6b\x01\x00\x00"),
},
"/static/js/graph": &vfsgen۰DirInfo{
name: "graph",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
@ -375,9 +387,9 @@ var Assets = func() http.FileSystem {
"/templates/config.html": &vfsgen۰CompressedFileInfo{
name: "config.html",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
uncompressedSize: 175,
uncompressedSize: 472,
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x4c\x8e\xc1\x0a\xc2\x30\x10\x44\xef\xf9\x8a\x35\xf7\x58\xe8\x39\xe6\xe2\x97\x84\xee\xc6\x2c\x94\xad\xa4\x69\x11\x96\xfd\x77\x69\x51\xf4\x36\xc3\x7b\x30\xa3\x8a\x54\x58\x08\x7c\xa5\x8c\xde\x2c\x5e\x42\x00\xe1\x17\x84\x90\x54\x49\xd0\xcc\xb9\x9f\x35\x2d\xd2\x49\xba\x37\x73\x00\x11\x79\x87\x69\xce\xeb\x7a\x3b\x41\x66\xa1\x16\xca\xbc\x31\xfa\xe4\x00\x00\x62\x1d\x81\xf1\xa4\x85\x1f\x5b\xcb\x9d\x17\xf1\xe9\xfe\x5f\xe3\x50\xc7\x8f\xfd\x6c\x94\x54\xaf\x66\x71\x38\xe2\x31\x31\x20\xef\xc9\x7d\x9f\xbc\x03\x00\x00\xff\xff\x41\xfa\xfc\xb0\xaf\x00\x00\x00"),
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\x31\x8f\x02\x21\x10\x85\xfb\xfd\x15\x13\x7a\x25\xb1\x66\xf7\x0a\xff\xc0\x15\x97\x6b\x2f\x2c\xcc\xba\xe3\x21\x10\x98\x35\x12\xc2\x7f\xbf\xe8\xea\x69\x63\xf9\x78\xcc\x37\xef\x4d\xad\x16\x27\xf2\x08\x62\x46\x6d\x45\x6b\x1d\x00\x80\x72\xe4\x7f\x81\x4b\xc4\x5e\x30\x5e\x58\x9a\x9c\x05\x24\x74\xbd\xc8\x5c\x1c\xe6\x19\x91\x05\xcc\x09\xa7\x5e\xd4\x0a\x51\xf3\xfc\x99\x70\xa2\x0b\xb4\x26\x33\x6b\x26\x73\x9d\x91\x26\xf8\x89\x0e\x5b\x93\xf3\xc7\xb9\xaf\x15\xc6\x85\x9c\xfd\xc6\x94\x29\x78\x68\x4d\x0c\xeb\xba\x6c\x12\x45\x86\x9c\xcc\x7b\xdc\xf1\x9f\x76\x7c\x07\x53\x72\x05\x0d\x5d\xad\xe8\x6d\x6b\x5d\xf7\xec\x67\x82\x67\xf4\xbc\x56\x54\x96\xce\x60\x9c\xce\xb9\xbf\x19\x9a\x3c\xa6\xcd\xe4\x16\xb2\x8f\x4c\xf3\x0e\xc8\xde\xdc\x89\x0e\x4b\xd2\x4c\xc1\x8b\x61\xff\x2a\x41\x8d\x0b\x73\xf0\xf7\x4b\xad\x42\x3c\xb8\x23\x7b\x18\xd9\x6f\x62\xa2\x93\x4e\x45\xdc\x71\xb1\x7c\x85\xbd\xa3\x38\x06\x9d\xec\x15\x18\x0b\x70\x00\xf3\x78\x52\x72\xe5\x0c\x4a\xce\xbb\x7b\x96\x98\xf0\x25\xcc\x4f\xd1\x27\x27\x86\x5a\xb7\xad\x29\x19\x13\x5e\x7f\x29\x69\xe9\xfc\x2c\xfe\x17\x00\x00\xff\xff\x2a\xd3\xb6\xd3\xd8\x01\x00\x00"),
},
"/templates/flags.html": &vfsgen۰CompressedFileInfo{
name: "flags.html",
@ -434,6 +446,7 @@ var Assets = func() http.FileSystem {
}
fs["/static/css"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
fs["/static/css/alerts.css"].(os.FileInfo),
fs["/static/css/config.css"].(os.FileInfo),
fs["/static/css/graph.css"].(os.FileInfo),
fs["/static/css/prom_console.css"].(os.FileInfo),
fs["/static/css/prometheus.css"].(os.FileInfo),
@ -446,6 +459,7 @@ var Assets = func() http.FileSystem {
}
fs["/static/js"].(*vfsgen۰DirInfo).entries = []os.FileInfo{
fs["/static/js/alerts.js"].(os.FileInfo),
fs["/static/js/config.js"].(os.FileInfo),
fs["/static/js/graph"].(os.FileInfo),
fs["/static/js/prom_console.js"].(os.FileInfo),
fs["/static/js/targets.js"].(os.FileInfo),
@ -551,6 +565,11 @@ func (fs vfsgen۰FS) Open(path string) (http.File, error) {
vfsgen۰CompressedFileInfo: f,
gr: gr,
}, nil
case *vfsgen۰FileInfo:
return &vfsgen۰File{
vfsgen۰FileInfo: f,
Reader: bytes.NewReader(f.content),
}, nil
case *vfsgen۰DirInfo:
return &vfsgen۰Dir{
vfsgen۰DirInfo: f,
@ -632,6 +651,37 @@ func (f *vfsgen۰CompressedFile) Close() error {
return f.gr.Close()
}
// vfsgen۰FileInfo is a static definition of an uncompressed file (because it's not worth gzip compressing).
type vfsgen۰FileInfo struct {
name string
modTime time.Time
content []byte
}
func (f *vfsgen۰FileInfo) Readdir(count int) ([]os.FileInfo, error) {
return nil, fmt.Errorf("cannot Readdir from file %s", f.name)
}
func (f *vfsgen۰FileInfo) Stat() (os.FileInfo, error) { return f, nil }
func (f *vfsgen۰FileInfo) NotWorthGzipCompressing() {}
func (f *vfsgen۰FileInfo) Name() string { return f.name }
func (f *vfsgen۰FileInfo) Size() int64 { return int64(len(f.content)) }
func (f *vfsgen۰FileInfo) Mode() os.FileMode { return 0444 }
func (f *vfsgen۰FileInfo) ModTime() time.Time { return f.modTime }
func (f *vfsgen۰FileInfo) IsDir() bool { return false }
func (f *vfsgen۰FileInfo) Sys() interface{} { return nil }
// vfsgen۰File is an opened file instance.
type vfsgen۰File struct {
*vfsgen۰FileInfo
*bytes.Reader
}
func (f *vfsgen۰File) Close() error {
return nil
}
// vfsgen۰DirInfo is a static definition of a directory.
type vfsgen۰DirInfo struct {
name string

View file

@ -0,0 +1,3 @@
.btn {
border-radius: 0;
}

View file

@ -0,0 +1,12 @@
function init() {
$("#copyToClipboard").on("click", function () {
var range = document.createRange();
range.selectNode(document.getElementById("config_yaml"));
window.getSelection().empty();
window.getSelection().addRange(range);
document.execCommand("copy");
window.getSelection().empty();
});
}
$(init);

View file

@ -1,8 +1,11 @@
{{define "head"}}<!-- nix -->{{end}}
{{define "head"}}
<link type="text/css" rel="stylesheet" href="{{ pathPrefix }}/static/css/config.css?v={{ buildVersion }}">
<script src="{{ pathPrefix }}/static/js/config.js?v={{ buildVersion }}"></script>
{{end}}
{{define "content"}}
<div class="container-fluid">
<h2 id="configuration">Configuration</h2>
<pre>{{.}}</pre>
<h2 id="configuration">Configuration <button type="button" class="btn btn-primary" id="copyToClipboard">Copy to clipboard</button></h2>
<pre id="config_yaml">{{.}}</pre>
</div>
{{end}}