diff --git a/frontend/src/components/ExploreWorkflow.jsx b/frontend/src/components/ExploreWorkflow.jsx
index 6333d673..69c44cd4 100644
--- a/frontend/src/components/ExploreWorkflow.jsx
+++ b/frontend/src/components/ExploreWorkflow.jsx
@@ -5,6 +5,7 @@ import 'react-alice-carousel/lib/alice-carousel.css';
import TrendingFlatIcon from '@mui/icons-material/TrendingFlat';
import theme from '../theme.jsx';
import {isMobile} from "react-device-detect";
+import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import CheckBoxSharpIcon from '@mui/icons-material/CheckBoxSharp';
import { findSpecificApp } from "../components/AppFramework.jsx"
import {
@@ -291,11 +292,29 @@ const ExploreWorkflow = (props) => {
return (
+
+ {
+ navigate('/welcome?tab=2');
+ window.location.reload();
+ }}
+ >
+
+ Back
+
+
{modalView}
Start using workflows
-
+
Based on what you selected workflows, here are our recommendations! You will see more of these later.
diff --git a/frontend/src/components/Files.jsx b/frontend/src/components/Files.jsx
index 75553621..670cba97 100644
--- a/frontend/src/components/Files.jsx
+++ b/frontend/src/components/Files.jsx
@@ -382,7 +382,7 @@ const Files = (props) => {
Files
- Files from Workflows.{" "}
+ Files from Workflows are a way to store as well as edit files.{" "}
{
const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, homePage, userdata, serverside, } = props;
- //const theme = useTheme();
- //const alert = useAlert()
-
-
- const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor);
- const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor);
- const [LoginHoverColor, setLoginHoverColor] = useState(hoverOutColor);
- const [DocsHoverColor, setDocsHoverColor] = useState(hoverOutColor);
+ const [HomeHoverColor, setHomeHoverColor] = useState(hoverOutColor);
+ const [SoarHoverColor, setSoarHoverColor] = useState(hoverOutColor);
+ const [LoginHoverColor, setLoginHoverColor] = useState(hoverOutColor);
+ const [DocsHoverColor, setDocsHoverColor] = useState(hoverOutColor);
const [HelpHoverColor, setHelpHoverColor] = useState(hoverOutColor);
const [anchorEl, setAnchorEl] = React.useState(null);
const [anchorElAvatar, setAnchorElAvatar] = React.useState(null);
@@ -543,6 +539,8 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
+
+
@@ -559,21 +557,6 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
- {/*
-
-
-
-
-
- */}
{isCloud ?
@@ -615,60 +598,33 @@ const { globalUrl, setNotifications, notifications, isLoggedIn, removeCookie, ho
-
-
-
+
+
-
-
-
-
-
-
- {isCloud ?
-
-
-
-
-
- : null}
-
- {/*
-
- {supportMenu}
-
- */}
-
- {/*
-
-
-
- */}
+ }
+ }}>Login
+ {isCloud ?
+
+ {
+ ReactGA.event({
+ category: "header",
+ action: "register_click",
+ label: "",
+ })
+ }}>Sign Up
+
+
+ : null}
+
diff --git a/frontend/src/components/Searchfield.jsx b/frontend/src/components/Searchfield.jsx
index 3bafef61..7edef2ca 100644
--- a/frontend/src/components/Searchfield.jsx
+++ b/frontend/src/components/Searchfield.jsx
@@ -1,34 +1,42 @@
-import React, {useState, useEffect, useRef} from 'react';
+import React, { useState, useEffect, useRef } from 'react';
import theme from '../theme.jsx';
import { useNavigate, Link, useParams } from "react-router-dom";
+import SearchBox from "./SearchData.jsx";
import {
- Chip,
- IconButton,
- TextField,
- InputAdornment,
- List,
- Card,
- ListItem,
- ListItemAvatar,
- ListItemText,
- Avatar,
+ Chip,
+ IconButton,
+ TextField,
+ InputAdornment,
+ List,
+ Card,
+ ListItem,
+ Button,
+ Dialog,
+ ListItemAvatar,
+ ListItemText,
+ Avatar,
Typography,
Tooltip,
+ Divider,
+ DialogTitle,
+ DialogContent,
} from '@mui/material';
+import Mousetrap from 'mousetrap';
import {
- AvatarGroup,
+ AvatarGroup,
} from "@mui/material"
-import {Search as SearchIcon, Close as CloseIcon, Folder as FolderIcon, Code as CodeIcon, LibraryBooks as LibraryBooksIcon} from '@mui/icons-material'
-
+import { Search as SearchIcon, Close as CloseIcon, Folder as FolderIcon, Code as CodeIcon, LibraryBooks as LibraryBooksIcon } from '@mui/icons-material'
+import KeyboardCommandKeyIcon from '@mui/icons-material/KeyboardCommandKey';
import algoliasearch from 'algoliasearch/lite';
import aa from 'search-insights'
import { InstantSearch, Configure, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
//import { InstantSearch, SearchBox, Hits, connectSearchBox, connectHits, Index } from 'react-instantsearch-dom';
+import { HotKeys } from 'react-hotkeys';
// https://www.algolia.com/doc/api-reference/widgets/search-box/react/
const chipStyle = {
backgroundColor: "#3d3f43", height: 30, marginRight: 5, paddingLeft: 5, paddingRight: 5, height: 28, cursor: "pointer", borderColor: "#3d3f43", color: "white",
@@ -36,623 +44,120 @@ const chipStyle = {
const searchClient = algoliasearch("JNSS5CFDZZ", "db08e40265e2941b9a7d8f644b6e5240")
const SearchField = props => {
- const { serverside, userdata } = props
+ const { serverside, userdata, isMobile, isLoaded, globalUrl, isHeader, isLoggedIn, small, rounded } = props
let navigate = useNavigate();
const borderRadius = 3
const node = useRef()
const [searchOpen, setSearchOpen] = useState(false)
+ const [modalOpen, setModalOpen] = React.useState(false);
const [oldPath, setOldPath] = useState("")
const [value, setValue] = useState("");
+ useEffect(() => {
+ Mousetrap.bind(['command+k', 'ctrl+k'], () => {
+ setModalOpen(true);
+ return false; // Prevent the default action
+ });
+ Mousetrap.bind(['esc'], () => {
+ setModalOpen(false);
+ return false; // Prevent the default action
+ });
- if (serverside === true) {
- return null
- }
-
- if (window !== undefined && window.location !== undefined && window.location.pathname === "/search") {
- return null
- }
-
- const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io";
-
- if (window.location.pathname !== oldPath) {
- setSearchOpen(false)
- setOldPath(window.location.pathname)
- }
-
- //useEffect(() => {
- // if (searchOpen) {
- // var tarfield = document.getElementById("shuffle_search_field")
- // tarfield.focus()
- // }
- //}, searchOpen)
-
- const SearchBox = ({currentRefinement, refine, isSearchStalled, } ) => {
- const keyPressHandler = (e) => {
- // e.preventDefault();
- if (e.which === 13) {
- // alert("You pressed enter!");
- navigate("/search?q=" + currentRefinement, { state: value, replace: true });
- }
+ return () => {
+ Mousetrap.unbind(['command+k', 'ctrl+k']);
};
- /*
- endAdornment: (
-
{
- event.preventDefault()
- }}>
- {
- setSearchOpen(false)
- }} />
-
- ),
- */
+ }, []);
- return (
-
- )
- }
-
- const WorkflowHits = ({ hits }) => {
- const [mouseHoverIndex, setMouseHoverIndex] = useState(0)
-
- var tmp = searchOpen
- if (!searchOpen) {
- return null
- }
-
-
- const positionInfo = document.activeElement.getBoundingClientRect()
- const outerlistitemStyle = {
- width: "100%",
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- }
-
- if (hits.length > 4) {
- hits = hits.slice(0, 4)
- }
-
- var type = "workflows"
- const baseImage =
-
- return (
-
-
- Workflows
-
-
-
- {hits.length === 0 ?
-
- console.log(hits)}>
-
-
-
-
-
-
- :
- hits.map((hit, index) => {
- const innerlistitemStyle = {
- width: positionInfo.width+35,
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- backgroundColor: mouseHoverIndex === index ? "#1f2023" : "inherit",
- cursor: "pointer",
- marginLeft: 5,
- marginRight: 5,
- maxHeight: 75,
- minHeight: 75,
- maxWidth: 420,
- minWidth: "100%",
- }
-
- const name = hit.name === undefined ?
- hit.filename.charAt(0).toUpperCase() + hit.filename.slice(1).replaceAll("_", " ") + " - " + hit.title :
- (hit.name.charAt(0).toUpperCase()+hit.name.slice(1)).replaceAll("_", " ")
- const secondaryText = hit.description !== undefined && hit.description !== null && hit.description.length > 3 ? hit.description.slice(0, 40)+"..." : ""
- const appGroup = hit.action_references === undefined || hit.action_references === null ? [] : hit.action_references
- const avatar = baseImage
-
- var parsedUrl = isCloud ? `/workflows/${hit.objectID}` : `https://shuffler.io/workflows/${hit.objectID}`
-
- parsedUrl += `?queryID=${hit.__queryID}`
-
- //
- return (
- {
- //console.log("CLICK")
- setSearchOpen(true)
-
- aa('init', {
- appId: searchClient.appId,
- apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"]
- })
-
- const timestamp = new Date().getTime()
- aa('sendEvents', [
- {
- eventType: 'click',
- eventName: 'Workflow Clicked',
- index: 'workflows',
- objectIDs: [hit.objectID],
- timestamp: timestamp,
- queryID: hit.__queryID,
- positions: [hit.__position],
- userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id,
- }
- ])
-
- if (!isCloud) {
- event.preventDefault()
- window.open(parsedUrl, '_blank');
- }
- }}>
- {
- setMouseHoverIndex(index)
- }}>
-
- {avatar}
-
-
-
-
- {appGroup.map((app, index) => {
- // Putting all this in secondary of ListItemText looked weird.
- return (
- {
- navigate("/apps/"+app.id)
- }}
- >
-
-
-
-
- )
- })}
-
-
- {/*
-
-
-
-
-
- */}
-
-
- )})
- }
-
- {/*
-
-
-
- See all workflows
-
-
-
- */}
-
- )
- }
-
- const AppHits = ({ hits }) => {
- const [mouseHoverIndex, setMouseHoverIndex] = useState(0)
-
- var tmp = searchOpen
- if (!searchOpen) {
- return null
- }
-
- const positionInfo = document.activeElement.getBoundingClientRect()
- const outerlistitemStyle = {
- width: "100%",
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- }
-
- if (hits.length > 4) {
- hits = hits.slice(0, 4)
- }
-
- var type = "app"
- const baseImage =
-
- return (
-
- {
- setSearchOpen(false)
- }}>
-
-
-
- Apps
-
-
-
- {hits.length === 0 ?
-
- console.log(hits)}>
-
-
-
-
-
-
- :
- hits.map((hit, index) => {
- const innerlistitemStyle = {
- width: positionInfo.width+35,
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- backgroundColor: mouseHoverIndex === index ? "#1f2023" : "inherit",
- cursor: "pointer",
- marginLeft: 5,
- marginRight: 5,
- maxHeight: 75,
- minHeight: 75,
- maxWidth: 420,
- minWidth: "100%",
- }
-
- const name = hit.name === undefined ?
- hit.filename.charAt(0).toUpperCase() + hit.filename.slice(1).replaceAll("_", " ") + " - " + hit.title :
- (hit.name.charAt(0).toUpperCase()+hit.name.slice(1)).replaceAll("_", " ")
-
- var secondaryText = hit.data !== undefined ? hit.data.slice(0, 40)+"..." : ""
- const avatar = hit.image_url === undefined ?
- baseImage
- :
-
-
- //console.log(hit)
- if (hit.categories !== undefined && hit.categories !== null && hit.categories.length > 0) {
- secondaryText = hit.categories.slice(0,3).map((data, index) => {
- if (index === 0) {
- return data
- }
-
- return ", "+data
-
- /*
- {
- //handleChipClick
- }}
- variant="outlined"
- color="primary"
- />
- */
- })
- }
-
- var parsedUrl = isCloud ? `/apps/${hit.objectID}` : `https://shuffler.io/apps/${hit.objectID}`
- parsedUrl += `?queryID=${hit.__queryID}`
-
- return (
- {
- console.log("CLICK")
- setSearchOpen(true)
-
- aa('init', {
- appId: searchClient.appId,
- apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"]
- })
-
- const timestamp = new Date().getTime()
- aa('sendEvents', [
- {
- eventType: 'click',
- eventName: 'App Clicked',
- index: 'appsearch',
- objectIDs: [hit.objectID],
- timestamp: timestamp,
- queryID: hit.__queryID,
- positions: [hit.__position],
- userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id,
- }
- ])
-
- if (!isCloud) {
- event.preventDefault()
- window.open(parsedUrl, '_blank');
- }
- }}>
- {
- setMouseHoverIndex(index)
- }}>
-
- {avatar}
-
-
- {/*
-
-
-
-
-
- */}
-
-
- )})
- }
-
-
-
-
- See more
-
-
-
-
- )
- }
-
- const DocHits = ({ hits }) => {
- const [mouseHoverIndex, setMouseHoverIndex] = useState(0)
-
- var tmp = searchOpen
- if (!searchOpen) {
- return null
- }
-
-
- const positionInfo = document.activeElement.getBoundingClientRect()
- const outerlistitemStyle = {
- width: "100%",
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- }
-
- if (hits.length > 4) {
- hits = hits.slice(0, 4)
- }
-
- const type = "documentation"
- const baseImage =
-
- //console.log(type, hits.length, hits)
-
- return (
-
- {
- setSearchOpen(false)
- }}>
-
-
-
- Documentation
-
- {/*
- {
- setSearchOpen(false)
- }}>
-
-
- */}
-
- {hits.length === 0 ?
-
- console.log(hits)}>
-
-
-
-
-
-
- :
- hits.map((hit, index) => {
- const innerlistitemStyle = {
- width: positionInfo.width+35,
- overflowX: "hidden",
- overflowY: "hidden",
- borderBottom: "1px solid rgba(255,255,255,0.4)",
- backgroundColor: mouseHoverIndex === index ? "#1f2023" : "inherit",
- cursor: "pointer",
- marginLeft: 5,
- marginRight: 5,
- maxHeight: 75,
- minHeight: 75,
- maxWidth: 420,
- minWidth: "100%",
- }
-
- var name = hit.name === undefined ?
- hit.filename.charAt(0).toUpperCase() + hit.filename.slice(1).replaceAll("_", " ") + " - " + hit.title
- :
- (hit.name.charAt(0).toUpperCase()+hit.name.slice(1)).replaceAll("_", " ")
-
- if (name.length > 30) {
- name = name.slice(0, 30)+"..."
- }
- const secondaryText = hit.data !== undefined ? hit.data.slice(0, 40)+"..." : ""
- const avatar = hit.image_url === undefined ?
- baseImage
- :
-
-
- var parsedUrl = hit.urlpath !== undefined ? hit.urlpath : ""
- parsedUrl += `?queryID=${hit.__queryID}`
- if (parsedUrl.includes("/apps/")) {
- const extraHash = hit.url_hash === undefined ? "" : `#${hit.url_hash}`
-
- parsedUrl = `/apps/${hit.filename}`
- parsedUrl += `?tab=docs&queryID=${hit.__queryID}${extraHash}`
- }
-
- return (
- {
- aa('init', {
- appId: searchClient.appId,
- apiKey: searchClient.transporter.queryParameters["x-algolia-api-key"]
- })
-
- const timestamp = new Date().getTime()
- aa('sendEvents', [
- {
- eventType: 'click',
- eventName: 'Document Clicked',
- index: 'documentation',
- objectIDs: [hit.objectID],
- timestamp: timestamp,
- queryID: hit.__queryID,
- positions: [hit.__position],
- userToken: userdata === undefined || userdata === null || userdata.id === undefined ? "unauthenticated" : userdata.id,
- }
- ])
-
- console.log("CLICK")
- setSearchOpen(true)
- }}>
- {
- setMouseHoverIndex(index)
- }}>
-
- {avatar}
-
-
- {/*
-
-
-
-
-
- */}
-
-
- )})
- }
-
- {type === "documentation" ?
-
-
- Search by
-
-
-
-
-
+ const fieldWidth = small === true ? 120 : 310
+ const modalView = (
+ // console.log("key:", dataValue.key),
+ //console.log("value:",dataValue.value),
+
- )
- }
-
- const CustomSearchBox = connectSearchBox(SearchBox)
- const CustomAppHits = connectHits(AppHits)
- const CustomWorkflowHits = connectHits(WorkflowHits)
- const CustomDocHits = connectHits(DocHits)
+
+
+
+
+
+
+ {/*
+ Discord
+ */}
+
+
+
+
+
+
+ Search by
+
+
+
+
+
+
+
+ );
return (
-
-
{
- console.log("CLICKED")
- }}>
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {modalView}
+
+
+
+ ),
+ endAdornment: (
+
+
+ + K
+
+ )
+ }}
+ variant="standard"
+ autoComplete='off'
+ color="primary"
+ placeholder="Search Apps, Workflows, Docs..."
+ onClick={(event) => {
+ setModalOpen(true)
+ }}
+ limit={5}
+ />
)
}
diff --git a/frontend/src/components/WorkflowTemplatePopup.jsx b/frontend/src/components/WorkflowTemplatePopup.jsx
index 9b283da9..ff20ad36 100644
--- a/frontend/src/components/WorkflowTemplatePopup.jsx
+++ b/frontend/src/components/WorkflowTemplatePopup.jsx
@@ -22,6 +22,7 @@ import {
Check as CheckIcon,
TrendingFlat as TrendingFlatIcon,
Close as CloseIcon,
+ East as EastIcon,
} from '@mui/icons-material';
import WorkflowTemplatePopup2 from "./WorkflowTemplatePopup.jsx";
@@ -36,6 +37,7 @@ const WorkflowTemplatePopup = (props) => {
const [errorMessage, setErrorMessage] = useState("");
const [workflowLoading, setWorkflowLoading] = useState(false);
const [workflow, setWorkflow] = useState({});
+ const [showLoginButton, setShowLoginButton] = useState(false);
const [appAuthentication, setAppAuthentication] = React.useState(undefined);
const [missingSource, setMissingSource] = React.useState(undefined)
@@ -119,7 +121,8 @@ const WorkflowTemplatePopup = (props) => {
const loadAppAuth = () => {
// Check if it exists, and has keys
if (userdata === undefined || userdata === null || Object.keys(userdata).length === 0) {
- setErrorMessage("You need to be logged in to try usecases. Redirecting in 5 seconds...")
+ setErrorMessage("You need to be logged in to try the pre-built Workflow Templates.")
+ setShowLoginButton(true)
// Send the user to the login screen after 3 seconds
setTimeout(() => {
@@ -350,12 +353,35 @@ const WorkflowTemplatePopup = (props) => {
{errorMessage !== "" ? errorMessage : ""}
+ {showLoginButton ?
+
+
+ Sign up
+
+
+
+ : null}
}
- {isLoggedIn && (missingSource !== undefined || missingDestination !== undefined) ?
-
- {"The following app category is required generate this workflow: "}
+ {(missingSource !== undefined || missingDestination !== undefined) ?
+
+ {"Find relevevant Apps for this Usecase"}
: null}
@@ -502,7 +528,7 @@ const WorkflowTemplatePopup = (props) => {
{parsedTitle}
-
+
{parsedDescription}
diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx
index 5f65e35a..9631fd1e 100755
--- a/frontend/src/views/Admin.jsx
+++ b/frontend/src/views/Admin.jsx
@@ -291,8 +291,6 @@ const Admin = (props) => {
//const alert = useAlert();
const handleStatusChange = (event) => {
const { value } = event.target;
- console.log("value: ", value)
-
setSelectedStatus(value);
@@ -331,7 +329,7 @@ const Admin = (props) => {
var your_apps = "- Connecting "
var subject_add = 0
- var subject = "Want to automate "
+ var subject = "POC to automate "
if (org.security_framework !== undefined && org.security_framework !== null) {
if (org.security_framework.cases.name !== undefined && org.security_framework.cases.name !== null && org.security_framework.cases.name !== "") {
@@ -400,7 +398,7 @@ const Admin = (props) => {
// Remove comma
- subject += "?"
+ //subject += "?"
your_apps = your_apps.substring(0, your_apps.length - 2)
}
@@ -432,12 +430,25 @@ const Admin = (props) => {
var admins = ""
// Loop users
+ var lastLogin = 0
for (var i = 0; i < users.length; i++) {
+ if (users[i].username.includes("shuffler")) {
+ continue
+ }
+
if (users[i].role === "admin") {
admins += users[i].username + ","
}
+
+ const data = users[i]
+ for (var i = 0; i < data.login_info.length; i++) {
+ if (data.login_info[i].timestamp > lastLogin) {
+ lastLogin = data.login_info[i].timestamp
+ }
+ }
}
+
// Remove last comma
admins = admins.substring(0, admins.length - 1)
@@ -452,15 +463,24 @@ const Admin = (props) => {
// Get drift username from userdata.username before @ in email
const username = userdata.username.substring(0, userdata.username.indexOf("@"))
- var body = `Hey,%0D%0A%0D%0AI saw you trying to use Shuffle, and thought we may be able to help. Right now, it looks like you have ${workflow_amount} workflows made, but it still doesn't look like you are getting the most out of Shuffle. If you're interested, I'd love to set up a quick call to see if we can help you get more out of Shuffle. %0D%0A%0D%0A
+ // Check if timestamp is more than 2 weeks ago and add "a while back" to the message
+ const timeComparison = 1209600
+ const extra_timestamp_text = lastLogin === 0 ? 0 : (Date.now()/1000 - lastLogin) > timeComparison ? " a while back" : ""
+ console.log("LAST LOGIN: " + lastLogin, extra_timestamp_text)
+
+ // Check if cloud sync is active, and if so, add a message about it
+ const cloudSyncInfo = selectedOrganization.cloud_sync === true ? "- Scale your onprem installation" : ""
+
+ var body = `Hey,%0D%0A%0D%0AI noticed you tried to use Shuffle${extra_timestamp_text}, and thought you may be interested in a POC. It looks like you have ${workflow_amount} workflows made, but it still doesn't look like you are getting what you wanted out of Shuffle. If you're interested, I'd love to set up a quick call to see if we can help you get more out of Shuffle. %0D%0A%0D%0A
Some of the things we can help with:%0D%0A
${your_apps}
- Configuring and authenticating your apps%0D%0A
${usecases}
-- Creating special usecases and apps%0D%0A%0D%0A
+- Multi-Tenancy and creating special usecases%0D%0A
+${cloudSyncInfo}%0D%0A
-Let me know if you're interested, or set up a call here: https://drift.me/${username}`
+If you're interested, please let me know a time that works for you, or set up a call here: https://drift.me/${username}`
return `mailto:${admins}?bcc=frikky@shuffler.io,binu@shuffler.io&subject=${subject}&body=${body}`
}
@@ -984,6 +1004,10 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
leads.push("old customer")
}
+ if (responseJson.lead_info.old_lead) {
+ leads.push("old lead")
+ }
+
if (responseJson.lead_info.tech_partner) {
leads.push("tech partner")
}
@@ -2428,7 +2452,7 @@ Let me know if you're interested, or set up a call here: https://drift.me/${user
renderValue={(selected) => selected.join(', ')}
MenuProps={MenuProps}
>
- {["contacted", "lead", "demo done", "pov", "customer", "open source", "student", "internal", "old customer", "creator", "tech partner"].map((name) => (
+ {["contacted", "lead", "demo done", "pov", "customer", "open source", "student", "internal", "creator", "tech partner", "old customer", "old lead", ].map((name) => (