From a4ebf3e55839710924a97a4bdd8968e7f1724a0b Mon Sep 17 00:00:00 2001 From: Frikky Date: Mon, 19 May 2025 00:04:37 +0200 Subject: [PATCH] Lightmode/Darkmode merge including many fixes since 2.0.2 --- backend/go-app/go.mod | 2 +- frontend/public/images/icons/shuffleLogo.svg | 5 + frontend/src/components/AdminNavBar.jsx | 282 +++- frontend/src/components/ApiExplorer.jsx | 82 +- frontend/src/components/AppAuthTab.jsx | 120 +- frontend/src/components/AppCreationModal.jsx | 38 +- frontend/src/components/AppModal.jsx | 49 +- frontend/src/components/AppSearchButtons.jsx | 19 +- frontend/src/components/AppStats.jsx | 11 +- frontend/src/components/Appsearch.jsx | 15 +- frontend/src/components/Billing.jsx | 649 ++++++++- frontend/src/components/BillingStats.jsx | 50 +- frontend/src/components/CacheView.jsx | 101 +- frontend/src/components/ChatBot.jsx | 846 ++++++++++++ frontend/src/components/CloudSyncTab.jsx | 49 +- frontend/src/components/ConfigureWorkflow.jsx | 10 +- frontend/src/components/EditOrgTab.jsx | 18 +- frontend/src/components/EditWorkflow.jsx | 49 +- frontend/src/components/EnvironmentTab.jsx | 113 +- frontend/src/components/Files.jsx | 154 ++- frontend/src/components/LeftSideBar.jsx | 848 ++++++------ frontend/src/components/LicencePopup.jsx | 36 +- frontend/src/components/Navbar.jsx | 166 ++- frontend/src/components/Oauth2Auth.jsx | 13 +- frontend/src/components/OrgHeaderNew.jsx | 28 +- .../src/components/OrgHeaderexpandedNew.jsx | 96 +- frontend/src/components/OrganizationTab.jsx | 72 +- frontend/src/components/ParsedAction.jsx | 181 ++- frontend/src/components/Priorities.jsx | 125 +- frontend/src/components/Priority.jsx | 22 +- frontend/src/components/RecentWorkflow.jsx | 13 +- frontend/src/components/RenderCytoscape.jsx | 10 +- frontend/src/components/RuntimeDebugger.jsx | 61 +- frontend/src/components/SchedulesTab.jsx | 117 +- frontend/src/components/SearchData.jsx | 50 +- frontend/src/components/Searchfield.jsx | 7 +- .../src/components/ShuffleCodeEditor1.jsx | 48 +- frontend/src/components/TenantsTab.jsx | 131 +- frontend/src/components/UserManagmentTab.jsx | 126 +- .../src/components/WorkflowTemplatePopup2.jsx | 24 +- frontend/src/components/ssoTab.jsx | 141 +- frontend/src/context/ContextApi.jsx | 74 +- frontend/src/defaultCytoscapeStyle.jsx | 1181 +++++++++-------- frontend/src/theme.jsx | 296 ++++- frontend/src/views/Admin2.jsx | 15 +- frontend/src/views/AngularWorkflow.jsx | 1147 +++++++++------- frontend/src/views/ApiExplorerWrapper.jsx | 9 +- frontend/src/views/AppCreator.jsx | 312 +++-- frontend/src/views/AppExplorer.jsx | 156 ++- frontend/src/views/Apps2.jsx | 129 +- frontend/src/views/Docs.jsx | 116 +- frontend/src/views/LoginPage.jsx | 2 +- frontend/src/views/RunWorkflow.jsx | 8 +- frontend/src/views/SetAuthentication.jsx | 7 +- frontend/src/views/SettingsPage.jsx | 49 +- frontend/src/views/UpdateAuthentication.jsx | 7 +- frontend/src/views/Usecases2.jsx | 30 +- frontend/src/views/Workflows.jsx | 110 ++ frontend/src/views/Workflows2.jsx | 267 ++-- 59 files changed, 5931 insertions(+), 2961 deletions(-) create mode 100755 frontend/public/images/icons/shuffleLogo.svg create mode 100644 frontend/src/components/ChatBot.jsx diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index ea02517b..6e354ef6 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -23,7 +23,7 @@ require ( github.com/h2non/filetype v1.1.3 github.com/satori/go.uuid v1.2.0 github.com/shuffle/shuffle-shared v0.8.50 - golang.org/x/crypto v0.36.0 + golang.org/x/crypto v0.37.0 google.golang.org/api v0.228.0 google.golang.org/grpc v1.71.1 gopkg.in/yaml.v3 v3.0.1 diff --git a/frontend/public/images/icons/shuffleLogo.svg b/frontend/public/images/icons/shuffleLogo.svg new file mode 100755 index 00000000..1024dd6a --- /dev/null +++ b/frontend/public/images/icons/shuffleLogo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/src/components/AdminNavBar.jsx b/frontend/src/components/AdminNavBar.jsx index e0faec6e..a37b8c15 100644 --- a/frontend/src/components/AdminNavBar.jsx +++ b/frontend/src/components/AdminNavBar.jsx @@ -19,17 +19,97 @@ import { FmdGoodOutlined as FmdGoodOutlinedIcon, GroupOutlined as GroupOutlinedIcon } from '@mui/icons-material'; -import theme from '../theme.jsx'; -import { Button, Tooltip } from '@mui/material'; +import theme, { getTheme } from '../theme.jsx'; +import { Button, Skeleton, Tooltip } from '@mui/material'; import { Index } from 'react-instantsearch-dom'; import { Context } from '../context/ContextApi.jsx'; +import { toast } from 'react-toastify'; const AdminNavBar = (props) => { const location = useLocation(); - const { globalUrl, userdata, isCloud, isLoaded,removeCookie, handleStatusChange, selectedStatus, setSelectedStatus, handleEditOrg, serverside, notifications, handleGetOrg, orgId, checkLogin, setNotifications, stripeKey, setSelectedOrganization, selectedOrganization } = props; + const { globalUrl, userdata, isCloud,isOrgLoaded, isLoaded,removeCookie, handleStatusChange, selectedStatus, setSelectedStatus, handleEditOrg, serverside, notifications, handleGetOrg, orgId, checkLogin, setNotifications, stripeKey, setSelectedOrganization, selectedOrganization } = props; const [selectedItem, setSelectedItem] = useState("Organization"); const [isSelectedFiles, setIsSelectedFiles] = useState(true); const [isSelectedDataStore, setIsSelectedDataStore] = useState(true); + const [isIntegrationPartner, setIsIntegrationPartner] = useState(false); + const [isChildOrg, setIsChildOrg] = useState(false); + const [isGlobalUser, setIsGlobalUser] = useState(false); + const [visibleItems, setVisibleItems] = useState([]); + const [isUserDataLoaded, setIsUserDataLoaded] = useState(false); + + const items = [ + { iconSrc: , alt: "Organization Icon", text: "Organization", component: OrganizationTab, props: { isIntegrationPartner, isChildOrg, isGlobalUser, globalUrl,removeCookie, selectedStatus, isLoaded, setSelectedStatus, handleStatusChange, handleEditOrg, handleGetOrg, userdata, isCloud, serverside, notifications, checkLogin, setNotifications, stripeKey, setSelectedOrganization, selectedOrganization } }, + { iconSrc: , alt: "Users Icon", text: "Users", component: UserManagmentTab, props: { globalUrl, userdata, serverside, isCloud, selectedOrganization, setSelectedOrganization, handleEditOrg } }, + { iconSrc: , alt: "App Auth Icon", text: "App_auth", component: AppAuthTab, props: { globalUrl, userdata, isCloud, selectedOrganization } }, + { iconSrc: , alt: "Datastore Icon", text: "Datastore", component: CacheView, props: { globalUrl, userdata, selectedOrganization, serverside, isSelectedDataStore, orgId , isCloud} }, + { iconSrc: , alt: "Files Icon", text: "Files", component: Files, props: { isCloud, globalUrl, userdata, serverside, selectedOrganization, isSelectedFiles } }, + { iconSrc: , alt: "Trigger Icon", text: "Triggers", component: SchedulesTab, props: { globalUrl, userdata, isCloud, serverside } }, + { iconSrc: , alt: "Environments Icon", text: "Locations", component: EnvironmentTab, props: { globalUrl, userdata, isCloud, selectedOrganization } }, + { iconSrc: , alt: "Tenants Icon", text: "Tenants", component: TenantsTab, props: {isCloud, globalUrl, userdata, serverside, selectedOrganization, setSelectedOrganization, checkLogin } } + ]; + + + useEffect(() => { + if (userdata && userdata?.active_org?.id?.length > 0) { + setIsUserDataLoaded(true); + } + }, [userdata]); + + + + const { themeMode, brandColor } = React.useContext(Context); + const theme = getTheme(themeMode, brandColor); + + const HandlePartnerChange = () => { + if (userdata?.id?.length > 0) { + const isIntegrationPartner = userdata?.org_status?.includes("integration_partner") || false; + setIsIntegrationPartner(isIntegrationPartner); + const isChildOrg = userdata?.org_status?.includes("sub_org") || false; + setIsChildOrg(isChildOrg); + const isGlobalUser = userdata?.active_org?.branding?.global_user || false; + setIsGlobalUser(isGlobalUser); + } else { + setIsIntegrationPartner(false); + setIsChildOrg(false); + setIsGlobalUser(false); + } + } + + useEffect(() => { + if (userdata && userdata?.id?.length > 0) { + HandlePartnerChange(); + } + }, [userdata]); + + const HandleVisibleTabs = () => { + if (userdata?.id?.length > 0) { + if (userdata?.active_org?.role === "admin" || userdata?.support) { + setVisibleItems(items); + }else { + const filteredItems = items.filter(item => item.text !== "Users" && item.text !== "Files" && item.text !== "Datastore" && item.text !== "Triggers" && item.text !== "Locations"); + setVisibleItems(filteredItems); + } + } + } + + useEffect(() => { + if (isIntegrationPartner && isChildOrg && !isGlobalUser) { + // Filter out Users and Tenants tabs + if (userdata?.active_org?.role === "admin" || userdata?.support) { + const filteredItems = items.filter(item => + item.text !== "Users" && item.text !== "Tenants" + ); + setVisibleItems(filteredItems); + }else { + const filteredItems = items.filter(item => + item.text !== "Users" && item.text !== "Tenants" && item.text !== "Files" && item.text !== "Datastore" && item.text !== "Triggers" && item.text !== "Locations" + ); + setVisibleItems(filteredItems); + } + } else { + HandleVisibleTabs(); + } + }, [isIntegrationPartner, isChildOrg, isGlobalUser, selectedOrganization, userdata]); const navigate = useNavigate(); @@ -52,18 +132,6 @@ const AdminNavBar = (props) => { setSelectedItem("Organization"); } }, [location.search]); - - - const items = [ - { iconSrc: , alt: "Organization Icon", text: "Organization", component: OrganizationTab, props: { globalUrl,removeCookie, selectedStatus, isLoaded, setSelectedStatus, handleStatusChange, handleEditOrg, handleGetOrg, userdata, isCloud, serverside, notifications, checkLogin, setNotifications, stripeKey, setSelectedOrganization, selectedOrganization } }, - { iconSrc: , alt: "Users Icon", text: "Users", component: UserManagmentTab, props: { globalUrl, userdata, serverside, isCloud, selectedOrganization, setSelectedOrganization, handleEditOrg } }, - { iconSrc: , alt: "App Auth Icon", text: "App_auth", component: AppAuthTab, props: { globalUrl, userdata, isCloud, selectedOrganization } }, - { iconSrc: , alt: "Datastore Icon", text: "Datastore", component: CacheView, props: { globalUrl, userdata, selectedOrganization, serverside, isSelectedDataStore, orgId , isCloud} }, - { iconSrc: , alt: "Files Icon", text: "Files", component: Files, props: { isCloud, globalUrl, userdata, serverside, selectedOrganization, isSelectedFiles } }, - { iconSrc: , alt: "Trigger Icon", text: "Triggers", component: SchedulesTab, props: { globalUrl, userdata, isCloud, serverside } }, - { iconSrc: , alt: "Environments Icon", text: "Locations", component: EnvironmentTab, props: { globalUrl, userdata, isCloud, selectedOrganization } }, - { iconSrc: , alt: "Tenants Icon", text: "Tenants", component: TenantsTab, props: {isCloud, globalUrl, userdata, serverside, selectedOrganization, setSelectedOrganization, checkLogin } } - ]; const setConfig = (newValue) => { setSelectedItem(newValue); @@ -76,12 +144,65 @@ const AdminNavBar = (props) => { } }; + useEffect(() => { + if (isIntegrationPartner && isChildOrg && !isGlobalUser && isOrgLoaded && isUserDataLoaded) { + const queryParams = new URLSearchParams(location.search); + const tabName = queryParams?.get('admin_tab')?.toLowerCase(); + if (tabName === "sso" || tabName === "branding") { + toast.info("You are not allowed to access this tab. Please contact your admin for more information. Redirecting to Organization Configuration tab."); + setTimeout(() => { + setSelectedItem("Organization"); + navigate(`?admin_tab=org_config`, { replace: true }); + window.location.reload(); + } + , 3000); + } + + const params = new URLSearchParams(location.search); + const tab = params?.get('tab')?.toLowerCase(); + if (tab === "users" || tab === "tenants") { + toast.info("You are not allowed to access this tab. Please contact your admin for more information. Redirecting to Organization Configuration tab."); + setTimeout(() => { + setSelectedItem("Organization"); + navigate(`?admin_tab=org_config`, { replace: true }); + window.location.reload(); + } + , 3000); + } + } else if (userdata && isOrgLoaded && isUserDataLoaded && userdata?.active_org?.role !== "admin" && !userdata?.support) { + const queryParams = new URLSearchParams(location.search); + const tabName = queryParams?.get('admin_tab')?.toLowerCase(); + if (tabName === "sso") { + toast.info("You are not allowed to access this tab. Please contact your admin for more information. Redirecting to Organization Configuration tab."); + setTimeout(() => { + setSelectedItem("Organization"); + navigate(`?admin_tab=org_config`, { replace: true }); + window.location.reload(); + } + , 3000); + } + + const params = new URLSearchParams(location.search); + const tab = params?.get('tab')?.toLowerCase(); + if (tab === "users" || tab === "locations" || tab === "environments" || tab === "files" || tab === "datastore" || tab === "triggers") { + toast.info("You are not allowed to access this tab. Please contact your admin for more information. Redirecting to Organization Configuration tab."); + setTimeout(() => { + setSelectedItem("Organization"); + navigate(`?admin_tab=org_config`, { replace: true }); + window.location.reload(); + } + , 3000); + } + } + }, [isIntegrationPartner, isChildOrg, isGlobalUser, location.search, userdata, isOrgLoaded, isUserDataLoaded]); + + const renderComponent = () => { - const selectedItemData = items.find(item => item.text === selectedItem); + const selectedItemData = visibleItems.find(item => item.text === selectedItem); if (!selectedItemData) { setSelectedItem("Organization"); // If no tab is specified, default to "Organization" tab - return ; + return ; }; const ComponentToRender = selectedItemData.component; @@ -97,15 +218,16 @@ const AdminNavBar = (props) => { : selectedOrganization?.image; return ( + !isOrgLoaded && !isUserDataLoaded ? :
-