diff --git a/ui/src/clientLibraries/components/ClientCSharpOverlay.tsx b/ui/src/clientLibraries/components/ClientCSharpOverlay.tsx index e39a6a981fc..e77fdb206d9 100644 --- a/ui/src/clientLibraries/components/ClientCSharpOverlay.tsx +++ b/ui/src/clientLibraries/components/ClientCSharpOverlay.tsx @@ -2,7 +2,7 @@ import React, {FunctionComponent} from 'react' // Components import ClientLibraryOverlay from 'src/clientLibraries/components/ClientLibraryOverlay' -import CodeSnippet from 'src/shared/components/CodeSnippet' +import TemplatedCodeSnippet from 'src/shared/components/TemplatedCodeSnippet' // Constants import {clientCSharpLibrary} from 'src/clientLibraries/constants' @@ -30,32 +30,67 @@ const ClientCSharpOverlay: FunctionComponent<{}> = () => {

Install Package

Package Manager

-

.NET CLI

-

Package Reference

- +
Initialize the Client
- +
Write Data

Option 1: Use InfluxDB Line Protocol to write data

-

Option 2: Use a Data Point to write data

- +

Option 3: Use POCO and corresponding Class to write data

- - + +
Execute a Flux query
- + ) } diff --git a/ui/src/clientLibraries/components/ClientGoOverlay.tsx b/ui/src/clientLibraries/components/ClientGoOverlay.tsx index 44c9ff0e065..18b4a80dfc2 100644 --- a/ui/src/clientLibraries/components/ClientGoOverlay.tsx +++ b/ui/src/clientLibraries/components/ClientGoOverlay.tsx @@ -3,7 +3,7 @@ import React, {FunctionComponent} from 'react' // Components import ClientLibraryOverlay from 'src/clientLibraries/components/ClientLibraryOverlay' -import CodeSnippet from 'src/shared/components/CodeSnippet' +import TemplatedCodeSnippet from 'src/shared/components/TemplatedCodeSnippet' // Constants import {clientGoLibrary} from 'src/clientLibraries/constants' @@ -24,9 +24,23 @@ const ClientGoOverlay: FunctionComponent<{}> = () => {

Initialize the Client
- +
Write Data
- + ) } diff --git a/ui/src/clientLibraries/components/ClientJSOverlay.tsx b/ui/src/clientLibraries/components/ClientJSOverlay.tsx index e081773ead1..f5208df5759 100644 --- a/ui/src/clientLibraries/components/ClientJSOverlay.tsx +++ b/ui/src/clientLibraries/components/ClientJSOverlay.tsx @@ -3,7 +3,7 @@ import React, {FunctionComponent} from 'react' // Components import ClientLibraryOverlay from 'src/clientLibraries/components/ClientLibraryOverlay' -import CodeSnippet from 'src/shared/components/CodeSnippet' +import TemplatedCodeSnippet from 'src/shared/components/TemplatedCodeSnippet' // Constants import {clientJSLibrary} from 'src/clientLibraries/constants' @@ -27,17 +27,31 @@ const ClientJSOverlay: FunctionComponent<{}> = () => {


Initialize the Client
-
Write Data
-
Execute a Flux query
- + ) } diff --git a/ui/src/clientLibraries/components/ClientJavaOverlay.tsx b/ui/src/clientLibraries/components/ClientJavaOverlay.tsx index e8229ad9910..32ed7eb534b 100644 --- a/ui/src/clientLibraries/components/ClientJavaOverlay.tsx +++ b/ui/src/clientLibraries/components/ClientJavaOverlay.tsx @@ -2,7 +2,7 @@ import React, {FunctionComponent} from 'react' // Components import ClientLibraryOverlay from 'src/clientLibraries/components/ClientLibraryOverlay' -import CodeSnippet from 'src/shared/components/CodeSnippet' +import TemplatedCodeSnippet from 'src/shared/components/TemplatedCodeSnippet' // Constants import {clientJavaLibrary} from 'src/clientLibraries/constants' @@ -30,24 +30,59 @@ const ClientJavaOverlay: FunctionComponent<{}> = () => {

Add Dependency

Build with Maven

- +

Build with Gradle

- +
Initialize the Client
- +
Write Data

Option 1: Use InfluxDB Line Protocol to write data

-

Option 2: Use a Data Point to write data

- +

Option 3: Use POJO and corresponding class to write data

- - + +
Execute a Flux query
- + ) } diff --git a/ui/src/clientLibraries/components/ClientPythonOverlay.tsx b/ui/src/clientLibraries/components/ClientPythonOverlay.tsx index 33959685f18..ebffd4e4b24 100644 --- a/ui/src/clientLibraries/components/ClientPythonOverlay.tsx +++ b/ui/src/clientLibraries/components/ClientPythonOverlay.tsx @@ -3,7 +3,7 @@ import React, {FunctionComponent} from 'react' // Components import ClientLibraryOverlay from 'src/clientLibraries/components/ClientLibraryOverlay' -import CodeSnippet from 'src/shared/components/CodeSnippet' +import TemplatedCodeSnippet from 'src/shared/components/TemplatedCodeSnippet' // Constants import {clientPythonLibrary} from 'src/clientLibraries/constants' @@ -29,21 +29,56 @@ const ClientPythonOverlay: FunctionComponent<{}> = () => {

Install Package
- +
Initialize the Client
- +
Write Data

Option 1: Use InfluxDB Line Protocol to write data

-

Option 2: Use a Data Point to write data

- +

Option 3: Use a Batch Sequence to write data

- +
Execute a Flux query
- + ) } diff --git a/ui/src/clientLibraries/constants/index.ts b/ui/src/clientLibraries/constants/index.ts index 22241ee1ab1..ae2ee0f87f7 100644 --- a/ui/src/clientLibraries/constants/index.ts +++ b/ui/src/clientLibraries/constants/index.ts @@ -22,45 +22,45 @@ export const clientCSharpLibrary = { packageReferenceCodeSnippet: ``, initializeClientCodeSnippet: `using InfluxDB.Client; namespace Examples -{ - public class Examples - { - public static void Main(string[] args) - { +{ + public class Examples + { + public static void Main(string[] args) + { // You can generate a Token from the "Tokens Tab" in the UI - var client = InfluxDBClientFactory.Create("basepath", "token".ToCharArray()); - } + var client = InfluxDBClientFactory.Create("<%= server %>", "<%= token %>".ToCharArray()); + } } }`, - executeQueryCodeSnippet: `const string query = "from(bucket: \\"my_bucket\\") |> range(start: -1h)"; -var tables = await client.GetQueryApi().QueryAsync(query, "myorgid");`, + executeQueryCodeSnippet: `const string query = "from(bucket: \\"<%= bucket %>\\") |> range(start: -1h)"; +var tables = await client.GetQueryApi().QueryAsync(query, "<%= org %>");`, writingDataLineProtocolCodeSnippet: `const string data = "mem,host=host1 used_percent=23.43234543 1556896326"; using (var writeApi = client.GetWriteApi()) -{ - writeApi.WriteRecord("bucketID", "orgID", WritePrecision.Ns, data); +{ + writeApi.WriteRecord("<%= bucket %>", "<%= org %>", WritePrecision.Ns, data); }`, - writingDataPointCodeSnippet: `var point = PointData - .Measurement("mem") - .Tag("host", "host1") - .Field("used_percent", 23.43234543) + writingDataPointCodeSnippet: `var point = PointData + .Measurement("mem") + .Tag("host", "host1") + .Field("used_percent", 23.43234543) .Timestamp(1556896326L, WritePrecision.Ns); - + using (var writeApi = client.GetWriteApi()) -{ - writeApi.WritePoint("bucketID", "orgID", point); +{ + writeApi.WritePoint("<%= bucket %>", "<%= org %>", point); }`, writingDataPocoCodeSnippet: `var mem = new Mem { Host = "host1", UsedPercent = 23.43234543, Time = DateTime.UtcNow }; - + using (var writeApi = client.GetWriteApi()) -{ - writeApi.WriteMeasurement("bucketID", "orgID", WritePrecision.Ns, mem); +{ + writeApi.WriteMeasurement("<%= bucket %>", "<%= org %>", WritePrecision.Ns, mem); }`, pocoClassCodeSnippet: `// Public class [Measurement("mem")] private class Mem -{ - [Column("host", IsTag = true)] public string Host { get; set; } - [Column("used_percent")] public double? UsedPercent { get; set; } +{ + [Column("host", IsTag = true)] public string Host { get; set; } + [Column("used_percent")] public double? UsedPercent { get; set; } [Column(IsTimestamp = true)] public DateTime Time { get; set; } }`, } @@ -71,7 +71,7 @@ export const clientGoLibrary = { url: 'https://github.com/influxdata/influxdb-client-go', image: GoLogo, initializeClientCodeSnippet: `// You can generate a Token from the "Tokens Tab" in the UI -influx, err := influxdb.New(myHTTPInfluxAddress, myToken, influxdb.WithHTTPClient(myHTTPClient)) +influx, err := influxdb.New(<%= server %>, <%= token %>, influxdb.WithHTTPClient(myHTTPClient)) if err != nil { panic(err) // error handling here; normally we wouldn't use fmt but it works for the example } @@ -93,7 +93,7 @@ myMetrics := []influxdb.Metric{ } // The actual write..., this method can be called concurrently. -if _, err := influx.Write(context.Background(), "my-awesome-bucket", "my-very-awesome-org", myMetrics...) +if _, err := influx.Write(context.Background(), "<%= bucket %>", "<%= org %>", myMetrics...) if err != nil { log.Fatal(err) // as above use your own error handling here. }`, @@ -113,46 +113,46 @@ export const clientJavaLibrary = { compile "com.influxdb:influxdb-client-java:1.1.0" }`, initializeClientCodeSnippet: `package example; - + import com.influxdb.client.InfluxDBClient; import com.influxdb.client.InfluxDBClientFactory; - -public class InfluxDB2Example { - public static void main(final String[] args) { - // You can generate a Token from the "Tokens Tab" in the UI - InfluxDBClient client = InfluxDBClientFactory.create("serverUrl", "token".toCharArray()); + +public class InfluxDB2Example { + public static void main(final String[] args) { + // You can generate a Token from the "Tokens Tab" in the UI + InfluxDBClient client = InfluxDBClientFactory.create("<%= server %>", "<%= token %>".toCharArray()); } }`, - executeQueryCodeSnippet: `String query = "from(bucket: \\"my_bucket\\") |> range(start: -1h)"; -List tables = client.getQueryApi().query(query, "myorgid");`, + executeQueryCodeSnippet: `String query = "from(bucket: \\"<%= bucket %>\\") |> range(start: -1h)"; +List tables = client.getQueryApi().query(query, "<%= org %>");`, writingDataLineProtocolCodeSnippet: `String data = "mem,host=host1 used_percent=23.43234543 1556896326"; -try (WriteApi writeApi = client.getWriteApi()) { - writeApi.writeRecord("bucketID", "orgID", WritePrecision.NS, data); +try (WriteApi writeApi = client.getWriteApi()) { + writeApi.writeRecord("<%= bucket %>", "<%= org %>", WritePrecision.NS, data); }`, - writingDataPointCodeSnippet: `Point point = Point - .measurement("mem") - .addTag("host", "host1") - .addField("used_percent", 23.43234543) + writingDataPointCodeSnippet: `Point point = Point + .measurement("mem") + .addTag("host", "host1") + .addField("used_percent", 23.43234543) .time(1556896326L, WritePrecision.NS); - -try (WriteApi writeApi = client.getWriteApi()) { - writeApi.writePoint("bucketID", "orgID", point); + +try (WriteApi writeApi = client.getWriteApi()) { + writeApi.writePoint("<%= bucket %>", "<%= org %>", point); }`, writingDataPojoCodeSnippet: `Mem mem = new Mem(); mem.host = "host1"; mem.used_percent = 23.43234543; mem.time = Instant.now(); -try (WriteApi writeApi = client.getWriteApi()) { - writeApi.writeMeasurement("bucketID", "orgID", WritePrecision.NS, mem); +try (WriteApi writeApi = client.getWriteApi()) { + writeApi.writeMeasurement("<%= bucket %>", "<%= org %>", WritePrecision.NS, mem); }`, pojoClassCodeSnippet: `@Measurement(name = "mem") -public class Mem { - @Column(tag = true) - String host; - @Column - Double used_percent; - @Column(timestamp = true) +public class Mem { + @Column(tag = true) + String host; + @Column + Double used_percent; + @Column(timestamp = true) Instant time; }`, } @@ -164,12 +164,12 @@ export const clientJSLibrary = { image: JSLogo, initializeClientCodeSnippet: `import Client from '@influxdata/influx' // You can generate a Token from the "Tokens Tab" in the UI -const client = new Client('serverUrl', 'token')`, +const client = new Client('<%= server %>', '<%= token %>')`, executeQueryCodeSnippet: `const query = 'from(bucket: "my_bucket") |> range(start: -1h)' -const {promise} = client.queries.execute('myorgid', query) +const {promise} = client.queries.execute('<%= org %>', query) const csv = await promise`, writingDataLineProtocolCodeSnippet: `const data = 'mem,host=host1 used_percent=23.43234543 1556896326' // Line protocol string -const response = await client.write.create('orgID', 'bucketID', data)`, +const response = await client.write.create('<%= org %>', '<%= bucket %>', data)`, } export const clientPythonLibrary = { @@ -182,20 +182,20 @@ export const clientPythonLibrary = { from influxdb_client import InfluxDBClient ## You can generate a Token from the "Tokens Tab" in the UI -client = InfluxDBClient(url="serverUrl", token="token")`, - executeQueryCodeSnippet: `query = 'from(bucket: "my_bucket") |> range(start: -1h)' -tables = client.query_api().query(query, org="myorgid")`, +client = InfluxDBClient(url="<%= server %>", token="<%= token %>")`, + executeQueryCodeSnippet: `query = 'from(bucket: "<%= bucket %>") |> range(start: -1h)' +tables = client.query_api().query(query, org="<%= org %>")`, writingDataLineProtocolCodeSnippet: `data = "mem,host=host1 used_percent=23.43234543 1556896326" -write_client.write("bucketID", "orgID", data)`, +write_client.write("<%= bucket %>", "<%= org %>", data)`, writingDataPointCodeSnippet: `point = Point("mem") .tag("host", "host1") .field("used_percent", 23.43234543) .time(1556896326, WritePrecision.NS) -write_client.write("bucketID", "orgID", point)`, +write_client.write("<%= bucket %>", "<%= org %>", point)`, writingDataBatchCodeSnippet: `sequence = ["mem,host=host1 used_percent=23.43234543 1556896326", "mem,host=host1 available_percent=15.856523 1556896326"] -write_client.write("bucketID", "orgID", sequence)`, +write_client.write("<%= bucket %>", "<%= org %>", sequence)`, } export const clientLibraries: ClientLibrary[] = [ diff --git a/ui/src/shared/components/TemplatedCodeSnippet.test.tsx b/ui/src/shared/components/TemplatedCodeSnippet.test.tsx new file mode 100644 index 00000000000..dfdd7990d02 --- /dev/null +++ b/ui/src/shared/components/TemplatedCodeSnippet.test.tsx @@ -0,0 +1,91 @@ +// Libraries +import React from 'react' +import {render} from 'react-testing-library' + +describe('TeplatedCodeSnippet', () => { + beforeEach(() => { + // NOTE: as long as you mock children like below, before importing your + // component by using a require().default pattern, this will reset your + // mocks between tests (alex) + jest.resetModules() + }) + + it('should allow normal strings', () => { + let props: any = {} + jest.mock('src/shared/components/CodeSnippet', () => _props => { + props = _props + return false + }) + + const template = 'this is only a test' + const Component = require('src/shared/components/TemplatedCodeSnippet') + .default + render() + + expect(props.hasOwnProperty('copyText')).toBe(true) + expect(props.copyText).toEqual(template) + }) + + it('should show undefined', () => { + let props: any = {} + jest.mock('src/shared/components/CodeSnippet', () => _props => { + props = _props + return false + }) + + const template = 'this is only a <%= word %>' + const response = 'this is only a undefined' + const Component = require('src/shared/components/TemplatedCodeSnippet') + .default + render() + + expect(props.hasOwnProperty('copyText')).toBe(true) + expect(props.copyText).toEqual(response) + }) + + it('should respect defaults', () => { + let props: any = {} + jest.mock('src/shared/components/CodeSnippet', () => _props => { + props = _props + return false + }) + + const template = 'this is only a <%= word %>' + const response = 'this is only a sentance' + const defaults = { + word: 'sentance', + } + const Component = require('src/shared/components/TemplatedCodeSnippet') + .default + render() + + expect(props.hasOwnProperty('copyText')).toBe(true) + expect(props.copyText).toEqual(response) + }) + + it('should overwrite defaults with values', () => { + let props: any = {} + jest.mock('src/shared/components/CodeSnippet', () => _props => { + props = _props + + return false + }) + + const template = 'this is only a <%= word %>' + const response = 'this is only a test' + const defaults = { + word: 'sentance', + } + const values = { + word: 'test', + } + const Component = require('src/shared/components/TemplatedCodeSnippet') + .default + render( + + ) + + expect(props.hasOwnProperty('copyText')).toBe(true) + expect(props.copyText).toEqual(response) + }) +}) diff --git a/ui/src/shared/components/TemplatedCodeSnippet.tsx b/ui/src/shared/components/TemplatedCodeSnippet.tsx new file mode 100644 index 00000000000..0fb7139d43e --- /dev/null +++ b/ui/src/shared/components/TemplatedCodeSnippet.tsx @@ -0,0 +1,46 @@ +import React, {PureComponent} from 'react' + +// Decorator +import {ErrorHandling} from 'src/shared/decorators/errors' + +// Components +import CodeSnippet from 'src/shared/components/CodeSnippet' + +interface StringMap { + [key: string]: string +} + +export interface Props { + template: string + label: string + values?: StringMap + defaults?: StringMap +} + +@ErrorHandling +class TemplatedCodeSnippet extends PureComponent { + // NOTE: this is just a simplified form of the resig classic: + // https://johnresig.com/blog/javascript-micro-templating/ + public transform() { + const text = this.props.template + const output = new Function( + 'vars', + 'var output=' + + JSON.stringify(text).replace(/<%=(.+?)%>/g, '"+(vars["$1".trim()])+"') + + ';return output;' + ) + return output(Object.assign({}, this.props.defaults, this.props.values)) + } + + render() { + const {label} = this.props + const props = { + label, + copyText: this.transform(), + } + + return + } +} + +export default TemplatedCodeSnippet