diff --git a/.gitignore b/.gitignore index 169fa08..4061451 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,7 @@ lib-cov coverage # Compiled binary addons (https://nodejs.org/api/addons.html) -dist/ +#dist/ data/ artifacts/ node_modules/ diff --git a/dist/LICENSE b/dist/LICENSE new file mode 100644 index 0000000..6af058e --- /dev/null +++ b/dist/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2020 Redis Labs + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..9af5c10 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,128 @@ +# Grafana Redis Datasource + +![Dashboard](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/redis-dashboard.png) + +[![Grafana 7](https://img.shields.io/badge/Grafana-7-red)](https://www.grafana.com) +[![Radix](https://img.shields.io/badge/Radix-powered-blue)](https://github.com/mediocregopher/radix) +[![RedisTimeSeries](https://img.shields.io/badge/RedisTimeSeries-inspired-yellowgreen)](https://oss.redislabs.com/redistimeseries/) +[![Redis Enterprise](https://img.shields.io/badge/Redis%20Enterprise-supported-orange)](https://redislabs.com/redis-enterprise/) +[![Go Report Card](https://goreportcard.com/badge/github.com/RedisTimeSeries/grafana-redis-datasource)](https://goreportcard.com/report/github.com/RedisTimeSeries/grafana-redis-datasource) + +## Summary + +- [**Introduction**](#introduction) +- [**Getting Started**](#getting-started) +- [**Supported Commands**](#supported-commands) +- [**Template variables**](#templates-variables) +- [**Feedback**](#feedback) +- [**Contributing**](#contributing) +- [**License**](#license) + +## Introduction + +### What is the Grafana Redis Datasource? + +The Grafana Redis Datasource, is a plugin that allows users to connect to Redis database and build dashboards in Grafana to easily monitor Redis data. It provides out-of-the box predefined dashboards - but the plugin allows to build entirely customized dashboards, tuned to your needs. + +### What is Grafana? + +If you are not familiar with Grafana yet, it is a very popular tool used to build dashboards allowing to monitor applications, infrastructures and any kind of software components. + +### What Grafana version is supported? + +Only Grafana 7.0 and later with a new plugin platform supported. + +### Does this datasource require anything special configured on the Redis databases? + +Datasource can connect to any Redis database. No special configuration is required. + +### Build datasource + +To learn step by step how to build Redis Datasource from scratch and register in new or existing Grafana please take a look at [BUILD](https://github.com/RedisTimeSeries/grafana-redis-datasource/blob/master/BUILD.md) instructions. + +## Getting Started + +### Install using `grafana-cli` + +Use the `grafana-cli` tool to install from the commandline: + +```bash +grafana-cli plugins install redis-datasource +``` + +### Run using `docker-compose` + +Project provides `docker-compose.yml` to start Redis with RedisTimeSeries module and Grafana 7.0. + +**Start Redis and Grafana** + +```bash +docker-compose up +``` + +Open Grafana in your browser [http://localhost:3000](http://localhost:3000) and configure datasource. You can add as many datasources as you want to support multiple Redis databases. + +![Datasource](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/datasource.png) + +There are certain settings that can be configured based on your own setup: + +- Grafana port +- Datasource URL + +#### Configure Grafana port in `docker-compose.yml` + +If standard port 3000 is occupied by another application update the port to bind Grafana to + +``` + ports: + - '3000:3000' +``` + +#### Configure Datasource url in `provisioning/datasources/redis.yaml` + +If Redis is running and listening on localhost:6379 no changes are required + +``` + url: redis://localhost:6379 +``` + +If Redis is running as Docker container on MacOS, please update host to `host.docker.internal` + +``` + url: redis://host.docker.internal:6379 +``` + +## Supported Commands + +Datasource supports many Redis commands using custom components and provide unified interface to query any command. + +![Query](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/query.png) + +## Template variables + +Template variables can query any command and use other variables as parameters. + +![Variables](https://raw.githubusercontent.com/RedisTimeSeries/grafana-redis-datasource/master/src/img/variables.png) + +## Feedback + +We love to hear from users, developers and the whole community interested by this plugin. These are various ways to get in touch with us: + +- Ask a question, request a new feature and file a bug with [GitHub issues](https://github.com/RedisTimeSeries/grafana-redis-datasource/issues/new/choose). +- Star the repository to show your support. + +## Contributing + +- Fork the repository. +- Find an issue to work on and submit a pull request + - Pick a [good first issue](https://github.com/RedisTimeSeries/grafana-redis-datasource/labels/good%20first%20issue). +- Could not find an issue? Look for documentation, bugs, typos, and missing features. + +## Other interesting resources + +- [RedisTimeSeries](https://oss.redislabs.com/redistimeseries/) +- [Redis Pop-up store](https://github.com/RedisTimeSeries/redis-pop-up-store) + +## License + +- Apache License Version 2.0, see [LICENSE](LICENSE) diff --git a/dist/dashboards/redis.json b/dist/dashboards/redis.json new file mode 100644 index 0000000..dd3aa2f --- /dev/null +++ b/dist/dashboards/redis.json @@ -0,0 +1,1404 @@ +{ + "__inputs": [ + { + "name": "DS_REDIS", + "label": "Redis", + "description": "", + "type": "datasource", + "pluginId": "redis-datasource", + "pluginName": "Redis" + } + ], + "__requires": [ + { + "type": "panel", + "id": "bargauge", + "name": "Bar gauge", + "version": "" + }, + { + "type": "panel", + "id": "gauge", + "name": "Gauge", + "version": "" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "7.1.0" + }, + { + "type": "datasource", + "id": "redis-datasource", + "name": "Redis", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Redis Dashboard", + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [ + { + "icon": "external link", + "tags": [], + "targetBlank": true, + "title": "Redis.io", + "type": "link", + "url": "https://redis.io/" + } + ], + "panels": [ + { + "collapsed": false, + "datasource": "${DS_REDIS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 56, + "panels": [], + "repeat": "redis", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "title": "Main", + "type": "row" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + }, + { + "color": "dark-yellow", + "value": 22000 + }, + { + "color": "dark-red", + "value": 25000 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 1 + }, + "id": 24, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "stats", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Ops/sec", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["instantaneous_ops_per_sec"] + } + } + } + ], + "type": "stat" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "decimals": 1, + "mappings": [], + "max": 11000, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + }, + { + "color": "dark-yellow", + "value": 8000 + }, + { + "color": "dark-red", + "value": 10000 + } + ] + }, + "unit": "KBs" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 3, + "y": 1 + }, + "id": 25, + "options": { + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "stats", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Network", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["instantaneous_input_kbps", "instantaneous_output_kbps"] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "instantaneous_input_kbps": "Input", + "instantaneous_output_kbps": "Output" + } + } + } + ], + "type": "gauge" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Used Memory" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used Memory, Peak" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Used Memory, LUA" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Memory Limit" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Total System Memory" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + } + ] + }, + "gridPos": { + "h": 6, + "w": 10, + "x": 11, + "y": 1 + }, + "id": 8, + "options": { + "displayMode": "lcd", + "orientation": "horizontal", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "showUnfilled": true + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "memory", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Memory", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["used_memory", "used_memory_peak", "total_system_memory", "maxmemory", "used_memory_lua"] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": { + "maxmemory": 3, + "total_system_memory": 4, + "used_memory": 0, + "used_memory_lua": 2, + "used_memory_peak": 1 + }, + "renameByName": { + "maxmemory": "Memory Limit", + "total_system_memory": "Total System Memory", + "used_memory": "Used Memory", + "used_memory_lua": "Used Memory, LUA", + "used_memory_peak": "Used Memory, Peak" + } + } + } + ], + "type": "bargauge" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 1 + }, + "id": 19, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "server", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Uptime", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["uptime_in_seconds"] + } + } + } + ], + "type": "stat" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "decimals": 0, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 4 + }, + "id": 22, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "clients", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Connected Clients", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["connected_clients"] + } + } + } + ], + "type": "stat" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 4 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "server", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Version", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["redis_version"] + } + } + } + ], + "type": "stat" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-blue", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 7 + }, + "id": 2, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "query": "dbsize", + "refId": "A", + "type": "cli" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Number of Keys", + "type": "stat" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "decimals": 0, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 3, + "y": 7 + }, + "id": 36, + "options": { + "displayMode": "lcd", + "orientation": "horizontal", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "showUnfilled": true + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "stats", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Keys", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["expired_keys", "evicted_keys"] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "evicted_keys": "Evicted", + "expired_keys": "Expired" + } + } + } + ], + "type": "bargauge" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "decimals": 0, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 10, + "x": 11, + "y": 7 + }, + "id": 38, + "options": { + "displayMode": "lcd", + "orientation": "horizontal", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "showUnfilled": true + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "stats", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Keyspace", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["keyspace_hits", "keyspace_misses"] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "keyspace_hits": "Hits", + "keyspace_misses": "Misses" + } + } + } + ], + "type": "bargauge" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-green", + "value": null + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 7 + }, + "id": 34, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "center", + "orientation": "auto", + "reduceOptions": { + "calcs": ["mean"], + "fields": "/.*/", + "values": true + }, + "textMode": "auto" + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "memory", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Eviction Policy", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["maxmemory_policy"] + } + } + } + ], + "type": "stat" + }, + { + "collapsed": false, + "datasource": "${DS_REDIS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 32, + "panels": [], + "repeat": "redis", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "title": "Other", + "type": "row" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "color-text" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Total duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 99 + }, + { + "id": "unit", + "value": "s" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Client" + }, + "properties": [ + { + "id": "custom.width", + "value": 127 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Idle time" + }, + "properties": [ + { + "id": "custom.width", + "value": 95 + }, + { + "id": "unit", + "value": "s" + }, + { + "id": "decimals", + "value": 0 + } + ] + } + ] + }, + "gridPos": { + "h": 15, + "w": 6, + "x": 0, + "y": 11 + }, + "id": 4, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Idle time" + } + ] + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "clientList", + "query": "", + "refId": "A", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Client connections", + "transformations": [ + { + "id": "filterFieldsByName", + "options": { + "include": { + "names": ["addr", "age", "idle", "cmd"] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "addr": "Client", + "age": "Total duration", + "cmd": "Last command", + "id": "Id", + "idle": "Idle time" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "color-text" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Calls" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Number of calls" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "custom.width", + "value": 127 + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Total Duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 127 + }, + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Duration per call" + }, + "properties": [ + { + "id": "decimals", + "value": 1 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Command" + }, + "properties": [ + { + "id": "custom.width", + "value": 115 + } + ] + } + ] + }, + "gridPos": { + "h": 15, + "w": 7, + "x": 6, + "y": 11 + }, + "id": 41, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Total Duration" + } + ] + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "info", + "query": "", + "refId": "A", + "section": "commandstats", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Command statistics", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": {}, + "indexByName": {}, + "renameByName": { + "Calls": "Number of calls", + "Command": "", + "Usec": "Total Duration", + "Usec_per_call": "Duration per call" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_REDIS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": null, + "displayMode": "color-text" + }, + "mappings": [ + { + "from": "", + "id": 0, + "operator": "", + "text": "", + "to": "", + "type": 1 + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Unique progressive identifier" + }, + "properties": [ + { + "id": "custom.width", + "value": 205 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Timestamp" + }, + "properties": [ + { + "id": "custom.width", + "value": 145 + }, + { + "id": "unit", + "value": "dateTimeFromNow" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Duration" + }, + "properties": [ + { + "id": "custom.width", + "value": 92 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Command" + }, + "properties": [ + { + "id": "custom.width", + "value": 1185 + } + ] + } + ] + }, + "gridPos": { + "h": 15, + "w": 11, + "x": 13, + "y": 11 + }, + "id": 11, + "options": { + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "7.1.0", + "scopedVars": { + "redis": { + "selected": true, + "text": "Redis", + "value": "Redis" + } + }, + "targets": [ + { + "command": "slowlogGet", + "query": "", + "refId": "A", + "type": "command" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Slow queries log", + "transformations": [ + { + "id": "organize", + "options": { + "excludeByName": { + "Id": true, + "Timestamp": false + }, + "indexByName": { + "Command": 4, + "Duration": 3, + "Id": 0, + "Timestamp": 1, + "Timestamp * 1000": 2 + }, + "renameByName": { + "Duration": "", + "Id": "Id", + "Timestamp * 1000": "Timestamp" + } + } + } + ], + "type": "table" + } + ], + "refresh": "5s", + "schemaVersion": 26, + "style": "dark", + "tags": ["redis"], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] + }, + "timezone": "", + "title": "Redis", + "uid": "RpSjVqWMz", + "version": 2 +} diff --git a/dist/img/datasource.png b/dist/img/datasource.png new file mode 100644 index 0000000..69fc129 Binary files /dev/null and b/dist/img/datasource.png differ diff --git a/dist/img/logo.svg b/dist/img/logo.svg new file mode 100644 index 0000000..d8a5e94 --- /dev/null +++ b/dist/img/logo.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + diff --git a/dist/img/query.png b/dist/img/query.png new file mode 100644 index 0000000..51ad4f2 Binary files /dev/null and b/dist/img/query.png differ diff --git a/dist/img/redis-dashboard.png b/dist/img/redis-dashboard.png new file mode 100644 index 0000000..dd36278 Binary files /dev/null and b/dist/img/redis-dashboard.png differ diff --git a/dist/img/variables.png b/dist/img/variables.png new file mode 100644 index 0000000..eb38aeb Binary files /dev/null and b/dist/img/variables.png differ diff --git a/dist/module.js b/dist/module.js new file mode 100644 index 0000000..570aba2 --- /dev/null +++ b/dist/module.js @@ -0,0 +1,3 @@ +/*! For license information please see module.js.LICENSE.txt */ +define(["react","@grafana/ui","@grafana/runtime","@grafana/data"],(function(e,t,n,r){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=4)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t){e.exports=n},function(e,t){e.exports=r},function(e,t,n){"use strict";n.r(t);var r=n(3),o=function(e,t){return(o=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function i(e,t){function n(){this.constructor=e}o(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return(a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","import React, { ChangeEvent, PureComponent } from 'react';\nimport { DataSourcePluginOptionsEditorProps } from '@grafana/data';\nimport { Button, LegacyForms, TextArea } from '@grafana/ui';\nimport { RedisDataSourceOptions, RedisSecureJsonData } from './types';\n\n/**\n * Form Field\n */\nconst { SecretFormField, FormField, Switch } = LegacyForms;\n\n/**\n * Editor Property\n */\ninterface Props extends DataSourcePluginOptionsEditorProps {}\n\n/**\n * State\n */\ninterface State {}\n\n/**\n * Config Editor\n */\nexport class ConfigEditor extends PureComponent {\n /**\n * URL change\n *\n * @param event Event\n */\n onURLChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, url: event.target.value });\n };\n\n /**\n * Pool Size change\n *\n * @param event Event\n */\n onPoolSizeChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, jsonData: { ...options.jsonData, poolSize: Number(event.target.value) } });\n };\n\n /**\n * Timeout change\n *\n * @param event Event\n */\n onTimeoutChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, jsonData: { ...options.jsonData, timeout: Number(event.target.value) } });\n };\n\n /**\n * Ping interval change\n *\n * @param event Event\n */\n onPingIntervalChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, jsonData: { ...options.jsonData, pingInterval: Number(event.target.value) } });\n };\n\n /**\n * Pipeline window change\n *\n * @param event Event\n */\n onPipelineWindowChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, jsonData: { ...options.jsonData, pipelineWindow: Number(event.target.value) } });\n };\n\n /**\n * Password Secure field (only sent to the backend)\n *\n * @param event Event\n */\n onPasswordChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({ ...options, secureJsonData: { ...options.secureJsonData, password: event.target.value } });\n };\n\n /**\n * Password Reset\n */\n onResetPassword = () => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonFields: { ...options.secureJsonFields, password: false },\n secureJsonData: { ...options.secureJsonData, password: '' },\n });\n };\n\n /**\n * TLS Client Certificate\n *\n * @param event Event\n */\n onTlsClientCertificateChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonData: { ...options.secureJsonData, tlsClientCert: event.currentTarget.value },\n });\n };\n\n /**\n * TLS Client Certificate Reset\n */\n onResetTlsClientCertificate = () => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonFields: { ...options.secureJsonFields, tlsClientCert: false },\n secureJsonData: { ...options.secureJsonData, tlsClientCert: '' },\n });\n };\n\n /**\n * TLS Certification Authority\n *\n * @param event Event\n */\n onTlsCACertificateChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonData: { ...options.secureJsonData, tlsCACert: event.currentTarget.value },\n });\n };\n\n /**\n * TLS CA Certificate Reset\n */\n onResetTlsCACertificate = () => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonFields: { ...options.secureJsonFields, tlsCACert: false },\n secureJsonData: { ...options.secureJsonData, tlsCACert: '' },\n });\n };\n\n /**\n * TLS Client key\n *\n * @param event Event\n */\n onTlsClientKeyChange = (event: ChangeEvent) => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonData: { ...options.secureJsonData, tlsClientKey: event.currentTarget.value },\n });\n };\n\n /**\n * TLS Client Key Reset\n */\n onResetTlsClientKey = () => {\n const { onOptionsChange, options } = this.props;\n onOptionsChange({\n ...options,\n secureJsonFields: { ...options.secureJsonFields, tlsClientKey: false },\n secureJsonData: { ...options.secureJsonData, tlsClientKey: '' },\n });\n };\n\n /**\n * Render Editor\n */\n render() {\n const { options, onOptionsChange } = this.props;\n const { url, jsonData, secureJsonFields } = options;\n const secureJsonData = (options.secureJsonData || {}) as RedisSecureJsonData;\n\n /**\n * Return\n */\n return (\n
\n

Redis

\n\n
\n \n
\n\n
\n \n
\n\n
\n \n
\n\n
\n

Advanced settings

\n\n
\n \n \n
\n\n
\n \n
\n\n
\n

TLS

\n\n
\n {\n const jsonData = { ...options.jsonData, tlsAuth: event.currentTarget.checked };\n onOptionsChange({ ...options, jsonData });\n }}\n />\n\n {jsonData.tlsAuth && (\n {\n const jsonData = { ...options.jsonData, tlsSkipVerify: event.currentTarget.checked };\n onOptionsChange({ ...options, jsonData });\n }}\n />\n )}\n
\n\n {jsonData.tlsAuth && (\n <>\n
\n
\n \n
\n\n {secureJsonFields && secureJsonFields.tlsClientCert ? (\n \n ) : (\n
\n \n
\n )}\n
\n\n
\n
\n \n
\n
\n {secureJsonFields && secureJsonFields.tlsClientKey ? (\n \n ) : (\n \n )}\n
\n
\n\n
\n
\n \n
\n {secureJsonFields && secureJsonFields.tlsCACert ? (\n \n ) : (\n
\n \n
\n )}\n
\n \n )}\n
\n );\n }\n}\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function isFunction(x) {\n return typeof x === 'function';\n}\n//# sourceMappingURL=isFunction.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nvar _enable_super_gross_mode_that_will_cause_bad_things = false;\nexport var config = {\n Promise: undefined,\n set useDeprecatedSynchronousErrorHandling(value) {\n if (value) {\n var error = /*@__PURE__*/ new Error();\n /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \\n' + error.stack);\n }\n else if (_enable_super_gross_mode_that_will_cause_bad_things) {\n /*@__PURE__*/ console.log('RxJS: Back to a better error behavior. Thank you. <3');\n }\n _enable_super_gross_mode_that_will_cause_bad_things = value;\n },\n get useDeprecatedSynchronousErrorHandling() {\n return _enable_super_gross_mode_that_will_cause_bad_things;\n },\n};\n//# sourceMappingURL=config.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function hostReportError(err) {\n setTimeout(function () { throw err; }, 0);\n}\n//# sourceMappingURL=hostReportError.js.map\n","/** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */\nimport { config } from './config';\nimport { hostReportError } from './util/hostReportError';\nexport var empty = {\n closed: true,\n next: function (value) { },\n error: function (err) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n throw err;\n }\n else {\n hostReportError(err);\n }\n },\n complete: function () { }\n};\n//# sourceMappingURL=Observer.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })();\n//# sourceMappingURL=isArray.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function isObject(x) {\n return x !== null && typeof x === 'object';\n}\n//# sourceMappingURL=isObject.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nvar UnsubscriptionErrorImpl = /*@__PURE__*/ (function () {\n function UnsubscriptionErrorImpl(errors) {\n Error.call(this);\n this.message = errors ?\n errors.length + \" errors occurred during unsubscription:\\n\" + errors.map(function (err, i) { return i + 1 + \") \" + err.toString(); }).join('\\n ') : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n return this;\n }\n UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype);\n return UnsubscriptionErrorImpl;\n})();\nexport var UnsubscriptionError = UnsubscriptionErrorImpl;\n//# sourceMappingURL=UnsubscriptionError.js.map\n","/** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */\nimport { isArray } from './util/isArray';\nimport { isObject } from './util/isObject';\nimport { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nvar Subscription = /*@__PURE__*/ (function () {\n function Subscription(unsubscribe) {\n this.closed = false;\n this._parentOrParents = null;\n this._subscriptions = null;\n if (unsubscribe) {\n this._unsubscribe = unsubscribe;\n }\n }\n Subscription.prototype.unsubscribe = function () {\n var errors;\n if (this.closed) {\n return;\n }\n var _a = this, _parentOrParents = _a._parentOrParents, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions;\n this.closed = true;\n this._parentOrParents = null;\n this._subscriptions = null;\n if (_parentOrParents instanceof Subscription) {\n _parentOrParents.remove(this);\n }\n else if (_parentOrParents !== null) {\n for (var index = 0; index < _parentOrParents.length; ++index) {\n var parent_1 = _parentOrParents[index];\n parent_1.remove(this);\n }\n }\n if (isFunction(_unsubscribe)) {\n try {\n _unsubscribe.call(this);\n }\n catch (e) {\n errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e];\n }\n }\n if (isArray(_subscriptions)) {\n var index = -1;\n var len = _subscriptions.length;\n while (++index < len) {\n var sub = _subscriptions[index];\n if (isObject(sub)) {\n try {\n sub.unsubscribe();\n }\n catch (e) {\n errors = errors || [];\n if (e instanceof UnsubscriptionError) {\n errors = errors.concat(flattenUnsubscriptionErrors(e.errors));\n }\n else {\n errors.push(e);\n }\n }\n }\n }\n }\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n };\n Subscription.prototype.add = function (teardown) {\n var subscription = teardown;\n if (!teardown) {\n return Subscription.EMPTY;\n }\n switch (typeof teardown) {\n case 'function':\n subscription = new Subscription(teardown);\n case 'object':\n if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') {\n return subscription;\n }\n else if (this.closed) {\n subscription.unsubscribe();\n return subscription;\n }\n else if (!(subscription instanceof Subscription)) {\n var tmp = subscription;\n subscription = new Subscription();\n subscription._subscriptions = [tmp];\n }\n break;\n default: {\n throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.');\n }\n }\n var _parentOrParents = subscription._parentOrParents;\n if (_parentOrParents === null) {\n subscription._parentOrParents = this;\n }\n else if (_parentOrParents instanceof Subscription) {\n if (_parentOrParents === this) {\n return subscription;\n }\n subscription._parentOrParents = [_parentOrParents, this];\n }\n else if (_parentOrParents.indexOf(this) === -1) {\n _parentOrParents.push(this);\n }\n else {\n return subscription;\n }\n var subscriptions = this._subscriptions;\n if (subscriptions === null) {\n this._subscriptions = [subscription];\n }\n else {\n subscriptions.push(subscription);\n }\n return subscription;\n };\n Subscription.prototype.remove = function (subscription) {\n var subscriptions = this._subscriptions;\n if (subscriptions) {\n var subscriptionIndex = subscriptions.indexOf(subscription);\n if (subscriptionIndex !== -1) {\n subscriptions.splice(subscriptionIndex, 1);\n }\n }\n };\n Subscription.EMPTY = (function (empty) {\n empty.closed = true;\n return empty;\n }(new Subscription()));\n return Subscription;\n}());\nexport { Subscription };\nfunction flattenUnsubscriptionErrors(errors) {\n return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError) ? err.errors : err); }, []);\n}\n//# sourceMappingURL=Subscription.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport var rxSubscriber = /*@__PURE__*/ (function () {\n return typeof Symbol === 'function'\n ? /*@__PURE__*/ Symbol('rxSubscriber')\n : '@@rxSubscriber_' + /*@__PURE__*/ Math.random();\n})();\nexport var $$rxSubscriber = rxSubscriber;\n//# sourceMappingURL=rxSubscriber.js.map\n","/** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { isFunction } from './util/isFunction';\nimport { empty as emptyObserver } from './Observer';\nimport { Subscription } from './Subscription';\nimport { rxSubscriber as rxSubscriberSymbol } from '../internal/symbol/rxSubscriber';\nimport { config } from './config';\nimport { hostReportError } from './util/hostReportError';\nvar Subscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(Subscriber, _super);\n function Subscriber(destinationOrNext, error, complete) {\n var _this = _super.call(this) || this;\n _this.syncErrorValue = null;\n _this.syncErrorThrown = false;\n _this.syncErrorThrowable = false;\n _this.isStopped = false;\n switch (arguments.length) {\n case 0:\n _this.destination = emptyObserver;\n break;\n case 1:\n if (!destinationOrNext) {\n _this.destination = emptyObserver;\n break;\n }\n if (typeof destinationOrNext === 'object') {\n if (destinationOrNext instanceof Subscriber) {\n _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable;\n _this.destination = destinationOrNext;\n destinationOrNext.add(_this);\n }\n else {\n _this.syncErrorThrowable = true;\n _this.destination = new SafeSubscriber(_this, destinationOrNext);\n }\n break;\n }\n default:\n _this.syncErrorThrowable = true;\n _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete);\n break;\n }\n return _this;\n }\n Subscriber.prototype[rxSubscriberSymbol] = function () { return this; };\n Subscriber.create = function (next, error, complete) {\n var subscriber = new Subscriber(next, error, complete);\n subscriber.syncErrorThrowable = false;\n return subscriber;\n };\n Subscriber.prototype.next = function (value) {\n if (!this.isStopped) {\n this._next(value);\n }\n };\n Subscriber.prototype.error = function (err) {\n if (!this.isStopped) {\n this.isStopped = true;\n this._error(err);\n }\n };\n Subscriber.prototype.complete = function () {\n if (!this.isStopped) {\n this.isStopped = true;\n this._complete();\n }\n };\n Subscriber.prototype.unsubscribe = function () {\n if (this.closed) {\n return;\n }\n this.isStopped = true;\n _super.prototype.unsubscribe.call(this);\n };\n Subscriber.prototype._next = function (value) {\n this.destination.next(value);\n };\n Subscriber.prototype._error = function (err) {\n this.destination.error(err);\n this.unsubscribe();\n };\n Subscriber.prototype._complete = function () {\n this.destination.complete();\n this.unsubscribe();\n };\n Subscriber.prototype._unsubscribeAndRecycle = function () {\n var _parentOrParents = this._parentOrParents;\n this._parentOrParents = null;\n this.unsubscribe();\n this.closed = false;\n this.isStopped = false;\n this._parentOrParents = _parentOrParents;\n return this;\n };\n return Subscriber;\n}(Subscription));\nexport { Subscriber };\nvar SafeSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(SafeSubscriber, _super);\n function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) {\n var _this = _super.call(this) || this;\n _this._parentSubscriber = _parentSubscriber;\n var next;\n var context = _this;\n if (isFunction(observerOrNext)) {\n next = observerOrNext;\n }\n else if (observerOrNext) {\n next = observerOrNext.next;\n error = observerOrNext.error;\n complete = observerOrNext.complete;\n if (observerOrNext !== emptyObserver) {\n context = Object.create(observerOrNext);\n if (isFunction(context.unsubscribe)) {\n _this.add(context.unsubscribe.bind(context));\n }\n context.unsubscribe = _this.unsubscribe.bind(_this);\n }\n }\n _this._context = context;\n _this._next = next;\n _this._error = error;\n _this._complete = complete;\n return _this;\n }\n SafeSubscriber.prototype.next = function (value) {\n if (!this.isStopped && this._next) {\n var _parentSubscriber = this._parentSubscriber;\n if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {\n this.__tryOrUnsub(this._next, value);\n }\n else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) {\n this.unsubscribe();\n }\n }\n };\n SafeSubscriber.prototype.error = function (err) {\n if (!this.isStopped) {\n var _parentSubscriber = this._parentSubscriber;\n var useDeprecatedSynchronousErrorHandling = config.useDeprecatedSynchronousErrorHandling;\n if (this._error) {\n if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {\n this.__tryOrUnsub(this._error, err);\n this.unsubscribe();\n }\n else {\n this.__tryOrSetError(_parentSubscriber, this._error, err);\n this.unsubscribe();\n }\n }\n else if (!_parentSubscriber.syncErrorThrowable) {\n this.unsubscribe();\n if (useDeprecatedSynchronousErrorHandling) {\n throw err;\n }\n hostReportError(err);\n }\n else {\n if (useDeprecatedSynchronousErrorHandling) {\n _parentSubscriber.syncErrorValue = err;\n _parentSubscriber.syncErrorThrown = true;\n }\n else {\n hostReportError(err);\n }\n this.unsubscribe();\n }\n }\n };\n SafeSubscriber.prototype.complete = function () {\n var _this = this;\n if (!this.isStopped) {\n var _parentSubscriber = this._parentSubscriber;\n if (this._complete) {\n var wrappedComplete = function () { return _this._complete.call(_this._context); };\n if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) {\n this.__tryOrUnsub(wrappedComplete);\n this.unsubscribe();\n }\n else {\n this.__tryOrSetError(_parentSubscriber, wrappedComplete);\n this.unsubscribe();\n }\n }\n else {\n this.unsubscribe();\n }\n }\n };\n SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {\n try {\n fn.call(this._context, value);\n }\n catch (err) {\n this.unsubscribe();\n if (config.useDeprecatedSynchronousErrorHandling) {\n throw err;\n }\n else {\n hostReportError(err);\n }\n }\n };\n SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) {\n if (!config.useDeprecatedSynchronousErrorHandling) {\n throw new Error('bad call');\n }\n try {\n fn.call(this._context, value);\n }\n catch (err) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n parent.syncErrorValue = err;\n parent.syncErrorThrown = true;\n return true;\n }\n else {\n hostReportError(err);\n return true;\n }\n }\n return false;\n };\n SafeSubscriber.prototype._unsubscribe = function () {\n var _parentSubscriber = this._parentSubscriber;\n this._context = null;\n this._parentSubscriber = null;\n _parentSubscriber.unsubscribe();\n };\n return SafeSubscriber;\n}(Subscriber));\nexport { SafeSubscriber };\n//# sourceMappingURL=Subscriber.js.map\n","/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { Subscriber } from './Subscriber';\nvar OuterSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(OuterSubscriber, _super);\n function OuterSubscriber() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n OuterSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {\n this.destination.next(innerValue);\n };\n OuterSubscriber.prototype.notifyError = function (error, innerSub) {\n this.destination.error(error);\n };\n OuterSubscriber.prototype.notifyComplete = function (innerSub) {\n this.destination.complete();\n };\n return OuterSubscriber;\n}(Subscriber));\nexport { OuterSubscriber };\n//# sourceMappingURL=OuterSubscriber.js.map\n","/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { Subscriber } from './Subscriber';\nvar InnerSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(InnerSubscriber, _super);\n function InnerSubscriber(parent, outerValue, outerIndex) {\n var _this = _super.call(this) || this;\n _this.parent = parent;\n _this.outerValue = outerValue;\n _this.outerIndex = outerIndex;\n _this.index = 0;\n return _this;\n }\n InnerSubscriber.prototype._next = function (value) {\n this.parent.notifyNext(this.outerValue, value, this.outerIndex, this.index++, this);\n };\n InnerSubscriber.prototype._error = function (error) {\n this.parent.notifyError(error, this);\n this.unsubscribe();\n };\n InnerSubscriber.prototype._complete = function () {\n this.parent.notifyComplete(this);\n this.unsubscribe();\n };\n return InnerSubscriber;\n}(Subscriber));\nexport { InnerSubscriber };\n//# sourceMappingURL=InnerSubscriber.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function getSymbolIterator() {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator';\n }\n return Symbol.iterator;\n}\nexport var iterator = /*@__PURE__*/ getSymbolIterator();\nexport var $$iterator = iterator;\n//# sourceMappingURL=iterator.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })();\n//# sourceMappingURL=observable.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });\n//# sourceMappingURL=isArrayLike.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function isPromise(value) {\n return !!value && typeof value.subscribe !== 'function' && typeof value.then === 'function';\n}\n//# sourceMappingURL=isPromise.js.map\n","/** PURE_IMPORTS_START _subscribeToArray,_subscribeToPromise,_subscribeToIterable,_subscribeToObservable,_isArrayLike,_isPromise,_isObject,_symbol_iterator,_symbol_observable PURE_IMPORTS_END */\nimport { subscribeToArray } from './subscribeToArray';\nimport { subscribeToPromise } from './subscribeToPromise';\nimport { subscribeToIterable } from './subscribeToIterable';\nimport { subscribeToObservable } from './subscribeToObservable';\nimport { isArrayLike } from './isArrayLike';\nimport { isPromise } from './isPromise';\nimport { isObject } from './isObject';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport var subscribeTo = function (result) {\n if (!!result && typeof result[Symbol_observable] === 'function') {\n return subscribeToObservable(result);\n }\n else if (isArrayLike(result)) {\n return subscribeToArray(result);\n }\n else if (isPromise(result)) {\n return subscribeToPromise(result);\n }\n else if (!!result && typeof result[Symbol_iterator] === 'function') {\n return subscribeToIterable(result);\n }\n else {\n var value = isObject(result) ? 'an invalid object' : \"'\" + result + \"'\";\n var msg = \"You provided \" + value + \" where a stream was expected.\"\n + ' You can provide an Observable, Promise, Array, or Iterable.';\n throw new TypeError(msg);\n }\n};\n//# sourceMappingURL=subscribeTo.js.map\n","/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport var subscribeToObservable = function (obj) {\n return function (subscriber) {\n var obs = obj[Symbol_observable]();\n if (typeof obs.subscribe !== 'function') {\n throw new TypeError('Provided object does not correctly implement Symbol.observable');\n }\n else {\n return obs.subscribe(subscriber);\n }\n };\n};\n//# sourceMappingURL=subscribeToObservable.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport var subscribeToArray = function (array) {\n return function (subscriber) {\n for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) {\n subscriber.next(array[i]);\n }\n subscriber.complete();\n };\n};\n//# sourceMappingURL=subscribeToArray.js.map\n","/** PURE_IMPORTS_START _hostReportError PURE_IMPORTS_END */\nimport { hostReportError } from './hostReportError';\nexport var subscribeToPromise = function (promise) {\n return function (subscriber) {\n promise.then(function (value) {\n if (!subscriber.closed) {\n subscriber.next(value);\n subscriber.complete();\n }\n }, function (err) { return subscriber.error(err); })\n .then(null, hostReportError);\n return subscriber;\n };\n};\n//# sourceMappingURL=subscribeToPromise.js.map\n","/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nexport var subscribeToIterable = function (iterable) {\n return function (subscriber) {\n var iterator = iterable[Symbol_iterator]();\n do {\n var item = iterator.next();\n if (item.done) {\n subscriber.complete();\n break;\n }\n subscriber.next(item.value);\n if (subscriber.closed) {\n break;\n }\n } while (true);\n if (typeof iterator.return === 'function') {\n subscriber.add(function () {\n if (iterator.return) {\n iterator.return();\n }\n });\n }\n return subscriber;\n };\n};\n//# sourceMappingURL=subscribeToIterable.js.map\n","/** PURE_IMPORTS_START PURE_IMPORTS_END */\nexport function identity(x) {\n return x;\n}\n//# sourceMappingURL=identity.js.map\n","/** PURE_IMPORTS_START _identity PURE_IMPORTS_END */\nimport { identity } from './identity';\nexport function pipe() {\n var fns = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n fns[_i] = arguments[_i];\n }\n return pipeFromArray(fns);\n}\nexport function pipeFromArray(fns) {\n if (fns.length === 0) {\n return identity;\n }\n if (fns.length === 1) {\n return fns[0];\n }\n return function piped(input) {\n return fns.reduce(function (prev, fn) { return fn(prev); }, input);\n };\n}\n//# sourceMappingURL=pipe.js.map\n","/** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */\nimport { canReportError } from './util/canReportError';\nimport { toSubscriber } from './util/toSubscriber';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nvar Observable = /*@__PURE__*/ (function () {\n function Observable(subscribe) {\n this._isScalar = false;\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n Observable.prototype.lift = function (operator) {\n var observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n };\n Observable.prototype.subscribe = function (observerOrNext, error, complete) {\n var operator = this.operator;\n var sink = toSubscriber(observerOrNext, error, complete);\n if (operator) {\n sink.add(operator.call(sink, this.source));\n }\n else {\n sink.add(this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ?\n this._subscribe(sink) :\n this._trySubscribe(sink));\n }\n if (config.useDeprecatedSynchronousErrorHandling) {\n if (sink.syncErrorThrowable) {\n sink.syncErrorThrowable = false;\n if (sink.syncErrorThrown) {\n throw sink.syncErrorValue;\n }\n }\n }\n return sink;\n };\n Observable.prototype._trySubscribe = function (sink) {\n try {\n return this._subscribe(sink);\n }\n catch (err) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n sink.syncErrorThrown = true;\n sink.syncErrorValue = err;\n }\n if (canReportError(sink)) {\n sink.error(err);\n }\n else {\n console.warn(err);\n }\n }\n };\n Observable.prototype.forEach = function (next, promiseCtor) {\n var _this = this;\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor(function (resolve, reject) {\n var subscription;\n subscription = _this.subscribe(function (value) {\n try {\n next(value);\n }\n catch (err) {\n reject(err);\n if (subscription) {\n subscription.unsubscribe();\n }\n }\n }, reject, resolve);\n });\n };\n Observable.prototype._subscribe = function (subscriber) {\n var source = this.source;\n return source && source.subscribe(subscriber);\n };\n Observable.prototype[Symbol_observable] = function () {\n return this;\n };\n Observable.prototype.pipe = function () {\n var operations = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n operations[_i] = arguments[_i];\n }\n if (operations.length === 0) {\n return this;\n }\n return pipeFromArray(operations)(this);\n };\n Observable.prototype.toPromise = function (promiseCtor) {\n var _this = this;\n promiseCtor = getPromiseCtor(promiseCtor);\n return new promiseCtor(function (resolve, reject) {\n var value;\n _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); });\n });\n };\n Observable.create = function (subscribe) {\n return new Observable(subscribe);\n };\n return Observable;\n}());\nexport { Observable };\nfunction getPromiseCtor(promiseCtor) {\n if (!promiseCtor) {\n promiseCtor = config.Promise || Promise;\n }\n if (!promiseCtor) {\n throw new Error('no Promise impl found');\n }\n return promiseCtor;\n}\n//# sourceMappingURL=Observable.js.map\n","/** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */\nimport { Subscriber } from '../Subscriber';\nimport { rxSubscriber as rxSubscriberSymbol } from '../symbol/rxSubscriber';\nimport { empty as emptyObserver } from '../Observer';\nexport function toSubscriber(nextOrObserver, error, complete) {\n if (nextOrObserver) {\n if (nextOrObserver instanceof Subscriber) {\n return nextOrObserver;\n }\n if (nextOrObserver[rxSubscriberSymbol]) {\n return nextOrObserver[rxSubscriberSymbol]();\n }\n }\n if (!nextOrObserver && !error && !complete) {\n return new Subscriber(emptyObserver);\n }\n return new Subscriber(nextOrObserver, error, complete);\n}\n//# sourceMappingURL=toSubscriber.js.map\n","/** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */\nimport { Subscriber } from '../Subscriber';\nexport function canReportError(observer) {\n while (observer) {\n var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped;\n if (closed_1 || isStopped) {\n return false;\n }\n else if (destination && destination instanceof Subscriber) {\n observer = destination;\n }\n else {\n observer = null;\n }\n }\n return true;\n}\n//# sourceMappingURL=canReportError.js.map\n","/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { Subscriber } from '../Subscriber';\nexport function map(project, thisArg) {\n return function mapOperation(source) {\n if (typeof project !== 'function') {\n throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');\n }\n return source.lift(new MapOperator(project, thisArg));\n };\n}\nvar MapOperator = /*@__PURE__*/ (function () {\n function MapOperator(project, thisArg) {\n this.project = project;\n this.thisArg = thisArg;\n }\n MapOperator.prototype.call = function (subscriber, source) {\n return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));\n };\n return MapOperator;\n}());\nexport { MapOperator };\nvar MapSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(MapSubscriber, _super);\n function MapSubscriber(destination, project, thisArg) {\n var _this = _super.call(this, destination) || this;\n _this.project = project;\n _this.count = 0;\n _this.thisArg = thisArg || _this;\n return _this;\n }\n MapSubscriber.prototype._next = function (value) {\n var result;\n try {\n result = this.project.call(this.thisArg, value, this.count++);\n }\n catch (err) {\n this.destination.error(err);\n return;\n }\n this.destination.next(result);\n };\n return MapSubscriber;\n}(Subscriber));\n//# sourceMappingURL=map.js.map\n","/** PURE_IMPORTS_START _scheduleObservable,_schedulePromise,_scheduleArray,_scheduleIterable,_util_isInteropObservable,_util_isPromise,_util_isArrayLike,_util_isIterable PURE_IMPORTS_END */\nimport { scheduleObservable } from './scheduleObservable';\nimport { schedulePromise } from './schedulePromise';\nimport { scheduleArray } from './scheduleArray';\nimport { scheduleIterable } from './scheduleIterable';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isPromise } from '../util/isPromise';\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isIterable } from '../util/isIterable';\nexport function scheduled(input, scheduler) {\n if (input != null) {\n if (isInteropObservable(input)) {\n return scheduleObservable(input, scheduler);\n }\n else if (isPromise(input)) {\n return schedulePromise(input, scheduler);\n }\n else if (isArrayLike(input)) {\n return scheduleArray(input, scheduler);\n }\n else if (isIterable(input) || typeof input === 'string') {\n return scheduleIterable(input, scheduler);\n }\n }\n throw new TypeError((input !== null && typeof input || input) + ' is not observable');\n}\n//# sourceMappingURL=scheduled.js.map\n","/** PURE_IMPORTS_START _symbol_observable PURE_IMPORTS_END */\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport function isInteropObservable(input) {\n return input && typeof input[Symbol_observable] === 'function';\n}\n//# sourceMappingURL=isInteropObservable.js.map\n","/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_observable PURE_IMPORTS_END */\nimport { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nimport { observable as Symbol_observable } from '../symbol/observable';\nexport function scheduleObservable(input, scheduler) {\n return new Observable(function (subscriber) {\n var sub = new Subscription();\n sub.add(scheduler.schedule(function () {\n var observable = input[Symbol_observable]();\n sub.add(observable.subscribe({\n next: function (value) { sub.add(scheduler.schedule(function () { return subscriber.next(value); })); },\n error: function (err) { sub.add(scheduler.schedule(function () { return subscriber.error(err); })); },\n complete: function () { sub.add(scheduler.schedule(function () { return subscriber.complete(); })); },\n }));\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleObservable.js.map\n","/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */\nimport { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nexport function schedulePromise(input, scheduler) {\n return new Observable(function (subscriber) {\n var sub = new Subscription();\n sub.add(scheduler.schedule(function () {\n return input.then(function (value) {\n sub.add(scheduler.schedule(function () {\n subscriber.next(value);\n sub.add(scheduler.schedule(function () { return subscriber.complete(); }));\n }));\n }, function (err) {\n sub.add(scheduler.schedule(function () { return subscriber.error(err); }));\n });\n }));\n return sub;\n });\n}\n//# sourceMappingURL=schedulePromise.js.map\n","/** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */\nimport { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nexport function scheduleArray(input, scheduler) {\n return new Observable(function (subscriber) {\n var sub = new Subscription();\n var i = 0;\n sub.add(scheduler.schedule(function () {\n if (i === input.length) {\n subscriber.complete();\n return;\n }\n subscriber.next(input[i++]);\n if (!subscriber.closed) {\n sub.add(this.schedule());\n }\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleArray.js.map\n","/** PURE_IMPORTS_START _symbol_iterator PURE_IMPORTS_END */\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nexport function isIterable(input) {\n return input && typeof input[Symbol_iterator] === 'function';\n}\n//# sourceMappingURL=isIterable.js.map\n","/** PURE_IMPORTS_START _Observable,_Subscription,_symbol_iterator PURE_IMPORTS_END */\nimport { Observable } from '../Observable';\nimport { Subscription } from '../Subscription';\nimport { iterator as Symbol_iterator } from '../symbol/iterator';\nexport function scheduleIterable(input, scheduler) {\n if (!input) {\n throw new Error('Iterable cannot be null');\n }\n return new Observable(function (subscriber) {\n var sub = new Subscription();\n var iterator;\n sub.add(function () {\n if (iterator && typeof iterator.return === 'function') {\n iterator.return();\n }\n });\n sub.add(scheduler.schedule(function () {\n iterator = input[Symbol_iterator]();\n sub.add(scheduler.schedule(function () {\n if (subscriber.closed) {\n return;\n }\n var value;\n var done;\n try {\n var result = iterator.next();\n value = result.value;\n done = result.done;\n }\n catch (err) {\n subscriber.error(err);\n return;\n }\n if (done) {\n subscriber.complete();\n }\n else {\n subscriber.next(value);\n this.schedule();\n }\n }));\n }));\n return sub;\n });\n}\n//# sourceMappingURL=scheduleIterable.js.map\n","/** PURE_IMPORTS_START tslib,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult,_map,_observable_from PURE_IMPORTS_END */\nimport * as tslib_1 from \"tslib\";\nimport { OuterSubscriber } from '../OuterSubscriber';\nimport { InnerSubscriber } from '../InnerSubscriber';\nimport { subscribeToResult } from '../util/subscribeToResult';\nimport { map } from './map';\nimport { from } from '../observable/from';\nexport function switchMap(project, resultSelector) {\n if (typeof resultSelector === 'function') {\n return function (source) { return source.pipe(switchMap(function (a, i) { return from(project(a, i)).pipe(map(function (b, ii) { return resultSelector(a, b, i, ii); })); })); };\n }\n return function (source) { return source.lift(new SwitchMapOperator(project)); };\n}\nvar SwitchMapOperator = /*@__PURE__*/ (function () {\n function SwitchMapOperator(project) {\n this.project = project;\n }\n SwitchMapOperator.prototype.call = function (subscriber, source) {\n return source.subscribe(new SwitchMapSubscriber(subscriber, this.project));\n };\n return SwitchMapOperator;\n}());\nvar SwitchMapSubscriber = /*@__PURE__*/ (function (_super) {\n tslib_1.__extends(SwitchMapSubscriber, _super);\n function SwitchMapSubscriber(destination, project) {\n var _this = _super.call(this, destination) || this;\n _this.project = project;\n _this.index = 0;\n return _this;\n }\n SwitchMapSubscriber.prototype._next = function (value) {\n var result;\n var index = this.index++;\n try {\n result = this.project(value, index);\n }\n catch (error) {\n this.destination.error(error);\n return;\n }\n this._innerSub(result, value, index);\n };\n SwitchMapSubscriber.prototype._innerSub = function (result, value, index) {\n var innerSubscription = this.innerSubscription;\n if (innerSubscription) {\n innerSubscription.unsubscribe();\n }\n var innerSubscriber = new InnerSubscriber(this, value, index);\n var destination = this.destination;\n destination.add(innerSubscriber);\n this.innerSubscription = subscribeToResult(this, result, undefined, undefined, innerSubscriber);\n if (this.innerSubscription !== innerSubscriber) {\n destination.add(this.innerSubscription);\n }\n };\n SwitchMapSubscriber.prototype._complete = function () {\n var innerSubscription = this.innerSubscription;\n if (!innerSubscription || innerSubscription.closed) {\n _super.prototype._complete.call(this);\n }\n this.unsubscribe();\n };\n SwitchMapSubscriber.prototype._unsubscribe = function () {\n this.innerSubscription = null;\n };\n SwitchMapSubscriber.prototype.notifyComplete = function (innerSub) {\n var destination = this.destination;\n destination.remove(innerSub);\n this.innerSubscription = null;\n if (this.isStopped) {\n _super.prototype._complete.call(this);\n }\n };\n SwitchMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) {\n this.destination.next(innerValue);\n };\n return SwitchMapSubscriber;\n}(OuterSubscriber));\n//# sourceMappingURL=switchMap.js.map\n","/** PURE_IMPORTS_START _Observable,_util_subscribeTo,_scheduled_scheduled PURE_IMPORTS_END */\nimport { Observable } from '../Observable';\nimport { subscribeTo } from '../util/subscribeTo';\nimport { scheduled } from '../scheduled/scheduled';\nexport function from(input, scheduler) {\n if (!scheduler) {\n if (input instanceof Observable) {\n return input;\n }\n return new Observable(subscribeTo(input));\n }\n else {\n return scheduled(input, scheduler);\n }\n}\n//# sourceMappingURL=from.js.map\n","import { SelectableValue } from '@grafana/data';\n\n/**\n * Query Type Values\n */\nexport enum QueryTypeValue {\n COMMAND = 'command',\n TIMESERIES = 'timeSeries',\n CLI = 'cli',\n}\n\n/**\n * Query Type\n */\nexport const QueryType: Array> = [\n {\n label: 'Redis commands',\n description: 'Hashes, Sets, Lists, Strings, Streams, etc.',\n value: QueryTypeValue.COMMAND,\n },\n {\n label: 'RedisTimeSeries commands',\n description: 'Redis Module adding a Time Series data structure to Redis',\n value: QueryTypeValue.TIMESERIES,\n },\n {\n label: 'Command-line interface (CLI)',\n description: 'Be mindful, not all commands are supported',\n value: QueryTypeValue.CLI,\n },\n];\n\n/**\n * Commands\n */\nexport const Commands = {\n command: [\n {\n label: 'CLIENT LIST',\n description: 'Returns information and statistics about the client connections server',\n value: 'clientList',\n },\n {\n label: 'GET',\n description: 'Returns the value of key',\n value: 'get',\n },\n { label: 'HGET', description: 'Returns the value associated with field in the hash stored at key', value: 'hget' },\n { label: 'HGETALL', description: 'Returns all fields and values of the hash stored at key', value: 'hgetall' },\n { label: 'HKEYS', description: 'Returns all field names in the hash stored at key', value: 'hkeys' },\n { label: 'HLEN', description: 'Returns the number of fields contained in the hash stored at key', value: 'hlen' },\n { label: 'INFO', description: 'Returns information and statistics about the server', value: 'info' },\n { label: 'LLEN', description: 'Returns the length of the list stored at key', value: 'llen' },\n {\n label: 'SCARD',\n description: 'Returns the set cardinality (number of elements) of the set stored at key',\n value: 'scard',\n },\n {\n label: 'SLOWLOG GET',\n description: 'Returns the Redis slow queries log',\n value: 'slowlogGet',\n },\n { label: 'SMEMBERS', description: 'Returns all the members of the set value stored at key', value: 'smembers' },\n {\n label: 'TTL',\n description: 'Returns the string representation of the type of the value stored at key',\n value: 'ttl',\n },\n {\n label: 'TYPE',\n description: 'Returns the string representation of the type of the value stored at key',\n value: 'type',\n },\n /**\n * {\n * label: 'XINFO STREAM',\n * description: 'Returns general information about the stream stored at the specified key',\n * value: 'xinfoStream',\n * },\n */\n {\n label: 'XLEN',\n description: 'Returns the number of entries inside a stream',\n value: 'xlen',\n },\n ],\n timeSeries: [\n {\n label: 'TS.MRANGE',\n description: 'Query a timestamp range across multiple time-series by filters',\n value: 'ts.mrange',\n },\n { label: 'TS.RANGE', description: 'Query a range', value: 'ts.range' },\n ],\n};\n\n/**\n * Input for Commands\n */\nexport const CommandParameters = {\n aggregation: ['ts.range', 'ts.mrange'],\n field: ['hget'],\n filter: ['ts.mrange'],\n key: [\n 'get',\n 'hget',\n 'hgetall',\n 'hkeys',\n 'hlen',\n 'llen',\n 'scard',\n 'smembers',\n 'ts.range',\n 'ttl',\n 'type',\n 'xinfoStream',\n 'xlen',\n ],\n legend: ['ts.range'],\n legendLabel: ['ts.mrange'],\n section: ['info'],\n valueLabel: ['ts.mrange'],\n};\n\n/**\n * Aggregations\n */\nexport const Aggregations: Array> = [\n { label: 'None', description: 'No aggregation', value: '' },\n { label: 'Avg', description: 'Average', value: 'avg' },\n { label: 'Count', description: 'Count number of samples', value: 'count' },\n { label: 'Max', description: 'Maximum', value: 'max' },\n { label: 'Min', description: 'Minimum', value: 'min' },\n { label: 'Range', description: 'Diff between maximum and minimum in the bucket', value: 'range' },\n { label: 'Sum', description: 'Sum', value: 'sum' },\n];\n\n/**\n * Info sections\n */\nexport const InfoSections: Array> = [\n { label: 'Server', description: 'General information about the Redis server', value: 'server' },\n { label: 'Clients', description: 'Client connections section', value: 'clients' },\n { label: 'Memory', description: 'Memory consumption related information', value: 'memory' },\n { label: 'Persistence', description: 'RDB and AOF related information', value: 'persistence' },\n { label: 'Stats', description: 'General statistics', value: 'stats' },\n { label: 'Replication', description: 'Master/replica replication information', value: 'replication' },\n { label: 'CPU', description: 'CPU consumption statistics', value: 'cpu' },\n { label: 'Command Stats', description: 'Redis command statistics', value: 'commandstats' },\n { label: 'Cluster', description: 'Redis Cluster section', value: 'cluster' },\n { label: 'Keyspace', description: 'Database related statistics', value: 'keyspace' },\n];\n","/** PURE_IMPORTS_START _InnerSubscriber,_subscribeTo,_Observable PURE_IMPORTS_END */\nimport { InnerSubscriber } from '../InnerSubscriber';\nimport { subscribeTo } from './subscribeTo';\nimport { Observable } from '../Observable';\nexport function subscribeToResult(outerSubscriber, result, outerValue, outerIndex, innerSubscriber) {\n if (innerSubscriber === void 0) {\n innerSubscriber = new InnerSubscriber(outerSubscriber, outerValue, outerIndex);\n }\n if (innerSubscriber.closed) {\n return undefined;\n }\n if (result instanceof Observable) {\n return result.subscribe(innerSubscriber);\n }\n return subscribeTo(result)(innerSubscriber);\n}\n//# sourceMappingURL=subscribeToResult.js.map\n","import { map as map$, switchMap as switchMap$ } from 'rxjs/operators';\nimport { DataFrame, DataQueryRequest, DataSourceInstanceSettings, MetricFindValue } from '@grafana/data';\nimport { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime';\nimport { RedisDataSourceOptions, RedisQuery } from './types';\n\n/**\n * Redis Data Source\n */\nexport class DataSource extends DataSourceWithBackend {\n /**\n * Constructor\n *\n * @param instanceSettings Instance Settings\n */\n constructor(instanceSettings: DataSourceInstanceSettings) {\n super(instanceSettings);\n }\n\n /**\n * Variable query action\n */\n async metricFindQuery?(query: string, options?: any): Promise {\n /**\n * If query or datasource not specified\n */\n if (!query || !options.variable.datasource) {\n return Promise.resolve([]);\n }\n\n /**\n * Run Query\n */\n return this.query({\n targets: [{ datasource: options.variable.datasource, query: query }],\n } as DataQueryRequest)\n .pipe(\n switchMap$(response => response.data),\n switchMap$((data: DataFrame) => data.fields),\n map$(field =>\n field.values.toArray().map(value => {\n return { text: value };\n })\n )\n )\n .toPromise();\n }\n\n /**\n * Override to apply template variables\n */\n applyTemplateVariables(query: RedisQuery) {\n const templateSrv = getTemplateSrv();\n\n /**\n * Replace variables\n */\n return {\n ...query,\n key: query.key ? templateSrv.replace(query.key) : '',\n query: query.query ? templateSrv.replace(query.query) : '',\n filter: query.filter ? templateSrv.replace(query.filter) : '',\n };\n }\n}\n","import { QueryEditorProps, SelectableValue } from '@grafana/data';\nimport { Button, InlineFormLabel, LegacyForms, Select, TextArea } from '@grafana/ui';\nimport { Aggregations, CommandParameters, Commands, QueryType, QueryTypeValue, InfoSections } from 'command';\nimport React, { ChangeEvent, PureComponent } from 'react';\nimport { DataSource } from './DataSource';\nimport { RedisDataSourceOptions, RedisQuery } from './types';\n\n/**\n * Form Field\n */\nconst { FormField } = LegacyForms;\n\n/**\n * Editor Property\n */\ntype Props = QueryEditorProps;\n\n/**\n * Query Editor\n */\nexport class QueryEditor extends PureComponent {\n /**\n * Key change\n *\n * @param event Event\n */\n onKeyChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, key: event.target.value });\n };\n\n /**\n * Query change\n *\n * @param event Event\n */\n onQueryChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, query: event.target.value });\n };\n\n /**\n * Execute the Query\n */\n executeQuery = () => {\n const { onRunQuery } = this.props;\n onRunQuery();\n };\n\n /**\n * Filter change\n *\n * @param event Event\n */\n onFilterChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, filter: event.target.value });\n };\n\n /**\n * Field change\n *\n * @param event Event\n */\n onFieldChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, field: event.target.value });\n };\n\n /**\n * Legend change\n *\n * @param event Event\n */\n onLegendChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, legend: event.target.value });\n };\n\n /**\n * Value change\n *\n * @param event Event\n */\n onValueChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, value: event.target.value });\n };\n\n /**\n * Command change\n *\n * @param val Value\n */\n onCommandChange = (val: SelectableValue) => {\n const { onChange, query } = this.props;\n onChange({ ...query, command: val.value });\n };\n\n /**\n * Type change\n *\n * @param val Value\n */\n onTypeChange = (val: SelectableValue) => {\n const { onChange, query } = this.props;\n onChange({\n ...query,\n type: val.value as QueryTypeValue,\n query: '',\n command: '',\n });\n };\n\n /**\n * Aggregation change\n *\n * @param val Value\n */\n onAggregationTextChange = (val: SelectableValue) => {\n const { onChange, query } = this.props;\n onChange({ ...query, aggregation: val.value });\n };\n\n /**\n * Info section change\n *\n * @param val Value\n */\n onInfoSectionTextChange = (val: SelectableValue) => {\n const { onChange, query } = this.props;\n onChange({ ...query, section: val.value });\n };\n\n /**\n * Bucket change\n *\n * @param val Value\n */\n onBucketTextChange = (event: ChangeEvent) => {\n const { onChange, query } = this.props;\n onChange({ ...query, bucket: event.target.value });\n };\n\n /**\n * Render Editor\n */\n render() {\n const { key, aggregation, bucket, legend, command, field, filter, value, query, type, section } = this.props.query;\n\n /**\n * Return\n */\n return (\n
\n
\n Type\n