Lightmode/Darkmode merge including many fixes since 2.0.2
This commit is contained in:
@@ -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: <BusinessIcon />, 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: <PermIdentityIcon />, alt: "Users Icon", text: "Users", component: UserManagmentTab, props: { globalUrl, userdata, serverside, isCloud, selectedOrganization, setSelectedOrganization, handleEditOrg } },
|
||||
{ iconSrc: <HttpsOutlinedIcon />, alt: "App Auth Icon", text: "App_auth", component: AppAuthTab, props: { globalUrl, userdata, isCloud, selectedOrganization } },
|
||||
{ iconSrc: <StorageOutlinedIcon />, alt: "Datastore Icon", text: "Datastore", component: CacheView, props: { globalUrl, userdata, selectedOrganization, serverside, isSelectedDataStore, orgId , isCloud} },
|
||||
{ iconSrc: <InsertDriveFileOutlinedIcon />, alt: "Files Icon", text: "Files", component: Files, props: { isCloud, globalUrl, userdata, serverside, selectedOrganization, isSelectedFiles } },
|
||||
{ iconSrc: <AccessTimeOutlinedIcon />, alt: "Trigger Icon", text: "Triggers", component: SchedulesTab, props: { globalUrl, userdata, isCloud, serverside } },
|
||||
{ iconSrc: <FmdGoodOutlinedIcon />, alt: "Environments Icon", text: "Locations", component: EnvironmentTab, props: { globalUrl, userdata, isCloud, selectedOrganization } },
|
||||
{ iconSrc: <GroupOutlinedIcon />, 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: <BusinessIcon />, 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: <PermIdentityIcon />, alt: "Users Icon", text: "Users", component: UserManagmentTab, props: { globalUrl, userdata, serverside, isCloud, selectedOrganization, setSelectedOrganization, handleEditOrg } },
|
||||
{ iconSrc: <HttpsOutlinedIcon />, alt: "App Auth Icon", text: "App_auth", component: AppAuthTab, props: { globalUrl, userdata, isCloud, selectedOrganization } },
|
||||
{ iconSrc: <StorageOutlinedIcon />, alt: "Datastore Icon", text: "Datastore", component: CacheView, props: { globalUrl, userdata, selectedOrganization, serverside, isSelectedDataStore, orgId , isCloud} },
|
||||
{ iconSrc: <InsertDriveFileOutlinedIcon />, alt: "Files Icon", text: "Files", component: Files, props: { isCloud, globalUrl, userdata, serverside, selectedOrganization, isSelectedFiles } },
|
||||
{ iconSrc: <AccessTimeOutlinedIcon />, alt: "Trigger Icon", text: "Triggers", component: SchedulesTab, props: { globalUrl, userdata, isCloud, serverside } },
|
||||
{ iconSrc: <FmdGoodOutlinedIcon />, alt: "Environments Icon", text: "Locations", component: EnvironmentTab, props: { globalUrl, userdata, isCloud, selectedOrganization } },
|
||||
{ iconSrc: <GroupOutlinedIcon />, 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 <OrganizationTab globalUrl={globalUrl} removeCookie={removeCookie} selectedStatus={selectedStatus} isLoaded={isLoaded} setSelectedStatus={setSelectedStatus} handleStatusChange={handleStatusChange} handleEditOrg={handleEditOrg} handleGetOrg={handleGetOrg} userdata={userdata} isCloud={isCloud} serverside={serverside} notifications={notifications} checkLogin={checkLogin} setNotifications={setNotifications} stripeKey={stripeKey} setSelectedOrganization={setSelectedOrganization} selectedOrganization={selectedOrganization}/>;
|
||||
return <OrganizationTab isIntegrationPartner={isIntegrationPartner} isChildOrg={isChildOrg} isGlobalUser={isGlobalUser} globalUrl={globalUrl} removeCookie={removeCookie} selectedStatus={selectedStatus} isLoaded={isLoaded} setSelectedStatus={setSelectedStatus} handleStatusChange={handleStatusChange} handleEditOrg={handleEditOrg} handleGetOrg={handleGetOrg} userdata={userdata} isCloud={isCloud} serverside={serverside} notifications={notifications} checkLogin={checkLogin} setNotifications={setNotifications} stripeKey={stripeKey} setSelectedOrganization={setSelectedOrganization} selectedOrganization={selectedOrganization}/>;
|
||||
};
|
||||
|
||||
const ComponentToRender = selectedItemData.component;
|
||||
@@ -97,15 +218,16 @@ const AdminNavBar = (props) => {
|
||||
: selectedOrganization?.image;
|
||||
|
||||
return (
|
||||
!isOrgLoaded && !isUserDataLoaded ? <Loader /> :
|
||||
<Wrapper>
|
||||
<div style={{ flexDirection: 'column', width: 220, }}>
|
||||
<nav style={{ padding: '25px 25px 3px 25px', height: isCloud ? "calc(100% - 60px)" : "calc(100% - 30px)" , fontSize: '16px', borderTopLeftRadius: 8, borderBottomLeftRadius: 8, background: '#212121', color: '#9CA3AF' }}>
|
||||
<nav style={{ padding: '25px 25px 3px 25px', height: isCloud ? "calc(100% - 60px)" : "calc(100% - 30px)" , fontSize: '16px', borderTopLeftRadius: 8, borderBottomLeftRadius: 8, background: theme.palette.platformColor, color: '#9CA3AF' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', }}>
|
||||
<img loading="lazy" src={imageData} alt="Logo" style={{ width: '30px', borderRadius: 8, height: '30px', marginRight: '8px' }} />
|
||||
<div style={{
|
||||
fontFamily: theme?.typography?.fontFamily,
|
||||
fontSize: '16px',
|
||||
color: "#FFFFFF",
|
||||
color: theme.palette.text.primary,
|
||||
fontWeight: 400,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
@@ -114,8 +236,8 @@ const AdminNavBar = (props) => {
|
||||
marginLeft: 5,
|
||||
}}>{selectedOrganization?.name}</div>
|
||||
</div>
|
||||
<div style={{ borderTop: '1px solid #494949', marginTop: 23 }} />
|
||||
{items.map((item, index) => (
|
||||
<div style={{ borderTop: theme.palette.defaultBorder, marginTop: 23 }} />
|
||||
{visibleItems.map((item, index) => (
|
||||
<Tooltip
|
||||
key={index}
|
||||
title={
|
||||
@@ -132,11 +254,10 @@ const AdminNavBar = (props) => {
|
||||
color="primary"
|
||||
sx={{
|
||||
gap: 1,
|
||||
"&:hover": {
|
||||
backgroundColor: "#323232 !important",
|
||||
},
|
||||
"&.MuiButton-root": {
|
||||
color: selectedItem === item.text ? "#FFFFFF" : "#9E9E9E",
|
||||
color: selectedItem === item.text
|
||||
? theme.palette.text.primary
|
||||
: theme.palette.text.secondary,
|
||||
fontSize: 16,
|
||||
backgroundColor: "transparent",
|
||||
textTransform: "none",
|
||||
@@ -149,13 +270,16 @@ const AdminNavBar = (props) => {
|
||||
justifyContent: "flex-start",
|
||||
borderLeft:
|
||||
selectedItem === item.text
|
||||
? "3px solid rgba(255, 132, 68, 1)"
|
||||
? `3px solid ${theme.palette.primary.main}`
|
||||
: "none",
|
||||
borderTopLeftRadius: selectedItem === item.text ? "2.5px" : null,
|
||||
borderBottomLeftRadius: selectedItem === item.text ? "2.5px" : null,
|
||||
paddingLeft: selectedItem === item.text ? "15px" : "10px",
|
||||
fontWeight: selectedItem === item.text ? 200 : "normal",
|
||||
flex: 1,
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.hoverColor,
|
||||
},
|
||||
},
|
||||
"&.Mui-disabled": {
|
||||
color: "#6F6F6F",
|
||||
@@ -183,6 +307,112 @@ const AdminNavBar = (props) => {
|
||||
|
||||
export default AdminNavBar;
|
||||
|
||||
const Loader = () => {
|
||||
const dummyItems = Array.from({ length: 6 });
|
||||
const dummyNavItems = Array.from({ length: 6 });
|
||||
const dummyTabItems = ['Org Configuration', 'SSO', 'Notifications', 'Billing & Stats', 'Branding'];
|
||||
const { leftSideBarOpenByClick, windowWidth, themeMode } = useContext(Context);
|
||||
const theme = getTheme(themeMode);
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
minHeight: '100vh',
|
||||
maxWidth: '1200px',
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
paddingLeft: leftSideBarOpenByClick ? windowWidth <= 1300 ? 220 : 200 : 80,
|
||||
transition: "padding-left 0.3s ease",
|
||||
}}>
|
||||
|
||||
<div style={{
|
||||
width: '220px',
|
||||
backgroundColor: theme.palette.platformColor,
|
||||
borderTopLeftRadius: '8px',
|
||||
borderBottomLeftRadius: '8px',
|
||||
padding: '25px 25px 3px 25px',
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', marginBottom: '20px' }}>
|
||||
<Skeleton
|
||||
width="30px"
|
||||
height="30px"
|
||||
sx={{ borderRadius: '8px', marginRight: '8px', }}
|
||||
/>
|
||||
<Skeleton width="120px" height="24px" />
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<Skeleton
|
||||
width="100%"
|
||||
height="1px"
|
||||
sx={{ marginBottom: '15px' }}
|
||||
/>
|
||||
|
||||
{/* Nav Items */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '5px', width: '100%' }}>
|
||||
{dummyNavItems.map((_, index) => (
|
||||
<div key={index} style={{ display: 'flex', alignItems: 'center', padding: '5px 0' }}>
|
||||
<Skeleton
|
||||
width="18px"
|
||||
height="18px"
|
||||
sx={{ marginRight: '10px' }}
|
||||
/>
|
||||
<Skeleton width={`${100 + Math.random() * 40}px`} height="36px" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
backgroundColor: theme.palette.platformColor,
|
||||
borderTopRightRadius: '8px',
|
||||
borderBottomRightRadius: '8px',
|
||||
borderLeft: theme.palette.defaultBorder,
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
}}>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
borderBottom: theme.palette.defaultBorder,
|
||||
padding: '0 16px'
|
||||
}}>
|
||||
{dummyTabItems.map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
style={{
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
padding: '28px 0',
|
||||
borderBottom: index === 0 ? '2px solid #FF8444' : 'none'
|
||||
}}
|
||||
>
|
||||
<Skeleton width={`${80 + Math.random() * 30}px`} height="24px" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ flex: 1, padding: '24px' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', width: '100%', margin: '0 auto', alignItems: 'flex-start' }}>
|
||||
<Skeleton variant='square' width="200px" height="200px" sx={{ marginBottom: '20px' }} />
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px', width: '100%', marginTop: '50px' }}>
|
||||
{dummyItems.map((_, index) => (
|
||||
<div key={index} style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
|
||||
<Skeleton width={'400px'} height="36px" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
const PaddingWrapper2 = memo(({ children }) => {
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user