diff --git a/frontend/src/components/AppGrid.jsx b/frontend/src/components/AppGrid.jsx index befdf4c9..0f3fedef 100644 --- a/frontend/src/components/AppGrid.jsx +++ b/frontend/src/components/AppGrid.jsx @@ -989,7 +989,7 @@ const AppGrid = (props) => { }} autoComplete="off" color="primary" - placeholder="Search more than 2500 Apps" + placeholder="Search your Activated or Self-built apps" id="shuffle_search_field" onChange={(event) => { setSearchQuery(event.currentTarget.value); @@ -1008,7 +1008,7 @@ const AppGrid = (props) => { useEffect(() => { if (currTab === 2) { const baseUrl = globalUrl; - const userAppsUrl = `${baseUrl}/api/v1/users/apps`; + const userAppsUrl = `${baseUrl}/api/v1/users/me/apps`; fetch(userAppsUrl, { method: "GET", credentials: "include", @@ -1559,8 +1559,8 @@ const AppGrid = (props) => { //Component to fetch all apps created by user and Org const UserAndOrgApps = ({ selectedCategoryForUsersAndOgsApps, selectedTagsForUserAndOrgApps, selectedOptionOfCreatedWith, setselectedCategoryForUsersAndOgsApps, setSelectedTagsForUserAndOrgApps, setSelectedOptionOfCreatedWith }) => { - const [searchQuery, setSearchQuery] = useState(""); + const [searchQuery, setSearchQuery] = useState(""); const [appsToShow, setAppsToShow] = useState([]); useEffect(() => { if (currTab === 1) { diff --git a/frontend/src/components/OrgHeaderexpanded.jsx b/frontend/src/components/OrgHeaderexpanded.jsx index 6946de94..19352b66 100644 --- a/frontend/src/components/OrgHeaderexpanded.jsx +++ b/frontend/src/components/OrgHeaderexpanded.jsx @@ -5,7 +5,7 @@ import theme from '../theme.jsx'; import { toast } from "react-toastify" import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; -import AuthenticationData from "./AuthenticationWindow"; +import SubflowSuggestions from "../components/SubflowSuggestions.jsx"; import { FormControl, @@ -45,7 +45,7 @@ const useStyles = makeStyles({ notchedOutline: { borderColor: "#f85a3e !important", }, -}); +}) const OrgHeaderexpanded = (props) => { const { @@ -113,6 +113,7 @@ const OrgHeaderexpanded = (props) => { ? "" : selectedOrganization.sso_config.sso_certificate ); + const [notificationWorkflow, setNotificationWorkflow] = React.useState( selectedOrganization.defaults === undefined ? "" @@ -120,7 +121,7 @@ const OrgHeaderexpanded = (props) => { selectedOrganization.defaults.notification_workflow.length === 0 ? "" : selectedOrganization.defaults.notification_workflow - ); + ) const [documentationReference, setDocumentationReference] = React.useState( selectedOrganization.defaults === undefined @@ -166,25 +167,6 @@ const OrgHeaderexpanded = (props) => { const [workflows, setWorkflows] = React.useState([]) const [workflow, setWorkflow] = React.useState({}) - // notification workflow - const [notificationWorkflowModal, setNotificationWorkflowModal] = React.useState(false); - const [selectedAppDetails, setSelectedAppDetails] = React.useState({}); - const [notificationWorkflowTestModal, setNotificationWorkflowTestModal] = React.useState(false); - const [selectedAuth, setSelectedAuth] = React.useState(''); - const [emailData,setEmailData] = React.useState([]); - const [notificationAppDetails, setNotificationAppDetails] = React.useState([]); - const [generatedWorkflow, setGeneatedWorkflow] = React.useState({}); - - - // for jira & email modal - const [textFieldValue, setTextFieldValue] = React.useState(""); - const [textFieldOneValue, setTextFieldOneValue] = React.useState(""); - - useEffect(() => { - let nameList = notificationAppList.length > 0? notificationAppList.map(item => item.name): ["email"]; - prepareNotificationAppList(nameList) - }, [notificationAppList,workflows]); - const getAvailableWorkflows = (trigger_index) => { fetch(globalUrl + "/api/v1/workflows", { method: "GET", @@ -351,142 +333,13 @@ const OrgHeaderexpanded = (props) => { }) } - // getting comms & cases app from app framework - var notificationAppList = []; - if (selectedOrganization.security_framework.cases && selectedOrganization.security_framework.cases.name.length > 0) { - notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.cases); - } - if (selectedOrganization.security_framework.communication && selectedOrganization.security_framework.communication.name.length > 0) { - notificationAppList = notificationAppList.concat(selectedOrganization.security_framework.communication); - } - const mergeAuthData = (result, responseJson) => { - const updatedResult = result.map(item => { - const matches = responseJson.filter(authItem => authItem.app.name === item.name); - return { - ...item, - authentication_data: matches.length > 0 ? matches : null - }; - }); - return updatedResult; - }; + - const prepareNotificationAppList = async (appList) => { - // getting App ID,Authentication fields and saved auths for each app - var result = [] - fetch(globalUrl + "/api/v1/apps", { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - credentials: "include", - }).then((response) => { - if (response.status !== 200) { - toast("Failed getting app ids: ", response.reason); - console.log("Status not 200 for app ids :O!"); - return; - } - return response.json(); - }).then((responseJson) => { - if (responseJson !== undefined) { - const filteredApps = responseJson.filter(app => appList.includes(app.name)); - const emailData = responseJson.filter(app => app.name === "email") - setEmailData(emailData) - const appDetails = filteredApps.map(app => ({ name: app.name, id: app.id })); //mapped apps with IDs as sometime Ids were not correct in security framework - // console.log("appDetails: ", appDetails) - // result = appDetails - - fetch(globalUrl + "/api/v1/apps/authentication", { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - credentials: "include", - }) - .then((response) => { - if (response.status !== 200) { - toast(`Failed getting auth for : `, response.reason); - console.log("Status not 200 for app auth :O!"); - return; - } - return response.json(); - }).then(async (responseJson) => { - if (!responseJson.success) { - console.log("Could not get app auth") - return; - } - // console.log("responseJson of auth: ", responseJson.data) - result = await mergeAuthData(appDetails, responseJson.data) - // console.log("merged auth data: ", result) - // console.log("result", result) - result.map(item => { - fetch(globalUrl + `/api/v1/apps/${item.id}/config`, { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - credentials: "include", - }).then((response) => { - if (response.status !== 200) { - toast(`Failed getting config for ${item.id}: `, response.reason); - console.log("Status not 200 for app config :O!"); - return; - } - return response.json(); - }).then((responseJson) => { - if (!responseJson.success) { - console.log("Could not get app config") - return; - } - var decodedString = JSON.parse(atob(responseJson.app)); - // console.log("dcodedString: ",decodedString) - item.auth_config = decodedString.authentication - item.large_image = decodedString.large_image - setNotificationAppDetails(result) - console.log("notificationAppDetails: ", notificationAppDetails) - }).then(async()=>{ - await checkIfAlreadyGenerated(appList,workflows); - - }).catch((error) => { - console.log("Error getting app config: " + error); - toast("Error getting app config: " + error); - }) - }) - }) - } - }).catch((error) => { - console.log("Error getting app ids: " + error); - }) - } + - const executeTestWorkflow = async (workflowid) => { - const data = { "execution_argument": '{"title":"THIS IS TEST ALERT","description":"TEST ALERT FROM SHUFFLE","reference_url": "shuffler.io"}' } - fetch(globalUrl + `/api/v1/workflows/${workflowid}/execute`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify(data), - credentials: "include", - }) - .then((response) => { - if (response.status !== 200) { - toast("Failed setting notification workflow: ", response.reason); - console.log("Status not 200 for workflows :O!"); - return; - } - toast("Notification workflow ran successfully"); - return response.json(); - }).catch((error) => { - console.log("Error getting workflows: " + error); - }) -} - + const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId,issuetype) => { //currently only supports JIRA figure out a way to support more apps var workflowName = `[GENERATED] ${appname} notification workflow` @@ -615,379 +468,7 @@ const generateNotificationWorkflow = async (appname,appImage,appAuthId,projectId }) } -const generateEmailNotificationWorkflow = async (appname,appImage,shuffleAPIKey,recepients) => { - //currently only supports figure out a way to support more apps - var workflowName = `[GENERATED] ${appname} notification workflow` - var workflowDescription = "Generated by Shuffle for sending info/error notifications." - var data = { - "name": workflowName, - "description": workflowDescription, - } - - fetch(globalUrl + "/api/v1/workflows", { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify(data), - credentials: "include", - }) - .then((response) => { - if (response.status !== 200) { - toast("Failed setting notification workflow: ", response.reason); - console.log("Status not 200 for workflows :O!"); - return; - } - return response.json(); - }).then((responseJson)=>{ - if (responseJson !== undefined) { - console.log("Notification workflow created successfully") - var workflow_id = responseJson.id - if (appname.toLowerCase() === "email"){ - console.log("updating workflow for email") - var workflowBody = { - "name": workflowName, - "Description": workflowDescription, - "id": workflow_id, - "actions": [ - { - "app_name": "email", - "name": "send_email_shuffle", - "large_image":appImage, - "isStartNode": true, - "label": "send_email_shuffle", - "app_version": "1.3.0", - "parameters": [ - { - "name": "apikey", - "value": shuffleAPIKey - }, - { - "name": "recipients", - "value": recepients - }, - { - "name": "subject", - "value": "$exec.title" - }, - { - "name":"body", - "value":"$exec.description" - } - ] - } - ] - } - } - fetch(globalUrl + `/api/v1/workflows/${workflow_id}`, { - method: "PUT", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify(workflowBody), - credentials: "include", - }) - .then((response) => { - if (response.status !== 200) { - toast("Failed setting notification workflow: ", response.reason); - console.log("Status not 200 for workflows :O!"); - return; - } - return response.json(); - }).then((responseJson)=>{ - if (responseJson !== undefined) { - handleEditOrg( - orgName, - orgDescription, - selectedOrganization.id, - selectedOrganization.image, - { - app_download_repo: appDownloadUrl, - app_download_branch: appDownloadBranch, - workflow_download_repo: workflowDownloadUrl, - workflow_download_branch: workflowDownloadBranch, - notification_workflow: workflow_id, - documentation_reference: documentationReference, - }, - { - sso_entrypoint: ssoEntrypoint, - sso_certificate: ssoCertificate, - client_id: openidClientId, - client_secret: openidClientSecret, - openid_authorization: openidAuthorization, - openid_token: openidToken, - } - ) - console.log("Notification workflow updated successfully") - toast("Notification workflow updated successfully") - } - }) - } - }).catch((error) => { - console.log("Error setting workflows: " + error); - }) -} - - -const testWorkflowModal = notificationWorkflowTestModal ? - ( { - setNotificationWorkflowTestModal(false); - }} - > - - {/* -
- Notification workflow -
-
*/} - - We have updated the Notification workflow. Do you want to test it? - - - - - -
-
) : null - -const modalView = notificationWorkflowModal ? ( - { - setNotificationWorkflowModal(false); - }} - > - - -
- {`Configure ${selectedAppDetails.name} workflow`} -
-
- - - {console.log("len Selected app details: ", selectedAppDetails)} - {(selectedAppDetails.authentication_data || (selectedAppDetails.auth_config && selectedAppDetails.auth_config.required == false) || (selectedAppDetails.authentication && selectedAppDetails.authentication.required == false)) ? - <> - - {(selectedAppDetails.auth_config && selectedAppDetails.auth_config.required == false || (selectedAppDetails.authentication && selectedAppDetails.authentication.required == false)) ? "No authentication required": - <> - - Pick an authentication method from the list - - - Available authentications - - } - - - - Provide additional required details: - - { - setTextFieldOneValue(e.target.value) - }} - InputProps={{ - classes: { - notchedOutline: classes.notchedOutline, - }, - style: { - color: "white", - }, - }} /> - { - setTextFieldValue(e.target.value) - }} - InputProps={{ - classes: { - notchedOutline: classes.notchedOutline, - }, - style: { - color: "white", - }, - }} /> - - : - <> - 0) ? false : true} - // // setAuthenticationModalOpen={false} - selectedApp={{...selectedAppDetails,authentication: selectedAppDetails.auth_config}} - // getAppAuthentication={selectedAppDetails.name} - /> - - } - - - - - -
-
-) : null - - - const checkIfAlreadyGenerated = async (appList, workflows) => { // fixxxxxxxxxxxxxxxxxxxxx - - var workflowName = workflows.find(workflow => workflow.id === notificationWorkflow) - if (workflowName) { - workflowName = workflowName.name - } - else { - console.log("no workflow set") - return - } - if (workflowName) { - const parts = workflowName.split(' '); - console.log("parts", parts) - if (parts[0].toString() === "[GENERATED]" && parts.length > 1) { - console.log("parts1", parts[1]) - if ((appList.includes(parts[1]))) { - console.log("workflow already generated") - setGeneatedWorkflow({"app_name": parts[1]}) - } - } - } - else { - return - } - } - -const renderChips = (apps) => { - return ( - - {apps.map((app) => ( - { - console.log(`Clicked ${app.name}`) - console.log("app: ",app) - setSelectedAppDetails(app) - if (app.authentication_data && app.authentication_data.length > 0){ //fixxxxxxxx - console.log("authdata: ",app.authentication_data[0]) - setSelectedAuth(app.authentication_data[app.authentication_data.length-1].id) - } - setNotificationWorkflowModal(true) - // getAppAuth(app.name) - console.log("selectedAppDEtails",selectedAppDetails) - }} - avatar={{app.name}} - - /> - ))} - - ); -}; + return (
@@ -995,11 +476,18 @@ const renderChips = (apps) => { Notification Workflow - {modalView} - {/*{testWorkflowModal} */} -
- {renderChips(notificationAppDetails.length > 0 ? notificationAppDetails : emailData)} -
+ + {/* + + */} + +
{workflows !== undefined && workflows !== null && workflows.length > 0 ? { return "The app's Docker Image is not available in the environment yet. Re-run the app to force a re-download of the app. If the problem persists, contact support" } - if (result.status !== 200 && stringjson.includes("192.168") || stringjson.includes("172.16") || stringjson.includes("10.0")) { + if (result.status !== 200 && (result.url.includes("192.168") || result.url.includes("172.16") || result.url.includes("10.0"))) { return "Consider whether your Orborus environment can connect to a local IP or not." } diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index 32fc5509..4f82f517 100755 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -1678,6 +1678,7 @@ const Workflows = (props) => { const [hover, setHover] = React.useState(false); const innerColor = "rgba(255,255,255,0.3)" + const setupPaperStyle = { minHeight: paperAppStyle.minHeight, maxWidth: "100%", @@ -1691,7 +1692,7 @@ const Workflows = (props) => { cursor: "pointer", backgroundColor: hover ? "rgba(39,41,45,0.5)" : "rgba(39,41,45,1)", borderRadius: paperAppStyle.borderRadius, - }; + } return ( @@ -1763,7 +1764,8 @@ const Workflows = (props) => { const menuClick = (event) => { setOpen(!open); setAnchorEl(event.currentTarget); - }; + } + var parsedName = data.name; if ( @@ -1776,8 +1778,9 @@ const Workflows = (props) => { const actions = data.actions !== null ? data.actions.length : 0; const appGroup = getWorkflowAppgroup(data) - const [triggers, subflows] = getWorkflowMeta(data); + const [triggers, subflows] = getWorkflowMeta(data) + const isDistributed = data.suborg_distribution !== undefined && data.suborg_distribution !== null && data.suborg_distribution.includes(userdata.active_org.id) const workflowMenuButtons = ( { } return ( -
+
- {selectedCategory !== "" ? - -
{ - addFilter(selectedCategory) - }} - /> - - : null} + {selectedCategory !== "" ? + +
{ + addFilter(selectedCategory) + }} + /> + + : null}