From 691908b680526f1f5cd3d38839cffdf94a6e259d Mon Sep 17 00:00:00 2001 From: iamskp99 Date: Tue, 20 Sep 2022 17:24:11 +0530 Subject: [PATCH] feat(ui): add copy to clipboard feature and installation guide Signed-off-by: iamskp99 --- src/components/onboarding/Accordion.tsx | 8 +- src/components/onboarding/Checkbox.tsx | 18 +-- src/components/onboarding/Constant.ts | 20 +-- src/components/onboarding/CopyToClipboard.tsx | 27 ++++ src/components/onboarding/Documentation.tsx | 132 ++++++++++++++++++ src/components/onboarding/Onboard.tsx | 33 ++++- static/onboardingCss/Accordion.css | 6 +- static/onboardingCss/App.css | 13 ++ static/onboardingCss/Checkbox.css | 8 +- static/onboardingCss/Documentation.css | 29 ++++ 10 files changed, 264 insertions(+), 30 deletions(-) create mode 100644 src/components/onboarding/CopyToClipboard.tsx create mode 100644 src/components/onboarding/Documentation.tsx create mode 100644 static/onboardingCss/Documentation.css diff --git a/src/components/onboarding/Accordion.tsx b/src/components/onboarding/Accordion.tsx index afebb17..32f2b9a 100644 --- a/src/components/onboarding/Accordion.tsx +++ b/src/components/onboarding/Accordion.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from "react" +import CopyToClipboard from "./CopyToClipboard" import '../../../static/onboardingCss/Accordion.css' export interface PanelProps { @@ -19,7 +20,7 @@ function Panel(props: PanelProps){ useEffect(()=>{ window.setTimeout(() => { - setHeight(500) + setHeight(620) }, 333); },[]) @@ -36,9 +37,12 @@ function Panel(props: PanelProps){
+
+ +

-                    { props.content }
+                        { props.content }
                     

diff --git a/src/components/onboarding/Checkbox.tsx b/src/components/onboarding/Checkbox.tsx index 7e4092a..39cb861 100644 --- a/src/components/onboarding/Checkbox.tsx +++ b/src/components/onboarding/Checkbox.tsx @@ -21,13 +21,13 @@ export function Checkbox(props:CheckboxProps){ handleCheckboxChange(label); } return( -
- - -
+
+ + +
) } @@ -70,9 +70,9 @@ export function ListCheckboxes(props: ListCheckboxesProps){
{formSubmitEvent.preventDefault(); props.setLang("None");}}> - +
- +
diff --git a/src/components/onboarding/Constant.ts b/src/components/onboarding/Constant.ts index 1621351..2408d99 100644 --- a/src/components/onboarding/Constant.ts +++ b/src/components/onboarding/Constant.ts @@ -2,16 +2,16 @@ export const languages : any = [["Go","https://cdn.worldvectorlogo.com/logos/go- export const frameworks : any = {"Go":["Chi","Gin","Echo","WebGo","Gorilla/MUX","MongoDB","DynamoDB","SQL Driver","net/http","gRPC"] ,"Java":["Spring Boot"]} -export const details : any = {"Go":{"Chi":'r := chi.NewRouter()\nkchi.ChiV5(k,r)\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/kchi")\n\nr := chi.NewRouter()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my_app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n })\nkchi.ChiV5(k,r)\nhttp.ListenAndServe(":" + port, r)', - "Gin":'r:=gin.New()\nkgin.GinV1(k, r)\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/kgin/v1")\n\nr:=gin.New()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my_app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkgin.GinV1(k, r)\nr.Run(":" + port)', - "Echo":'e := echo.New()\nkecho.EchoV4(k, e)\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/kecho/v4")\n\ne := echo.New()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkecho.EchoV4(k, e)\ne.Start(":" + port)', - "WebGo":'WebGoV4\n\nrouter := webgo.NewRouter(cfg, getRoutes())\nkwebgo.WebGoV4(k, router)\n\nWebGoV6\n\nkwebgo.WebGoV6(k, router)\nrouter.Start()\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/kwebgo/v4")\n\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\n\nkwebgo.WebGoV4(k\n\n, router)\nrouter.Start()', - "Gorilla/MUX":'r := mux.NewRouter()\nkmux.Mux(k, r)\n\nExample =>\n\nimport(\n "github.com/keploy/go-sdk/integrations/kmux"\n "net/http"\n)\n\nr := mux.NewRouter()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkmux.Mux(k, r)\nhttp.ListenAndServe(":"+port, r)', - "MongoDB":'import("github.com/keploy/go-sdk/integrations/kmongo")\n\ndb := client.Database("testDB")\ncol := kmongo.NewCollection(db.Collection("Demo-Collection"))\n\nFollowing operations are supported:\n\nFindOne - Err and Decode method of mongo.SingleResult\nFind - Next, TryNext, Err, Close, All and Decode methods of mongo.cursor\nInsertOne\nInsertMany\nUpdateOne\nUpdateMany\nDeleteOne\nDeleteMany\nCountDocuments\nDistinct\nAggregate - Next, TryNext, Err, Close, All and Decode methods of mongo.cursor', - "DynamoDB":'import("github.com/keploy/go-sdk/integrations/kddb")\n\nclient := kddb.NewDynamoDB(dynamodb.New(sess))\n\n\nFollowing operations are supported:\n\nQueryWithContext\nGetItemWithContext\nPutItemWithContext' - ,"SQL Driver":'import(\n "github.com/keploy/go-sdk/integrations/ksql"\n "github.com/lib/pq"\n)\n\nfunc init(){\n driver := ksql.Driver{Driver: pq.Driver{}}\n sql.Register("keploy", &driver)\n}\n\n', - "net/http":'khttpclient.NewHttpClient(&http.Client{})\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/khttpclient")\n\nfunc(w http.ResponseWriter, r *http.Request){\n client := khttpclient.NewHttpClient(&http.Client{})\n// ensure to add request context to all outgoing http requests\n client.SetCtxHttpClient(r.Context())\n resp, err := client.Get("https://example.com")\n}\n\nNote: ensure to add pass request context to all external \nrequests like http requests, db calls, etc.', - "gRPC":'conn, err := grpc.Dial(address, grpc.WithInsecure(), kgrpc.WithClientUnaryInterceptor(k))\n\nExample =>\n\nimport("github.com/keploy/go-sdk/integrations/kgrpc")\n\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\n\nconn, err := grpc.Dial(address, grpc.WithInsecure(), kgrpc.WithClientUnaryInterceptor(k))\n\nNote: Currently streaming is not yet supported.'}, +export const details : any = {"Go":{"Chi":'\n\nr := chi.NewRouter()\nkchi.ChiV5(k,r)\n\n// Example \n\nimport("github.com/keploy/go-sdk/integrations/kchi")\n\nr := chi.NewRouter()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my_app",\n\ Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n })\n\nkchi.ChiV5(k,r)\nhttp.ListenAndServe(":" + port, r)', + "Gin":'\n\nr:=gin.New()\nkgin.GinV1(k, r)\n\n// Example \n\nimport("github.com/keploy/go-sdk/integrations/kgin/v1")\n\nr:=gin.New()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my_app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkgin.GinV1(k, r)\nr.Run(":" + port)', + "Echo":'\n\ne := echo.New()\nkecho.EchoV4(k, e)\n\n// Example\n\nimport("github.com/keploy/go-sdk/integrations/kecho/v4")\n\ne := echo.New()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkecho.EchoV4(k, e)\ne.Start(":" + port)', + "WebGo":'// WebGoV4\n\nrouter := webgo.NewRouter(cfg, getRoutes())\nkwebgo.WebGoV4(k, router)\n\n// WebGoV6\n\nkwebgo.WebGoV6(k, router)\nrouter.Start()\n\n// Example\n\nimport("github.com/keploy/go-sdk/integrations/kwebgo/v4")\n\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\n\nkwebgo.WebGoV4(k,router)\nrouter.Start()', + "Gorilla/MUX":'\n\nr := mux.NewRouter()\nkmux.Mux(k, r)\n\n// Example \n\nimport(\n "github.com/keploy/go-sdk/integrations/kmux"\n "net/http"\n)\n\nr := mux.NewRouter()\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\nkmux.Mux(k, r)\nhttp.ListenAndServe(":"+port, r)', + "MongoDB":'\n\nimport("github.com/keploy/go-sdk/integrations/kmongo")\n\ndb := client.Database("testDB")\ncol := kmongo.NewCollection(db.Collection("Demo-Collection"))\n\n// Following operations are supported:\n\n// FindOne - Err and Decode method of mongo.SingleResult\n// Find - Next, TryNext, Err, Close, All and Decode methods of mongo.cursor\n// InsertOne\n// InsertMany\n// UpdateOne\n// UpdateMany\n// DeleteOne\n// DeleteMany\n// CountDocuments\n// Distinct\n// Aggregate - Next, TryNext, Err, Close, All and Decode methods of mongo.cursor', + "DynamoDB":'\n\nimport("github.com/keploy/go-sdk/integrations/kddb")\n\nclient := kddb.NewDynamoDB(dynamodb.New(sess))\n\n\n// Following operations are supported:\n\n// QueryWithContext\n// GetItemWithContext\n// PutItemWithContext' + ,"SQL Driver":'\n\nimport(\n "github.com/keploy/go-sdk/integrations/ksql"\n "github.com/lib/pq"\n)\n\nfunc init(){\n driver := ksql.Driver{Driver: pq.Driver{}}\n sql.Register("keploy", &driver)\n}\n\n', + "net/http":'\n\nkhttpclient.NewHttpClient(&http.Client{})\n\n// Example \n\nimport("github.com/keploy/go-sdk/integrations/khttpclient")\n\nfunc(w http.ResponseWriter, r *http.Request){\n client := khttpclient.NewHttpClient(&http.Client{})\n// ensure to add request context to all outgoing http requests\n client.SetCtxHttpClient(r.Context())\n resp, err := client.Get("https://example.com")\n}\n\n// Note: ensure to add pass request context to all external \nrequests like http requests, db calls, etc.', + "gRPC":'\n\nconn, err := grpc.Dial(address, grpc.WithInsecure(), kgrpc.WithClientUnaryInterceptor(k))\n\n// Example \n\nimport("github.com/keploy/go-sdk/integrations/kgrpc")\n\nport := "8080"\nk := keploy.New(keploy.Config{\n App: keploy.AppConfig{\n Name: "my-app",\n Port: port,\n },\n Server: keploy.ServerConfig{\n URL: "http://localhost:8081/api",\n },\n})\n\nconn, err := grpc.Dial(address, grpc.WithInsecure(), kgrpc.WithClientUnaryInterceptor(k))\n\n// Note: Currently streaming is not yet supported.'}, "Java":{"Spring Boot":'package com.example.demo;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\n\n@SpringBootApplication(scanBasePackages = {"com.example.demo", "io.keploy.servlet"})\npublic class SamplesJavaApplication {\n public static void main(String[] args) {\n SpringApplication.run(SamplesJavaApplication.class, args);\n }\n}'}} export const images : any = {"Go":"https://cdn.worldvectorlogo.com/logos/go-logo-1.svg", diff --git a/src/components/onboarding/CopyToClipboard.tsx b/src/components/onboarding/CopyToClipboard.tsx new file mode 100644 index 0000000..e3321d9 --- /dev/null +++ b/src/components/onboarding/CopyToClipboard.tsx @@ -0,0 +1,27 @@ +import { Button, Snackbar } from '@mui/material' +import { useState} from 'react' +import React from 'react' + +export interface CopyToClipboardProps { + data: string +} + +function CopyToClipboard(props:CopyToClipboardProps){ + const [open, setOpen] = useState(false) + const handleClick = () => { + setOpen(true) + navigator.clipboard.writeText(props.data) + } + return ( +
+ + setOpen(false)} + autoHideDuration={2000} + message="Copied To Clipboard" + /> +
+ ) +} +export default CopyToClipboard \ No newline at end of file diff --git a/src/components/onboarding/Documentation.tsx b/src/components/onboarding/Documentation.tsx new file mode 100644 index 0000000..7d92cb9 --- /dev/null +++ b/src/components/onboarding/Documentation.tsx @@ -0,0 +1,132 @@ +import React from 'react'; +import '../../../static/onboardingCss/Documentation.css' + +export default function Documentation(){ + return( +
+ Keploy Logo +
+
+

Installation

+
+
+

Start Keploy Server

+
+ +
+ git clone https://github.com/keploy/keploy.git && cd keploy +
+ docker-compose up +
+
+

The UI can be accessed at http://localhost:8081

+
+

Helm Chart

+

Keploy can also be installed to your Kubernetes cluster using the Helm chart available here

+
+
+

Run Sample application

+
+
+

Demos using Echo/PostgreSQL and Gin/MongoDB are available here. For this example, we will use the Echo/PostgreSQL sample.

+ +
+ git clone https://github.com/keploy/samples-go && cd samples-go/echo-sql +
+ go mod download +
+
+
+
Start PostgreSQL instance
+ +
+ docker-compose up -d +
+
+
+
Run the application
+ +
+ go run handler.go main.go +
+
+
+
+
+

Generate testcases

+
+
+ Testcase Gif +
+
+

To genereate testcases we just need to make some API calls. You can use Postman,Hoppscotch, or simply curl

+
+
1. Generate shortned url
+
+ +
+ {`curl --request POST`} \{`\n`} + {`--url http://localhost:8080/url`} \{`\n`} + {`--header 'content-type: application/json'`} \{`\n`} + {`--data `}'{`{\n`} + {` `}"url :" "https://github.com"{`\n`} + {`}`}' +
+
+
+
2. Redirect to original url from shortened url
+
+ +
+ {`curl --request GET`} \{`\n`} + {` `}--url http://localhost:8080/GuwHCgoQ +
+
+
+
+
+

Integration with native Go test framework

+
+
+ Test Integration Gif +
+
+

You just need 3 lines of code in your unit test file and that's it!!🔥🔥🔥

+
+ +
+ {`import (\n`} + {` `}{`github.com/keploy/go-sdk/keploy\n`} + {` `}{`testing\n`} + {`)\n`} + {`func TestKeploy(t *testing.T) {\n`} + {` `}{`keploy.SetTestMode()\n`} + {` `}{`go main()\n`} + {` `}{`keploy.AssertTests(t)\n`} + {`}`} +
+
+
+

Run the testcases

+
+

Note: Before running tests stop the sample application

+
+ +
+ go test -coverpkg=./... -covermode=atomic ./... +
+
+
+

this should show you have 74.4% coverage without writing any code!

+
+ +
+ ok echo-psql-url-shortener 5.820s coverage: 74.4% of statements in ./... +
+
+
+

All of these can be visualised here - http://localhost:8081/testlist

+
+
+ ) +} \ No newline at end of file diff --git a/src/components/onboarding/Onboard.tsx b/src/components/onboarding/Onboard.tsx index a89fa6b..9757a52 100644 --- a/src/components/onboarding/Onboard.tsx +++ b/src/components/onboarding/Onboard.tsx @@ -1,4 +1,5 @@ import React, { useState }from 'react'; +import Documentation from './Documentation'; import { Accordion } from './Accordion'; import {languages,frameworks,details,images,issueLink} from './Constant'; import Empty from '../global/empty'; @@ -7,6 +8,7 @@ import { ListFrameworks,ListLangs } from "./OnboardUtils"; export default function Onboard(){ const [language, setLang] = useState("None"); const [options, setOptions] = useState([]); + const [showPage, setShowPage] = useState(false); if(language === "None"){ return( @@ -35,15 +37,29 @@ export default function Onboard(){
- - Create Issue for New Dependency on Github ! - + + Create Issue for New Dependency on Github ! +


) } + if(showPage === true){ + return( +
+
+ +
+
+
{formSubmitEvent.preventDefault();setShowPage(false);}}> + +
+
+
+ ) + } let panels : any[] = []; options.forEach((i) => { panels.push({label:i,content:details[language][i]}) @@ -54,9 +70,14 @@ export default function Onboard(){

-
{formSubmitEvent.preventDefault();setOptions([]);}}> - -
+
+
{formSubmitEvent.preventDefault();setOptions([]);}}> + +
+
{formSubmitEvent.preventDefault();setShowPage(true);}}> + +
+
) } \ No newline at end of file diff --git a/static/onboardingCss/Accordion.css b/static/onboardingCss/Accordion.css index 2c17026..f9006e0 100644 --- a/static/onboardingCss/Accordion.css +++ b/static/onboardingCss/Accordion.css @@ -6,7 +6,7 @@ .accordion { width: 100%; - max-width: 700px; + max-width: 500px; } .panel { /* background-color: black; */ @@ -70,3 +70,7 @@ .panel:not(:last-child) { margin-bottom: 3px; } + +.clipboard{ + margin-right: -80%; +} diff --git a/static/onboardingCss/App.css b/static/onboardingCss/App.css index 1880a09..b9828cb 100644 --- a/static/onboardingCss/App.css +++ b/static/onboardingCss/App.css @@ -87,4 +87,17 @@ .framework{ /* position:static */ padding-bottom: 7rem; +} + +.alignCenter{ + text-align: center; + justify-content: center; + display: flex; + gap: 18px; +} + +.documentation{ + text-align: left; + margin-left: 155px; + margin-top: 45px; } \ No newline at end of file diff --git a/static/onboardingCss/Checkbox.css b/static/onboardingCss/Checkbox.css index 886e925..1470d7d 100644 --- a/static/onboardingCss/Checkbox.css +++ b/static/onboardingCss/Checkbox.css @@ -1,12 +1,12 @@ .chb-onboard { visibility: hidden; /* align-items:unset; */ - margin-left: -40px; + margin-left: -60px; } .chb-onboard + label { position: absolute; - padding-left: 5px; + padding-left: 17px; } .chb-3-onboard + label::before { @@ -48,4 +48,8 @@ justify-content: center; box-sizing: border-box; } + + .largeFont{ + font-size:large; + } \ No newline at end of file diff --git a/static/onboardingCss/Documentation.css b/static/onboardingCss/Documentation.css new file mode 100644 index 0000000..5306768 --- /dev/null +++ b/static/onboardingCss/Documentation.css @@ -0,0 +1,29 @@ +code { + display: block; + text-align: left; + white-space: pre; + position: relative; + word-break: normal; + word-wrap: normal; + line-height: 2; + background-color: #e8e8e8; + /* margin: 10px; */ + border-radius: 5px; +} + +.codeContent{ + margin-left: 10px; +} + +.docImg{ + width: 50%; + margin-left: 90px; +} + +.logoImg{ + width: 25%; +} + +.ident{ + margin-left: 30px; +} \ No newline at end of file