From 6753410525244d1416a2dae842acbbec2c6e0890 Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sat, 30 Nov 2024 21:39:45 +0530 Subject: [PATCH 01/10] Made some UI changes --- frontend/src/components/AppModal.jsx | 1 - frontend/src/views/Workflows2.jsx | 130 +++++++++++++++++++-------- 2 files changed, 94 insertions(+), 37 deletions(-) diff --git a/frontend/src/components/AppModal.jsx b/frontend/src/components/AppModal.jsx index a4bd272f..239cec7c 100644 --- a/frontend/src/components/AppModal.jsx +++ b/frontend/src/components/AppModal.jsx @@ -293,7 +293,6 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { sx: { borderRadius: 3, border: "1px solid var(--Container-Stroke, #494949)", - backgroundColor: "var(--Container, #212121)", minWidth: '440px', fontFamily: "Inter" } diff --git a/frontend/src/views/Workflows2.jsx b/frontend/src/views/Workflows2.jsx index 3937345e..506574e0 100644 --- a/frontend/src/views/Workflows2.jsx +++ b/frontend/src/views/Workflows2.jsx @@ -2086,9 +2086,9 @@ const Workflows2 = (props) => { continue } - if (parsedAction.name === "Shuffle Tools" || parsedAction.id === "bc78f35c6c6351b07a09b7aed5d29652") { - continue - } + // if (parsedAction.name === "Shuffle Tools" || parsedAction.id === "bc78f35c6c6351b07a09b7aed5d29652") { + // continue + // } if (appsFound.findIndex(data => data.name === parsedAction.name) < 0) { appsFound.push(parsedAction) @@ -3287,11 +3287,11 @@ const Workflows2 = (props) => { {editingWorkflow.id !== undefined ? "Edit Workflow" : "Create New Workflow"} -
+
upload.click()} style={{ backgroundColor: "rgba(255,255,255,0.08)" }} > @@ -3299,7 +3299,7 @@ const Workflows2 = (props) => { setDialogModalOpen(false)} style={{ backgroundColor: "rgba(255,255,255,0.08)" }} > @@ -3532,7 +3532,7 @@ const Workflows2 = (props) => { setDefaultReturnValue(""); setEditingWorkflow({}); setNewWorkflowTags([]); - setModalOpen(false); + setDialogModalOpen(false); setSelectedUsecases([]) }} > @@ -4035,6 +4035,7 @@ const Workflows2 = (props) => {
+ { setFilters(chips); findWorkflow(chips); }} - style={{ flex: 0.9, borderRadius: 8 }} - // style={searchStyle} - //onAdd={(chip) => { - // console.log("ADd: ", chip); - // addFilter(chip); - //}} - //onDelete={(_, index) => { - // console.log("Remove: ", index); - // removeFilter(index); - //}} + style={{ flex: 0.9 }} + InputProps={{ + style: { + color: "white", + borderRadius: 8, + }, + }} + sx={{ + '& .MuiOutlinedInput-root': { + '& fieldset': { + borderColor: 'rgba(255, 255, 255, 0.2)', + }, + '&:hover fieldset': { + borderColor: 'rgba(255, 255, 255, 0.3)', + }, + '&.Mui-focused fieldset': { + borderColor: '#f85a3e', + }, + }, + '& .MuiChip-root': { + backgroundColor: 'rgba(255, 255, 255, 0.1)', + color: 'white', + '& .MuiChip-deleteIcon': { + color: 'rgba(255, 255, 255, 0.7)', + '&:hover': { + color: 'white', + }, + }, + }, + }} /> - - From 6da219f53b42c73331ad2d2208372ab620391c8b Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 14:49:19 +0530 Subject: [PATCH 02/10] Create workflow form change to previous year --- frontend/src/views/Workflows2.jsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/src/views/Workflows2.jsx b/frontend/src/views/Workflows2.jsx index 506574e0..b0dded3c 100644 --- a/frontend/src/views/Workflows2.jsx +++ b/frontend/src/views/Workflows2.jsx @@ -724,7 +724,15 @@ const Workflows2 = (props) => { }; const handleCreateWorkflow = () => { - setDialogModalOpen(true) + setModalOpen(true) + setIsEditing(false) + setNewWorkflowName("") + setNewWorkflowDescription("") + setDefaultReturnValue("") + setEditingWorkflow({}) + setNewWorkflowTags([]) + setSelectedUsecases([]) + }; @@ -3232,7 +3240,7 @@ const Workflows2 = (props) => { { - setDialogModalOpen(true) + setModalOpen(true) setIsEditing(false) }} > @@ -4690,7 +4698,7 @@ const Workflows2 = (props) => { */} - {modalView} + {/* {modalView} */} {deleteModal} {exportVerifyModal} {publishModal} From e652d0039c84fe6dd73272ac7bce54adab3915ec Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 19:12:28 +0530 Subject: [PATCH 03/10] Done with the revamp of apps2 page : New look --- frontend/src/views/Apps2.jsx | 816 ++++++++++++++++++++--------------- 1 file changed, 468 insertions(+), 348 deletions(-) diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 7011be79..0f395471 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -15,6 +15,7 @@ import { } from "@mui/material"; import { Context } from "../context/ContextApi.jsx"; import Add from '@mui/icons-material/Add'; +import EditIcon from '@mui/icons-material/Edit'; import InputAdornment from '@mui/material/InputAdornment'; import Search from '@mui/icons-material/Search'; import ClearIcon from '@mui/icons-material/Clear'; @@ -34,20 +35,23 @@ const searchClient = algoliasearch( ); // AppCard Component -const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab, handleAppClick }) => { +const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, deactivatedIndexes, currTab, handleAppClick, leftSideBarOpenByClick, userdata }) => { 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}`; + var canEditApp = userdata.admin === "true" || userdata.id === data?.owner || data?.owner === "" || (userdata.admin === "true" && userdata.active_org.id === data?.reference_org) || !data?.generated const paperStyle = { - backgroundColor: mouseHoverIndex === index ? "rgba(26, 26, 26, 1)" : "#1A1A1A", + backgroundColor: mouseHoverIndex === index ? "rgba(26, 26, 26, 1)" : "#212121", color: "rgba(241, 241, 241, 1)", cursor: "pointer", - position: "relative", - width: 365, + fontFamily: "Inter", + // position: "relative", + width: "100%", height: 96, borderRadius: 8, boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.1)", marginBottom: 20, + transition: "width 0.3s ease", }; return ( @@ -63,7 +67,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, fontSize: 16, overflow: "hidden", display: "flex", - alignItems: "flex-start", + fontFamily: "Inter", width: '100%', backgroundColor: mouseHoverIndex === index ? "#2F2F2F" : "#212121" }} @@ -92,13 +96,14 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, fontWeight: '400', overflow: "hidden", margin: "12px 0", - fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" + fontFamily: "Inter" }}>
-
+
{data.generated !== true && data.tags && data.tags.slice(0, 2).map((tag, tagIndex) => ( {tag} @@ -134,44 +140,57 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
{/* Deactivate button */} {currTab === 0 && !deactivatedIndexes.includes(index) && mouseHoverIndex === index && data.generated === true && ( - + ) + } + + .then((response) => response.json()) + .then((responseJson) => { + if (responseJson.success === false) { + toast.error(responseJson.reason); + } else { + toast.success("App Deactivated Successfully. Reload UI to see updated changes."); + } + }) + .catch(error => { + console.log("app error: ", error.toString()); + }); + }} + > + Deactivate + +
)}
@@ -192,6 +211,7 @@ const Hits = ({ globalUrl, isLoading, isLoggedIn, + leftSideBarOpenByClick }) => { const [hoverEffect, setHoverEffect] = useState(-1); const [allActivatedAppIds, setAllActivatedAppIds] = useState(userdata?.active_apps); @@ -330,7 +350,7 @@ const Hits = ({ color: "rgba(241, 241, 241, 1)", cursor: "pointer", position: "relative", - width: 365, + width: leftSideBarOpenByClick ? 325 : 365, height: 96, borderRadius: 8, boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.1)", @@ -374,7 +394,6 @@ const Hits = ({ fontWeight: '400', overflow: "hidden", margin: "12px 0", - fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} >
{data.categories !== null @@ -514,46 +533,7 @@ const Hits = ({ ); } -// Custom Category Dropdown Component -const CategoryDropdown = ({ items, currentRefinement, refine }) => { - const handleChange = (event) => { - const value = event.target.value; - refine(value); - }; - return ( - - ); -}; - -const CustomCategoryDropdown = connectRefinementList(CategoryDropdown); // Custom SearchBox Component const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { @@ -608,10 +588,11 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { event.preventDefault(); } }} - style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} + style={{ borderRadius: 8, height: 45, fontFamily: "Inter", flex: 1 }} InputProps={{ style: { borderRadius: 8, + height: 45 }, endAdornment: ( @@ -637,6 +618,38 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { const CustomSearchBox = connectSearchBox(SearchBox); const CustomHits = connectHits(Hits); +// Custom Category Dropdown Component +const CategoryDropdown = ({ items, currentRefinement, refine }) => { + const handleChange = (event) => { + const value = event.target.value; + refine(value); + }; + + return ( + + ); +}; +const CustomCategoryDropdown = connectRefinementList(CategoryDropdown); + // Custom Label Dropdown Component const LabelDropdown = ({ items, currentRefinement, refine }) => { const handleChange = (event) => { @@ -652,15 +665,7 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => { onChange={handleChange} displayEmpty multiple - style={{ - width: '100%', - maxWidth: '300px', - borderRadius: '7px', - fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)", - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} + style={{ borderRadius: 8, height: 45, fontFamily: "Inter", flex: 1 }} renderValue={(selected) => selected.length ? selected.join(', ') : 'All Labels'} > @@ -675,9 +680,44 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => { ); }; - const CustomLabelDropdown = connectRefinementList(LabelDropdown); + + +// New filter function +const filterApps = (apps, searchQuery, selectedCategory, selectedLabel) => { + if (!Array.isArray(apps)) return []; + + return apps.filter((app) => { + const matchesSearchQuery = ( + searchQuery === "" || // If searchQuery is empty, match all apps + app.name.toLowerCase().includes(searchQuery.toLowerCase()) || + (app.tags && app.tags.some(tag => + tag.toLowerCase().includes(searchQuery.toLowerCase()) + )) || + (app.categories && app.categories.some((category) => + category.toLowerCase().includes(searchQuery.toLowerCase()) + )) + ); + + const matchesSelectedCategories = ( + selectedCategory.length === 0 || // If no category is selected, match all apps + (app.categories && app.categories.some(category => + selectedCategory.includes(category) + )) + ); + + const matchesSelectedTags = ( + selectedLabel.length === 0 || // If no label is selected, match all apps + (app.tags && app.tags.some(tag => + selectedLabel.includes(tag) + )) + ); + + return matchesSearchQuery && matchesSelectedCategories && matchesSelectedTags; + }); +}; + // Main Apps Component const Apps2 = (props) => { const { globalUrl, isLoaded, serverside, userdata, isLoggedIn, checkLogin } = props; @@ -803,14 +843,16 @@ const Apps2 = (props) => { } }, [currTab, globalUrl, userdata?.id]); // Remove location.search dependency - useEffect(() => { - setSearchQuery(""); - }, [currTab]) + // useEffect(() => { + // // setSearchQuery(""); + // setSelectedCategory([]); + // setSelectedLabel([]); + // }, [currTab]) // Find top categories and tags based on the current tab useEffect(() => { - if (currTab === 0) { + if (currTab === 0 || currTab === 1) { setCategories(findTopCategories()); setLabels(findTopTags()); } @@ -881,76 +923,81 @@ const Apps2 = (props) => { const handleCreateApp = (e) => { e.preventDefault(); - setOpenModal(true); + // setOpenModal(true); }; useEffect(() => { const apps = currTab === 1 ? userApps : orgApps; - // Search app based on app name, category, and tag - const filteredUserAppdata = Array.isArray(apps) ? apps.filter((app) => { - - const matchesSearchQuery = ( - searchQuery === "" || // If searchQuery is empty, match all apps - app.name.toLowerCase().includes(searchQuery.toLowerCase()) || - (app.tags && app.tags.some(tag => - tag.toLowerCase().includes(searchQuery.toLowerCase()) - )) || - (app.categories && app.categories.some((category) => - category.toLowerCase().includes(searchQuery.toLowerCase()) - )) - ); - - const matchesSelectedCategories = ( - selectedCategory.length === 0 || // If no category is selected, match all apps - (app.categories && app.categories.some(category => - selectedCategory.includes(category) - )) - ); - - const matchesSelectedTags = ( - selectedLabel.length === 0 || // If no label is selected, match all apps - (app.tags && app.tags.some(tag => - selectedLabel.includes(tag) - )) - ); - - return matchesSearchQuery && matchesSelectedCategories && matchesSelectedTags; - }) : []; - + const filteredUserAppdata = filterApps(apps, searchQuery, selectedCategory, selectedLabel); setAppsToShow(filteredUserAppdata); - }, [searchQuery, selectedCategory, selectedLabel]); + }, [searchQuery, selectedCategory, selectedLabel, currTab]); const handleTabChange = (newTab) => { setCurrTab(newTab); + // Apply filters immediately when changing tabs if (newTab === 0) { - setAppsToShow(orgApps) - const categories = findTopCategories(); - const labels = findTopTags(); - setCategories(categories); - setLabels(labels); - } - if (newTab === 1) { - setAppsToShow(userApps) + const filteredOrgApps = filterApps(orgApps, searchQuery, selectedCategory, selectedLabel); + setAppsToShow(filteredOrgApps); + } else if (newTab === 1) { + const filteredUserApps = filterApps(userApps, searchQuery, selectedCategory, selectedLabel); + setAppsToShow(filteredUserApps); } + + // Update URL query params const newQueryParam = newTab === 0 ? 'org_apps' : newTab === 1 ? 'my_apps' : 'all_apps'; const queryParams = new URLSearchParams(location.search); queryParams.set('tab', newQueryParam); - queryParams.delete('q'); + // Only remove 'q' param if search is empty + if (!searchQuery) { + queryParams.delete('q'); + } window.history.replaceState({}, '', `${location.pathname}?${queryParams.toString()}`); }; + // Update useEffect to handle initial load and URL search params + useEffect(() => { + const queryParams = new URLSearchParams(location.search); + const searchParam = queryParams.get('q'); + if (searchParam) { + setSearchQuery(searchParam); + } + }, []); + // Update useEffect for filtering to handle both tabs + useEffect(() => { + if (currTab === 2) return; // Skip for "Discover Apps" tab as it uses Algolia + const apps = currTab === 1 ? userApps : orgApps; + const filteredApps = filterApps(apps, searchQuery, selectedCategory, selectedLabel); + setAppsToShow(filteredApps); + + // Update URL with search query + const queryParams = new URLSearchParams(location.search); + if (searchQuery) { + queryParams.set('q', searchQuery); + } else { + queryParams.delete('q'); + } + window.history.replaceState({}, '', `${location.pathname}?${queryParams.toString()}`); + }, [searchQuery, selectedCategory, selectedLabel, currTab, userApps, orgApps]); + + // Update search input handler to maintain state across tabs + const handleSearchChange = (event) => { + const newSearchQuery = event.target.value; + setSearchQuery(newSearchQuery); + }; const boxStyle = { color: "white", display: "flex", flexDirection: "column", + height: "100%", width: "100%", margin: "auto", - maxWidth: "60%", + maxWidth: "70%", + fontFamily: "Inter", // padding: '20px 380px', }; @@ -975,214 +1022,287 @@ const Apps2 = (props) => { } return ( - - -
- - Apps - -
- handleTabChange(newTab)} - TabIndicatorProps={{ style: { height: '3px', borderRadius: 10 } }} - > - - - - -
-
-
+
+ + +
+ + Apps + +
+ handleTabChange(newTab)} + TabIndicatorProps={{ style: { height: '3px', borderRadius: 10 } }} + style={{ fontFamily: "Inter" }} + > + + + + +
+
+
+ { + (currTab === 0 || currTab === 1) && + { + if (event.key === "Enter") { + event.preventDefault(); + } + }} + limit={5} + InputProps={{ + style: { + borderRadius: 8, + height: 45 + }, + endAdornment: ( + + {searchQuery.length === 0 ? ( + + ) : ( + { + setSearchQuery(""); + }} + /> + )} + + ), + }} + /> + } + { + currTab === 2 && + + } +
+
+ {currTab === 2 ? ( + + ) : ( + <> + + {selectedCategory.length > 0 && ( + setSelectedCategory([])} + /> + )} + + )} +
+
+ {currTab === 2 ? ( + + ) : ( + <> + + {selectedLabel.length > 0 && ( + setSelectedLabel([])} + /> + )} + + )} +
+
+ +
+
+
+ { - (currTab === 0 || currTab === 1) && - { - setSearchQuery(event.target.value); - }} - onKeyDown={(event) => { - if (event.key === "Enter") { - event.preventDefault(); - } - }} - limit={5} - style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} - InputProps={{ - style: { - borderRadius: 8, - }, - endAdornment: ( - - { - searchQuery.length === 0 ? : - } - - ), - }} - /> + currTab === 0 && ( +
+ {isLoading ? ( +
+ +
+ ) : ( + <> + {appsToShow?.length > 0 && appsToShow !== undefined && !isLoading ? ( +
+ {appsToShow.map((data, index) => ( + + ))} +
+ ) : ( +
+ +
+ )} + + )} +
+ ) } + { + currTab === 1 && ( +
+ {isLoading ? ( +
+ +
+ ) : ( + <> + {appsToShow?.length > 0 && appsToShow !== undefined ? ( +
+ {appsToShow.map((data, index) => ( + + ))} +
+ ) : ( +
+ No Apps Found +
+ )} + + )} +
+ ) + } + { currTab === 2 && - + }
-
- {currTab === 2 ? ( - - ) : ( - - )} -
-
- {currTab === 2 ? ( - - ) : ( - - )} -
-
- -
-
-
- - { - currTab === 0 && ( -
- {isLoading ? ( -
- -
- ) : ( - <> - {appsToShow?.length > 0 && appsToShow !== undefined && !isLoading ? ( -
- {appsToShow.map((data, index) => ( - - ))} -
- ) : ( -
- -
- )} - - )} -
- ) - } - { - currTab === 1 && ( -
- {isLoading ? ( -
- -
- ) : ( - <> - {appsToShow?.length > 0 && appsToShow !== undefined ? ( -
- {appsToShow.map((data, index) => ( - - ))} -
- ) : ( -
- No Apps Found -
- )} - - )} -
- ) - } - - { - currTab === 2 && - - } -
-
- - +
+ + +
); }; From 02db40aa17c3fc276ecc8f07b65784b2666fae0f Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 19:51:51 +0530 Subject: [PATCH 04/10] Done with the discover apps tab revamp : New look --- frontend/src/components/AppModal.jsx | 2 +- frontend/src/views/Apps2.jsx | 552 ++++++++++++++------------- 2 files changed, 296 insertions(+), 258 deletions(-) diff --git a/frontend/src/components/AppModal.jsx b/frontend/src/components/AppModal.jsx index 239cec7c..0f0a3173 100644 --- a/frontend/src/components/AppModal.jsx +++ b/frontend/src/components/AppModal.jsx @@ -309,7 +309,7 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { }} > - About Gmail + About {app?.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} No Apps Found
) : ( - -
-
- {hits?.map((data, index) => { - const appUrl = - isCloud - ? `/apps/${data.objectID}?queryID=${data.__queryID}` - : `https://shuffler.io/apps/${data.objectID}?queryID=${data.__queryID}`; +
+ {hits?.map((data, index) => { + const appUrl = + isCloud + ? `/apps/${data.objectID}?queryID=${data.__queryID}` + : `https://shuffler.io/apps/${data.objectID}?queryID=${data.__queryID}`; - return ( - + { + setHoverEffect(index); + }} + onMouseLeave={() => { + setHoverEffect(-1); + }} + > + { + handleAppClick(data); }} > -
{ - handleAppClick(data); - } - } + {data.name} +
- { - setHoverEffect(index); - }} - onMouseLeave={() => { - setHoverEffect(-1); + display: 'flex', + flexDirection: "row", + overflow: "hidden", + gap: 8, + fontWeight:600, + textOverflow: "ellipsis", + whiteSpace: "nowrap", + color: '#F1F1F1' }} > - - {data.name} -
-
- {(allActivatedAppIds && allActivatedAppIds.includes(data.objectID)) && } - {normalizedString(data.name)} -
+ {(allActivatedAppIds && allActivatedAppIds.includes(data.objectID)) && } + {normalizedString(data.name)} +
-
- {data.categories !== null - ? normalizedString(data.categories).join(", ") - : "NA"} -
-
-
- {hoverEffect === index && isCloud ? ( -
- {data.tags && ( - - - {data.tags.slice(0, 1).map((tag, tagIndex) => ( - - {normalizedString(tag)} - {tagIndex < 1 ? ", " : ""} - - ))} - - - )} -
- ) : ( -
- {data.tags && - data.tags.map((tag, tagIndex) => ( - - {normalizedString(tag)} - {tagIndex < data.tags.length - 1 ? ", " : ""} - - ))} -
- )} -
-
- {hoverEffect === index && isCloud && ( -
- {allActivatedAppIds && allActivatedAppIds.includes(data.objectID) ? ( -
+
+
+ {hoverEffect === index && isCloud ? ( +
+ {data.tags && ( + { - handleActivateButton(event, data, "deactivate"); - }}> - Deactivate - - ) : ( - - )} -
- )} -
+ width: "auto", + height: "auto", + fontSize: 16, + border: "1px solid rgba(73, 73, 73, 1)", + } + } + }} + > + + {data.tags.slice(0, 1).map((tag, tagIndex) => ( + + {normalizedString(tag)} + {tagIndex < 1 ? ", " : ""} + + ))} + + + )}
-
- - + ) : ( +
+ {data.tags && + data.tags.map((tag, tagIndex) => ( + + {normalizedString(tag)} + {tagIndex < data.tags.length - 1 ? ", " : ""} + + ))} +
+ )} +
+
+ {hoverEffect === index && isCloud && ( +
+ {allActivatedAppIds && allActivatedAppIds.includes(data.objectID) ? ( + + ) : ( + + )} +
+ )} +
+
-
- ); - })} -
-
- + + + + ); + })} +
)}
) : (
- )} -
+ ) + } +
); } @@ -540,6 +528,14 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { const inputRef = useRef(null); const [localQuery, setLocalQuery] = useState(searchQuery); + // Initialize search when component mounts or when switching to Discover tab + useEffect(() => { + if (searchQuery) { + setLocalQuery(searchQuery); + refine(searchQuery); // This will trigger the Algolia search + } + }, [searchQuery, refine]); + // Debounced function to refine search const debouncedRefine = useRef( debounce((value) => { @@ -600,7 +596,6 @@ const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { { setLocalQuery(''); @@ -626,26 +621,43 @@ const CategoryDropdown = ({ items, currentRefinement, refine }) => { }; return ( - selected.length ? selected.join(', ') : 'All Categories'} + > + + All Categories - ))} - + {items.map(item => ( + + + {item.label} ({item.count}) + + ))} + + {currentRefinement.length > 0 && ( + refine([])} + /> + )} + ); }; const CustomCategoryDropdown = connectRefinementList(CategoryDropdown); @@ -658,26 +670,46 @@ const LabelDropdown = ({ items, currentRefinement, refine }) => { }; return ( - selected.length ? selected.join(', ') : 'All Labels'} + > + + All Labels - ))} - + {items.map(item => ( + + + {item.label} ({item.count}) + + ))} + + {currentRefinement.length > 0 && ( + refine([])} + /> + )} + ); }; const CustomLabelDropdown = connectRefinementList(LabelDropdown); @@ -936,6 +968,7 @@ const Apps2 = (props) => { const handleTabChange = (newTab) => { setCurrTab(newTab); + // Apply filters immediately when changing tabs if (newTab === 0) { const filteredOrgApps = filterApps(orgApps, searchQuery, selectedCategory, selectedLabel); @@ -944,15 +977,20 @@ const Apps2 = (props) => { const filteredUserApps = filterApps(userApps, searchQuery, selectedCategory, selectedLabel); setAppsToShow(filteredUserApps); } + // Note: We don't clear the search when switching to tab 2 (Discover Apps) anymore // Update URL query params const newQueryParam = newTab === 0 ? 'org_apps' : newTab === 1 ? 'my_apps' : 'all_apps'; const queryParams = new URLSearchParams(location.search); queryParams.set('tab', newQueryParam); - // Only remove 'q' param if search is empty - if (!searchQuery) { + + // Maintain search query in URL regardless of tab + if (searchQuery) { + queryParams.set('q', searchQuery); + } else { queryParams.delete('q'); } + window.history.replaceState({}, '', `${location.pathname}?${queryParams.toString()}`); }; @@ -1110,7 +1148,7 @@ const Apps2 = (props) => { All Categories {categories?.map((category) => ( - + {category.category} @@ -1153,7 +1191,7 @@ const Apps2 = (props) => { All Labels {labels?.map((tag) => ( - + {tag.tag} From cdad00152c318a31e1421a6210c6a01027562a85 Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 20:01:54 +0530 Subject: [PATCH 05/10] Minor fixes --- frontend/src/views/Apps2.jsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 3a9ad2d2..87fefcfd 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -966,7 +966,7 @@ const Apps2 = (props) => { }, [searchQuery, selectedCategory, selectedLabel, currTab]); - const handleTabChange = (newTab) => { + const handleTabChange = (event, newTab) => { setCurrTab(newTab); // Apply filters immediately when changing tabs @@ -977,12 +977,16 @@ const Apps2 = (props) => { const filteredUserApps = filterApps(userApps, searchQuery, selectedCategory, selectedLabel); setAppsToShow(filteredUserApps); } - // Note: We don't clear the search when switching to tab 2 (Discover Apps) anymore - // Update URL query params - const newQueryParam = newTab === 0 ? 'org_apps' : newTab === 1 ? 'my_apps' : 'all_apps'; + // Update URL query params based on tab index + const tabMapping = { + 0: 'org_apps', + 1: 'my_apps', + 2: 'all_apps' + }; + const queryParams = new URLSearchParams(location.search); - queryParams.set('tab', newQueryParam); + queryParams.set('tab', tabMapping[newTab]); // Maintain search query in URL regardless of tab if (searchQuery) { @@ -991,7 +995,7 @@ const Apps2 = (props) => { queryParams.delete('q'); } - window.history.replaceState({}, '', `${location.pathname}?${queryParams.toString()}`); + navigate(`${location.pathname}?${queryParams.toString()}`); }; // Update useEffect to handle initial load and URL search params @@ -1076,7 +1080,7 @@ const Apps2 = (props) => {
handleTabChange(newTab)} + onChange={(event, newTab) => handleTabChange(event, newTab)} TabIndicatorProps={{ style: { height: '3px', borderRadius: 10 } }} style={{ fontFamily: "Inter" }} > From 9e1d1e8ad7db0b5028a1601875f723cca300ffe0 Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 20:32:13 +0530 Subject: [PATCH 06/10] Added the skeleton loading --- frontend/src/views/Apps2.jsx | 87 ++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 87fefcfd..3b8fd0e8 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -12,6 +12,7 @@ import { Box, CircularProgress, Checkbox, + Skeleton, } from "@mui/material"; import { Context } from "../context/ContextApi.jsx"; import Add from '@mui/icons-material/Add'; @@ -280,7 +281,6 @@ const Hits = ({ const [showNoAppFound, setShowNoAppFound] = useState(false); - //show some delay to show the "App Not Found." so it doesn't not show while changing tab. useEffect(() => { const timer = setTimeout(() => { setShowNoAppFound(true); @@ -514,7 +514,7 @@ const Hits = ({ )}
) : ( -
+ ) } @@ -750,6 +750,81 @@ const filterApps = (apps, searchQuery, selectedCategory, selectedLabel) => { }); }; +// Add this new component for the app skeleton +const AppSkeleton = () => { + return ( + +
+ +
+ + + +
+
+
+ ); +}; + +// Replace the loading sections in the main component with this +const LoadingGrid = () => { + return ( +
+ {[...Array(7)].map((_, index) => ( + + ))} +
+ ); +}; + // Main Apps Component const Apps2 = (props) => { const { globalUrl, isLoaded, serverside, userdata, isLoggedIn, checkLogin } = props; @@ -1237,9 +1312,7 @@ const Apps2 = (props) => { currTab === 0 && (
{isLoading ? ( -
- -
+ ) : ( <> {appsToShow?.length > 0 && appsToShow !== undefined && !isLoading ? ( @@ -1292,9 +1365,7 @@ const Apps2 = (props) => { currTab === 1 && (
{isLoading ? ( -
- -
+ ) : ( <> {appsToShow?.length > 0 && appsToShow !== undefined ? ( From c9cba51d50ccc1430cab37534e04b450ebe0f160 Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Sun, 1 Dec 2024 21:07:42 +0530 Subject: [PATCH 07/10] Changed the app modal UI --- frontend/src/components/AppModal.jsx | 125 +++++++++++++++++---------- 1 file changed, 78 insertions(+), 47 deletions(-) diff --git a/frontend/src/components/AppModal.jsx b/frontend/src/components/AppModal.jsx index 0f0a3173..17cf2918 100644 --- a/frontend/src/components/AppModal.jsx +++ b/frontend/src/components/AppModal.jsx @@ -291,10 +291,23 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { fullWidth PaperProps={{ sx: { - borderRadius: 3, - border: "1px solid var(--Container-Stroke, #494949)", + borderRadius: 2, + border: "1px solid #494949", minWidth: '440px', - fontFamily: "Inter" + fontFamily: "Inter", + backgroundColor: "#212121", + '& .MuiDialogContent-root': { + backgroundColor: "#212121", + }, + '& .MuiDialogTitle-root': { + backgroundColor: "#212121", + }, + '& .MuiTypography-root': { + fontFamily: 'Inter, sans-serif', + }, + '& .MuiButton-root': { + fontFamily: 'Inter, sans-serif', + }, } }} > @@ -303,27 +316,29 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { display: 'flex', justifyContent: 'space-between', alignItems: 'center', - pb: 1, + pb: 2, pt: 2, - px: 3 + pl: 3, + pr: 2, + fontFamily: "Inter" }} > - + About {app?.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} - - + +
{ boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.2)" }} /> -
+
{ @@ -420,14 +438,26 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { textAlign: "start", flex: 1, }}> - + 20 - + Public Workflow
@@ -438,8 +468,9 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { paddingLeft: "10px", height: "100%", }}> - @@ -455,7 +486,7 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { paddingLeft: "10px", paddingTop: "5px" }}> -
+
{ app?.collection ? ( <> @@ -473,7 +504,7 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { }
- + Part of a collection
@@ -488,9 +519,9 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => {
{ (foundAppUsecase?.srcapp !== undefined && foundAppUsecase?.dstapp !== undefined) ? ( @@ -502,9 +533,9 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => {
{ ) } - + {foundAppUsecase?.name || "Search for a Usecase"} @@ -559,24 +590,24 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => {
- + ); }; From 675707cb4992bc6ea2e2446ae7f59eab4a6107ea Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Mon, 2 Dec 2024 12:08:21 +0530 Subject: [PATCH 08/10] Added the UI for download from github and added two CTAs --- frontend/src/components/AppModal.jsx | 4 +- frontend/src/views/Apps2.jsx | 624 +++++++++++++++++++++++++-- 2 files changed, 596 insertions(+), 32 deletions(-) diff --git a/frontend/src/components/AppModal.jsx b/frontend/src/components/AppModal.jsx index 17cf2918..17189887 100644 --- a/frontend/src/components/AppModal.jsx +++ b/frontend/src/components/AppModal.jsx @@ -323,7 +323,7 @@ const AppModal = ({ open, onClose, app, userdata, globalUrl }) => { fontFamily: "Inter" }} > - + About {app?.name.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase())} { display: "flex", flexDirection: "row", }}> - + {newAppname} { diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 3b8fd0e8..59037947 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -13,13 +13,21 @@ import { CircularProgress, Checkbox, Skeleton, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + IconButton, } from "@mui/material"; import { Context } from "../context/ContextApi.jsx"; import Add from '@mui/icons-material/Add'; +import CachedIcon from '@mui/icons-material/Cached'; +import CloudDownloadIcon from '@mui/icons-material/CloudDownload'; import EditIcon from '@mui/icons-material/Edit'; import InputAdornment from '@mui/material/InputAdornment'; import Search from '@mui/icons-material/Search'; import ClearIcon from '@mui/icons-material/Clear'; +import CloseIcon from '@mui/icons-material/Close'; import { ClearRefinements, connectHits, connectSearchBox, connectStateResults, InstantSearch, RefinementList, connectRefinementList, Configure } from "react-instantsearch-dom"; import { removeQuery } from "../components/ScrollToTop.jsx"; @@ -147,7 +155,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, }}> { canEditApp && ( - ) @@ -158,7 +166,7 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl, // marginLeft: 15, width: 102, height: 35, - borderRadius: 6, + borderRadius: 3, backgroundColor: "rgba(73, 73, 73, 1)", color: "rgba(241, 241, 241, 1)", textTransform: "none", @@ -391,7 +399,7 @@ const Hits = ({ flexDirection: "row", overflow: "hidden", gap: 8, - fontWeight:600, + fontWeight: 600, textOverflow: "ellipsis", whiteSpace: "nowrap", color: '#F1F1F1' @@ -765,14 +773,14 @@ const AppSkeleton = () => { width: "100%", height: "100%" }}> -
{ flex: 1, gap: 6 }}> - - -
@@ -827,7 +835,7 @@ const LoadingGrid = () => { // Main Apps Component const Apps2 = (props) => { - const { globalUrl, isLoaded, serverside, userdata, isLoggedIn, checkLogin } = props; + const { globalUrl, isLoaded, serverside, userdata, isLoggedIn, checkLogin, isCloud } = props; let navigate = useNavigate(); const { leftSideBarOpenByClick } = useContext(Context); const location = useLocation(); @@ -850,6 +858,20 @@ const Apps2 = (props) => { const [selectedApp, setSelectedApp] = useState(null); const [appFramework, setAppFramework] = useState(undefined); const [defaultSearch, setDefaultSearch] = useState(""); + + const [apps, setApps] = useState([]); + const [filteredApps, setFilteredApps] = useState([]); + const [appSearchLoading, setAppSearchLoading] = useState(false); + const [creatorProfile, setCreatorProfile] = useState({}); + const [openApi, setOpenApi] = React.useState(""); + const [loadAppsModalOpen, setLoadAppsModalOpen] = useState(false); + const [downloadBranch, setDownloadBranch] = useState("master"); + const [field1, setField1] = useState(""); + const [field2, setField2] = useState(""); + const [validation, setValidation] = useState(null); + + const baseRepository = "https://github.com/frikky/shuffle-apps"; + // Set the current tab based on the query parameter useEffect(() => { const queryParams = new URLSearchParams(location.search); @@ -965,6 +987,40 @@ const Apps2 = (props) => { } }, [currTab, appsToShow]) + const getUserProfile = (username) => { + if (serverside === true || !isCloud) { + setCreatorProfile({}) + return; + } + + fetch(`${globalUrl}/api/v1/users/creators/${username}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + if (response.status !== 200) { + console.log("Status not 200 for WORKFLOW EXECUTION :O!"); + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success !== false) { + console.log("creator profile: ", responseJson) + setCreatorProfile(responseJson); + } else { + setCreatorProfile({}) + } + }) + .catch((error) => { + console.log(error); + setCreatorProfile({}) + }); + }; useEffect(() => { if (serverside) { @@ -972,6 +1028,426 @@ const Apps2 = (props) => { } }, [serverside]); + const getApps = () => { + // Get apps from localstorage + var storageApps = [] + try { + const appstorage = localStorage.getItem("apps") + storageApps = JSON.parse(appstorage) + if (storageApps === null || storageApps === undefined || storageApps.length === 0) { + storageApps = [] + } else { + setApps(storageApps) + setFilteredApps(storageApps) + setAppSearchLoading(false) + } + } catch (e) { + //console.log("Failed to get apps from localstorage: ", e) + } + + fetch(globalUrl + "/api/v1/apps", { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + setIsLoading(false); + if (response.status !== 200) { + console.log("Status not 200 for apps :O!"); + + //if (isCloud) { + // window.location.pathname = "/search"; + //} + } + + return response.json(); + }) + .then((responseJson) => { + //responseJson = sortByKey(responseJson, "large_image") + //responseJson = sortByKey(responseJson, "is_valid") + //setFilteredApps(responseJson.filter(app => !internalIds.includes(app.name) && !(!app.activated && app.generated))) + console.log("responseJson: from getApps ", responseJson) + var privateapps = []; + var valid = []; + var invalid = []; + for (var key in responseJson) { + const app = responseJson[key]; + if (app.is_valid && !(!app.activated && app.generated)) { + privateapps.push(app); + } else if ( + app.private_id !== undefined && + app.private_id.length > 0 + ) { + valid.push(app); + } else { + invalid.push(app); + } + } + + //console.log(privateapps) + //console.log(valid) + //console.log(invalid) + //console.log(privateapps) + //privateapps.reverse() + privateapps.push(...valid); + privateapps.push(...invalid); + console.log("privateapps: setting apps ", privateapps) + setApps(privateapps); + // setCursearch(""); + + //handleSearchChange(event.target.value) + //setCursearch(event.target.value) + setFilteredApps(privateapps); + if (privateapps.length > 0) { + if (selectedApp.id === undefined || selectedApp.id === null) { + if (privateapps[0].owner !== undefined && privateapps[0].owner !== null) { + getUserProfile(privateapps[0].owner); + } + + // setContact(privateapps[0].contact_info) + + // setSelectedApp(privateapps[0]); + // setSharingConfiguration(privateapps[0].sharing === true ? "public" : "you") + } + + // if ( + // privateapps[0].actions !== null && + // privateapps[0].actions.length > 0 + // ) { + // setSelectedAction(privateapps[0].actions[0]); + // } else { + // setSelectedAction({}); + // } + } + + if (privateapps.length > 0 && storageApps.length === 0) { + try { + localStorage.setItem("apps", JSON.stringify(privateapps)) + } catch (e) { + console.log("Failed to set apps in localstorage: ", e) + } + } + + //setTimeout(() => { + // setFirstLoad(false) + //}, 5000) + }) + .catch((error) => { + toast(error.toString()); + setIsLoading(false); + }); + }; + + + // Locally hotloads app from folder + const hotloadApps = () => { + toast("Hotloading apps from location in .env"); + setIsLoading(true); + fetch(globalUrl + "/api/v1/apps/run_hotload", { + method: "POST", + mode: "cors", + headers: { + Accept: "application/json", + }, + credentials: "include", + }) + .then((response) => { + setIsLoading(false); + if (response.status === 200) { + //toast("Hotloaded apps!") + getApps(); + } + + return response.json(); + }) + .then((responseJson) => { + if (responseJson.success === true) { + toast("Successfully finished hotload"); + } else { + toast("Failed hotload: ", responseJson.reason); + //(responseJson.reason !== undefined && responseJson.reason.length > 0) { + } + }) + .catch((error) => { + toast(error.toString()); + }); + }; + + + // Load data e.g. from github + const getSpecificApps = (url, forceUpdate) => { + setValidation(true); + + setIsLoading(true); + //start() + + const parsedData = { + url: url, + branch: downloadBranch || "master", + }; + + if (field1.length > 0) { + parsedData["field_1"] = field1; + } + + if (field2.length > 0) { + parsedData["field_2"] = field2; + } + + parsedData["force_update"] = forceUpdate; + + toast("Getting specific apps from your URL."); + var cors = "cors"; + fetch(globalUrl + "/api/v1/apps/get_existing", { + method: "POST", + mode: "cors", + headers: { + Accept: "application/json", + }, + body: JSON.stringify(parsedData), + credentials: "include", + }) + .then((response) => { + if (response.status === 200) { + toast("Loaded existing apps!"); + } + + //stop() + setIsLoading(false); + setValidation(false); + return response.json(); + }) + .then((responseJson) => { + console.log("DATA: ", responseJson); + if (responseJson.reason !== undefined) { + toast("Failed loading: " + responseJson.reason); + } + }) + .catch((error) => { + console.log("ERROR: ", error.toString()); + //toast(error.toString()); + //stop() + + setIsLoading(false); + setValidation(false); + }); + }; + + const handleGithubValidation = (forceUpdate) => { + getSpecificApps(openApi, forceUpdate); + setLoadAppsModalOpen(false); + }; + + + const appsModalLoad = loadAppsModalOpen ? ( + { + setOpenApi(""); + setLoadAppsModalOpen(false); + setField1(""); + setField2(""); + }} + maxWidth="md" + fullWidth + PaperProps={{ + sx: { + borderRadius: 2, + border: "1px solid #494949", + minWidth: '440px', + fontFamily: "Inter", + backgroundColor: "#212121", + zIndex: 1000, + '& .MuiDialogContent-root': { + backgroundColor: "#212121", + }, + '& .MuiDialogTitle-root': { + backgroundColor: "#212121", + }, + '& .MuiTypography-root': { + fontFamily: 'Inter, sans-serif', + }, + '& .MuiButton-root': { + fontFamily: 'Inter, sans-serif', + }, + } + }} + > + + + Load from Github Repository + + { + setOpenApi(""); + setLoadAppsModalOpen(false); + setField1(""); + setField2(""); + }} + sx={{ + color: 'rgba(255, 255, 255, 0.7)', + '&:hover': { bgcolor: 'rgba(255, 255, 255, 0.1)' } + }} + > + + + + + + Repository (supported: github, gitlab, bitbucket) + + setOpenApi(e.target.value)} + sx={{ + mb: 3, + '& .MuiOutlinedInput-root': { + color: 'white', + height: '50px', + '& fieldset': { + borderColor: 'rgba(255, 255, 255, 0.23)', + }, + }, + }} + /> + + + Branch (default value is "master") + + setDownloadBranch(e.target.value)} + placeholder="master" + sx={{ + mb: 3, + '& .MuiOutlinedInput-root': { + color: 'white', + height: '50px', + '& fieldset': { + borderColor: 'rgba(255, 255, 255, 0.23)', + }, + }, + }} + /> + + + Authentication (optional - private repos etc) + +
+ setField1(e.target.value)} + sx={{ + '& .MuiOutlinedInput-root': { + color: 'white', + height: '50px', + '& fieldset': { + borderColor: 'rgba(255, 255, 255, 0.23)', + }, + }, + }} + /> + setField2(e.target.value)} + sx={{ + '& .MuiOutlinedInput-root': { + color: 'white', + height: '50px', + '& fieldset': { + borderColor: 'rgba(255, 255, 255, 0.23)', + }, + }, + }} + /> +
+
+ + + {!isCloud && ( + + )} + + +
+ ) : null; + const findTopCategories = () => { const categoryCountMap = {}; @@ -1043,7 +1519,7 @@ const Apps2 = (props) => { const handleTabChange = (event, newTab) => { setCurrTab(newTab); - + // Apply filters immediately when changing tabs if (newTab === 0) { const filteredOrgApps = filterApps(orgApps, searchQuery, selectedCategory, selectedLabel); @@ -1059,17 +1535,17 @@ const Apps2 = (props) => { 1: 'my_apps', 2: 'all_apps' }; - + const queryParams = new URLSearchParams(location.search); queryParams.set('tab', tabMapping[newTab]); - + // Maintain search query in URL regardless of tab if (searchQuery) { queryParams.set('q', searchQuery); } else { queryParams.delete('q'); } - + navigate(`${location.pathname}?${queryParams.toString()}`); }; @@ -1148,10 +1624,98 @@ const Apps2 = (props) => { userdata={userdata} globalUrl={globalUrl} /> + {appsModalLoad}
- - Apps - +
+ + Apps + + {isCloud ? null : ( + + {userdata === undefined || userdata === null || isLoading ? null : ( + + + + )} + + {userdata === undefined || userdata === null || userdata.admin === "false" ? null : + + + + } + + )} +
Date: Mon, 2 Dec 2024 12:29:40 +0530 Subject: [PATCH 09/10] Buttons on right : hotlaod and download from github --- frontend/src/views/Apps2.jsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/frontend/src/views/Apps2.jsx b/frontend/src/views/Apps2.jsx index 59037947..011df1ad 100644 --- a/frontend/src/views/Apps2.jsx +++ b/frontend/src/views/Apps2.jsx @@ -1037,9 +1037,11 @@ const Apps2 = (props) => { if (storageApps === null || storageApps === undefined || storageApps.length === 0) { storageApps = [] } else { + setAppsToShow(storageApps) + setOrgApps(storageApps) setApps(storageApps) - setFilteredApps(storageApps) - setAppSearchLoading(false) + // setFilteredApps(storageApps) + // setAppSearchLoading(false) } } catch (e) { //console.log("Failed to get apps from localstorage: ", e) @@ -1095,12 +1097,14 @@ const Apps2 = (props) => { privateapps.push(...valid); privateapps.push(...invalid); console.log("privateapps: setting apps ", privateapps) + setAppsToShow(privateapps); + setOrgApps(privateapps); setApps(privateapps); // setCursearch(""); //handleSearchChange(event.target.value) //setCursearch(event.target.value) - setFilteredApps(privateapps); + // setFilteredApps(privateapps); if (privateapps.length > 0) { if (selectedApp.id === undefined || selectedApp.id === null) { if (privateapps[0].owner !== undefined && privateapps[0].owner !== null) { @@ -1141,7 +1145,6 @@ const Apps2 = (props) => { }); }; - // Locally hotloads app from folder const hotloadApps = () => { toast("Hotloading apps from location in .env"); @@ -1167,12 +1170,13 @@ const Apps2 = (props) => { if (responseJson.success === true) { toast("Successfully finished hotload"); } else { - toast("Failed hotload: ", responseJson.reason); + console.log("failed hotload: ", responseJson) + // toast(`Failed hotload: ${responseJson.reason}`); //(responseJson.reason !== undefined && responseJson.reason.length > 0) { } }) .catch((error) => { - toast(error.toString()); + toast(`Failed hotload: ${error.toString()}`); }); }; From 899bde4947088a7ee998807112ef0c960bb54dc6 Mon Sep 17 00:00:00 2001 From: monilprajapati Date: Mon, 2 Dec 2024 12:49:23 +0530 Subject: [PATCH 10/10] added the app library link when searched app not found in org --- frontend/src/components/AppSelection.jsx | 74 ++++++++++++++++-------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/AppSelection.jsx b/frontend/src/components/AppSelection.jsx index df78af8e..76d38d88 100644 --- a/frontend/src/components/AppSelection.jsx +++ b/frontend/src/components/AppSelection.jsx @@ -428,30 +428,56 @@ const AppSelection = props => { />
) : null} - - Find your apps - - - Select the apps you work with and we will connect them for you. - + { + !isAppPage && ( + <> + + Find your apps + + + Select the apps you work with and we will connect them for you. + + + ) + } + { + isAppPage && ( +
+ + Your organization has no apps yet, select your starting apps here + or discover more apps using the { + navigate("/apps2?tab=all_apps") + }} + style={{ color: "#FF8444", fontWeight: "medium", fontSize: 16, cursor:"pointer" }}>App Library + +
+ ) + } {appButtons.map((appData, index) => { // This is here due to a memory issue with setting apps properly