#165: Fixed app deletion frontend bug

This commit is contained in:
frikky
2020-10-14 11:39:06 +02:00
parent c0474d400a
commit c622788472
5 changed files with 103 additions and 33 deletions
+21
View File
@@ -6811,11 +6811,32 @@ 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() {
var err error
+21 -4
View File
@@ -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") {
+1 -2
View File
@@ -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 = ""
+28 -9
View File
@@ -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>
{/*
+23 -9
View File
@@ -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()