Added org and suborg swapping POC
This commit is contained in:
@@ -22,7 +22,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.0.72
|
||||
github.com/frikky/shuffle-shared v0.0.74
|
||||
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
|
||||
|
||||
@@ -739,12 +739,15 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
apikey := ""
|
||||
if count != 0 {
|
||||
if user.Role != "admin" {
|
||||
resp.WriteHeader(401)
|
||||
resp.Write([]byte(`{"success": false, "reason": "Can't register without being admin (2)"}`))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
apikey = uuid.NewV4().String()
|
||||
}
|
||||
|
||||
// Gets a struct of Username, password
|
||||
@@ -819,7 +822,7 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
err = createNewUser(data.Username, data.Password, role, "", currentOrg)
|
||||
err = createNewUser(data.Username, data.Password, role, apikey, currentOrg)
|
||||
if err != nil {
|
||||
log.Printf("[WARNING] Failed registering user: %s", err)
|
||||
resp.WriteHeader(401)
|
||||
@@ -828,7 +831,7 @@ func handleRegister(resp http.ResponseWriter, request *http.Request) {
|
||||
}
|
||||
|
||||
resp.WriteHeader(200)
|
||||
resp.Write([]byte(`{"success": true}`))
|
||||
resp.Write([]byte(fmt.Sprintf(`{"success": true, "apikey": "%s"}`, apikey)))
|
||||
log.Printf("[INFO] %s Successfully registered.", data.Username)
|
||||
}
|
||||
|
||||
@@ -4147,12 +4150,12 @@ func runInitEs(ctx context.Context) {
|
||||
r, err := git.Clone(storer, fs, cloneOptions)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Failed loading repo into memory (init): %s", err)
|
||||
log.Printf("[WARNING] Failed loading repo into memory (init): %s", err)
|
||||
}
|
||||
|
||||
dir, err := fs.ReadDir("")
|
||||
if err != nil {
|
||||
log.Printf("Failed reading folder: %s", err)
|
||||
log.Printf("[WARNING] Failed reading folder (init): %s", err)
|
||||
}
|
||||
_ = r
|
||||
//iterateAppGithubFolders(fs, dir, "", "testing")
|
||||
@@ -5837,6 +5840,7 @@ func initHandlers() {
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleGetOrg).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}", shuffle.HandleEditOrg).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}/create_sub_org", shuffle.HandleCreateSubOrg).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/api/v1/orgs/{orgId}/change", shuffle.HandleChangeUserOrg).Methods("POST", "OPTIONS") // Swaps to the org
|
||||
|
||||
// This is a new API that validates if a key has been seen before.
|
||||
// Not sure what the best course of action is for it.
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
version: '3'
|
||||
services:
|
||||
frontend:
|
||||
#build: ./frontend
|
||||
build: ./frontend
|
||||
image: ghcr.io/frikky/shuffle-frontend:nightly
|
||||
container_name: shuffle-frontend
|
||||
hostname: shuffle-frontend
|
||||
@@ -16,7 +16,7 @@ services:
|
||||
depends_on:
|
||||
- backend
|
||||
backend:
|
||||
#build: ./backend
|
||||
build: ./backend
|
||||
image: ghcr.io/frikky/shuffle-backend:nightly
|
||||
container_name: shuffle-backend
|
||||
hostname: ${BACKEND_HOSTNAME}
|
||||
|
||||
@@ -105,7 +105,7 @@ const App = (message, props) => {
|
||||
</div> :
|
||||
<div style={{ backgroundColor: "#1F2023", color: "rgba(255, 255, 255, 0.65)", minHeight: "100vh" }}>
|
||||
<ScrollToTop setCurpath={setCurpath} />
|
||||
<Header cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
|
||||
<Header checkLogin={checkLogin} cookies={cookies} removeCookie={removeCookie} isLoaded={isLoaded} globalUrl={globalUrl} setIsLoggedIn={setIsLoggedIn} isLoggedIn={isLoggedIn} userdata={userdata} {...props} />
|
||||
<Route exact path="/login" render={props => <LoginPage isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin" render={props => <Admin userdata={userdata} isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
<Route exact path="/admin/:key" render={props => <Admin isLoggedIn={isLoggedIn} setIsLoggedIn={setIsLoggedIn} register={true} isLoaded={isLoaded} globalUrl={globalUrl} setCookie={setCookie} cookies={cookies} {...props} />} />
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+103
-78
@@ -390,10 +390,10 @@ const Admin = (props) => {
|
||||
if (responseJson.reason !== undefined) {
|
||||
alert.error(responseJson.reason)
|
||||
} else {
|
||||
alert.error("Failed setting new password")
|
||||
alert.error("Failed creating suborg")
|
||||
}
|
||||
} else {
|
||||
alert.success("Successfully updated password!")
|
||||
alert.success("Successfully created suborg!")
|
||||
setSelectedUserModalOpen(false)
|
||||
}
|
||||
|
||||
@@ -499,6 +499,10 @@ const Admin = (props) => {
|
||||
if (responseJson["success"] === false) {
|
||||
alert.error("Failed getting org: ", responseJson.readon)
|
||||
} else {
|
||||
if (responseJson.sync_features === undefined || responseJson.sync_features === null) {
|
||||
responseJson.sync_features = {}
|
||||
|
||||
}
|
||||
setSelectedOrganization(responseJson)
|
||||
var lists = {
|
||||
"active": {
|
||||
@@ -1726,65 +1730,65 @@ const Admin = (props) => {
|
||||
</div>
|
||||
}
|
||||
<Typography style={{marginTop: 40, marginLeft: 10, marginBottom: 5,}}>Cloud sync features</Typography>
|
||||
<Grid container style={{width: "100%", marginBottom: 15, }}>
|
||||
{Object.keys(selectedOrganization.sync_features).map(function(key, index) {
|
||||
if (key === "schedule") {
|
||||
return null
|
||||
}
|
||||
<Grid container style={{width: "100%", marginBottom: 15, }}>
|
||||
{selectedOrganization.sync_features === undefined || selectedOrganization.sync_features === null ? null : Object.keys(selectedOrganization.sync_features).map(function(key, index) {
|
||||
if (key === "schedule") {
|
||||
return null
|
||||
}
|
||||
|
||||
const item = selectedOrganization.sync_features[key]
|
||||
const newkey = key.replaceAll("_", " ")
|
||||
const griditem = {
|
||||
"primary": newkey,
|
||||
"secondary": item.description === undefined || item.description === null || item.description.length === 0 ? "Not defined yet" : item.description,
|
||||
"limit": item.limit,
|
||||
"usage": 0,
|
||||
"data_collection": "None",
|
||||
"active": item.active,
|
||||
"icon": <PolymerIcon style={{color: itemColor}}/>,
|
||||
}
|
||||
const item = selectedOrganization.sync_features[key]
|
||||
const newkey = key.replaceAll("_", " ")
|
||||
const griditem = {
|
||||
"primary": newkey,
|
||||
"secondary": item.description === undefined || item.description === null || item.description.length === 0 ? "Not defined yet" : item.description,
|
||||
"limit": item.limit,
|
||||
"usage": 0,
|
||||
"data_collection": "None",
|
||||
"active": item.active,
|
||||
"icon": <PolymerIcon style={{color: itemColor}}/>,
|
||||
}
|
||||
|
||||
return (
|
||||
<Zoom key={index} >
|
||||
<GridItem data={griditem} />
|
||||
</Zoom>
|
||||
)
|
||||
})}
|
||||
</Grid>
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
{isCloud && selectedOrganization.subscriptions !== undefined && selectedOrganization.subscriptions !== null && selectedOrganization.subscriptions.length > 0 ?
|
||||
<div style={{marginTop: 30, marginBottom: 20}}>
|
||||
<Typography style={{marginTop: 40, marginLeft: 10, marginBottom: 5,}}>
|
||||
Your subscription{selectedOrganization.subscriptions.length > 1 ? "s" : ""}
|
||||
</Typography>
|
||||
<Grid container spacing={3} style={{marginTop: 15}}>
|
||||
{selectedOrganization.subscriptions.reverse().map((sub, index) => {
|
||||
return (
|
||||
<Grid item key={index} xs={4}>
|
||||
<Card elevation={6} style={{backgroundColor: theme.palette.inputColor, color: "white", padding: 25, textAlign: "left",}}>
|
||||
<b>Type</b>: {sub.level}<div/>
|
||||
<b>Recurrence</b>: {sub.recurrence}<div/>
|
||||
{sub.active ?
|
||||
<div>
|
||||
<b>Started</b>: {new Date(sub.startdate*1000).toISOString()}<div/>
|
||||
<Button variant="outlined" color="primary" style={{marginTop: 15}} onClick={() => {
|
||||
cancelSubscriptions(sub.reference)
|
||||
}}>
|
||||
Cancel subscription
|
||||
</Button>
|
||||
</div>
|
||||
:
|
||||
<div>
|
||||
<b>Cancelled</b>: {new Date(sub.cancellationdate*1000).toISOString()}<div/>
|
||||
<Typography color="textSecondary">
|
||||
<b>Status</b>: Deactivated
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
return (
|
||||
<Zoom key={index} >
|
||||
<GridItem data={griditem} />
|
||||
</Zoom>
|
||||
)
|
||||
})}
|
||||
</Grid>
|
||||
<Divider style={{ marginTop: 20, marginBottom: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
{isCloud && selectedOrganization.subscriptions !== undefined && selectedOrganization.subscriptions !== null && selectedOrganization.subscriptions.length > 0 ?
|
||||
<div style={{marginTop: 30, marginBottom: 20}}>
|
||||
<Typography style={{marginTop: 40, marginLeft: 10, marginBottom: 5,}}>
|
||||
Your subscription{selectedOrganization.subscriptions.length > 1 ? "s" : ""}
|
||||
</Typography>
|
||||
<Grid container spacing={3} style={{marginTop: 15}}>
|
||||
{selectedOrganization.subscriptions.reverse().map((sub, index) => {
|
||||
return (
|
||||
<Grid item key={index} xs={4}>
|
||||
<Card elevation={6} style={{backgroundColor: theme.palette.inputColor, color: "white", padding: 25, textAlign: "left",}}>
|
||||
<b>Type</b>: {sub.level}<div/>
|
||||
<b>Recurrence</b>: {sub.recurrence}<div/>
|
||||
{sub.active ?
|
||||
<div>
|
||||
<b>Started</b>: {new Date(sub.startdate*1000).toISOString()}<div/>
|
||||
<Button variant="outlined" color="primary" style={{marginTop: 15}} onClick={() => {
|
||||
cancelSubscriptions(sub.reference)
|
||||
}}>
|
||||
Cancel subscription
|
||||
</Button>
|
||||
</div>
|
||||
:
|
||||
<div>
|
||||
<b>Cancelled</b>: {new Date(sub.cancellationdate*1000).toISOString()}<div/>
|
||||
<Typography color="textSecondary">
|
||||
<b>Status</b>: Deactivated
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
</Card>
|
||||
</Grid>
|
||||
)
|
||||
})}
|
||||
</Grid>
|
||||
<Divider style={{ marginTop: 20, backgroundColor: theme.palette.inputColor }} />
|
||||
</div>
|
||||
@@ -1813,7 +1817,7 @@ const Admin = (props) => {
|
||||
}}
|
||||
>
|
||||
<DialogTitle><span style={{ color: "white" }}>
|
||||
{curTab === 1 ? "Add user" : curTab === 7 ? "Add Sub-Organization" : "Add environment"}
|
||||
{curTab === 1 ? "Add user" : curTab === 6 ? "Add Sub-Organization" : "Add environment"}
|
||||
</span></DialogTitle>
|
||||
<DialogContent>
|
||||
{curTab === 1 && isCloud ?
|
||||
@@ -1821,7 +1825,7 @@ const Admin = (props) => {
|
||||
We'll send an email to invite them to your organization.
|
||||
</Typography>
|
||||
:
|
||||
curTab === 7 ?
|
||||
curTab === 6 ?
|
||||
<Typography variant="body1" style={{marginBottom: 10}}>
|
||||
The organization created will become a child of your current organization, and be available to you.
|
||||
</Typography>
|
||||
@@ -1876,7 +1880,7 @@ const Admin = (props) => {
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
: curTab === 7 ?
|
||||
: curTab === 6 ?
|
||||
<div>
|
||||
Name
|
||||
<TextField
|
||||
@@ -1938,7 +1942,7 @@ const Admin = (props) => {
|
||||
} else {
|
||||
submitUser(modalUser)
|
||||
}
|
||||
} else if (curTab === 7) {
|
||||
} else if (curTab === 6) {
|
||||
createSubOrg(selectedOrganization.id, orgName)
|
||||
} else if (curTab === 5) {
|
||||
submitEnvironment(modalUser)
|
||||
@@ -2513,6 +2517,7 @@ const Admin = (props) => {
|
||||
bgColor = "#1f2023"
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<ListItem key={index} style={{backgroundColor: bgColor}}>
|
||||
<ListItemText
|
||||
@@ -2696,7 +2701,7 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const organizationsTab = curTab === 7 ?
|
||||
const organizationsTab = curTab === 6 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
<h2 style={{display: "inline",}}>Organizations</h2>
|
||||
@@ -2716,17 +2721,21 @@ const Admin = (props) => {
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Name"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
primary="Logo"
|
||||
style={{minWidth: 100, maxWidth: 100}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="id"
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
primary="Name"
|
||||
style={{minWidth: 250, maxWidth: 250}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Your role"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="id"
|
||||
style={{minWidth: 400, maxWidth: 400}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary="Selected"
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
@@ -2736,25 +2745,41 @@ const Admin = (props) => {
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
</ListItem>
|
||||
{organizations !== undefined && organizations !== null && organizations.length > 0 ?
|
||||
{userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 ?
|
||||
<span>
|
||||
{organizations.map((data, index) => {
|
||||
{userdata.orgs.map((data, index) => {
|
||||
const isSelected = props.userdata.active_org.id === undefined ? "False" : props.userdata.active_org.id === data.id ? "True" : "False"
|
||||
|
||||
const imagesize = 40
|
||||
const imageStyle = {width: imagesize, height: imagesize, pointerEvents: "none", }
|
||||
const image = data.image === "" ?
|
||||
<img alt={data.name} src={theme.palette.defaultImage} style={imageStyle} />
|
||||
:
|
||||
<img alt={data.name} src={data.image} style={imageStyle} />
|
||||
|
||||
var bgColor = "#27292d"
|
||||
if (index % 2 === 0) {
|
||||
bgColor = "#1f2023"
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem key={index}>
|
||||
<ListItem key={index} style={{backgroundColor: bgColor,}}>
|
||||
<ListItemText
|
||||
primary={data.name}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
primary={image}
|
||||
style={{minWidth: 100, maxWidth: 100}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.id}
|
||||
style={{minWidth: 200, maxWidth: 200}}
|
||||
primary={data.name}
|
||||
style={{minWidth: 250, maxWidth: 250}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.role}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={data.id}
|
||||
style={{minWidth: 400, maxWidth: 400}}
|
||||
/>
|
||||
<ListItemText
|
||||
primary={isSelected}
|
||||
style={{minWidth: 150, maxWidth: 150}}
|
||||
@@ -2776,7 +2801,7 @@ const Admin = (props) => {
|
||||
</div>
|
||||
: null
|
||||
|
||||
const hybridTab = curTab === 6 ?
|
||||
const hybridTab = curTab === 7 ?
|
||||
<div>
|
||||
<div style={{marginTop: 20, marginBottom: 20,}}>
|
||||
<h2 style={{display: "inline",}}>Hybrid</h2>
|
||||
@@ -2836,9 +2861,9 @@ const Admin = (props) => {
|
||||
<Tab label=<span><DescriptionIcon style={iconStyle} />Files</span> />
|
||||
<Tab label=<span><ScheduleIcon style={iconStyle} />Schedules</span> />
|
||||
{isCloud ? null : <Tab label=<span><EcoIcon style={iconStyle} />Environments</span>/>}
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><CloudIcon style={iconStyle} /> Hybrid</span>/> : null}
|
||||
{window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><BusinessIcon style={iconStyle} /> Organizations</span>/> : null}
|
||||
{window.location.protocol === "http:" && window.location.port === "3000" ? <Tab label=<span><LockIcon style={iconStyle} />Categories</span>/> : null}
|
||||
{isCloud ? null : <Tab label=<span><BusinessIcon style={iconStyle} /> Organizations</span>/>}
|
||||
{/*window.location.protocol == "http:" && window.location.port === "3000" ? <Tab label=<span><CloudIcon style={iconStyle} /> Hybrid</span>/> : null*/}
|
||||
{/*window.location.protocol === "http:" && window.location.port === "3000" ? <Tab label=<span><LockIcon style={iconStyle} />Categories</span>/> : null*/}
|
||||
</Tabs>
|
||||
<Divider style={{marginTop: 0, marginBottom: 10, backgroundColor: "rgb(91, 96, 100)"}} />
|
||||
<div style={{padding: 15}}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect} from 'react';
|
||||
import { useInterval } from 'react-powerhooks';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import { useTheme } from '@material-ui/core/styles';
|
||||
|
||||
import {Avatar, Grid, Paper, Tooltip, Divider, Button, TextField, FormControl, IconButton, Menu, MenuItem, FormControlLabel, Chip, Switch, Typography, Zoom, CircularProgress, Dialog, DialogTitle, DialogActions, DialogContent} from '@material-ui/core';
|
||||
import {Close as CloseIcon, Compare as CompareIcon, Maximize as MaximizeIcon, Minimize as MinimizeIcon, AddCircle as AddCircleIcon, Toc as TocIcon, Send as SendIcon, Search as SearchIcon, FileCopy as FileCopyIcon, Delete as DeleteIcon, BubbleChart as BubbleChartIcon, Restore as RestoreIcon, Cached as CachedIcon, GetApp as GetAppIcon, Apps as AppsIcon, Edit as EditIcon, MoreVert as MoreVertIcon, PlayArrow as PlayArrowIcon, Add as AddIcon, Publish as PublishIcon, CloudUpload as CloudUploadIcon, CloudDownload as CloudDownloadIcon} from '@material-ui/icons';
|
||||
@@ -328,6 +329,7 @@ export const validateJson = (showResult) => {
|
||||
const Workflows = (props) => {
|
||||
const { globalUrl, isLoggedIn, isLoaded, removeCookie, cookies, userdata} = props;
|
||||
document.title = "Shuffle - Workflows"
|
||||
const theme = useTheme();
|
||||
const referenceUrl = globalUrl+"/api/v1/hooks/"
|
||||
|
||||
const alert = useAlert()
|
||||
@@ -391,6 +393,10 @@ const Workflows = (props) => {
|
||||
return true
|
||||
} else if (curWorkflow.tags.includes(filter)) {
|
||||
return true
|
||||
} else if (curWorkflow.owner === filter) {
|
||||
return true
|
||||
} else if (curWorkflow.org_id === filter) {
|
||||
return true
|
||||
} else if (curWorkflow.actions !== null && curWorkflow.actions !== undefined) {
|
||||
const newfilter = filter.toLowerCase()
|
||||
for (var key in curWorkflow.actions) {
|
||||
@@ -1065,16 +1071,38 @@ const Workflows = (props) => {
|
||||
parsedName = parsedName.slice(0,26)+".."
|
||||
}
|
||||
|
||||
|
||||
const actions = data.actions !== null ? data.actions.length : 0
|
||||
const [triggers, schedules, webhooks, subflows] = getWorkflowMeta(data)
|
||||
|
||||
const imagesize = 22
|
||||
const foundOrg = userdata.orgs.find(org => org.id === data["org_id"])
|
||||
|
||||
//position: "absolute", bottom: 5, right: -5,
|
||||
const imageStyle = {width: imagesize, height: imagesize, pointerEvents: "none", marginRight: 10, marginLeft: data.creator_org !== undefined && data.creator_org.length > 0 ? 20 : 0, borderRadius: 10, border: foundOrg.id === userdata.active_org.id ? `4px solid ${boxColor}` : null, cursor: "pointer", marginRight: 10, }
|
||||
|
||||
//<Tooltip title={`Org: ${foundOrg.name}`} placement="bottom">
|
||||
const image = foundOrg.image === "" ?
|
||||
<img alt={foundOrg.name} src={theme.palette.defaultImage} style={imageStyle} />
|
||||
:
|
||||
<img alt={foundOrg.name} src={foundOrg.image} style={imageStyle} onClick={() => {
|
||||
//setFilteredWorkflows(newWorkflows)
|
||||
}}/>
|
||||
|
||||
return (
|
||||
<Grid item xs={4} style={{padding: "12px 10px 12px 10px",}}>
|
||||
<Paper square style={paperAppStyle} >
|
||||
<div style={{position: "absolute", bottom: 1, left: 1, height: 12, width: 12, backgroundColor: boxColor, borderRadius: "0 100px 0 0",}} />
|
||||
<Grid item style={{display: "flex", flexDirection: "column", width: "100%"}}>
|
||||
<Grid item style={{display: "flex", maxHeight: 34,}}>
|
||||
<Tooltip title={`Org "${foundOrg.name}"`} placement="bottom">
|
||||
<div styl={{cursor: "pointer"}} onClick={() => {
|
||||
addFilter(foundOrg.id)
|
||||
//setFilters(["Org "+foundOrg.name])
|
||||
//setFilteredWorkflows(newWorkflows)
|
||||
}}>
|
||||
{image}
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title={`Edit ${data.name}`} placement="bottom">
|
||||
<Typography variant="body1" style={{marginBottom: 0, paddingBottom: 0, maxHeight: 30, flex: 10,}}>
|
||||
<Link to={"/workflows/"+data.id} style={{textDecoration: "none", color: "inherit",}}>
|
||||
|
||||
Reference in New Issue
Block a user