diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index ab71062e..04cdd17c 100755 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -418,6 +418,7 @@ const App = (message, props) => { serverside={false} isLoaded={isLoaded} isLoggedIn={isLoggedIn} + checkLogin={checkLogin} userdata={userdata} globalUrl={globalUrl} surfaceColor={theme.palette.surfaceColor} diff --git a/frontend/src/components/AppSelection.jsx b/frontend/src/components/AppSelection.jsx index 5bbb5ff0..df78af8e 100644 --- a/frontend/src/components/AppSelection.jsx +++ b/frontend/src/components/AppSelection.jsx @@ -47,6 +47,7 @@ const AppSelection = props => { defaultSearch, setDefaultSearch, checkLogin, + isAppPage=false } = props; const [discoveryData, setDiscoveryData] = React.useState({}) @@ -507,26 +508,31 @@ const AppSelection = props => { })} - {!moreButton ? ( -
- { + { + !isAppPage && ( + <> + {!moreButton ? ( +
+ { setMoreButton(true) - setTimeout(() => { navigate("/welcome?tab=2") }, 250) }} >See More Apps -
) : ""} +
) : ""} -
- -
+
+ +
+ + ) + } ) diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 9ccbd95e..079d4b2e 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -24,6 +24,7 @@ import { removeQuery } from "../components/ScrollToTop.jsx"; import { toast } from "react-toastify"; import algoliasearch from "algoliasearch/lite"; import { debounce } from "lodash"; +import AppSelection from "../components/AppSelection.jsx"; const searchClient = algoliasearch( @@ -32,7 +33,7 @@ const searchClient = algoliasearch( ); // AppCard Component -const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes }) => { +const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab }) => { const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "localhost:3000"; const appUrl = isCloud ? `/apps/${data.id}` : `https://shuffler.io/apps/${data.id}`; @@ -50,9 +51,13 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, return ( - - setMouseHoverIndex(index)} onMouseOut={() => setMouseHoverIndex(-1)}> - setMouseHoverIndex(index)} + onMouseOut={() => setMouseHoverIndex(-1)} + > + { + // if (!event.target.closest('.deactivate-button')) { + // window.location.href = appUrl; + // } + console.log("clicked"); + }} + > + {data.name} +
- {data.name}
-
- {data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} + {data.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} +
+
+ {data.categories ? data.categories.join(", ") : "NA"} +
+
+
+ {data.generated !== true && data.tags && data.tags.slice(0, 2).map((tag, tagIndex) => ( + + {tag} + {tagIndex < data.tags.length - 1 ? ", " : ""} + + ))}
-
- {data.categories ? data.categories.join(", ") : "NA"} -
-
-
- {data.generated !== true && data.tags && data.tags.slice(0, 2).map((tag, tagIndex) => ( - - {tag} - {tagIndex < data.tags.length - 1 ? ", " : ""} - - ))} -
- {/* Deactivate button logic */} - {mouseHoverIndex === index ? - - : null} -
+ .catch(error => { + console.log("app error: ", error.toString()); + }); + }} + > + Deactivate + + )}
- - -
+
+ + ); }; @@ -183,7 +196,7 @@ const Hits = ({ }) => { const [hoverEffect, setHoverEffect] = useState(-1); const [allActivatedAppIds, setAllActivatedAppIds] = useState(userdata?.active_apps); - const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io" || window.location.host === "localhost:3000"; + const isCloud = window.location.host === "localhost:3002" || window.location.host === "shuffler.io"; const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]); const normalizedString = (name) => { @@ -194,12 +207,6 @@ const Hits = ({ } }; - useEffect(() => { - console.log("searchQuery", searchQuery) - console.log("hits", hits) - }, [searchQuery, hits]) - - //Function for activation and deactivation of app @@ -270,7 +277,9 @@ const Hits = ({ {!isLoading ? (
{hits?.length === 0 && searchQuery.length >= 0 && showNoAppFound ? ( - No Apps Found +
+ No Apps Found +
) : (
{ }, [debouncedRefine]); useEffect(() => { + if (searchQuery === "") { + return; + } if (inputRef.current) { inputRef.current.focus(); } @@ -628,24 +640,62 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { const CustomSearchBox = connectSearchBox(SearchBox); const CustomHits = connectHits(Hits); +// Custom Label Dropdown Component +const LabelDropdown = ({ items, currentRefinement, refine }) => { + const handleChange = (event) => { + const value = event.target.value; + refine(value); + }; + + return ( + + ); +}; + +const CustomLabelDropdown = connectRefinementList(LabelDropdown); + // Main Apps Component const Apps2 = (props) => { - const { globalUrl, isLoaded, serverside, userdata, isLoggedIn } = props; + const { globalUrl, isLoaded, serverside, userdata, isLoggedIn, checkLogin } = props; let navigate = useNavigate(); const { leftSideBarOpenByClick } = useContext(Context); const location = useLocation(); const [searchQuery, setSearchQuery] = useState(""); const [selectedCategory, setSelectedCategory] = useState([]); const [selectedLabel, setSelectedLabel] = useState([]); - const [algoliaSelectedLabels, setAlgoliaSelectedLabels] = useState([]); const [currTab, setCurrTab] = useState(0); const [categories, setCategories] = useState([]); const [labels, setLabels] = useState([]); const [isLoading, setIsLoading] = useState(false); const [userApps, setUserApps] = useState([]); const [orgApps, setOrgApps] = useState([]); - const [selectedCategoryForUsersAndOgsApps, setselectedCategoryForUsersAndOgsApps] = useState([]); - const [selectedTagsForUserAndOrgApps, setSelectedTagsForUserAndOrgApps] = useState([]); const [appsToShow, setAppsToShow] = useState([]); const [deactivatedIndexes, setDeactivatedIndexes] = React.useState([]); const [IsAnyAppActivated, setIsAnyAppActivated] = useState(false); @@ -654,6 +704,8 @@ const Apps2 = (props) => { const [showNoAppFound, setShowNoAppFound] = useState(false); + const [appFramework, setAppFramework] = useState(undefined); + const [defaultSearch, setDefaultSearch] = useState(""); // Set the current tab based on the query parameter useEffect(() => { const queryParams = new URLSearchParams(location.search); @@ -666,11 +718,47 @@ const Apps2 = (props) => { } else { setCurrTab(2); } - } else { - setCurrTab(0); } }, [location.search]); + useEffect(() => { + + const getFramework = () => { + fetch(globalUrl + "/api/v1/apps/frameworkConfiguration", { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for framework!"); + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success === false) { + setAppFramework({}) + + if (responseJson.reason !== undefined) { + //toast("Failed loading: " + responseJson.reason) + } else { + //toast("Failed to load framework for your org.") + } + } else { + setAppFramework(responseJson) + } + }) + .catch((error) => { + console.log("err in framework: ", error.toString()); + }) + } + + getFramework(); + }, []); // Fetch apps based on the current tab : 0 -> org_apps, 1 -> my_apps, 2 -> all_apps useEffect(() => { @@ -695,23 +783,27 @@ const Apps2 = (props) => { }); const data = await response.json(); if (currTab === 1) { - console.log("data from userApps", data) setAppsToShow(data); setUserApps(data); - setIsLoading(false); } else if (currTab === 0) { - console.log("data from orgApps", data) setAppsToShow(data); setOrgApps(data); - setIsLoading(false); + // For testing the empty state + // setAppsToShow([]); + // setOrgApps([]); } + setIsLoading(false); } catch (err) { console.error("Error fetching apps:", err); + setIsLoading(false); } }; - fetchApps(); - }, [currTab, globalUrl, location.search]); // Added globalUrl to dependencies to avoid stale closures + // Only fetch if we have required data + if (globalUrl && (currTab === 0 || (currTab === 1 && userdata?.id))) { + fetchApps(); + } + }, [currTab, globalUrl, userdata?.id]); // Remove location.search dependency useEffect(() => { setSearchQuery(""); @@ -789,8 +881,9 @@ const Apps2 = (props) => { return topTags; }; - const handleCreateApp = () => { - navigate('/create-app'); + const handleCreateApp = (e) => { + e.preventDefault(); + console.log("Create app clicked") }; @@ -832,7 +925,6 @@ const Apps2 = (props) => { const handleTabChange = (newTab) => { - console.log("Current Tab", newTab) setCurrTab(newTab); if (newTab === 0) { setAppsToShow(orgApps) @@ -956,44 +1048,34 @@ const Apps2 = (props) => { {category.category} ))} - { - selectedCategory.length > 0 && ( - setSelectedCategory([])} style={{ display: 'flex', justifyContent: 'center', padding: '10px', backgroundColor: '#212121', color: '#fff', marginTop: '10px', cursor: 'pointer' }}> - Remove All Categories - - ) - } )}
- selected.length ? selected.join(', ') : 'All Labels'} + > + + All Labels - ))} - { - selectedLabel.length > 0 && ( - setSelectedCategory([])} style={{ display: 'flex', justifyContent: 'center', padding: '10px', backgroundColor: '#212121', color: '#fff', marginTop: '10px', cursor: 'pointer' }}> - Remove All Labels + {labels?.map((tag) => ( + + + {tag.tag} - ) - } - + ))} + + )}