#124: Frontend changes for latest issues with notifications

This commit is contained in:
frikky
2021-10-05 22:01:54 +02:00
parent 2842b04a69
commit 030adab327
9 changed files with 165 additions and 183 deletions
+9 -7
View File
@@ -1,16 +1,18 @@
FROM python:3.9.1-alpine as base
FROM base as builder
RUN apk --no-cache add --update alpine-sdk libffi libffi-dev musl-dev openssl-dev tzdata
RUN mkdir /install
WORKDIR /install
COPY requirements.txt /requirements.txt
RUN pip3 install --prefix="/install" -r /requirements.txt
FROM base
COPY --from=builder /install /usr/local
WORKDIR /app
COPY sub.py /app/sub.py
CMD python sub.py
#--no-cache
RUN apk update && apk add --update tzdata libmagic alpine-sdk libffi libffi-dev musl-dev openssl-dev
COPY --from=builder /install /usr/local
COPY requirements.txt /requirements.txt
RUN pip3 install -r /requirements.txt
COPY __init__.py /app/walkoff_app_sdk/__init__.py
COPY app_base.py /app/walkoff_app_sdk/app_base.py
+72 -154
View File
@@ -30,6 +30,7 @@ class AppBase:
self.url = os.getenv("CALLBACK_URL", "https://shuffler.io")
self.base_url = os.getenv("BASE_URL", "https://shuffler.io")
self.action = os.getenv("ACTION", "")
self.original_action = os.getenv("ACTION", "")
self.authorization = os.getenv("AUTHORIZATION", "")
self.current_execution_id = os.getenv("EXECUTIONID", "")
self.full_execution = os.getenv("FULL_EXECUTION", "")
@@ -49,6 +50,7 @@ class AppBase:
if isinstance(self.action, str):
try:
self.action = json.loads(self.action)
self.original_action = json.loads(self.action)
except:
print("[WARNING] Failed parsing action as JSON")
@@ -162,7 +164,7 @@ class AppBase:
except (KeyError, NameError) as e:
print(f"""Key/NameError in param handler for {param["name"]}: {e}""")
print(f"OUTER VALUE: {param_value}")
print(f"[DEBUG] OUTER VALUE: {param_value}")
if len(param_value) > 0:
md5 = hashlib.md5(param_value.encode('utf-8')).hexdigest()
values.append(md5)
@@ -296,7 +298,7 @@ class AppBase:
#print(f"Baseparams to check!!: {baseparams}")
for key, value in baseparams.items():
check_value = ""
for param in self.action["parameters"]:
for param in self.original_action["parameters"]:
if param["name"] == key:
#print("PARAM: %s" % param)
check_value = param["value"]
@@ -343,7 +345,7 @@ class AppBase:
# Specific for OpenAPI body replacement
#print("\n\n\nDOING STUFF BELOW HERE")
if not should_merge:
for parameter in self.action["parameters"]:
for parameter in self.original_action["parameters"]:
if parameter["name"] == key:
#print("CHECKING BODY FOR VALUE REPLACE DATA!")
try:
@@ -359,7 +361,7 @@ class AppBase:
#print(f"MERGE: {should_merge}")
if isinstance(value, list):
print("Item {value} is a list.")
print(f"[DEBUG] Item {value} is a list.")
if len(value) <= 1:
if len(value) == 1:
baseparams[key] = value[0]
@@ -368,7 +370,7 @@ class AppBase:
# should_merge = True
else:
if not should_merge:
print("Adding WITHOUT looping list")
print("[DEBUG] Adding WITHOUT looping list")
else:
if len(value) not in listlengths:
listlengths.append(len(value))
@@ -385,38 +387,38 @@ class AppBase:
#print(f"{value} is not a list")
pass
print("Listlengths: %s" % listlengths)
print("[DEBUG] Listlengths: %s" % listlengths)
if len(listlengths) == 0:
print("NO multiplier. Running a single iteration.")
print("[DEBUG] NO multiplier. Running a single iteration.")
paramlist.append(baseparams)
elif len(listlengths) == 1:
print("NO MULTIPLIER NECESSARY. Length is %d" % len(listitems))
print("[DEBUG] NO MULTIPLIER NECESSARY. Length is %d" % len(listitems))
for item in listitems:
# This loops should always be length 1
for key, value in item.items():
if isinstance(value, int):
print("\nShould run key %s %d times from %s" % (key, value, baseparams[key]))
print("\n[DEBUG] Should run key %s %d times from %s" % (key, value, baseparams[key]))
if len(paramlist) == value:
print("List ALREADY exists - just changing values")
print("[DEBUG] List ALREADY exists - just changing values")
for subloop in range(value):
baseitem = copy.deepcopy(baseparams)
paramlist[subloop][key] = baseparams[key][subloop]
else:
print("List DOESNT exist - ADDING values")
print("[DEBUG] List DOESNT exist - ADDING values")
for subloop in range(value):
baseitem = copy.deepcopy(baseparams)
baseitem[key] = baseparams[key][subloop]
paramlist.append(baseitem)
else:
print("Multipliers to handle: %s" % listitems)
print("[DEBUG] Multipliers to handle: %s" % listitems)
newlength = 1
for item in listitems:
for key, value in item.items():
newlength = newlength * value
print("Newlength of array: %d. Lists: %s" % (newlength, all_lists))
print("[DEBUG] Newlength of array: %d. Lists: %s" % (newlength, all_lists))
# Get the cartesian product of the arrays
cartesian = await self.cartesian_product(all_lists)
newlist = []
@@ -454,7 +456,7 @@ class AppBase:
newparams = {}
for key, value in baseparams.items():
if isinstance(value, list) and len(value) > 0:
print(f"In list check for {key}")
print(f"[DEBUG] In list check for {key}")
try:
# Added skip for body (OpenAPI) which uses data= in requests
@@ -462,33 +464,36 @@ class AppBase:
if key != "body":
value[0] = json.loads(value[0])
except json.decoder.JSONDecodeError as e:
print("JSON casting error: %s" % e)
print("[WARNING] JSON casting error (1): %s" % e)
except TypeError as e:
print("TypeError: %s" % e)
print("[WARNING] TypeError: %s" % e)
print("POST initial list check")
print("[DEBUG] POST initial list check")
if isinstance(value, list) and len(value) == 1 and isinstance(value[0], list):
try:
loop_wrapper[key] += 1
except IndexError:
loop_wrapper[key] = 1
except KeyError:
loop_wrapper[key] = 1
try:
if isinstance(value, list) and len(value) == 1 and isinstance(value[0], list):
try:
loop_wrapper[key] += 1
except Exception as e:
print("[WARNING] Exception in loop wrapper: {e}")
loop_wrapper[key] = 1
print(f"Key {key} is a list: {value}")
newparams[key] = value[0]
has_loop = True
else:
#print(f"Key {key} is NOT a list within a list. Value: {value}")
print(f"[DEBUG] Key {key} is a list: {value}")
newparams[key] = value[0]
has_loop = True
else:
#print(f"Key {key} is NOT a list within a list. Value: {value}")
newparams[key] = value
except Exception as e:
print(f"[WARNING] Error in baseparams list: {e}")
newparams[key] = value
results = []
if has_loop:
print("[WARNING] Should run inner loop: %s" % newparams)
print(f"[DEBUG] Should run inner loop: {newparams}")
ret = await self.run_recursed_items(func, newparams, loop_wrapper)
else:
#print("[INFO] Should run multiplier check with params (inner): %s" % newparams)
print(f"[DEBUG] Should run multiplier check with params (inner): {newparams}")
# 1. Find the loops that are required and create new multipliers
# If here: check for multipliers within this scope.
ret = []
@@ -592,10 +597,10 @@ class AppBase:
#else:
ret.append(new_value)
print("Ret length: %d" % len(ret))
print("[INFO] Ret length: %d" % len(ret))
if len(ret) == 1:
#ret = ret[0]
print("DONT make list of 1 into 0!!")
print("[DEBUG] DONT make list of 1 into 0!!")
print("Return from execution: %s" % ret)
if ret == None:
@@ -909,7 +914,7 @@ class AppBase:
# If found, we get the full results list from backend
fullexecution = {}
if len(self.full_execution) == 0:
print("NO EXECUTION - LOADING!")
print("[DEBUG] NO EXECUTION - LOADING!")
try:
tmpdata = {
"authorization": self.authorization,
@@ -944,7 +949,7 @@ class AppBase:
try:
fullexecution = json.loads(self.full_execution)
except json.decoder.JSONDecodeError as e:
print("Json decode execution error: %s" % e)
print("[WARNING] Json decode execution error: %s" % e)
self.action_result["result"] = "Json error during startup: %s" % e
self.send_result(self.action_result, headers, stream_path)
return
@@ -1011,8 +1016,9 @@ class AppBase:
try:
return int(data)
except ValueError:
print("ValueError while casting %s to int" % data)
print("[DEBUG] ValueError while casting %s to int" % data)
return data
if "lower" in thistype:
return data.lower()
if "upper" in thistype:
@@ -1156,8 +1162,8 @@ class AppBase:
inner_value = parse_nested_param(data, maxDepth(data) - 0)
outer_value = parse_nested_param(data, maxDepth(data) - 1)
print("INNER: ", inner_value)
print("OUTER: ", outer_value)
#print("[DEBUG] INNER: ", inner_value)
#print("[DEBUG] OUTER: ", outer_value)
wrapper_group = "|".join(wrappers)
parse_string = data
@@ -1336,7 +1342,7 @@ class AppBase:
newvalue = []
firstitem = actualitem[0][0]
seconditem = actualitem[0][1]
print("ACTUAL PARSED: %s" % actualitem)
print("[DEBUG] ACTUAL PARSED: %s" % actualitem)
# Means it's a single item -> continue
if seconditem == "":
@@ -1348,7 +1354,7 @@ class AppBase:
else:
firstitem = int(firstitem)
#print("Post lower checks")
print(f"[DEBUG] Post lower checks with item {firstitem}")
tmpitem = basejson[int(firstitem)]
try:
newvalue, is_loop = recurse_json(tmpitem, parsersplit[outercnt+1:])
@@ -1370,7 +1376,7 @@ class AppBase:
else:
seconditem = int(seconditem)
print("Post lower checks")
print(f"[DEBUG] Post lower checks 2: {firstitem} AND {seconditem}")
newvalue = []
if int(seconditem) > len(basejson):
seconditem = len(basejson)
@@ -1383,7 +1389,7 @@ class AppBase:
try:
ret, tmp_loop = recurse_json(basejson[i], parsersplit[outercnt+1:])
except IndexError:
print("INDEXERROR: ", parsersplit[outercnt])
print("[DEBUG] INDEXERROR: ", parsersplit[outercnt])
#ret = innervalue
ret, tmp_loop = recurse_json(innervalue, parsersplit[outercnt:])
@@ -1404,12 +1410,12 @@ class AppBase:
print("[WARNING] VALUE IN ISINSTANCE IS NOT TO BE USED (list): %s" % value)
return basejson, False
elif isinstance(basejson[value], str):
print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
#print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
try:
basejson = json.loads(basejson[value])
print("BASEJSON: %s" % basejson)
#print("[DEBUG] BASEJSON: %s" % basejson)
except json.decoder.JSONDecodeError as e:
print("RETURNING BECAUSE '%s' IS A NORMAL STRING (0)" % basejson[value])
#print("[DEBUG] RETURNING BECAUSE '%s' IS A NORMAL STRING (0)" % basejson[value])
return basejson[value], False
else:
basejson = basejson[value]
@@ -1427,9 +1433,9 @@ class AppBase:
print(f"[INFO] LOADING STRING '%s' AS JSON" % basejson[value])
try:
basejson = json.loads(basejson[value])
print("BASEJSON: %s" % basejson)
print("[DEBUG] BASEJSON: %s" % basejson)
except json.decoder.JSONDecodeError as e:
print("RETURNING BECAUSE '%s' IS A NORMAL STRING (1)" % basejson[value])
print("[DEBUG] RETURNING BECAUSE '%s' IS A NORMAL STRING (1)" % basejson[value])
return basejson[value], False
else:
basejson = basejson[value]
@@ -1539,7 +1545,7 @@ class AppBase:
pass
except KeyError as error:
print(f"KeyError in JSON: {error}")
print(f"[DEBUG] KeyError in JSON: {error}")
print(f"[INFO] After first trycatch. Baseresult")#, baseresult)
@@ -1603,12 +1609,13 @@ class AppBase:
print("Error in decoder: %s" % e)
return returndata, is_loop
# Sending self as it's not a normal function
def parse_liquid(template, self):
#print("Inside liquid with glob: %s" % globals())
try:
if len(template) > 5000000:
print("Skipping liquid - size is %d" % len(template))
print("[DEBUG] Skipping liquid - size too big (%d)" % len(template))
return template
#if not "{{" in template or not "}}" in template:
@@ -1620,7 +1627,7 @@ class AppBase:
# return template
#print(globals())
print("Running liquid with data of length %d" % len(template))
print("[DEBUG] Running liquid with data of length %d" % len(template))
run = Liquid(template, mode="wild", from_file=False)
# Can't handle self yet (?)
@@ -2074,7 +2081,7 @@ class AppBase:
# Checks whether conditions are met, otherwise set
branchcheck, tmpresult = check_branch_conditions(action, fullexecution, self)
if isinstance(tmpresult, object) or isinstance(tmpresult, list):
print("Fixing branch return as object -> string")
print("[DEBUG] Fixing branch return as object -> string")
try:
#tmpresult = tmpresult.replace("'", "\"")
tmpresult = json.dumps(tmpresult)
@@ -2093,7 +2100,7 @@ class AppBase:
except requests.exceptions.ConnectionError as e:
self.logger.exception(e)
print("\n\nRETURNING BECAUSE A BRANCH FAILED: %s\n\n" % tmpresult)
print("\n\n[DEBUG] RETURNING BECAUSE A BRANCH FAILED: %s\n\n" % tmpresult)
return
# Replace name cus there might be issues
@@ -2130,7 +2137,7 @@ class AppBase:
#print("AUTH: ", key, value)
params[item["key"]] = item["value"]
except KeyError:
print("No authentication specified!")
print("[DEBUG] No authentication specified!")
pass
#action["authentication"]
@@ -2195,50 +2202,6 @@ class AppBase:
print(f"""HANDLING {action["parameters"][counter]["value"]}""")
action["parameters"][counter]["value"] = recurse_cleanup_script(action["parameters"][counter]["value"])
#try:
# newvalue = json.loads(action["parameters"][counter]["value"])
# deletekeys = []
# for key, value in newvalue.items():
# print("%s: %s" % (key, value))
# if isinstance(value, str) and len(value) == 0:
# deletekeys.append(key)
# continue
# if value == "${%s}" % key:
# print("Deleting %s because key = value" % key)
# deletekeys.append(key)
# continue
#
# for deletekey in deletekeys:
# try:
# del newvalue[deletekey]
# except:
# pass
# #print("Post delete: %s" % newvalue)
# for key, value in newvalue.items():
# if isinstance(value, bool):
# continue
# try:
# value = json.loads(value)
# newvalue[key] = value
# except json.decoder.JSONDecodeError as e:
# print("Inner overwrite issue: %s" % e)
# continue
# except Exception as e:
# print("General error in newvalue items loop: %s" % e)
# continue
# try:
# action["parameters"][counter]["value"] = json.dumps(newvalue)
# except json.decoder.JSONDecodeError as e:
# print("[WARNING] JsonDecodeError: %s" % e)
# action["parameters"][counter]["value"] = newvalue
#
#except json.decoder.JSONDecodeError as e:
# print("Failed JSON replacement for OpenAPI keys (2) {e}")
#print(action["parameters"])
@@ -2249,6 +2212,12 @@ class AppBase:
self.action = action
# Setting due to them being overwritten, but still later useful
try:
self.original_action = json.loads(json.dumps(action))
except Exception as e:
print(f"[ERROR] Failed parsing action as JSON to original action. This COULD have bad effects on LOOPED executions: {e}")
# calltimes is used to handle forloops in the app itself.
# 2 kinds of loop - one in gui with one app each, and one like this,
# which is super fast, but has a bad overview (potentially good tho)
@@ -2409,6 +2378,7 @@ class AppBase:
actualitem = actualitem[:-2]
except IndexError:
print("[WARNING] Indexerror")
continue
#print(f"\n\nTMPITEM: {actualitem}\n\n")
@@ -2488,65 +2458,13 @@ class AppBase:
multi_execution_lists.append(resultarray)
multi_parameters[parameter["name"]] = resultarray
#if parameter["id"] == "body_replacement":
# print("Should run body MULTI replacement in index %d with %s" % (bodyindex, parameter))
# try:
# print("PREBODY: %s" % params["body"])
# parsedarray = str(resultarray)
# try:
# parsedarray = json.dumps(resultarray)
# except:
# pass
# if f'\"{parameter["name"]}\"' in params["body"]:
# params["body"] = params["body"].replace(f'\"{parameter["name"]}\"' , parsedarray, -1)
# multi_parameters["body"] = multi_parameters["body"].replace(f'\"{parameter["name"]}\"' , parsedarray, -1)
# else:
# params["body"] = params["body"].replace(parameter["name"], parsedarray, -1)
# multi_parameters["body"] = multi_parameters["body"].replace(parameter["name"], parsedarray, -1)
# #print("POSTBODY: %s" % params["body"])
# #if isinstance(multi_parameters, list):
# # print("MULTIPARAM AS LIST (NOT REPLACING!!)!")
# # for multiparam in multi_parameters:
# # print(f"MULTIPARAM: {multiparam}")
# # #multi_parameters["body"] = multi_parameters["body"].replace(parameter["name"], str(parameter["value"]), -1)
# #else:
# except KeyError as e:
# print("KEYERROR: %s" % e)
# remove_params.append(parameter["name"])
# #bodyindex = counter
# continue
else:
# Parses things like int(value)
print("Normal parsing (not looping)")#with data %s" % value)
print("[DEBUG] Normal parsing (not looping)")#with data %s" % value)
# This part has fucked over so many random JSON usages because of weird paranthesis parsing
value = parse_wrapper_start(value, self)
print("Post return: %s" % value)
#if parameter["id"] == "body_replacement":
# print("Should run body replacement in index %d with %s" % (bodyindex, parameter))
# try:
# print("PREBODY: %s" % params["body"])
# params["body"] = params["body"].replace(parameter["name"], parameter["value"], -1)
# print("POSTBODY: %s" % params["body"])
# except KeyError as e:
# print("KEYERROR: %s" % e)
# #bodyindex = counter
# continue
#for parameter in action["parameters"]:
#if parameter["name"] == "body":
# print("PARAM: %s" % parameter)
#if param.id == "body_replacement":
print("[DEBUG] Post return: %s" % value)
#print("POST data value: %s" % value)
params[parameter["name"]] = value
@@ -2568,9 +2486,9 @@ class AppBase:
#remove_params.append(parameter["name"])
# Fix lists here
# FIXME: This doesn't really do anything anymore
print("CHECKING multi execution list: %d!" % len(multi_execution_lists))
print("[DEBUG] CHECKING multi execution list: %d!" % len(multi_execution_lists))
if len(multi_execution_lists) > 0:
print("\n Multi execution list has more data: %d" % len(multi_execution_lists))
print("\n [DEBUG] Multi execution list has more data: %d" % len(multi_execution_lists))
filteredlist = []
for listitem in multi_execution_lists:
if listitem in filteredlist:
@@ -2709,7 +2627,7 @@ class AppBase:
# 1. Use number of executions based on the arrays being similar
# 2. Find the right value from the parsed multi_params
print("[INFO] Running WITHOUT outer loop")
print("[INFO] Running WITHOUT outer loop (looping)")
json_object = False
results = await self.run_recursed_items(func, multi_parameters, {})
if isinstance(results, dict) or isinstance(results, list):
+1 -1
View File
@@ -3,7 +3,7 @@
### DEFAULT
NAME=shuffle-app_sdk
VERSION=0.9.20
VERSION=0.9.21
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
docker build . -f Dockerfile -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
+1 -1
View File
@@ -23,7 +23,7 @@ require (
github.com/docker/go-units v0.4.0 // indirect
github.com/elastic/go-elasticsearch/v7 v7.13.1 // indirect
github.com/frikky/kin-openapi v0.39.0
github.com/frikky/shuffle-shared v0.1.3
github.com/frikky/shuffle-shared v0.1.5
github.com/fsouza/go-dockerclient v1.7.2
github.com/ghodss/yaml v1.0.0
github.com/go-git/go-billy/v5 v5.0.0
+17 -2
View File
@@ -7,6 +7,7 @@ import (
"bytes"
"context"
"crypto/md5"
"crypto/tls"
//"crypto/x509"
"encoding/hex"
"encoding/json"
@@ -48,6 +49,7 @@ import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/storage/memory"
githttp "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
// Random
xj "github.com/basgys/goxml2json"
@@ -57,7 +59,7 @@ import (
"gopkg.in/yaml.v3"
// PROXY overrides
// "gopkg.in/src-d/go-git.v4/plumbing/transport/client"
"gopkg.in/src-d/go-git.v4/plumbing/transport/client"
// githttp "gopkg.in/src-d/go-git.v4/plumbing/transport/http"
// Web
@@ -4131,6 +4133,17 @@ func runInitEs(ctx context.Context) {
// FIXME: Isn't this a little backwards?
workflowapps, err := shuffle.GetAllWorkflowApps(ctx, 1000)
log.Printf("[INFO] Getting and validating workflowapps. Got %d with err %#v", len(workflowapps), err)
// accept any certificate (might be useful for testing)
customGitClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
Timeout: 15 * time.Second,
}
client.InstallProtocol("http", githttp.NewClient(customGitClient))
client.InstallProtocol("https", githttp.NewClient(customGitClient))
if err != nil && len(workflowapps) == 0 {
log.Printf("[WARNING] Failed getting apps (runInit): %s", err)
} else if err == nil {
@@ -4156,6 +4169,7 @@ func runInitEs(ctx context.Context) {
Password: password,
}
}
branch := os.Getenv("SHUFFLE_DOWNLOAD_AUTH_BRANCH")
if len(branch) > 0 && branch != "master" && branch != "main" {
cloneOptions.ReferenceName = plumbing.ReferenceName(branch)
@@ -4202,7 +4216,7 @@ func runInitEs(ctx context.Context) {
}
_, err = git.Clone(storer, fs, cloneOptions)
if err != nil {
log.Printf("Failed loading repo %s into memory: %s", apis, err)
log.Printf("[WARNING] Failed loading repo %s into memory: %s", apis, err)
} else {
log.Printf("[INFO] Finished git clone. Looking for updates to the repo.")
dir, err := fs.ReadDir("")
@@ -5898,6 +5912,7 @@ func initHandlers() {
// Introduced in 0.9.21 to handle notifications for e.g. failed Workflow
r.HandleFunc("/api/v1/notifications", shuffle.HandleGetNotifications).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/notifications/clear", shuffle.HandleClearNotifications).Methods("GET", "OPTIONS")
r.HandleFunc("/api/v1/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS")
//r.HandleFunc("/api/v1/notifications/{notificationId}/markasread", shuffle.HandleMarkAsRead).Methods("GET", "OPTIONS")
+1 -1
View File
@@ -127,7 +127,7 @@ const App = (message, props) => {
<Route exact path="/home" render={props => <LandingPageNew isLoaded={isLoaded} {...props} />} />
</div> :
<div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}>
<ScrollToTop setCurpath={setCurpath} />
<ScrollToTop getUserNotifications={getUserNotifications} setCurpath={setCurpath} />
<Header notifications={notifications} setNotifications={setNotifications} checkLogin={checkLogin} cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
<div style={{height: 60}}/>
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} checkLogin={checkLogin} {...props} />} />
+60 -6
View File
@@ -30,6 +30,40 @@ const Header = props => {
textDecoration: "none",
}
const handleClose = () => {
setAnchorEl(null);
setAnchorElAvatar(null);
};
const clearNotifications = () => {
// Don't really care about the logout
fetch(`${globalUrl}/api/v1/notifications/clear`, {
credentials: "include",
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then(function(response) {
if (response.status !== 200) {
console.log("Error in response")
}
return response.json();
}).then(function(responseJson) {
if (responseJson.success === true) {
setNotifications([])
handleClose()
} else {
alert.error("Failed dismissing notifications. Please try again later.")
}
})
.catch(error => {
console.log("error in notification dismissal: ", error)
//removeCookie("session_token", {path: "/"})
})
}
const dismissNotification = (alert_id) => {
// Don't really care about the logout
fetch(`${globalUrl}/api/v1/notifications/${alert_id}/markasread`, {
@@ -175,19 +209,17 @@ const Header = props => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
setAnchorElAvatar(null);
};
const chipStyle = {
backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white",
}
const notificationWidth = 350
const NotificationItem = (props) => {
const {data} = props
return (
<Paper style={{backgroundColor: theme.palette.surfaceColor, width: 300, padding: 25, borderBottom: "1px solid rgba(255,255,255,0.4)"}}>
<Paper style={{backgroundColor: theme.palette.surfaceColor, width: notificationWidth, padding: 25, borderBottom: "1px solid rgba(255,255,255,0.4)"}}>
{/*<Typography variant="h6">
{new Date(data.updated_at).toISOString()}
</Typography >*/}
@@ -251,11 +283,33 @@ const Header = props => {
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
style={{zIndex: 10002, maxHeight: "100vh", overflowX: "hidden", overflowY: "auto",}}
style={{zIndex: 10002, maxHeight: "90vh", overflowX: "hidden", overflowY: "auto",}}
PaperProps={{
style: {
backgroundColor: theme.palette.surfaceColor,
}
}}
onClose={() => {
handleClose()
}}
>
<Paper style={{backgroundColor: theme.palette.surfaceColor, width: notificationWidth, padding: 25, borderBottom: "3px solid rgba(255,255,255,0.4)"}}>
<div style={{display: "flex", marginBottom: 5, }}>
<Typography variant="h6">
Your Notifications ({notifications.length})
</Typography>
{notifications.length > 1 ?
<Button color="primary" variant="contained" style={{marginLeft: 30, }} onClick={() => {
clearNotifications()
}}>
Flush
</Button>
: null}
</div>
<Typography variant="body2">
Notifications are made by Shuffle to help you discover issues or improvements.
</Typography >
</Paper>
{notifications.map((data, index) => {
return (
<NotificationItem data={data} key={index} />
+2 -9
View File
@@ -1,8 +1,7 @@
import { useEffect } from 'react';
import { withRouter } from 'react-router-dom';
import ReactGA from 'react-ga';
function ScrollToTop({setCurpath, history }) {
function ScrollToTop({getUserNotifications, setCurpath, history }) {
useEffect(() => {
const unlisten = history.listen(() => {
window.scroll({
@@ -11,14 +10,8 @@ function ScrollToTop({setCurpath, history }) {
behavior: "smooth",
});
//ReactGA.event({
// category: "referral",
// action: "new_user_referral",
// label: "",
//})
ReactGA.pageview(window.location.pathname)
setCurpath(window.location.pathname)
getUserNotifications()
});
return () => {
unlisten();
+2 -2
View File
@@ -380,14 +380,14 @@ const Docs = (props) => {
<Typography style={{color: itemMatching ? "#f86a3e" : "inherit"}} variant="body1"><b>> {newname}</b></Typography>
</Link>
{itemMatching && tocLines !== null && tocLines !== undefined && tocLines.length > 0 ?
<div style={{marginLeft: 13}}>
<div style={{marginLeft: 5}}>
{tocLines.map((data, index) => {
console.log(data)
return (
<Link key={index} style={innerHrefStyle} to={data.link} onClick={() => {}}>
<Typography variant="body2" style={{cursor: "pointer"}}>
{data.text}
- {data.text}
</Typography>
</Link>
)