diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 2a45fb5f..e9d6d683 100755 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,18 +1,17 @@ # Build environment -FROM node:18 as builder +FROM node:21 as builder RUN mkdir /usr/src/app - WORKDIR /usr/src/app ENV PATH /usr/src/app/node_modules/.bin:$PATH COPY package.json /usr/src/app/package.json # Nocache yarn install -RUN yarn config set "strict-ssl" false -g -RUN yarn install --network-timeout 1000000 +#RUN yarn config set "strict-ssl" false -g +#RUN yarn install --network-timeout 1000000 -#RUN npm install +RUN npm install --legacy-peer-deps # copy only required files to not trigger rebuilding every time COPY ./certs /usr/src/app/certs/ @@ -22,7 +21,8 @@ COPY ./*.sh /usr/src/app/ COPY ./*.json /usr/src/app/ #RUN rm -rf /usr/src/app/node_modules/webpack -RUN yarn build +#RUN yarn build --verbose +RUN npm run build --loglevel verbose 2>&1 # Production environment FROM nginx:1.21.5 diff --git a/frontend/package.json b/frontend/package.json index c45a9a9f..c8cb2465 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "shuffler", "homepage": "https://shuffler.io", - "version": "1.3.3", + "version": "1.4.0", "private": true, "dependencies": { "@babel/plugin-proposal-class-properties": "^7.18.6", @@ -27,7 +27,7 @@ "codemirror": "^6.0.1", "cpx": "^1.5.0", "create-react-app": "^5.0.1", - "cytoscape": "^3.23.0", + "cytoscape": "^3.29.2", "cytoscape-clipboard": "^2.2.1", "cytoscape-cxtmenu": "^3.4.0", "cytoscape-edgehandles": "^3.5.1", diff --git a/frontend/src/components/AppFramework.jsx b/frontend/src/components/AppFramework.jsx index a73be239..d119e708 100644 --- a/frontend/src/components/AppFramework.jsx +++ b/frontend/src/components/AppFramework.jsx @@ -31,8 +31,8 @@ import { Delete as DeleteIcon, } from "@mui/icons-material"; -import * as edgehandles from "cytoscape-edgehandles"; -import * as cytoscape from "cytoscape"; +import edgehandles from "cytoscape-edgehandles"; +import cytoscape from "cytoscape"; import { toast } from 'react-toastify'; cytoscape.use(edgehandles); diff --git a/frontend/src/components/AppGrid.jsx b/frontend/src/components/AppGrid.jsx index c75f2449..e84bbf35 100644 --- a/frontend/src/components/AppGrid.jsx +++ b/frontend/src/components/AppGrid.jsx @@ -18,7 +18,7 @@ import { toast } from "react-toastify" import ClearIcon from '@mui/icons-material/Clear'; import Box from '@mui/material/Box'; -import noImage from "../no_image.png" +// import noImage from "../no_image.png" import CircularProgress from '@mui/material/CircularProgress'; @@ -89,6 +89,7 @@ const AppGrid = (props) => { const innerColor = "rgba(255,255,255,0.65)"; const borderRadius = 3; window.title = "Shuffle | Apps | Find and integrate any app"; + const noImage = "/public/no_image.png"; const submitContact = (email, message) => { diff --git a/frontend/src/components/FilterCSS.css b/frontend/src/components/FilterCSS.css new file mode 100644 index 00000000..348fcbb1 --- /dev/null +++ b/frontend/src/components/FilterCSS.css @@ -0,0 +1,85 @@ +/* Style for the outer container */ +.ais-RefinementList { + justify-content: center; + } + + /* Style for the list */ + .ais-RefinementList-list { + list-style-type: none; + padding: 0; + } + + /* Style for each list item */ + .ais-RefinementList-item { + margin-bottom: 5px; + } + + /* Style for label */ + .ais-RefinementList-label { + cursor: pointer; + display: flex; + gap: 5px; + } + + /* Style for checkbox */ + .ais-RefinementList-checkbox { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + width: 16px; + height: 16px; + border: 1px solid #595b5e; + border-radius: 4px; + background-color: #27292d; + cursor: pointer; + flex-shrink: 0; + margin-top: "10px"; + } + + .ais-RefinementList-checkbox:checked { + background-color: rgb(248, 103, 67); + border-color: rgb(248, 103, 67); + width: 16px; + height: 16px; + } + + /* Style for checked state - inner dot */ + .ais-RefinementList-checkbox:checked::before { + content: "\2714"; + display: block; + width: 100%; + height: 100%; + text-align: center; + line-height: 18px; + color: #fff; + font-size: 14px; + } + + /* Style for hover state */ + /* .ais-RefinementList-checkbox:hover { + border-color: rgb(248, 103, 67); + } */ + + /* Style for label text */ + .ais-RefinementList-labelText { + /* margin-left: 5px; */ + font-size: 16px; + display: inline-flex; + flex-direction: row; + cursor: pointer; + } + + /* Style for count */ + .ais-RefinementList-count { + /* margin-left: 5px; + font-weight: bold; + color: gray; */ + display: none; + } + .ais-ClearRefinements-button { + cursor: pointer; + color: rgb(248, 103, 67); + border: none; + font-size: 16px; + background-color: transparent; + } \ No newline at end of file diff --git a/frontend/src/components/NewHeader.jsx b/frontend/src/components/NewHeader.jsx index f94dfb57..def025c2 100644 --- a/frontend/src/components/NewHeader.jsx +++ b/frontend/src/components/NewHeader.jsx @@ -103,7 +103,8 @@ const Header = (props) => { serverside === true || typeof window === "undefined" ? true : window.location.host === "localhost:3002" || - window.location.host === "shuffler.io"; + window.location.host === "shuffler.io" || + window.location.host === "localhost:5002"; const clearNotifications = () => { // Don't really care about the logout diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index a678bf3b..a02f0930 100755 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -216,22 +216,32 @@ const Admin = (props) => { getUsers(); setTimeout(() => { - if (adminTab === 3) { - window.scroll({ - top: 450, - left: 0, - behavior: "smooth", - }); - } + const urlSearchParams = new URLSearchParams(window.location.search); + const params = Object.fromEntries(urlSearchParams.entries()); + const foundTab = params["admin_tab"] + if (foundTab !== null && foundTab !== undefined) { + if (adminTab === 3) { + window.scroll({ + top: 450, + left: 0, + behavior: "smooth", + }); + } + } }, 1500); }, []); useEffect(() => { - window.scroll({ - top: 450, - left: 0, - behavior: "smooth", - }); + const urlSearchParams = new URLSearchParams(window.location.search); + const params = Object.fromEntries(urlSearchParams.entries()); + const foundTab = params["admin_tab"] + if (foundTab !== null && foundTab !== undefined) { + window.scroll({ + top: 450, + left: 0, + behavior: "smooth", + }) + } }, [adminTab]); useEffect(() => { @@ -759,7 +769,7 @@ If you're interested, please let me know a time that works for you, or set up a // setPipelines(responseJson.pipelines || []); }) .catch((error) => { - toast(error.toString()); + // toast(error.toString()); }); }; @@ -3342,7 +3352,7 @@ If you're interested, please let me know a time that works for you, or set up a color="textSecondary" style={{ marginLeft: 0 }} > - On this page organization admins can configure organisations, and + On this page organization admins can configure organizations, and sub-orgs (MSSP).{" "} { props.userdata.active_org !== undefined ? props.userdata.active_org.cloud_sync === true : false; - const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; + const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "migration.shuffler.io"; const appBarSize = isCloud ? 75 : 72; const triggerEnvironments = isCloud ? ["cloud"] : ["onprem", "cloud"]; @@ -4016,42 +4013,50 @@ const AngularWorkflow = (defaultprops) => { workflow.actions.push(newNodeData); - const sourcebranches = workflow.branches.filter( - (foundbranch) => foundbranch.source_id === parentNode.data("id") - ); - const destinationbranches = workflow.branches.filter( - (foundbranch) => - foundbranch.destination_id === parentNode.data("id") - ); + const sourcebranches = workflow.branches.filter((foundbranch) => foundbranch.source_id === parentNode.data("id")) + + + const destinationbranches = workflow.branches.filter((foundbranch) => foundbranch.destination_id === parentNode.data("id")) + for (var sourceBranchesKey in sourcebranches) { var newbranch = JSON.parse(JSON.stringify(sourcebranches[sourceBranchesKey])); - newbranch.id = uuidv4(); - newbranch.source_id = newNodeData.id; - newbranch._id = newbranch.id; - newbranch.source = newbranch.source_id; - newbranch.target = newbranch.destination_id; - cy.add({ - group: "edges", - data: newbranch, - }); + newbranch.id = uuidv4() + newbranch.source_id = newNodeData.id + + newbranch._id = newbranch.id + newbranch.source = newbranch.source_id + newbranch.target = newbranch.destination_id + cy.add({ + group: "edges", + data: newbranch, + }) } for (var destinationBranchesKey in destinationbranches) { - var newbranch = JSON.parse( - JSON.stringify(destinationbranches[destinationBranchesKey]) - ); - newbranch.id = uuidv4(); - newbranch.destination_id = newNodeData.id; + var newbranch = JSON.parse(JSON.stringify(destinationbranches[destinationBranchesKey])) - newbranch._id = newbranch.id; - newbranch.source = newbranch.source_id; - newbranch.target = newbranch.destination_id; - cy.add({ - group: "edges", - data: newbranch, - }); + const sourcenode = cy.getElementById(newbranch.source_id) + if (sourcenode !== null && sourcenode !== undefined) { + const sourcedata = sourcenode.data() + + if (sourcedata.trigger_type !== "SUBFLOW" && sourcedata.trigger_type !== "USERINPUT") { + continue + } + + } + + newbranch.id = uuidv4() + newbranch.destination_id = newNodeData.id + + newbranch._id = newbranch.id + newbranch.source = newbranch.source_id + newbranch.target = newbranch.destination_id + cy.add({ + group: "edges", + data: newbranch, + }) } //event.target.unselect(); @@ -4803,7 +4808,7 @@ const AngularWorkflow = (defaultprops) => { event.target.remove() //console.log("Found branch already!") - toast("Triggers can have exactly one target node") + toast.error("Triggers can have exactly one target node") return @@ -5214,7 +5219,7 @@ const AngularWorkflow = (defaultprops) => { data: newdata, }) - toast("You must STOP the trigger before deleting its branches") + toast.error("You must STOP the trigger before deleting its branches") } catch (e) { console.log("Failed re-adding edge: ", e) } diff --git a/frontend/src/views/EditWorkflow.jsx b/frontend/src/views/EditWorkflow.jsx index 29066fef..bf30f62f 100755 --- a/frontend/src/views/EditWorkflow.jsx +++ b/frontend/src/views/EditWorkflow.jsx @@ -207,7 +207,7 @@ const EditWorkflow = (props) => { const cyDummy = cytoscape(); if (!cyDummy.edgehandles) { - cytoscape.use(edgehandles); + //cytoscape.use(edgehandles); } });