#165: Fixed app deletion frontend bug
This commit is contained in:
@@ -6811,10 +6811,31 @@ func handleCloudSetup(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
type responseStruct struct {
|
||||
Success bool `json:"success"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
log.Printf("Respbody: %s", string(respBody))
|
||||
|
||||
responseData := responseStruct{}
|
||||
err = json.Unmarshal(respBody, &responseData)
|
||||
if err != nil {
|
||||
resp.WriteHeader(500)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed handling cloud data"`)))
|
||||
return
|
||||
}
|
||||
|
||||
if responseData.Success {
|
||||
resp.WriteHeader(200)
|
||||
if len(responseData.Reason) > 0 {
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "reason": "%s"}`, responseData.Reason)))
|
||||
} else {
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true}`)))
|
||||
}
|
||||
} else {
|
||||
resp.WriteHeader(400)
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "%s"}`, responseData.Reason)))
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -66,6 +66,18 @@ type ExecutionRequest struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type SyncFeatures struct {
|
||||
Apps SyncData `json:"apps" datastore:"apps"`
|
||||
Workflows SyncData `json:"apps" datastore:"apps"`
|
||||
Schedules SyncData `json:"apps" datastore:"apps"`
|
||||
Autocomplete SyncData `json:"apps" datastore:"apps"`
|
||||
Authentication SyncData `json:"apps" datastore:"apps"`
|
||||
}
|
||||
|
||||
type SyncData struct {
|
||||
Active bool `json:"active" datastore:"active"`
|
||||
}
|
||||
|
||||
// Role is just used for feedback for a user
|
||||
type Org struct {
|
||||
Name string `json:"name" datastore:"name"`
|
||||
@@ -75,6 +87,7 @@ type Org struct {
|
||||
Role string `json:"role" datastore:"role"`
|
||||
Roles []string `json:"roles" datastore:"roles"`
|
||||
CloudSync bool `json:"cloud_sync" datastore:"CloudSync"`
|
||||
SyncFeatures SyncFeatures `json:"sync_features" datastore:"sync_features"`
|
||||
}
|
||||
|
||||
type AppAuthenticationStorage struct {
|
||||
@@ -1148,8 +1161,8 @@ func JSONCheck(str string) bool {
|
||||
}
|
||||
|
||||
func handleExecutionStatistics(execution WorkflowExecution) {
|
||||
// FIXME: CLEAN UP THE JSON THAT'S SAVED!
|
||||
|
||||
// FIXME: CLEAN UP THE JSON THAT'S SAVED.
|
||||
// https://github.com/frikky/Shuffle/issues/172
|
||||
appResults := []AppExecutionExample{}
|
||||
for _, result := range execution.Results {
|
||||
resultCheck := JSONCheck(result.Result)
|
||||
@@ -3403,6 +3416,7 @@ func deleteAppAuthentication(resp http.ResponseWriter, request *http.Request) {
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
}
|
||||
|
||||
// FIXME: Not suitable for cloud right now :O
|
||||
func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
cors := handleCors(resp, request)
|
||||
if cors {
|
||||
@@ -3443,7 +3457,7 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
// FIXME - check whether it's in use and maybe restrict again for later?
|
||||
// FIXME - actually delete other than private apps too..
|
||||
private := false
|
||||
if app.Downloaded {
|
||||
if app.Downloaded && user.Role == "admin" {
|
||||
log.Printf("Deleting downloaded app (authenticated users can do this)")
|
||||
} else if user.Id != app.Owner && user.Role != "admin" {
|
||||
log.Printf("Wrong user (%s) for app %s (delete)", user.Username, app.Name)
|
||||
@@ -3463,6 +3477,8 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Finds workflows using the app to set errors
|
||||
// FIXME: this will be WAY too big for cloud :O
|
||||
for _, workflow := range workflows {
|
||||
found := false
|
||||
|
||||
@@ -3483,7 +3499,8 @@ func deleteWorkflowApp(resp http.ResponseWriter, request *http.Request) {
|
||||
workflow.Actions = newActions
|
||||
|
||||
for _, trigger := range workflow.Triggers {
|
||||
log.Printf("TRIGGER: %#v", trigger)
|
||||
_ = trigger
|
||||
//log.Printf("TRIGGER: %#v", trigger)
|
||||
//err = deleteSchedule(ctx, scheduleId)
|
||||
//if err != nil {
|
||||
// if strings.Contains(err.Error(), "Job not found") {
|
||||
|
||||
@@ -2611,7 +2611,7 @@ const AngularWorkflow = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (curstring.length > 0) {
|
||||
if (curstring.length > 0 && actionlist !== null) {
|
||||
// Search back in the action list
|
||||
curstring = curstring.split(" ").join("_").toLowerCase()
|
||||
var actionItem = actionlist.find(data => data.autocomplete.split(" ").join("_").toLowerCase() === curstring)
|
||||
@@ -3794,7 +3794,6 @@ const AngularWorkflow = (props) => {
|
||||
// Uses the target's parents, as the target should be executing the checks (I think)
|
||||
var parents = getParents(workflow.actions.find(a => a.id === selectedEdge["target"]))
|
||||
if (parents.length > 0) {
|
||||
console.log(parents)
|
||||
data.action_field = parents[0].label
|
||||
} else {
|
||||
data.action_field = ""
|
||||
|
||||
@@ -1079,19 +1079,29 @@ const AppCreator = (props) => {
|
||||
:
|
||||
<div>
|
||||
{actions.map((data, index) => {
|
||||
var error = <Tooltip color="secondary" title={data.errors.join("\n")} placement="bottom">
|
||||
<CheckCircleIcon />
|
||||
</Tooltip>
|
||||
|
||||
// "ERROR: "+data.errors.join("\n")
|
||||
if (data.errors.length > 0) {
|
||||
error =
|
||||
var error = data.errors.length > 0 ?
|
||||
<Tooltip color="primary" title={data.errors.join("\n")} placement="bottom">
|
||||
<ErrorOutline />
|
||||
</Tooltip>
|
||||
}
|
||||
:
|
||||
<Tooltip color="secondary" title={data.errors.join("\n")} placement="bottom">
|
||||
<CheckCircleIcon />
|
||||
</Tooltip>
|
||||
|
||||
|
||||
var bgColor = "#61afee"
|
||||
if (data.method === "POST") {
|
||||
bgColor = "#49cc90"
|
||||
} else if (data.method === "PUT") {
|
||||
bgColor = "#fca130"
|
||||
} else if (data.method === "PATCH") {
|
||||
bgColor = "#50e3c2"
|
||||
} else if (data.method === "DELETE") {
|
||||
bgColor = "#f93e3e"
|
||||
} else if (data.method === "HEAD") {
|
||||
bgColor = "#9012fe"
|
||||
}
|
||||
|
||||
const url = data.url
|
||||
return (
|
||||
<Paper style={actionListStyle}>
|
||||
@@ -1104,7 +1114,16 @@ const AppCreator = (props) => {
|
||||
setUrlPath(data.url)
|
||||
setActionsModalOpen(true)
|
||||
}}>
|
||||
{data.method} - {url} - {data.name}
|
||||
<div style={{display: "flex"}}>
|
||||
<Chip
|
||||
style={{backgroundColor: bgColor, color: "white", borderRadius: 5, minWidth: 80, marginRight: 10, marginTop: 2, cursor: "pointer", fontSize: 14,}}
|
||||
label={data.method}
|
||||
variant="contained"
|
||||
/>
|
||||
<span style={{fontSize: 16, marginTop: "auto", marginBottom: "auto",}}>
|
||||
{url} - {data.name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</Tooltip>
|
||||
{/*
|
||||
|
||||
@@ -183,6 +183,8 @@ const Apps = (props) => {
|
||||
maxHeight: 130,
|
||||
minWidth: "100%",
|
||||
maxWidth: "100%",
|
||||
marginBottom: 5,
|
||||
borderRadius: 5,
|
||||
color: "white",
|
||||
backgroundColor: surfaceColor,
|
||||
cursor: "pointer",
|
||||
@@ -295,6 +297,10 @@ const Apps = (props) => {
|
||||
boxColor = "green"
|
||||
}
|
||||
|
||||
if (!data.activated && data.generated) {
|
||||
boxColor = "orange"
|
||||
}
|
||||
|
||||
var imageline = data.large_image.length === 0 ?
|
||||
<img alt={data.title} style={{width: 100, height: 100}} />
|
||||
:
|
||||
@@ -325,6 +331,7 @@ const Apps = (props) => {
|
||||
description = data.description.slice(0, maxDescLen)+"..."
|
||||
}
|
||||
|
||||
const version = data.app_version
|
||||
return (
|
||||
<Paper square key={data.id} style={paperAppStyle} onClick={() => {
|
||||
if (selectedApp.id !== data.id) {
|
||||
@@ -337,7 +344,6 @@ const Apps = (props) => {
|
||||
setSelectedAction({})
|
||||
}
|
||||
|
||||
console.log("Sharing: ", data.sharing_config)
|
||||
if (data.sharing) {
|
||||
setSharingConfiguration("everyone")
|
||||
}
|
||||
@@ -393,9 +399,10 @@ const Apps = (props) => {
|
||||
|
||||
const dividerColor = "rgb(225, 228, 232)"
|
||||
const uploadViewPaperStyle = {
|
||||
minWidth: "100%",
|
||||
minWidth: 662.5,
|
||||
maxWidth: 662.5,
|
||||
color: "white",
|
||||
borderRadius: 5,
|
||||
backgroundColor: surfaceColor,
|
||||
display: "flex",
|
||||
marginBottom: 10,
|
||||
@@ -448,7 +455,7 @@ const Apps = (props) => {
|
||||
</Tooltip>
|
||||
</Link> : null
|
||||
|
||||
var activateButton = selectedApp.generated && !selectedApp.activated ?
|
||||
const activateButton = selectedApp.generated && !selectedApp.activated ?
|
||||
<div>
|
||||
<Link to={activateUrl} style={{textDecoration: "none"}}>
|
||||
<Button
|
||||
@@ -476,7 +483,12 @@ const Apps = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
var deleteButton = ((selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated) || (selectedApp.downloaded != undefined && selectedApp.downloaded == true)) && activateButton === null ?
|
||||
const deleteButton = (
|
||||
(selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated)
|
||||
|| (selectedApp.downloaded !== undefined && selectedApp.downloaded == true)
|
||||
|| (!selectedApp.generated)
|
||||
)
|
||||
&& activateButton === null ?
|
||||
<Tooltip title={"Delete app"}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
@@ -525,10 +537,10 @@ const Apps = (props) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
{paths.map(data => {
|
||||
{paths.map((data, index) => {
|
||||
const circleSize = 10
|
||||
return (
|
||||
<MenuItem style={{backgroundColor: inputColor, color: "white"}} value={data} onClick={() => console.log(data.autocomplete)}>
|
||||
<MenuItem key={index} style={{backgroundColor: inputColor, color: "white"}} value={data} onClick={() => console.log(data.autocomplete)}>
|
||||
{data.name}
|
||||
</MenuItem>
|
||||
)
|
||||
@@ -567,12 +579,13 @@ const Apps = (props) => {
|
||||
{imageline}
|
||||
</div>
|
||||
<div style={{maxWidth: "75%", overflow: "hidden"}}>
|
||||
<h2>{newAppname}</h2>
|
||||
<p>{description}</p>
|
||||
<h2 style={{marginTop: 20, marginBottom: 0, }}>{newAppname}</h2>
|
||||
<p style={{marginTop: 5, marginBottom: 0,}}>Version {selectedApp.app_version}</p>
|
||||
<p style={{marginTop: 5, marginBottom: 0}}>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
{activateButton}
|
||||
{props.userdata.role === "admin" || props.userdata.id === selectedApp.owner ?
|
||||
{(props.userdata.role === "admin" || props.userdata.id === selectedApp.owner) || !selectedApp.generated ?
|
||||
<div>
|
||||
{downloadButton}
|
||||
{editButton}
|
||||
@@ -957,6 +970,7 @@ const Apps = (props) => {
|
||||
setIsLoading(false)
|
||||
if (response.status === 200) {
|
||||
alert.success("Hotloaded apps!")
|
||||
getApps()
|
||||
}
|
||||
|
||||
return response.json()
|
||||
|
||||
Reference in New Issue
Block a user