added labels

This commit is contained in:
PhilReact 2024-10-25 12:32:39 +03:00
parent 4260c148fb
commit 16222b845a
9 changed files with 418 additions and 176 deletions

View File

@ -149,7 +149,7 @@ const defaultValues: MyContextInterface = {
message: "", message: "",
}, },
}; };
export let isMobile = false; export let isMobile = true;
const isMobileDevice = () => { const isMobileDevice = () => {
const userAgent = navigator.userAgent || navigator.vendor || window.opera; const userAgent = navigator.userAgent || navigator.vendor || window.opera;

View File

@ -5,7 +5,7 @@ export const sortablePinnedAppsAtom = atom({
key: 'sortablePinnedAppsFromAtom', key: 'sortablePinnedAppsFromAtom',
default: [{ default: [{
name: 'Q-Tube', name: 'Q-Tube',
servic: 'APP' service: 'APP'
}, { }, {
name: 'Q-Mail', name: 'Q-Mail',
service: 'APP' service: 'APP'

View File

@ -28,9 +28,17 @@ import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { AppRating } from "./AppRating"; import { AppRating } from "./AppRating";
import { settingsLocalLastUpdatedAtom, sortablePinnedAppsAtom } from "../../atoms/global";
import { saveToLocalStorage } from "./AppsNavBar";
import { useRecoilState, useSetRecoilState } from "recoil";
export const AppInfo = ({ app, myName }) => { export const AppInfo = ({ app, myName }) => {
const isInstalled = app?.status?.status === "READY"; const isInstalled = app?.status?.status === "READY";
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === app?.name && item?.service === app?.service)
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
return ( return (
<AppsLibraryContainer <AppsLibraryContainer
sx={{ sx={{
@ -104,6 +112,56 @@ export const AppInfo = ({ app, myName }) => {
<AppInfoSnippetRight></AppInfoSnippetRight> <AppInfoSnippetRight></AppInfoSnippetRight>
</AppInfoSnippetContainer> </AppInfoSnippetContainer>
<Spacer height="11px" /> <Spacer height="11px" />
<Box sx={{
width: '100%',
display: 'flex',
alignItems: 'center',
gap: '20px'
}}>
<AppDownloadButton
onClick={() => {
setSortablePinnedApps((prev) => {
let updatedApps;
if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
updatedApps = prev.filter(
(item) => !(item?.name === app?.name && item?.service === app?.service)
);
} else {
// Add the selected app if it is not pinned
updatedApps = [...prev, {
name: app?.name,
service: app?.service,
}];
}
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps)
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now())
}}
sx={{
backgroundColor: "#359ff7ff",
width: "100%",
maxWidth: "320px",
height: "29px",
opacity: isSelectedAppPinned ? 0.6 : 1
}}
>
<AppDownloadButtonText>
{!isMobile ? (
<>
{isSelectedAppPinned ? 'Unpin from dashboard' : 'Pin to dashboard'}
</>
) : (
<>
{isSelectedAppPinned ? 'Unpin' : 'Pin'}
</>
)}
</AppDownloadButtonText>
</AppDownloadButton>
<AppDownloadButton <AppDownloadButton
onClick={() => { onClick={() => {
executeEvent("addTab", { executeEvent("addTab", {
@ -121,6 +179,8 @@ export const AppInfo = ({ app, myName }) => {
{isInstalled ? "Open" : "Download"} {isInstalled ? "Open" : "Download"}
</AppDownloadButtonText> </AppDownloadButtonText>
</AppDownloadButton> </AppDownloadButton>
</Box>
</AppsWidthLimiter> </AppsWidthLimiter>
<Spacer height="20px" /> <Spacer height="20px" />
<AppsWidthLimiter> <AppsWidthLimiter>

View File

@ -12,16 +12,23 @@ import {
AppInfoUserName, AppInfoUserName,
} from "./Apps-styles"; } from "./Apps-styles";
import { Avatar, ButtonBase } from "@mui/material"; import { Avatar, ButtonBase } from "@mui/material";
import { getBaseApiReact } from "../../App"; import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg"; import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { AppRating } from "./AppRating"; import { AppRating } from "./AppRating";
import { useRecoilState, useSetRecoilState } from "recoil";
import { settingsLocalLastUpdatedAtom, sortablePinnedAppsAtom } from "../../atoms/global";
import { saveToLocalStorage } from "./AppsNavBar";
export const AppInfoSnippet = ({ app, myName, isFromCategory }) => { export const AppInfoSnippet = ({ app, myName, isFromCategory }) => {
const isInstalled = app?.status?.status === 'READY' const isInstalled = app?.status?.status === 'READY'
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom);
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === app?.name && item?.service === app?.service)
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom);
return ( return (
<AppInfoSnippetContainer> <AppInfoSnippetContainer>
<AppInfoSnippetLeft> <AppInfoSnippetLeft>
@ -74,6 +81,7 @@ export const AppInfoSnippet = ({ app, myName, isFromCategory }) => {
</AppCircleContainer> </AppCircleContainer>
</ButtonBase> </ButtonBase>
<AppInfoSnippetMiddle> <AppInfoSnippetMiddle>
<ButtonBase onClick={()=> { <ButtonBase onClick={()=> {
if(isFromCategory){ if(isFromCategory){
executeEvent("selectedAppInfoCategory", { executeEvent("selectedAppInfoCategory", {
@ -97,7 +105,41 @@ export const AppInfoSnippet = ({ app, myName, isFromCategory }) => {
<AppRating app={app} myName={myName} /> <AppRating app={app} myName={myName} />
</AppInfoSnippetMiddle> </AppInfoSnippetMiddle>
</AppInfoSnippetLeft> </AppInfoSnippetLeft>
<AppInfoSnippetRight> <AppInfoSnippetRight sx={{
gap: '10px'
}}>
{!isMobile && (
<AppDownloadButton onClick={()=> {
setSortablePinnedApps((prev) => {
let updatedApps;
if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
updatedApps = prev.filter(
(item) => !(item?.name === app?.name && item?.service === app?.service)
);
} else {
// Add the selected app if it is not pinned
updatedApps = [...prev, {
name: app?.name,
service: app?.service,
}];
}
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps)
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now())
}} sx={{
backgroundColor: '#359ff7ff',
opacity: isSelectedAppPinned ? 0.6 : 1
}}>
<AppDownloadButtonText> {isSelectedAppPinned ? 'Unpin' : 'Pin'}</AppDownloadButtonText>
</AppDownloadButton>
)}
<AppDownloadButton onClick={()=> { <AppDownloadButton onClick={()=> {
executeEvent("addTab", { executeEvent("addTab", {

View File

@ -3,6 +3,7 @@ import {
AppCircle, AppCircle,
AppCircleContainer, AppCircleContainer,
AppCircleLabel, AppCircleLabel,
AppLibrarySubTitle,
AppsContainer, AppsContainer,
AppsParent, AppsParent,
} from "./Apps-styles"; } from "./Apps-styles";
@ -12,9 +13,26 @@ import { getBaseApiReact } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg"; import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { SortablePinnedApps } from "./SortablePinnedApps"; import { SortablePinnedApps } from "./SortablePinnedApps";
import { Spacer } from "../../common/Spacer";
export const AppsHome = ({ setMode, myApp, myWebsite, availableQapps }) => { export const AppsHome = ({ setMode, myApp, myWebsite, availableQapps }) => {
return ( return (
<>
<AppsContainer
sx={{
justifyContent: "flex-start",
}}
>
<AppLibrarySubTitle
>
Apps Dashboard
</AppLibrarySubTitle>
</AppsContainer>
<Spacer height="20px" />
<AppsContainer> <AppsContainer>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
@ -32,5 +50,6 @@ export const AppsHome = ({ setMode, myApp, myWebsite, availableQapps }) => {
<SortablePinnedApps availableQapps={availableQapps} myWebsite={myWebsite} myApp={myApp} /> <SortablePinnedApps availableQapps={availableQapps} myWebsite={myWebsite} myApp={myApp} />
</AppsContainer> </AppsContainer>
</>
); );
}; };

View File

@ -3,6 +3,7 @@ import {
AppCircle, AppCircle,
AppCircleContainer, AppCircleContainer,
AppCircleLabel, AppCircleLabel,
AppLibrarySubTitle,
AppsContainer, AppsContainer,
AppsParent, AppsParent,
} from "./Apps-styles"; } from "./Apps-styles";
@ -12,30 +13,61 @@ import { getBaseApiReact, isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg"; import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { SortablePinnedApps } from "./SortablePinnedApps"; import { SortablePinnedApps } from "./SortablePinnedApps";
import { Spacer } from "../../common/Spacer";
export const AppsHomeDesktop = ({ setMode, myApp, myWebsite, availableQapps }) => { export const AppsHomeDesktop = ({
setMode,
myApp,
myWebsite,
availableQapps,
}) => {
return ( return (
<AppsContainer sx={{ <>
gap: '75px', <AppsContainer
justifyContent: 'flex-start' sx={{
}}>
justifyContent: "flex-start",
}}
>
<AppLibrarySubTitle
sx={{
fontSize: "30px",
}}
>
Apps Dashboard
</AppLibrarySubTitle>
</AppsContainer>
<Spacer height="45px" />
<AppsContainer
sx={{
gap: "75px",
justifyContent: "flex-start",
}}
>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setMode("library"); setMode("library");
}} }}
> >
<AppCircleContainer sx={{ <AppCircleContainer
gap: !isMobile ? '10px': '5px' sx={{
}}> gap: !isMobile ? "10px" : "5px",
}}
>
<AppCircle> <AppCircle>
<Add>+</Add> <Add>+</Add>
</AppCircle> </AppCircle>
<AppCircleLabel>Library</AppCircleLabel> <AppCircleLabel>Library</AppCircleLabel>
</AppCircleContainer> </AppCircleContainer>
</ButtonBase> </ButtonBase>
<SortablePinnedApps isDesktop={true} availableQapps={availableQapps} myWebsite={myWebsite} myApp={myApp} /> <SortablePinnedApps
isDesktop={true}
availableQapps={availableQapps}
myWebsite={myWebsite}
myApp={myApp}
/>
</AppsContainer> </AppsContainer>
</>
); );
}; };

View File

@ -25,11 +25,13 @@ import IconSearch from "../../assets/svgs/Search.svg";
import IconClearInput from "../../assets/svgs/ClearInput.svg"; import IconClearInput from "../../assets/svgs/ClearInput.svg";
import qappDevelopText from "../../assets/svgs/qappDevelopText.svg"; import qappDevelopText from "../../assets/svgs/qappDevelopText.svg";
import qappDots from "../../assets/svgs/qappDots.svg"; import qappDots from "../../assets/svgs/qappDots.svg";
import ReturnSVG from '../../assets/svgs/Return.svg'
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { AppInfoSnippet } from "./AppInfoSnippet"; import { AppInfoSnippet } from "./AppInfoSnippet";
import { Virtuoso } from "react-virtuoso"; import { Virtuoso } from "react-virtuoso";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { ComposeP, MailIconImg, ShowMessageReturnButton } from "../Group/Forum/Mail-styles";
const officialAppList = [ const officialAppList = [
"q-tube", "q-tube",
"q-blog", "q-blog",
@ -160,6 +162,15 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
</Box> </Box>
</AppsWidthLimiter> </AppsWidthLimiter>
<Spacer height="25px" /> <Spacer height="25px" />
<ShowMessageReturnButton sx={{
padding: '2px'
}} onClick={() => {
setMode('home')
}}>
<MailIconImg src={ReturnSVG} />
<ComposeP>Return to Apps Dashboard</ComposeP>
</ShowMessageReturnButton>
<Spacer height="25px" />
{searchedList?.length > 0 ? ( {searchedList?.length > 0 ? (
<AppsWidthLimiter> <AppsWidthLimiter>
<StyledVirtuosoContainer sx={{ <StyledVirtuosoContainer sx={{

View File

@ -44,6 +44,8 @@ import {
AppsDesktopLibraryHeader, AppsDesktopLibraryHeader,
} from "./AppsDesktop-styles"; } from "./AppsDesktop-styles";
import { AppsNavBarDesktop } from "./AppsNavBarDesktop"; import { AppsNavBarDesktop } from "./AppsNavBarDesktop";
import ReturnSVG from '../../assets/svgs/Return.svg'
import { ComposeP, MailIconImg, ShowMessageReturnButton } from "../Group/Forum/Mail-styles";
const officialAppList = [ const officialAppList = [
"q-tube", "q-tube",
"q-blog", "q-blog",
@ -217,7 +219,17 @@ export const AppsLibraryDesktop = ({
width: "90%", width: "90%",
}} }}
> >
<Spacer height="90px" />
<Spacer height="70px" />
<ShowMessageReturnButton sx={{
padding: '2px'
}} onClick={() => {
setMode('home')
}}>
<MailIconImg src={ReturnSVG} />
<ComposeP>Return to Apps Dashboard</ComposeP>
</ShowMessageReturnButton>
<Spacer height="20px" />
{searchedList?.length > 0 ? ( {searchedList?.length > 0 ? (
<AppsWidthLimiter> <AppsWidthLimiter>
<StyledVirtuosoContainer <StyledVirtuosoContainer

View File

@ -7,13 +7,28 @@ import {
import NavBack from "../../assets/svgs/NavBack.svg"; import NavBack from "../../assets/svgs/NavBack.svg";
import NavAdd from "../../assets/svgs/NavAdd.svg"; import NavAdd from "../../assets/svgs/NavAdd.svg";
import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg"; import NavMoreMenu from "../../assets/svgs/NavMoreMenu.svg";
import { ButtonBase, ListItemIcon, ListItemText, Menu, MenuItem, Tab, Tabs } from "@mui/material"; import {
import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events"; ButtonBase,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Tab,
Tabs,
} from "@mui/material";
import {
executeEvent,
subscribeToEvent,
unsubscribeFromEvent,
} from "../../utils/events";
import TabComponent from "./TabComponent"; import TabComponent from "./TabComponent";
import PushPinIcon from '@mui/icons-material/PushPin'; import PushPinIcon from "@mui/icons-material/PushPin";
import RefreshIcon from '@mui/icons-material/Refresh'; import RefreshIcon from "@mui/icons-material/Refresh";
import { useRecoilState, useSetRecoilState } from "recoil"; import { useRecoilState, useSetRecoilState } from "recoil";
import { settingsLocalLastUpdatedAtom, sortablePinnedAppsAtom } from "../../atoms/global"; import {
settingsLocalLastUpdatedAtom,
sortablePinnedAppsAtom,
} from "../../atoms/global";
export function saveToLocalStorage(key, subKey, newValue) { export function saveToLocalStorage(key, subKey, newValue) {
try { try {
@ -28,13 +43,13 @@ export function saveToLocalStorage(key, subKey, newValue) {
combinedData = { combinedData = {
...parsedData, ...parsedData,
timestamp: Date.now(), // Update the root timestamp timestamp: Date.now(), // Update the root timestamp
[subKey]: newValue // Assuming the data is an array [subKey]: newValue, // Assuming the data is an array
}; };
} else { } else {
// If no existing data, just use the new data under the subKey // If no existing data, just use the new data under the subKey
combinedData = { combinedData = {
timestamp: Date.now(), // Set the initial root timestamp timestamp: Date.now(), // Set the initial root timestamp
[subKey]: newValue [subKey]: newValue,
}; };
} }
@ -42,22 +57,24 @@ export function saveToLocalStorage(key, subKey, newValue) {
const serializedValue = JSON.stringify(combinedData); const serializedValue = JSON.stringify(combinedData);
localStorage.setItem(key, serializedValue); localStorage.setItem(key, serializedValue);
} catch (error) { } catch (error) {
console.error('Error saving to localStorage:', error); console.error("Error saving to localStorage:", error);
} }
} }
export const AppsNavBar = () => { export const AppsNavBar = () => {
const [tabs, setTabs] = useState([]) const [tabs, setTabs] = useState([]);
const [selectedTab, setSelectedTab] = useState(null) const [selectedTab, setSelectedTab] = useState(null);
const [isNewTabWindow, setIsNewTabWindow] = useState(false) const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const tabsRef = useRef(null); const tabsRef = useRef(null);
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(sortablePinnedAppsAtom); const [sortablePinnedApps, setSortablePinnedApps] = useRecoilState(
sortablePinnedAppsAtom
);
const setSettingsLocalLastUpdated = useSetRecoilState(settingsLocalLastUpdatedAtom); const setSettingsLocalLastUpdated = useSetRecoilState(
settingsLocalLastUpdatedAtom
);
const handleClick = (event) => { const handleClick = (event) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
@ -70,20 +87,24 @@ export const AppsNavBar = () => {
useEffect(() => { useEffect(() => {
// Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added) // Scroll to the last tab whenever the tabs array changes (e.g., when a new tab is added)
if (tabsRef.current) { if (tabsRef.current) {
const tabElements = tabsRef.current.querySelectorAll('.MuiTab-root'); const tabElements = tabsRef.current.querySelectorAll(".MuiTab-root");
if (tabElements.length > 0) { if (tabElements.length > 0) {
const lastTab = tabElements[tabElements.length - 1]; const lastTab = tabElements[tabElements.length - 1];
lastTab.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'end' }); lastTab.scrollIntoView({
behavior: "smooth",
block: "nearest",
inline: "end",
});
} }
} }
}, [tabs.length]); // Dependency on the number of tabs }, [tabs.length]); // Dependency on the number of tabs
const setTabsToNav = (e) => { const setTabsToNav = (e) => {
const {tabs, selectedTab, isNewTabWindow} = e.detail?.data; const { tabs, selectedTab, isNewTabWindow } = e.detail?.data;
setTabs([...tabs]) setTabs([...tabs]);
setSelectedTab(!selectedTab ? nulll : {...selectedTab}) setSelectedTab(!selectedTab ? nulll : { ...selectedTab });
setIsNewTabWindow(isNewTabWindow) setIsNewTabWindow(isNewTabWindow);
}; };
useEffect(() => { useEffect(() => {
@ -94,70 +115,94 @@ export const AppsNavBar = () => {
}; };
}, []); }, []);
const isSelectedAppPinned = !!sortablePinnedApps?.find(
const isSelectedAppPinned = !!sortablePinnedApps?.find((item)=> item?.name === selectedTab?.name && item?.service === selectedTab?.service) (item) =>
item?.name === selectedTab?.name && item?.service === selectedTab?.service
);
return ( return (
<AppsNavBarParent> <AppsNavBarParent>
<AppsNavBarLeft> <AppsNavBarLeft>
<ButtonBase onClick={()=> { <ButtonBase
executeEvent("navigateBack", { onClick={() => {
}); executeEvent("navigateBack", {});
}}> }}
>
<img src={NavBack} /> <img src={NavBack} />
</ButtonBase> </ButtonBase>
<Tabs <Tabs
ref={tabsRef} ref={tabsRef}
aria-label="basic tabs example" aria-label="basic tabs example"
variant="scrollable" // Make tabs scrollable variant="scrollable" // Make tabs scrollable
scrollButtons={false} scrollButtons={false}
sx={{
"& .MuiTabs-indicator": {
backgroundColor: "white",
},
maxWidth: `calc(100vw - 150px)`, // Ensure the tabs container fits within the available space
overflow: 'hidden', // Prevents overflow on small screens
}}
>
{tabs?.map((tab) => (
<Tab
key={tab.tabId}
label={<TabComponent isSelected={tab?.tabId === selectedTab?.tabId && !isNewTabWindow} app={tab} />} // Pass custom component
sx={{ sx={{
"&.Mui-selected": { "& .MuiTabs-indicator": {
color: "white", backgroundColor: "white",
}, },
padding: '0px', maxWidth: `calc(100vw - 150px)`, // Ensure the tabs container fits within the available space
margin: '0px', overflow: "hidden", // Prevents overflow on small screens
minWidth: '0px',
width: '50px'
}} }}
/> >
))} {tabs?.map((tab) => (
</Tabs> <Tab
key={tab.tabId}
label={
<TabComponent
isSelected={
tab?.tabId === selectedTab?.tabId && !isNewTabWindow
}
app={tab}
/>
} // Pass custom component
sx={{
"&.Mui-selected": {
color: "white",
},
padding: "0px",
margin: "0px",
minWidth: "0px",
width: "50px",
}}
/>
))}
</Tabs>
</AppsNavBarLeft> </AppsNavBarLeft>
<AppsNavBarRight sx={{ {selectedTab && (
gap: '10px' <AppsNavBarRight
}}> sx={{
<ButtonBase onClick={()=> { gap: "10px",
setSelectedTab(null) }}
executeEvent("newTabWindow", { >
}); <ButtonBase
}}> onClick={() => {
<img style={{ setSelectedTab(null);
height: '40px', executeEvent("newTabWindow", {});
width: '40px' }}
}} src={NavAdd} /> >
</ButtonBase> <img
<ButtonBase onClick={(e)=> { style={{
if(!selectedTab) return height: "40px",
handleClick(e) width: "40px",
}}> }}
<img style={{ src={NavAdd}
height: '34px', />
width: '34px' </ButtonBase>
}} src={NavMoreMenu} /> <ButtonBase
</ButtonBase> onClick={(e) => {
</AppsNavBarRight> if (!selectedTab) return;
handleClick(e);
}}
>
<img
style={{
height: "34px",
width: "34px",
}}
src={NavMoreMenu}
/>
</ButtonBase>
</AppsNavBarRight>
)}
<Menu <Menu
id="navbar-more-mobile" id="navbar-more-mobile"
anchorEl={anchorEl} anchorEl={anchorEl}
@ -167,102 +212,123 @@ export const AppsNavBar = () => {
"aria-labelledby": "basic-button", "aria-labelledby": "basic-button",
}} }}
anchorOrigin={{ anchorOrigin={{
vertical: 'bottom', vertical: "bottom",
horizontal: 'center', horizontal: "center",
}}
}} transformOrigin={{
transformOrigin={{ vertical: "top",
vertical: 'top', horizontal: "center",
horizontal: 'center', }}
}} slotProps={{
slotProps={{ paper: {
paper: { sx: {
sx: { backgroundColor: "var(--bg-primary)",
backgroundColor: 'var(--bg-primary)', color: "#fff",
color: '#fff', width: "148px",
width: '148px', borderRadius: "5px",
borderRadius: '5px'
},
}, },
},
}} }}
sx={{ sx={{
marginTop: '10px' marginTop: "10px",
}} }}
> >
<MenuItem <MenuItem
onClick={() => { onClick={() => {
if (!selectedTab) return; if (!selectedTab) return;
setSortablePinnedApps((prev) => {
let updatedApps;
if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
updatedApps = prev.filter(
(item) => !(item?.name === selectedTab?.name && item?.service === selectedTab?.service)
);
} else {
// Add the selected app if it is not pinned
updatedApps = [...prev, {
name: selectedTab?.name,
service: selectedTab?.service,
}];
}
saveToLocalStorage('ext_saved_settings', 'sortablePinnedApps', updatedApps)
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now())
handleClose(); setSortablePinnedApps((prev) => {
}} let updatedApps;
>
<ListItemIcon sx={{ if (isSelectedAppPinned) {
// Remove the selected app if it is pinned
minWidth: '24px !important', updatedApps = prev.filter(
marginRight: '5px' (item) =>
}}> !(
<PushPinIcon height={20} sx={{ item?.name === selectedTab?.name &&
color: isSelectedAppPinned ? 'red' : "rgba(250, 250, 250, 0.5)", item?.service === selectedTab?.service
)
}} /> );
</ListItemIcon> } else {
<ListItemText sx={{ // Add the selected app if it is not pinned
"& .MuiTypography-root": { updatedApps = [
fontSize: "12px", ...prev,
fontWeight: 600, {
color: isSelectedAppPinned ? 'red' : "rgba(250, 250, 250, 0.5)" name: selectedTab?.name,
service: selectedTab?.service,
}, },
}} primary={`${isSelectedAppPinned ? 'Unpin app' : 'Pin app'}`} /> ];
</MenuItem> }
<MenuItem
onClick={() => { saveToLocalStorage(
executeEvent('refreshApp', { "ext_saved_settings",
tabId: selectedTab?.tabId "sortablePinnedApps",
}) updatedApps
);
return updatedApps;
});
setSettingsLocalLastUpdated(Date.now());
handleClose(); handleClose();
}} }}
> >
<ListItemIcon sx={{ <ListItemIcon
sx={{
minWidth: '24px !important', minWidth: "24px !important",
marginRight: '5px' marginRight: "5px",
}}> }}
<RefreshIcon height={20} sx={{ >
color:"rgba(250, 250, 250, 0.5)" <PushPinIcon
}} /> height={20}
sx={{
color: isSelectedAppPinned ? "red" : "rgba(250, 250, 250, 0.5)",
}}
/>
</ListItemIcon> </ListItemIcon>
<ListItemText sx={{ <ListItemText
"& .MuiTypography-root": { sx={{
fontSize: "12px", "& .MuiTypography-root": {
fontWeight: 600, fontSize: "12px",
color:"rgba(250, 250, 250, 0.5)" fontWeight: 600,
}, color: isSelectedAppPinned ? "red" : "rgba(250, 250, 250, 0.5)",
}} primary="Refresh" /> },
}}
primary={`${isSelectedAppPinned ? "Unpin app" : "Pin app"}`}
/>
</MenuItem> </MenuItem>
</Menu> <MenuItem
onClick={() => {
executeEvent("refreshApp", {
tabId: selectedTab?.tabId,
});
handleClose();
}}
>
<ListItemIcon
sx={{
minWidth: "24px !important",
marginRight: "5px",
}}
>
<RefreshIcon
height={20}
sx={{
color: "rgba(250, 250, 250, 0.5)",
}}
/>
</ListItemIcon>
<ListItemText
sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Refresh"
/>
</MenuItem>
</Menu>
</AppsNavBarParent> </AppsNavBarParent>
); );
}; };