Added styled features to frontend
This commit is contained in:
@@ -3,7 +3,6 @@ module shuffle
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared
|
replace github.com/frikky/shuffle-shared => ../../../../git/shuffle-shared
|
||||||
|
|
||||||
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
|
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
|
||||||
|
|
||||||
require (
|
require (
|
||||||
@@ -22,7 +21,7 @@ require (
|
|||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/docker/go-units v0.4.0 // indirect
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
github.com/frikky/kin-openapi v0.38.0
|
github.com/frikky/kin-openapi v0.38.0
|
||||||
github.com/frikky/shuffle-shared v0.0.38
|
github.com/frikky/shuffle-shared v0.0.39
|
||||||
github.com/ghodss/yaml v1.0.0
|
github.com/ghodss/yaml v1.0.0
|
||||||
github.com/go-git/go-billy/v5 v5.0.0
|
github.com/go-git/go-billy/v5 v5.0.0
|
||||||
github.com/go-git/go-git/v5 v5.0.0
|
github.com/go-git/go-git/v5 v5.0.0
|
||||||
|
|||||||
+1
-194
@@ -3932,199 +3932,6 @@ func handleSwaggerValidation(body []byte) (ParsedOpenApi, error) {
|
|||||||
return parsed, err
|
return parsed, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Migrate this to use handleSwaggerValidation()
|
|
||||||
func validateSwagger(resp http.ResponseWriter, request *http.Request) {
|
|
||||||
cors := handleCors(resp, request)
|
|
||||||
if cors {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just here to verify that the user is logged in
|
|
||||||
_, err := shuffle.HandleApiAuthentication(resp, request)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Api authentication failed in validate swagger: %s", err)
|
|
||||||
resp.WriteHeader(401)
|
|
||||||
resp.Write([]byte(`{"success": false}`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(request.Body)
|
|
||||||
if err != nil {
|
|
||||||
resp.WriteHeader(401)
|
|
||||||
resp.Write([]byte(`{"success": false, "reason": "Failed reading body"}`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type versionCheck struct {
|
|
||||||
Swagger string `datastore:"swagger" json:"swagger" yaml:"swagger"`
|
|
||||||
SwaggerVersion string `datastore:"swaggerVersion" json:"swaggerVersion" yaml:"swaggerVersion"`
|
|
||||||
OpenAPI string `datastore:"openapi" json:"openapi" yaml:"openapi"`
|
|
||||||
}
|
|
||||||
|
|
||||||
//body = []byte(`swagger: "2.0"`)
|
|
||||||
//body = []byte(`swagger: '1.0'`)
|
|
||||||
//newbody := string(body)
|
|
||||||
//newbody = strings.TrimSpace(newbody)
|
|
||||||
//body = []byte(newbody)
|
|
||||||
//log.Println(string(body))
|
|
||||||
//tmpbody, err := yaml.YAMLToJSON(body)
|
|
||||||
//log.Println(err)
|
|
||||||
//log.Println(string(tmpbody))
|
|
||||||
|
|
||||||
// This has to be done in a weird way because Datastore doesn't
|
|
||||||
// support map[string]interface and similar (openapi3.Swagger)
|
|
||||||
var version versionCheck
|
|
||||||
|
|
||||||
log.Printf("API length SET: %d", len(string(body)))
|
|
||||||
|
|
||||||
isJson := false
|
|
||||||
err = json.Unmarshal(body, &version)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Json err: %s", err)
|
|
||||||
err = yaml.Unmarshal(body, &version)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Yaml error (3): %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi to json and yaml. Is version defined?: %s"}`, err)))
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
log.Printf("[INFO] Successfully parsed YAML (3)!")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
isJson = true
|
|
||||||
log.Printf("[INFO] Successfully parsed JSON!")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(version.SwaggerVersion) > 0 && len(version.Swagger) == 0 {
|
|
||||||
version.Swagger = version.SwaggerVersion
|
|
||||||
}
|
|
||||||
log.Printf("[INFO] Version: %#v", version)
|
|
||||||
log.Printf("[INFO] OpenAPI: %s", version.OpenAPI)
|
|
||||||
|
|
||||||
if strings.HasPrefix(version.Swagger, "3.") || strings.HasPrefix(version.OpenAPI, "3.") {
|
|
||||||
log.Println("[INFO] Handling v3 API")
|
|
||||||
swaggerLoader := openapi3.NewSwaggerLoader()
|
|
||||||
swaggerLoader.IsExternalRefsAllowed = true
|
|
||||||
swagger, err := swaggerLoader.LoadSwaggerFromData(body)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[WARNING] Failed to convert v3 API: %s", err)
|
|
||||||
resp.WriteHeader(401)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hasher := md5.New()
|
|
||||||
hasher.Write(body)
|
|
||||||
idstring := hex.EncodeToString(hasher.Sum(nil))
|
|
||||||
|
|
||||||
log.Printf("Swagger v3 validation success with ID %s and %d paths!", idstring, len(swagger.Paths))
|
|
||||||
|
|
||||||
if !isJson {
|
|
||||||
log.Printf("[INFO] NEED TO TRANSFORM FROM YAML TO JSON for %s", idstring)
|
|
||||||
}
|
|
||||||
|
|
||||||
swaggerdata, err := json.Marshal(swagger)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed unmarshaling v3 data: %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling swaggerv3 data: %s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
parsed := ParsedOpenApi{
|
|
||||||
ID: idstring,
|
|
||||||
Body: string(swaggerdata),
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
err = setOpenApiDatastore(ctx, idstring, parsed)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed uploading openapi to datastore: %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[INFO] Successfully set OpenAPI with ID %s", idstring)
|
|
||||||
resp.WriteHeader(200)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, idstring)))
|
|
||||||
return
|
|
||||||
} else { //strings.HasPrefix(version.Swagger, "2.") || strings.HasPrefix(version.OpenAPI, "2.") {
|
|
||||||
// Convert
|
|
||||||
log.Println("Handling v2 API")
|
|
||||||
var swagger openapi2.Swagger
|
|
||||||
//log.Println(string(body))
|
|
||||||
err = json.Unmarshal(body, &swagger)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Json error for v2 - trying yaml: %s", err)
|
|
||||||
err = yaml.Unmarshal([]byte(body), &swagger)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Yaml error (4): %s", err)
|
|
||||||
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err)))
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
log.Printf("Found valid yaml!")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
swaggerv3, err := openapi2conv.ToV3Swagger(&swagger)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed converting from openapi2 to 3: %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed converting from openapi2 to openapi3: %s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
swaggerdata, err := json.Marshal(swaggerv3)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed unmarshaling v3 from v2 data: %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed marshalling swaggerv3 data: %s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hasher := md5.New()
|
|
||||||
hasher.Write(swaggerdata)
|
|
||||||
idstring := hex.EncodeToString(hasher.Sum(nil))
|
|
||||||
if !isJson {
|
|
||||||
log.Printf("FIXME: NEED TO TRANSFORM FROM YAML TO JSON for %s?", idstring)
|
|
||||||
}
|
|
||||||
log.Printf("Swagger v2 -> v3 validation success with ID %s!", idstring)
|
|
||||||
|
|
||||||
parsed := ParsedOpenApi{
|
|
||||||
ID: idstring,
|
|
||||||
Body: string(swaggerdata),
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.Background()
|
|
||||||
err = setOpenApiDatastore(ctx, idstring, parsed)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Failed uploading openapi2 to datastore: %s", err)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed reading openapi2: %s"}`, err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.WriteHeader(200)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "id": "%s"}`, idstring)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else {
|
|
||||||
log.Printf("Swagger / OpenAPI version %s is not supported or there is an error.", version.Swagger)
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Swagger version %s is not currently supported"}`, version.Swagger)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// save the openapi ID
|
|
||||||
resp.WriteHeader(422)
|
|
||||||
resp.Write([]byte(`{"success": false}`))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates an app from the app builder
|
// Creates an app from the app builder
|
||||||
func verifySwagger(resp http.ResponseWriter, request *http.Request) {
|
func verifySwagger(resp http.ResponseWriter, request *http.Request) {
|
||||||
cors := handleCors(resp, request)
|
cors := handleCors(resp, request)
|
||||||
@@ -6233,7 +6040,7 @@ func initHandlers() {
|
|||||||
r.HandleFunc("/api/v1/verify_swagger", verifySwagger).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/verify_swagger", verifySwagger).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/verify_openapi", verifySwagger).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/verify_openapi", verifySwagger).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/get_openapi_uri", echoOpenapiData).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/get_openapi_uri", echoOpenapiData).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/validate_openapi", validateSwagger).Methods("POST", "OPTIONS")
|
r.HandleFunc("/api/v1/validate_openapi", shuffle.ValidateSwagger).Methods("POST", "OPTIONS")
|
||||||
r.HandleFunc("/api/v1/get_openapi/{key}", getOpenapi).Methods("GET", "OPTIONS")
|
r.HandleFunc("/api/v1/get_openapi/{key}", getOpenapi).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
// NEW for 0.8.0
|
// NEW for 0.8.0
|
||||||
|
|||||||
@@ -1420,7 +1420,6 @@ const ParsedAction = (props) => {
|
|||||||
fullWidth
|
fullWidth
|
||||||
style={{backgroundColor: theme.palette.inputColor, color: "white", height: 50, borderRadius: theme.palette.borderRadius,}}
|
style={{backgroundColor: theme.palette.inputColor, color: "white", height: 50, borderRadius: theme.palette.borderRadius,}}
|
||||||
onChange={(event, newValue) => {
|
onChange={(event, newValue) => {
|
||||||
console.log("Changed to ", event.target, newValue)
|
|
||||||
// Workaround with event lol
|
// Workaround with event lol
|
||||||
setNewSelectedAction({"target": {"value": newValue.name}})
|
setNewSelectedAction({"target": {"value": newValue.name}})
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ const data = [{
|
|||||||
css: {
|
css: {
|
||||||
'shape': 'ellipse',
|
'shape': 'ellipse',
|
||||||
'border-color': '#80deea',
|
'border-color': '#80deea',
|
||||||
'width': '12px',
|
'width': '5px',
|
||||||
'height': '12px',
|
'height': '5px',
|
||||||
'z-index': '5002',
|
'z-index': '5002',
|
||||||
'font-size': '10px',
|
'font-size': '10px',
|
||||||
'text-valign': 'center',
|
'text-valign': 'center',
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ function removeParam(key, sourceURL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const splitter = "|~|"
|
const splitter = "|~|"
|
||||||
|
const svgSize = 24
|
||||||
//const referenceUrl = "https://shuffler.io/functions/webhooks/"
|
//const referenceUrl = "https://shuffler.io/functions/webhooks/"
|
||||||
//const referenceUrl = window.location.origin+"/api/v1/hooks/"
|
//const referenceUrl = window.location.origin+"/api/v1/hooks/"
|
||||||
|
|
||||||
@@ -1368,7 +1369,7 @@ const AngularWorkflow = (props) => {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
console.log("Node wasn't found")
|
console.log("Node wasn't found")
|
||||||
const iconInfo = GetIconInfo(nodedata)
|
const iconInfo = GetIconInfo(nodedata)
|
||||||
const svg_pin = `<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
const svg_pin = `<svg width="${svgSize}" height="${svgSize}" viewBox="0 0 ${svgSize} ${svgSize}" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
||||||
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
||||||
|
|
||||||
const offset = nodedata.isStartNode ? 36 : 44
|
const offset = nodedata.isStartNode ? 36 : 44
|
||||||
@@ -2264,7 +2265,7 @@ const AngularWorkflow = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const iconInfo = GetIconInfo(action)
|
const iconInfo = GetIconInfo(action)
|
||||||
const svg_pin = `<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
const svg_pin = `<svg width="${svgSize}" height="${svgSize}" viewBox="0 0 ${svgSize} ${svgSize}" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
||||||
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
||||||
|
|
||||||
const offset = action.isStartNode ? 36 : 44
|
const offset = action.isStartNode ? 36 : 44
|
||||||
@@ -2428,7 +2429,12 @@ const AngularWorkflow = (props) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedNode.remove()
|
if (selectedNode.data().decorator === true) {
|
||||||
|
alert.info("This edge can't be deleted.")
|
||||||
|
} else {
|
||||||
|
selectedNode.remove()
|
||||||
|
}
|
||||||
|
|
||||||
setSelectedTrigger({})
|
setSelectedTrigger({})
|
||||||
setSelectedTriggerIndex({})
|
setSelectedTriggerIndex({})
|
||||||
}
|
}
|
||||||
@@ -3430,7 +3436,7 @@ const AngularWorkflow = (props) => {
|
|||||||
const foundnode = cy.getElementById(currentNode.data.id)
|
const foundnode = cy.getElementById(currentNode.data.id)
|
||||||
if (foundnode !== null && foundnode !== undefined) {
|
if (foundnode !== null && foundnode !== undefined) {
|
||||||
const iconInfo = GetIconInfo(newaction)
|
const iconInfo = GetIconInfo(newaction)
|
||||||
const svg_pin = `<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
const svg_pin = `<svg width="${svgSize}" height="${svgSize}" viewBox="0 0 ${svgSize} ${svgSize}" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="${iconInfo.icon}" fill="${iconInfo.iconColor}"></path></svg>`
|
||||||
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin)
|
||||||
foundnode.data("image", svgpin_Url)
|
foundnode.data("image", svgpin_Url)
|
||||||
foundnode.data("imageColor", iconInfo.iconBackgroundColor)
|
foundnode.data("imageColor", iconInfo.iconBackgroundColor)
|
||||||
|
|||||||
@@ -81,15 +81,15 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
export const GetIconInfo = (action) => {
|
export const GetIconInfo = (action) => {
|
||||||
// Finds the icon based on the action. Should be verbs.
|
// Finds the icon based on the action. Should be verbs.
|
||||||
const iconList = [
|
const iconList = [
|
||||||
{"key": "download", "values": ["get", "download"]},
|
{"key": "download", "values": ["get", "download", "return", "hello world"]},
|
||||||
{"key": "search", "values": ["search", "find"]},
|
{"key": "search", "values": ["search", "find"]},
|
||||||
{"key": "delete", "values": ["delete", "remove"]},
|
{"key": "delete", "values": ["delete", "remove"]},
|
||||||
{"key": "send", "values": ["send", "dispatch", "mail", "forward", "post", "submit"]},
|
{"key": "send", "values": ["send", "dispatch", "mail", "forward", "post", "submit"]},
|
||||||
{"key": "repeat", "values": ["repeat", "retry"]},
|
{"key": "repeat", "values": ["repeat", "retry", "pause",]},
|
||||||
{"key": "execute", "values": ["execute", "run", "play"]},
|
{"key": "execute", "values": ["execute", "run", "play", "raise",]},
|
||||||
{"key": "extract", "values": ["extract", "unpack", "decompress"]},
|
{"key": "extract", "values": ["extract", "unpack", "decompress"]},
|
||||||
{"key": "inflate", "values": ["inflate", "pack", "compress",]},
|
{"key": "inflate", "values": ["inflate", "pack", "compress",]},
|
||||||
{"key": "edit", "values": ["update", "edit", "put", "patch", "change", "parse", "replace", "filter", "conver", "map"]},
|
{"key": "edit", "values": ["update", "create", "edit", "put", "patch", "change", "parse", "replace", "filter", "conver", "map"]},
|
||||||
{"key": "compare", "values": ["compare", "convert", "to", "filter", "translate", ]},
|
{"key": "compare", "values": ["compare", "convert", "to", "filter", "translate", ]},
|
||||||
{"key": "list", "values": ["list"]},
|
{"key": "list", "values": ["list"]},
|
||||||
]
|
]
|
||||||
@@ -480,7 +480,7 @@ const Workflows = (props) => {
|
|||||||
const ret = setNewWorkflow(data.name, data.description, data.tags, data, false)
|
const ret = setNewWorkflow(data.name, data.description, data.tags, data, false)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response !== undefined) {
|
if (response !== undefined) {
|
||||||
alert.success("Successfully imported "+data.name)
|
alert.success(`Successfully imported ${data.name}`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user